From 935a709c94399486f2e765385bdabfdd8a555a31 Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Thu, 21 Mar 2024 16:54:01 +0000 Subject: [PATCH] wip --- .../aztec-nr/aztec/src/context/avm_context.nr | 16 +- .../aztec-nr/aztec/src/context/inputs.nr | 2 + .../src/context/inputs/avm_context_inputs.nr | 4 + .../contracts/avm_test_contract/src/main.nr | 10 + .../aztec_macros/src/transforms/functions.rs | 9 +- .../__snapshots__/contract_class.test.ts.snap | 10 +- .../simulator/src/avm/avm_context.test.ts | 6 +- .../src/avm/avm_execution_environment.test.ts | 9 +- .../src/avm/avm_execution_environment.ts | 17 +- .../simulator/src/avm/avm_simulator.test.ts | 1127 +++++++++-------- .../types/src/abi/contract_artifact.ts | 7 + 11 files changed, 646 insertions(+), 571 deletions(-) create mode 100644 noir-projects/aztec-nr/aztec/src/context/inputs/avm_context_inputs.nr diff --git a/noir-projects/aztec-nr/aztec/src/context/avm_context.nr b/noir-projects/aztec-nr/aztec/src/context/avm_context.nr index 803d1e92935e..ac918ca5b1f4 100644 --- a/noir-projects/aztec-nr/aztec/src/context/avm_context.nr +++ b/noir-projects/aztec-nr/aztec/src/context/avm_context.nr @@ -3,15 +3,17 @@ use dep::protocol_types::traits::Serialize; use dep::protocol_types::abis::function_selector::FunctionSelector; use dep::protocol_types::abis::public_circuit_public_inputs::PublicCircuitPublicInputs; use dep::protocol_types::constants::RETURN_VALUES_LENGTH; -use crate::context::inputs::PublicContextInputs; +use crate::context::inputs::avm_context_inputs::AvmContextInputs; use crate::context::interface::ContextInterface; use crate::context::interface::PublicContextInterface; -struct AVMContext {} +struct AVMContext { + inputs: AvmContextInputs, +} impl AVMContext { - pub fn new() -> Self { - AVMContext {} + pub fn new(inputs: AvmContextInputs) -> Self { + AVMContext { inputs } } pub fn origin(self) -> AztecAddress { @@ -190,16 +192,14 @@ impl ContextInterface for AVMContext { version() } fn selector(self) -> FunctionSelector { - assert(false, "'selector' not implemented!"); - FunctionSelector::zero() + FunctionSelector::from_field(self.inputs.selector) } fn get_header(self) -> Header { assert(false, "'get_header' not implemented!"); Header::empty() } fn get_args_hash(self) -> Field { - assert(false, "'get_args_hash' not implemented!"); - 0 + self.inputs.args_hash } } diff --git a/noir-projects/aztec-nr/aztec/src/context/inputs.nr b/noir-projects/aztec-nr/aztec/src/context/inputs.nr index 0d7c56574d52..86595969e1e7 100644 --- a/noir-projects/aztec-nr/aztec/src/context/inputs.nr +++ b/noir-projects/aztec-nr/aztec/src/context/inputs.nr @@ -1,5 +1,7 @@ mod private_context_inputs; mod public_context_inputs; +mod avm_context_inputs; use crate::context::inputs::private_context_inputs::PrivateContextInputs; use crate::context::inputs::public_context_inputs::PublicContextInputs; +use crate::context::inputs::avm_context_inputs::AvmContextInputs; diff --git a/noir-projects/aztec-nr/aztec/src/context/inputs/avm_context_inputs.nr b/noir-projects/aztec-nr/aztec/src/context/inputs/avm_context_inputs.nr new file mode 100644 index 000000000000..ffd16b268ac7 --- /dev/null +++ b/noir-projects/aztec-nr/aztec/src/context/inputs/avm_context_inputs.nr @@ -0,0 +1,4 @@ +struct AvmContextInputs { + selector: Field, + args_hash: Field, +} diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index 1bed81cb60bd..212987ee22ea 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -232,6 +232,16 @@ contract AvmTest { // context.contract_call_depth() // } + #[aztec(public-vm)] + fn check_selector() { + assert(context.selector() == FunctionSelector::from_signature("check_selector()")); + } + + #[aztec(public-vm)] + fn get_args_hash(_a: u8, _fields: [Field; 3]) -> pub Field { + context.get_args_hash() + } + #[aztec(public-vm)] fn emit_unencrypted_log() { context.accumulate_unencrypted_logs(/*event_selector=*/ 5, /*message=*/ [10, 20, 30]); diff --git a/noir/noir-repo/aztec_macros/src/transforms/functions.rs b/noir/noir-repo/aztec_macros/src/transforms/functions.rs index c719651e10eb..4d5c2d4ab39b 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/functions.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/functions.rs @@ -116,6 +116,10 @@ pub fn transform_vm_function( let create_context = create_avm_context()?; func.def.body.0.insert(0, create_context); + // Add the inputs to the params (last!) + let input = create_inputs("AvmContextInputs"); + func.def.parameters.push(input); + // We want the function to be seen as a public function func.def.is_unconstrained = true; @@ -354,11 +358,14 @@ fn create_context(ty: &str, params: &[Param]) -> Result, AztecMac /// // ... /// } fn create_avm_context() -> Result { + // Create the inputs to the context + let inputs_expression = variable("inputs"); + let let_context = mutable_assignment( "context", // Assigned to call( variable_path(chained_dep!("aztec", "context", "AVMContext", "new")), // Path - vec![], // args + vec![inputs_expression], // args ), ); diff --git a/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap b/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap index d0b5e308a320..5e018af31d11 100644 --- a/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap +++ b/yarn-project/circuits.js/src/contract/__snapshots__/contract_class.test.ts.snap @@ -9,18 +9,18 @@ exports[`ContractClass creates a contract class from a contract compilation arti "selector": { "value": 2381782501 }, - "bytecode": "0x1f8b08000000000000ffed9d77781447baee5b20e22001ced9c2f6ae033616424409189c73c6c618631002830d88689c713639384772cec1648c0163eccdd9bbeb0db677d71bce7dee73ef9fe79c7b8fefed9aa9efe8a5a81e3472d7f04a53fd3ca5a9fe54dddfafdefeba3a55771504e9e95f612ad0f9a661ba20387a92ff27f56fe9779b3ac7b8ae52979c050d84b34903e16cda40380b1b0867b306c2d9bc8170b668209c2d1b0867ab18390b80cf156feb06c69b6860bc6d828611b7450d84b3b88170b66d209ced1a0867fb06c2794203e13cb181709ed440384f6e209ca73410ce531b08e7690d84f3f406c2794603e13cb381709ed54038cf6e209ce73410ce731b08674903e1ecd04038cf6b209ce7c7c8d91138e55efef7f4eff7f5ef85faf722fd7bb1febd44ff76d4752cd4f39786e9b230750ad3e5c6ff9430ea867e5998ba18ff2b0f53d730750b5377fdbf12fdbf1e61ea19a65e61aa085365987a87a94f98fa6a3dfa85e98a305d19a6abc2747598ae09d3b561ba2e4cd787e98630dd18a69bc27473986e09d3ad61ba2d4cb787e98e30dd19a6bbc2d43f4c7787e91e83654098ee0dd3c030dd17a64161ba3f4c83c3f440988684696898aac2342c4cd5611a1ea611617a304c23c3342a4c0f85e9e1308d0ed398308d0d534d98c685697c98268469629826856972981e09d31443b347c3f458981e0fd31306e793617a2a4c4f87696a989e09d3b3617a2e4ccf87e98530bd18a697c2f47298a685697a9866846966986685697698e684696e98e685697e985e09d3ab617a2d4caf87e98d30bd19a6b7c2f47698de09d3bb9a457684f7c2f47e98168469619816856971989684696998968569799856846965985685697598d684696d98d685697d9836846963983685697398b684696b983e08d3b6306d0fd38e30ed0cd3ae30ed0ed39e30ed0dd38761da17a68fc2b43f4c07c274304c1f87e950983e09d3e1307d1aa6cfc2f48330fd304c3f3234ff71987e12a69f86e967daf673fdfb0b5d56f6f95feadf5fe9df5febdfdfe8dfcf8df2bf35e67f67ccff5eff7ea17fffa07fffa87fffa47fffac7fbfd4bf5fe9dfaff5ef5ff4ef5ff5efdff4ef37faf7effaf71ffaf79ffa573dff7bb5433adf32a89d92414c6d52f9f0a1eafebf886d3e5f54cfae9aeaffc96f89b617ea79f92dd0f6667abe99616faee79b1beb69a9e75b1af6623d5f6cd8dbe9f97686fd043d7f82613f49cf9f64d83be8f90e604fe8ffa52b96fe51b6a6da54003689cf26606ba66d4dc1d65c5607b616dad60c6cb27d9b83ad95b6b5005b6b6d6b09b684b6b5122dc3d446db92415cb1523a54adb728eef5ea6726c5f1f356a9f5b675c4db2e7ede616abded1df0aaf83841afab08e2e6446d2b06db49dad6166c276b5b3bb09da26dedc176aab69d00b6d3b4ed44b09dae6d2781ed0c6d3b196c676adb29603b4bdb4e05dbd9da761ad8ced1b6d3c176aeb69d01b6126d3b136cbac90dce02db79da7636d8ced7b673c07681b69d0b3639c72b019b9cef75009b9cfb9d0736390f3c5fdb54dbd1aa00fc69bbb45b297fd26683edfbd25e83ed4269abc17691b4d360bb187c8bed12686bc4d651dba4dd52ffeba5f3c920aefda42cb59f54c4bdde70cd6abdbde35f6feaf95d9fa056eb24f8a900adfaea7c8c7d5b3aa36f39b7113f622f84fc0d5056ca891e72ec1176752ca8d4f9be1996eb652c570c652a2df54f06f1d6bfb7c1d3db606e06793731dba5d4c76c9da7ac6376009435634fce831a63ccde0c1c0e62b6dcc76c9da7ac6376049435634fce851b63ccde071c0e62b6879b982d2bf5319bbe371604f6d893eba1c618b3a38023fe98edea63b6ee53d631fb1c9435634fae891b63cc4e018ef863b67b0f7f6e50e729eb989d0765cdd893fb338d31665f040e07313bccb7b3759eb28ed90550d68c3db957d81863f655e0883f667b3a8ad92e3e6683f473ce20b0c79edcb76e8c31bb1838e28fd961fefe6cdda7ac6376379435634f9ea134c698dda8f3ea39c3cff57386b3c0f60b6d3b1b78e38fedea3247b1ddd9c776baff4710d863549ee735c6d8fe48e7551cff0afa2388edd7d257016cbfd1b6f3c0f6b9b69d0ff572b00f74f7fb40ddeb94ed3ef047286bc6b23c5b6e8cfbc02f80c341ccf6f0315bf73a651bb3ff0665cdd8937e0e8d3166bf040e0731dbd3c76cddeb946dccfe3b943563ef229d6f8c31fb3f755e9d2f7ca1cf172e01db1fb4ad23d8fea86d9782ed4fda7619d8feac6d9dc0f6a5b65d0eb6afb4ad146c5f6b5b67b0fd45dbcac0f6576deb02b6bf695b39d8bed1b6ae60fbbbb67503db3fb4ad3bd8fea96d3dc0f62f6deba96daa9f9ef4bd3aac6d2d813f19c4bb6da5dfa5ac5be63be7c0775bc377db1cfa6e6ff86e6ff15de6c077027cc85460cc27215fe696a7b41878d05779fcbebaa8ba7709ea5ef772e0e9eaa0ee09f051179eaec0d32d7e9ed4f1b37bfceb4d6de32e86a609f0d505ead5c341bd0ac097ac5be6c55f31d8b06ded6161ec193f635901f89275cb7c4f60141bb6f5f22e95ec3fea787861412daf837d29754e24fee4db55c2510e76297371875ab68e9aad08fe8fc7bd6e86cd515ca6e2427cc9ba655efc15417dbae59eb1acae8c5d0d46576d4401f892757bdfb5db41f2781c7771ad636bd3c477450e7cf7347c971bbeb1ed9429d3b1ad2730c77ecda98f6d95f1afb714af4fe4da50fce0f9035ec3c55527f42dd786e247ec8590bfa5a0b6ac94133da41d167615cbb22d91dd5cae87b15c3194a9b0d43f19c45bff4a83a7d26056dbe44a38163ad81f5231506170c87c39685719a15d056827652e02ed5cb567bd0c1e99ef063cd28e75071e57d744513cb9b81e3b966f3c87c5eb67f93f9e07b8da5e9d0d4699b76daf9ec0683b5771703d93f15ca52b308aad17f07471a459d476ed42e2db41aca4da23f121e7e6b2ff7603bb94e9a95fa8536de543d056ba88118c4799ea7acd1bff762a4b5d8377cd8207b79d83ebaace8ee2b114efdf7c1bc41b6b66bbd4d5d02aea1e8fabb6bc8bc123f3e2cf337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993d333f333e4fc27e5b52ae1b09a3d9ffcdd57dfed4370cf5ba64fdeab9ceff71da1facac14fbc7483f884b8c3a174299a226b565ff1ff407339f53611fc96e6eb54b6d4bec8f998479f1877dad705b32f4772a89cd77fa5b942e9eb7a93ed6ea3b9a66dfcf6e164d5df47f464d0b0c4db13ffea5068f8ad3caa6b56c2e9efd65fb2c12b5927c9ccff68a037bacc7bf5dca8e7866dd2438b2fdc0e38cabfe3bd256cbf3f20ac377219439b349edb691be5532ce6c176339ecf723eb96652e017ba5b1ee767a59e16866acbf3b2c2b65ce8136f540935acd1cb49565d9f65dc7e7e6f11f87d3cff1bb64c1d319785cb4338ece378ef8de6adccff1cdfe69b6f31829837dfb1cf4abccd8df49fc7966cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367e667563ce6b3567cbfb69c8431477d1f52cf33e45b65b2fed4f7829bd4fa75fd1c4e9e397534ea8cef8efeef26b565b7ea7c5170747f87a86de9eafb1451db52fce1b767f059908be7ba05e04bd65d66d142f225b1f92e733636843cc7ef62e85a6ed1d4d5fe8acf585153dc5fbb1a3cf86c34eadb3e6586cd65dfa1a8b8107fb82f95814df2f87eb48bed8cc712b35f8ff8c3e7d73fd2dab60b5c6dfbb25297ed067e3725191c1ddff83d959f43dbf74b9dc73e1cd877e46bcbff65caf49c5af4537576f07dcdd20258976c5fdbb73dfb016b4cbe3be3ba0a74ea67685008f9af9ad49695725256b41676b58fc8376090dd5caeabb15c3194e963a97f3288b7fee6b756fb1acc6a9bfc06e2ec6b38febb6a93fa446874096824651c7fb3d1dabfd2ec5788ed6873a38c2c8bdfa2fb17b45151fd476dc700d7c73159b7ed38661e17ead2cf33dffb69fd07b41771f7d3fa0f8821eca71518ebef08eb17aee641f4b145cafc97b17ef39c5c96c17e60ffbd9fc0f75cca743e9b73f2e3757d653b27c7e5a2eaae98f13b68c9189931269005cf13a44c6badb56cb3ca08ee9e96658b229615adcc6f85150547ebe7e63b6be97dbeaf5117896bfc06b9943911eae2e6bc257d0ee8ea9b7249a893ca9759ea2a654e837ded0c9d4fc076c2fdf662cbff65ca740e8863b85f117f9d53dbf74ae04c821ff47d15b0c6e4bb33fa967340f123f642c85fd4b4b6ac94133d446b6157fb889c4721bbb95c85b15c3194e967a97f3288b7fe57183c5718cc6a9b9c0d717631f44377d556f78bd0a823682465f09ea2ed3ba0b67b1daededf883a97c2f797ccf32b3c4eba396fb29fc79af7d56ce7081d0d7e3c47e80eed6cc252d6bc5f28c7cb38fb0de3bb12ddc12fbe2be1eadbcdbd40b724cce379c1f1f4ede23bb6ca5fd49809bd72e03b6acc845cf86e6ff86e9f43df5e73af3993e60ec62048bd7f86df2c5553a6f3521c9740966b028c2ec6724804477e7bfc588c38be832cd714185d1c1fb2fdf679776094e50a81d1c5bba538fe465d18f11bc3789c174607df8aed5cdf6fc5e23dbde6c0c8f4ce263e9b6a018c2ece8bebfbae1e9ecfb7845f57e31275c982b10c1865b956c0e8e2de385ecbd48511af8b64b9d6c0e8e21956b6e33be1b7e7f1deb24bc64cc776c77d51cab2bdf752e99627e3b906fa7630ae614a0bbccf782c2d7abbe5c978ee83be1ddcf74b6981e30c1e4b0b7c36e862dcc34470e473b863f1e0f34b59ee04604c3a62ec9b05631218fffb5e3130f673c498cc82b11f308afd24607470ff35c5d82f0b46bc4f29cb9d0c8c573a62bc220bc62b8151963b05185ddc4b4d80dfba305e058cb2dca9c078b523c6abb260bc1a1865b9d380f11a478c5767c1780d30ca72a703e3b58e18afc982f15a6094e5ce00c6eb1c315e9b05e375c028cb9d098cd73b62bc2e0bc6eb8151963b0b186f70c4787d168c3700a32c773630dee888f1862c186f044659ee1c60bcc911e38d5930de048cb2dcb9c078b323c69bb260bc191865b91260bcc511e3cd5930de028cb25c0760bcd511e32d5930de0a8cb2dc79c0789b23c65bb360bc0d1865b9f381f176478cb765c1783b30ca721700e31d8e186fcf82f10e6094e5be078c773a62bc230bc63b815196fb3e30dee588f1ce2c18ef02c63b2d8cfd1d31de9505637f6094e52e05c6bbe3674c5d4bf7cf82f16ee0b9277e9e94667767c1738f5b9ed477f5eeb6f8ba377e5fa96d3120a87bddef059e81f1f3a4b6c5bd59f00843312c879add173f634ab3815930de073c83e2e74969765f163c8340b3fb2c9add1f3f634ab3415930de0f3c83e3e74969767f163c8341b3fb2d9a3d103f634ab3c159303e003c43e2e74969f640163c43825acd1eb06836347ec6946643b2601c0a3c55f1f3a4341b9a054f156836d4a2d9b0f819539a5565c1380c78aae3e74969362c0b9e6ad06c9845b3e1f133a634abce827138f08c889f27a5d9f02c78468066c32d9a3d183f634ab31159303e083c23e3e74969f660163c2341b3072d9a8d8a9f31a5d9c82c184701cf43f1f3a4341b9505cf43a0d9288b660f3b627c280bc6872d3c717f27fb218baf318eea3e3aa87bdd85a11896c37e12631d318ec982712c30ca72d84fa2c611e3d82c186b8051964b3866ccd44fa2067c8f8bdf77aa5daa09eaaecf38b73c19fb49a0eff18eb41817d45d8bf16e7932f69340df131c69313ea8bb16138067a2032d12e0a32e3cc2500ccb613f89498e182766c13809186539ec2731d911e3a42c182703a32c87fd241e71c438390bc647805196c37e12531c313e9205e3146094e5b09fc4a38e18a764c1f82830ca72d84fe231478c8f66c1f81830ca72d84fe271478c8f65c1f83830ca72d84fe209478c8f67c1f80430ca72d84fe249478c4f64c1f82430ca72d84fe229478c4f66c1f81430ca72d84fe269478c4f65c1f83430ca72d84f62aa23c6a7b3609c0a8cb21cf69378c611e3d42c189f0146590efb493ceb88f1992c189f054659ee61c78c99ae5f9e6de4bea3ae551abbefa8eb92c6eedbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ece997c3fe7c077027cc85460cc27212f0cc5b0dcc39eb15133224f497c3ca55877f4f53c41dd9fb7f01438aa3bfa7a81a0eec2d0d0189f6b008c0f370046af63ba0f627d1815cf8bf0ff648c3c2f64c1f322f0bce488e7c52c785e029e97e3e749c5d44b59f00843312cf77003607cae01307a1dbd8e4c8c5ec7fcd1d1337a46cfe8198f07634368c33d638388c7b2fa322a9e69f1f3a4347b390b9e69a0992c778f5bc6b2fa322a9ee9f1f3a4349b9605cf74d06c9a4533078c65f565543c33e2e74969363d0b9e19a0d9748b660e18cbeacba87866c6cf93d26c46163c3341b31916cd1c3096d59751f1cc8a9f27a5d9cc2c78668166332d9a39602cab2fa3e2991d3f4f4ab35959f0cc06cd66593473c058565f46c533277e9e9466b3b3e099039acdb668e680b1acbe8c8a676efc3c29cde664c13317349b63d1cc0163597d1915cfbcf879529acdcd82671e6836d7a2192be3c30d80f1b906c0e858c7b2fa322a9ef98e78e665c1331f785e71c4333f0b9e5780e7d5f8795231f54a163cc2500ccb3ddc00189f6b008c5e47af2313a3d7317f74f48c9ed13366c7f87c0360f4dbda33b2323ab8becaf80ecd2b8ddc77d43b348ddd77d43b348dddb78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9c33f97e2d7edf65d97e63e635e071f1cd1b47f52c55eb7d5dafebdb18f5535abd6168f58aa1553194791df47bc3817e05e057d62df3e22f5be60b09981df92e53ed4b2ba8bff878ced043f97fd351dda3dafa371bb9efa8b6beb1fb8e6aeb1bbb6f1fe73ecef3c1b78f731fe7f9e0dbc7b98f7316df986f16d49eb7cbf74fd53aded2f9423d2fe59f07bb9499d822fddb2ef0fb900bdf7e1ff2c78a7cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f73be382f86ff57e680273078820c3cf3c8782693f1cc24e31949c633888ce756329e2bc9789e24e32927e31947c6338c8ce76e329e1bc8782e27e3e943c633858ca72719cf2c329e87c8785e22e3194cc6733b19cfd5643c4f93f19491f14c20e3194ec6732f19cf4d643c49329ec7c878ba93f15c4cc633868c673619cf45643c43c8785e26e3b9938ca7988ca72d19cfb5643c2f90f15c46c65341c6f30c19cf5c329e49643c0f92f1dc47c6534ac6730b194f27329e2bc8789e20e3e94ac633878ca7868c671a194f15194f7f329e4bc878ae27e3694ac6d39b8c673e19cf23643cbdc8784691f17424e3b99f8ce736329eabc8789e22e3e942c6339e8c673a194f3519cf00329e1bc978fa92f13c4ac6d3838c673419cf85643c0f90f1dc41c6938bef9966c3d3868ca7888ce71a329e67c978a692f17426e39948c633838c670419cf40329e9bc978fa91f13c4ec6d38d8c672c19cf50329ebbc8785e24e36947c6d39e8ce73a329e02029e4470f4182609f8ff6b606b622cab3efb3aba43edffdfd6f626b0cc3b3adfd4b2eeb7c126df927dc7b22ceaf436d425a9f3a5df6d4ae984be92302ffe8a80e31d129eebc878da93f1b423e379918ce72e329ea1643c63c978ba91f13c4ec6d38f8ce766329e81643c23c8786690f14c24e3e94cc633958ce759329e6bc8788ac878da90f1bc46c6730719cf03643c1792f18c26e3e941c6f328194f5f329e1bc9780690f15493f14c27e3194fc6d3858ce729329eabc8786e23e3b99f8ca72319cf28329e5e643c8f90f1cc27e3e94dc6d3948ce77a329e4bc878fa93f15491f14c23e3a921e39943c6d3958ce709329e2bc8783a91f1dc42c6534ac6731f19cf83643c93c878e692f13c43c65341c6731919cf0b643cd792f1b425e32926e3b9938ce765329e21643c1791f1cc26e31943c67331194f77329ec7c87892643c3791f1dc4bc6339c8c6702194f1919cfd3643c5793f1dc4ec633988ce725329e87c8786691f1f424e39942c6d3878ce772329e1bc878ee26e31946c6338e8ca79c8ce749329e2bc9786e25e31944c633928c672619cf64329e79643c95169ed71cf1c8fbeeb26e997f8dc4b783ed50aad6fbaea33abda7d7d54caf57f8c55f219499da3afdabde0fc76585cbfc3e01be9bf31e68f49ea3bac8f62830b60ffa7ecb916f79474bd62df36f3572df6d0ddf6df3c4777bc377fb3cf1ede3dcc7793ef8f671eee33c1f7cfb38f771cee4dbc1b541197e274da602633e0979bc5e70f17d3947f53ce23af1db18f5535abd6f68655e5b1543997741bff71de867bbf69479f1972df38504cc18172541bc71b120fe3a95a976ab15e8bac0d017ebb5d091a651c790858ddc77d431a4b1fb8e3a863476df3ece7d9ce7836f1fe73ecef3c1b78f731fe74cbe17e97c8cd78da5e8433d5f94eb8145e07789ce17c4e857ad6bb15e57a15eb7702c01bb94f94f78aee9f779bfcfc7e5db1fdb7c9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8668e73332ffdc52f023657fdf9a3623117ef121c4fdf51b1d8d87d47c56263f7ede3dcc73993efa50e7c27c0874c99faf82d059ec50e781cd533f56c639951a7d78c3a1543193cc62f7350cf02f02beb96f965c0235325f0b88883ba6c73e49947c633998c672619cf48329e41643cb792f15c49c6f324194f3919cf38329e61643c7793f1dc40c67339194f1f329e29643c3dc9786691f13c44c6f31219cf60329edbc978ae26e3799a8ca78c8c670219cf70329e7bc9786e22e34992f13c46c6d39d8ce762329e31643cb3c9788690f1bc4cc67327194f31194f5b329e6bc9785e20e3b98c8ca7828ce719329eb9643c93c8781e24e3b98f8ca7948c672119cf2d643c9dc878ae20e379828ca72b19cf1c329e1a329e69643c55643cfdc9782e21e3b99e8ca729194f6f329ef9643c8f90f1f422e31945c6d3918ce77e329edbc878ae22e3798a8ca70b19cf78329ee9643cd5643c03c878de27e3b9918ca72f19cfa3643c3dc8784693f15c48c6f30019cf1d643c6dc8788ac878ae21e379968c672a194f67329e89643c33c8784690f10c24e3b9998ca71f19cfe3643cddc878c692f10c25e3b98b8ce745329e76643cedc978ae23e32920e0490447bffb9f80ffbf0f367947fd35b02dd7f9c5606b62f1d154e79781ad50e7651d2dc234a5c3d1eb469d5cbd978fbe92302ffe8a80633909cf75643cedc978da91f1bc48c6731719cf50329eb1643cddc8781e27e3e947c6733319cf40329e11643c33c8782692f17426e3994ac6f32c19cf35643c45643c6dc878ee20e379808ce742329ed1643c3dc8781e25e3e94bc6732319cffb643c03c878aac978a693f18c27e3e942c6f31419cf55643cb791f1dc4fc6d3918c6714194f2f329e47c878e693f1f426e3694ac6733d19cf25643cfdc978aac878a691f1d490f1cc21e3e94ac6f30419cf15643c9dc8786e21e35948c6534ac6731f19cf83643c93c878e692f13c43c65341c6731919cf0b643cd792f1b425e32926e3b9938ce765329e21643cb3c978c690f15c4cc6d39d8ce731329e2419cf4d643cf792f10c27e39940c65346c6f33419cfd5643cb793f10c26e379898ce721329e59643c3dc978a690f1f421e3b99c8ce706329ebbc9788691f18c23e32927e379928ce74a329e5bc9780691f18c24e39949c633998c671e194f658e78d4bbedd2d73a002e9c92905f063c0b1df038aa67297ed7e0db18d7abb45a6168f5bea1553194590afaad70a05f01f89575cbfc0ae07956e76ddf54789684516c0b1df324a0ce3265da0756008f8b7dd2513d53b1bad2a8d3b316dda50cc6ea4a07f5b4ed3b32bf12785ed079614d40b9174818c5b6cc314f02ea2c53a6585d093c2ef61d47f54cc5ea2aa34e2f5874973218abab1cd4d3b6efc8fc2ae07951e7853501e55e246114db0ab73ce509a8b34c99627515f0b8d8771cd53315abab8d3abd68d15dca60acae76504fdbbe23f3ab613b7866cf6c63563c72ff5e581350ee251246b1ad74ca535e9a803acb94a91d5b0d3c2eda7947baa7dab135469d5eb2e82e653056d738a8a76ddf91f93516df2541bc5aacad83166b2d3c6b73ac85f8cb9679690364f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e6266d059f1c8f709853501e55e266114db2ab73ca9f7825e0e8e9c0a8cf924e4d702cf6a07fa38aa67aa0ff93aa34e2f5b749732b87fad73504fdbbe23f3eb603b64c3bca601327b9debc7ac78a6e9bcb026a0dc341246b1ad76cb936ac7a605474e99dab175c0e3a29d7754cf543bb6dea8d3348bee5206f7aff50eea69db77647e3d6c07cfec996dcc8a67bace0b6b02ca4d276114db5aa73c65a9f71ba707474e99dab1f5c0e3a29d77a47baa1ddb60d469ba45772983b1bac1413d6dfb8ecc6f80ed900df39a06c8ec75f63a47317b9dbdce51cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9dbdce51cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9df34767c53343e7853501e56690308a6d9d539e2ea9e70e338223a74ccf1d36008f8be7328e744f3d77d868d4698645772983fbd74607f5b4ed3b32bf11b64363675ed300997d6ce486d9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a398196243f1ccd479614d40b999248c625bef9627f5dd8399c19153a67e3b1b816783037d1cd533d56f679351a79916dda50cee5f9b1cd4d3b6efc8fc26d80e9ed933db9815cf2c9d17d604949b45c228b60d6e7952edd8ace0c829533bb609785cb4f38eea996ac7361b759a65d15dca60ac6e76504fdbbe23f39b613b7866cf6c63563cb3755e5813506e3609a3d836bae549b563b38323a74cedd866e071d1ce3baa67aa1ddb62d469b645772983b1bac5413d6dfb8ecc6f81ede0993db38d59f1ccd179614d40b939248c62dbe4982701759629533bb605785cb4f38eea996ac7b61a759a63d15dca60ac6e75504fdbbe23f35b8167aece0b6b02cacd256114db66c73c09a8b34c9962752bf0b8d8771cd53315ab1f18759a6bd15dca60ac7ee0a09eb67d47e63f009e793a2fac0928378f84516c5b1cf324a0ce32658ad50f80c7c5bee3a89ea958dd66d4699e45772983b1bacd413d6dfb8ecc6f039ef93a2fac0928379f84516cd88ecd77c45364f01459b4385ebe9516153adf46ff26e0ff15c0e8aa6d996f30ca3cc6b8d88a72a0595b83a7ada1d9f1f4adb4a884bc9a707b550223c3f66a9b03cdda1b3ced0dcd8ea76fa5456f9d6fa77f717bf5064686edd51e781cb4cfe50983474d998edddb1cebe3a89ea963f7f6c0ae3b1e87a40c1ebbb73ba8a7ed5c42e6b7c376f0cc9ed9c6ac78faebbcb026a05c7f1246b1e139ff8ef879ca13068f9a32b5633b1cebe3a89ea9766c6760d77d07e82e653056773aa86701f89575cbfc4ed80ed930af6980cc5ee7fa312b9e013a2fac0928378084516cdb816757fc3ce50983474d99dab15d8ef57154cf543bb63bb0ebbe0b749732b87fed7650cf02f02beb96f9ddb01db2615ed30099bdcef563563c03755e5813506e2009a3d87602cf9ed879d263be208f9a32b5637b1cebe3a69ee9766c6f60d77d0fe82e6570ffdaeba09e05e057d62df37b613b7866cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367e666563c83745e5813506e1009a3d87603cf87b1f3a49f3b208f9a323d77f8d0b13e6eea997eeeb02fb0ebfe21e82e653056f739a86701f89575cbfc3ed80e9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec99b99915cf609d17d604941b4cc228b6bdc0f351fc3ce50983474d999e3b7ce4581f47f54c3d77d81fd875ff0874973218abfb1dd4b300fccaba657e3f6c87fd9ed9335b9815cf109d17d604941b42c228b67dc07320769ef4f353e45153a676ec80637ddcd433dd8e1d0cecba1f00dda50cc6ea4107f52c00bfb26e993f08db211be6350d90d9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63ae78fce8aa74ae7853501e5aa4818c5b61f783e8e9da74b69c2e0515381319f84fcc78ef57153cff4738743815df78f41772983fbd72107f52c00bfb26e993f04dba1b133af6980cc3e3672c3ec63c3334731fbd8f0cc51cc3e363c7314b38f0dcf1cc5ec63c3334731fbd8f0cc51cc3e363c7314b38f0dcf1cc5ec63c3334731fbd8f0cc51cc3e363c7314b38f0dcf1cc5ec63c3334731fbd8f0cc51cc0cb1a178aa755e581350ae9a84516c0781e793f879ca13068f9a0a8cf924e43f71ac8fa37aa6faed1c0eecba7f02ba4b19dcbf0e3ba86701f89575cbfc61d80e9ed933db9815cf089d17d604941b41c228b643c0f3a9039e84c1a3a64cedd8a78ef57154cf543bf65960d7fd53d05dca60ac7ee6a09e05e057d62df39f01cf489d17d604941b49c228b6c3c0e32256154f91c123f39f12f8565ad4e87c1bfd8bdbab061819b657510e346b6bf0b435343b9ebe9516e320af26dc5ee38091617bb5cd8166ed0d9ef68666c7d3b7d262bcceb7d3bfb8bdc60323c3f66a9f03cd8e677b783cf7ede319a75ef3e3a779c171d4bce0386a5ee035a7d2dcc1f1a50c8f650130e09484fc67c0f3c3f87952f7b83ecb82e787c0f383f8793a3baa67a95aef8f803daef52aad7e6c68f599a155319441861f3bd0af00fccaba655efc7966cf1cc58ce7b6c29a80729f92308aed07c0e3a2dd5075bf4caf4bd6df2c4cfb4eaaf5ebe2d903de776da6d72b1ce2af10cadc5e525bf6a0662b82ffcb7653f53964d81cbd0fdcd9f60c4ce6c55f5190bbfba099eecba2162e9edd647bdc3f64e1f9363e9e52dccfd1d7414775cfe639da410b4f8c75ef1cf50cf140fc754fb51f9df4ba64fd6a1ffdfc24a79a97e3be27ed4727a3ce8550e6b292dab25f40fb616b2b5cef9b724e6eee9b4d82daf64cb84ab4dd7cbef2adb64bb94fa03cb63915fa17f7cf0aa8abab7631ea1e13b68b66dbed527bf3199fe9bb1874f9845433db730ad4b1d2c25d49c08df198cbfd4cd66d7b465669e8c8a6196eeb4f2c3af6b670f726e066dcaf7b1b3ab26976acfdbabf85bb3f0137e37edddfd0914db363edd7032cdc0308b819f7eb01868e6c9a1d6bbf1e68e11e48c0cdb85f0f347464d3ec58fbf5200bf720026ec6fd7a90a1239b66c7daaf075bb807137033eed7830d1dd9343bd67e3dc4c23d84809b71bf1e121ca9239b66c7daafab2cdc5504dc8cfb7595a1239b66c7daafab2ddcd504dc8cfb75b5a1239b66c7daaf4758b847107033eed7230c1dd9343bd67e3dd2c23d92809b71bfae6bbf7dd6fdbac6c25d43c0cdb85fd7183ab26976acfd7a9c857b1c0137e37e3dced0914db363edd7e32ddce309b819f7ebf1868e6c9ad9f66b47efe59565fb9ee061a7faa4c76b3e9c05cfc7c0e322a61cc541a9a37e2ea9bea9070cad0e1b5ae1381807413f077d6132bedf2ffe3cb367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed933f333e3370ef1f98a94fb8484516cf84ccac57d7e55f7cbf5ba64fdcdc2d4f9945abf0763f75b565a60f84b0287f82b8432ff794e6dd9ae9aad28387abbe1b8d6b82df7c75e87f4b634e35fe6c55f11d4e700f038783f3fc573d0e03968d102df3b8dc777d930371a9795aaefefb40a6ab7f37ea33ea8e947b1fb3f52d30243d38f1cfb4e04476e4f61c0290979e471f16cd8513d536dc13ea34ea6c6c550e642a8e73e07f52c00bfb26e99df073c3235011e573118183c81451f992ac9782693f18c24e3b9808c671019cf69643cb792f1b422e3b9928ce749329e72329e71643cc3c878ce25e3b99b8ce744329e1bc8782e27e32924e3e943c633858ca72719cf43643cdf27e3194cc6732919cf19643cb793f124c878ae26e3799a8ca78c8c670219cf70329e0e643cf792f19c4cc67313194f73329e2419cf63643cddc9782e26e31943c6731119cf10329eb3c878ee24e32926e3694bc6732d19cf33643c15643c9791f14c22e379908ce77c329efbc8784ac9784e25e3b9858ca71319cf15643c2dc9789e20e3e94ac65343c65345c6730e194f7f329e4bc8784e20e3b99e8ca729194f6f329e47c8787a91f18c22e3e948c6f33d329efbc9784e27e3b98d8ca73519cf55643c07c8789e22e3e942c6339e8ca79a8ce710194f0919cf00329e93c8786e24e36946c6d3978ce751329e1e643ca3c9782e24e379808ce74c329e3bc878da90f11491f15c43c633958ca73319cf44329e11643ce791f10c24e339858ce766329e16643cfdc8781e27e3e946c633968c672819cfd9643c7791f1b423e3694fc6731d194f01014f2238fa5b4c09f8ff41b0c937833e065b13cbfae439b59457c7c5673b1cbdee2696757f6461409d3e84ba2475bef4bb4d299dd05712e6c55f11707c44c2731d194f7b329e76643c7791f19c4dc633948c672c194f37329ec7c978fa91f1b420e3b9998ce714329e81643ce791f18c20e39948c6d3998c672a19cf35643c45643c6dc878ee20e339938ce701329e0bc9784693f1f420e379948ca72f194f33329e1bc9784e22e31940c65342c673888ca79a8c673c194f17329ea7c8780e90f15c45c6d39a8ce736329ed3c978ee27e3f91e194f47329e51643cbdc8781e21e3e94dc6d3948ce77a329e13c8782e21e3e94fc6730e194f15194f0d194f57329e27c8785a92f15c41c6d3898ce716329e53c9784ac978ee23e3399f8ce741329e49643c9791f15490f13c43c6732d194f5b329e62329e3bc978ce22e31942c6731119cf18329e8bc978ba93f13c46c69324e3694ec6731319cfc9643cf792f17420e3194ec633818ca78c8ce769329eabc97812643cb793f19c41c6732919cf60329eef93f13c44c6d3938c670a194f1f329e42329ecbc9786e20e339918ce76e329e73c9788691f18c23e32927e379928ce74a329e56643cb792f19c46c633888ce702329e91643c93c9782ac9789a183cf87ff56ed8019d976f0715c2ffefd69dcbdbe97549197946acee55ec356caabe7b1cd5776f503b25617e0fd457d8f702cf5e473c1f1a3ca6ef22c8578266bb0d9b62dce58871b7c128f3bb8051f4db0d3cbb1df1ec31784cdf4590ef0d9aed346c8a718723c69d06a3ccef0046d16f27f0ec74c4b3cbe0317d1741be3f68b6ddb029c66d8e18b71b8c32bf0d1845bfedc0b3dd11cf0e83c7f45d04f901a0d907864d316e75c4f881c128f35b8151f4fb00783e70c4b3cde0317d17417e2068b6c5b029c6cd8e18b7188c32bf191845bf2dc0b3c511cf5683c7f45d04f941a0d926c3a618373a62dc6430cafc466014fd3601cf26473c9b0d1ed37711e40783661b0c9b625cef887183c128f3eb8151f4db003c1b1cf16c34784cdf45901f029aad336c8a71ad23c67506a3ccaf0546d16f1df0ac73c4b3dee0317d1741be0a345b63d814e36a478c6b0c46995f0d8ca2df1ae059e38867adc163fa2e827c3568b6cab029c6958e1857198c32bf121845bf55c0b3ca11cf6a83c7f45d04f911a0d90ac3a618973b625c6130cafc726014fd5600cf0a473c2b0d1ed37711e4478266cb0c9b625cea887199c128f34b8151f45b063ccb1cf12c37784cdf4590af01cd961836c5b8d811e3128351e61703a3e8b704789638e2596af098be8b203f0e345b64d814e342478c8b0c46995f088ca2df22e059e48867b1c163fa2e82fc78d06c8161538cef3b625c6030cafcfbc028fa2d009e058e78161a3ca6ef22c8df0936e1ed05b6f774be27d8ded5f91e607b47e7bb83ed6d9def06b6b774be2bd8ded4f972b0bda1f35dc0f6bace9781ed359def0cb65775be0fd85ed1f9be609baff349b0cdd3f97e609babf357806d8ece5f09b6d93a7f15d866e9fcd5609ba9f3d7806d86ce5f0bb6e93a7f1dd8a6e9fcf5607b59e76f00db4b3a7f23d85ed4f99bc0f682cedf0cb6e775fe16b03da7f3b782ed599dbf0d6c0febfced60bb47e7ef00db619dbf0b6c9feafcdd60fb4ce7ef05db0f74fe3eb0fd50e7ef07db8f74fe01b0fd58e78782ed273a3f0c6c3fd5f9e160fb99ce3f08b69febfc28b0fd42e71f02db2f757e34d87ea5f363c0f66b9d1f0bb6dfe8fc04b07daef313c1f65b9d9f04b6dfe9fc64b0fd5ee71f01db173a3f056c7fd0f947c1f6479d7f0c6c7fd2f9c7c1f6679d7f026c5feafc9360fb4ae79f02dbd73aff34d8fea2f353c1f6579d7f066c7fd37969d7543bfb779d2f09e26d67bf096aa712f02dfe54997fe87c73a38c2c5b08655aeb0e85ea19877a7749da616997954ddae1f7c026edf0bb609376f81db0493bfc36d8a41d7e0b6cd20ebf09366987df009bb4c3af834ddae1d7c026edf0ab609376f815b025757e3ed8a41d9e07366987e7824ddae1396093767836d8a41d9e0536698767824ddae119609376783ad8a41d9e063669875f069bb4c32f814ddae117c126edf00b609376f879b0493bfc1cd8a41d7e166cd20e3f0c366987ef019bec2fdf804ddae6c36093b6f953b049dbfc19d8a46dfe01d8a46dfe21d8a46dfe11d8a46dfe31d8a46dfe09d8a46dfe29d8a46dfe19d8a46dfe39d8a46dfe05d8a46dfe25d8a46dfe15d8c6eafcafc1266df36fc0266df3e76093b6f9b76093b6f9776093b6f9f76093b6f90bb049dbfc07b049dbfc47b049dbfc27b049dbfc67b049dbfc25d8a46dfe0a6cd2367f0d36699bff02b667745edaea96609367c56a2afd8e138ec3d3047c094b3288b7edc7290979acbb4c95643cb3c8784692f1bc45c6730119cf20329ed3c8785a91f12c20e31947c6339f8c671919cf52329ef7c978ce25e3d944c6b3918ce744329ebd643c7bc8782e27e32924e39941c6f306198fbcf7c9c233988ce752329e33c87812643c73c9789690f12c26e379978ca70319cf06329ef5643c2793f1ec26e3d945c6d39c8ce71b329e69643c1793f1bc46c6731119cf10329eb3c8788ac978da92f15490f15c46c6339b8c671119cf42329eb7c978ce27e35947c6b3968ca7948ce754329e9d643c3bc8783a91f1b424e379898ca7868ce715329e2a329e73c878fa93f15c42c67302194f53329ede643cf790f1cc24e379938ca72319cff7c878d690f1ac26e3f92b19cfe9643cdbc978b691f1b426e33940c6339e8c671e194f3519cf7b643c87c8784ac8780690f19c44c6d38c8ce73019cf74329ed7c9785691f1ac24e339938ce703329ead643c6dc8788ac878e690f18c20e379878ce73c329e81643ca790f1b420e379998ce755329e15643ccbc978ce26e3d942c6b3998ca71d194f7b329e7d643c1f92f11410f0248023009bfcbf29d8e43b3c87c0f6b5ce1f009b7cc36701d8bed2f967c0f694c5d6c4c2270c53c126efca7e0d36b93ff334d8e49d89afc026e70de25fcd4fef70347f135846fc34b5f0a3bfaf2c5c92c7ed2dcb248378b737fa4a06f66fde15188cc79be743329e7d643cedc978da91f16c26e3d942c6733619cf72329e15643caf92f1bc4cc6d3828ce714329e81643ce791f1bc43c633828c670e194f11194f1b329ead643c1f90f19c49c6b3928c671519cfeb643cd3c9780e93f13423e339898c6700194f0919cf21329ef7c878aac978e691f18c27e33940c6d39a8c671b19cf76329ed3c978fe4ac6b39a8c670d19cff7c8783a92f1bc49c633938ce71e329ede643c4dc9784e20e3b9848ca73f19cf39643c55643caf90f1d490f1bc44c6d3928ca71319cf0e329e9d643ca792f19492f1ac25e35947c6733e19cfdb643c0bc9781691f1cc26e3b98c8ca7828ca72d194f3119cf59643c43c8782e22e3798d8ce762329e69643cdf90f13427e3d945c6b39b8ce764329ef5643c1bc8783a90f1bc4bc6b3988c670919cf5c329e0419cf19643c9792f10c26e3f93e19cf1b643c33c8780ac9782e27e3d943c6b3978ce744329e8d643c9bc878ce25e3799f8c672919cf32329ef9643ce3c8781690f1b422e3398d8c671019cf05643c6f91f18c24e39945c65349c6d3c4c273c8118f7c2b46d62df3871ab9ef3d86ef3d79e27b97e17b579ef8de61f8de9127beb719beb7e589efad86efad79e27bb3e17b739ef8de68f8de9827bed71bbed7e789efb586efb579e27bb5e17b759ef85e69f85e9927be971bbe97e789efa586efa579e27bb1e17b719ef85e68f85e9827be99afbf553f5ce9abbc4fff26e0ff15c0b8c011e3218351e61700a3d8f07bd4158e78a2aedd2b087c2b2de45e963cf34cc0ff2b81d1554c55188c326f8ba93dc053e98827ea9e4325816fa585bc8b2d7d2a13f07f1c7fd9554c551a8c326f8ba95dc0d3db114fd4bd92de04be9516f2eeb3bcf39780ffe378ebae62aab7c128f3b698da013cfd1df144dde3e94fe05b6921df0a936fd224e0ff383ea3ab98ea6f30cabc2da670fcdc018e78a2ee4d0d20f0adb4906fedca372f13f07f1cbfc9554c0d301865de1653387edc40473c51f7d40612f8565ac8b360f9467b02fe3f08185dc5d4408351e66d3185e3dd0c72c413752f7010816fa5c5609d973e5609f8ff6060741553830c4699b7c5d446e019ec8827ea1ee66002df4a8b213a2fef7024e0ff4380d1554c0d361865de1653eb816788239ea87baf43087c2b2daa745edee94fc0ffab80d1554c0d311865de16536b81a7ca114fd43de32a02df4a8b6a9d976fce25e0ff38fefb10478c5506a3cc0f0146b1ad069e6a473c51f7baab097c2b2de4dbfeabf46f02fe8fe3b1ba8aa96a8351e66d3185e3418f70c413758f7e04816fa5c5489d97316112f0ff91c0e82aa646188c326f8b291cbf72a4239ea8670b23097c2b2de4db5ccbf46f02fe5f038cae626aa4c128f3b6985a0a3c358e78161b3c8b2d5a1c2fdf4a0be9cbbd44ff26e0ffe380d1554cd5188c326f8ba9c5c033ce114fd4b39c7104be9516f26ded45fa3701ff1f0f8cae626a9cc128f3b6985a083ce31df1443d831a9f03df51cf5372e13bead9402e7c47dde7ce85efa87bb6b9f01d75ff3117bea3eea5e5c277d47da15cf88ebac7910bdf51d7ebb9f01d75ed990bdf51d751b9f01d754d900bdf51e7b7b9f01d75ae960bdf51e71dbe3df7ed79dcbe8fe7b943beb6e7c7f3187a3c8f25fedac05f1be4cab73f96f86b835cf9ced76b03df9ee7be3d97ebaf8220fa7a6cb923df4b0ddf328fcf59963af2bdd8f02df3f8cc60b123df0b0ddf328ff7bf173af25d64f896f98539f0ddd6f0dd3687bedb1bbedb5b7cbbd8de89e0c8eb6f61c02909798c81450e781cd5b354ad77895ed7b731aed776dfc6dc5f8aa1cc12d0cf75db21ebced476b48ccf7769027cc837be944d9ec5be07366943df059b3c637f076cd2cebf0d3679bef316d8e4f9cf9b601ba9f387c126cf61b1ffbb3c4bdf01b62a9dc77ed743747e1bd8a45f12f6f795be655bc126fd03b19fa9f4f1dc0c36e9a78bfd1ba5aff546b0497f79ec5727ef3cac079bbcb782fdb9e4dda3b5603ba0f3d88f48bee9b21a6c53757e15d8fea2f32bc1f6a4cedf03b62f75fe1bb0fd59e71782ed099d5f04b63fe9fc12b03daef36f80ed8f3aff3ad81ed3f9d7c0f6a8cee37b617fd0f90fc1f685cee3fb4853747e0fd87eaff3f81ecc233abf0b6cbfd3f957c13659e75f01db249d9f0fb6dfeafc3cb07daef373c13651e7e780ed373a3f1b6c13747e16d87eadf333c13656e76780ed573a3f1d6c63747e1ad846ebfccb60fba5cebf04b65fe8fc5fc1f690ce2f065b139d5f0a36197f11fb7c14eafc72b0c9b8f4d89747be953f1e6c2d747e1cd85aea7c0dd8e43b6b23c126632b8f005b42e7abc1d646e7abc026e73a43c02663890c069b9c970c025b3b9d1f08363987180036191bb23fd8e47b9ebdc17692ce57824dbe535f01b65374fe10d864fcae0560936fc01d009b8c6bfc34d8e4dbcf53c176a6ceff056c32a6c993603b5be7bf04db393aff67b0c9f7309f005b89ceff096c1d74fe71b09da7f37f049b8c37f518d82ed0f947c126e3f0fe016cf2ede42fc076a1ce4f01db453aff7bb0c9b81c8f804dc6dafc1dd83aeafc64b0c937ad2781ed329dff2dd864ecbccfc126dfeb9d08361923ed3760ebacf313c056a6f3bf065b179d1f0bb6729dff15d8baeafc18b075d3f9d160ebaef3bf045b0f9dff05d87aeabcb4336a7f56fbf9413d9f0ce23dcffe383872ca749e2d0cc813e7796b31f0a0affdb1d7bd2c758e2cfb7d13bd5e89a1fde07b5fecbed3e7e71fe97515eaf5ee337c17429996ba7150cbc931bfa95eee80b11cde139275cb329783fd4363dded747d3f7254df7d069370a30e52a68d6652c7c68d3adf12968991ad4ced03126b0168885312f2c2e046abb2523cefad0bcf47c0b33f769ef4b5af8b98c07d2bee6b5ff39ea8196bc550661fe8f7a103fd705f9775cbbcf8f3cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfcccfac780eea3c3e579672074918c5b61f785cdce7c7e7b0b27ef55ce7fd736bfdee8fddef91cff79ae9f5961a752e84327f86674e8b75be08fe2fdb2d6a5b3a784e98715b8abf22a80f3e0b3ae88867bfc1b3dfa285e44b62f35d36cc8dc665a5aadf8a7ac67ec0d0f5a0455357fbeb7ebdae024353dc5f3f3678f0d96811f07ea27f13b09e4fa00e0ef6f18c7121fe705fda0f36c97f0c8c2eb6331e4ba43d90e7e1f86c5acaec329e8bc7bfedcb4a5db61b7ba14ec9e0e8f82e8432fba0eddbaff3d837e420e8f633cbff65caf49c5af45375de1d7f9d53db77177026c10ffade09ac31f93ee27d94029dc48fd80b21ff53e8cf21e5440fd15ad871ec6f643797fbd858ae18caecb1d43f19c45bffdd06cf6e83596d938f21ce7e06c77f576dd29e088d2e078da4cc7ed0e880239efd068f70883f5546b67f73a38c2c5b08657e0b6d94aa8bb4f3524fecdb82c70057c731f125eb9679dbb9f147c068d651c547e7536a79f7c7cedbb0fa7ffd03da8bb8fb7ffd0362a800380263fda5b07ee16a1e441f5ba4ccff308ea32eae31705b9a7aa2ce52e67f413bf4fd92743e9b73fde375dd1675aebfc7014f2238f2da5b4d998eef788cd9eb80c7513d4b6dc7ae0f8d3a1543990ba19e0ece6332be57bb1b7cbbd8e6a8859c43ed33b42884320525e95f693ba274c46bd58f72529732ebf960a9a52e52a645496d5d5a823d4e2697db6d27d449ad77bfa5ae52a64d49ad2ec53a9f80ed84f74dceb6fc5fa64ced018e6bb33dfe3aa7b6ef36e04c821ff4fd01b0c6e4fb88ef6ac8f9bef8117b21e4cf2aa92d2be5440fd15ad8d53e22effc21bbb9dc3e63b96228b3c352ff64106ffdb71b3cdb0d66b54dda97d4e6258e5cb69b3b22342a058da40cde3f96633bbe77673beeef77c41d75dcdf0f8c66bb89e72e2ed90e186ce63d54dbf9a094c1733229d3b124fdabdad984a56cb3e0c87bc32eee63e23ba801d42330ea2a13c680836bc372bc7692764afc7402fb7e9d179d3b19da154299ae25e95f87e7ddd67b97e6f51d5e5308b7b96fe1bb1fbd4a6ab9711cc2fdfab7086c9fea5f47d769e5b67b86c261bb67982ca965c76585ebb0a52ee6357293e0e87beadf1a65f1be5ba6e5ccbc39a6a3d2f753a39ccd0f5ef3c4f6ae46e7d252646a12d8ef177c6cb01704478f5f29fb01c69c791fa593b11ebc8f726b49fa57da24b3acdaf69f9f54ab8f6c47d10edb138cc98f8131a9f3a5df6dea6cabbfcc8b3fc5f8895107376d57fa7da56cee031f001e176dbba336ba148fb1f17d9fa26795edf8ffb1a1550e9fd75a8ff9e633f796463e1edf65d5b6fb4f362df659785c3d4789d2629fc5777c5a741b663b7ed8b4c865df87282d3eb4f88e518b1178df3393167b2d3c2eee4565d262afc5777c5a742fcdf45c03b5d863e17175ef214a0bf1972df38704cc2d8d7c3cbecbab6cf7c96c5aecb6f0b8ba6e8ed262b7c5777c5a74ee86f7e83269b1cbc213fffdb9cc5aecb2f88e4f8b1e3df11e5e262d765a785c3dd38dd262a7c5778c7131dc762fc7a6c50e0bcf8e1c6bb1c3e23bc6f3c36eb67b6d362db65b781cdc77cda8c5768bef18b5188af75d3369b1cdc2b32dc75a6cb3f88e4f8baaaeb67bc2362d3eb0f0b8ba271ca5c50716dff16931b487f2bdb50e5a6cb5f06ccdb1165b2dbe63bc864ac5c5963a68b1c5c2b325c75a6cb1f88e4f8bead4b9d6e63a68b1d9c2b339c75a6cb6f88e4f8bd2d43175531db4d864e1d994632d36597cc71817a9ebc98d75d062a38567638eb5d868f11de3712415171beaa0c5060bcf861c6bb1c1e23b3e2d46a4ee3fadaf8316eb2d3ceb73acc57a8bef18efb9a4e2625d1db45867e15997632dd6597cc7a74597d431756d1db4586be1599b632dd65a7cc7a7c5f0d433b13575d0628d85674d8eb55863f11de37967aabd585d072d565b7856e7588bd516df319e77a6ee5facaa8316ab2c3cab72acc52a8bef18dbced479e7ca3a68b1d2c2b332c75aacb4f88ef1bc33a5c58a3a68b1c2c2b322c75aacb0f88ef1bc33751c595e072d965b7896e7588be516df31c645aaed5c56072d96597896e5588b6516df31ded74ab59d4beba0c5520b8fabf11aa2b4586af11de3f548ea1edf923a68b1c4c2b324c75a2cb1f88ef15951ea1c7c711db4586ce1599c632d1683ef03b1fb4ef7e7161fd217eb32438b4228f36d49fa57fa6245e928ebc07e65589745b1d725ddaf6c61445d16415da44c6187dabab40c9c8cf753eea8aea99859007552ebfdc4525729d3aa43ad2e099d4fc036390cba9d61f9bf4c05c67c12f2a29faaf37bf1d73915abef026712fca0ef77803526df9dd177814ee247ec85903fbd436d5929277a88d6c2aef691f7751ed9cde5161bcb154399f72df54f06f1d6ff3d83e73d83596d936288338923376d579ae9fd088d2e038da40cf6d9fbc4118fd9875038c49f2a23dbbfb95106fb504a99f3a08dc27ea552cf447074bf49476d5967649775cbbcf82b06db016034eba8e2631ff4fd94b122641c0965937121bac07aba1b3655d71e8eea2abe64dd32df0318659c8aeeb9672cab2b63378351f1f472a0198ebd2153a6e3452fe0e9e980c7513d53c7a10aa34e3d8c3a1543197cb7b1c2413d0bc0afac5be62bc0b78b6d8e5ac831f962438b42ac37b46799749475a8f8ed6ea94b1fc77591754bbbd42707be2b0ddf5d0ddf89e0c8ed1c0499f7af4a60eeed8059adb76ffceb2dc5f3368929f1d315ead40f3488ab4eb82e39cfeb67685b08f9fe709e27e5a4ac1cbf845dc5b26c4b643797eb652c570c65fa58ea9f0ce2ad7f5f83a7afc1acb6c90d706ee7607f48c5401f8343e6bb82767d23b4eb03da49193cfe7573a45d6f8347e6bb018f9ce354804dce15843f01ffef92036eb3ddabb0708b0dc789eb6661ec1a3f63ea5ca79bc128f35d81516cbd81a7d29166e6b6bed8d0078fcbcd8d32b26c219479088e8d094b59b5df5d58505bafa6da1edbbb63ba4d6fee402f1ca731007d0243c300f4927a3673c0d33aa81dab71e2a49a09431f1c7ec7f0f4a347412b3430f1b7c0528d2660c37c538b2d088e1c92b2106c32246533b0353164c1a130a5bc0c69e7422ed443d65d6870b60496387de3709e32650a9d16c0e3229455e8c8909e3a74ee99306ad2708c8f6606677d6247fdaf69867251eb72b51dcc7d2209f3660c163af2df14ea9b8479f1a7b68d0cad3a6ee8b087fb4d7870f298e163274d44a1cc1d1bf305c1911bc0fc8d12dcd54e87018015c6c6a199512f6c30e47fb2615ac7cf598e63e69ada04e04fa6d6a05b2b07baa9f5cbd8b7c3868e1e7ddbe4aad1a3865d3379ecb049a36ac6e2d66c692817b5a5e5ffcdc1666be2b1ac9ab0d9c2655b586cb60947196e09363972b5029bf0b4065b53c84b7973cb3809d70b60fdb24ba9ff29719ae98ab7086a43400ec7aa5d55fbaf3a95539f9055a7426a6863b539d5d0c5ea8ea11a9a587dc54e0d3dac861a56430b9f11a4870e5643059f1da48702565fbb2809d243fb9e17d40eddaba6c3c0f9bd203d34afba4d7351903eed5243eb760cd243e7aa5b979d82f467ded4bbf5eaf45ddd1650a7bcea124f9d7eaad34e7579a16e5fa85b59ea944e9d2eab534175faa62e47fa6aadfb85e98a305d19a6abc2747598ae09d3b561ba2e4cd787e98630dd18a69bc27473986e09d3ad61ba2d4cb787e98e30dd19a6bb82f4f0ce7707e9e1d7d5f0cff706e9a1a1ef0bd2c346df1fa487947e20480f373d34480f453d2c480f533d3c480f61fd60901ede7a54901e26f7e1203dd4ae1a82776c901e0e5b0d93ad86cf56c3fcaa2181d590c26aa861352cb11ac2580d81ac86467e3c480fb9ac866c7e2a480ffb3c354ccf84e9d9303d17a6e7c3f442985e0cd2c383ab61c3a705e961c6d5f0e33383f470e5b383f4f0e66ad873351cba1a265d0d9fae865557c3bcabe1dfd5b0f06f86e9ad30bd1da41f49a84731ea1185bafdaf1e83a95bd48b82f4adf32541fa11b77ae4afba40a82e21aa8bccaa20dd854a7529535dec549743d505537549555d74559765d5855b7569575dfcd52b0fea1510f54a8c7a4548bd32a55e2153afd4a9570cd56ba2eab54bf51ab17aad7a7f90be2d7e30483f2a55b7c3d5a301158feaf6fd6761fa41987e18a61f85e9c761fa49987e1aa69f85e9e7417a586335dcb11a2e590dadac8661564336aba19cd550d06ad8e82f82f4d0d36ae8ea3f05e921b1bf0cd35761fa3a480faffdd730fd2d4cdf84e9ef61fa4798fe19a67f05b54369636371866e61f4554a3074d2a4e163c64d2a9954533266f2e849a3c68d7eac64caa849234b6a1e193e61c4e89a29b8f00ff5c2320e78bf0913863e56326a6cf5f0474b6a264f2aa91951525533796cf51107ea7fea85ce3adae3d0eaea6867fffe5d48ff6f3d9db6d26d9f8cb07e7de6bab5695a0f414ea8cf42dd9ad6af4213f4514a2e67ef4c9feb964c1c5d33a9a4b4646cf8373cb8d64c195edda904ff37311479e2a4928993864e9854326242cd9892ce9d70bd4fb7ae4725fea3b51b985667d44f9c16fa5b4af50ab19de7d64381cfcfad1fe9dfbf0be9bfd5d369eac09b6d0d9bd767a14b4aea47585e1229cbc4c95593260c1d36297ae19edf65e1bef5a9e62df5ace67fd5c759d30ef558a84387fa11f6ad8fb35159380bfe3f244cae11d44d0600", + "bytecode": "0x1f8b08000000000000ffed9d777414c7dae65b2030782c01ced9c2e13a60632144163038e78c8d31c62004061b104118e76c72744ee49c93c91803c6d8d737e7ec74af6fd87376bf3dbb7fecf79dddf56ed74cbd9f1e8aea4123770d8f34d5e794a6fa5575bfbf7afaedea54dd5510a4a77f85a940e79b86e9c2e0c849fe9fd4bfa5df6fea10e3ba4a5d72163410ce260d84b36903e12c6c209ccd1a0867f306c2795c03e16cd140385bc6c859007cae788f6f60bc8906c67b42d030e2b6a88170163710ce560d84b37503e16cd340384f6c209c273510ce931b08e7290d84f3d406c2795a03e13cbd81709ed14038cf6c209c673510ceb31b08e7390d84f3dc06c2795e03e12c69209c6d1b08e7f90d84f3821839db01a7dccbbf48fffe40ff5eac7f2fd1bf97eadfcbf46f3b5dc7423d7f7998ae0853fb305d69fc4f09a36ee89785a9a3f1bff230750a53e73075d1ff2bd1ffeb1aa66e61ea1ea61e61aa0853cf30f50a536fad479f305d15a6abc3744d98ae0dd37561ba3e4c3784e9c630dd14a69bc3744b986e0dd36d61ba3d4c7784e9ce30dd15a6bbc3744f98fa86e9de30dd67b0f40bd3fd61ea1fa607c234204c0f866960981e0ad3a0300d0e5365988684a92a4c43c3342c4c0f876978984684e991303d1aa691611a15a6d161aa0ed398308d0dd3b8308d0f534d982684e9b1304d34347b3c4c4f84e9c9303d65703e1da667c2f46c989e0bd3f3617a214c2f86e9a530bd1ca657c234294c93c334254c53c3342d4cd3c334234c33c3342b4cb3c334274c73c3f46a985e0bd3eb617a234c6f86e9ad30bd1da677c2f46e98ded32cb223bc1fa679619a1fa605615a18a645615a1ca625615a1aa665615a1ea615615a19a655615a1da635615a1ba675615a1fa60d61da18a64d61da1ca62d61fa204c5bc3b42d4cdbc3b4234c3bc3b42b4cbbc3b4274c1f86696f983e0ad3be30ed0fd381307d1ca68361fa244c87c2f469983e0bd30fc3f479987e6468fee330fd244c3f0dd3cfb4ede7faf717baacecf3bfd4bfbfd2bfbfd6bfbfd1bfbf35caffce98ffbd31ff07fdfb47fdfb27fdfb67fdfb17fdfb85fefd52ff7ea57fbfd6bfdfe8dfbfeadfbfe9df6ff5efdff5ef3ff4ef3ff5af7afef75edb74be45503b258398daa4f2a183d5fd7f11db7cbea89e5d35d5ff93df126d2fd4f3f25ba0edcdf47c33c3de5ccf3737d6d342cfb730ecc57abed8b0b7d6f3ad0dfb897afe44c37eb29e3fd9b0b7d5f36dc19ed0ff4b572cfda36c4db5a9006c129f4dc0d64cdb9a82adb9ac0e6cc7695b33b0c9f66d0eb696da761cd88ed7b616604b685b4bd1324c27685b32882b564a07abf516c5bd5efdcca4387ede4ab5de568e785bc7cf3b44adb78d035e151f27ea751541dc9ca46dc5603b59db5a81ed146d6b0db653b5ad0dd84ed3b613c176bab69d04b633b4ed64b09da96da780ed2c6d3b156c676bdb69603b47db4e07dbb9da7606d8ced3b633c156a26d67814d37b9c1d9603b5fdbce01db05da762ed82ed4b6f3c026e778256093f3bdb6609373bff3c126e78117689b6a3b5a16803f6d97762be54fda6cb0fd40da6bb05d2c6d35d82e91761a6c97826fb15d066d8dd8da699bb45bea7fdd753e19c4b59f94a5f6931e71af375cb35a6fcff8d79b7a7ed72ba8d53a097e7a8056bd753ec6be2d1dd0b79cdb881fb11742fe26282be5440f39f608bb3a1654e87cef0ccb7537962b86321596fa278378ebdfd3e0e969303783bc9b98ed58ea63b6ce53d631db0fca9ab127e7418d31666f050e07315bee63b6ce53d6313b0cca9ab127e7c28d31661f000e0731dbd54dcc9695fa984ddf1b0b027becc9f550638cd911c0117fcc76f2315bf729eb987d11ca9ab127d7c48d3166270247fc31dba5ab3f37a8f39475ccce81b266ecc9fd99c618b3af008783981de2dbd93a4f59c7ec7c286bc69edc2b6c8c31fb1a70c41fb3dd1cc56c471fb341fa396710d8634fee5b37c6985d041cf1c7ec107f7fb6ee53d631bb0bca9ab127cf501a63cc6ed079f59ce1e7fa39c3d960fb85b69d03bcf1c7765599a3d8eee0633bddff2308ec312acff31a636c7fa4f32a8e7f05fd11c4f66be9ab00b6df68dbf960fbadb65d00f572b00f74f1fb40ddeb94ed3ef067286bc6b23c5b6e8cfbc02f80c341cc76f5315bf73a651bb3ff05ca9ab127fd1c1a63cc7e091c0e62b69b8fd9bad729db98fd77286bc6de253adf1863f6bfeabc3a5ff8a33e5fb80c6c7fd2b67660fbb3b65d0eb6bf68db1560fb42dbda83ed4b6dbb126c5f695b29d8bed6b60e60fb46dbcac0f6576deb08b6bf695b39d8bed5b64e60fbbbb67506db3fb4ad0bd8fea96d5dc1f62f6deba66daa9f9ef4bd3aa46d2d803f19c4bb6da5dfa5ac5be63be4c0772bc377ab1cfa6e63f86e63f15de6c077027cc85460cc27215fe696a7b41878d05779fcbe3aaaba770cea5ef772e0e9e4a0ee09f051179e4ec0d3397e9ed4f1b34bfceb4d6de38e86a609f0d511ead5d541bd0ac097ac5be6c55f31d8b06ded6a61ec163f635901f89275cb7c3760141bb6f5f22e95ec3fea787871412daf837d29754e24fee4db55c2510e7629d3a16d2d5b3bcd5604ffc7e35e67c3e6282e537121be64dd322ffe8aa03e9d73cf585657c64e06a3ab36a2007cc9babdefdaed20793c8ebbb8d6b1b569e2bb470e7c77337c971bbeb1ed9429d3b1ad1b30c77ecda98f6d15f1afb714af4fe4da50fce0f9035ec3c55527f42dd786e247ec8590bfada0b6ac94133da41d167615cbb22d91dd5caeabb15c3194e961a97f3288b7fe15064f85c1acb6c9d5702c74b03fa462a087c121f3e5a05d4584763d403b29730968e7aa3deb6ef0c87c67e09176ac0bf0b8ba268ae2c9c5f5d8d17ce3392c5e3fcbfff13cc0d5f6ea6030cabc6d7b750346dbb98a83eb998ce72a9d80516cdd81a7a323cda2b66b4712df0e6225d51e890f393797fdb733d8a54c37fd429d6a2b1f81b6d2458c603cca54d76bdef8b75359ea1abc53163cb8ed1c5c577570148fa578ffe6bb20de5833dba54e865651f7785cb5e51d0d1e99177f9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec99f999f17912f6db92729d4918cdfe6faeeef3a7be61a8d725eb57cf75feb7d3fe6065a5d83f46fa415c66d4b910ca1435a92dfbffa03f98f99c0afb487676ab5d6a5b627fcc24cc8b3fec6b85db92a1bf53496cbed3dfa274f1bc4df5b156dfd134fb7e76b668eaa2ff336a5a60688afdf12f3778549c5634ad6573f1ec2fdb6791a895e4e37cb6571cd8633dfeed5276d833eb26c1e1ed071e675cf5df91b65a9e97f7307c174299b39ad46e1be95b25e3cc763496c37e3fb26e59e632b05718eb6ead97158e66c6fabbc0b252e65c6853f737a9d5cc415b59966ddf757c6e1eff7138fd1cbf63163c1d80c7453be3e87ce3b0efadc6fd1cdfec9f663b8f9132d8b7cf41bfca8cfd9dc49f67f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b667e66c5633e6bc5f76bcb491873d4f721f53c43be5526eb4f7d2fb849ad5fd7cfe1e499533ba3cef8eee87f6f525b768bce170547f67788da96aebe4f11b52dc51f7e7b069f05b978ae5b00be64dd65162d245f129bef32676343c873fc8e86aee5164d5dedaff88c1535c5fdb593c183cf46a3beed5366d85cf61d8a8a0bf187fb5219d8248fef47bbd8ce782c31fbf5883f7c7efd23ad6debc0d5b62f2b75d96ee0775392c191f18ddf53f939b47dbfd479ecc3817d47beb6fc5fa64ccfa9453f556707dfd72c2d8075c9f6b57ddbb30fb0c6e4bb03aeab40a73e86068590ffaa496d59292765456b6157fb887c0306d9cde53a19cb1543995e96fa278378eb6f7e6bb5b7c1acb6c96f20cebe86e3bfab36a95784469781465206cf835cf5c933db48b37f23f6db6b6e94c1731629f32f68a3a2fa8fdafa1cba3a8e45f539b49d1b770046b38e663fcf7cefa7f51fd05ec4dd4feb3f2086b09f5660acbf1dac5fb89a07d1c71629f37f8df59be7e4b20cf603fbcffe4ff03d97329dcfe69cfc585d5fd9cec971b9a8ba2b66fc0e5a3246668c0964c1f3042973bcd65ab65945047737cbb24511cb8a56e6b7c28a8223f573f39db5f43edfdba88bc4357e835cca9c04757173de923e0774f54db924d449e5cb2c759532a7c3be76a6ce27603be17e7ba9e5ff32653a07c431dcaf8abfcea9ed7b357026c10ffabe065863f2dd017dcb39a0f8117b21e42f695a5b56ca891ea2b5b0ab7d44cea390dd5cae87b15c3194e963a97f3288b7fe57193c5719cc6a9b9c03717629f44377d556f789d0a81d682465f09ea2ed3ba0b6638cabbefd51c798326034db4d3c4eba6433df1332efabd9ce11a48c2c8be7085da09d4d58ca9af70be5781967bf617c57a20bf8c577255c7dbbb93be89684793c2f3896be5d7cc756f98b1a33a17b0e7c478d99900bdf6d0cdf6d72e8db6bee3567d2dcc11804a9f7cff09ba56aca745e8ae312c8724d80d1c5580e89e0f06f8f1f8d11c77790e59a02a38be343b6df3eef028cb25c2130ba78b714c7dfa80b237e63188ff3c2e8e05bb11deafbad58bca7d71c1899ded9c46753c701a38b7ba8f57d570fcfe75bc0afab71893a66c188e7f3b25c4b6074716f1c9f0dd68511af8b64b9e381d1c533ac6cc777c26fcfe3bd65978c998eed8efba294657befa5c22d4fc6730df4ed605cc39416789ff1685af474cb93f1dc077d3bb8ef97d202c7193c9a16f86cd0c5b88789e0f0e77047e3c1e797b2dc89c09874c4d83b0bc62430fee7bd6260ece388319905631f6014fbc9c0e8e0fe6b8ab14f168c789f52963b0518af76c47855168c5703a32c772a30bab8979a00bf7561bc061865b9d380f15a478cd764c1782d30ca72a703e3758e18afcd82f13a6094e5ce00c6eb1d315e9705e3f5c028cb9d098c373862bc3e0bc61b8051963b0b186f74c47843168c3702a32c773630dee488f1c62c186f024659ee1c60bcd911e34d5930de0c8cb2dcb9c0788b23c69bb360bc051865b9f380f156478cb764c1782b30ca7225c0789b23c65bb360bc0d1865b9b6c078bb23c6dbb260bc1d1865b9f381f10e478cb767c1780730ca721700e39d8e18efc882f14e6094e52e04c6bb1c31de9905e35dc028cb5d048c773b62bc2b0bc6bb815196fb0130dee388f1ee2c18ef01c6bb2d8c7d1d31de9305635f6094e52e07c67be3674c5d4bf7cd82f15ee0b92f7e9e9466f766c1739f5b9ed477f5eeb5f8ba3f7e5fa96dd12fa87bddef079efef1f3a4b6c5fd59f00843312c879a3d103f634ab3fe59303e003c03e2e74969f640163c0340b3072c9a3d183f634ab30159303e083c03e3e74969f660163c0341b3072d9a3d143f634ab38159303e043c83e2e74969f650163c83825acd1eb26836387ec6946683b2601c0c3c95f1f3a4341b9c054f256836d8a2d990f819539a5566c1380478aae2e7496936240b9e2ad06c8845b3a1f133a634abca827128f00c8b9f27a5d9d02c78868166432d9a3d1c3f634ab36159303e0c3cc3e3e74969f670163cc341b3872d9a8d889f31a5d9f02c184700cf23f1f3a4341b9105cf23a0d9088b668f3a627c240bc6472d3c717f27fb118baf518eea3e32a87bdd85a11896c37e12a31d318eca82713430ca72d84fa2da11e3e82c18ab8151964b3866ccd44fa21a7c8f89df77aa5daa0eeaaecf18b73c19fb49a0efb18eb41813d45d8bb16e7932f69340dfe31c693136a8bb16e38067bc032d12e0a32e3cc2500ccb613f891a478ce3b360ac0146590efb494c70c4589305e3046094e5b09fc4638e182764c1f81830ca72d84f62a223c6c7b2609c088cb21cf69378dc11e3c42c181f0746590efb493ce188f1f12c189f0046590efb493ce988f1892c189f0446590efb493ce588f1c92c189f0246590efb493ced88f1a92c189f0646590efb493ce388f1e92c189f0146590efb493ceb88f1992c189f0546590efb493ce788f1d92c189f0346590efb493cef88f1b92c189f0746590efb49bce088f1f92c185f004659ee51c78c99ae5f5e68e4bea3ae551abbefa8eb92c6eedbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ece997cbfe8c077027cc85460cc27212f0cc5b0dca39eb15133224f497c3ca55877f4f51241dd5fb2f01438aa3bfa7a99a0eec2d0d0185f6c008c8f360046af63ba0f627d1815cf2bf0ff648c3c2f67c1f30af04c72c4f34a163c93806772fc3ca9989a94058f3014c3728f3600c6171b00a3d7d1ebc8c4e875cc1f1d3da367f48c9ef15830368436dc333688782cab2fa3e299123f4f4ab3c959f04c01cd64b9fbdc3296d59751f14c8d9f27a5d9942c78a68266532c9a39602cab2fa3e299163f4f4ab3a959f04c03cda65a3473c058565f46c5333d7e9e9466d3b2e0990e9a4db368e680b1acbe8c8a6746fc3c29cda667c13303349b6ed1cc0163597d1915cfccf879529acdc88267266836c3a29903c6b2fa322a9e59f1f3a4349b9905cf2cd06ca64533078c65f565543cb3e3e74969362b0b9ed9a0d92c8b660e18cbeacba878e6c4cf93d26c76163c7340b3d916cd58191f6d008c2f360046c73a96d59751f1cc75c433270b9eb9c0f3aa239eb959f0bc0a3cafc5cf938aa957b3e011866258eed106c0f8620360f43a7a1d9918bd8ef9a3a367f48c9e313bc6971a00a3dfd69ed133366e4607d7a919df457ab591fb8e7a17a9b1fb8e7a17a9b1fbf671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98f7326dfafc7efbb2cdb6fccbc0e3c2ebe79e3a89ea56abd6fe8757d17a37e4aab370dad5e35b42a86326f807e6f3ad0af00fccaba655efc65cb7c3101b323df65aa7d6909f5171f2f1a7a28ff6f39aa7b545bff5623f71dd5d63776df516d7d63f7ede3dcc7793ef8f671eee33c1f7cfb38f771cee21bf3cd82daf376f9fea95ac7db3a5fa8e7a5fc4b6097324f1d97fe6d1df87dc8856fbf0ff963453ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7395f9c17c3ffc7e680273078820c3c53c978aac878fa91f1dc4cc6d39b8ce771329eae643c23c9781e22e3b98b8ce705329eebc8789e23e3e940c6339e8c671a19cf30329efe643cb792f1f421e379928ce70a329ece643ca3c9780693f1dc43c6534ac6f30a19cf0d643cb9785f281b9ef6643c15643c73c8782690f14c27e3194ec6732919cf00329e4bc8786e27e3b99a8ca7988ca715194f3919cfd3643c63c8788690f1dc4bc67313194f2f329e89643cddc8786690f13c42c633898c672019cf9d643cd792f15c46c6f32c194f19194f53329e71643c43c978ee27e36947c6730b194f928ce709329e2e643c33c9784691f14c26e31944c6733719cfcb643cd793f13c4fc6d3838c6736194f0d19cfc3643c0f90f15c4cc6731b19cf55643c2790f11491f17422e3798a8c6716194f3519cf14329e4a329ebe643c3792f1f424e3994bc6f318194f77329e11643c0f92f1dc41c6730d19cf95643ccf90f1b426e36943c6d3918ca7808027111c39864902feff3ad89a18cbaacfbed6b4adfdff3bdade04967957e79b5ad6fd0ed8e45bb2ef5a96459dde81ba2475bef4fb4d299dd05712e6c55f1170bc4bc2d3918ca70d194f6b329e67c878ae24e3b9868ce70e329e07c9784690f17427e3798c8c672e194f4f329e1bc978fa92f15492f14c21e3a926e39945c6f314194f27329e22329e13c878ae22e3b98d8ce762329e07c8781e26e3a921e3994dc6d3838ce779329eebc9785e26e3b99b8c671019cf64329e51643c33c978ba90f13c41c69324e3b9858ca71d19cffd643c43c978c691f13425e32923e379968ce732329e6bc978ee24e31948c633898ce711329e19643cddc8782692f1f422e3b9898ce75e329e21643c63c8789e26e32927e36945c6534cc6733519cfed643c9790f10c20e391ef79b2f00c27e3994ec633818c670e194f05194f7b329ed7c9786e20e379858ca7948ce71e329ec1643ca3c9783a93f15c41c6f324194f1f329e5bc978fa93f10c23e39946c6339e8ca70319cf73643cd791f1bc40c6731719cf43643c23c978ba92f13c4ec6d39b8ce766329e7e643c55643c53c978c65a785e77c423efbbcbba65fe7512df0eb643a95aef7b8eeaf4be5e5733bd5ee1177f855066f2f1e95ff57e382e2b5ce6f709f0ded7fba0d1fb8eea22dba3c0d83ee8fb6d47bee51d2459b7ccbfddc87db7327cb7ca13df6d0cdf6df2c4b78f731fe7f9e0dbc7b98ff37cf0ede3dcc739936f07d70665f89d34990a8cf924e4f17ac1c5f7e51cd5f3b0ebc4ef62d44f6935cfd0cabcb62a8632ef817ef31ce867bbf69479f1972df3c504cc18172541bc71313ffe3a95a976ab25e83adfd017ebb5c091a651c790058ddc77d431a4b1fb8e3a863476df3ece7d9ce7836f1fe73ecef3c1b78f731fe74cbe17ea7c8cd78da5e8433d5f94eb8185e077b1ce17c4e857ad6b915e57a15eb7702c06bb94699248ffb60efc3eefc2b7dfe7fdb12d1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f73be3837f3d25ffc126073d59f3f2a1673f12ec1b1f41d158b8ddd77542c3676df3ece7d9c33f95ee2c077027cc894a98fdf12e059e480c7513d53cf36961a757adda8533194c163fc5207f52c00bfb26e995f0a3c328d051e177150976d8e3c53c978aac878fa91f1dc4cc6d39b8ce771329eae643c23c9781e22e3b98b8ce705329eebc8789e23e3e940c6339e8c671a19cf30329efe643cf3c8786e25e3e943c6f32419cf15643c9dc9784693f10c26e3b9878ca7948ce715329e1bc878da93f15490f1cc21e39940c6339d8c673819cfa5643c03c8786e27e3b99a8ca7988ca715194f3919cfd3643c63c8788690f1dc4bc67313194f2f329e89643cddc8786690f13c42c633898c672019cf9d643cd792f15c46c6f32c194f19194f53329e71643c43c978ee27e36947c6730b194f928ce709329e2e643c33c9784691f14c26e31944c6733719cfcb643cd793f13c4fc6d3838c6736194f0d19cfc3643c0f90f15c4cc6731b19cf55643c2790f11491f17422e3798a8c6716194f3519cf14329e4a329ebe643c3792f1f424e3994bc6f318194f77329e11643c0f92f12c20e3b9838ce71a329e2bc9789e21e3694dc6d3868ca723194f01014f2238f2ddff04fc7f1ed8e41df5d7c1b64ce71781ad89c547539d5f0ab6429d97751c17a6e7da1eb96ed4c9d57bf9e82b09f3e2af08389691f07424e36943c6d39a8ce719329e2bc978ae21e3b9838c670119cf83643c23c878ba93f13c46c633978ca72719cf8d643c7dc9782ac978a690f15493f1cc22e3798a8ca713194f1119cf09643c5791f1dc46c6733119cf03643c0f93f1d490f1cc26e3e941c6f33c19cff5643c2f93f1dc4dc633888c673219cf28329e99643c5dc8789e20e34992f1dc42c6d38e8ce77e329ea1643ce3c8789a92f19491f13c4bc6731919cfb5643c7792f10c24e39944c6f30819cf0c329e6e643c13c9787a91f1dc44c6732f19cf10329e31643c4f93f19493f1b422e32926e3b99a8ce776329e01643c9792f10c27e3994ec633818c670e194f05194f7b329e1bc8785e21e32925e3b9878c673019cf68329ece643c5790f13c49c6d3878ce756329e79643cfdc9788691f14c23e3194fc6d3818ce739329eebc8785e20e3b98b8ce721329e91643c5dc9781e27e3e94dc67333194f3f329e2a329ea9643c6373c4a3de6d97773903e0c22909f9a5c033cf018fa37a96e2770dbe8b71bd4aabe586560b0cad8aa1cc12d06fb903fd0ac0afac5be697038f9c8f082b7e53e1051246b1cd73cc93803acb94691f580e3c2ef64947f54cc5ea0aa34e2f5874973218ab2b1cd4d3b6efc8fc0ae07959e7853501e55e266114db52c73c09a8b34c99627505f0b8d8771cd53315ab2b8d3abd6cd15dca60acae74504fdbbe23f32b81e7159d17d604947b8584516ccbddf29427a0ce32658ad595c0e362df7154cf54acae32eaf48a45772983b1baca413d6dfb8eccaf82ede0993db38d59f148ff56614d40b949248c625be194a7bc3401759629533bb60a785cb4f38e744fb563ab8d3a4db2e82e653056573ba8a76ddf91f9d516df2541bc5aaca983166b2c3c6b72ac85f8cb9679490364f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e6266d059f1c87822c29a8072934918c5b6d22d4feabda0c9c1e15381319f84fc1ae059e5401f47f54cf5215f6bd469b245772983fbd75a07f5b4ed3b32bf16b64336ccab1b20b3d7b97ecc8a678ace0b6b02ca4d216114db2ab73ca9766c4a70f894a91d5b0b3c2eda7947f54cb563eb8c3a4db1e82e6570ff5ae7a09eb67d47e6d7c176f0cc9ed9c6ac78a6eabcb026a0dc541246b1ad71ca53967abf716a70f894a91d5b073c2eda7947baa7dab1f5469da65a74973218abeb1dd4d3b6efc8fc7ad80ed930af6e80cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9dbdce51cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9dbdce51cc5e67af7314b3d7397f74563cd3745e5813506e1a09a3d8d63ae5e9987aee302d387ccaf4dc613df0b8782ee348f7d473870d469da659749732b87f6d70504fdbbe23f31b603b3476e6d50d90d9c7466e987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398a99213614cf749d17d604949b4ec228b6756e7952df3d981e1c3e65eab7b30178d63bd0c7513d53fd76361a759a6ed15dcae0feb5d1413d6dfb8ecc6f84ede0993db38d59f1ccd079614d40b919248c625bef9627d58ecd080e9f32b5631b81c7453befa89ea9766c9351a71916dda50cc6ea2607f5b4ed3b32bf09b68367f6cc3666c53353e7853501e56692308a6d835b9e543b3633387ccad48e6d021e17edbca37aa6dab1cd469d665a74973218ab9b1dd4d3b6efc8fc66d80e9ed933db9815cf2c9d17d604949b45c228b68d8e791250679932b5639b81c7453befa89ea9766c8b51a75916dda50cc6ea1607f5b4ed3b32bf057866ebbcb026a0dc6c1246b16d72cc93803acb942956b7008f8b7dc7513d53b1fa8151a7d916dda50cc6ea070eea69db7764fe03e099a3f3c29a8072734818c5b6d9314f02ea2c53a658fd00785cec3b8eea998ad5ad469de65874973218ab5b1dd4d3b6efc8fc56e099abf3c29a8072734918c586edd85c473c45064f91458b63e55b69d143e74fd0bf09f87f0f6074d5b6cc3518651e635c6c4539d0ac95c1d3cad0ec58fa565a54405e4db8bd2a8091617bb5ca81666d0c9e368666c7d2b7d2a2a7ceb7d6bfb8bd7a0223c3f66a033c0edae7f284c1a3a64cc7eead8ef57154cfd4b17b5b60d71d8f4352068fdddb1cd4d3762e21f3db603b7866cf6c63563c7d755e581350ae2f09a3d8f09c7f7bfc3ce50983474d99dab1ed8ef57154cf543bb623b0ebbe1d74973218ab3b1cd4b300fccaba657e076c876c9857374066af73fd98154f3f9d17d60494eb47c228b66dc0b3337e9ef284c1a3a64cedd84ec7fa38aa67aa1ddb15d875df09ba4b19dcbf7639a86701f89575cbfc2ed80ed930af6e80cc5ee7fa312b9efe3a2fac0928d79f84516c3b806777ec3ce9315f90474d99dab1dd8ef57153cf743bb627b0ebbe1b749732b87fed7150cf02f02beb96f93db01d3cb367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed93373332b9e013a2fac0928378084516cbb80e7c3d879d2cf1d90474d999e3b7ce8581f37f54c3f77d81bd875ff1074973218ab7b1dd4b300fccaba657e2f6c07cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6ccdccc8a67a0ce0b6b02ca0d246114db1ee0f9287e9ef284c1a3a64ccf1d3e72ac8fa37aa69e3bec0becba7f04ba4b198cd57d0eea59007e65dd32bf0fb6c33ecfec992dcc8a6790ce0b6b02ca0d226114db5ee0d91f3b4ffaf929f2a829533bb6dfb13e6eea996ec70e0476ddf783ee520663f580837a16805f59b7cc1f80ed900df3ea06c8ec75f63a47317b9dbdce51cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9dbdce51cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9df34767c553a9f3c29a807295248c62db073c1fc7ced3b13461f0a8a9c0984f42fe63c7fab8a967fab9c3c1c0aefbc7a0bb94c1fdeba0837a16805f59b7cc1f84edd0d899573740661f1bb961f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e6286686d8503c553a2fac09285745c228b603c0f349fc3ce50983474d05c67c12f29f38d6c7513d53fd760e0576dd3f01dda50cee5f871cd4b300fccaba65fe106c07cfec996dcc8a6798ce0b6b02ca0d236114db41e0f9d4014fc2e05153a676ec53c7fa38aa67aa1dfb2cb0ebfe29e82e6530563f7350cf02f02beb96f9cf8067b8ce0b6b02ca0d276114db21e07111ab8aa7c8e091f94f097c2b2daa75fe04fd8bdbab1a1819b657510e346b65f0b432343b96be95166320af26dc5e638091617bb5ca81666d0c9e368666c7d2b7d262acceb7d6bfb8bdc60223c3f66a9303cd8e657b782cf7ed6319a75ef363a779c131d4bce0186a5ee035a7d2dcc1f1a50c8f650130e09484fc67c0f379fc3ca97b5c9f65c1f339f0fc307e9e0e8eea59aad6fb23608f6bbd4aab1f1b5a7d6668550c6590e1c70ef42b00bfb26e99177f9ed9334731e3b9adb026a0dca7248c629336c855bba1ea7e855e97acbf59980e9d5cebd7c5b307bcefda4caf5738c45f2194b9bfa4b6ece79aad08fe2fdb4dd5e7a06173f43e7007db333099177f4541eeee8366ba2f8b5ab8787693ed71ffa085e7bbf8784a713f475f071cd53d9be768072c3c31d6bd43d433c4fdf1d73dd57eb4d7eb92f5ab7df48b939d6a5e8efb9eb41fed8d3a1742994e25b565bf81f6c3d656b8de37e59cdcdc379b04b5ed99709568bbf97ce53b6d97729f40796c737ae85fdc3f7b405d5db58b51f798b05d34db6e97da9bcff84cdfc5a0cb27a49ad99e53a08e1516ee0a026e8cc75cee67b26edb33b20a434736cd705b7f62d1b1a785bb270137e37eddd3d0914db3a3edd77d2ddc7d09b819f7ebbe868e6c9a1d6dbfee67e1ee47c0cdb85ff7337464d3ec68fb757f0b777f026ec6fdbabfa1239b6647dbaf0758b807107033eed7030c1dd9343bda7e3dd0c23d90809b71bf1e68e8c8a6d9d1f6eb4116ee4104dc8cfbf5a0e0701dd9343bda7e5d69e1ae24e066dcaf2b0d1dd9343bda7e5d65e1ae22e066dcafab0c1dd9343bda7e3dccc23d8c809b71bf1e66e8c8a6d9d1f6ebe116eee104dc8cfb755dfbedb3eed7d516ee6a026ec6fdbadad0914db3a3edd7632cdc6308b819f7eb31868e6c9a1d6dbf1e6be11e4bc0cdb85f8f357464d3ccb65f3b7a2faf2cdbf7040f39d5273d5ef3a12c783e061e1731e5280e4a1df57349f54ddd6f6875c8d00ac7c13800fa39e80b93f1fd7ef1e7993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9e999f19bf7188cf57a4dc27248c62c367522eeef3abba5fa9d725eb6f16a66ea7d6fa3d10bbdfb2d202c35f1238c45f219469725e6dd99e9aad283872bbe1b8d6b82df7c55e87f4b634e35fe6c55f11d4673ff038783f3fc573c0e03960d102df3b8dc777d910371a9795aaefefb40c6ab7f33ea33ea8e947b1fb3f5cd30243d38f1cfb4e04876f4f61c0290979e471f16cd8513d536dc15ea34ea6c6c550e662a8e75e07f52c00bfb26e99df0b3c32e13379573118183c81451f999a90f15491f1f423e3b9908ce766329ed3c9787a93f13c4ec6d3958ca72519cf48329e87c878ee22e3398f8ce73a329e5c9c8367c3f31c194f07329e93c878c693f11492f10c23e33948c6d39f8ce707643cb792f15c4ec67326194f1f329e27c9783a93f15c41c69320e3194dc633988ce71e329e52329eb6643c3790f19c42c65341c6d39e8c6702194f73329ee1643c9792f10c20e3b9848ce776329eb3c978ae26e3799a8ca79c8ca7988ca71519cf18329e21643cf792f15c40c6731319cf69643cbdc8782692f17423e36941c6f30819cf40329e3bc978ce25e3b9968ce732329e67c978cac8784e24e31947c6d3948c672819cffd643cedc8782e22e3b9858ce70c329e2419cf13643c5dc8788e27e31945c633888ce76e329e12329eebc9789e27e3e941c67332194f0d194f33329e87c9781e20e3b9988ce736329eb3c878ae22e3798a8ca71319cf09643c45643cd5643c95643c7dc978ce27e3b9918ce754329e9e643c8f91f17427e3398e8c670419cf83643c7790f19c43c6730d19cf95643cadc978da90f13c43c6d3918ca7808027111cf92da604fcff00d8e49b411f83ad89657df21c56caabe3e2d4b647aebb8965dd1f591850a70fa12e499d2ffd7e534a27f4958479f157041c1f91f07424e379868ca70d194f6b329e2bc978ae21e339878ce70e329e07c9784690f11c47c6d39d8ce731329e9e643ca792f1dc48c6733e194f5f329e4a329e6a329e22329e13c8783a91f13c45c6731519cf59643cb791f15c4cc6f30019cfc3643ccdc8786ac8784e26e3e941c6f33c19cff5643c25643c7793f10c22e31945c6733c194f17329e27c87892643c6790f1dc42c67311194f3b329efbc9788692f13425e31947c67322194f1919cfb3643c9791f15c4bc6732e19cf9d643c03c9781e21e36941c6d38d8c6722194f2f329ed3c8786e22e3b9808ce75e329e21643c63c8785a91f11493f19493f13c4dc6733519cfd9643cb793f15c42c633808ce752329ee1643ccdc9782690f1b427e3a920e339858ce706329eb6643ca5643cf790f10c26e3194dc69320e3b9828ca73319cf93643c7dc878ce24e3b99c8ce756329e1f90f1f427e33948c6338c8ca7908c673c19cf49643c1dc8789e23e3d94fc6731d19cf79643c7791f13c44c633928ca725194f57329ec7c9787a93f19c4ec6733319cf85643cfdc878aac8789a90f18c3578f0ffeadd30393f926f0715c2ff07eacee5adf5baa48cbca3a4ee75ed316caabebb1dd5774f503b25617e37d457d8f700cf1e473c1f1a3ca6ef22c8578066bb0c9b62dce9887197c128f33b8151f4db053cbb1cf1ec36784cdf4590ef099aed306c8a71bb23c61d06a3cc6f0746d16f07f0ec70c4b3d3e0317d1741be2f68b6cdb029c6ad8e18b7198c32bf151845bf6dc0b3cd11cf7683c7f45d04f97ea0d907864d316e71c4f881c128f35b8051f4fb00783e70c4b3d5e0317d1741be3f68b6d9b029c64d8e18371b8c32bf091845bfcdc0b3d911cf1683c7f45d04f901a0d946c3a618373862dc6830cafc066014fd3602cf46473c9b0c1ed37711e4078266eb0d9b625ce78871bdc128f3eb8051f45b0f3ceb1df16c30784cdf45901f049aad356c8a718d23c6b506a3ccaf0146d16f2df0ac75c4b3cee0317d1741be12345b6dd814e32a478cab0d46995f058ca2df6ae059ed88678dc163fa2e827c1568b6d2b029c6158e18571a8c32bf021845bf95c0b3d211cf2a83c7f45d04f961a0d972c3a6189739625c6e30cafc326014fd9603cf72473c2b0c1ed37711e48783664b0d9b625ce28871a9c128f34b8051f45b0a3c4b1df12c33784cdf4590af06cd161b36c5b8c811e3628351e61701a3e8b71878163be25962f098be8b203f06345b68d814e302478c0b0d46995f008ca2df42e059e8886791c163fa2e82fc58d06cbe61538cf31c31ce3718657e1e308a7ef38167be239e05068fe9bb08f277834d78bb83ed7d9def06b6f774be2bd8ded5f92e607b47e73b83ed6d9def04b6b774be1c6c6fea7c47b0bda1f365607b5de73b80ed359def05b65775be37d8e6ea7c126c7374be0fd866ebfc55609ba5f357836da6ce5f03b6193a7f2dd8a6ebfc75609ba6f3d7836daacedf00b6293a7f23d826ebfc4d609ba4f33783ed159dbf056c2febfcad607b49e76f03db8b3a7f3bd85ed0f93bc0f6a8cedf09b6fb74fe2eb01dd2f97bc0f6a9cedf0bb6cf74fe7eb0fd50e71f00dbe73aff20d87ea4f30f81edc73a3f186c3fd1f92160fba9ce0f05dbcf74fe61b0fd5ce74780ed173aff08d87ea9f323c1f62b9d1f05b65febfc68b0fd46e7c781edb73a3f1e6cbfd3f91ab0fd5ee72780ed0f3aff18d8fea8f313c1f6279d7f1c6c7fd6f927c0f6179d7f126c5fe8fc5360fb52e79f06db573aff0cd8bed6f967c1f68dce3f07b6bfeafcf360fb9bcee358b77fd7f99220de76f6dba0762a01dfe24f95f987ce3737cac8b28550e644ddc1513de350efe2493b2cedb2b2493bfc3ed8a41d7e0f6cd20ebf0b366987df019bb4c36f834ddae1b7c026edf09b609376f80db0493bfc3ad8a41d7e0d6cd20ebf0ab6a4cecf059bb4c373c026edf06cb0493b3c0b6cd20ecf049bb4c333c026edf074b0493b3c0d6cd20e4f059bb4c353c026edf064b0493b3c096cd20ebf023669875f069bb4c32f814ddae117c126edf00b609376f851b0493b7c1fd8647ff9166cd2361f029bb4cd9f824ddae6cfc0266df30fc1266df3e76093b6f9476093b6f9c76093b6f9276093b6f9a76093b6f9676093b6f9e76093b6f9176093b6f9976093b6f957601badf3bf069bb4cdbf019bb4cdbf059bb4cdbf039bb4cdbf079bb4cd7f009bb4cd7f049bb4cd7f029bb4cd7f069bb4cd7f019bb4cd5f804ddae62fc1266df3576093b6f96bb049dbfc0dd89ed77969ab5b804d9e15aba9f47b4e380e0f9ef30b533288b7edc72909f9e7a0ee323521e379958ca78a8ca71f19cf85643ca793f1dc47c6d3928c673a19cf5b643c7f25e3594dc6b38a8c671b19cf56329ef3c878f693f19c44c65348c633878c671819cffb643c07c978fa93f1fc808ce772329e33c9780e91f15c41c69320e379838c672a19cf4a329e15643c1f90f16c21e32925e3694bc6730a194f05194f7b329ee6643cb3c8788693f1bc4bc6732919cf00329e4bc878ce26e32926e36945c633998c670c19cf6b643ccbc9789691f16c26e3d944c6730119cf5e329e0fc9784e23e36941c633838ce76d329e81643ce792f1cc27e3b98c8ce744329ea6643c73c9789692f12c21e39947c6b3918c6703194f3b329e8bc878f690f1ec26e339838ce778329e69643c6f92f10c22e32921e3e941c67332194f33329ed9643c8bc9781691f1bc47c6b39e8c671d19cfb7643cbbc8787692f19c45c67302194f1119cf14329e6a329ed7c9782ac978fa92f19c4fc6732a194f4f329ee3c8786692f12c24e35940c6f30e19cf5a329e35643c3bc878b693f19c43c67325194f6b329e36643c93c8780a087812c011804dfedf146cdfe8fc41b0c9f77af683ed6b9d9f0fb6af74fe79b03d63b135b1f009c3376093779b9f059bdcfffc1a6cf24ec0576093f32af1afe6e7b63d92bf092c237e9a5af8d1df57162ec9e3f696659241bcdb1b7d258323bfa754041ccf92f04c22e36943c6d39a8ce74a329e73c878b693f1ec20e35943c6b3968ce71d329e05643c0bc9786692f11c47c6d3938ce754329ef3c978fa92f15492f1bc4ec6534dc633858ca7888ce704329eb3c8787692f1ec22e3f9968c671d19cf7a329ef7c8781691f12c26e3994dc6d38c8ce764329e1e643c25643c83c878de24e39946c6733c19cf19643cbbc978f690f15c44c6d38e8c670319cf46329e79643c4bc8789692f1cc25e3694ac6732219cf65643cf3c978ce25e31948c6f33619cf0c329e16643ca791f17c48c6b3978ce702329e4d643c9bc9789691f12c27e3798d8c670c19cf64329e56643cc5643c6793f15c42c633808ce752329e77c9788693f1cc22e3694ec6d39e8ca7828ce714329eb6643ca5643c5bc8783e20e35941c6b3928c672a19cf1b643c09329e2bc8780e91f19c49c6733919cf0fc878fa93f11c24e3799f8c671819cf1c329e42329e93c878f693f19c47c6b3958c671b19cf2a329ed5643c7f25e3798b8c673a194f4b329efbc8784e27e3b9908ca71f194f1519cfab643c4dc878c65a78e63be291be2bb26e999fdfc87def367cefce13df3b0ddf3bf3c4f776c3f7f63cf1bdd5f0bd354f7c6f317c6fc913df9b0cdf9bf2c4f706c3f7863cf1bdcef0bd2e4f7caf317cafc913dfab0cdfabf2c4f70ac3f78a3cf1bdccf0bd2c4f7c2f317c2fc913df8b0cdf8bf2c4f702c3f7823cf1cd7cfdadfa29cbb720f6eadf04fc1fc78fdbef8871bec128f3fb81516c38fe7b0f473c51d7ee3d087c2b2da4efa2bc439f80ff5700a3ab98ea6130cabc2da670bcd10a473c51f71c2a087c2b2de45b8ef24dac04fc1fc74f7115531506a3ccdb620ac7ffeae98827ea5e494f02df4a0bf996a37c033801ffc7f1895cc5544f8351e66d3185e34df475c413758fa72f816fa5853c8b9167e609f87f3f607415537d0d4699b7c5d456e0e9e78827eade543f02df4a0be97b267d9613f0fffec0e82aa6fa198c326f8ba92dc0d3df114fd43db5fe04be9516f26e94bcc39a80ff0f00465731d5df6094795b4c6d029e018e78a2ee050e20f0adb418a8f3f28d9c04fc7f2030ba8aa90106a3ccdb626a03f00c74c413750f7320816fa5c5209d976f7026e0ff8380d1554c0d341865de1653eb806790239ea87baf83087c2b2d2a755ec64048c0ff2b81d1554c0d321865de1653385e5ba5239ea87bc69504be9516d23746fa0c26e0ff55c038c81163a5c128f38380516cab80a7ca114fd4bdee2a02df4a0be9ebbe52ff26e0ffc380d1554c55198c326f8ba915c033cc114fd43dfa6104be9516c3755ebee19180ff0f0746573135cc6094795b4c2d039ee18e78a29e2d0c27f0adb490b10fe49b7c09f83f8e97ed2aa6861b8c326f8ba925c053ed886791c1b3c8a2c5b1f2adb4906fbf2cd6bf09f8ff1860741553d506a3ccdb626a11f08c71c413f52c670c816fa585f4ed5ca87f13f0ffb1c0e82aa6c6188c326f8b291c7f79ac239ea867506373e03bea794a2e7c473d1bc885efa8fbdcb9f01d75cf3617bea3ee3fe6c277d4bdb45cf88eba2f940bdf51f73872e13bea7a3d17bea3ae3d73e13bea3a2a17bea3ae0972e13beafc3617bea3ced572e13beabcc3b7e7be3d8fdbf7b13c77c8d7f6fc581e438fe5b1c45f1bf86b835cf9f6c7127f6d902bdff97a6de0dbf3dcb7e772fd5510445f8f2d73e47b89e15be6f139cb1247be1719be651e9f192c72e47b81e15be6f1fef70247be8b0cdf32bf2007be5b19be5be5d0771bc3771b8b6f17db3b111c7efd2d0c3825218f31b0d0018fa37a96aaf52ed6ebfa2ec6f5daeedb98fb4b3194590cfab96e3b64dd99da8e16f1f92e4d800f19334ed9e459ecfb609336f43db0c933f677c126edfc3b6093e73b6f834d9effbc05b6e13a7f086cf21c16fbbfcbb3f4ed60abd479ec773d48e7b7824dfa25617f5fe95bb6056cd23f10fb994a1fcf4d60937ebad8bf51fa5a6f009bf497c77e75f2cec33ab0c97b2bd89f6bbfceaf019b7ca312fb117dadf3abc0f68dceaf04db733abf026c4febfc7d60fb52e7bf05db533abf006c5fe8fc42b03da9f38bc1f6179d7f136c7fd6f937c0f684cebf0eb6c7751edf0bfb93ce7f08b6893a8fef23fd51e77783ed319dc7f760fea0f33bc1f67b9d7f0d6c1374fe55b0d5e8fc5cb0fd4ee7e7806dbccecf06db6f757e16d8c6e9fc4cb0fd46e76780edd73a3f1d6ca3757e1ad87ea5f353c1364ae7a7806da4ce4f06db2f757e12d81ed1f9bf82ed173abf086c4d747e09d8647c41ecf321dfcc5c063619371bfbf2c8580263c1769cce8f015b0b9daf069b7c676d38d864acde61604be87c15d84ed0f94ab0c9b9ce20b0c9582b03c126e72503c0d65ae7fb834dce21fa814dc63eec0b36f99e674fb0c998de156093eff8f700dba93a3f1f6c32bed97eb0c937d70e824dc611fe1a6cf2ade56fc07696ce3f073619f3e569b09da3f35f82ed5c9d7f0a6cf27dce2fc056a2f34f82adadceff056ce7ebfc9fc126e3833d0136f9a6dbe360937178ff0436f976f244b05dacf37f04db253aff18d8641c953f804dc692fc3dd8dae9fc04b0c937a46bc07685ceff0e6c32b6c578b05da9f3bf059b8c61300e6c1d74fe37602bd3f95f83ada3ce8f065bb9ceff0a6c9d747e14d83aebfc48b075d1f95f82adabce3f02b66e3a2fed8cda9fd57e7e40cf278378cfb33f0e0e9f329d670b03f2c479de5a0c3ce86b5fec752f4b9d234b5bd044af5762681ff8de1bbbeff4f9f9477a5d857abd7b0ddf8550a6b56e1cd47272cc6faa97db6f2c87f78464ddb2cc9560ffd058776b5ddf8f1cd577afc124dca88394395933a963e3769d77f43e7c99da0724d602d010a724e485c18d5665a5782e5c179e8f80675fec3ce96b5f173181fb56dcd7bee63d5133d68aa1cc5ed0ef4307fae1be2eeb9679f1e7993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9e999f59f11cd0797cd62ce50e90308a6d1ff0b8b8cf8fcf6165fdeab9ceb2f36afdee8bddefe1cff79ae9f5961a752e84327f87674eab741ec7f194ed16b52d1d3c27ccb82dc55f11d4079f051d70c4b3cfe0d967d142f225b1f92e1be246e3b252d56f453d63df6fe87ac0a2a9abfd759f5e5781a129eeaf1f1b3cf86cb408783fd1bf0958cf27500707fb78c6b8107fb82fed039be43f064617db198f25d21ec8f3707c362d65f61bcfc5e3dff665a52edb8d3d50a76470647c17429943d0f67da6f3d837e400e8f63bcbff65caf49c5af45375de157f9d53db77277026c10ffade01ac31f93eec7d94029dc48fd80b21ff5be8cf21e5440fd15ad8d53e227d3a91dd5cee6363b96228b3db52ff64106ffd77193cbb0c66b54d7e0471f63b38febb6a937647687425682465f68146fb1df1ec33788443fca932b2fd9b1b6564d94228f325b451aa2ed2ce4b3db16f0b1e035c1dc7c497ac5be66de7c61f01a35947151fdd4eade5dd173b6fc3eafff56fd05ec4ddffebdf20860a802330d65f0aeb17aee641f4b145cafc4fe338eae21a03b7a5a927ea2c65fe17b443ed4bd2f96ccef58fd5755bd4b9fe6e073c89e0f06b6f35653abee331668f031e47f52cb51dbb3e34ea540c652e867a3a388fc9f85eed2ef0ed629ba316720eb5d7d0a210cab42c49ff4adb11a5235eab7e9493ba9459cf074b2d759132ad4a6aebd202ec7132b9dc6e3ba04e6abdfb2c7595322797d4ea72aace27603be17d938b2cff9729537b80e3da6c8bbfcea9edbb153893e0077d7f00ac31f93eecbb1a72be2f7ec45e08f90b4b6acb4a39d143b41676b58fc83b7fc86e2eb7d758ae18ca6cb7d43f19c45bff6d06cf3683596d93334a6af312472edbcded111a9582465206ef1fcbb11ddfbbb31df7f739e28e3aeeef0346b3ddc47317976cfb0d36f31eaaed7c50cae0399994e95892fe55ed6cc252d6bc37ece23e26be5b1a403d02a3ae32610c38b8362cc76b2769a7c44f7bb0efd379d1b9bda15d2194e95992fe7578de6dbd77695edfe13585709bfb16befb7155492db78a7bd94efbf46f11d83ed5bf2d0227d769e5b67b86c261bb677843492d3b2e2b5c872c7531af919b0447de53ffce288bf7dd322d87bed474d05846e9fba985699fe1a7052c1bdbbb1a1d4a4ba3f80f02dfc706b34d57d90f30e6f6e9bcb9afe0b5b194b9af24fd2b6d9259566dfb2f4eaed547b6a36887ed09c6e4c7c098d4f9d2ef37a5f6b98346fd655efc2946b9df731078e26fbbd2ef2b65731f783ff0b868db1db5d1a5788c6d11db7abb55da8eff1f1b5ae5f079adf5986f3e736f61e4e3f15d5665bbff64d362af85c7d57394282df65a7cc7a745e721b676cea6452efb3e4469f1a1c5778c5a0cc3fb9e99b4d863e171712f2a93167b2cbee3d3a24b69a6e71aa8c56e0b8fab7b0f515a88bf6c993f24606e61e4e3f15d5e69bb4f66d3629785c7d575739416bb2cbee3d3a24367bc4797498b9d169ef8efcf65d662a7c5777c5a74ed86f7f03269b1c3c2e3ea996e94163b2cbe638c8ba1b67b39362db65b78b6e7588bed16df319e1f76b6dd6bb369b1cdc2e3e0be6b462db6597cc7a8c560bcef9a498bad169ead39d662abc5777c5a5476b2dd13b669f18185c7d53de1282d3eb0f88e4f8bc15d95ef2d75d0628b85674b8eb5d862f11de335542a2e36d7418bcd169ecd39d662b3c5777c5a54a5ceb536d5418b4d169e4d39d66293c5777c5a94a68ea91beba0c5460bcfc61c6bb1d1e23bc6b8485d4f6ea883161b2c3c1b72acc5068bef188f23a9b8585f072dd65b78d6e7588bf516dff169312c75ff695d1db45867e15997632dd6597cc778cf2515176beba0c55a0bcfda1c6bb1d6e23b3e2d3aa68ea96beaa0c51a0bcf9a1c6bb1c6e23b3e2d86a69e89adae8316ab2d3cab73acc56a8bef18cf3b53edc5aa3a68b1cac2b32ac75aacb2f88ef1bc3375ff62651db45869e15999632d565a7cc7d876a6ce3b57d4418b15169e1539d66285c5778ce79d292d96d7418be5169ee539d662b9c5778ce79da9e3c8b23a68b1ccc2e36a3c91282d96597cc71817a9b673691db4586ae1599a632d965a7cc7785f2bd5762ea983164b2c3caec66b88d26289c5778cd723a97b7c8beba0c5620bcfe21c6bb1d8e23bc66745a973f04575d062918567518eb55804bef7c7ee3bdd9f5b7c485fac2b0c2d0aa14cf3b6e95fe98b15a5a3ac03fb95615d16c65e9774bfb2051175590875913227405d5a044ec6fb297754d754cccc873aa9f57e62a9ab9469d3b6569793743e01dbe410e876bee5ff321518f349c88b7eaaceefc75fe754acbe079c49f083bedf05d6987c7740df053a891fb11742be6ddbdab2524ef410ad855ded23f3741ed9cde51619cb1543997996fa278378ebffbec1f3bec19c7aef01e24ce2c84ddb95669a17a1d115a09194c13e7b9f38e231fb100a87f8536564fb3737cac8b28550e63268a3b05fa9d433111cd96fd2515bd601d965dd322ffe8ac1b61f18cd3aaaf838047d3f65ac08194742d9645c888eb09e2e864dd5b5aba3ba8a2f59b7cc77054619a7a24bee19cbeacad8d960543cdd1d6886636fc894e978d11d78ba39e07154cfd471a88751a7ae469d8aa10cbedbd8c3413d0bc0afac5be67b806f17db1cb59063f2a586168550e606e3fc314a4759878adf2e96baf4725c1759b7b44bbd72e0bbc2f0ddc9f09d080edfce419079ffaa00e69e0e98d57a7bc7bfde523c6f9398123f9da04e7d4083b8ea84eb92f3bc3e86b685907f10cef3a49c9495e397b0ab58966d89ece672dd8de58aa14c2f4bfd9341bcf5ef6df0f43698d536b90bceed1cec0fa918e86570c87c27d0ae778476bd403b2983c7bf2e8eb4eb69f0f4347c2b1e39c7e90136395710fe04fcbf630eb8cd76af87855b6c384e9ced5ca773fc8c19cf753a03a3d87a024f8523cdcc6d7da9a10f1e979b1b6564d94228330e8e8d094b59b5df5d5c505bafa6da1edbbb63ba4d6fee402f1ca731007d0243c300f4927a3673c0737c503b56e3f89aea71831f1e7ad7d0f4a347412b3430f1b7c0528d2660c37c538b2d080e1f92b2106c32246533b0353164c1a130a5bc0c69e7422ed443d65d6870b60096387de3709e32650a9de380c74528abd091213d75e8dc376e44cd508c8f6606677d6247fdaf69867251eb72b51dcc7d2209f3660c163af2df14ea9b8479f1a7b68d0cad3a66f09047fb8c7b78c2a8a1a36bc6a350e68e8df982e0f00d60fe4609ee6aa7c300c00a63e3d0cca8173618f23fd930c7c7cf598e63e69ada04e04fa6e341b7960e7453eb97b16f870c1e39f28e099523470cb96ec2e8213523aa47e3d66c612817b5a5e5ffcdc1666be2b1ac9ab0d9c2658fb3d86c138e32dc026c72e46a0936e1391e6c4d212fe5cd2de3245c2f84f5cb2ea5fea7c469a62b7e5c501b02723856edaada7fd5a99cfa84ac3a1552431babcda9862e56770cd5d0c4ea2b766ae86135d4b01a5af8cc203d74b01a2af89c203d14b0fada4549901edaf7fca076e85e351d02ce8b82f4d0bcea36cd2541fab44b0daddb2e480f9dab6e5db60fd29f7953efd6abd377755b409df2aa4b3c7539a24e41d5a9a7ba7da16e65a9533a75baac4e05d5e99bba1ce9adb5ee13a6abc2747598ae09d3b561ba2e4cd787e98630dd18a69bc27473986e09d3ad61ba2d4cb787e98e30dd19a6bbc2747798ee09d2c33bdf1ba4875f57c33fdf1fa487867e20480f1bfd60901e52faa1203ddcf4e0203d14f590203d4cf5d0203d84f5c3417a78eb11417ae8dc4783f450bb6a08ded1417a386c354cb61a3e5b0dfdab860956430aaba186d550c56a58633504b21a1af9c9203d0cb31ab2f999303d1ba487747e3e4c2f84e9c530bd14a697c3f44a901e1e5c0d1b3e25480f33ae861f9f1ea4872b9f19a4873757c39eabe1d0d530e96af87435acba1ae65d0dffae86857f2b4c6f87e99d20fd48423d8a518f28d4ed7ff5184cdda25e18a46f9d2f0ed28fb8d5237fd505427509515d645606e92e54aa4b99ea62a7ba1caa2e98aa4baaeaa2abba2cab2edcaa4bbbeae2af5e7950af80a85762d42b42ea9529f50a997aa54ebd62a85e1355af5daad788d56bd5fb82f46df10341fa51a9ba1dae1e0da87854b7ef3f0bd30fc3f479987e14a61f87e92761fa69987e16a69f07e9218cd570c76ab86435b4b21a72590dcfac8672564341ab21a2ff18a4879e564357ff25480f7ffd6598be0ad243707f13a4875fff5b98be0dd3dfc3f48f30fd334cff0a6a87d2c6c6e24cddc2e8ab9460704dcdd051636a4a6aaa4b464d18593362ccc8274a268ea8195e52fdd8d071c346564fc4853fd70bcb38e07dc68d1bfc44c988d155431f2fa99e5053523daca4b27ac2e8aac30ed4ffd40b9d7da4c7c15555d1cefefdfb90fe9f7a3a6da9db3e1961fdc6cc753ba1693d0439b13e0b756e5abf0a3da98f5272397b77fa5cb764fcc8ea9a92d292d1e1dff0e05a3d716855fb12fcdff850e4f13525e36b068fab291936ae7a544987f6b8de49c7d7a312050937306dceac9f38adf4b794ea1562fbceab87025f9c573fd2fff67d48ff473d9db628a9470d8bebb3505949fd082b4a2265193fa1b266dce02135d10bf7f93e0b5f5f9f6ade5bcf6a366b5b0f6789fa2c7469dbfa115e5f1f6763b37016fc7f9f92ba051c4f0600", "isInternal": false }, { "selector": { "value": 2603445359 }, - "bytecode": "0x1f8b08000000000000ffed9d77701cc795c667911856581024981324db1423b8586430813953a6242b072650a44512140925cbb2244b72ce395b4e6739e77c9673ce39e7ecba2adf3f57bef255b9ae7bb69ff1a139b3c6aee6816fb06faa1eb6e76defbc5f7ff3a667b67b7690098acb9f8d655cb9d6d8638273177a7fc0bde61fddd29ee0b6f29c9c999470d6a484b336259c7529e1ac4f0967434a3827a58473724a38a724c899013e2edea929e3cda68cf782201d79db9812ce5c4a389b52c2392d259ccd29e19c9e12ce1929e16c4909e7cc9470ce4a09e7ec9470ce4909e7dc9470ce4b09e7fc94702e4809e7c294702e4a09e7e29470b6a684f3c294705e9420e70ae0a431f2c7bad7c7b9d725eef562f7bad4bd2e73afcb5d1bebdcbadde64a63ab8cb579efadb6ccc6ec6079c17bafc358a7b12e63ddeebd56f75e8fb15e637dc6fa8dad31b6d6d83a63eb8d6d709a6c34b6c9d866635b8c6d35b6cdd876633b8ced34b6cbd86e637b8ced35b6cfd825c61e6f6cbfb14b8d5d66ec72634f307685c772a5b1ab8c5d6dec1a63d71abbced8f5c66e3076a3b103c60e1a3b64ecb0b123c6068d1d357693b163c68e1b7ba2b19b8d9d3076d2d8296343c64e1bbbc5d81963678d0d1bbbd5d86d9e66b71bbbc3d89dc69ee471de65ecc9c6ee36f61463f718bbd7d87dc69e6aec7e630f187bd0d8d38c3dddd8338c3dd3d8b38c3ddbd8738c3dd7d8f38c3ddfd80b8cbdd0d88b8cbdd8d84b8cbdd4d8cb8cbddcd82b8cbdd2d8ab1c0b1d08af36f61a63af35f63a63af37f690b137187ba3b137197bb3b1b718fb0f636f35f6b0b1b7197bbbb177187ba7b177197bb7b1f7187bafb1f7197bbfb10f18fba0b10f19fbb0b18f18fba8b18f19fbb8b14f18fb4f639f34f688b14f19fbb4b1cf18fbacb1cf19fbbcb12f18fba2b12f19fbb2b1af18fbaaa7f9d78c7dddd8378c7dd3f9bee55ebfedead231ff1df7fa5df7fa3df7fa7df7fa03affe0fbdf51f79eb3f76af3f71af3f75af3f73af3f77afbf70afbf74afbf72afbf76afbf71afbf75afbf73afbf77af7f70af7f74af7f72af765e6dc5cc62797230b20c0409f5499d837d765c9dc4f6e7edec9c50ad7b8f5e5b9dbfceadd36bc6f9ebdd7abde76f70eb0dde7626bbf5c99e3fe7d6739e7f9a5b9fe6f9a7bbf5e99ebfc5adb778fe0bddfa85e0cfbaf78a0d2bbe585fad7365c047f95903be7ae7ab055f036d0e7c939caf1e7cb47f1bc037c5f926816faaf34d065fd6f9a69096c62e70be8120a95cc91fb4db6d4c7abb6e2e22973cef21bbdd2626de69c9f31eb6db6d66e0b5f931dd6dab11f26686f3e5c0d7e27c4de0735dd0bf8e39eb9be57ccde09bed7cd3c137c7f966806faef3b5806f9ef3cd04df7ce79b05be05ce371b7c0b9d6f0ef81639df5cf02d76be79e06b75bef9e0bbd0f91680ef22e75b083eea2f1781efb1ceb7187c746dd70a3ebacebb107c74cd7791f3d97e627206e2393ff551613cea9fc1f738ea9bc1b784fa65f05d4c7d32f896426cf22d837e857ccb9d8ffa28fb5ebf2b0f04491d1385f0185e93f476cd96ed76d725bfdd700e6c7d30a2f500c459035a6d70e504ef0f69c7d8741d4371c85f07e59d5097ea911e749e2176dbefaf75e50d253ed7ef7d2e0775d646b47f2048b6fdeb3c9e751e733db49f29678f6ace8e79293b67af84ba7eeed135cf44ccd93dc0917cce767468ce8e79293b6707a1ae9f7b74dd3b1173f61ae060c8d91e9e9c2de435678be36041109d7bf4dd6722e6ec31e0483e67bb3467c7be949db3f7415d3ff7e8fbef44ccd9db8023f99cede9d16b83312f65e7ecf3a1ae9f7b3416331173f601e060c8d943dacf8e79293b675f0b75fddca371c18998b32f028ee473b68f29673b346783e29c661044e71e8d514fc49c7d083892cfd9c33a3e3bf6a5ec9cfd18d4f5738fe64b2662cebedb95ed3cc3b7dc3cc302f07ddbf916026ff2b97da49d29b7db35b78bf77a0441748ed2dcdd44cced475cd9e6f177e1de03f27d8fee4b00dff79def22f0fdc0bb6783e918e8d66360ec6d2af718f819d4f57399e69127e231f06de060c8d91ecdd9b1b7a9dc9cfd0bd4f5738fee69988839fb4be060c8d95ecdd9b1b7a9dc9cfd3bd4f5736fa92b4fc49cfd2f57b6d70b3f71d70bcbc1f753e75b01be9f39df4af0fddcf95681ef17ced706be5f3adf6af0fdcaf9f2e0fbb5f3b583ef37ce5700df6f9daf037cbf73be4ef0fddef9bac0f707e7eb06df1f9daf077c7f72be5ef0fdd9f9fa9ccfde9347f75e7dd1f9ecbe258d068264f72ddd6349dba6f595e310bbc98bdd348eb19bbdd8cd11b15731c4ce420c5a32defa009457f1f2e473c083b156271fabc3b6bd2d187bdb57034f9ea1ed598831169e3cf0b427cf139e3f0bc96f37dcc76d9ea65988d506edea6068570662d1b6699de2e5c087fd7747046367f28c850cc4a26dd37a2730920fcf27745ea7e3c79e0f97644678198ea5f09a88e2d1f39f886335f8a9ce375b46d8963bb646781fcfaded9e8f292fc3bca058b46d5aa7788dd09ef6f1672c8c9531ef3172f511198845dbf663e3f1be6afc351bd37ecd81ef3cf449854afba446601b8feb94b87d2d2536c7f92a0331a86f23cd0be0a73ab3dc0f126cdfb61dfa5d86e3af50eef51bf607c9e771218fc7f558783a8087e3d8673a5ef378deff67906cae75795ab57b5ae5a04e27e8d7c5a05fa9eb108aa7cccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaacccf299f1fe0b9cdfa47a2b853092af003c1ce3fce133a0dcb668fb765ee7c730af93fcbc45218f7396748fe132afcd7550e7af9991ba3f87f9747f6e10e73457f26a37a6fb2c1a8373e76239e710e3e681a3e62f5b138b5d38cc35df66ef51b3cf216bf3745d19a129c37d2aa334cd789ae27d8a2b3c1e9ba7736b47d838e6feca9d8b44ada89ce4dc1ede63c0bb5f8afd07e5424d30baffc0f34c77e2b147cf61d27c79b717bb0eeafc6f6664dfd0bda8f4bfeefc7b9e6c9d1e6fdbf49965e0eff1b63dcd7d9638eabdedb7c167a9ceff419ffaba9ae05f9a71dcff81fd72006dc56500ca386f9efc79b8388fdf51064f17f070f4334cd71b793c06929ec7eff1b48aba8ea13adda05f0f837e51d7a2b44ef194599995599995599995599995599995599995599995599995599995599995593e33fe569458b350af2084719cee7d08e733e8f92fb47d3baff39c9a91b8dcf37034e7b4dc6b731dd4f946cd48dd17b8726370eefd0e71fb92613eafe4bea4788dd01e9c0be2fa3d77a7c7d319a105955b138b5d9cc74f5ee39179fc0e4fd74284a65cc72bceb1a2a678bcb67b3c3837da189c7b6f4916b6331ef70ec5e505c5c363a9137c54c6df4773ec673c97f8f7f5503c9cbf7ed8693b2de0daf7853c67bfd10b6d1a08cecdef3aa8f32ee8fbdee3ca780f07de3bf248c4fbb4949aa726fd589e65972fcefbae01ce018883b1d7026b42b1db3176c619c5217f1d943f59335297ea911ea435b1db63849e0986ecfee7dabdcfe5a04e5f44fb078264dbdfeff1f47bcc769fbc1ff2ec1138ff73f5497d311a2d038da80e5e0771dd93e7f791fefd8d78df5e835707af59a8ce17a18f8abb7f34ea9e43aef358dc3d8751d7c65dc0e8b7d1bfcfb3daefd3fa21f41749dfa7f543c821bc4f2bf0b6bf1cb64f5c0d41fcb985eafcd4dbbe7f4d4e9fc1fbc0a8ce2fa0bf6872f72c3606e75e7fe33d53e3f1fd2aee3e698a87d735786cffbbb65be65ea83f902033e604b2e07502d5f993b7cf7a62b857477cf6af319f25ade83954f8fdc5d7cfead0079f19484487e231dfefb585f2ba0fda4275fedbbb064cfebaa5780d987c5b475f93503fd019d156aaf33f70acfd1daef1683fe1f78e86da73dfa7a5d43520e967db3cdecf07c6d8129e0f5c5f3b52d77fce2f695deef381bbbdcf497c3ef03f20cf1ae03e74aebe7a6d8c46cb4123aa83bf0da2f3083ecb37ea1cc3756f7fdc3926ea1994d83f37d58e3f9b3fae16758d4075e8b3788dd0e298a7399dfdbafe78219d2f93bc6f187f2bd10671f1b7126d4c7ae641b70158c7eb82f3193bcf143bee99d3f971881df7cce9f188ddecc56e1ec7d8aab96a2e497386672287bf3fc36796daa5d4752931e4e073352960ac4d01635d0a18eb53c0d89002c64929609c9c02c62929609c9a02c62c309ecf733b833e854af5e1da5fa5ae353036c3ff2e2994fbff3b98ff974ac96b1f8ccdf09d2ed4625530762df07b1ec7b31fcafd5f2fc480ffbb607a0a1867a480b125058c3353c0382b058cb353c03827058c7353c0382f058cf353c0b820058c0b53c0b828058c8b53c0d89a02c60b53c078510a181f9302c6c7a680f17129605ca28c8930aee0652c54ca687938fee7dfa3f99f630c3cf9a87b4e997e7b52f6ff5b637e3e697ba5cf8dc37b4b78ff27dca37bb61dc7bd23e53edbaed4ff5b65622c54cac8751f3bfe8e672c3cf8bbc8a8dfd63030162a65e4fafd0bfe466f2c3cdda0595784660c8c854a19b9ee952bf75e4ebca7bf3b423306c642a58c785f75823ca1663d65f0f482663d119a3130162a65e4ba2f390b31c6c2d3079af54668c6c058a89491e9b76da1667d65f0e06fc0fa223463602c54ca6879d63069d65f06cf1ad0ac3f4233498cc893f473b2fb236271fc66b0dcb61303324e4901e3d41430e27d121cfd57a9fb24fa79f52954aa0fd7fe2a759f04c666f87d4ca805fe1ee2df69b18e97a7e47d12187b3d9316f87b957fa7c57ae0e1f8fd4c16628c85871872f0b9e929609c9102c6961430ce4c01e3ac1430ce4e01e39c1430ce4d01e3bc1430ce4f01e38214302e4c01e3a214302e4e01237e5765b8562cf9fd65fd048f1df75d65a2c78efb5e32d1636b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae79262a7618c5f19271e23f2b426c793c7b663ac01016d1f88e0c930b51d636d14d07662481be3861430ae4901a3ea58bc07b11246cbb389896763193c9b80673313cfa632783603cf96e479c29cda5c060f31e4e0736b52c0b821058caaa3ea28895175ac1e1d955119955119cf07631afa70654c453e162a65b43c5b93e70935db5206cf56d08c3ed7cecb58a894d1f26c4b9e27d46c6b193cdb40b3ad119a3130162a65b43cdb93e70935db5606cf76d06c5b84660c8c854a192dcf8ee47942cdb697c1b30334db1ea1190363a15246cbb333799e50b31d65f0ec04cd764468c6c058a894d1f2ec4a9e27d46c67193cbb40b39d119a3130162a65b43cbb93e70935db5506cf6ed06c5784660c8c854a192dcf9ee47942cd7697c1b30734db1da1190363a15246cbb337799e50b33d65f0ec05cdf644682695714d0a1837a4809159c742a58c96671f13cfde3278f601cf254c3cfbcae0b904781e9f3c4f98539794c1430c39f8dc9a14306e4801a3eaa83a4a62541dab4747655446652c8f7120058cbaaf95512a23c3f7ab92bfa1b96482c76ef262375549ecb8dfd04cf4d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e6b9a4d8fb938f5d28f71933fb8187e399374cedccdbed5eeab6f5cf04f5b35a5de6697589a7550eea5c0afa5dc6a05f06e2d2b6699de295cb7cb10066a6d805dbbf4c81f6538c0d9e1e36fee54c6d8febeb2f9fe0b1e3fafa891e3baeaf9fe8b135cf35cfab21b6e6b9e67935c4d63cd73c97121bcbf5c1c8753b3dffd46ee309ae5ce7d69195fc54e7f1938aafd3023d863862eb31a4e78a6a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9ecbcbf31cbc5f330e3c81c71394e059248c678e309ee9c278a608e359268ca75618cf7a613ce3713f5f393cbb84f16c17c6d32b8c67b1309ee5c278e60ae32908e399218ca74b18cf54613c5b84f1d409e3d9288c272f8c678f309e25c278e609e36911c6b342184f56184fbd309e4dc278560be3592a8c67af309eddc278fa85f1ec10c6d3278ca75b18cf7c613c1dc278660ae36913c67381309e46613c5b85f13408e359258c679f309eb5c2781608e399258c27278ca74918cf24613ceb84f1ec14c6b34d184f8f309e85c2783a85f1cc16c6b35218cf34613ccdc278360be3992c8c272380271b9cfb4cb22cbcbf1f7c35de67edf540f3cc91f7af70fe1af8cc95ae5c1bb1ed2bc047bf0dbf32e2b3a8d315d0960157ce3fba25d409630dc03ac56b048e2b85f04c16c6b359184fb3309e69c278560ae3992d8ca75318cf42613c3dc278b609e3d9298c679d309e49c2789a84f1e484f1cc12c6b34018cf5a613cfb84f1ac12c6d3208c67ab309e46613c1708e36913c63353184f87309ef9c278ba85f1f409e3d9218ca75f18cf6e613c7b85f12c15c6b35a18cf26613cf5c278b2c2785608e36911c6334f18cf12613c7b84f1e485f16c14c653278c678b309ea9c278ba84f1cc10c65310c6335718cf72613c8b85f1f40ae3d92e8c6797309efdc278d60be3a915c6b34c18cf14613cd385f1cc11c6b348184f4d040fc3ffbf0c79e8fe35da36adef17129b613f84fff7f32aa6365dedb655efb64bfc14af0eea5ce33a0a7b7f157e96b8fcfb0df1dc7435687435535b687f64bcfdc31d1befab0c8021f0f409227838ee47656ae7a83c4cf0ffcfe6ad56d7785af9fb2e0775ae02fdae61d02f2ab7ff750c000f5de7106b16eaad17c248becb9979b2d0665a4a1d03d7000fc731c9d4ce3057aff5dab43e4277aa83b97a2d433ba38e1d5abf167836ba32b166a1de46218ce4bb9a99270b6da6a554ae5e0b3c1cc70e533bc35cbdce6bd3c608dda90ee6ea750ced8c3a7668fd3ae0d9e4cac49a857a9b843092ef1a5e9ece2cb4999652b97a1df0701c3b4ced0c73f57aaf4d9b2274a73a98abd733b433ead8a1f5eb613f28b33247315b1efa9d0eb166a1de66218ce4bb9695a7339f8536d352aa1fbb1e7838fa7926ddc37eec06af4d9b2374a73a98ab3730b433ead8a1f51b2262b706c96a71e318b4b83182e7c671d682e295cb7c550a995567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de39855e7f161569d55e73866d559758e63569d55e73866d559758e63569d55e73866d559758e63569d55e73866d559758e63569d55e73866d559758e63569d55e73866d5b93266cb43cf4522d62cd4db2284917cd7f1f284bf0bda128c5e32defa00946f049eeb19f4616a67780ff901af4d5b2274a73a787c1d606867d4b143eb07603f1c2883f9861432abce95315b1e7afe38b166a1de56218ce4bb9e9727ecc7b606a39752fdd801e0e1e8e799da19f66307bd366d8dd09deae0f17590a19d51c70ead533c6556e63866cb43ff078858b3506f9b1046f2ddc8ca53087fdfb82d18bd94eac70e02cf81c4798afd1883ee613f76c86bd3b608dda90ee6ea218676461d3bb47e08f64339cc37a4905975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de39855e7ead1d9f2d0ff8321d62cd4db2e84917c0758793ac27987edc1e825e3ad0f40f910f01c4c9ca738efc0a07b38ef70d86bd3f608dda90e1e5f8719da1975ecd0fa61d80f139df98614326b6e8c0fb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb384dcb03c3b5c9958b3506f871046f21de4e5099f7bb02318bd94ba6fe730f01c62d087a99de17d3b47bc36ed88d09deae0f17584a19d51c70ead1f81fda0ccca1cc56c7976ba32b166a1de4e218ce43bc4cb13f6633b83d14ba97eec08f070f4f34ced0cfbb141af4d3b2374a73a98ab830ced8c3a76687d10f683322b7314b3e5d9e5cac49a857abb843092ef302f4fd88fed0a462fa5fab141e0e1e8e799da19f66347bd36ed8ad09dea60ae1e656867d4b143eb47613f28b33247315b9eddae4cac59a8b75b0823f98e30f364a1cdb494eac78e020f473fcfd4ceb01fbbc96bd3ee08dda90ee6ea4d0ced8c3a7668fd26e0d9e3cac49a857a7b8430926f9099270b6da6a554aede043c1cc70e533bc35c3de6b5694f84ee540773f518433ba38e1d5a3f063c7b5d9958b3506faf1046f21d65e6c9429b692995abc78087e3d8616a6798abc7bd36ed8dd09dea60ae1e676867d4b143ebc781679f2b136b16eaed13c2483eecc7f631f1347a3c8d115a4cc4d84d5eeca62a89ddecc56eae92d89ae79ae7d5105bf35cf3bc1a626b9e6b9e5743ec6acd35d5bc3a35cf9c47cd33e751f38c6a2e52f37f2617bb2b178c2c35108b617cae7d2c638ec8b34818cf1c613cd385f14c11c6b34c184fad309e5e613c8b85f12c17c63357184f4118cf0c613c5dc278a60ae3a913c69317c6b34418cf3c613c2dc2785608e3c90ae3a917c6b35a18cf52613cfdc278fa84f1740be3992f8ca74318cf4c613c6dc2782e10c6d3288ca74118cf2a613c6b85f12c10c6334b184f4e184f93309efdc2782609e359278ca74718cf42613c9dc278660be359298c679a309e66613c9385f16404f06483737fdb81bf27a8051fdddfbf0f7c4f74e5fde0ab898841db390e3e1acfa56dd8f3d58299e732d4c0676e8ee07a62443c8a7373c467c743778c3500eb14af11386e16c23359184fb3309e69c278560ae3992d8ca75318cf42613c3dc278d609e399248c67bf309e26613c39613cb384f12c10c6b35618cf2a613c0dc2781a85f15c208ca74d18cf4c613c1dc278e60be3e916c6d3278ca75f18cf52613cab85f1d40be3c90ae359218ca74518cf3c613c4b84f1e485f1d409e3992a8ca74b18cf0c613c05613c7385f12c17c6b358184faf309e5a613ccb84f14c11c6335d18cf1c613c8b84f1d444f0ec67e2897b9ec27e01b1edb8375d0bd2985816de1f8fdf29edf71869fd1830920fefd3cd33f1c43d83222f20b6d5623594ed9285f7f177265c3995f718693d2aa7f03ecbd54c3c71cfed582d20b6d582e606e81e802cbc8ff75573e5d46a8f91d6a372aa999727fcff01ab82d14ba97b8df098e3d8874cedcce3f197e03334229f91bccad32a0775c6e3bee2b8fe80e229b332c7315b1e9afb22563c9f8dc7ef96c6c218757e65e009fbc7b660f452aa7f3c063c1ce70fa67686fdd809af4d6d11ba531dccd5130ced8c3a7668fd4444ecd620592d4e8e418b93113c27c7590b8a572ef3fe14324bd0d9f2d0bd9ac49a857a2b8530922fcfcb13f68f2b83d14ba9fef124f0709c3f98da19f609a7bc36ad8cd09deae0f1758aa19d51c70ead9f82fd500ef3891432abce95315b1e9aa321d62cd42b086124df31569e423e0b6da6a5543f760a7838fa7926ddc37e6cc86b53214277aa83c7d710433ba38e1d5a1f82fda0cccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaacccb2992d0ffd769858b350af430823f94eb2f214e71d3a82d14ba9798721e03995384f71de8141f770dee1b4d7a68e08dda90ee6ea698676461d3bb47e1af683322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb332cb66b63cf40c7962cd42bd4e218ce43bc5cb13fe6eab3318bd949a77380d3c1cf3324ced0ce71d6ef1dad419a13bd5c15cbd85a19d51c70eaddf02fb419995398ad9f2d0b30789350bf5ba8430926f8895a7387fda158c5e4af563b7000f473fcfa47bd88f9df1dad415a13bd5c15c3dc3d0cea86387d6cfc07e2887f9440a995567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975ae1e9d2d0ffd4f4362cd42bd6e218ce43bcdcad311ce3b7407a39752f30e678087635e8649f770dee1acd7a6ee08dda90e1e5f6719da1975ecd0fa59d80f139df9440a993537c68759734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59426e589e1e5726d62cd4eb11c248be5b7879c2e71ef404a39752f7ed9c059e330cfa30b533bc6f67d86b534f84ee54078faf618676461d3bb43e0cfb419995398ad9f2f4ba32b166a15eaf1046f29d61e6c9429b6929d58f0d030f473fcfd4ceb01fbbd56b536f84ee540773f5568676461d3bb47e2bf0f4b932b166a15e9f1046f2e139ae8f89a7d1e3698cd0e27cc5b65af4bbf205ee350beff7032357dfd2e731d23ae638f91a81a79f89a7c9e3698ad0e27cc5b65aac85b25db2f0fe5a60e4caa97e8f91d6a372aa0978d632f1347b3ccd115a9cafd8568b75ae3ccdbd66e1fd75c0c895536b3d465a8fcaa966e059c7c413d727ad1b87d871c7d778c48ecb95f188ad9aabe6aab96acea979e63c6a9e398f9a675473519a335c478563a7142300065c06a08cdf1538ae3d99da998ffa3eb6ce6b137e1fc33187f3f57d439995398e9969dca233ebc5267d028f879661662dc6730cb2df6b93b431c872994fa4905975ae8cd9c6be2df9d89d592f36e913783cb4dcc6ac05533bc3fee0f6205a638a97833a98a7b733b433037169dbb47e3bec8772984fa4905975ae8cd9c6be23f1d8c567b3636cd227f07868b983590b9e7616fb833b83688d295e0eea609edec9d0ce0cc4a56dd3fa9db01f945999955999955999955999955999955999955999955999955999955999955936b38dfda4c46317c7ef3136e913783cb43c89590b9e7616c7efef0aa235a67839a883fbfc2e867666202e6d9bd6ef82fda0cccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaacccb2996dec27271f3bfc3d0ec6267d028f879627336bc1d4ce70fcfeee205a638a97833ab8cfef66686706e2d2b669fd6ed80fcaaccc51cc36f653128f5d9ccfc3d8a44fe0f1d0f214662d78da59ec0fee09a235a67839a883fbfc1e867666202e6d9bd6ef81fd500ef3891432abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3ea5c3d3adbd8f7261ebb231cbfc7d8a44fe0f1d0722fb3163ced2c8edfdf17446b4cf1725007f3f43e867666202e6d9bd6295e35309f4821b3e6c6f8306b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7314bc80d1bfba9c9c70e7fcf8eb1499fc0e3a1e5a9cc5a30b533bcffe5fe205a638a97833a98a7f733b433037169dbb47e3fec076556e628661bfb0186d8592f36e913783cb43cc0ac05533bc3fee0c1205a638a97833ab8cf1f64686706e2d2b669fd41888d7a27143bbc079262d4b857eb7b9a2bd782efe9ae5c07be67b8723df89ee9ca0de07b962b4f02dfb3a13de47b8e2baf00df735d791df89ee7ca6bc1f77c57ee07df0b5cb90f7c2f74e561f0bdc8956f05df8b5df936f0bdc4956f07df4b5df90ef0bdcc95ef04dfcb5df949e07b852bdf05be57baf293c1f72a57be1b7caf76e5a780ef35ae7c0ff85eebcaf782ef75ae7c1ff85eefca4bc0f75084ef0daefc54f0bdd195ef07df9b5c793ff8deecca53c0f716579e0abeff8032bdbed5952f00dfc3aedc08beb7b9720e7c6f77e526f0bdc395a781ef9daedc0cbe77b9f274f0bddb956780ef3daedc02bef7baf24cf0bdcf956781effdae3c1b7c1f70e539e0fba02bcf05df875c791ef83eeccaf3c1f711575e00be8fbaf242f07dcc951781efe3aebc187c9f7065dcbfffe9ca0f808ffa9507c147fdcad3c047fdcad3c147fdca33c047fdca33c147fdcab3c047fdcab3c14779f71cf051de3d177c9477cf031fe5ddf3c14779f702f051debd107c94772f021fe5dd8bc14779f712f051debd147c94772f031fe5ddcbc14779f70af051debd127c9477af021fe5ddabc14779f71af051debd167c9477af031fe5ddebc14779f710f828efde003ecabb3782afd595df04be0b5df9cde0bbc895df02bec7b832f6338f75e5b782ef71aefc30f8a82f7c1bf82e76e5b7836fa92bbf037ccb5cf99de05beecaef02df0a577e37f856baf27bc0b7ca95df0bbe36577e1ff856bbf2fbc19777e50f80afdd953f08be822b7f087c1daefc61f075baf247c0d7e5ca1f055fb72b7f0c7c3daefc71f0f5baf227c047e771ea67ecf16c8f41d28134b23e6a735b445bc83719da3210247b4d47b168dbb4de018cb40f0ae3cf58182b63bbc76879ba1834c3bca2a5d4f78f2ee0e964e0616a67f8fda3db6b5387d7a61cd4b918dad9cdd0ce0cc4a56dd37a37c4e6d8e7a845bddbee524f8b3aa8f3077792b3e7ce523ad2366cfe1622dad2c7dc16da36f54b7de310bbc78b9df762637f4c4ba9e3ab07987b1998ed76fb93df6e787cad71dba29ca2387968d35ad020a93661ec8c338a43fe3a28ffa365a42ed5233de8fc45ec3697695f22bbffb92eef7339a8d317d1fe8120d9f6f77b3cfd1eb3dd277f6b19e160381ec21ce8f338683d0fdaf5c768d707da511d3cff1598b4ebf5787abdd89687ae71bac147d70ac48fd7596de3c0edf77bdd11dce4eb01c6a86b9df6e4194b5eebb40323f97a81a78749337f5f2ff5f4c1f3728357873e5b07759adc97bd69c1e8ef1f54d71e774b3223eda2efe0ff0c92edd31b18f4c2f18100f4093c0d03d08bda59cfc03335181923383b3c74e6e04d83970e1e3c9201b43a0f135f3311cda8011f966b237c41307a2804876469280487646b3c59700886eadbaf52b65934dc3078f2f8f0134e0d9e3a7ce6ced3c38347f60cdd84d4f51e3d92c6b50049d147cbe46064d066204836791abc58a5926732bc4e62e0616a6778d29be2b5a9c16b530eead4c37b5318da9981b8b46d5ac70160f26176d2fb386150e3b505b3780abcfafb36d10651c0c7c0f6330ecebe57e7846d70f0242ef5187614d15ec9d91d6147056d6f6d47fdec616747f5ec8591edc8ed289d1d95b3a37076d4cd8eb2d951353b8a6647cdec28991d156b0d8aa35e1701cf1781d18e6ad9512c3b6a65bf49dab3821d85b2a34e7694c95e4dd86f29f60c6caf38edd5913d23da33a1fd3665bf59db338c3d7bdb33933d9bd8ab237b5564af62ed559d9d99596f6c83d37aa3b14dc6361bdb626cabb16dc6b61bdb616ca7b15dc6761bdb636cafb17dc62e31f6f8a038a27ca9b1cb8c5d6eec09c6ae3076a5b1ab8c5d6dec1a63d71abbced8f5c66e3076a3b103c60e1a3b64ecb0b123c6068d1d357693b163c68e1b7ba2b19b83e21d1e278d9d323664ecb4b15b8c9d31763628ce12d959213b0b64677dec2c8f9dd5b1b33876d6c6ced2d859193b0b63675dee0d8ab32a7676c4ce86d891703bf26d47baedc8f63382e2c8b51da97e76501c89b623cf76a4d98e2cdb91643b726c478aedc8b01d09b623bf76a4d78eecda915c3b726b476aedc8ac1d89b523af76a4d58eac3e1414474eed48a91d19b523a176e4d38e74da91cd8783e2c8a51da9b423937624d28e3cda91463bb2684712edc8a11d29b423837624d08efcd9913e3bb26747f2ecc89d1da9b323737624ee93c61e31f629639f36f619639f35f639639f37f685a098935f32f665635f31f655635f33f67563df30f64d63df32f66d63df31f65d63df33f67d633f30f643633f32f663633f31f653633f33f67363bf30f64b63bf32f66b63bf31f65b63bf33f67b637f30f647637f32f6e76064d41e3b8abfbb151a413e383c3c78f2f470ebf050ebc95b4f0c1f3f7de2ced6db8f0f1f6b1dba6df0ccd11343b7e387dfeaba261a1edf78e6ccc13b5b8f9f3a327847ebd0adc3ad43475b0f0ddd7aeac859fcd017dc87169c1bf1e09123f1c17e50f328487f5261d03fbacfd1c4c3ced26dfb4b2582fcad920fcda8adac4197b8330b7d2bbdac7815d77af6c4d0706bbef594f97bf084f9cce091b6567cefac11f9ec70ebd9e18367865b8f9e193ad9dade86dbbd7a4a058df87d4b051fcacd1c7bcb83ff079bac954d69010400", + "bytecode": "0x1f8b08000000000000ffed9d77701cc795c6679118565810cc99902c538ce06291c104e64c9992ac1c98409116495024942ccb922cc939e76c39cb39675bce392739e7ecf2d5dd3f57bebaab525df76c3fe34373668d5dcd03df60df543d6ccfdbde79bffee64dcf6cf7ec20131497bf1acbb872adb1c705672ff47ebf7bcd3fb6a52dc16de539393329e1ac4909676d4a38eb52c2599f12ce8694704e4809e7c494704e4a9033037c5cbc9353c69b4d19ef79413af2b631259cb9947036a584734a4a389b53c23935259cd352c2393d259c3352c23933259cb352c2393b259c7352c23937259cf352c2393f259c0b52c2b930259c8b52c2d99212cef353c27941829ccb8193c6c82f74af8f77af8bddeb45ee75897b5dea5e97b936d6b975bbcd15c6561a6bf5de5b65998dd9c1f282f75ebbb10e639dc6badc7b2deebd6e633dc67a8df5195b6d6c8db1b5c6d6195bef34d9606ca3b14dc6361bdb626cabb16dc6b61bdb616ca7b15dc6761bdb636cafb18b8d3dc1d83e639718bbd4d865c69e68ec728fe50a63571abbcad8d5c6ae3176adb1eb8c5d6fec0663fb8d1d3076d0d82163878d0d183b62ec4663478d1d33f6246337193b6eec84b193c6068d9d3276b3b1d3c6ce181b32768bb15b3dcd6e3376bbb13b8c3dd9e3bcd3d8538cdd65eca9c6ee36768fb17b8d3dcdd87dc6ee37f680b1a71b7b86b1671a7b96b1671b7b8eb1e71a7b9eb1e71b7b81b1171a7b91b1171b7b89b1971a7b99b1971b7b85b1571a7b95b1573b163a105e63ecb5c65e67ecf5c6de60ec41636f34f626636f36f616636f35f636636f37f690b177187ba7b177197bb7b1f7187bafb1f7197bbfb10f18fba0b10f19fbb0b18f18fba8b18f19fbb8b14f18fba4b14f19fbb4b1cf187bd8d8678d7dced8e78d7dc1d8178d7dc9d8978d7dc5d8578d7dcdd8d78d7dc3d3fc9bc6be65ecdbc6bee37cdf75afdf7375e998ffbe7bfd817bfda17bfd917bfdb157ff116ffd27defa4fddebcfdcebcfddeb2fdceb2fddebafdcebafddeb6fdceb6fddebefdcebefddeb1fdceb1fddeb9fdceb9fddeb5fdcab9d576b9f512c4f0c8697fe20a13ea963a0d78eab93d8febc9d9d13aa75efd16b8bf3d7b9757acd387fbd5baff7fc0d6ebdc1dbce44b73ed1f3e7dc7acef34f71eb533cff54b73ed5f34f77ebd33dfff96efd7cf067dd7bc586155facafd6b932e0a3fcac015fbdf3d582af813607be09ce570f3edabf0de09be47c13c037d9f926822feb7c93484b63e7395f7f9054aee40fd8ed3626bd5d3717914b9ef7a0dd6e1313ef94e4790fd9ed3633f0dafc98eab6d5087933cdf972e09bee7c4de0735dd0bf8e39eb9be97ccde09be57c53c137dbf9a6816f8ef34d07df5ce79b01be79ce37137cf39d6f16f81638df6cf02d74be39e05be47c73c1d7e27cf3c077bef3cd07df05ceb7007cd45f2e04df85ceb7087c746dd7023ebace3b1f7c74cd7781f3d97e626206e2393ff551613cea9fc1f778ea9bc1b798fa65f05d447d32f896406cf22d857e857ccb9c8ffa28fb5e9f2bf707491d1385f0185e9df476cd96ed76d726bfdd700e6c5d30ac753fc4590d5aad77e504ef0f69c3d8741d4371c85f07e51d5097ea911e749e2176dbefaf71e5f5253ed7e77d2e0775d644b4bf3f48b6fd6b3d9eb51e733db49f29678f68ce8e7a293b67af80ba7eeed135cf78ccd9ddc0917cceb6b76bce8e7a293b6707a0ae9f7b74dd3b1e73f66ae060c8d96e9e9c2de435678be36041109d7bf4dd673ce6ec51e0483e673b356747bf949db3f7425d3ff7e8fbef78ccd95b8123f99cedeed66b83512f65e7ec0ba0ae9f7b3416331e73f67ee060c8d983dacf8e7a293b675f0775fddca371c1f198b32f068ee473b6972967db356783e29c661044e71e8d518fc79c7d103892cfd9433a3e3bfaa5ec9cfd04d4f5738fe64bc663cebed795ed3cc377dd3cc37cf07dcff916006ff2b97db88d29b7db34b78bf77a0441748ed2dcdd78cced875dd9e6f10fe0de03f2fd90ee4b00df8f9cef02f0fdd8bb6783e918e8d26360f46d2af718f805d4f57399e691c7e331f03de060c8d96ecdd9d1b7a9dc9cfd1bd4f5738fee69188f39fb6be060c8d91ecdd9d1b7a9dc9cfd27d4f5736f892b8fc79cfd872bdbeb859fb9eb8565e0fbb9f32d07df2f9c6f05f87ee97c2bc1f72be76b05dfaf9d6f15f87ee37c79f0fdd6f9dac0f73be72b80eff7ced70ebe3f385f07f8fee87c9de0fb93f37581efcfced70dbebf385f0ff8feea7cbdce67efc9a37bafbee27c76df9246fd41b2fb96eeb1a46dd3fa8a3188dde4c56e1ac3d8cd5eece688d82b19626721062d196fbd1fca2b7979f239e0c158ab928fd56edbde1a8cbeedab8027cfd0f62cc4180d4f1e78da92e709cf9f85e4b71beee3564fd32cc46a8576b533b42b03b168dbb44ef172e0c3febb3d82b12379c6420662d1b669bd0318c987e7133aafd3f163cf878b33c3bc0cc752784d44f1e8f94fc4b10afc54e791e9c36ccb1c5b23bc8fe7d636cfc79497615e502cda36ad53bc46684fdbd8331646cb98f718b9fa880cc4a26dfbb1f1785f39f69a8d6abfe6c0770efaa442a57d5223b08dc5754adcbe96129be37c958118d4b791e605f0539d99ee0709b66fdb06fd2ec3f15728f7fa0dfb83e4f3b890c7e37a343cedc0c371ec331daf793cef3f1a249b6b9d9e566d9e5639a8d301fa7532e857ea3a84e229b3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb37c66bcff02e737a9de0a218ce42b000fc7387ff80c28b72ddabe9dd7f929cceb243f6f51c8e39c25dd63b8d46b731dd4f97b66b8ee2f613edd9f1bc439cd15bcda8dea3e8bc6e0ecb958ce39c4b879e0a8f9cb96c462170e71cdb7d97bd4ec73c85a3d5d574468ca709fca084d339ea6789fe2728fc7e6e99cda61368eb9bf72e722512b2a2739b787f718f0ee9762ff41b950138cec3ff03cd39578ec917398345fdee5c5ae833aff9319de37742f2afdaf3bff9e275ba7dbdb367d6629f8bbbd6d4f719f258e7a6ffbadf059aaf37fd0a7bebe26f897661cf77f60bf1c405b71e98732ce9b277f1e2ecee3b797c1d3093c1cfd0cd3f5461e8f81a4e7f1bb3dada2ae63a84e17e8d7cda05fd4b528ad533c6556666556666556666556666556666556666556666556666556666556666596cf8cbf1525d62cd42b08611ca37b1fc2f90c7afe0b6ddfceeb3cb766382ef73c1ccd392df3da5c0775be5d335cf785aedc189c7dbf43dcbe6498cf2bb92f295e23b407e782b87ecfdde1f174446841e596c46217e7f193d778781ebfddd3b510a129d7f18a73aca8291eaf6d1e0fce8d360667df5b9285ed8cc5bd43717941f1f058ea001f95f1f7d11cfb19cf25fe7d3d140fe7af1f72da4e09b8f67d21cfd96ff4409bfa83b3f3bb0eeabc07fabef7b932dec381f78e3c1cf13e2da5e6a9493f9667d9e58bf3beab81b31fe260ec35c09a50ec368c9d714671c85f07e5cfd40cd7a57aa407694decf618a1678221bbffb936ef7339a8d31bd1fefe20d9f6f7793c7d1eb3dd271f843c7b18ceff5c7d526f8c464b4123aa83d7415ce74efffe4affbe42ec471bbc3af4d93aa8f315e8a3e2ee1f8d3a07709fc768db51e731ffbc309afb3cabfd3ead47a0bf48fa3ead472087f03eadc0dbfe32d83e713504f1e716aaf3736ffbfe35397d06ef03a33abf82fea2c9ddb3d8189c7dfd8df74c8dc5f7abb8fba4291e5ed7d07ba369bb65ee81fafd0932634e200b5e27509dbf78fbac3b867b55c467ff1ef359d28a9e4385df5f7cfdac0ebdf099fe4474281ef37d5e5b28af7ba12d54e7bfbc6bc0e4af5b8ad780c9b775e43509f5031d116da53aff0dc7da3fe11a8ff6137eef68a83dfb7d5a4a5d03927eb6cd63fd7c608c2de1f9c0f5b5c375fde7fc92d6e53e1fb8cbfb9cc4e703ff2fe45903dc87ced557af89d16819684475f0b741741ec167f9468d759cabefd3782d85fd731368caf5bb03fffce78fab455d232cf334c66b84e98e798ad3d9afeb8f17d2f932c9fb86f1b712ad10177f2bd1caa4671e74eb8775bc2e3897b1f34cb1e39e399d1f83d871cf9c1e8bd8cd5eece6318cad9aabe6923467782672f8fb337c66a95d4a5d9712430e3e579302c6da1430d6a580b13e058c0d29609c9002c68929609c9402c6c92960cc02e3b93cb733e853a8541faefd55ea5a036333fcef9242b9ffbf83f97fa994bcf6c1d80cdfe9422d5606a3d702bfe7713cfba1dcfff5420cf8bf0ba6a680715a0a18a7a78071460a1867a68071560a1867a780714e0a18e7a680715e0a18e7a78071410a1817a68071510a185b52c0787e0a182f4801e3e352c078610a181f9f02c6c5ca9808e3725ec642a58c9687e37ffe3d96ff39c6c0938fbae794e9fed9b2ffdf1af3f349db2a7d6e1cde5bc2fb3fe11edbb3ed38ee1d29f7d976a5fedf2a1363a15246ae7b81f0bea3d1f044dd1fd4c6cb58a89491ebf72ff81bbdd1f07481669d119a3130162a65e4ba57aedc7b39f19efeae08cd18180b9532e27dd509f2849a7597c1d3039a754768c6c058a89491ebbee42cc4180d4f2f68d613a1190363a15246a6dfb6859af596c183bf01eb8dd08c81b15029a3e559cda4595f193cab41b3be08cd2431224fd2cfc9ee8b88c5f19bc172db4e0cc83829058c9353c088f74970f45fa5ee93e8e3d5a750a93e5cfbabd47d12189be1f731a116f87b887fa7c55a5e9e92f74960ec754c5ae0ef55fe9d16eb8087e3f7335988311a1e62c8c1e7a6a680715a0a18a7a78071460a1867a68071560a1867a780714e0a18e7a680715e0a18e7a78071410a1817a68071510a18f1bb2ac3b562c9ef2febc679ecb8ef2ae33d76dcf792f11e5bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73c97143b0d63fcca38fe1891a725399e3cb61d63f50b687b7f044f86a9ed186b8380b61343da18d7a78071750a1855c7e23d8895305a9e8d4c3c1bcae0d9083c9b98783696c1b309783627cf13e6d4a632788821079f5b9d02c6f52960541d5547498caa63f5e8a88ccaa88cca782e18d3d0872b632af2b15029a3e5d9923c4fa8d9e63278b68066f4b9365ec642a58c96676bf23ca1665bcae0d90a9a6d89d08c81b15029a3e5d9963c4fa8d9d63278b681665b233463602c54ca6879b627cf136ab6ad0c9eeda0d9b608cd18180b95325a9e1dc9f3849a6d2f83670768b63d423306c642a58c966767f23ca1663bcae0d9099aed88d08c81b15029a3e5d9953c4fa8d9ce32787681663b233463602c54ca68797627cf136ab6ab0c9edda0d9ae08cd18180b95325a9e3dc9f3849aed2e83670f68b63b4233a98cab53c0b83e058ccc3a162a65b43c7b9978f694c1b317782e66e2d95b06cfc5c0f384e479c29cbab80c1e62c8c1e756a780717d0a185547d55112a3ea583d3a2aa3322a63798cfd2960d47dad8cca38be1919bea796fc2dd2c5e33c769317bba94a62c7fd1669bcc7d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cf25c5de977cec42b9cf98d9073c1ccfbc616a67de6ef712b7ad4713d4cf6a75a9a7d5c59e5639a87309e87729837e19884bdba6758a572ef34502989962176cff3209da4f31d67b7ad8f89731b53daeafbf6c9cc78eebebc77becb8be7ebcc7d63cd73caf86d89ae79ae7d5105bf35cf35c4a6c2cd707c3d7edf4fc53bb8d27ba729d5b4756f2539d2b27145fa7047a0c71c4d66348cf15d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63c9797e73978bf660c78028f2728c1b35018cf6c613c5385f1ac13c6334918cf52613cb5c278760ae3d9268ca74718cf66613c9dc2780ac2781609e359268c678e309e69c2783608e3992c8ca74e184f5e18cf6e613c8b85f1cc15c63316bfaf288767ba309ee5c278b2c278360ae3a917c6b34a18cf1e613cbb84f1f409e3d92e8c6789309e5e613c5dc278da85f16c11c6d32a8c679e309e19c278ce13c6d3288ca74118cf4a613c7b85f1ac11c6335f18cf4c613c39613c4dc2782608e3592b8c6787309eadc278ba85f16c12c6d3218c6785309e05c2786609e399228ca75918cf44613c19013cd9e0ec679265e1fd7de0abf13e6baf07e6cc187eff72e7af81cf5ce1cab511dbbe1c7cf4dbf02b223e8b3a5d0e6de977e5fc635b429d30563fac53bc46e0b84208cf44613ccdc278a608e399258c6781309e15c2783a84f16c12c6d32d8c67ab309e1dc278d60ae399208ca749184f4e18cf4c613cf385f1ac11c6b35718cf4a613c0dc2781a85f19c278c6786309e79c2785a85f16c11c6d32e8ca74b184faf309e25c278b60be3e913c6b34b18cf1e613cab84f1d40be3d9288c272b8c67b9309ee9c278f609e3992b8c67b1309eddc278f2c278ea84f14c16c6b34118cf34613c7384f12c13c6b348184f41184fa7309ecdc2787a84f16c13c6b353184fad309ea5c2782609e359278c67aa309ed9c278160ae3a989e061f8ff97210fddbf46dba6f57d426233ec87f0ff7e5ec9d4a6abdcb6eadd76899fe2d5419d83aee3b2f77be16789cbbfdf10c70aae028dae626a0bed8f8cb77fb863e37d950130049e3e41040fc7fda84ced1c918709feffd9bcd5ea6a4f2b7fdfe5a0ce95a0dfd50cfa45e536ad5f0d3c74de24d62cd45b2784917c9731f364a1cdb4943a06ae061e8e6392a99d61ae5ee3b5695d84ee540773f51a8676461d3bb47e0df06c706562cd42bd0d4218c97715334f16da4c4ba95cbd0678388e1da67686b97aadd7a60d11ba531dccd56b19da1975ecd0fab5c0b3d19589350bf5360a6124dfd5bc3c1d5968332da572f55ae0e1387698da19e6ea755e9b3646e84e753057af636867d4b143ebd7c17e5066658e62b63cf43b0262cd42bd4d4218c9770d2b4f473e0b6da6a5543f761df070f4f34cba87fdd8f55e9b3645e84e753057af676867d4b143ebd747c46e0992d5e2865168714304cf0d63ac05c52b97f9ca1432abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac7314bd0d9f2d0734988350bf5360b6124dfb5bc3ce1ef82360723978cb7de0fe51b80e73a067d98da19de43bedf6bd3e608dda90e1e5ffb19da1975ecd0fa7ed80ffbcb60be3e85ccaa7365cc96879ed74cac59a8b7450823f9aee3e509fbb12dc1c8a5543fb61f7838fa79a67686fdd801af4d5b2274a73a787c1d606867d4b143eb144f9995398ed9f2d0ff0122d62cd4db2a84917c37b0f214c2df376e0d462ea5fab103c0b33f719e623fc6a07bd88f1df4dab4354277aa83b97a90a19d51c70ead1f84fd500ef3f52964569d55e73866d559758e63569d55e73866d559758e63569d55e73866d559758e63569d55e73866d559758e63569d55e73866d5b97a74b63cf4ff5788350bf5b6096124df7e569ef670de615b3072c978ebfd503e083c0712e729ce3b30e81ece3b1cf2dab42d4277aa83c7d7218676461d3bb47e08f6c37867be3e85cc9a1b63c3acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc72c21372ccf765726d62cd4db2e84917c077879c2e71e6c0f462ea5eedb39043c0719f4616a6778dfce61af4ddb2374a73a787c1d666867d4b143eb87613f28b33247315b9e1dae4cac59a8b7430823f90ef2f284fdd88e60e452aa1f3b0c3c1cfd3c533bc37e6cc06bd38e08dda90ee6ea00433ba38e1d5a1f80fda0ccca1cc56c7976ba32b166a1de4e218ce43bc4cb13f6633b83914ba97e6c007838fa79a67686fdd811af4d3b2374a73a98ab4718da1975ecd0fa11d80fcaaccc51cc9667972b136b16eaed12c248bec3cc3c5968332da5fab123c0c3d1cf33b533ecc76ef4dab42b4277aa83b97a23433ba38e1d5abf117876bb32b166a1de6e218ce41b60e6c9429b692995ab37020fc7b1c3d4ce30578f7a6dda1da13bd5c15c3dcad0cea86387d68f02cf1e5726d62cd4db2384917c479879b2d0665a4ae5ea51e0e1387698da19e6ea31af4d7b2274a73a98abc718da1975ecd0fa31e0d9ebcac49a857a7b8530920ffbb1bd4c3c8d1e4f638416e331769317bba94a62377bb19bab24b6e6b9e67935c4d63cd73c0faa20b6e6b9e67935c4aed65c53cdab53f3cc39d43c730e35cfa8e622357f34b9d89db96078a981580ce3736da31973449e85c278f609e3992d8c67aa309e49c278960ae3a915c6d3238ca753184f4118cf22613ccb84f1cc11c6334d18cf64613c75c278f2c278160be3992b8c67ba309ee5c278b2c278ea85f1ac12c6d3278c6789309e5e613c5dc278da85f1b40ae399278c6786309ef384f1340ae36910c6b35218cf1a613cf385f1cc14c69313c6d3248c6782309eb5c278ba85f17408e359218c6781309e59c278a608e36916c63351184f46004f3638fbb71df87b825af0d1fdfd7bc1f72457de07be9a8818b49d63e0a3f153da863d5f5d38e36c861af8cc4d115c4f8a8847716e8af8ec58e88eb1fa619de23502c74d4278260ae36916c6334518cf2c613c0b84f1ac10c6d3218ca75b18cf5a613c1384f13409e3c909e399298c67be309e35c278560ae36910c6d3288ce73c613c3384f1cc13c6d32a8ca75d184f97309e5e613c4b84f1f409e359258ca75e184f5618cf72613cd385f1cc15c6b358184f5e184f9d309ec9c278a609e399238c6799309e45c2780ac2783a85f1f408e3a915c6b35418cf24613c5385f1cc16c6b34f18cf42613c35113cfb9878e29ea7b04f406c3b0e4fd7a634469785f7c7e27741fb3c465a3f0a8ce4c3fb62f34c3c71cfa0c80b886db5580565bb64e17dfc5d07574ee53d465a8fca29bcaf7115134fdc733b5609886db5a0b90aba07200befe37dcc5c39b5ca63a4f5a89c6ae6e509ff7fc0ca60e452ea5e233ce638f621533bf378fc25f80c8dc86724aff4b4ca419db1788e445c7f40f1945999e3982d0fcd35112b9ecfc6e27754a3618c3abf32f084fd636b307229d53f1e051e8ef307533bc37eecb8d7a6d608dda90ee6ea718676461d3bb47e3c22764b90ac162746a1c589089e1363ac05c52b97795f0a9925e86c79e85e4462cd42bd154218c997e7e509fbc715c1c8a554ff78027838ce1f4ced0cfb84935e9b5644e84e75f0f83ac9d0cea86387d64fc27e2887f9780a9955e7ca982d0fcd89106b16ea15843092ef282b4f219f8536d352aa1f3b093c1cfd3c93ee613f36e8b5a910a13bd5c1e36b90a19d51c70ead0fc27e5066655666655666655666655666655666655666655666655666655666655666d9cc96877e3b4cac59a8d72e84917c2758798af30eedc1c8a5d4bcc320f09c4c9ca738efc0a07b38ef70ca6b537b84ee540773f514433ba38e1d5a3f05fb419995599995599995599995599995599995599995599995599995599995599965335b1e7a663bb166a15e871046f29de4e5097fb7d5118c5c4acd3b9c021e8e7919a67686f30e377b6dea88d09dea60aedeccd0cea86387d66f86fda0ccca1cc56c79e8d971c49a857a9d4218c937c8ca539c3fed0c462ea5fab19b8187a39f67d23decc74e7b6dea8cd09dea60ae9e666867d4b143eba7613f94c37c3c85ccaab3ea1cc7ac3aabce71ccaab3ea1cc7ac3aabce71ccaab3ea1cc7ac3aabce71ccaab3ea1cc7ac3aabce71ccaab3ea1cc7ac3a578fce9687fec722b166a15e971046f29d62e5690fe71dba82914ba97987d3c0c3312fc3a47b38ef70c66b535784ee54078faf330ced8c3a7668fd0cec87f1ce7c3c85cc9a1b63c3acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc72c21372c4fb72b136b16ea750b6124dfcdbc3ce1730fba83914ba9fb76ce00cf69067d98da19deb733e4b5a93b4277aa83c7d710433ba38e1d5a1f82fda0ccca1cc56c797a5c9958b350af470823f94e33f364a1cdb494eac7868087a39f676a67d88fdde2b5a9274277aa83b97a0b433ba38e1d5abf05787a5d9958b350af570823f9f01cd7cbc4d3e8f134466871ae625b2dfa5cf93cf79a85f7fb8091ab6fe9f518691d739c7c8dc0d3c7c4d3e4f134456871ae625b2dd640d92e59787f0d3072e5549fc748eb5139d5043c6b98789a3d9ee6082dce556cabc55a579ee25eb3f0fe5a60e4caa9351e23ad47e55433f0ac65e289eb93d68e41ecb8e36b2c62c7e5ca58c456cd5573d55c35e7d43c730e35cf9c43cd33aab928cd19aea3c2b1538a1100032efd50c6ef0a1cd79e4cedcc477d1f5bebb509bf8fe198c3b9fabea1ccca1cc7cc346ed191f562933e81c743cb10b316633906d9e7b549da1864b9ccc753c8ac3a57c66c63df9a7cec8eac179bf4093c1e5a6e65d682a99d617f705b10ad31c5cb411dccd3db18da9981b8b46d5abf0df64339ccc753c8ac3a57c66c63df9e78ece2b3d93136e913783cb4dcceac054f3b8bfdc11d41b4c6142f0775304fef60686706e2d2b669fd0ed80fcaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaacccca2c9bd9c67e72e2b18be3f7189bf4093c1e5a9eccac054f3b8be3f77706d11a53bc1cd4c17d7e27433b331097b64deb77c27e5066655666655666655666655666655666655666655666655666655666655666d9cc36f653928f1dfe1e0763933e81c743cb5398b5606a67387e7f5710ad31c5cb411ddce77731b433037169dbb47e17ec076556e628661bfba989c72ecee7616cd227f07868792ab3163ced2cf6077707d11a53bc1cd4c17d7e37433b331097b64deb77c37e2887f9780a995567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975ae1e9d6dec7b128fdd1e8edf636cd227f07868b987590b9e7616c7efef0da235a67839a883797a2f433b331097b64deb14af1a988fa7905973636c98353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e39825e4868dfdb4e46387bf67c7d8a44fe0f1d0f234662d98da19deff725f10ad31c5cb411dccd3fb18da9981b8b46d5abf0ff683322b7314b38d7d3f43ecac179bf4093c1e5aee67d682a99d617ff04010ad31c5cb411ddce70f30b433037169dbb4fe00c446bd138a1dde0349316adcabf53ddd956bc1f70c57ae03df335db91e7ccf72e506f03ddb952780ef39d01ef23dd7959783ef79aebc167ccf77e535e07b812bf781ef85aedc0bbe17b9f210f85eeccab780ef25ae7c2bf85eeacab781ef65ae7c3bf85eeeca7780ef15aefc64f0bdd295ef04dfab5cf929e07bb52bdf05bed7b8f253c1f75a57be1b7caf73e57bc0f77a57be177c6f70e5c5e07b30c2f746577e1af8dee4caf781efcdaebc0f7c6f71e549e07bab2b4f06dfdba04caf6f77e5f3c0f7902b3782ef1dae9c03df3b5db9097cef72e529e07bb72b3783ef3dae3c157cef75e569e07b9f2b4f07dffb5d7906f83ee0ca33c1f741579e05be0fb9f26cf07dd895e780ef23ae3c177c1f75e579e0fb982bcf07dfc75d7901f83ee1ca0bc1f749575e04be4fb932eedf4fbbf2fde0a37ee501f051bff274f051bff20cf051bff24cf051bff22cf051bff26cf051bff21cf051de3d177c9477cf031fe5ddf3c14779f702f051debd107c94772f021fe5dd8bc14779f712f051debd147c94772f031fe5ddcbc14779f70af051debd127c9477af021fe5ddabc14779f71af051debd167c9477af031fe5ddebc14779f706f051de3d083ecabb37828ff2ee4de06b71e53783ef7c577e0bf82e70e5b782ef71ae8cfdcc85aefc76f03dde951f021ff585ef00df45aefc4ef02d71e577816fa92bbf1b7ccb5cf93de05beecaef05df0a577e1ff856baf2fbc1d7eaca1f00df2a57fe20f8f2aefc21f0b5b9f287c15770e58f80afdd953f0abe0e57fe18f83a5df9e3e0eb72e54f80afdb953f09be1e57fe14f8e83c4efd8c3d9eed31483a9046d6476d6e8d680bf926425bfa8364afe928166d9bd6db8191f64161ec190ba3656cf3182d4f2783669857b494fafed1093c1d0c3c4ced0cbf7f74796d6af7da94833a17413bbb18da9981b8b46d5aef82d81cfb1cb5a877db5de269510775fec39de4ecb9b3948eb40d9bbf8588b6f432b785b64dfd52ef18c4eef662e7bdd8d81fd352eaf8ea06e61e0666bbddbee4b71b1e5fabddb628a7284e1edab4063448aa4d183be38ce290bf0eca353386eb523dd283ce5fc46e7399f625b2fb9febf43e97833abd11edef0f926d7f9fc7d3e731db7df2cfe9c31c0cc7439803bd1e07ade741bbbe18ed7a413baa83e7bf3626ed7a3c1e5a6f031ebac6e9021f5d2b103f5e67b58e01b7dfef75457093af1b18db2218f3c93386d73a6d1e23ade781917c3dc0d3cda499bfaf9778fae079b9c1ab439fad833ab35c5f322518f9fd83eadae36e7166b85df41dfcd120d93ebd81412f1c1f08409fc0d33000bda89df50c3c9383e13182334383a70fdc3870c9c081c31940abf330f13513d18c1af061b936c2170423874270489686427048b6c693058760a8befd2a659b45c30d03278e0d3df1e4c0c943a7ef3835347078f7e08d485defd123695c0b90147db44c0c86076dfa836493a7c18b552a7926c2eb04061ea6768627bd495e9b1abc36e5a04e3dbc3789a19d19884bdba6751c00261f6627bd8f1306355e5b308b27c1abbf6f136d10057c1c6c3fe3e0ec7b754ed806074fe2528f614711ed959cdd117654d0f6d676d4cf1e767654cf5e18d98edc8ed2d951393b0a6747ddec289b1d55b3a36876d4cc8e92d951b196a038ea7501f07c0518eda8961dc5b2a356f69ba43d2bd851283bea644799ecd584fd9662cfc0f68ad39e0ded59d05eedd86f53f69bb53dc3d8b3b73d33d9b389bd3ab25745f62ad65ed5d9999975c6d63bad3718db686c93b1cdc6b618db6a6c9bb1edc67618db696c97b1ddc6f618db6bec62634f088a23ca9718bbd4d865c69e68ec72635718bbd2d855c6ae36768db16b8d5d67ec7a633718db6fec80b183c60e193b6c6cc0d81163371a3b6aec98b12719bb2928dee171c2d8496383c64e19bbd9d869636782e22c919d15b2b34076d6c7cef2d8591d3b8b63676dec2c8d9d95b1b33076d6e59ea038ab626747ec6c881d09b723df76a4db8e6c3f33288e5cdb91eae704c591683bf26c479aedc8b21d49b623c776a4d88e0cdb91603bf26b477aedc8ae1dc9b523b776a4d68eccda91583bf26a475aedc8ea834171e4d48e94da91513b126a473eed48a71dd97c28288e5cda914a3b32694722edc8a31d69b4238b7624d18e1cda91423b32684702edc89f1de9b3237b7624cf8edcd9913a3b326747e23e63ec61639f35f639639f37f605635f34f625635f0e8a39f955635f33f67563df30f64d63df32f66d63df31f65d63df33f67d633f30f643633f32f663638f18fb89b19f1afb99b19f1bfb85b15f1afb95b15f1bfb8db1df1afb9db1df1bfb83b13f1afb93b13f1bfb8bb1bf06c3a3f6d851fcd3add008f281a1a18113a7865a86065b4edc727ce8d8a9e377b4dc766ce868cbe0ad03a78f1c1fbc0d3ffc76d735d1f0f886d3a70fdcd172ece4e181db5b066f196a193cd27270f0969387cfe087beec3e34ffec88070e1f8e0ff6e39ac740fab30a83fed97d8e261e76946edbdf2a11e43f2bf9d0b4daca1a74853bb3d0b7d24b8b57712d678e0f0eb5e45b4e9abf078e9bcf0c1c6e6dc1f7ce1891cf0cb59c193a707aa8e5c8e9c1132d6dadb8dd03932a68c43fa657f0a1993346dff2e0ff01dcf19ec8b1020400", "isInternal": false } ], - "packedBytecode": "0x000000028df71de500000047641f8b08000000000000ffed9d77781447baee5b20e22001ced9c2f6ae033616424409189c73c6c618631002830d88689c713639384772cec1648c0163eccdd9bbeb0db677d71bce7dee73ef9fe79c7b8fefed9aa9efe8a5a81e3472d7f04a53fd3ca5a9fe54dddfafdefeba3a55771504e9e95f612ad0f9a661ba20387a92ff27f56fe9779b3ac7b8ae52979c050d84b34903e16cda40380b1b0867b306c2d9bc8170b668209c2d1b0867ab18390b80cf156feb06c69b6860bc6d828611b7450d84b3b88170b66d209ced1a0867fb06c2794203e13cb181709ed440384f6e209ca73410ce531b08e7690d84f3f406c2794603e13cb381709ed54038cf6e209ce73410ce731b08674903e1ecd04038cf6b209ce7c7c8d91138e55efef7f4eff7f5ef85faf722fd7bb1febd44ff76d4752cd4f39786e9b230750ad3e5c6ff9430ea867e5998ba18ff2b0f53d730750b5377fdbf12fdbf1e61ea19a65e61aa085365987a87a94f98fa6a3dfa85e98a305d19a6abc2747598ae09d3b561ba2e4cd787e98630dd18a69bc27473986e09d3ad61ba2d4cb787e98e30dd19a6bbc2d43f4c7787e91e83654098ee0dd3c030dd17a64161ba3f4c83c3f440988684696898aac2342c4cd5611a1ea611617a304c23c3342a4c0f85e9e1308d0ed398308d0d534d98c685697c98268469629826856972981e09d31443b347c3f458981e0fd31306e793617a2a4c4f87696a989e09d3b3617a2e4ccf87e98530bd18a697c2f47298a685697a9866846966986685697698e684696e98e685697e985e09d3ab617a2d4caf87e98d30bd19a6b7c2f47698de09d3bb9a457684f7c2f47e98168469619816856971989684696998968569799856846965985685697598d684696d98d685697d9836846963983685697398b684696b983e08d3b6306d0fd38e30ed0cd3ae30ed0ed39e30ed0dd38761da17a68fc2b43f4c07c274304c1f87e950983e09d3e1307d1aa6cfc2f48330fd304c3f3234ff71987e12a69f86e967daf673fdfb0b5d56f6f95feadf5fe9df5febdfdfe8dfcf8df2bf35e67f67ccff5eff7ea17fffa07fffa87fffa47fffac7fbfd4bf5fe9dfaff5ef5ff4ef5ff5efdff4ef37faf7effaf71ffaf79ffa573dff7bb5433adf32a89d92414c6d52f9f0a1eafebf886d3e5f54cfae9aeaffc96f89b617ea79f92dd0f6667abe99616faee79b1beb69a9e75b1af6623d5f6cd8dbe9f97686fd043d7f82613f49cf9f64d83be8f90e604fe8ffa52b96fe51b6a6da54003689cf26606ba66d4dc1d65c5607b616dad60c6cb27d9b83ad95b6b5005b6b6d6b09b684b6b5122dc3d446db92415cb1523a54adb728eef5ea6726c5f1f356a9f5b675c4db2e7ede616abded1df0aaf83841afab08e2e6446d2b06db49dad6166c276b5b3bb09da26dedc176aab69d00b6d3b4ed44b09dae6d2781ed0c6d3b196c676adb29603b4bdb4e05dbd9da761ad8ced1b6d3c176aeb69d01b6126d3b136cbac90dce02db79da7636d8ced7b673c07681b69d0b3639c72b019b9cef75009b9cfb9d0736390f3c5fdb54dbd1aa00fc69bbb45b297fd26683edfbd25e83ed4269abc17691b4d360bb187c8bed12686bc4d651dba4dd52ffeba5f3c920aefda42cb59f54c4bdde70cd6abdbde35f6feaf95d9fa056eb24f8a900adfaea7c8c7d5b3aa36f39b7113f622f84fc0d5056ca891e72ec1176752ca8d4f9be1996eb652c570c652a2df54f06f1d6bfb7c1d3db606e06793731dba5d4c76c9da7ac6376009435634fce831a63ccde0c1c0e62b6dcc76c9da7ac6376049435634fce851b63ccde071c0e62b6879b982d2bf5319bbe371604f6d893eba1c618b3a38023fe98edea63b6ee53d631fb1c9435634fae891b63cc4e018ef863b67b0f7f6e50e729eb989d0765cdd893fb338d31665f040e07313bccb7b3759eb28ed90550d68c3db957d81863f655e0883f667b3a8ad92e3e6683f473ce20b0c79edcb76e8c31bb1838e28fd961fefe6cdda7ac6376379435634f9ea134c698dda8f3ea39c3cff57386b3c0f60b6d3b1b78e38fedea3247b1ddd9c776baff4710d863549ee735c6d8fe48e7551cff0afa2388edd7d257016cbfd1b6f3c0f6b9b69d0ff572b00f74f7fb40ddeb94ed3ef047286bc6b23c5b6e8cfbc02f80c341ccf6f0315bf73a651bb3ff0665cdd8937e0e8d3166bf040e0731dbd3c76cddeb946dccfe3b943563ef229d6f8c31fb3f755e9d2f7ca1cf172e01db1fb4ad23d8fea86d9782ed4fda7619d8feac6d9dc0f6a5b65d0eb6afb4ad146c5f6b5b67b0fd45dbcac0f6576deb02b6bf695b39d8bed1b6ae60fbbbb67503db3fb4ad3bd8fea96d3dc0f62f6deba96daa9f9ef4bd3aac6d2d813f19c4bb6da5dfa5ac5be63be7c0775bc377db1cfa6e6ff86e6ff15de6c077027cc85460cc27215fe696a7b41878d05779fcbebaa8ba7709ea5ef772e0e9eaa0ee09f051179eaec0d32d7e9ed4f1b37bfceb4d6de32e86a609f0d505ead5c341bd0ac097ac5be6c55f31d8b06ded6161ec193f635901f89275cb7c4f60141bb6f5f22e95ec3fea787861412daf837d29754e24fee4db55c2510e76297371875ab68e9aad08fe8fc7bd6e86cd515ca6e2427cc9ba655efc15417dbae59eb1acae8c5d0d46576d4401f892757bdfb5db41f2781c7771ad636bd3c477450e7cf7347c971bbeb1ed9429d3b1ad2730c77ecda98f6d95f1afb714af4fe4da50fce0f9035ec3c55527f42dd786e247ec8590bfa5a0b6ac94133da41d167615cbb22d91dd5cae87b15c3194a9b0d43f19c45bff4a83a7d26056dbe44a38163ad81f5231506170c87c39685719a15d056827652e02ed5cb567bd0c1e99ef063cd28e75071e57d744513cb9b81e3b966f3c87c5eb67f93f9e07b8da5e9d0d4699b76daf9ec0683b5771703d93f15ca52b308aad17f07471a459d476ed42e2db41aca4da23f121e7e6b2ff7603bb94e9a95fa8536de543d056ba88118c4799ea7acd1bff762a4b5d8377cd8207b79d83ebaace8ee2b114efdf7c1bc41b6b66bbd4d5d02aea1e8fabb6bc8bc123f3e2cf337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993d333f333e4fc27e5b52ae1b09a3d9ffcdd57dfed4370cf5ba64fdeab9ceff71da1facac14fbc7483f884b8c3a174299a226b565ff1ff407339f53611fc96e6eb54b6d4bec8f998479f1877dad705b32f4772a89cd77fa5b942e9eb7a93ed6ea3b9a66dfcf6e164d5df47f464d0b0c4db13ffea5068f8ad3caa6b56c2e9efd65fb2c12b5927c9ccff68a037bacc7bf5dca8e7866dd2438b2fdc0e38cabfe3bd256cbf3f20ac377219439b349edb691be5532ce6c176339ecf723eb96652e017ba5b1ee767a59e16866acbf3b2c2b65ce8136f540935acd1cb49565d9f65dc7e7e6f11f87d3cff1bb64c1d319785cb4338ece378ef8de6adccff1cdfe69b6f31829837dfb1cf4abccd8df49fc7966cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367e667563ce6b3567cbfb69c8431477d1f52cf33e45b65b2fed4f7829bd4fa75fd1c4e9e397534ea8cef8efeef26b565b7ea7c5170747f87a86de9eafb1451db52fce1b767f059908be7ba05e04bd65d66d142f225b1f92e733636843cc7ef62e85a6ed1d4d5fe8acf585153dc5fbb1a3cf86c34eadb3e6586cd65dfa1a8b8107fb82f95814df2f87eb48bed8cc712b35f8ff8c3e7d73fd2dab60b5c6dfbb25297ed067e3725191c1ddff83d959f43dbf74b9dc73e1cd877e46bcbff65caf49c5af4537576f07dcdd20258976c5fdbb73dfb016b4cbe3be3ba0a74ea67685008f9af9ad49695725256b41676b58fc8376090dd5caeabb15c3194e963a97f3288b7fee6b756fb1acc6a9bfc06e2ec6b38febb6a93fa446874096824651c7fb3d1dabfd2ec5788ed6873a38c2c8bdfa2fb17b45151fd476dc700d7c73159b7ed38661e17ead2cf33dffb69fd07b41771f7d3fa0f8821eca71518ebef08eb17aee641f4b145cafc97b17ef39c5c96c17e60ffbd9fc0f75cca743e9b73f2e3757d653b27c7e5a2eaae98f13b68c9189931269005cf13a44c6badb56cb3ca08ee9e96658b229615adcc6f85150547ebe7e63b6be97dbeaf5117896bfc06b9943911eae2e6bc257d0ee8ea9b7249a893ca9759ea2a654e837ded0c9d4fc076c2fdf662cbff65ca740e8863b85f117f9d53dbf74ae04c821ff47d15b0c6e4bb33fa967340f123f642c85fd4b4b6ac94133d446b6157fb889c4721bbb95c85b15c3194e967a97f3288b7fe57183c5718cc6a9b9c0d717631f44377d556f78bd0a823682465f09ea2ed3ba0b67b1daededf883a97c2f797ccf32b3c4eba396fb29fc79af7d56ce7081d0d7e3c47e80eed6cc252d6bc5f28c7cb38fb0de3bb12ddc12fbe2be1eadbcdbd40b724cce379c1f1f4ede23bb6ca5fd49809bd72e03b6acc845cf86e6ff86e9f43df5e73af3993e60ec62048bd7f86df2c5553a6f3521c9740966b028c2ec6724804477e7bfc588c38be832cd714185d1c1fb2fdf679776094e50a81d1c5bba538fe465d18f11bc3789c174607df8aed5cdf6fc5e23dbde6c0c8f4ce263e9b6a018c2ece8bebfbae1e9ecfb7845f57e31275c982b10c1865b956c0e8e2de385ecbd48511af8b64b9d6c0e8e21956b6e33be1b7e7f1deb24bc64cc776c77d51cab2bdf752e99627e3b906fa7630ae614a0bbccf782c2d7abbe5c978ee83be1ddcf74b6981e30c1e4b0b7c36e862dcc34470e473b863f1e0f34b59ee04604c3a62ec9b05631218fffb5e3130f673c498cc82b11f308afd24607470ff35c5d82f0b46bc4f29cb9d0c8c573a62bc220bc62b8151963b05185ddc4b4d80dfba305e058cb2dca9c078b523c6abb260bc1a1865b9d380f11a478c5767c1780d30ca72a703e3b58e18afc982f15a6094e5ce00c6eb1c315e9b05e375c028cb9d098cd73b62bc2e0bc6eb8151963b0b186f70c4787d168c3700a32c773630dee888f1862c186f044659ee1c60bcc911e38d5930de048cb2dcb9c078b323c69bb260bc191865b91260bcc511e3cd5930de028cb25c0760bcd511e32d5930de0a8cb2dc79c0789b23c65bb360bc0d1865b9f381f176478cb765c1783b30ca721700e31d8e186fcf82f10e6094e5be078c773a62bc230bc63b815196fb3e30dee588f1ce2c18ef02c63b2d8cfd1d31de9505637f6094e52e05c6bbe3674c5d4bf7cf82f16ee0b9277e9e94667767c1738f5b9ed477f5eeb6f8ba377e5fa96d3120a87bddef059e81f1f3a4b6c5bd59f00843312c879add173f634ab3815930de073c83e2e74969765f163c8340b3fb2c9add1f3f634ab3415930de0f3c83e3e74969767f163c8341b3fb2d9a3d103f634ab3c159303e003c43e2e74969f640163c43825acd1eb06836347ec6946643b2601c0a3c55f1f3a4341b9a054f156836d4a2d9b0f819539a5565c1380c78aae3e74969362c0b9e6ad06c9845b3e1f133a634abce827138f08c889f27a5d9f02c78468066c32d9a3d183f634ab31159303e083c23e3e74969f660163c2341b3072d9a8d8a9f31a5d9c82c184701cf43f1f3a4341b9505cf43a0d9288b660f3b627c280bc6872d3c717f27fb218baf318eea3e3aa87bdd85a11896c37e12631d318ec982712c30ca72d84fa2c611e3d82c186b8051964b3866ccd44fa2067c8f8bdf77aa5daa09eaaecf38b73c19fb49a0eff18eb41817d45d8bf16e7932f69340df131c69313ea8bb16138067a2032d12e0a32e3cc2500ccb613f89498e182766c13809186539ec2731d911e3a42c182703a32c87fd241e71c438390bc647805196c37e12531c313e9205e3146094e5b09fc4a38e18a764c1f82830ca72d84fe231478c8f66c1f81830ca72d84fe271478c8f65c1f83830ca72d84fe209478c8f67c1f80430ca72d84fe249478c4f64c1f82430ca72d84fe229478c4f66c1f81430ca72d84fe269478c4f65c1f83430ca72d84f62aa23c6a7b3609c0a8cb21cf69378c611e3d42c189f0146590efb493ceb88f1992c189f054659ee61c78c99ae5f9e6de4bea3ae551abbefa8eb92c6eedbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ece997c3fe7c077027cc85460cc27212f0cc5b0dcc39eb15133224f497c3ca55877f4f53c41dd9fb7f01438aa3bfa7a81a0eec2d0d0189f6b008c0f370046af63ba0f627d1815cf8bf0ff648c3c2f64c1f322f0bce488e7c52c785e029e97e3e749c5d44b59f00843312cf77003607cae01307a1dbd8e4c8c5ec7fcd1d1337a46cfe8198f07634368c33d638388c7b2fa322a9e69f1f3a4347b390b9e69a0992c778f5bc6b2fa322a9ee9f1f3a4349b9605cf74d06c9a4533078c65f565543c33e2e74969363d0b9e19a0d9748b660e18cbeacba87866c6cf93d26c46163c3341b31916cd1c3096d59751f1cc8a9f27a5d9cc2c78668166332d9a39602cab2fa3e2991d3f4f4ab35959f0cc06cd66593473c058565f46c533277e9e9466b3b3e099039acdb668e680b1acbe8c8a676efc3c29cde664c13317349b63d1cc0163597d1915cfbcf879529acdcd82671e6836d7a2192be3c30d80f1b906c0e858c7b2fa322a9ef98e78e665c1331f785e71c4333f0b9e5780e7d5f8795231f54a163cc2500ccb3ddc00189f6b008c5e47af2313a3d7317f74f48c9ed13366c7f87c0360f4dbda33b2323ab8becaf80ecd2b8ddc77d43b348ddd77d43b348dddb78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9c33f97e2d7edf65d97e63e635e071f1cd1b47f52c55eb7d5dafebdb18f5535abd6168f58aa1553194791df47bc3817e05e057d62df3e22f5be60b09981df92e53ed4b2ba8bff878ced043f97fd351dda3dafa371bb9efa8b6beb1fb8e6aeb1bbb6f1fe73ecef3c1b78f731fe7f9e0dbc7b98f7316df986f16d49eb7cbf74fd53aded2f9423d2fe59f07bb9499d822fddb2ef0fb900bdf7e1ff2c78a7cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f73be382f86ff57e680273078820c3cf3c8782693f1cc24e31949c633888ce756329e2bc9789e24e32927e31947c6338c8ce76e329e1bc8782e27e3e943c633858ca72719cf2c329e87c8785e22e3194cc6733b19cfd5643c4f93f19491f14c20e3194ec6732f19cf4d643c49329ec7c878ba93f15c4cc633868c673619cf45643c43c8785e26e3b9938ca7988ca72d19cfb5643c2f90f15c46c65341c6f30c19cf5c329e49643c0f92f1dc47c6534ac6730b194f27329e2bc8789e20e3e94ac633878ca7868c671a194f15194f7f329e4bc878ae27e3694ac6d39b8c673e19cf23643cbdc8784691f17424e3b99f8ce736329eabc8789e22e3e942c6339e8c673a194f3519cf00329e1bc978fa92f13c4ac6d3838c673419cf85643c0f90f1dc41c6938bef9966c3d3868ca7888ce71a329e67c978a692f17426e39948c633838c670419cf40329e9bc978fa91f13c4ec6d38d8c672c19cf50329ebbc8785e24e36947c6d39e8ce73a329e02029e4470f4182609f8ff6b606b622cab3efb3aba43edffdfd6f626b0cc3b3adfd4b2eeb7c126df927dc7b22ceaf436d425a9f3a5df6d4ae984be92302ffe8a80e31d129eebc878da93f1b423e379918ce72e329ea1643c63c978ba91f13c4ec6d38f8ce766329e81643c23c8786690f14c24e3e94cc633958ce759329e6bc8788ac878da90f1bc46c6730719cf03643c1792f18c26e3e941c6f328194f5f329e1bc9780690f15493f14c27e3194fc6d3858ce729329eabc8786e23e3b99f8ca72319cf28329e5e643c8f90f1cc27e3e94dc6d3948ce77a329e4bc878fa93f15491f14c23e3a921e39943c6d3958ce709329e2bc8783a91f1dc42c6534ac6731f19cf83643c93c878e692f13c43c65341c6731919cf0b643cd792f1b425e32926e3b9938ce765329e21643c1791f1cc26e31943c67331194f77329ec7c87892643c3791f1dc4bc6339c8c6702194f1919cfd3643c5793f1dc4ec633988ce725329e87c8786691f1f424e39942c6d3878ce772329e1bc878ee26e31946c6338e8ca79c8ce749329e2bc9786e25e31944c633928c672619cf64329e79643c95169ed71cf1c8fbeeb26e997f8dc4b783ed50aad6fbaea33abda7d7d54caf57f8c55f219499da3afdabde0fc76585cbfc3e01be9bf31e68f49ea3bac8f62830b60ffa7ecb916f79474bd62df36f3572df6d0ddf6df3c4777bc377fb3cf1ede3dcc7793ef8f671eee33c1f7cfb38f771cee4dbc1b541197e274da602633e0979bc5e70f17d3947f53ce23af1db18f5535abd6f68655e5b1543997741bff71de867bbf69479f1972df38504cc18172541bc71b120fe3a95a976ab15e8bac0d017ebb5d091a651c790858ddc77d431a4b1fb8e3a863476df3ece7d9ce7836f1fe73ecef3c1b78f731fe74cbe17e97c8cd78da5e8433d5f94eb8145e07789ce17c4e857ad6bb15e57a15eb7702c01bb94f94f78aee9f779bfcfc7e5db1fdb7c9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8668e73332ffdc52f023657fdf9a3623117ef121c4fdf51b1d8d87d47c56263f7ede3dcc73993efa50e7c27c0874c99faf82d059ec50e781cd533f56c639951a7d78c3a1543193cc62f7350cf02f02beb96f965c0235325f0b88883ba6c73e49947c633998c672619cf48329e41643cb792f15c49c6f324194f3919cf38329e61643c7793f1dc40c67339194f1f329e29643c3dc9786691f13c44c6f31219cf60329edbc978ae26e3799a8ca78c8c670219cf70329e7bc9786e22e34992f13c46c6d39d8ce762329e31643cb3c9788690f1bc4cc67327194f31194f5b329e6bc9785e20e3b98c8ca7828ce719329eb9643c93c8781e24e3b98f8ca7948c672119cf2d643c9dc878ae20e379828ca72b19cf1c329e1a329e69643c55643cfdc9782e21e3b99e8ca729194f6f329ef9643c8f90f1f422e31945c6d3918ce77e329edbc878ae22e3798a8ca70b19cf78329ee9643cd5643c03c878de27e3b9918ca72f19cfa3643c3dc8784693f15c48c6f30019cf1d643c6dc8788ac878ae21e379968c672a194f67329e89643c33c8784690f10c24e3b9998ca71f19cfe3643cddc878c692f10c25e3b98b8ce745329e76643cedc978ae23e32920e0490447bffb9f80ffbf0f367947fd35b02dd7f9c5606b62f1d154e79781ad50e7651d2dc234a5c3d1eb469d5cbd978fbe92302ffe8a80633909cf75643cedc978da91f1bc48c6731719cf50329eb1643cddc8781e27e3e947c6733319cf40329e11643c33c8782692f17426e3994ac6f32c19cf35643c45643c6dc878ee20e379808ce742329ed1643c3dc8781e25e3e94bc6732319cffb643c03c878aac978a693f18c27e3e942c6f31419cf55643cb791f1dc4fc6d3918c6714194f2f329e47c878e693f1f426e3694ac6733d19cf25643cfdc978aac878a691f1d490f1cc21e3e94ac6f30419cf15643c9dc8786e21e35948c6534ac6731f19cf83643c93c878e692f13c43c65341c6731919cf0b643cd792f1b425e32926e3b9938ce765329e21643cb3c978c690f15c4cc6d39d8ce731329e2419cf4d643cf792f10c27e39940c65346c6f33419cfd5643cb793f10c26e379898ce721329e59643c3dc978a690f1f421e3b99c8ce706329ebbc9788691f18c23e32927e379928ce74a329e5bc9780691f18c24e39949c633998c671e194f658e78d4bbedd2d73a002e9c92905f063c0b1df038aa67297ed7e0db18d7abb45a6168f5bea1553194590afaad70a05f01f89575cbfc0ae07956e76ddf54789684516c0b1df324a0ce3265da0756008f8b7dd2513d53b1bad2a8d3b316dda50cc6ea4a07f5b4ed3b32bf12785ed079614d40b9174818c5b6cc314f02ea2c53a6585d093c2ef61d47f54cc5ea2aa34e2f5874973218abab1cd4d3b6efc8fc2ae07951e7853501e55e246114db0ab73ce509a8b34c99627515f0b8d8771cd53315abab8d3abd68d15dca60acae76504fdbbe23f3ab613b7866cf6c63563c72ff5e581350ee251246b1ad74ca535e9a803acb94a91d5b0d3c2eda7947baa7dab135469d5eb2e82e653056d738a8a76ddf91f93516df2541bc5aacad83166b2d3c6b73ac85f8cb9679690364f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e6266d059f1c8f709853501e55e266114db2ab73ca9f7825e0e8e9c0a8cf924e4d702cf6a07fa38aa67aa0ff93aa34e2f5b749732b87fad73504fdbbe23f3eb603b64c3bca601327b9debc7ac78a6e9bcb026a0dc341246b1ad76cb936ac7a605474e99dab175c0e3a29d7754cf543bb6dea8d3348bee5206f7aff50eea69db77647e3d6c07cfec996dcc8a67bace0b6b02ca4d276114db5aa73c65a9f71ba707474e99dab1f5c0e3a29d77a47baa1ddb60d469ba45772983b1bac1413d6dfb8ecc6f80ed900df39a06c8ec75f63a47317b9dbdce51cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9dbdce51cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9df34767c53343e7853501e56690308a6d9d539e2ea9e70e338223a74ccf1d36008f8be7328e744f3d77d868d4698645772983fbd74607f5b4ed3b32bf11b64363675ed300997d6ce486d9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a398196243f1ccd479614d40b999248c625bef9627f5dd8399c19153a67e3b1b816783037d1cd533d56f679351a79916dda50cee5f9b1cd4d3b6efc8fc26d80e9ed933db9815cf2c9d17d604949b45c228b60d6e7952edd8ace0c829533bb609785cb4f38eea996ac7361b759a65d15dca60ac6e76504fdbbe23f39b613b7866cf6c63563cb3755e5813506e3609a3d836bae549b563b38323a74cedd866e071d1ce3baa67aa1ddb62d469b645772983b1bac5413d6dfb8ecc6f81ede0993db38d59f1ccd179614d40b939248c62dbe4982701759629533bb605785cb4f38eea996ac7b61a759a63d15dca60ac6e75504fdbbe23f35b8167aece0b6b02cacd256114db66c73c09a8b34c9962752bf0b8d8771cd53315ab1f18759a6bd15dca60ac7ee0a09eb67d47e63f009e793a2fac0928378f84516c5b1cf324a0ce32658ad50f80c7c5bee3a89ea958dd66d4699e45772983b1bacd413d6dfb8ecc6f039ef93a2fac0928379f84516cd88ecd77c45364f01459b4385ebe9516153adf46ff26e0ff15c0e8aa6d996f30ca3cc6b8d88a72a0595b83a7ada1d9f1f4adb4a884bc9a707b550223c3f66a9b03cdda1b3ced0dcd8ea76fa5456f9d6fa77f717bf5064686edd51e781cb4cfe50983474d998edddb1cebe3a89ea963f7f6c0ae3b1e87a40c1ebbb73ba8a7ed5c42e6b7c376f0cc9ed9c6ac78faebbcb026a05c7f1246b1e139ff8ef879ca13068f9a32b5633b1cebe3a89ea9766c6760d77d07e82e653056773aa86701f89575cbfc4ed80ed930af6980cc5ee7fa312b9e013a2fac0928378084516cdb816757fc3ce50983474d99dab15d8ef57154cf543bb63bb0ebbe0b749732b87fed7650cf02f02beb96f9ddb01db2615ed30099bdcef563563c03755e5813506e2009a3d87602cf9ed879d263be208f9a32b5637b1cebe3a69ee9766c6f60d77d0fe82e6570ffdaeba09e05e057d62df37b613b7866cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367e666563c83745e5813506e1009a3d87603cf87b1f3a49f3b208f9a323d77f8d0b13e6eea997eeeb02fb0ebfe21e82e653056f739a86701f89575cbfc3ed80e9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec99b99915cf609d17d604941b4cc228b6bdc0f351fc3ce50983474d999e3b7ce4581f47f54c3d77d81fd875ff0874973218abfb1dd4b300fccaba657e3f6c87fd9ed9335b9815cf109d17d604941b42c228b67dc07320769ef4f353e45153a676ec80637ddcd433dd8e1d0cecba1f00dda50cc6ea4107f52c00bfb26e993f08db211be6350d90d9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63ae78fce8aa74ae7853501e5aa4818c5b61f783e8e9da74b69c2e0515381319f84fcc78ef57153cff4738743815df78f41772983fbd72107f52c00bfb26e993f04dba1b133af6980cc3e3672c3ec63c3334731fbd8f0cc51cc3e363c7314b38f0dcf1cc5ec63c3334731fbd8f0cc51cc3e363c7314b38f0dcf1cc5ec63c3334731fbd8f0cc51cc3e363c7314b38f0dcf1cc5ec63c3334731fbd8f0cc51cc0cb1a178aa755e581350ae9a84516c0781e793f879ca13068f9a0a8cf924e43f71ac8fa37aa6faed1c0eecba7f02ba4b19dcbf0e3ba86701f89575cbfc61d80e9ed933db9815cf089d17d604941b41c228b643c0f3a9039e84c1a3a64cedd8a78ef57154cf543bf65960d7fd53d05dca60ac7ee6a09e05e057d62df39f01cf489d17d604941b49c228b6c3c0e32256154f91c123f39f12f8565ad4e87c1bfd8bdbab061819b657510e346b6bf0b435343b9ebe9516e320af26dc5ee38091617bb5cd8166ed0d9ef68666c7d3b7d262bcceb7d3bfb8bdc60323c3f66a9f03cd8e677b783cf7ede319a75ef3e3a779c171d4bce0386a5ee035a7d2dcc1f1a50c8f650130e09484fc67c0f3c3f87952f7b83ecb82e787c0f383f8793a3baa67a95aef8f803daef52aad7e6c68f599a155319441861f3bd0af00fccaba655efc7966cf1cc58ce7b6c29a80729f92308aed07c0e3a2dd5075bf4caf4bd6df2c4cfb4eaaf5ebe2d903de776da6d72b1ce2af10cadc5e525bf6a0662b82ffcb7653f53964d81cbd0fdcd9f60c4ce6c55f5190bbfba099eecba2162e9edd647bdc3f64e1f9363e9e52dccfd1d7414775cfe639da410b4f8c75ef1cf50cf140fc754fb51f9df4ba64fd6a1ffdfc24a79a97e3be27ed4727a3ce8550e6b292dab25f40fb616b2b5cef9b724e6eee9b4d82daf64cb84ab4dd7cbef2adb64bb94fa03cb63915fa17f7cf0aa8abab7631ea1e13b68b66dbed527bf3199fe9bb1874f9845433db730ad4b1d2c25d49c08df198cbfd4cd66d7b465669e8c8a6196eeb4f2c3af6b670f726e066dcaf7b1b3ab26976acfdbabf85bb3f0137e37edddfd0914db363edd7032cdc0308b819f7eb01868e6c9a1d6bbf1e68e11e48c0cdb85f0f347464d3ec58fbf5200bf720026ec6fd7a90a1239b66c7daaf075bb807137033eed7830d1dd9343bd67e3dc4c23d84809b71bf1e121ca9239b66c7daafab2cdc5504dc8cfb7595a1239b66c7daafab2ddcd504dc8cfb75b5a1239b66c7daaf4758b847107033eed7230c1dd9343bd67e3dd2c23d92809b71bfae6bbf7dd6fdbac6c25d43c0cdb85fd7183ab26976acfd7a9c857b1c0137e37e3dced0914db363edd7e32ddce309b819f7ebf1868e6c9ad9f66b47efe59565fb9ee061a7faa4c76b3e9c05cfc7c0e322a61cc541a9a37e2ea9bea9070cad0e1b5ae1381807413f077d6132bedf2ffe3cb367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed933f333e3370ef1f98a94fb8484516cf84ccac57d7e55f7cbf5ba64fdcdc2d4f9945abf0763f75b565a60f84b0287f82b8432ff794e6dd9ae9aad28387abbe1b8d6b82df7c75e87f4b634e35fe6c55f11d4e700f038783f3fc573d0e03968d102df3b8dc777d930371a9795aaefefb40a6ab7f37ea33ea8e947b1fb3f52d30243d38f1cfb4e04476e4f61c0290979e471f16cd8513d536dc13ea34ea6c6c550e642a8e73e07f52c00bfb26e99df073c3235011e573118183c81451f992ac9782693f18c24e3b9808c671019cf69643cb792f1b422e3b9928ce749329e72329e71643cc3c878ce25e3b99b8ce744329e1bc8782e27e32924e3e943c633858ca72719cf43643cdf27e3194cc6732919cf19643cb793f124c878ae26e3799a8ca78c8c670219cf70329e0e643cf792f19c4cc67313194f73329e2419cf63643cddc9782e26e31943c6731119cf10329eb3c878ee24e32926e3694bc6732d19cf33643c15643c9791f14c22e379908ce77c329efbc8784ac9784e25e3b9858ca71319cf15643c2dc9789e20e3e94ac65343c65345c6730e194f7f329e4bc8784e20e3b99e8ca729194f6f329e47c8787a91f18c22e3e948c6f33d329efbc9784e27e3b98d8ca73519cf55643c07c8789e22e3e942c6339e8ca79a8ce710194f0919cf00329e93c8786e24e36946c6d3978ce751329e1e643ca3c9782e24e379808ce74c329e3bc878da90f11491f15c43c633958ca73319cf44329e11643ce791f10c24e339858ce766329e16643cfdc8781e27e3e946c633968c672819cfd9643c7791f1b423e3694fc6731d194f01014f2238fa5b4c09f8ff41b0c937833e065b13cbfae439b59457c7c5673b1cbdee2696757f6461409d3e84ba2475bef4bb4d299dd05712e6c55f11707c44c2731d194f7b329e76643c7791f19c4dc633948c672c194f37329ec7c978fa91f1b420e3b9998ce714329e81643ce791f18c20e39948c6d3998c672a19cf35643c45643c6dc878ee20e339938ce701329e0bc9784693f1f420e379948ca72f194f33329e1bc9784e22e31940c65342c673888ca79a8c673c194f17329ea7c8780e90f15c45c6d39a8ce736329ed3c978ee27e3f91e194f47329e51643cbdc8781e21e3e94dc6d3948ce77a329e13c8782e21e3e94fc6730e194f15194f0d194f57329e27c8785a92f15c41c6d3898ce716329e53c9784ac978ee23e3399f8ce741329e49643c9791f15490f13c43c6732d194f5b329e62329e3bc978ce22e31942c6731119cf18329e8bc978ba93f13c46c69324e3694ec6731319cfc9643cf792f17420e3194ec633818ca78c8ce769329eabc97812643cb793f19c41c6732919cf60329eef93f13c44c6d3938c670a194f1f329e42329ecbc9786e20e339918ce76e329e73c9788691f18c23e32927e379928ce74a329e56643cb792f19c46c633888ce702329e91643c93c9782ac9789a183cf87ff56ed8019d976f0715c2ffefd69dcbdbe97549197946acee55ec356caabe7b1cd5776f503b25617e0fd457d8f702cf5e473c1f1a3ca6ef22c8578266bb0d9b62dce58871b7c128f3bb8051f4db0d3cbb1df1ec31784cdf4590ef0d9aed346c8a718723c69d06a3ccef0046d16f27f0ec74c4b3cbe0317d1741be3f68b6ddb029c66d8e18b71b8c32bf0d1845bfedc0b3dd11cf0e83c7f45d04f901a0d907864d316e75c4f881c128f35b8151f4fb00783e70c4b3cde0317d17417e2068b6c5b029c6cd8e18b7188c32bf191845bf2dc0b3c511cf5683c7f45d04f941a0d926c3a618373a62dc6430cafc466014fd3601cf26473c9b0d1ed37711e40783661b0c9b625cef887183c128f3eb8151f4db003c1b1cf16c34784cdf45901f029aad336c8a71ad23c67506a3ccaf0546d16f1df0ac73c4b3dee0317d1741be0a345b63d814e36a478c6b0c46995f0d8ca2df1ae059e38867adc163fa2e827c3568b6cab029c6958e1857198c32bf121845bf55c0b3ca11cf6a83c7f45d04f911a0d90ac3a618973b625c6130cafc726014fd5600cf0a473c2b0d1ed37711e4478266cb0c9b625cea887199c128f34b8151f45b063ccb1cf12c37784cdf4590af01cd961836c5b8d811e3128351e61703a3e8b704789638e2596af098be8b203f0e345b64d814e342478c8b0c46995f088ca2df22e059e48867b1c163fa2e82fc78d06c8161538cef3b625c6030cafcfbc028fa2d009e058e78161a3ca6ef22c8df0936e1ed05b6f774be27d8ded5f91e607b47e7bb83ed6d9def06b6b774be2bd8ded4f972b0bda1f35dc0f6bace9781ed359def0cb65775be0fd85ed1f9be609baff349b0cdd3f97e609babf357806d8ece5f09b6d93a7f15d866e9fcd5609ba9f3d7806d86ce5f0bb6e93a7f1dd8a6e9fcf5607b59e76f00db4b3a7f23d85ed4f99bc0f682cedf0cb6e775fe16b03da7f3b782ed599dbf0d6c0febfced60bb47e7ef00db619dbf0b6c9feafcdd60fb4ce7ef05db0f74fe3eb0fd50e7ef07db8f74fe01b0fd58e78782ed273a3f0c6c3fd5f9e160fb99ce3f08b69febfc28b0fd42e71f02db2f757e34d87ea5f363c0f66b9d1f0bb6dfe8fc04b07daef313c1f65b9d9f04b6dfe9fc64b0fd5ee71f01db173a3f056c7fd0f947c1f6479d7f0c6c7fd2f9c7c1f6679d7f026c5feafc9360fb4ae79f02dbd73aff34d8fea2f353c1f6579d7f066c7fd37969d7543bfb779d2f09e26d67bf096aa712f02dfe54997fe87c73a38c2c5b08655aeb0e85ea19877a7749da616997954ddae1f7c026edf0bb609376f81db0493bfc36d8a41d7e0b6cd20ebf09366987df009bb4c3af834ddae1d7c026edf0ab609376f815b025757e3ed8a41d9e07366987e7824ddae1396093767836d8a41d9e0536698767824ddae119609376783ad8a41d9e063669875f069bb4c32f814ddae117c126edf00b609376f879b0493bfc1cd8a41d7e166cd20e3f0c366987ef019bec2fdf804ddae6c36093b6f953b049dbfc19d8a46dfe01d8a46dfe21d8a46dfe11d8a46dfe31d8a46dfe09d8a46dfe29d8a46dfe19d8a46dfe39d8a46dfe05d8a46dfe25d8a46dfe15d8c6eafcafc1266df36fc0266df3e76093b6f9b76093b6f9776093b6f9f76093b6f90bb049dbfc07b049dbfc47b049dbfc27b049dbfc67b049dbfc25d8a46dfe0a6cd2367f0d36699bff02b667745edaea96609367c56a2afd8e138ec3d3047c094b3288b7edc7290979acbb4c95643cb3c8784692f1bc45c6730119cf20329ed3c8785a91f12c20e31947c6339f8c671919cf52329ef7c978ce25e3d944c6b3918ce744329ebd643c7bc8782e27e32924e39941c6f306198fbcf7c9c233988ce752329e33c87812643c73c9789690f12c26e379978ca70319cf06329ef5643c2793f1ec26e3d945c6d39c8ce71b329e69643c1793f1bc46c6731119cf10329eb3c8788ac978da92f15490f15c46c6339b8c671119cf42329eb7c978ce27e35947c6b3968ca7948ce754329e9d643c3bc8783a91f1b424e379898ca7868ce715329e2a329e73c878fa93f15c42c67302194f53329ede643cf790f1cc24e379938ca72319cff7c878d690f1ac26e3f92b19cfe9643cdbc978b691f1b426e33940c6339e8c671e194f3519cf7b643c87c8784ac8780690f19c44c6d38c8ce73019cf74329ed7c9785691f1ac24e339938ce703329ead643c6dc8788ac878e690f18c20e379878ce73c329e81643ca790f1b420e379998ce755329e15643ccbc978ce26e3d942c6b3998ca71d194f7b329e7d643c1f92f11410f0248023009bfcbf29d8e43b3c87c0f6b5ce1f009b7cc36701d8bed2f967c0f694c5d6c4c2270c53c126efca7e0d36b93ff334d8e49d89afc026e70de25fcd4fef70347f135846fc34b5f0a3bfaf2c5c92c7ed2dcb248378b737fa4a06f66fde15188cc79be743329e7d643cedc978da91f16c26e3d942c6733619cf72329e15643caf92f1bc4cc6d3828ce714329e81643ce791f1bc43c633828c670e194f11194f1b329ead643c1f90f19c49c6b3928c671519cfeb643cd3c9780e93f13423e339898c6700194f0919cf21329ef7c878aac978e691f18c27e33940c6d39a8c671b19cf76329ed3c978fe4ac6b39a8c670d19cff7c8783a92f1bc49c633938ce71e329ede643c4dc9784e20e3b9848ca73f19cf39643c55643caf90f1d490f1bc44c6d3928ca71319cf0e329e9d643ca792f19492f1ac25e35947c6733e19cfdb643c0bc9781691f1cc26e3b98c8ca7828ca72d194f3119cf59643c43c8782e22e3798d8ce762329e69643cdf90f13427e3d945c6b39b8ce764329ef5643c1bc8783a90f1bc4bc6b3988c670919cf5c329e0419cf19643c9792f10c26e3f93e19cf1b643c33c8780ac9782e27e3d943c6b3978ce744329e8d643c9bc878ce25e3799f8c672919cf32329ef9643ce3c8781690f1b422e3398d8c671019cf05643c6f91f18c24e39945c65349c6d3c4c273c8118f7c2b46d62df3871ab9ef3d86ef3d79e27b97e17b579ef8de61f8de9127beb719beb7e589efad86efad79e27bb3e17b739ef8de68f8de9827bed71bbed7e789efb586efb579e27bb5e17b759ef85e69f85e9927be971bbe97e789efa586efa579e27bb1e17b719ef85e68f85e9827be99afbf553f5ce9abbc4fff26e0ff15c0b8c011e3218351e61700a3d8f07bd4158e78a2aedd2b087c2b2de45e963cf34cc0ff2b81d1554c55188c326f8ba93dc053e98827ea9e4325816fa585bc8b2d7d2a13f07f1c7fd9554c551a8c326f8ba95dc0d3db114fd4bd92de04be9516f2eeb3bcf39780ffe378ebae62aab7c128f3b698da013cfd1df144dde3e94fe05b6921df0a936fd224e0ff383ea3ab98ea6f30cabc2da670fcdc018e78a2ee4d0d20f0adb4906fedca372f13f07f1cbfc9554c0d301865de1653387edc40473c51f7d40612f8565ac8b360f9467b02fe3f08185dc5d4408351e66d3185e3dd0c72c413752f7010816fa5c5609d973e5609f8ff6060741553830c4699b7c5d446e019ec8827ea1ee66002df4a8b213a2fef7024e0ff4380d1554c0d361865de1653eb816788239ea87baf43087c2b2daa745edee94fc0ffab80d1554c0d311865de16536b81a7ca114fd43de32a02df4a8b6a9d976fce25e0ff38fefb10478c5506a3cc0f0146b1ad069e6a473c51f7baab097c2b2de4dbfeabf46f02fe8fe3b1ba8aa96a8351e66d3185e3418f70c413758f7e04816fa5c5489d97316112f0ff91c0e82aa646188c326f8b291cbf72a4239ea8670b23097c2b2de4db5ccbf46f02fe5f038cae626aa4c128f3b6985a0a3c358e78161b3c8b2d5a1c2fdf4a0be9cbbd44ff26e0ffe380d1554cd5188c326f8ba9c5c033ce114fd4b39c7104be9516f26ded45fa3701ff1f0f8cae626a9cc128f3b6985a083ce31df1443d831a9f03df51cf5372e13bead9402e7c47dde7ce85efa87bb6b9f01d75ff3117bea3eea5e5c277d47da15cf88ebac7910bdf51d7ebb9f01d75ed990bdf51d751b9f01d754d900bdf51e7b7b9f01d75ae960bdf51e71dbe3df7ed79dcbe8fe7b943beb6e7c7f3187a3c8f25fedac05f1be4cab73f96f86b835cf9ced76b03df9ee7be3d97ebaf8220fa7a6cb923df4b0ddf328fcf59963af2bdd8f02df3f8cc60b123df0b0ddf328ff7bf173af25d64f896f98539f0ddd6f0dd3687bedb1bbedb5b7cbbd8de89e0c8eb6f61c02909798c81450e781cd5b354ad77895ed7b731aed776dfc6dc5f8aa1cc12d0cf75db21ebced476b48ccf7769027cc837be944d9ec5be07366943df059b3c637f076cd2cebf0d3679bef316d8e4f9cf9b601ba9f387c126cf61b1ffbb3c4bdf01b62a9dc77ed743747e1bd8a45f12f6f795be655bc126fd03b19fa9f4f1dc0c36e9a78bfd1ba5aff546b0497f79ec5727ef3cac079bbcb782fdb9e4dda3b5603ba0f3d88f48bee9b21a6c53757e15d8fea2f32bc1f6a4cedf03b62f75fe1bb0fd59e71782ed099d5f04b63fe9fc12b03daef36f80ed8f3aff3ad81ed3f9d7c0f6a8cee37b617fd0f90fc1f685cee3fb4853747e0fd87eaff3f81ecc233abf0b6cbfd3f957c13659e75f01db249d9f0fb6dfeafc3cb07daef373c13651e7e780ed373a3f1b6c13747e16d87eadf333c13656e76780ed573a3f1d6c63747e1ad846ebfccb60fba5cebf04b65fe8fc5fc1f690ce2f065b139d5f0a36197f11fb7c14eafc72b0c9b8f4d89747be953f1e6c2d747e1cd85aea7c0dd8e43b6b23c126632b8f005b42e7abc1d646e7abc026e73a43c02663890c069b9c970c025b3b9d1f08363987180036191bb23fd8e47b9ebdc17692ce57824dbe535f01b65374fe10d864fcae0560936fc01d009b8c6bfc34d8e4dbcf53c176a6ceff056c32a6c993603b5be7bf04db393aff67b0c9f7309f005b89ceff096c1d74fe71b09da7f37f049b8c37f518d82ed0f947c126e3f0fe016cf2ede42fc076a1ce4f01db453aff7bb0c9b81c8f804dc6dafc1dd83aeafc64b0c937ad2781ed329dff2dd864ecbccfc126dfeb9d08361923ed3760ebacf313c056a6f3bf065b179d1f0bb6729dff15d8baeafc18b075d3f9d160ebaef3bf045b0f9dff05d87aeabcb4336a7f56fbf9413d9f0ce23dcffe383872ca749e2d0cc813e7796b31f0a0affdb1d7bd2c758e2cfb7d13bd5e89a1fde07b5fecbed3e7e71fe97515eaf5ee337c17429996ba7150cbc931bfa95eee80b11cde139275cb329783fd4363dded747d3f7254df7d069370a30e52a68d6652c7c68d3adf12968991ad4ced03126b0168885312f2c2e046abb2523cefad0bcf47c0b33f769ef4b5af8b98c07d2bee6b5ff39ea8196bc550661fe8f7a103fd705f9775cbbcf8f3cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfcccfac780eea3c3e579672074918c5b61f785cdce7c7e7b0b27ef55ce7fd736bfdee8fddef91cff79ae9f5961a752e84327f86674e8b75be08fe2fdb2d6a5b3a784e98715b8abf22a80f3e0b3ae88867bfc1b3dfa285e44b62f35d36cc8dc665a5aadf8a7ac67ec0d0f5a0455357fbeb7ebdae024353dc5f3f3678f0d96811f07ea27f13b09e4fa00e0ef6f18c7121fe705fda0f36c97f0c8c2eb6331e4ba43d90e7e1f86c5acaec329e8bc7bfedcb4a5db61b7ba14ec9e0e8f82e8432fba0eddbaff3d837e420e8f633cbff65caf49c5af45375de1d7f9d53db77177026c10ffade09ac31f93ee27d94029dc48fd80b21ff53e8cf21e5440fd15ad871ec6f643797fbd858ae18caecb1d43f19c45bffdd06cf6e83596d938f21ce7e06c77f576dd29e088d2e078da4cc7ed0e880239efd068f70883f5546b67f73a38c2c5b08657e0b6d94aa8bb4f3524fecdb82c70057c731f125eb9679dbb9f147c068d651c547e7536a79f7c7cedbb0fa7ffd03da8bb8fb7ffd0362a800380263fda5b07ee16a1e441f5ba4ccff308ea32eae31705b9a7aa2ce52e67f413bf4fd92743e9b73fde375dd1675aebfc7014f2238f2da5b4d998eef788cd9eb80c7513d4b6dc7ae0f8d3a1543990ba19e0ece6332be57bb1b7cbbd8e6a8859c43ed33b42884320525e95f693ba274c46bd58f72529732ebf960a9a52e52a645496d5d5a823d4e2697db6d27d449ad77bfa5ae52a64d49ad2ec53a9f80ed84f74dceb6fc5fa64ced018e6bb33dfe3aa7b6ef36e04c821ff4fd01b0c6e4fb88ef6ac8f9bef8117b21e4cf2aa92d2be5440fd15ad8d53e22effc21bbb9dc3e63b96228b3c352ff64106ffdb71b3cdb0d66b54dda97d4e6258e5cb69b3b22342a058da40cde3f96633bbe77673beeef77c41d75dcdf0f8c66bb89e72e2ed90e186ce63d54dbf9a094c1733229d3b124fdabdad984a56cb3e0c87bc32eee63e23ba801d42330ea2a13c680836bc372bc7692764afc7402fb7e9d179d3b19da154299ae25e95f87e7ddd67b97e6f51d5e5308b7b96fe1bb1fbd4a6ab9711cc2fdfab7086c9fea5f47d769e5b67b86c261bb67982ca965c76585ebb0a52ee6357293e0e87beadf1a65f1be5ba6e5ccbc39a6a3d2f753a39ccd0f5ef3c4f6ae46e7d252646a12d8ef177c6cb01704478f5f29fb01c69c791fa593b11ebc8f726b49fa57da24b3acdaf69f9f54ab8f6c47d10edb138cc98f8131a9f3a5df6dea6cabbfcc8b3fc5f8895107376d57fa7da56cee031f001e176dbba336ba148fb1f17d9fa26795edf8ffb1a1550e9fd75a8ff9e633f796463e1edf65d5b6fb4f362df659785c3d4789d2629fc5777c5a741b663b7ed8b4c865df87282d3eb4f88e518b1178df3393167b2d3c2eee4565d262afc5777c5a742fcdf45c03b5d863e17175ef214a0bf1972df38704cc2d8d7c3cbecbab6cf7c96c5aecb6f0b8ba6e8ed262b7c5777c5a74ee86f7e83269b1cbc213fffdb9cc5aecb2f88e4f8b1e3df11e5e262d765a785c3dd38dd262a7c5778c7131dc762fc7a6c50e0bcf8e1c6bb1c3e23bc6f3c36eb67b6d362db65b781cdc77cda8c5768bef18b5188af75d3369b1cdc2b32dc75a6cb3f88e4f8baaaeb67bc2362d3eb0f0b8ba271ca5c50716dff16931b487f2bdb50e5a6cb5f06ccdb1165b2dbe63bc864ac5c5963a68b1c5c2b325c75a6cb1f88e4f8bead4b9d6e63a68b1d9c2b339c75a6cb6f88e4f8bd2d43175531db4d864e1d994632d36597cc71817a9ebc98d75d062a38567638eb5d868f11de3712415171beaa0c5060bcf861c6bb1c1e23b3e2d46a4ee3fadaf8316eb2d3ceb73acc57a8bef18efb9a4e2625d1db45867e15997632dd6597cc7a74597d431756d1db4586be1599b632dd65a7cc7a7c5f0d433b13575d0628d85674d8eb55863f11de37967aabd585d072d565b7856e7588bd516df319e77a6ee5facaa8316ab2c3cab72acc52a8bef18dbced479e7ca3a68b1d2c2b332c75aacb4f88ef1bc33a5c58a3a68b1c2c2b322c75aacb0f88ef1bc33751c595e072d965b7896e7588be516df31c645aaed5c56072d96597896e5588b6516df31ded74ab59d4beba0c5520b8fabf11aa2b4586af11de3f548ea1edf923a68b1c4c2b324c75a2cb1f88ef15951ea1c7c711db4586ce1599c632d1683ef03b1fb4ef7e7161fd217eb32438b4228f36d49fa57fa6245e928ebc07e65589745b1d725ddaf6c61445d16415da44c6187dabab40c9c8cf753eea8aea99859007552ebfdc4525729d3aa43ad2e099d4fc036390cba9d61f9bf4c05c67c12f2a29faaf37bf1d73915abef026712fca0ef77803526df9dd177814ee247ec85903fbd436d5929277a88d6c2aef691f7751ed9cde5161bcb154399f72df54f06f1d6ff3d83e73d83596d936288338923376d579ae9fd088d2e038da40cf6d9fbc4118fd9875038c49f2a23dbbfb95106fb504a99f3a08dc27ea552cf447074bf49476d5967649775cbbcf82b06db016034eba8e2631ff4fd94b122641c0965937121bac07aba1b3655d71e8eea2abe64dd32df0318659c8aeeb9672cab2b63378351f1f472a0198ebd2153a6e3452fe0e9e980c7513d53c7a10aa34e3d8c3a1543197cb7b1c2413d0bc0afac5be62bc0b78b6d8e5ac831f962438b42ac37b46799749475a8f8ed6ea94b1fc77591754bbbd42707be2b0ddf5d0ddf89e0c8ed1c0499f7af4a60eeed8059adb76ffceb2dc5f3368929f1d315ead40f3488ab4eb82e39cfeb67685b08f9fe709e27e5a4ac1cbf845dc5b26c4b643797eb652c570c65fa58ea9f0ce2ad7f5f83a7afc1acb6c90d706ee7607f48c5401f8343e6bb82767d23b4eb03da49193cfe7573a45d6f8347e6bb018f9ce354804dce15843f01ffef92036eb3ddabb0708b0dc789eb6661ec1a3f63ea5ca79bc128f35d81516cbd81a7d29166e6b6bed8d0078fcbcd8d32b26c219479088e8d094b59b5df5d58505bafa6da1edbbb63ba4d6fee402f1ca731007d0243c300f4927a3673c0d33aa81dab71e2a49a09431f1c7ec7f0f4a347412b3430f1b7c0528d2660c37c538b2d088e1c92b2106c32246533b0353164c1a130a5bc0c69e7422ed443d65d6870b60496387de3709e32650a9d16c0e3229455e8c8909e3a74ee99306ad2708c8f6606677d6247fdaf69867251eb72b51dcc7d2209f3660c163af2df14ea9b8479f1a7b68d0cad3a6ee8b087fb4d7870f298e163274d44a1cc1d1bf305c1911bc0fc8d12dcd54e87018015c6c6a199512f6c30e47fb2615ac7cf598e63e69ada04e04fa6d6a05b2b07baa9f5cbd8b7c3868e1e7ddbe4aad1a3865d3379ecb049a36ac6e2d66c692817b5a5e5ffcdc1666be2b1ac9ab0d9c2655b586cb60947196e09363972b5029bf0b4065b53c84b7973cb3809d70b60fdb24ba9ff29719ae98ab7086a43400ec7aa5d55fbaf3a95539f9055a7426a6863b539d5d0c5ea8ea11a9a587dc54e0d3dac861a56430b9f11a4870e5643059f1da48702565fbb2809d243fb9e17d40eddaba6c3c0f9bd203d34afba4d7351903eed5243eb760cd243e7aa5b979d82f467ded4bbf5eaf45ddd1650a7bcea124f9d7eaad34e7579a16e5fa85b59ea944e9d2eab534175faa62e47fa6aadfb85e98a305d19a6abc2747598ae09d3b561ba2e4cd787e98630dd18a69bc27473986e09d3ad61ba2d4cb787e98e30dd19a6bb82f4f0ce7707e9e1d7d5f0cff706e9a1a1ef0bd2c346df1fa487947e20480f373d34480f453d2c480f533d3c480f61fd60901ede7a54901e26f7e1203dd4ae1a82776c901e0e5b0d93ad86cf56c3fcaa2181d590c26aa861352cb11ac2580d81ac86467e3c480fb9ac866c7e2a480ffb3c354ccf84e9d9303d17a6e7c3f442985e0cd2c383ab61c3a705e961c6d5f0e33383f470e5b383f4f0e66ad873351cba1a265d0d9fae865557c3bcabe1dfd5b0f06f86e9ad30bd1da41f49a84731ea1185bafdaf1e83a95bd48b82f4adf32541fa11b77ae4afba40a82e21aa8bccaa20dd854a7529535dec549743d505537549555d74559765d5855b7569575dfcd52b0fea1510f54a8c7a4548bd32a55e2153afd4a9570cd56ba2eab54bf51ab17aad7a7f90be2d7e30483f2a55b7c3d5a301158feaf6fd6761fa41987e18a61f85e9c761fa49987e1aa69f85e9e7417a586335dcb11a2e590dadac8661564336aba19cd550d06ad8e82f82f4d0d36ae8ea3f05e921b1bf0cd35761fa3a480faffdd730fd2d4cdf84e9ef61fa4798fe19a67f05b54369636371866e61f4554a3074d2a4e163c64d2a9954533266f2e849a3c68d7eac64caa849234b6a1e193e61c4e89a29b8f00ff5c2320e78bf0913863e56326a6cf5f0474b6a264f2aa91951525533796cf51107ea7fea85ce3adae3d0eaea6867fffe5d48ff6f3d9db6d26d9f8cb07e7de6bab5695a0f414ea8cf42dd9ad6af4213f4514a2e67ef4c9feb964c1c5d33a9a4b4646cf8373cb8d64c195edda904ff37311479e2a4928993864e9854326242cd9892ce9d70bd4fb7ae4725fea3b51b985667d44f9c16fa5b4af50ab19de7d64381cfcfad1fe9dfbf0be9bfd5d369eac09b6d0d9bd767a14b4aea47585e1229cbc4c95593260c1d36297ae19edf65e1bef5a9e62df5ace67fd5c759d30ef558a84387fa11f6ad8fb35159380bfe3f244cae11d44d06009b2d6c6f00000027cc1f8b08000000000000ffed9d77701cc795c667911856581024981324db1423b8586430813953a6242b072650a44512140925cbb2244b72ce395b4e6739e77c9673ce39e7ecba2adf3f57bef255b9ae7bb69ff1a139b3c6aee6816fb06faa1eb6e76defbc5f7ff3a667b67b7690098acb9f8d655cb9d6d8638273177a7fc0bde61fddd29ee0b6f29c9c999470d6a484b336259c7529e1ac4f0967434a3827a58473724a38a724c899013e2edea929e3cda68cf782201d79db9812ce5c4a389b52c2392d259ccd29e19c9e12ce1929e16c4909e7cc9470ce4a09e7ec9470ce4909e7dc9470ce4b09e7fc94702e4809e7c294702e4a09e7e29470b6a684f3c294705e9420e70ae0a431f2c7bad7c7b9d725eef562f7bad4bd2e73afcb5d1bebdcbadde64a63ab8cb579efadb6ccc6ec6079c17bafc358a7b12e63ddeebd56f75e8fb15e637dc6fa8dad31b6d6d83a63eb8d6d709a6c34b6c9d866635b8c6d35b6cdd876633b8ced34b6cbd86e637b8ced35b6cfd825c61e6f6cbfb14b8d5d66ec72634f307685c772a5b1ab8c5d6dec1a63d71abbced8f5c66e3076a3b103c60e1a3b64ecb0b123c6068d1d357693b163c68e1b7ba2b19b8d9d3076d2d8296343c64e1bbbc5d81963678d0d1bbbd5d86d9e66b71bbbc3d89dc69ee471de65ecc9c6ee36f61463f718bbd7d87dc69e6aec7e630f187bd0d8d38c3dddd8338c3dd3d8b38c3ddbd8738c3dd7d8f38c3ddfd80b8cbdd0d88b8cbdd8d84b8cbdd4d8cb8cbddcd82b8cbdd2d8ab1c0b1d08af36f61a63af35f63a63af37f690b137187ba3b137197bb3b1b718fb0f636f35f6b0b1b7197bbbb177187ba7b177197bb7b1f7187bafb1f7197bbfb10f18fba0b10f19fbb0b18f18fba8b18f19fbb8b14f18fb4f639f34f688b14f19fbb4b1cf18fbacb1cf19fbbcb12f18fba2b12f19fbb2b1af18fbaaa7f9d78c7dddd8378c7dd3f9bee55ebfedead231ff1df7fa5df7fa3df7fa7df7fa03affe0fbdf51f79eb3f76af3f71af3f75af3f73af3f77afbf70afbf74afbf72afbf76afbf71afbf75afbf73afbf77af7f70af7f74af7f72af765e6dc5cc62797230b20c0409f5499d837d765c9dc4f6e7edec9c50ad7b8f5e5b9dbfceadd36bc6f9ebdd7abde76f70eb0dde7626bbf5c99e3fe7d6739e7f9a5b9fe6f9a7bbf5e99ebfc5adb778fe0bddfa85e0cfbaf78a0d2bbe585fad7365c047f95903be7ae7ab055f036d0e7c939caf1e7cb47f1bc037c5f926816faaf34d065fd6f9a69096c62e70be8120a95cc91fb4db6d4c7abb6e2e22973cef21bbdd2626de69c9f31eb6db6d66e0b5f931dd6dab11f26686f3e5c0d7e27c4de0735dd0bf8e39eb9be57ccde09bed7cd3c137c7f966806faef3b5806f9ef3cd04df7ce79b05be05ce371b7c0b9d6f0ef81639df5cf02d76be79e06b75bef9e0bbd0f91680ef22e75b083eea2f1781efb1ceb7187c746dd70a3ebacebb107c74cd7791f3d97e627206e2393ff551613cea9fc1f738ea9bc1b784fa65f05d4c7d32f896426cf22d837e857ccb9d8ffa28fb5ebf2b0f04491d1385f0185e93f476cd96ed76d725bfdd700e6c7d30a2f500c459035a6d70e504ef0f69c7d8741d4371c85f07e59d5097ea911e749e2176dbefaf75e50d253ed7ef7d2e0775d646b47f2048b6fdeb3c9e751e733db49f29678f6ace8e79293b67af84ba7eeed135cf44ccd93dc0917cce767468ce8e79293b6707a1ae9f7b74dd3b1173f61ae060c8d91e9e9c2de435678be36041109d7bf4dd6722e6ec31e0483e67bb3467c7be949db3f7415d3ff7e8fbef44ccd9db8023f99cede9d16b83312f65e7ecf3a1ae9f7b3416331173f601e060c8d943dacf8e79293b675f0b75fddca371c18998b32f028ee473b68f29673b346783e29c661044e71e8d514fc49c7d083892cfd9c33a3e3bf6a5ec9cfd18d4f5738fe64b2662cebedb95ed3cc3b7dc3cc302f07ddbf916026ff2b97da49d29b7db35b78bf77a0441748ed2dcdd44cced475cd9e6f177e1de03f27d8fee4b00dff79def22f0fdc0bb6783e918e8d66360ec6d2af718f819d4f57399e69127e231f06de060c8d91ecdd9b1b7a9dc9cfd0bd4f5738fee69988839fb4be060c8d95ecdd9b1b7a9dc9cfd3bd4f5736fa92b4fc49cfd2f57b6d70b3f71d70bcbc1f753e75b01be9f39df4af0fddcf95681ef17ced706be5f3adf6af0fdcaf9f2e0fbb5f3b583ef37ce5700df6f9daf037cbf73be4ef0fddef9bac0f707e7eb06df1f9daf077c7f72be5ef0fdd9f9fa9ccfde9347f75e7dd1f9ecbe258d068264f72ddd6349dba6f595e310bbc98bdd348eb19bbdd8cd11b15731c4ce420c5a32defa009457f1f2e473c083b156271fabc3b6bd2d187bdb57034f9ea1ed598831169e3cf0b427cf139e3f0bc96f37dcc76d9ea65988d506edea6068570662d1b6699de2e5c087fd7747046367f28c850cc4a26dd37a2730920fcf27745ea7e3c79e0f97644678198ea5f09a88e2d1f39f886335f8a9ce375b46d8963bb646781fcfaded9e8f292fc3bca058b46d5aa7788dd09ef6f1672c8c9531ef3172f511198845dbf663e3f1be6afc351bd37ecd81ef3cf449854afba446601b8feb94b87d2d2536c7f92a0331a86f23cd0be0a73ab3dc0f126cdfb61dfa5d86e3af50eef51bf607c9e771218fc7f558783a8087e3d8673a5ef378deff67906cae75795ab57b5ae5a04e27e8d7c5a05fa9eb108aa7cccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaacccf299f1fe0b9cdfa47a2b853092af003c1ce3fce133a0dcb668fb765ee7c730af93fcbc45218f7396748fe132afcd7550e7af9991ba3f87f9747f6e10e73457f26a37a6fb2c1a8373e76239e710e3e681a3e62f5b138b5d38cc35df66ef51b3cf216bf3745d19a129c37d2aa334cd789ae27d8a2b3c1e9ba7736b47d838e6feca9d8b44ada89ce4dc1ede63c0bb5f8afd07e5424d30baffc0f34c77e2b147cf61d27c79b717bb0eeafc6f6664dfd0bda8f4bfeefc7b9e6c9d1e6fdbf49965e0eff1b63dcd7d9638eabdedb7c167a9ceff419ffaba9ae05f9a71dcff81fd72006dc56500ca386f9efc79b8388fdf51064f17f070f4334cd71b793c06929ec7eff1b48aba8ea13adda05f0f837e51d7a2b44ef194599995599995599995599995599995599995599995599995599995599995593e33fe569458b350af2084719cee7d08e733e8f92fb47d3baff39c9a91b8dcf37034e7b4dc6b731dd4f946cd48dd17b8726370eefd0e71fb92613eafe4bea4788dd01e9c0be2fa3d77a7c7d319a105955b138b5d9cc74f5ee39179fc0e4fd74284a65cc72bceb1a2a678bcb67b3c3837da189c7b6f4916b6331ef70ec5e505c5c363a9137c54c6df4773ec673c97f8f7f5503c9cbf7ed8693b2de0daf7853c67bfd10b6d1a08cecdef3aa8f32ee8fbdee3ca780f07de3bf248c4fbb4949aa726fd589e65972fcefbae01ce018883b1d7026b42b1db3176c619c5217f1d943f59335297ea911ea435b1db63849e0986ecfee7dabdcfe5a04e5f44fb078264dbdfeff1f47bcc769fbc1ff2ec1138ff73f5497d311a2d038da80e5e0771dd93e7f791fefd8d78df5e835707af59a8ce17a18f8abb7f34ea9e43aef358dc3d8751d7c65dc0e8b7d1bfcfb3daefd3fa21f41749dfa7f543c821bc4f2bf0b6bf1cb64f5c0d41fcb985eafcd4dbbe7f4d4e9fc1fbc0a8ce2fa0bf6872f72c3606e75e7fe33d53e3f1fd2aee3e698a87d735786cffbbb65be65ea83f902033e604b2e07502d5f993b7cf7a62b857477cf6af319f25ade83954f8fdc5d7cfead0079f19484487e231dfefb585f2ba0fda4275fedbbb064cfebaa5780d987c5b475f93503fd019d156aaf33f70acfd1daef1683fe1f78e86da73dfa7a5d43520e967db3cdecf07c6d8129e0f5c5f3b52d77fce2f695deef381bbbdcf497c3ef03f20cf1ae03e74aebe7a6d8c46cb4123aa83bf0da2f3083ecb37ea1cc3756f7fdc3926ea1994d83f37d58e3f9b3fae16758d4075e8b3788dd0e298a7399dfdbafe78219d2f93bc6f187f2bd10671f1b7126d4c7ae641b70158c7eb82f3193bcf143bee99d3f971881df7cce9f188ddecc56e1ec7d8aab96a2e497386672287bf3fc36796daa5d4752931e4e073352960ac4d01635d0a18eb53c0d89002c64929609c9c02c62929609c9a02c62c309ecf733b833e854af5e1da5fa5ae353036c3ff2e2994fbff3b98ff974ac96b1f8ccdf09d2ed4625530762df07b1ec7b31fcafd5f2fc480ffbb607a0a1867a480b125058c3353c0382b058cb353c03827058c7353c0382f058cf353c0b820058c0b53c0b828058c8b53c0d89a02c60b53c078510a181f9302c6c7a680f17129605ca28c8930aee0652c54ca687938fee7dfa3f99f630c3cf9a87b4e997e7b52f6ff5b637e3e697ba5cf8dc37b4b78ff27dca37bb61dc7bd23e53edbaed4ff5b65622c54cac8751f3bfe8e672c3cf8bbc8a8dfd63030162a65e4fafd0bfe466f2c3cdda0595784660c8c854a19b9ee952bf75e4ebca7bf3b423306c642a58c785f75823ca1663d65f0f482663d119a3130162a65e4ba2f390b31c6c2d3079af54668c6c058a89491e9b76da1667d65f0e06fc0fa223463602c54ca6879d63069d65f06cf1ad0ac3f4233498cc893f473b2fb236271fc66b0dcb61303324e4901e3d41430e27d121cfd57a9fb24fa79f52954aa0fd7fe2a759f04c666f87d4ca805fe1ee2df69b18e97a7e47d12187b3d9316f87b957fa7c57ae0e1f8fd4c16628c85871872f0b9e929609c9102c6961430ce4c01e3ac1430ce4e01e39c1430ce4d01e3bc1430ce4f01e38214302e4c01e3a214302e4e01237e5765b8562cf9fd65fd048f1df75d65a2c78efb5e32d1636b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae79262a7618c5f19271e23f2b426c793c7b663ac01016d1f88e0c930b51d636d14d07662481be3861430ae4901a3ea58bc07b11246cbb389896763193c9b80673313cfa632783603cf96e479c29cda5c060f31e4e0736b52c0b821058caaa3ea28895175ac1e1d955119955119cf07631afa70654c453e162a65b43c5b93e70935db5206cf56d08c3ed7cecb58a894d1f26c4b9e27d46c6b193cdb40b3ad119a3130162a65b43cdb93e70935db5606cf76d06c5b84660c8c854a192dcf8ee47942cdb697c1b30334db1ea1190363a15246cbb333799e50b31d65f0ec04cd764468c6c058a894d1f2ec4a9e27d46c67193cbb40b39d119a3130162a65b43cbb93e70935db5506cf6ed06c5784660c8c854a192dcf9ee47942cd7697c1b30734db1da1190363a15246cbb337799e50b33d65f0ec05cdf644682695714d0a1837a4809159c742a58c96671f13cfde3278f601cf254c3cfbcae0b904781e9f3c4f98539794c1430c39f8dc9a14306e4801a3eaa83a4a62541dab4747655446652c8f7120058cbaaf95512a23c3f7ab92bfa1b96482c76ef262375549ecb8dfd04cf4d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e6b9a4d8fb938f5d28f71933fb8187e399374cedccdbed5eeab6f5cf04f5b35a5de6697589a7550eea5c0afa5dc6a05f06e2d2b6699de295cb7cb10066a6d805dbbf4c81f6538c0d9e1e36fee54c6d8febeb2f9fe0b1e3fafa891e3baeaf9fe8b135cf35cfab21b6e6b9e67935c4d63cd73c97121bcbf5c1c8753b3dffd46ee309ae5ce7d69195fc54e7f1938aafd3023d863862eb31a4e78a6a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9ecbcbf31cbc5f330e3c81c71394e059248c678e309ee9c278a608e359268ca75618cf7a613ce3713f5f393cbb84f16c17c6d32b8c67b1309ee5c278e60ae32908e399218ca74b18cf54613c5b84f1d409e3d9288c272f8c678f309e25c278e609e36911c6b342184f56184fbd309e4dc278560be3592a8c67af309eddc278fa85f1ec10c6d3278ca75b18cf7c613c1dc278660ae36913c67381309e46613c5b85f13408e359258c679f309eb5c2781608e399258c27278ca74918cf24613ceb84f1ec14c6b34d184f8f309e85c2783a85f1cc16c6b35218cf34613ccdc278360be3992c8c272380271b9cfb4cb22cbcbf1f7c35de67edf540f3cc91f7af70fe1af8cc95ae5c1bb1ed2bc047bf0dbf32e2b3a8d315d0960157ce3fba25d409630dc03ac56b048e2b85f04c16c6b359184fb3309e69c278560ae3992d8ca75318cf42613c3dc278b609e3d9298c679d309e49c2789a84f1e484f1cc12c6b34018cf5a613cfb84f1ac12c6d3208c67ab309e46613c1708e36913c63353184f87309ef9c278ba85f1f409e3d9218ca75f18cf6e613c7b85f12c15c6b35a18cf26613cf5c278b2c2785608e36911c6334f18cf12613c7b84f1e485f16c14c653278c678b309ea9c278ba84f1cc10c65310c6335718cf72613c8b85f1f40ae3d92e8c6797309efdc278d60be3a915c6b34c18cf14613cd385f1cc11c6b348184f4d040fc3ffbf0c79e8fe35da36adef17129b613f84fff7f32aa6365dedb655efb64bfc14af0eea5ce33a0a7b7f157e96b8fcfb0df1dc7435687435535b687f64bcfdc31d1befab0c8021f0f409227838ee47656ae7a83c4cf0ffcfe6ad56d7785af9fb2e0775ae02fdae61d02f2ab7ff750c000f5de7106b16eaad17c248becb9979b2d0665a4a1d03d7000fc731c9d4ce3057aff5dab43e4277aa83b97a2d433ba38e1d5abf167836ba32b166a1de46218ce4bb9a99270b6da6a554ae5e0b3c1cc70e533bc35cbdce6bd3c608dda90ee6ea750ced8c3a7668fd3ae0d9e4cac49a857a9b843092ef1a5e9ece2cb4999652b97a1df0701c3b4ced0c73f57aaf4d9b2274a73a98abd733b433ead8a1f5eb613f28b33247315b1efa9d0eb166a1de66218ce4bb9695a7339f8536d352aa1fbb1e7838fa7926ddc37eec06af4d9b2374a73a98ab3730b433ead8a1f51b2262b706c96a71e318b4b83182e7c671d682e295cb7c550a995567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de39855e7f161569d55e73866d559758e63569d55e73866d559758e63569d55e73866d559758e63569d55e73866d559758e63569d55e73866d559758e63569d55e73866d5b93266cb43cf4522d62cd4db2284917cd7f1f284bf0bda128c5e32defa00946f049eeb19f4616a67780ff901af4d5b2274a73a787c1d606867d4b143eb07603f1c2883f9861432abce95315b1e7afe38b166a1de56218ce4bb9e9727ecc7b606a39752fdd801e0e1e8e799da19f66307bd366d8dd09deae0f17590a19d51c70ead533c6556e63866cb43ff078858b3506f9b1046f2ddc8ca53087fdfb82d18bd94eac70e02cf81c4798afd1883ee613f76c86bd3b608dda90ee6ea218676461d3bb47e08f64339cc37a4905975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de39855e7ead1d9f2d0ff8321d62cd4db2e84917c0758793ac27987edc1e825e3ad0f40f910f01c4c9ca738efc0a07b38ef70d86bd3f608dda90e1e5f8719da1975ecd0fa61d80f139df98614326b6e8c0fb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb384dcb03c3b5c9958b3506f871046f21de4e5099f7bb02318bd94ba6fe730f01c62d087a99de17d3b47bc36ed88d09deae0f17584a19d51c70ead1f81fda0ccca1cc56c7976ba32b166a1de4e218ce43bc4cb13f6633b83d14ba97eec08f070f4f34ced0cfbb141af4d3b2374a73a98ab830ced8c3a76687d10f683322b7314b3e5d9e5cac49a857abb843092ef302f4fd88fed0a462fa5fab141e0e1e8e799da19f66347bd36ed8ad09dea60ae1e656867d4b143eb47613f28b33247315b9eddae4cac59a8b75b0823f98e30f364a1cdb494eac78e020f473fcfd4ceb01fbbc96bd3ee08dda90ee6ea4d0ced8c3a7668fd26e0d9e3cac49a857a7b8430926f9099270b6da6a554aede043c1cc70e533bc35c3de6b5694f84ee540773f518433ba38e1d5a3f063c7b5d9958b3506faf1046f21d65e6c9429b692995abc78087e3d8616a6798abc7bd36ed8dd09dea60ae1e676867d4b143ebc781679f2b136b16eaed13c2483eecc7f631f1347a3c8d115a4cc4d84d5eeca62a89ddecc56eae92d89ae79ae7d5105bf35cf3bc1a626b9e6b9e5743ec6acd35d5bc3a35cf9c47cd33e751f38c6a2e52f37f2617bb2b178c2c35108b617cae7d2c638ec8b34818cf1c613cd385f14c11c6b34c184fad309e5e613c8b85f12c17c63357184f4118cf0c613c5dc278a60ae3a913c69317c6b34418cf3c613c2dc2785608e3c90ae3a917c6b35a18cf52613cfdc278fa84f1740be3992f8ca74318cf4c613c6dc2782e10c6d3288ca74118cf2a613c6b85f12c10c6334b184f4e184f93309efdc2782609e359278ca74718cf42613c9dc278660be359298c679a309e66613c9385f16404f06483737fdb81bf27a8051fdddfbf0f7c4f74e5fde0ab898841db390e3e1acfa56dd8f3d58299e732d4c0676e8ee07a62443c8a7373c467c743778c3500eb14af11386e16c23359184fb3309e69c278560ae3992d8ca75318cf42613c3dc278d609e399248c67bf309e26613c39613cb384f12c10c6b35618cf2a613c0dc2781a85f15c208ca74d18cf4c613c1dc278e60be3e916c6d3278ca75f18cf52613cab85f1d40be3c90ae359218ca74518cf3c613c4b84f1e485f1d409e3992a8ca74b18cf0c613c05613c7385f12c17c6b358184faf309e5a613ccb84f14c11c6335d18cf1c613c8b84f1d444f0ec67e2897b9ec27e01b1edb8375d0bd2985816de1f8fdf29edf71869fd1830920fefd3cd33f1c43d83222f20b6d5623594ed9285f7f177265c3995f718693d2aa7f03ecbd54c3c71cfed582d20b6d582e606e81e802cbc8ff75573e5d46a8f91d6a372aa999727fcff01ab82d14ba97b8df098e3d8874cedcce3f197e03334229f91bccad32a0775c6e3bee2b8fe80e229b332c7315b1e9afb22563c9f8dc7ef96c6c218757e65e009fbc7b660f452aa7f3c063c1ce70fa67686fdd809af4d6d11ba531dccd5130ced8c3a7668fd4444ecd620592d4e8e418b93113c27c7590b8a572ef3fe14324bd0d9f2d0bd9ac49a857a2b8530922fcfcb13f68f2b83d14ba9fef124f0709c3f98da19f609a7bc36ad8cd09deae0f1758aa19d51c70ead9f82fd500ef3891432abce95315b1e9aa321d62cd42b086124df31569e423e0b6da6a5543f760a7838fa7926ddc37e6cc86b53214277aa83c7d710433ba38e1d5a1f82fda0cccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaacccb2992d0ffd769858b350af430823f94eb2f214e71d3a82d14ba9798721e03995384f71de8141f770dee1b4d7a68e08dda90ee6ea698676461d3bb47e1af683322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb332cb66b63cf40c7962cd42bd4e218ce43bc5cb13fe6eab3318bd949a77380d3c1cf3324ced0ce71d6ef1dad419a13bd5c15cbd85a19d51c70eaddf02fb419995398ad9f2d0b30789350bf5ba8430926f8895a7387fda158c5e4af563b7000f473fcfa47bd88f9df1dad415a13bd5c15c3dc3d0cea86387d6cfc07e2887f9440a995567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975ae1e9d2d0ffd4f4362cd42bd6e218ce43bcdcad311ce3b7407a39752f30e678087635e8649f770dee1acd7a6ee08dda90e1e5f6719da1975ecd0fa59d80f139df9440a993537c68759734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59426e589e1e5726d62cd4eb11c248be5b7879c2e71ef404a39752f7ed9c059e330cfa30b533bc6f67d86b534f84ee54078faf618676461d3bb43e0cfb419995398ad9f2f4ba32b166a15eaf1046f29d61e6c9429b6929d58f0d030f473fcfd4ceb01fbbd56b536f84ee540773f5568676461d3bb47e2bf0f4b932b166a15e9f1046f2e139ae8f89a7d1e3698cd0e27cc5b65af4bbf205ee350beff7032357dfd2e731d23ae638f91a81a79f89a7c9e3698ad0e27cc5b65aac85b25db2f0fe5a60e4caa97e8f91d6a372aa0978d632f1347b3ccd115a9cafd8568b75ae3ccdbd66e1fd75c0c895536b3d465a8fcaa966e059c7c413d727ad1b87d871c7d778c48ecb95f188ad9aabe6aab96acea979e63c6a9e398f9a675473519a335c478563a7142300065c06a08cdf1538ae3d99da998ffa3eb6ce6b137e1fc33187f3f57d439995398e9969dca233ebc5267d028f879661662dc6730cb2df6b93b431c872994fa4905975ae8cd9c6be2df9d89d592f36e913783cb4dcc6ac05533bc3fee0f6205a638a97833a98a7b733b433037169dbb47e3bec8772984fa4905975ae8cd9c6be23f1d8c567b3636cd227f07868b983590b9e7616fb833b83688d295e0eea609edec9d0ce0cc4a56dd3fa9db01f945999955999955999955999955999955999955999955999955999955999955936b38dfda4c46317c7ef3136e913783cb43c89590b9e7616c7efef0aa235a67839a883fbfc2e867666202e6d9bd6ef82fda0cccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaacccb2996dec27271f3bfc3d0ec6267d028f879627336bc1d4ce70fcfeee205a638a97833ab8cfef66686706e2d2b669fd6ed80fcaaccc51cc36f653128f5d9ccfc3d8a44fe0f1d0f214662d78da59ec0fee09a235a67839a883fbfc1e867666202e6d9bd6ef81fd500ef3891432abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3ea5c3d3adbd8f7261ebb231cbfc7d8a44fe0f1d0722fb3163ced2c8edfdf17446b4cf1725007f3f43e867666202e6d9bd6295e35309f4821b3e6c6f8306b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7316b6e28731cb3e68632c7314bc80d1bfba9c9c70e7fcf8eb1499fc0e3a1e5a9cc5a30b533bcffe5fe205a638a97833a98a7f733b433037169dbb47e3fec076556e628661bfb0186d8592f36e913783cb43cc0ac05533bc3fee0c1205a638a97833ab8cf1f64686706e2d2b669fd41888d7a27143bbc079262d4b857eb7b9a2bd782efe9ae5c07be67b8723df89ee9ca0de07b962b4f02dfb3a13de47b8e2baf00df735d791df89ee7ca6bc1f77c57ee07df0b5cb90f7c2f74e561f0bdc8956f05df8b5df936f0bdc4956f07df4b5df90ef0bdcc95ef04dfcb5df949e07b852bdf05be57baf293c1f72a57be1b7caf76e5a780ef35ae7c0ff85eebcaf782ef75ae7c1ff85eefca4bc0f75084ef0daefc54f0bdd195ef07df9b5c793ff8deecca53c0f716579e0abeff8032bdbed5952f00dfc3aedc08beb7b9720e7c6f77e526f0bdc395a781ef9daedc0cbe77b9f274f0bddb956780ef3daedc02bef7baf24cf0bdcf956781effdae3c1b7c1f70e539e0fba02bcf05df875c791ef83eeccaf3c1f711575e00be8fbaf242f07dcc951781efe3aebc187c9f7065dcbfffe9ca0f808ffa9507c147fdcad3c047fdcad3c147fdca33c047fdca33c147fdcab3c047fdcab3c14779f71cf051de3d177c9477cf031fe5ddf3c14779f702f051debd107c94772f021fe5dd8bc14779f712f051debd147c94772f031fe5ddcbc14779f70af051debd127c9477af021fe5ddabc14779f71af051debd167c9477af031fe5ddebc14779f710f828efde003ecabb3782afd595df04be0b5df9cde0bbc895df02bec7b832f6338f75e5b782ef71aefc30f8a82f7c1bf82e76e5b7836fa92bbf037ccb5cf99de05beecaef02df0a577e37f856baf27bc0b7ca95df0bbe36577e1ff856bbf2fbc19777e50f80afdd953f08be822b7f087c1daefc61f075baf247c0d7e5ca1f055fb72b7f0c7c3daefc71f0f5baf227c047e771ea67ecf16c8f41d28134b23e6a735b445bc83719da3210247b4d47b168dbb4de018cb40f0ae3cf58182b63bbc76879ba1834c3bca2a5d4f78f2ee0e964e0616a67f8fda3db6b5387d7a61cd4b918dad9cdd0ce0cc4a56dd37a37c4e6d8e7a845bddbee524f8b3aa8f3077792b3e7ce523ad2366cfe1622dad2c7dc16da36f54b7de310bbc78b9df762637f4c4ba9e3ab07987b1998ed76fb93df6e787cad71dba29ca2387968d35ad020a93661ec8c338a43fe3a28ffa365a42ed5233de8fc45ec3697695f22bbffb92eef7339a8d317d1fe8120d9f6f77b3cfd1eb3dd277f6b19e160381ec21ce8f338683d0fdaf5c768d707da511d3cff1598b4ebf5787abdd89687ae71bac147d70ac48fd7596de3c0edf77bdd11dce4eb01c6a86b9df6e4194b5eebb40323f97a81a78749337f5f2ff5f4c1f3728357873e5b07759adc97bd69c1e8ef1f54d71e774b3223eda2efe0ff0c92edd31b18f4c2f18100f4093c0d03d08bda59cfc03335181923383b3c74e6e04d83970e1e3c9201b43a0f135f3311cda8011f966b237c41307a2804876469280487646b3c59700886eadbaf52b65934dc3078f2f8f0134e0d9e3a7ce6ced3c38347f60cdd84d4f51e3d92c6b50049d147cbe46064d066204836791abc58a5926732bc4e62e0616a6778d29be2b5a9c16b530eead4c37b5318da9981b8b46d5ac70160f26176d2fb386150e3b505b3780abcfafb36d10651c0c7c0f6330ecebe57e7846d70f0242ef5187614d15ec9d91d6147056d6f6d47fdec616747f5ec8591edc8ed289d1d95b3a37076d4cd8eb2d951353b8a6647cdec28991d156b0d8aa35e1701cf1781d18e6ad9512c3b6a65bf49dab3821d85b2a34e7694c95e4dd86f29f60c6caf38edd5913d23da33a1fd3665bf59db338c3d7bdb33933d9bd8ab237b5564af62ed559d9d99596f6c83d37aa3b14dc6361bdb626cabb16dc6b61bdb616ca7b15dc6761bdb636cafb17dc62e31f6f8a038a27ca9b1cb8c5d6eec09c6ae3076a5b1ab8c5d6dec1a63d71abbced8f5c66e3076a3b103c60e1a3b64ecb0b123c6068d1d357693b163c68e1b7ba2b19b83e21d1e278d9d323664ecb4b15b8c9d31763628ce12d959213b0b64677dec2c8f9dd5b1b33876d6c6ced2d859193b0b63675dee0d8ab32a7676c4ce86d891703bf26d47baedc8f63382e2c8b51da97e76501c89b623cf76a4d98e2cdb91643b726c478aedc8b01d09b623bf76a4d78eecda915c3b726b476aedc8ac1d89b523af76a4d58eac3e1414474eed48a91d19b523a176e4d38e74da91cd8783e2c8a51da9b423937624d28e3cda91463bb2684712edc8a11d29b423837624d08efcd9913e3bb26747f2ecc89d1da9b323737624ee93c61e31f629639f36f619639f35f639639f37f685a098935f32f665635f31f655635f33f67563df30f64d63df32f66d63df31f65d63df33f67d633f30f643633f32f663633f31f653633f33f67363bf30f64b63bf32f66b63bf31f65b63bf33f67b637f30f647637f32f6e76064d41e3b8abfbb151a413e383c3c78f2f470ebf050ebc95b4f0c1f3f7de2ced6db8f0f1f6b1dba6df0ccd11343b7e387dfeaba261a1edf78e6ccc13b5b8f9f3a327847ebd0adc3ad43475b0f0ddd7aeac859fcd017dc87169c1bf1e09123f1c17e50f328487f5261d03fbacfd1c4c3ced26dfb4b2582fcad920fcda8adac4197b8330b7d2bbdac7815d77af6c4d0706bbef594f97bf084f9cce091b6567cefac11f9ec70ebd9e18367865b8f9e193ad9dade86dbbd7a4a058df87d4b051fcacd1c7bcb83ff079bac954d69010400", + "packedBytecode": "0x000000028df71de5000000476f1f8b08000000000000ffed9d777414c7dae65b2030782c01ced9c2e13a60632144163038e78c8d31c62004061b104118e76c72744ee49c93c91803c6d8d737e7ec74af6fd87376bf3dbb7fecf79dddf56ed74cbd9f1e8aea4123770d8f34d5e794a6fa5575bfbf7afaedea54dd5510a4a77f85a940e79b86e9c2e0c849fe9fd4bfa5df6fea10e3ba4a5d72163410ce260d84b36903e12c6c209ccd1a0867f306c2795c03e16cd140385bc6c859007cae788f6f60bc8906c67b42d030e2b6a88170163710ce560d84b37503e16cd340384f6c209c273510ce931b08e7290d84f3d406c2795a03e13cbd81709ed14038cf6c209c673510ceb31b08e7390d84f3dc06c2795e03e12c69209c6d1b08e7f90d84f3821839db01a7dccbbf48fffe40ff5eac7f2fd1bf97eadfcbf46f3b5dc7423d7f7998ae0853fb305d69fc4f09a36ee89785a9a3f1bff230750a53e73075d1ff2bd1ffeb1aa66e61ea1ea61e61aa0853cf30f50a536fad479f305d15a6abc3744d98ae0dd37561ba3e4c3784e9c630dd14a69bc3744b986e0dd36d61ba3d4c7784e9ce30dd15a6bbc3744f98fa86e9de30dd67b0f40bd3fd61ea1fa607c234204c0f866960981e0ad3a0300d0e5365988684a92a4c43c3342c4c0f876978984684e991303d1aa691611a15a6d161aa0ed398308d0dd3b8308d0f534d982684e9b1304d34347b3c4c4f84e9c9303d65703e1da667c2f46c989e0bd3f3617a214c2f86e9a530bd1ca657c234294c93c334254c53c3342d4cd3c334234c33c3342b4cb3c334274c73c3f46a985e0bd3eb617a234c6f86e9ad30bd1da677c2f46e98ded32cb223bc1fa679619a1fa605615a18a645615a1ca625615a1aa665615a1ea615615a19a655615a1da635615a1ba675615a1fa60d61da18a64d61da1ca62d61fa204c5bc3b42d4cdbc3b4234c3bc3b42b4cbbc3b4274c1f86696f983e0ad3be30ed0fd381307d1ca68361fa244c87c2f469983e0bd30fc3f479987e6468fee330fd244c3f0dd3cfb4ede7faf717baacecf3bfd4bfbfd2bfbfd6bfbfd1bfbf35caffce98ffbd31ff07fdfb47fdfb27fdfb67fdfb17fdfb85fefd52ff7ea57fbfd6bfdfe8dfbfeadfbfe9df6ff5efdff5ef3ff4ef3ff5af7afef75edb74be45503b258398daa4f2a183d5fd7f11db7cbea89e5d35d5ff93df126d2fd4f3f25ba0edcdf47c33c3de5ccf3737d6d342cfb730ecc57abed8b0b7d6f3ad0dfb897afe44c37eb29e3fd9b0b7d5f36dc19ed0ff4b572cfda36c4db5a9006c129f4dc0d64cdb9a82adb9ac0e6cc7695b33b0c9f66d0eb696da761cd88ed7b616604b685b4bd1324c27685b32882b564a07abf516c5bd5efdcca4387ede4ab5de568e785bc7cf3b44adb78d035e151f27ea751541dc9ca46dc5603b59db5a81ed146d6b0db653b5ad0dd84ed3b613c176bab69d04b633b4ed64b09da96da780ed2c6d3b156c676bdb69603b47db4e07dbb9da7606d8ced3b633c156a26d67814d37b9c1d9603b5fdbce01db05da762ed82ed4b6f3c026e778256093f3bdb6609373bff3c126e78117689b6a3b5a16803f6d97762be54fda6cb0fd40da6bb05d2c6d35d82e91761a6c97826fb15d066d8dd8da699bb45bea7fdd753e19c4b59f94a5f6931e71af375cb35a6fcff8d79b7a7ed72ba8d53a097e7a8056bd753ec6be2d1dd0b79cdb881fb11742fe26282be5440f39f608bb3a1654e87cef0ccb7537962b86321596fa278378ebdfd3e0e969303783bc9b98ed58ea63b6ce53d631db0fca9ab127e7418d31666f050e07315bee63b6ce53d6313b0cca9ab127e7c28d31661f000e0731dbd54dcc9695fa984ddf1b0b027becc9f550638cd911c0117fcc76f2315bf729eb987d11ca9ab127d7c48d3166270247fc31dba5ab3f37a8f39475ccce81b266ecc9fd99c618b3af008783981de2dbd93a4f59c7ec7c286bc69edc2b6c8c31fb1a70c41fb3dd1cc56c471fb341fa396710d8634fee5b37c6985d041cf1c7ec107f7fb6ee53d631bb0bca9ab127cf501a63cc6ed079f59ce1e7fa39c3d960fb85b69d03bcf1c7765599a3d8eee0633bddff2308ec312acff31a636c7fa4f32a8e7f05fd11c4f66be9ab00b6df68dbf960fbadb65d00f572b00f74f1fb40ddeb94ed3ef067286bc6b23c5b6e8cfbc02f80c341cc76f5315bf73a651bb3ff05ca9ab127fd1c1a63cc7e091c0e62b69b8fd9bad729db98fd77286bc6de253adf1863f6bfeabc3a5ff8a33e5fb80c6c7fd2b67660fbb3b65d0eb6bf68db1560fb42dbda83ed4b6dbb126c5f695b29d8bed6b60e60fb46dbcac0f6576deb08b6bf695b39d8bed5b64e60fbbbb67506db3fb4ad0bd8fea96d5dc1f62f6deba66daa9f9ef4bd3aa46d2d803f19c4bb6da5dfa5ac5be63be4c0772bc377ab1cfa6e63f86e63f15de6c077027cc85460cc27215fe696a7b41878d05779fcbe3aaaba770cea5ef772e0e9e4a0ee09f051179e4ec0d3397e9ed4f1b34bfceb4d6de38e86a609f0d511ead5d541bd0ac097ac5be6c55f31d8b06ded6a61ec163f635901f89275cb7c3760141bb6f5f22e95ec3fea787871412daf837d29754e24fee4db55c2510e7629d3a16d2d5b3bcd5604ffc7e35e67c3e6282e537121be64dd322ffe8aa03e9d73cf585657c64e06a3ab36a2007cc9babdefdaed20793c8ebbb8d6b1b569e2bb470e7c77337c971bbeb1ed9429d3b1ad1b30c77ecda98f6d15f1afb714af4fe4da50fce0f9035ec3c55527f42dd786e247ec8590bfada0b6ac94133da41d167615cbb22d91dd5caeabb15c3194e961a97f3288b7fe15064f85c1acb6c9d5702c74b03fa462a087c121f3e5a05d4584763d403b29730968e7aa3deb6ef0c87c67e09176ac0bf0b8ba268ae2c9c5f5d8d17ce3392c5e3fcbfff13cc0d5f6ea6030cabc6d7b750346dbb98a83eb998ce72a9d80516cdd81a7a323cda2b66b4712df0e6225d51e890f393797fdb733d8a54c37fd429d6a2b1f81b6d2458c603cca54d76bdef8b75359ea1abc53163cb8ed1c5c577570148fa578ffe6bb20de5833dba54e865651f7785cb5e51d0d1e99177f9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec99f999f17912f6db92729d4918cdfe6faeeef3a7be61a8d725eb57cf75feb7d3fe6065a5d83f46fa415c66d4b910ca1435a92dfbffa03f98f99c0afb487676ab5d6a5b627fcc24cc8b3fec6b85db92a1bf53496cbed3dfa274f1bc4df5b156dfd134fb7e76b668eaa2ff336a5a60688afdf12f3778549c5634ad6573f1ec2fdb6791a895e4e37cb6571cd8633dfeed5276d833eb26c1e1ed071e675cf5df91b65a9e97f7307c174299b39ad46e1be95b25e3cc763496c37e3fb26e59e632b05718eb6ead97158e66c6fabbc0b252e65c6853f737a9d5cc415b59966ddf757c6e1eff7138fd1cbf63163c1d80c7453be3e87ce3b0efadc6fd1cdfec9f663b8f9132d8b7cf41bfca8cfd9dc49f67f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b667e66c5633e6bc5f76bcb491873d4f721f53c43be5526eb4f7d2fb849ad5fd7cfe1e499533ba3cef8eee87f6f525b768bce170547f67788da96aebe4f11b52dc51f7e7b069f05b978ae5b00be64dd65162d245f129bef32676343c873fc8e86aee5164d5dedaff88c1535c5fdb593c183cf46a3beed5366d85cf61d8a8a0bf187fb5219d8248fef47bbd8ce782c31fbf5883f7c7efd23ad6debc0d5b62f2b75d96ee0775392c191f18ddf53f939b47dbfd479ecc3817d47beb6fc5fa64ccfa9453f556707dfd72c2d8075c9f6b57ddbb30fb0c6e4bb03aeab40a73e86068590ffaa496d59292765456b6157fb887c0306d9cde53a19cb1543995e96fa278378eb6f7e6bb5b7c1acb6c96f20cebe86e3bfab36a95784469781465206cf835cf5c933db48b37f23f6db6b6e94c1731629f32f68a3a2fa8fdafa1cba3a8e45f539b49d1b770046b38e663fcf7cefa7f51fd05ec4dd4feb3f2086b09f5660acbf1dac5fb89a07d1c71629f37f8df59be7e4b20cf603fbcffe4ff03d97329dcfe69cfc585d5fd9cec971b9a8ba2b66fc0e5a3246668c0964c1f3042973bcd65ab65945047737cbb24511cb8a56e6b7c28a8223f573f39db5f43edfdba88bc4357e835cca9c04757173de923e0774f54db924d449e5cb2c759532a7c3be76a6ce27603be17e7ba9e5ff32653a07c431dcaf8abfcea9ed7b357026c10ffabe065863f2dd017dcb39a0f8117b21e42f695a5b56ca891ea2b5b0ab7d44cea390dd5cae87b15c3194e963a97f3288b7fe57193c5719cc6a9b9c03717629f44377d556f789d0a81d682465f09ea2ed3ba0b6638cabbefd51c798326034db4d3c4eba6433df1332efabd9ce11a48c2c8be7085da09d4d58ca9af70be5781967bf617c57a20bf8c577255c7dbbb93be89684793c2f3896be5d7cc756f98b1a33a17b0e7c478d99900bdf6d0cdf6d72e8db6bee3567d2dcc11804a9f7cff09ba56aca745e8ae312c8724d80d1c5580e89e0f06f8f1f8d11c77790e59a02a38be343b6df3eef028cb25c2130ba78b714c7dfa80b237e63188ff3c2e8e05bb11deafbad58bca7d71c1899ded9c46753c701a38b7ba8f57d570fcfe75bc0afab71893a66c188e7f3b25c4b6074716f1c9f0dd68511af8b64b9e381d1c533ac6cc777c26fcfe3bd65978c998eed8efba294657befa5c22d4fc6730df4ed605cc39416789ff1685af474cb93f1dc077d3bb8ef97d202c7193c9a16f86cd0c5b88789e0f0e77047e3c1e797b2dc89c09874c4d83b0bc62430fee7bd6260ece388319905631f6014fbc9c0e8e0fe6b8ab14f168c789f52963b0518af76c47855168c5703a32c772a30bab8979a00bf7561bc061865b9d380f15a478cd764c1782d30ca72a703e3758e18afcd82f13a6094e5ce00c6eb1d315e9705e3f5c028cb9d098c373862bc3e0bc61b8051963b0b186f74c47843168c3702a32c773630dee488f1c62c186f024659ee1c60bcd911e34d5930de0c8cb2dcb9c0788b23c69bb360bc051865b9f380f156478cb764c1782b30ca7225c0789b23c65bb360bc0d1865b9b6c078bb23c6dbb260bc1d1865b9f381f10e478cb767c1780730ca721700e39d8e18efc882f14e6094e52e04c6bb1c31de9905e35dc028cb5d048c773b62bc2b0bc6bb815196fb0130dee388f1ee2c18ef01c6bb2d8c7d1d31de9305635f6094e52e07c67be3674c5d4bf7cd82f15ee0b92f7e9e9466f766c1739f5b9ed477f5eeb5f8ba3f7e5fa96dd12fa87bddef079efef1f3a4b6c5fd59f00843312c879a3d103f634ab3fe59303e003c03e2e74969f640163c0340b3072c9a3d183f634ab30159303e083c03e3e74969f660163c0341b3072d9a3d143f634ab38159303e043c83e2e74969f650163c83825acd1eb26836387ec6946683b2601c0c3c95f1f3a4341b9c054f256836d8a2d990f819539a5566c1380478aae2e7496936240b9e2ad06c8845b3a1f133a634abca827128f00c8b9f27a5d9d02c78868166432d9a3d1c3f634ab36159303e0c3cc3e3e74969f670163cc341b3872d9a8d889f31a5d9f02c184700cf23f1f3a4341b9105cf23a0d9088b668f3a627c240bc6472d3c717f27fb118baf518eea3e32a87bdd85a11896c37e12a31d318eca82713430ca72d84fa2da11e3e82c18ab8151964b3866ccd44fa21a7c8f89df77aa5daa0eeaaecf18b73c19fb49a0efb18eb41813d45d8bb16e7932f69340dfe31c693136a8bb16e38067bc032d12e0a32e3cc2500ccb613f891a478ce3b360ac0146590efb494c70c4589305e3046094e5b09fc4638e182764c1f81830ca72d84f62a223c6c7b2609c088cb21cf69378dc11e3c42c181f0746590efb493ce188f1f12c189f0046590efb493ce988f1892c189f0446590efb493ce588f1c92c189f0246590efb493ced88f1a92c189f0646590efb493ce388f1e92c189f0146590efb493ceb88f1992c189f0546590efb493ce788f1d92c189f0346590efb493cef88f1b92c189f0746590efb49bce088f1f92c185f004659ee51c78c99ae5f5e68e4bea3ae551abbefa8eb92c6eedbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ece997cbfe8c077027cc85460cc27212f0cc5b0dca39eb15133224f497c3ca55877f4f51241dd5fb2f01438aa3bfa7a99a0eec2d0d0185f6c008c8f360046af63ba0f627d1815cf2bf0ff648c3c2f67c1f30af04c72c4f34a163c93806772fc3ca9989a94058f3014c3728f3600c6171b00a3d7d1ebc8c4e875cc1f1d3da367f48c9ef15830368436dc333688782cab2fa3e299123f4f4ab3c959f04c01cd64b9fbdc3296d59751f14c8d9f27a5d9942c78a68266532c9a39602cab2fa3e299163f4f4ab3a959f04c03cda65a3473c058565f46c5333d7e9e9466d3b2e0990e9a4db368e680b1acbe8c8a6746fc3c29cda667c13303349b6ed1cc0163597d1915cfccf879529acdc88267266836c3a29903c6b2fa322a9e59f1f3a4349b9905cf2cd06ca64533078c65f565543cb3e3e74969362b0b9ed9a0d92c8b660e18cbeacba878e6c4cf93d26c76163c7340b3d916cd58191f6d008c2f360046c73a96d59751f1cc75c433270b9eb9c0f3aa239eb959f0bc0a3cafc5cf938aa957b3e011866258eed106c0f8620360f43a7a1d9918bd8ef9a3a367f48c9e313bc6971a00a3dfd69ed133366e4607d7a919df457ab591fb8e7a17a9b1fb8e7a17a9b1fbf671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98ff37cf0ede3dcc7793ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7b98f7326dfafc7efbb2cdb6fccbc0e3c2ebe79e3a89ea56abd6fe8757d17a37e4aab370dad5e35b42a86326f807e6f3ad0af00fccaba655efc65cb7c3101b323df65aa7d6909f5171f2f1a7a28ff6f39aa7b545bff5623f71dd5d63776df516d7d63f7ede3dcc7793ef8f671eee33c1f7cfb38f771cee21bf3cd82daf376f9fea95ac7db3a5fa8e7a5fc4b6097324f1d97fe6d1df87dc8856fbf0ff963453ef8f671eee33c1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f731fe7f9e0dbc7395f9c17c3ffc7e680273078820c3c53c978aac878fa91f1dc4cc6d39b8ce771329eae643c23c9781e22e3b98b8ce705329eebc8789e23e3e940c6339e8c671a19cf30329efe643cb792f1f421e379928ce70a329ece643ca3c9780693f1dc43c6534ac6f30a19cf0d643cb9785f281b9ef6643c15643c73c8782690f14c27e3194ec6732919cf00329e4bc8786e27e3b99a8ca7988ca715194f3919cfd3643c63c8788690f1dc4bc67313194f2f329e89643cddc8786690f13c42c633898c672019cf9d643cd792f15c46c6f32c194f19194f53329e71643c43c978ee27e36947c6730b194f928ce709329e2e643c33c9784691f14c26e31944c6733719cfcb643cd793f13c4fc6d3838c6736194f0d19cfc3643c0f90f15c4cc6731b19cf55643c2790f11491f17422e3798a8c6716194f3519cf14329e4a329ebe643c3792f1f424e3994bc6f318194f77329e11643c0f92f1dc41c6730d19cf95643ccf90f1b426e36943c6d3918ca7808027111c39864902feff3ad89a18cbaacfbed6b4adfdff3bdade04967957e79b5ad6fd0ed8e45bb2ef5a96459dde81ba2475bef4fb4d299dd05712e6c55f1170bc4bc2d3918ca70d194f6b329e67c878ae24e3b9868ce70e329e07c9784690f17427e3798c8c672e194f4f329e1bc978fa92f15492f14c21e3a926e39945c6f314194f27329e22329e13c878ae22e3b98d8ce762329e07c8781e26e3a921e3994dc6d3838ce779329eebc9785e26e3b99b8c671019cf64329e51643c33c978ba90f13c41c69324e3b9858ca71d19cffd643c43c978c691f13425e32923e379968ce732329e6bc978ee24e31948c633898ce711329e19643cddc8782692f1f422e3b9898ce75e329e21643c63c8789e26e32927e36945c6534cc6733519cfed643c9790f10c20e391ef79b2f00c27e3994ec633818c670e194f05194f7b329ed7c9786e20e379858ca7948ce71e329ec1643ca3c9783a93f15c41c6f324194f1f329e5bc978fa93f10c23e39946c6339e8ca70319cf73643cd791f1bc40c6731719cf43643c23c978ba92f13c4ec6d39b8ce766329e7e643c55643c53c978c65a785e77c423efbbcbba65fe7512df0eb643a95aef7b8eeaf4be5e5733bd5ee1177f855066f2f1e95ff57e382e2b5ce6f709f0ded7fba0d1fb8eea22dba3c0d83ee8fb6d47bee51d2459b7ccbfddc87db7327cb7ca13df6d0cdf6df2c4b78f731fe7f9e0dbc7b98ff37cf0ede3dcc739936f07d70665f89d34990a8cf924e4f17ac1c5f7e51cd5f3b0ebc4ef62d44f6935cfd0cabcb62a8632ef817ef31ce867bbf69479f1972df3c504cc18172541bc71313ffe3a95a976ab25e83adfd017ebb5c091a651c790058ddc77d431a4b1fb8e3a863476df3ece7d9ce7836f1fe73ecef3c1b78f731fe74cbe17ea7c8cd78da5e8433d5f94eb8185e077b1ce17c4e857ad6b915e57a15eb7702c06bb94699248ffb60efc3eefc2b7dfe7fdb12d1f7cfb38f7719e0fbe7d9cfb38cf07df3ece7d9ce7836f1fe73ecef3c1b78f73be3837f3d25ffc126073d59f3f2a1673f12ec1b1f41d158b8ddd77542c3676df3ece7d9c33f95ee2c077027cc894a98fdf12e059e480c7513d53cf36961a757adda8533194c163fc5207f52c00bfb26e995f0a3c328d051e177150976d8e3c53c978aac878fa91f1dc4cc6d39b8ce771329eae643c23c9781e22e3b98b8ce705329eebc8789e23e3e940c6339e8c671a19cf30329efe643cf3c8786e25e3e943c6f32419cf15643c9dc9784693f10c26e3b9878ca7948ce715329e1bc878da93f15490f1cc21e39940c6339d8c673819cfa5643c03c8786e27e3b99a8ca7988ca715194f3919cfd3643c63c8788690f1dc4bc67313194f2f329e89643cddc8786690f13c42c633898c672019cf9d643cd792f15c46c6f32c194f19194f53329e71643c43c978ee27e36947c6730b194f928ce709329e2e643c33c9784691f14c26e31944c6733719cfcb643cd793f13c4fc6d3838c6736194f0d19cfc3643c0f90f15c4cc6731b19cf55643c2790f11491f17422e3798a8c6716194f3519cf14329e4a329ebe643c3792f1f424e3994bc6f318194f77329e11643c0f92f12c20e3b9838ce71a329e2bc9789e21e3694dc6d3868ca723194f01014f2238f2ddff04fc7f1ed8e41df5d7c1b64ce71781ad89c547539d5f0ab6429d97751c17a6e7da1eb96ed4c9d57bf9e82b09f3e2af08389691f07424e36943c6d39a8ce719329e2bc978ae21e3b9838c670119cf83643c23c878ba93f13c46c633978ca72719cf8d643c7dc9782ac978a690f15493f1cc22e3798a8ca713194f1119cf09643c5791f1dc46c6733119cf03643c0f93f1d490f1cc26e3e941c6f33c19cff5643c2f93f1dc4dc633888c673219cf28329e99643c5dc8789e20e34992f1dc42c6d38e8ce77e329ea1643ce3c8789a92f19491f13c4bc6731919cfb5643c7792f10c24e39944c6f30819cf0c329e6e643c13c9787a91f1dc44c6732f19cf10329e31643c4f93f19493f1b422e32926e3b99a8ce776329e01643c9792f10c27e3994ec633818c670e194f05194f7b329e1bc8785e21e32925e3b9878c673019cf68329ece643c5790f13c49c6d3878ce756329e79643cfdc9788691f14c23e3194fc6d3818ce739329eebc8785e20e3b98b8ce721329e91643c5dc9781e27e3e94dc67333194f3f329e2a329ea9643c6373c4a3de6d97773903e0c22909f9a5c033cf018fa37a96e2770dbe8b71bd4aabe586560b0cad8aa1cc12d06fb903fd0ac0afac5be697038f9c8f082b7e53e1051246b1cd73cc93803acb94691f580e3c2ef64947f54cc5ea0aa34e2f5874973218ab2b1cd4d3b6efc8fc0ae07959e7853501e55e266114db52c73c09a8b34c99627505f0b8d8771cd53315ab2b8d3abd6cd15dca60acae74504fdbbe23f32b81e7159d17d604947b8584516ccbddf29427a0ce32658ad595c0e362df7154cf54acae32eaf48a45772983b1baca413d6dfb8eccaf82ede0993db38d59f148ff56614d40b949248c625be194a7bc3401759629533bb60a785cb4f38e744fb563ab8d3a4db2e82e653056573ba8a76ddf91f9d516df2541bc5aaca983166b2c3c6b72ac85f8cb9679490364f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e62f63a7b9da398bdce5ee72866afb3d7398ad9ebec758e6266d059f1c87822c29a8072934918c5b6d22d4feabda0c9c1e15381319f84fc1ae059e5401f47f54cf5215f6bd469b245772983fbd75a07f5b4ed3b32bf16b64336ccab1b20b3d7b97ecc8a678ace0b6b02ca4d216114db2ab73ca9766c4a70f894a91d5b0b3c2eda7947f54cb563eb8c3a4db1e82e6570ff5ae7a09eb67d47e6d7c176f0cc9ed9c6ac78a6eabcb026a0dc541246b1ad71ca53967abf716a70f894a91d5b073c2eda7947baa7dab1f5469da65a74973218abeb1dd4d3b6efc8fc7ad80ed930af6e80cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9dbdce51cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9dbdce51cc5e67af7314b3d7397f74563cd3745e5813506e1a09a3d8d63ae5e9987aee302d387ccaf4dc613df0b8782ee348f7d473870d469da659749732b87f6d70504fdbbe23f31b603b3476e6d50d90d9c7466e987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398a99213614cf749d17d604949b4ec228b6756e7952df3d981e1c3e65eab7b30178d63bd0c7513d53fd76361a759a6ed15dcae0feb5d1413d6dfb8ecc6f84ede0993db38d59f1ccd079614d40b919248c625bef9627d58ecd080e9f32b5631b81c7453befa89ea9766c9351a71916dda50cc6ea2607f5b4ed3b32bf09b68367f6cc3666c53353e7853501e56692308a6d835b9e543b3633387ccad48e6d021e17edbca37aa6dab1cd469d665a74973218ab9b1dd4d3b6efc8fc66d80e9ed933db9815cf2c9d17d604949b45c228b68d8e791250679932b5639b81c7453befa89ea9766c8b51a75916dda50cc6ea1607f5b4ed3b32bf057866ebbcb026a0dc6c1246b16d72cc93803acb942956b7008f8b7dc7513d53b1fa8151a7d916dda50cc6ea070eea69db7764fe03e099a3f3c29a8072734818c5b6d9314f02ea2c53a658fd00785cec3b8eea998ad5ad469de65874973218ab5b1dd4d3b6efc8fc56e099abf3c29a8072734918c586edd85c473c45064f91458b63e55b69d143e74fd0bf09f87f0f6074d5b6cc3518651e635c6c4539d0ac95c1d3cad0ec58fa565a54405e4db8bd2a8091617bb5ca81666d0c9e368666c7d2b7d2a2a7ceb7d6bfb8bd7a0223c3f66a033c0edae7f284c1a3a64cc7eead8ef57154cfd4b17b5b60d71d8f4352068fdddb1cd4d3762e21f3db603b7866cf6c63563c7d755e581350ae2f09a3d8f09c7f7bfc3ce50983474d99dab1ed8ef57154cf543bb623b0ebbe1d74973218ab3b1cd4b300fccaba657e076c876c9857374066af73fd98154f3f9d17d60494eb47c228b66dc0b3337e9ef284c1a3a64cedd84ec7fa38aa67aa1ddb15d875df09ba4b19dcbf7639a86701f89575cbfc2ed80ed930af6e80cc5ee7fa312b9efe3a2fac0928d79f84516c3b806777ec3ce9315f90474d99dab1dd8ef57153cf743bb627b0ebbe1b749732b87fed7150cf02f02beb96f93db01d3cb367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed93373332b9e013a2fac0928378084516cbb80e7c3d879d2cf1d90474d999e3b7ce8581f37f54c3f77d81bd875ff1074973218ab7b1dd4b300fccaba657e2f6c07cfec993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6ccdccc8a67a0ce0b6b02ca0d246114db1ee0f9287e9ef284c1a3a64ccf1d3e72ac8fa37aa69e3bec0becba7f04ba4b198cd57d0eea59007e65dd32bf0fb6c33ecfec992dcc8a6790ce0b6b02ca0d226114db5ee0d91f3b4ffaf929f2a829533bb6dfb13e6eea996ec70e0476ddf783ee520663f580837a16805f59b7cc1f80ed900df3ea06c8ec75f63a47317b9dbdce51cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9dbdce51cc5e67af7314b3d7d9eb1cc5ec75f63a47317b9df34767c553a9f3c29a807295248c62db073c1fc7ced3b13461f0a8a9c0984f42fe63c7fab8a967fab9c3c1c0aefbc7a0bb94c1fdeba0837a16805f59b7cc1f84edd0d899573740661f1bb961f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e628661f1b9e398ad9c786678e62f6b1e199a3987d6c78e6286686d8503c553a2fac09285745c228b603c0f349fc3ce50983474d05c67c12f29f38d6c7513d53fd760e0576dd3f01dda50cee5f871cd4b300fccaba65fe106c07cfec996dcc8a6798ce0b6b02ca0d236114db41e0f9d4014fc2e05153a676ec53c7fa38aa67aa1dfb2cb0ebfe29e82e6530563f7350cf02f02beb96f9cf8067b8ce0b6b02ca0d276114db21e07111ab8aa7c8e091f94f097c2b2daa75fe04fd8bdbab1a1819b657510e346b65f0b432343b96be95166320af26dc5e638091617bb5ca81666d0c9e368666c7d2b7d262acceb7d6bfb8bdc60223c3f66a9303cd8e657b782cf7ed6319a75ef363a779c131d4bce0186a5ee035a7d2dcc1f1a50c8f650130e09484fc67c0f379fc3ca97b5c9f65c1f339f0fc307e9e0e8eea59aad6fb23608f6bbd4aab1f1b5a7d6668550c6590e1c70ef42b00bfb26e99177f9ed9334731e3b9adb026a0dca7248c629336c855bba1ea7e855e97acbf59980e9d5cebd7c5b307bcefda4caf5738c45f2194b9bfa4b6ece79aad08fe2fdb4dd5e7a06173f43e7007db333099177f4541eeee8366ba2f8b5ab8787693ed71ffa085e7bbf8784a713f475f071cd53d9be768072c3c31d6bd43d433c4fdf1d73dd57eb4d7eb92f5ab7df48b939d6a5e8efb9eb41fed8d3a1742994e25b565bf81f6c3d656b8de37e59cdcdc379b04b5ed99709568bbf97ce53b6d97729f40796c737ae85fdc3f7b405d5db58b51f798b05d34db6e97da9bcff84cdfc5a0cb27a49ad99e53a08e1516ee0a026e8cc75cee67b26edb33b20a434736cd705b7f62d1b1a785bb270137e37eddd3d0914db3a3edd77d2ddc7d09b819f7ebbe868e6c9a1d6dbfee67e1ee47c0cdb85ff7337464d3ec68fb757f0b777f026ec6fdbabfa1239b6647dbaf0758b807107033eed7030c1dd9343bda7e3dd0c23d90809b71bf1e68e8c8a6d9d1f6eb4116ee4104dc8cfbf5a0e0701dd9343bda7e5d69e1ae24e066dcaf2b0d1dd9343bda7e5d65e1ae22e066dcafab0c1dd9343bda7e3dccc23d8c809b71bf1e66e8c8a6d9d1f6ebe116eee104dc8cfb755dfbedb3eed7d516ee6a026ec6fdbadad0914db3a3edd7632cdc6308b819f7eb31868e6c9a1d6dbf1e6be11e4bc0cdb85f8f357464d3ccb65f3b7a2faf2cdbf7040f39d5273d5ef3a12c783e061e1731e5280e4a1df57349f54ddd6f6875c8d00ac7c13800fa39e80b93f1fd7ef1e7993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9e999f19bf7188cf57a4dc27248c62c367522eeef3abba5fa9d725eb6f16a66ea7d6fa3d10bbdfb2d202c35f1238c45f219469725e6dd99e9aad283872bbe1b8d6b82df7c55e87f4b634e35fe6c55f11d4673ff038783f3fc573c0e03960d102df3b8dc777d910371a9795aaefefb40c6ab7f33ea33ea8e947b1fb3f5cd30243d38f1cfb4e04876f4f61c0290979e471f16cd8513d536dc15ea34ea6c6c550e662a8e75e07f52c00bfb26e99df0b3c32e13379573118183c81451f999a90f15491f1f423e3b9908ce766329ed3c9787a93f13c4ec6d3958ca72519cf48329e87c878ee22e3398f8ce73a329e5c9c8367c3f31c194f07329e93c878c693f11492f10c23e33948c6d39f8ce707643cb792f15c4ec67326194f1f329e27c9783a93f15c41c69320e3194dc633988ce71e329e52329eb6643c3790f19c42c65341c6d39e8c6702194f73329ee1643c9792f10c20e3b9848ce776329eb3c978ae26e3799a8ca79c8ca7988ca71519cf18329e21643cf792f15c40c6731319cf69643cbdc8782692f17423e36941c6f30819cf40329e3bc978ce25e3b9968ce732329e67c978cac8784e24e31947c6d3948c672819cffd643cedc8782e22e3b9858ce70c329e2419cf13643c5dc8788e27e31945c633888ce76e329e12329eebc9789e27e3e941c67332194f0d194f33329e87c9781e20e3b9988ce736329eb3c878ae22e3798a8ca71319cf09643c45643cd5643c95643c7dc978ce27e3b9918ce754329e9e643c8f91f17427e3398e8c670419cf83643c7790f19c43c6730d19cf95643cadc978da90f13c43c6d3918ca7808027111cf92da604fcff00d8e49b411f83ad89657df21c56caabe3e2d4b647aebb8965dd1f591850a70fa12e499d2ffd7e534a27f4958479f157041c1f91f07424e379868ca70d194f6b329e2bc978ae21e339878ce70e329e07c9784690f11c47c6d39d8ce731329e9e643ca792f1dc48c6733e194f5f329e4a329e6a329e22329e13c8783a91f13c45c6731519cf59643cb791f15c4cc6f30019cfc3643ccdc8786ac8784e26e3e941c6f33c19cff5643c25643c7793f10c22e31945c6733c194f17329e27c87892643c6790f1dc42c67311194f3b329efbc9788692f13425e31947c67322194f1919cfb3643c9791f15c4bc6732e19cf9d643c03c9781e21e36941c6d38d8c6722194f2f329ed3c8786e22e3b9808ce75e329e21643c63c8785a91f11493f19493f13c4dc6733519cfd9643cb793f15c42c633808ce752329ee1643ccdc9782690f1b427e3a920e339858ce706329eb6643ca5643cf790f10c26e3194dc69320e3b9828ca73319cf93643c7dc878ce24e3b99c8ce756329e1f90f1f427e33948c6338c8ca7908c673c19cf49643c1dc8789e23e3d94fc6731d19cf79643c7791f13c44c633928ca725194f57329ec7c9787a93f19c4ec6733319cf85643cfdc878aac8789a90f18c3578f0ffeadd30393f926f0715c2ff07eacee5adf5baa48cbca3a4ee75ed316caabebb1dd5774f503b25617e37d457d8f700cf1e473c1f1a3ca6ef22c8578066bb0c9b62dce9887197c128f33b8151f4db053cbb1cf1ec36784cdf4590ef099aed306c8a71bb23c61d06a3cc6f0746d16f07f0ec70c4b3d3e0317d1741be2f68b6cdb029c6ad8e18b7198c32bf151845bf6dc0b3cd11cf7683c7f45d04f97ea0d907864d316e71c4f881c128f35b8051f4fb00783e70c4b3d5e0317d1741be3f68b6d9b029c64d8e18371b8c32bf091845bfcdc0b3d911cf1683c7f45d04f901a0d946c3a618373862dc6830cafc066014fd3602cf46473c9b0c1ed37711e4078266eb0d9b625ce78871bdc128f3eb8051f45b0f3ceb1df16c30784cdf45901f049aad356c8a718d23c6b506a3ccaf0146d16f2df0ac75c4b3cee0317d1741be12345b6dd814e32a478cab0d46995f058ca2df6ae059ed88678dc163fa2e827c1568b6d2b029c6158e18571a8c32bf021845bf95c0b3d211cf2a83c7f45d04f961a0d972c3a6189739625c6e30cafc326014fd9603cf72473c2b0c1ed37711e48783664b0d9b625ce28871a9c128f34b8051f45b0a3c4b1df12c33784cdf4590af06cd161b36c5b8c811e3628351e61701a3e8b71878163be25962f098be8b203f06345b68d814e302478c0b0d46995f008ca2df42e059e8886791c163fa2e82fc58d06cbe61538cf31c31ce3718657e1e308a7ef38167be239e05068fe9bb08f277834d78bb83ed7d9def06b6f774be2bd8ded5f92e607b47e73b83ed6d9def04b6b774be1c6c6fea7c47b0bda1f365607b5de73b80ed359def05b65775be37d8e6ea7c126c7374be0fd866ebfc55609ba5f357836da6ce5f03b6193a7f2dd8a6ebfc75609ba6f3d7836daacedf00b6293a7f23d826ebfc4d609ba4f33783ed159dbf056c2febfcad607b49e76f03db8b3a7f3bd85ed0f93bc0f6a8cedf09b6fb74fe2eb01dd2f97bc0f6a9cedf0bb6cf74fe7eb0fd50e71f00dbe73aff20d87ea4f30f81edc73a3f186c3fd1f92160fba9ce0f05dbcf74fe61b0fd5ce74780ed173aff08d87ea9f323c1f62b9d1f05b65febfc68b0fd46e7c781edb73a3f1e6cbfd3f91ab0fd5ee72780ed0f3aff18d8fea8f313c1f6279d7f1c6c7fd6f927c0f6179d7f126c5fe8fc5360fb52e79f06db573aff0cd8bed6f967c1f68dce3f07b6bfeafcf360fb9bcee358b77fd7f99220de76f6dba0762a01dfe24f95f987ce3737cac8b28550e644ddc1513de350efe2493b2cedb2b2493bfc3ed8a41d7e0f6cd20ebf0b366987df019bb4c36f834ddae1b7c026edf09b609376f80db0493bfc3ad8a41d7e0d6cd20ebf0ab6a4cecf059bb4c373c026edf06cb0493b3c0b6cd20ecf049bb4c333c026edf074b0493b3c0d6cd20e4f059bb4c353c026edf064b0493b3c096cd20ebf023669875f069bb4c32f814ddae117c126edf00b609376f851b0493b7c1fd8647ff9166cd2361f029bb4cd9f824ddae6cfc0266df30fc1266df3e76093b6f9476093b6f9c76093b6f9276093b6f9a76093b6f9676093b6f9e76093b6f9176093b6f9976093b6f957601badf3bf069bb4cdbf019bb4cdbf059bb4cdbf039bb4cdbf079bb4cd7f009bb4cd7f049bb4cd7f029bb4cd7f069bb4cd7f019bb4cd5f804ddae62fc1266df3576093b6f96bb049dbfc0dd89ed77969ab5b804d9e15aba9f47b4e380e0f9ef30b533288b7edc72909f9e7a0ee323521e379958ca78a8ca71f19cf85643ca793f1dc47c6d3928c673a19cf5b643c7f25e3594dc6b38a8c671b19cf56329ef3c878f693f19c44c65348c633878c671819cffb643c07c978fa93f1fc808ce772329e33c9780e91f15c41c69320e379838c672a19cf4a329e15643c1f90f16c21e32925e3694bc6730a194f05194f7b329ee6643cb3c8788693f1bc4bc6732919cf00329e4bc878ce26e32926e36945c633998c670c19cf6b643ccbc9789691f16c26e3d944c6730119cf5e329e0fc9784e23e36941c633838ce76d329e81643ce792f1cc27e3b98c8ce744329ea6643c73c9789692f12c21e39947c6b3918c6703194f3b329e8bc878f690f1ec26e339838ce778329e69643c6f92f10c22e32921e3e941c67332194f33329ed9643c8bc9781691f1bc47c6b39e8c671d19cfb7643cbbc8787692f19c45c67302194f1119cf14329e6a329ed7c9782ac978fa92f19c4fc6732a194f4f329ee3c8786692f12c24e35940c6f30e19cf5a329e35643c3bc878b693f19c43c67325194f6b329e36643c93c8780a087812c011804dfedf146cdfe8fc41b0c9f77af683ed6b9d9f0fb6af74fe79b03d63b135b1f009c3376093779b9f059bdcfffc1a6cf24ec0576093f32af1afe6e7b63d92bf092c237e9a5af8d1df57162ec9e3f696659241bcdb1b7d258323bfa754041ccf92f04c22e36943c6d39a8ce74a329e73c878b693f1ec20e35943c6b3968ce71d329e05643c0bc9786692f11c47c6d3938ce754329ef3c978fa92f15492f1bc4ec6534dc633858ca7888ce704329eb3c8787692f1ec22e3f9968c671d19cf7a329ef7c8781691f12c26e3994dc6d38c8ce764329e1e643c25643c83c878de24e39946c6733c19cf19643cbbc978f690f15c44c6d38e8c670319cf46329e79643c4bc8789692f1cc25e3694ac6732219cf65643cf3c978ce25e31948c6f33619cf0c329e16643ca791f17c48c6b3978ce702329e4d643c9bc9789691f12c27e3798d8c670c19cf64329e56643cc5643c6793f15c42c633808ce752329e77c9788693f1cc22e3694ec6d39e8ca7828ce714329eb6643ca5643c5bc8783e20e35941c6b3928c672a19cf1b643c09329e2bc8780e91f19c49c6733919cf0fc878fa93f11c24e3799f8c671819cf1c329e42329e93c878f693f19c47c6b3958c671b19cf2a329ed5643c7f25e3798b8c673a194f4b329efbc8784e27e3b9908ca71f194f1519cfab643c4dc878c65a78e63be291be2bb26e999fdfc87def367cefce13df3b0ddf3bf3c4f776c3f7f63cf1bdd5f0bd354f7c6f317c6fc913df9b0cdf9bf2c4f706c3f7863cf1bdcef0bd2e4f7caf317cafc913dfab0cdfabf2c4f70ac3f78a3cf1bdccf0bd2c4f7c2f317c2fc913df8b0cdf8bf2c4f702c3f7823cf1cd7cfdadfa29cbb720f6eadf04fc1fc78fdbef8871bec128f3fb81516c38fe7b0f473c51d7ee3d087c2b2da4efa2bc439f80ff5700a3ab98ea6130cabc2da670bcd10a473c51f71c2a087c2b2de45b8ef24dac04fc1fc74f7115531506a3ccdb620ac7ffeae98827ea5e494f02df4a0bf996a37c033801ffc7f1895cc5544f8351e66d3185e34df475c413758fa72f816fa5853c8b9167e609f87f3f607415537d0d4699b7c5d456e0e9e78827eade543f02df4a0be97b267d9613f0fffec0e82aa6fa198c326f8ba92dc0d3df114fd43db5fe04be9516f26e94bcc39a80ff0f00465731d5df6094795b4c6d029e018e78a2ee050e20f0adb418a8f3f28d9c04fc7f2030ba8aa90106a3ccdb626a03f00c74c413750f7320816fa5c5209d976f7026e0ff8380d1554c0d341865de1653eb806790239ea87baf83087c2b2d2a755ec64048c0ff2b81d1554c0d321865de1653385e5ba5239ea87bc69504be9516d23746fa0c26e0ff55c038c81163a5c128f38380516cab80a7ca114fd4bdee2a02df4a0be9ebbe52ff26e0ffc380d1554c55198c326f8ba915c033cc114fd43dfa6104be9516c3755ebee19180ff0f0746573135cc6094795b4c2d039ee18e78a29e2d0c27f0adb490b10fe49b7c09f83f8e97ed2aa6861b8c326f8ba925c053ed886791c1b3c8a2c5b1f2adb4906fbf2cd6bf09f8ff1860741553d506a3ccdb626a11f08c71c413f52c670c816fa585f4ed5ca87f13f0ffb1c0e82aa6c6188c326f8b291c7f79ac239ea867506373e03bea794a2e7c473d1bc885efa8fbdcb9f01d75cf3617bea3ee3fe6c277d4bdb45cf88eba2f940bdf51f73872e13bea7a3d17bea3ae3d73e13bea3a2a17bea3ae0972e13beafc3617bea3ced572e13beabcc3b7e7be3d8fdbf7b13c77c8d7f6fc581e438fe5b1c45f1bf86b835cf9f6c7127f6d902bdff97a6de0dbf3dcb7e772fd5510445f8f2d73e47b89e15be6f139cb1247be1719be651e9f192c72e47b81e15be6f1fef70247be8b0cdf32bf2007be5b19be5be5d0771bc3771b8b6f17db3b111c7efd2d0c3825218f31b0d0018fa37a96aaf52ed6ebfa2ec6f5daeedb98fb4b3194590cfab96e3b64dd99da8e16f1f92e4d800f19334ed9e459ecfb609336f43db0c933f677c126edfc3b6093e73b6f834d9effbc05b6e13a7f086cf21c16fbbfcbb3f4ed60abd479ec773d48e7b7824dfa25617f5fe95bb6056cd23f10fb994a1fcf4d60937ebad8bf51fa5a6f009bf497c77e75f2cec33ab0c97b2bd89f6bbfceaf019b7ca312fb117dadf3abc0f68dceaf04db733abf026c4febfc7d60fb52e7bf05db533abf006c5fe8fc42b03da9f38bc1f6179d7f136c7fd6f937c0f684cebf0eb6c7751edf0bfb93ce7f08b6893a8fef23fd51e77783ed319dc7f760fea0f33bc1f67b9d7f0d6c1374fe55b0d5e8fc5cb0fd4ee7e7806dbccecf06db6f757e16d8c6e9fc4cb0fd46e76780edd73a3f1d6ca3757e1ad87ea5f353c1364ae7a7806da4ce4f06db2f757e12d81ed1f9bf82ed173abf086c4d747e09d8647c41ecf321dfcc5c063619371bfbf2c8580263c1769cce8f015b0b9daf069b7c676d38d864acde61604be87c15d84ed0f94ab0c9b9ce20b0c9582b03c126e72503c0d65ae7fb834dce21fa814dc63eec0b36f99e674fb0c998de156093eff8f700dba93a3f1f6c32bed97eb0c937d70e824dc611fe1a6cf2ade56fc07696ce3f073619f3e569b09da3f35f82ed5c9d7f0a6cf27dce2fc056a2f34f82adadceff056ce7ebfc9fc126e3833d0136f9a6dbe360937178ff0436f976f244b05dacf37f04db253aff18d8641c953f804dc692fc3dd8dae9fc04b0c937a46bc07685ceff0e6c32b6c578b05da9f3bf059b8c61300e6c1d74fe37602bd3f95f83ada3ce8f065bb9ceff0a6c9d747e14d83aebfc48b075d1f95f82adabce3f02b66e3a2fed8cda9fd57e7e40cf278378cfb33f0e0e9f329d670b03f2c479de5a0c3ce86b5fec752f4b9d234b5bd044af5762681ff8de1bbbeff4f9f9477a5d857abd7b0ddf8550a6b56e1cd47272cc6faa97db6f2c87f78464ddb2cc9560ffd058776b5ddf8f1cd577afc124dca88394395933a963e3769d77f43e7c99da0724d602d010a724e485c18d5665a5782e5c179e8f80675fec3ce96b5f173181fb56dcd7bee63d5133d68aa1cc5ed0ef4307fae1be2eeb9679f1e7993db367f6cc9ed9337b66cfec993db367f6cc9ed9337b66cfec993db367f6cc9e999f59f11cd0797cd62ce50e90308a6d1ff0b8b8cf8fcf6165fdeab9ceb2f36afdee8bddefe1cff79ae9f5961a752e84327f87674eab741ec7f194ed16b52d1d3c27ccb82dc55f11d4079f051d70c4b3cfe0d967d142f225b1f92e1be246e3b252d56f453d63df6fe87ac0a2a9abfd759f5e5781a129eeaf1f1b3cf86cb408783fd1bf0958cf27500707fb78c6b8107fb82fed039be43f064617db198f25d21ec8f3707c362d65f61bcfc5e3dff665a52edb8d3d50a76470647c17429943d0f67da6f3d837e400e8f63bcbff65caf49c5af45375de157f9d53db77277026c10ffade01ac31f93eec7d94029dc48fd80b21ff5be8cf21e5440fd15ad8d53e227d3a91dd5cee6363b96228b3db52ff64106ffd77193cbb0c66b54d7e0471f63b38febb6a937647687425682465f68146fb1df1ec33788443fca932b2fd9b1b6564d94228f325b451aa2ed2ce4b3db16f0b1e035c1dc7c497ac5be66de7c61f01a35947151fdd4eade5dd173b6fc3eafff56fd05ec4ddffebdf20860a802330d65f0aeb17aee641f4b145cafc4fe338eae21a03b7a5a927ea2c65fe17b443ed4bd2f96ccef58fd5755bd4b9fe6e073c89e0f06b6f35653abee331668f031e47f52cb51dbb3e34ea540c652e867a3a388fc9f85eed2ef0ed629ba316720eb5d7d0a210cab42c49ff4adb11a5235eab7e9493ba9459cf074b2d759132ad4a6aebd202ec7132b9dc6e3ba04e6abdfb2c7595322797d4ea72aace27603be17d938b2cff9729537b80e3da6c8bbfcea9edbb153893e0077d7f00ac31f93eecbb1a72be2f7ec45e08f90b4b6acb4a39d143b41676b58fc83b7fc86e2eb7d758ae18ca6cb7d43f19c45bff6d06cf3683596d93334a6af312472edbcded111a9582465206ef1fcbb11ddfbbb31df7f739e28e3aeeef0346b3ddc47317976cfb0d36f31eaaed7c50cae0399994e95892fe55ed6cc252d6bc37ece23e26be5b1a403d02a3ae32610c38b8362cc76b2769a7c44f7bb0efd379d1b9bda15d2194e95992fe7578de6dbd77695edfe13585709bfb16befb7155492db78a7bd94efbf46f11d83ed5bf2d0227d769e5b67b86c261bb677843492d3b2e2b5c872c7531af919b0447de53ffce288bf7dd322d87bed474d05846e9fba985699fe1a7052c1bdbbb1a1d4a4ba3f80f02dfc706b34d57d90f30e6f6e9bcb9afe0b5b194b9af24fd2b6d9259566dfb2f4eaed547b6a36887ed09c6e4c7c098d4f9d2ef37a5f6b98346fd655efc2946b9df731078e26fbbd2ef2b65731f783ff0b868db1db5d1a5788c6d11db7abb55da8eff1f1b5ae5f079adf5986f3e736f61e4e3f15d5665bbff64d362af85c7d57394282df65a7cc7a745e721b676cea6452efb3e4469f1a1c5778c5a0cc3fb9e99b4d863e171712f2a93167b2cbee3d3a24b69a6e71aa8c56e0b8fab7b0f515a88bf6c993f24606e61e4e3f15d5e69bb4f66d3629785c7d575739416bb2cbee3d3a24367bc4797498b9d169ef8efcf65d662a7c5777c5a74ed86f7f03269b1c3c2e3ea996e94163b2cbe638c8ba1b67b39362db65b78b6e7588bed16df319e1f76b6dd6bb369b1cdc2e3e0be6b462db6597cc7a8c560bcef9a498bad169ead39d662abc5777c5a5476b2dd13b669f18185c7d53de1282d3eb0f88e4f8bc15d95ef2d75d0628b85674b8eb5d862f11de335542a2e36d7418bcd169ecd39d662b3c5777c5a54a5ceb536d5418b4d169e4d39d66293c5777c5a94a68ea91beba0c5460bcfc61c6bb1d1e23bc6b8485d4f6ea883161b2c3c1b72acc5068bef188f23a9b8585f072dd65b78d6e7588bf516dff169312c75ff695d1db45867e15997632dd6597cc778cf2515176beba0c55a0bcfda1c6bb1d6e23b3e2d3aa68ea96beaa0c51a0bcf9a1c6bb1c6e23b3e2d86a69e89adae8316ab2d3cab73acc56a8bef18cf3b53edc5aa3a68b1cac2b32ac75aacb2f88ef1bc3375ff62651db45869e15999632d565a7cc7d876a6ce3b57d4418b15169e1539d66285c5778ce79d292d96d7418be5169ee539d662b9c5778ce79da9e3c8b23a68b1ccc2e36a3c91282d96597cc71817a9b673691db4586ae1599a632d965a7cc7785f2bd5762ea983164b2c3caec66b88d26289c5778cd723a97b7c8beba0c5620bcfe21c6bb1d8e23bc66745a973f04575d062918567518eb55804bef7c7ee3bdd9f5b7c485fac2b0c2d0aa14cf3b6e95fe98b15a5a3ac03fb95615d16c65e9774bfb2051175590875913227405d5a044ec6fb297754d754cccc873aa9f57e62a9ab9469d3b6569793743e01dbe410e876bee5ff321518f349c88b7eaaceefc75fe754acbe079c49f083bedf05d6987c7740df053a891fb11742be6ddbdab2524ef410ad855ded23f3741ed9cde51619cb1543997996fa278378ebffbec1f3bec19c7aef01e24ce2c84ddb95669a17a1d115a09194c13e7b9f38e231fb100a87f8536564fb3737cac8b28550e63268a3b05fa9d433111cd96fd2515bd601d965dd322ffe8ac1b61f18cd3aaaf838047d3f65ac08194742d9645c888eb09e2e864dd5b5aba3ba8a2f59b7cc77054619a7a24bee19cbeacad8d960543cdd1d6886636fc894e978d11d78ba39e07154cfd471a88751a7ae469d8aa10cbedbd8c3413d0bc0afac5be67b806f17db1cb59063f2a586168550e606e3fc314a4759878adf2e96baf4725c1759b7b44bbd72e0bbc2f0ddc9f09d080edfce419079ffaa00e69e0e98d57a7bc7bfde523c6f9398123f9da04e7d4083b8ea84eb92f3bc3e86b685907f10cef3a49c9495e397b0ab58966d89ece672dd8de58aa14c2f4bfd9341bcf5ef6df0f43698d536b90bceed1cec0fa918e86570c87c27d0ae778476bd403b2983c7bf2e8eb4eb69f0f4347c2b1e39c7e90136395710fe04fcbf630eb8cd76af87855b6c384e9ced5ca773fc8c19cf753a03a3d87a024f8523cdcc6d7da9a10f1e979b1b6564d94228330e8e8d094b59b5df5d5c505bafa6da1edbbb63ba4d6fee402f1ca731007d0243c300f4927a3673c0737c503b56e3f89aea71831f1e7ad7d0f4a347412b3430f1b7c0528d2660c37c538b2d080e1f92b2106c32246533b0353164c1a130a5bc0c69e7422ed443d65d6870b60096387de3709e32650a9de380c74528abd091213d75e8dc376e44cd508c8f6606677d6247fdaf69867251eb72b51dcc7d2209f3660c163af2df14ea9b8479f1a7b68d0cad3a66f09047fb8c7b78c2a8a1a36bc6a350e68e8df982e0f00d60fe4609ee6aa7c300c00a63e3d0cca8173618f23fd930c7c7cf598e63e69ada04e04fa6e341b7960e7453eb97b16f870c1e39f28e099523470cb96ec2e8213523aa47e3d66c612817b5a5e5ffcdc1666be2b1ac9ab0d9c2658fb3d86c138e32dc026c72e46a0936e1391e6c4d212fe5cd2de3245c2f84f5cb2ea5fea7c469a62b7e5c501b02723856edaada7fd5a99cfa84ac3a1552431babcda9862e56770cd5d0c4ea2b766ae86135d4b01a5af8cc203d74b01a2af89c203d14b0fada4549901edaf7fca076e85e351d02ce8b82f4d0bcea36cd2541fab44b0daddb2e480f9dab6e5db60fd29f7953efd6abd377755b409df2aa4b3c7539a24e41d5a9a7ba7da16e65a9533a75baac4e05d5e99bba1ce9adb5ee13a6abc2747598ae09d3b561ba2e4cd787e98630dd18a69bc27473986e09d3ad61ba2d4cb787e98e30dd19a6bbc2747798ee09d2c33bdf1ba4875f57c33fdf1fa487867e20480f1bfd60901e52faa1203ddcf4e0203d14f590203d4cf5d0203d84f5c3417a78eb11417ae8dc4783f450bb6a08ded1417a386c354cb61a3e5b0dfdab860956430aaba186d550c56a58633504b21a1af9c9203d0cb31ab2f999303d1ba487747e3e4c2f84e9c530bd14a697c3f44a901e1e5c0d1b3e25480f33ae861f9f1ea4872b9f19a4873757c39eabe1d0d530e96af87435acba1ae65d0dffae86857f2b4c6f87e99d20fd48423d8a518f28d4ed7ff5184cdda25e18a46f9d2f0ed28fb8d5237fd505427509515d645606e92e54aa4b99ea62a7ba1caa2e98aa4baaeaa2abba2cab2edcaa4bbbeae2af5e7950af80a85762d42b42ea9529f50a997aa54ebd62a85e1355af5daad788d56bd5fb82f46df10341fa51a9ba1dae1e0da87854b7ef3f0bd30fc3f479987e14a61f87e92761fa69987e16a69f07e9218cd570c76ab86435b4b21a72590dcfac8672564341ab21a2ff18a4879e564357ff25480f7ffd6598be0ad243707f13a4875fff5b98be0dd3dfc3f48f30fd334cff0a6a87d2c6c6e24cddc2e8ab9460704dcdd051636a4a6aaa4b464d18593362ccc8274a268ea8195e52fdd8d071c346564fc4853fd70bcb38e07dc68d1bfc44c988d155431f2fa99e5053523daca4b27ac2e8aac30ed4ffd40b9d7da4c7c15555d1cefefdfb90fe9f7a3a6da9db3e1961fdc6cc753ba1693d0439b13e0b756e5abf0a3da98f5272397b77fa5cb764fcc8ea9a92d292d1e1dff0e05a3d716855fb12fcdff850e4f13525e36b068fab291936ae7a544987f6b8de49c7d7a312050937306dceac9f38adf4b794ea1562fbceab87025f9c573fd2fff67d48ff473d9db628a9470d8bebb3505949fd082b4a2265193fa1b266dce02135d10bf7f93e0b5f5f9f6ade5bcf6a366b5b0f6789fa2c7469dbfa115e5f1f6763b37016fc7f9f92ba051c4f06009b2d6c6f00000027cb1f8b08000000000000ffed9d77701cc795c6679118565810cc99902c538ce06291c104e64c9992ac1c98409116495024942ccb922cc939e76c39cb39675bce392739e7ecf2d5dd3f57bebaab525df76c3fe34373668d5dcd03df60df543d6ccfdbde79bffee64dcf6cf7ec20131497bf1acbb872adb1c705672ff47ebf7bcd3fb6a52dc16de539393329e1ac4909676d4a38eb52c2599f12ce8694704e4809e7c494704e4a9033037c5cbc9353c69b4d19ef79413af2b631259cb9947036a584734a4a389b53c23935259cd352c2393d259c3352c23933259cb352c2393b259c7352c23937259cf352c2393f259c0b52c2b930259c8b52c2d99212cef353c27941829ccb8193c6c82f74af8f77af8bddeb45ee75897b5dea5e97b936d6b975bbcd15c6561a6bf5de5b65998dd9c1f282f75ebbb10e639dc6badc7b2deebd6e633dc67a8df5195b6d6c8db1b5c6d6195bef34d9606ca3b14dc6361bdb626cabb16dc6b61bdb616ca7b15dc6761bdb636cafb18b8d3dc1d83e639718bbd4d865c69e68ec728fe50a63571abbcad8d5c6ae3176adb1eb8c5d6fec0663fb8d1d3076d0d82163878d0d183b62ec4663478d1d33f6246337193b6eec84b193c6068d9d3276b3b1d3c6ce181b32768bb15b3dcd6e3376bbb13b8c3dd9e3bcd3d8538cdd65eca9c6ee36768fb17b8d3dcdd87dc6ee37f680b1a71b7b86b1671a7b96b1671b7b8eb1e71a7b9eb1e71b7b81b1171a7b91b1171b7b89b1971a7b99b1971b7b85b1571a7b95b1573b163a105e63ecb5c65e67ecf5c6de60ec41636f34f626636f36f616636f35f636636f37f690b177187ba7b177197bb7b1f7187bafb1f7197bbfb10f18fba0b10f19fbb0b18f18fba8b18f19fbb8b14f18fba4b14f19fbb4b1cf187bd8d8678d7dced8e78d7dc1d8178d7dc9d8978d7dc5d8578d7dcdd8d78d7dc3d3fc9bc6be65ecdbc6bee37cdf75afdf7375e998ffbe7bfd817bfda17bfd917bfdb157ff116ffd27defa4fddebcfdcebcfddeb2fdceb2fddebafdcebafddeb6fdceb6fddebefdcebefddeb1fdceb1fddeb9fdceb9fddeb5fdcab9d576b9f512c4f0c8697fe20a13ea963a0d78eab93d8febc9d9d13aa75efd16b8bf3d7b9757acd387fbd5baff7fc0d6ebdc1dbce44b73ed1f3e7dc7acef34f71eb533cff54b73ed5f34f77ebd33dfff96efd7cf067dd7bc586155facafd6b932e0a3fcac015fbdf3d582af813607be09ce570f3edabf0de09be47c13c037d9f926822feb7c93484b63e7395f7f9054aee40fd8ed3626bd5d3717914b9ef7a0dd6e1313ef94e4790fd9ed3633f0dafc98eab6d5087933cdf972e09bee7c4de0735dd0bf8e39eb9be97ccde09be57c53c137dbf9a6816f8ef34d07df5ce79b01be79ce37137cf39d6f16f81638df6cf02d74be39e05be47c73c1d7e27cf3c077bef3cd07df05ceb7007cd45f2e04df85ceb7087c746dd7023ebace3b1f7c74cd7781f3d97e626206e2393ff551613cea9fc1f778ea9bc1b798fa65f05d447d32f896406cf22d857e857ccb9c8ffa28fb5e9f2bf707491d1385f0185e9df476cd96ed76d726bfdd700e6c5d30ac753fc4590d5aad77e504ef0f69c3d8741d4371c85f07e51d5097ea911e749e2176dbefaf71e5f5253ed7e77d2e0775d644b4bf3f48b6fd6b3d9eb51e733db49f29678f68ce8e7a293b67af80ba7eeed135cf78ccd9ddc0917cceb6b76bce8e7a293b6707a0ae9f7b74dd3b1e73f66ae060c8d96e9e9c2de435678be36041109d7bf4dd673ce6ec51e0483e673b356747bf949db3f7425d3ff7e8fbef78ccd95b8123f99cedeed66b83512f65e7ec0ba0ae9f7b3416331e73f67ee060c8d983dacf8e7a293b675f0775fddca371c1f198b32f068ee473b6972967db356783e29c661044e71e8d518fc79c7d103892cfd9433a3e3bfaa5ec9cfd04d4f5738fe64bc663cebed795ed3cc377dd3cc37cf07dcff916006ff2b97db88d29b7db34b78bf77a0441748ed2dcdd78cced875dd9e6f10fe0de03f2fd90ee4b00df8f9cef02f0fdd8bb6783e918e8d26360f46d2af718f805d4f57399e691c7e331f03de060c8d96ecdd9d1b7a9dc9cfd1bd4f5738fee69188f39fb6be060c8d91ecdd9d1b7a9dc9cfd27d4f5736f892b8fc79cfd872bdbeb859fb9eb8565e0fbb9f32d07df2f9c6f05f87ee97c2bc1f72be76b05dfaf9d6f15f87ee37c79f0fdd6f9dac0f73be72b80eff7ced70ebe3f385f07f8fee87c9de0fb93f37581efcfced70dbebf385f0ff8feea7cbdce67efc9a37bafbee27c76df9246fd41b2fb96eeb1a46dd3fa8a3188dde4c56e1ac3d8cd5eece688d82b19626721062d196fbd1fca2b7979f239e0c158ab928fd56edbde1a8cbeedab8027cfd0f62cc4180d4f1e78da92e709cf9f85e4b71beee3564fd32cc46a8576b533b42b03b168dbb44ef172e0c3febb3d82b12379c6420662d1b669bd0318c987e7133aafd3f163cf878b33c3bc0cc752784d44f1e8f94fc4b10afc54e791e9c36ccb1c5b23bc8fe7d636cfc79497615e502cda36ad53bc46684fdbd8331646cb98f718b9fa880cc4a26dfbb1f1785f39f69a8d6abfe6c0770efaa442a57d5223b08dc5754adcbe96129be37c958118d4b791e605f0539d99ee0709b66fdb06fd2ec3f15728f7fa0dfb83e4f3b890c7e37a343cedc0c371ec331daf793cef3f1a249b6b9d9e566d9e5639a8d301fa7532e857ea3a84e229b3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb3322bb37c66bcff02e737a9de0a218ce42b000fc7387ff80c28b72ddabe9dd7f929cceb243f6f51c8e39c25dd63b8d46b731dd4f97b66b8ee2f613edd9f1bc439cd15bcda8dea3e8bc6e0ecb958ce39c4b879e0a8f9cb96c462170e71cdb7d97bd4ec73c85a3d5d574468ca709fca084d339ea6789fe2728fc7e6e99cda61368eb9bf72e722512b2a2739b787f718f0ee9762ff41b950138cec3ff03cd39578ec917398345fdee5c5ae833aff9319de37742f2afdaf3bff9e275ba7dbdb367d6629f8bbbd6d4f719f258e7a6ffbadf059aaf37fd0a7bebe26f897661cf77f60bf1c405b71e98732ce9b277f1e2ecee3b797c1d3093c1cfd0cd3f5461e8f81a4e7f1bb3dada2ae63a84e17e8d7cda05fd4b528ad533c6556666556666556666556666556666556666556666556666556666556666596cf8cbf1525d62cd42b08611ca37b1fc2f90c7afe0b6ddfceeb3cb766382ef73c1ccd392df3da5c0775be5d335cf785aedc189c7dbf43dcbe6498cf2bb92f295e23b407e782b87ecfdde1f174446841e596c46217e7f193d778781ebfddd3b510a129d7f18a73aca8291eaf6d1e0fce8d360667df5b9285ed8cc5bd43717941f1f058ea001f95f1f7d11cfb19cf25fe7d3d140fe7af1f72da4e09b8f67d21cfd96ff4409bfa83b3f3bb0eeabc07fabef7b932dec381f78e3c1cf13e2da5e6a9493f9667d9e58bf3beab81b31fe260ec35c09a50ec368c9d714671c85f07e5cfd40cd7a57aa407694decf618a1678221bbffb936ef7339a8d31bd1fefe20d9f6f7793c7d1eb3dd271f843c7b18ceff5c7d526f8c464b4123aa83d7415ce74efffe4affbe42ec471bbc3af4d93aa8f315e8a3e2ee1f8d3a07709fc768db51e731ffbc309afb3cabfd3ead47a0bf48fa3ead472087f03eadc0dbfe32d83e713504f1e716aaf3736ffbfe35397d06ef03a33abf82fea2c9ddb3d8189c7dfd8df74c8dc5f7abb8fba4291e5ed7d07ba369bb65ee81fafd0932634e200b5e27509dbf78fbac3b867b55c467ff1ef359d28a9e4385df5f7cfdac0ebdf099fe4474281ef37d5e5b28af7ba12d54e7bfbc6bc0e4af5b8ad780c9b775e43509f5031d116da53aff0dc7da3fe11a8ff6137eef68a83dfb7d5a4a5d03927eb6cd63fd7c608c2de1f9c0f5b5c375fde7fc92d6e53e1fb8cbfb9cc4e703ff2fe45903dc87ced557af89d16819684475f0b741741ec167f9468d759cabefd3782d85fd731368caf5bb03fffce78fab455d232cf334c66b84e98e798ad3d9afeb8f17d2f932c9fb86f1b712ad10177f2bd1caa4671e74eb8775bc2e3897b1f34cb1e39e399d1f83d871cf9c1e8bd8cd5eece6318cad9aabe6923467782672f8fb337c66a95d4a5d9712430e3e579302c6da1430d6a580b13e058c0d29609c9002c68929609c9402c6c92960cc02e3b93cb733e853a8541faefd55ea5a036333fcef9242b9ffbf83f97fa994bcf6c1d80cdfe9422d5606a3d702bfe7713cfba1dcfff5420cf8bf0ba6a680715a0a18a7a78071460a1867a68071560a1867a780714e0a18e7a680715e0a18e7a78071410a1817a68071510a185b52c0787e0a182f4801e3e352c078610a181f9f02c6c5ca9808e3725ec642a58c9687e37ffe3d96ff39c6c0938fbae794e9fed9b2ffdf1af3f349db2a7d6e1cde5bc2fb3fe11edbb3ed38ee1d29f7d976a5fedf2a1363a15246ae7b81f0bea3d1f044dd1fd4c6cb58a89491ebf72ff81bbdd1f07481669d119a3130162a65e4ba57aedc7b39f19efeae08cd18180b9532e27dd509f2849a7597c1d3039a754768c6c058a89491ebbee42cc4180d4f2f68d613a1190363a15246a6dfb6859af596c183bf01eb8dd08c81b15029a3e559cda4595f193cab41b3be08cd2431224fd2cfc9ee8b88c5f19bc172db4e0cc83829058c9353c088f74970f45fa5ee93e8e3d5a750a93e5cfbabd47d12189be1f731a116f87b887fa7c55a5e9e92f74960ec754c5ae0ef55fe9d16eb8087e3f7335988311a1e62c8c1e7a6a680715a0a18a7a78071460a1867a68071560a1867a780714e0a18e7a680715e0a18e7a78071410a1817a68071510a18f1bb2ac3b562c9ef2febc679ecb8ef2ae33d76dcf792f11e5bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73c97143b0d63fcca38fe1891a725399e3cb61d63f50b687b7f044f86a9ed186b8380b61343da18d7a78071750a1855c7e23d8895305a9e8d4c3c1bcae0d9083c9b98783696c1b309783627cf13e6d4a632788821079f5b9d02c6f52960541d5547498caa63f5e8a88ccaa88cca782e18d3d0872b632af2b15029a3e5d9923c4fa8d9e63278b68066f4b9365ec642a58c96676bf23ca1665bcae0d90a9a6d89d08c81b15029a3e5d9963c4fa8d9d63278b681665b233463602c54ca6879b627cf136ab6ad0c9eeda0d9b608cd18180b95325a9e1dc9f3849a6d2f83670768b63d423306c642a58c966767f23ca1663bcae0d9099aed88d08c81b15029a3e5d9953c4fa8d9ce32787681663b233463602c54ca68797627cf136ab6ab0c9edda0d9ae08cd18180b95325a9e3dc9f3849aed2e83670f68b63b4233a98cab53c0b83e058ccc3a162a65b43c7b9978f694c1b317782e66e2d95b06cfc5c0f384e479c29cbab80c1e62c8c1e756a780717d0a185547d55112a3ea583d3a2aa3322a63798cfd2960d47dad8cca38be1919bea796fc2dd2c5e33c769317bba94a62c7fd1669bcc7d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63cd73caf86d89ae79ae7d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cf25c5de977cec42b9cf98d9073c1ccfbc616a67de6ef712b7ad4713d4cf6a75a9a7d5c59e5639a87309e87729837e19884bdba6758a572ef34502989962176cff3209da4f31d67b7ad8f89731b53daeafbf6c9cc78eebebc77becb8be7ebcc7d63cd73caf86d89ae79ae7d5105bf35cf35c4a6c2cd707c3d7edf4fc53bb8d27ba729d5b4756f2539d2b27145fa7047a0c71c4d66348cf15d5105bf35cf3bc1a626b9e6b9e57436ccd73cdf36a88ad79ae795e0db135cf35cfab21b6e6b9e67935c4d63c9797e73978bf660c78028f2728c1b35018cf6c613c5385f1ac13c6334918cf52613cb5c278760ae3d9268ca74718cf66613c9dc2780ac2781609e359268c678e309e69c2783608e3992c8ca74e184f5e18cf6e613c8b85f1cc15c63316bfaf288767ba309ee5c278b2c278360ae3a917c6b34a18cf1e613cbb84f1f409e3d92e8c6789309e5e613c5dc278da85f16c11c6d32a8c679e309e19c278ce13c6d3288ca74118cf4a613c7b85f1ac11c6335f18cf4c613c39613c4dc2782608e3592b8c6787309eadc278ba85f16c12c6d3218c6785309e05c2786609e399228ca75918cf44613c19013cd9e0ec679265e1fd7de0abf13e6baf07e6cc187eff72e7af81cf5ce1cab511dbbe1c7cf4dbf02b223e8b3a5d0e6de977e5fc635b429d30563fac53bc46e0b84208cf44613ccdc278a608e399258c6781309e15c2783a84f16c12c6d32d8c67ab309e1dc278d60ae399208ca749184f4e18cf4c613cf385f1ac11c6b35718cf4a613c0dc2781a85f19c278c6786309e79c2785a85f16c11c6d32e8ca74b184faf309e25c278b60be3e913c6b34b18cf1e613cab84f1d40be3d9288c272b8c67b9309ee9c278f609e3992b8c67b1309eddc278f2c278ea84f14c16c6b34118cf34613c7384f12c13c6b348184f41184fa7309ecdc2787a84f16c13c6b353184fad309ea5c2782609e359278c67aa309ed9c278160ae3a989e061f8ff97210fddbf46dba6f57d426233ec87f0ff7e5ec9d4a6abdcb6eadd76899fe2d5419d83aee3b2f77be16789cbbfdf10c70aae028dae626a0bed8f8cb77fb863e37d950130049e3e41040fc7fda84ced1c918709feffd9bcd5ea6a4f2b7fdfe5a0ce95a0dfd50cfa45e536ad5f0d3c74de24d62cd45b2784917c9731f364a1cdb4943a06ae061e8e6392a99d61ae5ee3b5695d84ee540773f51a8676461d3bb47e0df06c706562cd42bd0d4218c97715334f16da4c4ba95cbd0678388e1da67686b97aadd7a60d11ba531dccd56b19da1975ecd0fab5c0b3d19589350bf5360a6124dfd5bc3c1d5968332da572f55ae0e1387698da19e6ea755e9b3646e84e753057af636867d4b143ebd7c17e5066658e62b63cf43b0262cd42bd4d4218c9770d2b4f473e0b6da6a5543f761df070f4f34cba87fdd8f55e9b3645e84e753057af676867d4b143ebd747c46e0992d5e2865168714304cf0d63ac05c52b97f9ca1432abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac731abceaa731cb3eaac3ac7314bd0d9f2d0734988350bf5360b6124dfb5bc3ce1ef82360723978cb7de0fe51b80e73a067d98da19de43bedf6bd3e608dda90e1e5ffb19da1975ecd0fa7ed80ffbcb60be3e85ccaa7365cc96879ed74cac59a8b7450823f9aee3e509fbb12dc1c8a5543fb61f7838fa79a67686fdd801af4d5b2274a73a787c1d606867d4b143eb144f9995398ed9f2d0ff0122d62cd4db2a84917c37b0f214c2df376e0d462ea5fab103c0b33f719e623fc6a07bd88f1df4dab4354277aa83b97a90a19d51c70ead1f84fd500ef3f52964569d55e73866d559758e63569d55e73866d559758e63569d55e73866d559758e63569d55e73866d559758e63569d55e73866d5b97a74b63cf4ff5788350bf5b6096124df7e569ef670de615b3072c978ebfd503e083c0712e729ce3b30e81ece3b1cf2dab42d4277aa83c7d7218676461d3bb47e08f6c37867be3e85cc9a1b63c3acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc72c21372ccf765726d62cd4db2e84917c077879c2e71e6c0f462ea5eedb39043c0719f4616a6778dfce61af4ddb2374a73a787c1d666867d4b143eb87613f28b33247315b9e1dae4cac59a8b7430823f90ef2f284fdd88e60e452aa1f3b0c3c1cfd3c533bc37e6cc06bd38e08dda90ee6ea00433ba38e1d5a1f80fda0ccca1cc56c7976ba32b166a1de4e218ce43bc4cb13f6633b83914ba97e6c007838fa79a67686fdd811af4d3b2374a73a98ab4718da1975ecd0fa11d80fcaaccc51cc9667972b136b16eaed12c248bec3cc3c5968332da5fab123c0c3d1cf33b533ecc76ef4dab42b4277aa83b97a23433ba38e1d5abf117876bb32b166a1de6e218ce41b60e6c9429b692995ab37020fc7b1c3d4ce30578f7a6dda1da13bd5c15c3dcad0cea86387d68f02cf1e5726d62cd4db2384917c479879b2d0665a4ae5ea51e0e1387698da19e6ea31af4d7b2274a73a98abc718da1975ecd0fa31e0d9ebcac49a857a7b8530920ffbb1bd4c3c8d1e4f638416e331769317bba94a62377bb19bab24b6e6b9e67935c4d63cd73c0faa20b6e6b9e67935c4aed65c53cdab53f3cc39d43c730e35cfa8e622357f34b9d89db96078a981580ce3736da31973449e85c278f609e3992d8c67aa309e49c278960ae3a915c6d3238ca753184f4118cf22613ccb84f1cc11c6334d18cf64613c75c278f2c278160be3992b8c67ba309ee5c278b2c278ea85f1ac12c6d3278c6789309e5e613c5dc278da85f1b40ae399278c6786309ef384f1340ae36910c6b35218cf1a613cf385f1cc14c69313c6d3248c6782309eb5c278ba85f17408e359218c6781309e59c278a608e36916c63351184f46004f3638fbb71df87b825af0d1fdfd7bc1f72457de07be9a8818b49d63e0a3f153da863d5f5d38e36c861af8cc4d115c4f8a8847716e8af8ec58e88eb1fa619de23502c74d4278260ae36916c6334518cf2c613c0b84f1ac10c6d3218ca75b18cf5a613c1384f13409e3c909e399298c67be309e35c278560ae36910c6d3288ce73c613c3384f1cc13c6d32a8ca75d184f97309e5e613c4b84f1f409e359258ca75e184f5618cf72613cd385f1cc15c6b358184f5e184f9d309ec9c278a609e399238c6799309e45c2780ac2783a85f1f408e3a915c6b35418cf24613c5385f1cc16c6b34f18cf42613c35113cfb9878e29ea7b04f406c3b0e4fd7a634469785f7c7e27741fb3c465a3f0a8ce4c3fb62f34c3c71cfa0c80b886db5580565bb64e17dfc5d07574ee53d465a8fca29bcaf7115134fdc733b5609886db5a0b90aba07200befe37dcc5c39b5ca63a4f5a89c6ae6e509ff7fc0ca60e452ea5e233ce638f621533bf378fc25f80c8dc86724aff4b4ca419db1788e445c7f40f1945999e3982d0fcd35112b9ecfc6e27754a3618c3abf32f084fd636b307229d53f1e051e8ef307533bc37eecb8d7a6d608dda90ee6ea718676461d3bb47e3c22764b90ac162746a1c589089e1363ac05c52b97795f0a9925e86c79e85e4462cd42bd154218c997e7e509fbc715c1c8a554ff78027838ce1f4ced0cfb84935e9b5644e84e75f0f83ac9d0cea86387d64fc27e2887f9780a9955e7ca982d0fcd89106b16ea15843092ef282b4f219f8536d352aa1f3b093c1cfd3c93ee613f36e8b5a910a13bd5c1e36b90a19d51c70ead0fc27e5066655666655666655666655666655666655666655666655666655666655666d9cc96877e3b4cac59a8d72e84917c2758798af30eedc1c8a5d4bcc320f09c4c9ca738efc0a07b38ef70ca6b537b84ee540773f514433ba38e1d5a3f05fb419995599995599995599995599995599995599995599995599995599995599965335b1e7a663bb166a15e871046f29de4e5097fb7d5118c5c4acd3b9c021e8e7919a67686f30e377b6dea88d09dea60aedeccd0cea86387d66f86fda0ccca1cc56c79e8d971c49a857a9d4218c937c8ca539c3fed0c462ea5fab19b8187a39f67d23decc74e7b6dea8cd09dea60ae9e666867d4b143eba7613f94c37c3c85ccaab3ea1cc7ac3aabce71ccaab3ea1cc7ac3aabce71ccaab3ea1cc7ac3aabce71ccaab3ea1cc7ac3aabce71ccaab3ea1cc7ac3a578fce9687fec722b166a15e971046f29d62e5690fe71dba82914ba97987d3c0c3312fc3a47b38ef70c66b535784ee54078faf330ced8c3a7668fd0cec87f1ce7c3c85cc9a1b63c3acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc7acb9a1cc71cc9a1bca1cc72c21372c4fb72b136b16ea750b6124dfcdbc3ce1730fba83914ba9fb76ce00cf69067d98da19deb733e4b5a93b4277aa83c7d710433ba38e1d5a1f82fda0ccca1cc56c797a5c9958b350af470823f94e33f364a1cdb494eac7868087a39f676a67d88fdde2b5a9274277aa83b97a0b433ba38e1d5abf05787a5d9958b350af570823f9f01cd7cbc4d3e8f134466871ae625b2dfa5cf93cf79a85f7fb8091ab6fe9f518691d739c7c8dc0d3c7c4d3e4f134456871ae625b2dd640d92e59787f0d3072e5549fc748eb5139d5043c6b98789a3d9ee6082dce556cabc55a579ee25eb3f0fe5a60e4caa9351e23ad47e55433f0ac65e289eb93d68e41ecb8e36b2c62c7e5ca58c456cd5573d55c35e7d43c730e35cf9c43cd33aab928cd19aea3c2b1538a1100032efd50c6ef0a1cd79e4cedcc477d1f5bebb509bf8fe198c3b9fabea1ccca1cc7cc346ed191f562933e81c743cb10b316633906d9e7b549da1864b9ccc753c8ac3a57c66c63df9a7cec8eac179bf4093c1e5a6e65d682a99d617f705b10ad31c5cb411dccd3db18da9981b8b46d5abf0df64339ccc753c8ac3a57c66c63df9e78ece2b3d93136e913783cb4dcceac054f3b8bfdc11d41b4c6142f0775304fef60686706e2d2b669fd0ed80fcaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaaccccaacccca2c9bd9c67e72e2b18be3f7189bf4093c1e5a9eccac054f3b8be3f77706d11a53bc1cd4c17d7e27433b331097b64deb77c27e5066655666655666655666655666655666655666655666655666655666655666d9cc36f653928f1dfe1e0763933e81c743cb5398b5606a67387e7f5710ad31c5cb411ddce77731b433037169dbb47e17ec076556e628661bfba989c72ecee7616cd227f07868792ab3163ced2cf6077707d11a53bc1cd4c17d7e37433b331097b64deb77c37e2887f9780a995567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975569de3985567d5398e5975ae1e9d6dec7b128fdd1e8edf636cd227f07868b987590b9e7616c7efef0da235a67839a883797a2f433b331097b64deb14af1a988fa7905973636c98353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e398353794398e59734399e39825e4868dfdb4e46387bf67c7d8a44fe0f1d0f234662d98da19deff725f10ad31c5cb411dccd3fb18da9981b8b46d5abf0ff683322b7314b38d7d3f43ecac179bf4093c1e5aee67d682a99d617ff04010ad31c5cb411ddce70f30b433037169dbb4fe00c446bd138a1dde0349316adcabf53ddd956bc1f70c57ae03df335db91e7ccf72e506f03ddb952780ef39d01ef23dd7959783ef79aebc167ccf77e535e07b812bf781ef85aedc0bbe17b9f210f85eeccab780ef25ae7c2bf85eeacab781ef65ae7c3bf85eeeca7780ef15aefc64f0bdd295ef04dfab5cf929e07bb52bdf05bed7b8f253c1f75a57be1b7caf73e57bc0f77a57be177c6f70e5c5e07b30c2f746577e1af8dee4caf781efcdaebc0f7c6f71e549e07bab2b4f06dfdba04caf6f77e5f3c0f7902b3782ef1dae9c03df3b5db9097cef72e529e07bb72b3783ef3dae3c157cef75e569e07b9f2b4f07dffb5d7906f83ee0ca33c1f741579e05be0fb9f26cf07dd895e780ef23ae3c177c1f75e579e0fb982bcf07dfc75d7901f83ee1ca0bc1f749575e04be4fb932eedf4fbbf2fde0a37ee501f051bff274f051bff20cf051bff24cf051bff22cf051bff26cf051bff21cf051de3d177c9477cf031fe5ddf3c14779f702f051debd107c94772f021fe5dd8bc14779f712f051debd147c94772f031fe5ddcbc14779f70af051debd127c9477af021fe5ddabc14779f71af051debd167c9477af031fe5ddebc14779f706f051de3d083ecabb37828ff2ee4de06b71e53783ef7c577e0bf82e70e5b782ef71ae8cfdcc85aefc76f03dde951f021ff585ef00df45aefc4ef02d71e577816fa92bbf1b7ccb5cf93de05beecaef05df0a577e1ff856baf2fbc1d7eaca1f00df2a57fe20f8f2aefc21f0b5b9f287c15770e58f80afdd953f0abe0e57fe18f83a5df9e3e0eb72e54f80afdb953f09be1e57fe14f8e83c4efd8c3d9eed31483a9046d6476d6e8d680bf926425bfa8364afe928166d9bd6db8191f64161ec190ba3656cf3182d4f2783669857b494fafed1093c1d0c3c4ced0cbf7f74796d6af7da94833a17413bbb18da9981b8b46d5aef82d81cfb1cb5a877db5de269510775fec39de4ecb9b3948eb40d9bbf8588b6f432b785b64dfd52ef18c4eef662e7bdd8d81fd352eaf8ea06e61e0666bbddbee4b71b1e5fabddb628a7284e1edab4063448aa4d183be38ce290bf0eca353386eb523dd283ce5fc46e7399f625b2fb9febf43e97833abd11edef0f926d7f9fc7d3e731db7df2cfe9c31c0cc7439803bd1e07ade741bbbe18ed7a413baa83e7bf3626ed7a3c1e5a6f031ebac6e9021f5d2b103f5e67b58e01b7dfef75457093af1b18db2218f3c93386d73a6d1e23ade781917c3dc0d3cda499bfaf9778fae079b9c1ab439fad833ab35c5f322518f9fd83eadae36e7166b85df41dfcd120d93ebd81412f1c1f08409fc0d33000bda89df50c3c9383e13182334383a70fdc3870c9c081c31940abf330f13513d18c1af061b936c2170423874270489686427048b6c693058760a8befd2a659b45c30d03278e0d3df1e4c0c943a7ef3835347078f7e08d485defd123695c0b90147db44c0c86076dfa836493a7c18b552a7926c2eb04061ea6768627bd495e9b1abc36e5a04e3dbc3789a19d19884bdba6751c00261f6627bd8f1306355e5b308b27c1abbf6f136d10057c1c6c3fe3e0ec7b754ed806074fe2528f614711ed959cdd117654d0f6d676d4cf1e767654cf5e18d98edc8ed2d951393b0a6747ddec289b1d55b3a36876d4cc8e92d951b196a038ea7501f07c0518eda8961dc5b2a356f69ba43d2bd851283bea644799ecd584fd9662cfc0f68ad39e0ded59d05eedd86f53f69bb53dc3d8b3b73d33d9b389bd3ab25745f62ad65ed5d9999975c6d63bad3718db686c93b1cdc6b618db6a6c9bb1edc67618db696c97b1ddc6f618db6bec62634f088a23ca9718bbd4d865c69e68ec72635718bbd2d855c6ae36768db16b8d5d67ec7a633718db6fec80b183c60e193b6c6cc0d81163371a3b6aec98b12719bb2928dee171c2d8496383c64e19bbd9d869636782e22c919d15b2b34076d6c7cef2d8591d3b8b63676dec2c8d9d95b1b33076d6e59ea038ab626747ec6c881d09b723df76a4db8e6c3f33288e5cdb91eae704c591683bf26c479aedc8b21d49b623c776a4d88e0cdb91603bf26b477aedc8ae1dc9b523b776a4d68eccda91583bf26a475aedc8ea834171e4d48e94da91513b126a473eed48a71dd97c28288e5cda914a3b32694722edc8a31d69b4238b7624d18e1cda91423b32684702edc89f1de9b3237b7624cf8edcd9913a3b326747e23e63ec61639f35f639639f37f605635f34f625635f0e8a39f955635f33f67563df30f64d63df32f66d63df31f65d63df33f67d633f30f643633f32f663638f18fb89b19f1afb99b19f1bfb85b15f1afb95b15f1bfb8db1df1afb9db1df1bfb83b13f1afb93b13f1bfb8bb1bf06c3a3f6d851fcd3add008f281a1a18113a7865a86065b4edc727ce8d8a9e377b4dc766ce868cbe0ad03a78f1c1fbc0d3ffc76d735d1f0f886d3a70fdcd172ece4e181db5b066f196a193cd27270f0969387cfe087beec3e34ffec88070e1f8e0ff6e39ac740fab30a83fed97d8e261e76946edbdf2a11e43f2bf9d0b4daca1a74853bb3d0b7d24b8b57712d678e0f0eb5e45b4e9abf078e9bcf0c1c6e6dc1f7ce1891cf0cb59c193a707aa8e5c8e9c1132d6dadb8dd03932a68c43fa657f0a1993346dff2e0ff01dcf19ec8b1020400", "privateFunctions": [ { "selector": { @@ -37,8 +37,8 @@ exports[`ContractClass creates a contract class from a contract compilation arti "isInternal": false } ], - "id": "0x25ff42e7b5351646829b6ce29c6a64660cbcc9d81954e67ab57d47dfbc096613", + "id": "0x2c7b796a4fde879ee00d7603170a1611c382cc9a0d5bce8622037c43e31f20b5", "privateFunctionsRoot": "0x2dc1f38d7be98a8e72227d6f8aec393c60db813a1819c9c86b02a00cc18f6687", - "publicBytecodeCommitment": "0x2152b1029338584a8d43bbf80c6da9cf988c33c54e1f9b86741a2fa94986fe6b" + "publicBytecodeCommitment": "0x2fcce3b509bf46bbaf03634c4b983109b608e6bbd4084eec3b9880dfd17c8e37" }" `; diff --git a/yarn-project/simulator/src/avm/avm_context.test.ts b/yarn-project/simulator/src/avm/avm_context.test.ts index e2a29c8be9ba..efe11debf4da 100644 --- a/yarn-project/simulator/src/avm/avm_context.test.ts +++ b/yarn-project/simulator/src/avm/avm_context.test.ts @@ -15,7 +15,8 @@ describe('Avm Context', () => { allSameExcept(context.environment, { address: newAddress, storageAddress: newAddress, - calldata: newCalldata, + // Calldata also includes AvmContextInputs + calldata: expect.objectContaining(newCalldata), isStaticCall: false, }), ); @@ -41,7 +42,8 @@ describe('Avm Context', () => { allSameExcept(context.environment, { address: newAddress, storageAddress: newAddress, - calldata: newCalldata, + // Calldata also includes AvmContextInputs + calldata: expect.objectContaining(newCalldata), isStaticCall: true, }), ); diff --git a/yarn-project/simulator/src/avm/avm_execution_environment.test.ts b/yarn-project/simulator/src/avm/avm_execution_environment.test.ts index e2104cbad596..52bd524c894e 100644 --- a/yarn-project/simulator/src/avm/avm_execution_environment.test.ts +++ b/yarn-project/simulator/src/avm/avm_execution_environment.test.ts @@ -14,7 +14,8 @@ describe('Execution Environment', () => { allSameExcept(executionEnvironment, { address: newAddress, storageAddress: newAddress, - calldata, + // Calldata also includes AvmContextInputs + calldata: expect.objectContaining(calldata), }), ); }); @@ -27,7 +28,8 @@ describe('Execution Environment', () => { allSameExcept(executionEnvironment, { address: newAddress, isDelegateCall: true, - calldata, + // Calldata also includes AvmContextInputs + calldata: expect.objectContaining(calldata), }), ); }); @@ -41,7 +43,8 @@ describe('Execution Environment', () => { address: newAddress, storageAddress: newAddress, isStaticCall: true, - calldata, + // Calldata also includes AvmContextInputs + calldata: expect.objectContaining(calldata), }), ); }); diff --git a/yarn-project/simulator/src/avm/avm_execution_environment.ts b/yarn-project/simulator/src/avm/avm_execution_environment.ts index 23340dd42b8b..9ca1c3d649cb 100644 --- a/yarn-project/simulator/src/avm/avm_execution_environment.ts +++ b/yarn-project/simulator/src/avm/avm_execution_environment.ts @@ -1,8 +1,17 @@ import { FunctionSelector, GlobalVariables } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; +import { pedersenHash } from '@aztec/foundation/crypto'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; +class AvmContextInputs { + constructor(private selector: Fr, private argsHash: Fr) {} + + public toFields(): Fr[] { + return [this.selector, this.argsHash]; + } +} + /** * Contains variables that remain constant during AVM execution * These variables are provided by the public kernel circuit @@ -40,7 +49,13 @@ export class AvmExecutionEnvironment { // containing all functions, and function selector will become an application-level mechanism // (e.g. first few bytes of calldata + compiler-generated jump table) public readonly temporaryFunctionSelector: FunctionSelector, - ) {} + ) { + const inputs = new AvmContextInputs( + temporaryFunctionSelector.toField(), + pedersenHash(calldata.map(word => word.toBuffer())), + ); + this.calldata = [...calldata, ...inputs.toFields()]; + } public deriveEnvironmentForNestedCall( address: AztecAddress, diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index fc703ed3eac7..fbc9807f3213 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -1,5 +1,5 @@ import { UnencryptedL2Log } from '@aztec/circuit-types'; -import { EventSelector } from '@aztec/foundation/abi'; +import { EventSelector, FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { keccak, pedersenHash, poseidonHash, sha256 } from '@aztec/foundation/crypto'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -20,7 +20,7 @@ import { import { Add, CalldataCopy, Return } from './opcodes/index.js'; import { encodeToBytecode } from './serialization/bytecode_serialization.js'; -describe('AVM simulator', () => { +describe('AVM simulator: injected bytecode', () => { it('Should execute bytecode that performs basic addition', async () => { const calldata: Fr[] = [new Fr(1), new Fr(2)]; @@ -37,663 +37,688 @@ describe('AVM simulator', () => { expect(results.reverted).toBe(false); expect(results.output).toEqual([new Fr(3)]); }); +}); - describe('Transpiled Noir contracts', () => { - it('Should execute contract function that performs addition', async () => { - const calldata: Fr[] = [new Fr(1), new Fr(2)]; - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); +describe('AVM simulator: transpiled Noir contracts', () => { + it('addition', async () => { + const calldata: Fr[] = [new Fr(1), new Fr(2)]; + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + + const bytecode = getAvmTestContractBytecode('add_args_return'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + expect(results.reverted).toBe(false); + expect(results.output).toEqual([new Fr(3)]); + }); + + it('U128 addition', async () => { + const calldata: Fr[] = [ + // First U128 + new Fr(1), + new Fr(2), + // Second U128 + new Fr(3), + new Fr(4), + ]; + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const bytecode = getAvmTestContractBytecode('add_args_return'); + const bytecode = getAvmTestContractBytecode('add_u128'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + expect(results.reverted).toBe(false); + expect(results.output).toEqual([new Fr(4), new Fr(6)]); + }); + + describe.each([ + ['set_opcode_u8', 8n], + ['set_opcode_u32', 1n << 30n], + ['set_opcode_u64', 1n << 60n], + ['set_opcode_small_field', 0x001234567890abcdef1234567890abcdefn], + ['set_opcode_big_field', 0x991234567890abcdef1234567890abcdefn], + ])('SET functions', (name: string, res: bigint) => { + it(`function '${name}'`, async () => { + const context = initContext(); + const bytecode = getAvmTestContractBytecode(name); const results = await new AvmSimulator(context).executeBytecode(bytecode); expect(results.reverted).toBe(false); - expect(results.output).toEqual([new Fr(3)]); + expect(results.output).toEqual([new Fr(res)]); }); + }); + + describe.each([ + ['sha256_hash', sha256], + ['keccak_hash', keccak], + ])('Hashes with 2 fields returned in noir contracts', (name: string, hashFunction: (data: Buffer) => Buffer) => { + it(`Should execute contract function that performs ${name} hash`, async () => { + const calldata = [new Fr(1), new Fr(2), new Fr(3)]; + const hash = hashFunction(Buffer.concat(calldata.map(f => f.toBuffer()))); - it('Should execute contract function that performs U128 addition', async () => { - const calldata: Fr[] = [ - // First U128 - new Fr(1), - new Fr(2), - // Second U128 - new Fr(3), - new Fr(4), - ]; const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + const bytecode = getAvmTestContractBytecode(name); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - const bytecode = getAvmTestContractBytecode('add_u128'); + expect(results.reverted).toBe(false); + expect(results.output).toEqual([new Fr(hash.subarray(0, 16)), new Fr(hash.subarray(16, 32))]); + }); + }); + + describe.each([ + ['poseidon_hash', poseidonHash], + ['pedersen_hash', pedersenHash], + ])('Hashes with field returned in noir contracts', (name: string, hashFunction: (data: Buffer[]) => Fr) => { + it(`Should execute contract function that performs ${name} hash`, async () => { + const calldata = [new Fr(1), new Fr(2), new Fr(3)]; + const hash = hashFunction(calldata.map(f => f.toBuffer())); + + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + const bytecode = getAvmTestContractBytecode(name); const results = await new AvmSimulator(context).executeBytecode(bytecode); expect(results.reverted).toBe(false); - expect(results.output).toEqual([new Fr(4), new Fr(6)]); - }); - - describe.each([ - ['set_opcode_u8', 8n], - ['set_opcode_u32', 1n << 30n], - ['set_opcode_u64', 1n << 60n], - ['set_opcode_small_field', 0x001234567890abcdef1234567890abcdefn], - ['set_opcode_big_field', 0x991234567890abcdef1234567890abcdefn], - ])('Should execute contract SET functions', (name: string, res: bigint) => { - it(`Should execute contract function '${name}'`, async () => { - const context = initContext(); - const bytecode = getAvmTestContractBytecode(name); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - expect(results.output).toEqual([new Fr(res)]); - }); + expect(results.output).toEqual([new Fr(hash)]); }); + }); + + describe('Environment getters', () => { + const testEnvGetter = async (valueName: string, value: any, functionName: string, globalVar: boolean = false) => { + // Execute + let overrides = {}; + if (globalVar === true) { + const globals = initGlobalVariables({ [valueName]: value }); + overrides = { globals }; + } else { + overrides = { [valueName]: value }; + } + const context = initContext({ env: initExecutionEnvironment(overrides) }); + const bytecode = getAvmTestContractBytecode(functionName); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - describe.each([ - ['sha256_hash', sha256], - ['keccak_hash', keccak], - ])('Hashes with 2 fields returned in noir contracts', (name: string, hashFunction: (data: Buffer) => Buffer) => { - it(`Should execute contract function that performs ${name} hash`, async () => { - const calldata = [new Fr(1), new Fr(2), new Fr(3)]; - const hash = hashFunction(Buffer.concat(calldata.map(f => f.toBuffer()))); + expect(results.reverted).toBe(false); - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const bytecode = getAvmTestContractBytecode(name); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + const returnData = results.output; + expect(returnData).toEqual([value.toField()]); + }; - expect(results.reverted).toBe(false); - expect(results.output).toEqual([new Fr(hash.subarray(0, 16)), new Fr(hash.subarray(16, 32))]); - }); + it('address', async () => { + const address = AztecAddress.fromField(new Fr(1)); + await testEnvGetter('address', address, 'get_address'); }); - describe.each([ - ['poseidon_hash', poseidonHash], - ['pedersen_hash', pedersenHash], - ])('Hashes with field returned in noir contracts', (name: string, hashFunction: (data: Buffer[]) => Fr) => { - it(`Should execute contract function that performs ${name} hash`, async () => { - const calldata = [new Fr(1), new Fr(2), new Fr(3)]; - const hash = hashFunction(calldata.map(f => f.toBuffer())); + it('storageAddress', async () => { + const storageAddress = AztecAddress.fromField(new Fr(1)); + await testEnvGetter('storageAddress', storageAddress, 'get_storage_address'); + }); - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const bytecode = getAvmTestContractBytecode(name); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + it('sender', async () => { + const sender = AztecAddress.fromField(new Fr(1)); + await testEnvGetter('sender', sender, 'get_sender'); + }); - expect(results.reverted).toBe(false); - expect(results.output).toEqual([new Fr(hash)]); - }); + it('origin', async () => { + const origin = AztecAddress.fromField(new Fr(1)); + await testEnvGetter('origin', origin, 'get_origin'); }); - describe('Test env getters from noir contract', () => { - const testEnvGetter = async (valueName: string, value: any, functionName: string, globalVar: boolean = false) => { - // Execute - let overrides = {}; - if (globalVar === true) { - const globals = initGlobalVariables({ [valueName]: value }); - overrides = { globals }; - } else { - overrides = { [valueName]: value }; - } - const context = initContext({ env: initExecutionEnvironment(overrides) }); - const bytecode = getAvmTestContractBytecode(functionName); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - - const returnData = results.output; - expect(returnData).toEqual([value.toField()]); - }; - - it('address', async () => { - const address = AztecAddress.fromField(new Fr(1)); - await testEnvGetter('address', address, 'get_address'); - }); + it('portal', async () => { + const portal = EthAddress.fromField(new Fr(1)); + await testEnvGetter('portal', portal, 'get_portal'); + }); - it('storageAddress', async () => { - const storageAddress = AztecAddress.fromField(new Fr(1)); - await testEnvGetter('storageAddress', storageAddress, 'get_storage_address'); - }); + it('getFeePerL1Gas', async () => { + const fee = new Fr(1); + await testEnvGetter('feePerL1Gas', fee, 'get_fee_per_l1_gas'); + }); - it('sender', async () => { - const sender = AztecAddress.fromField(new Fr(1)); - await testEnvGetter('sender', sender, 'get_sender'); - }); + it('getFeePerL2Gas', async () => { + const fee = new Fr(1); + await testEnvGetter('feePerL2Gas', fee, 'get_fee_per_l2_gas'); + }); - it('origin', async () => { - const origin = AztecAddress.fromField(new Fr(1)); - await testEnvGetter('origin', origin, 'get_origin'); - }); + it('getFeePerDaGas', async () => { + const fee = new Fr(1); + await testEnvGetter('feePerDaGas', fee, 'get_fee_per_da_gas'); + }); - it('portal', async () => { - const portal = EthAddress.fromField(new Fr(1)); - await testEnvGetter('portal', portal, 'get_portal'); - }); + it('chainId', async () => { + const chainId = new Fr(1); + await testEnvGetter('chainId', chainId, 'get_chain_id', /*globalVar=*/ true); + }); - it('getFeePerL1Gas', async () => { - const fee = new Fr(1); - await testEnvGetter('feePerL1Gas', fee, 'get_fee_per_l1_gas'); - }); + it('version', async () => { + const version = new Fr(1); + await testEnvGetter('version', version, 'get_version', /*globalVar=*/ true); + }); - it('getFeePerL2Gas', async () => { - const fee = new Fr(1); - await testEnvGetter('feePerL2Gas', fee, 'get_fee_per_l2_gas'); - }); + it('blockNumber', async () => { + const blockNumber = new Fr(1); + await testEnvGetter('blockNumber', blockNumber, 'get_block_number', /*globalVar=*/ true); + }); - it('getFeePerDaGas', async () => { - const fee = new Fr(1); - await testEnvGetter('feePerDaGas', fee, 'get_fee_per_da_gas'); - }); + it('timestamp', async () => { + const timestamp = new Fr(1); + await testEnvGetter('timestamp', timestamp, 'get_timestamp', /*globalVar=*/ true); + }); + }); - it('chainId', async () => { - const chainId = new Fr(1); - await testEnvGetter('chainId', chainId, 'get_chain_id', /*globalVar=*/ true); + describe('AvmContextInputs', () => { + it('selector', async () => { + const context = initContext({ + env: initExecutionEnvironment({ + temporaryFunctionSelector: FunctionSelector.fromSignature('check_selector()'), + }), }); + const bytecode = getAvmTestContractBytecode('check_selector'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - it('version', async () => { - const version = new Fr(1); - await testEnvGetter('version', version, 'get_version', /*globalVar=*/ true); - }); + expect(results.reverted).toBe(false); + }); - it('blockNumber', async () => { - const blockNumber = new Fr(1); - await testEnvGetter('blockNumber', blockNumber, 'get_block_number', /*globalVar=*/ true); - }); + it('get_args_hash', async () => { + const calldata = [new Fr(8), new Fr(1), new Fr(2), new Fr(3)]; - it('timestamp', async () => { - const timestamp = new Fr(1); - await testEnvGetter('timestamp', timestamp, 'get_timestamp', /*globalVar=*/ true); - }); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + const bytecode = getAvmTestContractBytecode('get_args_hash'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + expect(results.reverted).toBe(false); + expect(results.output).toEqual([pedersenHash(calldata.map(f => f.toBuffer()))]); }); + }); - describe('Test tree access functions from noir contract (notes & nullifiers)', () => { - it(`Should execute contract function that checks if a note hash exists (it does not)`, async () => { - const noteHash = new Fr(42); - const leafIndex = new Fr(7); - const calldata = [noteHash, leafIndex]; + describe('Tree access (notes & nullifiers)', () => { + it(`Note hash exists (it does not)`, async () => { + const noteHash = new Fr(42); + const leafIndex = new Fr(7); + const calldata = [noteHash, leafIndex]; - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const bytecode = getAvmTestContractBytecode('note_hash_exists'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + const bytecode = getAvmTestContractBytecode('note_hash_exists'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - expect(results.reverted).toBe(false); - expect(results.output).toEqual([/*exists=false*/ new Fr(0)]); + expect(results.reverted).toBe(false); + expect(results.output).toEqual([/*exists=false*/ new Fr(0)]); - // Note hash existence check should be in trace - const trace = context.persistableState.flush(); - expect(trace.noteHashChecks).toEqual([expect.objectContaining({ noteHash, leafIndex, exists: false })]); - }); + // Note hash existence check should be in trace + const trace = context.persistableState.flush(); + expect(trace.noteHashChecks).toEqual([expect.objectContaining({ noteHash, leafIndex, exists: false })]); + }); - it(`Should execute contract function that checks if a note hash exists (it does)`, async () => { - const noteHash = new Fr(42); - const leafIndex = new Fr(7); - const calldata = [noteHash, leafIndex]; - - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - // note hash exists! - jest - .spyOn(context.persistableState.hostStorage.commitmentsDb, 'getCommitmentIndex') - .mockReturnValue(Promise.resolve(BigInt(7))); - const bytecode = getAvmTestContractBytecode('note_hash_exists'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - expect(results.output).toEqual([/*exists=true*/ new Fr(1)]); - - // Note hash existence check should be in trace - const trace = context.persistableState.flush(); - expect(trace.noteHashChecks).toEqual([expect.objectContaining({ noteHash, leafIndex, exists: true })]); - }); + it(`Note hash exists (it does)`, async () => { + const noteHash = new Fr(42); + const leafIndex = new Fr(7); + const calldata = [noteHash, leafIndex]; - it(`Should execute contract function to emit unencrypted logs (should be traced)`, async () => { - const context = initContext(); - const bytecode = getAvmTestContractBytecode('emit_unencrypted_log'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - - const expectedFields = [new Fr(10), new Fr(20), new Fr(30)]; - const expectedString = 'Hello, world!'.split('').map(c => new Fr(c.charCodeAt(0))); - const expectedCompressedString = Buffer.from( - '\0A long time ago, in a galaxy fa' + '\0r far away...\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', - ); - expect(context.persistableState.flush().newLogs).toEqual([ - new UnencryptedL2Log( - context.environment.address, - new EventSelector(5), - Buffer.concat(expectedFields.map(f => f.toBuffer())), - ), - new UnencryptedL2Log( - context.environment.address, - new EventSelector(8), - Buffer.concat(expectedString.map(f => f.toBuffer())), - ), - new UnencryptedL2Log(context.environment.address, new EventSelector(10), expectedCompressedString), - ]); - }); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + // note hash exists! + jest + .spyOn(context.persistableState.hostStorage.commitmentsDb, 'getCommitmentIndex') + .mockReturnValue(Promise.resolve(BigInt(7))); + const bytecode = getAvmTestContractBytecode('note_hash_exists'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - it(`Should execute contract function to emit note hash (should be traced)`, async () => { - const utxo = new Fr(42); - const calldata = [utxo]; + expect(results.reverted).toBe(false); + expect(results.output).toEqual([/*exists=true*/ new Fr(1)]); - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const bytecode = getAvmTestContractBytecode('new_note_hash'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + // Note hash existence check should be in trace + const trace = context.persistableState.flush(); + expect(trace.noteHashChecks).toEqual([expect.objectContaining({ noteHash, leafIndex, exists: true })]); + }); - expect(results.reverted).toBe(false); + it(`Emit unencrypted logs (should be traced)`, async () => { + const context = initContext(); + const bytecode = getAvmTestContractBytecode('emit_unencrypted_log'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - expect(context.persistableState.flush().newNoteHashes).toEqual([utxo]); - }); + expect(results.reverted).toBe(false); - it(`Should execute contract function to emit nullifier (should be traced)`, async () => { - const utxo = new Fr(42); - const calldata = [utxo]; + const expectedFields = [new Fr(10), new Fr(20), new Fr(30)]; + const expectedString = 'Hello, world!'.split('').map(c => new Fr(c.charCodeAt(0))); + const expectedCompressedString = Buffer.from( + '\0A long time ago, in a galaxy fa' + '\0r far away...\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', + ); + expect(context.persistableState.flush().newLogs).toEqual([ + new UnencryptedL2Log( + context.environment.address, + new EventSelector(5), + Buffer.concat(expectedFields.map(f => f.toBuffer())), + ), + new UnencryptedL2Log( + context.environment.address, + new EventSelector(8), + Buffer.concat(expectedString.map(f => f.toBuffer())), + ), + new UnencryptedL2Log(context.environment.address, new EventSelector(10), expectedCompressedString), + ]); + }); - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const bytecode = getAvmTestContractBytecode('new_nullifier'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + it(`Emit note hash (should be traced)`, async () => { + const utxo = new Fr(42); + const calldata = [utxo]; - expect(results.reverted).toBe(false); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + const bytecode = getAvmTestContractBytecode('new_note_hash'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - expect(context.persistableState.flush().newNullifiers).toEqual([utxo]); - }); + expect(results.reverted).toBe(false); - it(`Should execute contract function that checks if a nullifier exists (it does not)`, async () => { - const utxo = new Fr(42); - const calldata = [utxo]; + expect(context.persistableState.flush().newNoteHashes).toEqual([utxo]); + }); - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const bytecode = getAvmTestContractBytecode('nullifier_exists'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + it(`Emit nullifier (should be traced)`, async () => { + const utxo = new Fr(42); + const calldata = [utxo]; - expect(results.reverted).toBe(false); - expect(results.output).toEqual([/*exists=false*/ new Fr(0)]); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + const bytecode = getAvmTestContractBytecode('new_nullifier'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - // Nullifier existence check should be in trace - const trace = context.persistableState.flush(); - expect(trace.nullifierChecks.length).toEqual(1); - expect(trace.nullifierChecks[0].exists).toEqual(false); - }); + expect(results.reverted).toBe(false); - it(`Should execute contract function that checks if a nullifier exists (it does)`, async () => { - const utxo = new Fr(42); - const calldata = [utxo]; - - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - // nullifier exists! - jest - .spyOn(context.persistableState.hostStorage.commitmentsDb, 'getNullifierIndex') - .mockReturnValue(Promise.resolve(BigInt(42))); - const bytecode = getAvmTestContractBytecode('nullifier_exists'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - expect(results.output).toEqual([/*exists=true*/ new Fr(1)]); - - // Nullifier existence check should be in trace - const trace = context.persistableState.flush(); - expect(trace.nullifierChecks.length).toEqual(1); - expect(trace.nullifierChecks[0].exists).toEqual(true); - }); + expect(context.persistableState.flush().newNullifiers).toEqual([utxo]); + }); - it(`Should execute contract function that checks emits a nullifier and checks its existence`, async () => { - const utxo = new Fr(42); - const calldata = [utxo]; + it(`Nullifier exists (it does not)`, async () => { + const utxo = new Fr(42); + const calldata = [utxo]; - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const bytecode = getAvmTestContractBytecode('emit_nullifier_and_check'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + const bytecode = getAvmTestContractBytecode('nullifier_exists'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - expect(results.reverted).toBe(false); - // Nullifier existence check should be in trace - const trace = context.persistableState.flush(); - expect(trace.newNullifiers).toEqual([utxo]); - expect(trace.nullifierChecks.length).toEqual(1); - expect(trace.nullifierChecks[0].exists).toEqual(true); - }); + expect(results.reverted).toBe(false); + expect(results.output).toEqual([/*exists=false*/ new Fr(0)]); - it(`Should execute contract function that emits same nullifier twice (should fail)`, async () => { - const utxo = new Fr(42); - const calldata = [utxo]; + // Nullifier existence check should be in trace + const trace = context.persistableState.flush(); + expect(trace.nullifierChecks.length).toEqual(1); + expect(trace.nullifierChecks[0].exists).toEqual(false); + }); - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const bytecode = getAvmTestContractBytecode('nullifier_collision'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + it(`Nullifier exists (it does)`, async () => { + const utxo = new Fr(42); + const calldata = [utxo]; - expect(results.reverted).toBe(true); - // Only the first nullifier should be in the trace, second one failed to add - expect(context.persistableState.flush().newNullifiers).toEqual([utxo]); - }); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + // nullifier exists! + jest + .spyOn(context.persistableState.hostStorage.commitmentsDb, 'getNullifierIndex') + .mockReturnValue(Promise.resolve(BigInt(42))); + const bytecode = getAvmTestContractBytecode('nullifier_exists'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + expect(results.reverted).toBe(false); + expect(results.output).toEqual([/*exists=true*/ new Fr(1)]); + + // Nullifier existence check should be in trace + const trace = context.persistableState.flush(); + expect(trace.nullifierChecks.length).toEqual(1); + expect(trace.nullifierChecks[0].exists).toEqual(true); }); - describe('Test tree access functions from noir contract (l1ToL2 messages)', () => { - it(`Should execute contract function that checks if a message exists (it does not)`, async () => { - const msgHash = new Fr(42); - const leafIndex = new Fr(24); - const calldata = [msgHash, leafIndex]; + it(`Emits a nullifier and checks its existence`, async () => { + const utxo = new Fr(42); + const calldata = [utxo]; - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - const bytecode = getAvmTestContractBytecode('l1_to_l2_msg_exists'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + const bytecode = getAvmTestContractBytecode('emit_nullifier_and_check'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - expect(results.reverted).toBe(false); - expect(results.output).toEqual([/*exists=false*/ new Fr(0)]); - // Message existence check should be in trace - const trace = context.persistableState.flush(); - expect(trace.l1ToL2MessageChecks.length).toEqual(1); - expect(trace.l1ToL2MessageChecks[0].exists).toEqual(false); - }); + expect(results.reverted).toBe(false); + // Nullifier existence check should be in trace + const trace = context.persistableState.flush(); + expect(trace.newNullifiers).toEqual([utxo]); + expect(trace.nullifierChecks.length).toEqual(1); + expect(trace.nullifierChecks[0].exists).toEqual(true); + }); - it(`Should execute contract function that checks if a message exists (it does)`, async () => { - const msgHash = new Fr(42); - const leafIndex = new Fr(24); - const calldata = [msgHash, leafIndex]; - - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - jest - .spyOn(context.persistableState.hostStorage.commitmentsDb, 'getL1ToL2MembershipWitness') - .mockResolvedValue(initL1ToL2MessageOracleInput(leafIndex.toBigInt())); - const bytecode = getAvmTestContractBytecode('l1_to_l2_msg_exists'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - expect(results.output).toEqual([/*exists=false*/ new Fr(1)]); - // Message existence check should be in trace - const trace = context.persistableState.flush(); - expect(trace.l1ToL2MessageChecks.length).toEqual(1); - expect(trace.l1ToL2MessageChecks[0].exists).toEqual(true); - }); + it(`Emits same nullifier twice (should fail)`, async () => { + const utxo = new Fr(42); + const calldata = [utxo]; + + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + const bytecode = getAvmTestContractBytecode('nullifier_collision'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + expect(results.reverted).toBe(true); + // Only the first nullifier should be in the trace, second one failed to add + expect(context.persistableState.flush().newNullifiers).toEqual([utxo]); }); + }); - describe('Test nested external calls from noir contract', () => { - it(`Should execute contract function that makes a nested call`, async () => { - const calldata: Fr[] = [new Fr(1), new Fr(2)]; - const callBytecode = getAvmTestContractBytecode('raw_nested_call_to_add'); - const addBytecode = getAvmTestContractBytecode('add_args_return'); - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - jest - .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') - .mockReturnValueOnce(Promise.resolve(addBytecode)); + describe('Test tree access (l1ToL2 messages)', () => { + it(`Message exists (it does not)`, async () => { + const msgHash = new Fr(42); + const leafIndex = new Fr(24); + const calldata = [msgHash, leafIndex]; - const results = await new AvmSimulator(context).executeBytecode(callBytecode); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + const bytecode = getAvmTestContractBytecode('l1_to_l2_msg_exists'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - expect(results.reverted).toBe(false); - expect(results.output).toEqual([new Fr(3)]); - }); + expect(results.reverted).toBe(false); + expect(results.output).toEqual([/*exists=false*/ new Fr(0)]); + // Message existence check should be in trace + const trace = context.persistableState.flush(); + expect(trace.l1ToL2MessageChecks.length).toEqual(1); + expect(trace.l1ToL2MessageChecks[0].exists).toEqual(false); + }); - it(`Should execute contract function that makes a nested call through the old interface`, async () => { - const calldata: Fr[] = [new Fr(1), new Fr(2)]; - const callBytecode = getAvmTestContractBytecode('nested_call_to_add'); - const addBytecode = getAvmTestContractBytecode('add_args_return'); - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - jest - .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') - .mockReturnValueOnce(Promise.resolve(addBytecode)); + it(`Message exists (it does)`, async () => { + const msgHash = new Fr(42); + const leafIndex = new Fr(24); + const calldata = [msgHash, leafIndex]; - const results = await new AvmSimulator(context).executeBytecode(callBytecode); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + jest + .spyOn(context.persistableState.hostStorage.commitmentsDb, 'getL1ToL2MembershipWitness') + .mockResolvedValue(initL1ToL2MessageOracleInput(leafIndex.toBigInt())); + const bytecode = getAvmTestContractBytecode('l1_to_l2_msg_exists'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - expect(results.reverted).toBe(false); - expect(results.output).toEqual([new Fr(3)]); - }); + expect(results.reverted).toBe(false); + expect(results.output).toEqual([/*exists=false*/ new Fr(1)]); + // Message existence check should be in trace + const trace = context.persistableState.flush(); + expect(trace.l1ToL2MessageChecks.length).toEqual(1); + expect(trace.l1ToL2MessageChecks[0].exists).toEqual(true); + }); + }); - it(`Should execute contract function that makes a nested static call`, async () => { - const calldata: Fr[] = [new Fr(1), new Fr(2)]; - const callBytecode = getAvmTestContractBytecode('raw_nested_static_call_to_add'); - const addBytecode = getAvmTestContractBytecode('add_args_return'); - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - jest - .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') - .mockReturnValueOnce(Promise.resolve(addBytecode)); + describe('Nested external calls', () => { + it(`Nested call`, async () => { + const calldata: Fr[] = [new Fr(1), new Fr(2)]; + const callBytecode = getAvmTestContractBytecode('raw_nested_call_to_add'); + const addBytecode = getAvmTestContractBytecode('add_args_return'); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + jest + .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') + .mockReturnValueOnce(Promise.resolve(addBytecode)); - const results = await new AvmSimulator(context).executeBytecode(callBytecode); + const results = await new AvmSimulator(context).executeBytecode(callBytecode); - expect(results.reverted).toBe(false); - expect(results.output).toEqual([/*result=*/ new Fr(3), /*success=*/ new Fr(1)]); - }); + expect(results.reverted).toBe(false); + expect(results.output).toEqual([new Fr(3)]); + }); - it(`Should execute contract function that makes a nested static call which modifies storage`, async () => { - const callBytecode = getAvmTestContractBytecode('raw_nested_static_call_to_set_storage'); - const nestedBytecode = getAvmTestContractBytecode('set_storage_single'); - const context = initContext(); - jest - .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') - .mockReturnValueOnce(Promise.resolve(nestedBytecode)); + it(`Nested call through the old interface`, async () => { + const calldata: Fr[] = [new Fr(1), new Fr(2)]; + const callBytecode = getAvmTestContractBytecode('nested_call_to_add'); + const addBytecode = getAvmTestContractBytecode('add_args_return'); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + jest + .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') + .mockReturnValueOnce(Promise.resolve(addBytecode)); - const results = await new AvmSimulator(context).executeBytecode(callBytecode); + const results = await new AvmSimulator(context).executeBytecode(callBytecode); - expect(results.reverted).toBe(false); // The outer call should not revert. - expect(results.output).toEqual([new Fr(0)]); // The inner call should have reverted. - }); + expect(results.reverted).toBe(false); + expect(results.output).toEqual([new Fr(3)]); + }); - it(`Should execute contract function that makes a nested static call (old interface)`, async () => { - const calldata: Fr[] = [new Fr(1), new Fr(2)]; - const callBytecode = getAvmTestContractBytecode('nested_static_call_to_add'); - const addBytecode = getAvmTestContractBytecode('add_args_return'); - const context = initContext({ env: initExecutionEnvironment({ calldata }) }); - jest - .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') - .mockReturnValueOnce(Promise.resolve(addBytecode)); + it(`Nested static call`, async () => { + const calldata: Fr[] = [new Fr(1), new Fr(2)]; + const callBytecode = getAvmTestContractBytecode('raw_nested_static_call_to_add'); + const addBytecode = getAvmTestContractBytecode('add_args_return'); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + jest + .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') + .mockReturnValueOnce(Promise.resolve(addBytecode)); - const results = await new AvmSimulator(context).executeBytecode(callBytecode); + const results = await new AvmSimulator(context).executeBytecode(callBytecode); - expect(results.reverted).toBe(false); - expect(results.output).toEqual([/*result=*/ new Fr(3)]); - }); + expect(results.reverted).toBe(false); + expect(results.output).toEqual([/*result=*/ new Fr(3), /*success=*/ new Fr(1)]); + }); - it(`Should execute contract function that makes a nested static call which modifies storage (old interface)`, async () => { - const callBytecode = getAvmTestContractBytecode('nested_static_call_to_set_storage'); - const nestedBytecode = getAvmTestContractBytecode('set_storage_single'); - const context = initContext(); - jest - .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') - .mockReturnValueOnce(Promise.resolve(nestedBytecode)); + it(`Nested static call which modifies storage`, async () => { + const callBytecode = getAvmTestContractBytecode('raw_nested_static_call_to_set_storage'); + const nestedBytecode = getAvmTestContractBytecode('set_storage_single'); + const context = initContext(); + jest + .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') + .mockReturnValueOnce(Promise.resolve(nestedBytecode)); - const results = await new AvmSimulator(context).executeBytecode(callBytecode); + const results = await new AvmSimulator(context).executeBytecode(callBytecode); - expect(results.reverted).toBe(true); // The outer call should revert. - }); + expect(results.reverted).toBe(false); // The outer call should not revert. + expect(results.output).toEqual([new Fr(0)]); // The inner call should have reverted. }); - describe('Storage accesses', () => { - it('Should set value in storage (single)', async () => { - const slot = 1n; - const address = AztecAddress.fromField(new Fr(420)); - const value = new Fr(88); - const calldata = [value]; + it(`Nested static call (old interface)`, async () => { + const calldata: Fr[] = [new Fr(1), new Fr(2)]; + const callBytecode = getAvmTestContractBytecode('nested_static_call_to_add'); + const addBytecode = getAvmTestContractBytecode('add_args_return'); + const context = initContext({ env: initExecutionEnvironment({ calldata }) }); + jest + .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') + .mockReturnValueOnce(Promise.resolve(addBytecode)); - const context = initContext({ - env: initExecutionEnvironment({ calldata, address, storageAddress: address }), - }); - const bytecode = getAvmTestContractBytecode('set_storage_single'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + const results = await new AvmSimulator(context).executeBytecode(callBytecode); - expect(results.reverted).toBe(false); + expect(results.reverted).toBe(false); + expect(results.output).toEqual([/*result=*/ new Fr(3)]); + }); - // World state - const worldState = context.persistableState.flush(); - const storageSlot = worldState.currentStorageValue.get(address.toBigInt())!; - const adminSlotValue = storageSlot.get(slot); - expect(adminSlotValue).toEqual(value); + it(`Nested static call which modifies storage (old interface)`, async () => { + const callBytecode = getAvmTestContractBytecode('nested_static_call_to_set_storage'); + const nestedBytecode = getAvmTestContractBytecode('set_storage_single'); + const context = initContext(); + jest + .spyOn(context.persistableState.hostStorage.contractsDb, 'getBytecode') + .mockReturnValueOnce(Promise.resolve(nestedBytecode)); - // Tracing - const storageTrace = worldState.storageWrites.get(address.toBigInt())!; - const slotTrace = storageTrace.get(slot); - expect(slotTrace).toEqual([value]); - }); + const results = await new AvmSimulator(context).executeBytecode(callBytecode); + + expect(results.reverted).toBe(true); // The outer call should revert. + }); + }); + + describe('Storage accesses', () => { + it('Should set value in storage (single)', async () => { + const slot = 1n; + const address = AztecAddress.fromField(new Fr(420)); + const value = new Fr(88); + const calldata = [value]; - it('Should read value in storage (single)', async () => { - const slot = 1n; - const value = new Fr(12345); - const address = AztecAddress.fromField(new Fr(420)); - const storage = new Map([[slot, value]]); - - const context = initContext({ - env: initExecutionEnvironment({ storageAddress: address }), - }); - jest - .spyOn(context.persistableState.hostStorage.publicStateDb, 'storageRead') - .mockImplementation((_address, slot) => Promise.resolve(storage.get(slot.toBigInt())!)); - const bytecode = getAvmTestContractBytecode('read_storage_single'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - // Get contract function artifact - expect(results.reverted).toBe(false); - expect(results.output).toEqual([value]); - - // Tracing - const worldState = context.persistableState.flush(); - const storageTrace = worldState.storageReads.get(address.toBigInt())!; - const slotTrace = storageTrace.get(slot); - expect(slotTrace).toEqual([value]); + const context = initContext({ + env: initExecutionEnvironment({ calldata, address, storageAddress: address }), }); + const bytecode = getAvmTestContractBytecode('set_storage_single'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + expect(results.reverted).toBe(false); + + // World state + const worldState = context.persistableState.flush(); + const storageSlot = worldState.currentStorageValue.get(address.toBigInt())!; + const adminSlotValue = storageSlot.get(slot); + expect(adminSlotValue).toEqual(value); + + // Tracing + const storageTrace = worldState.storageWrites.get(address.toBigInt())!; + const slotTrace = storageTrace.get(slot); + expect(slotTrace).toEqual([value]); + }); + + it('Should read value in storage (single)', async () => { + const slot = 1n; + const value = new Fr(12345); + const address = AztecAddress.fromField(new Fr(420)); + const storage = new Map([[slot, value]]); - it('Should set and read a value from storage (single)', async () => { - const slot = 1n; - const value = new Fr(12345); - const address = AztecAddress.fromField(new Fr(420)); - const calldata = [value]; - - const context = initContext({ - env: initExecutionEnvironment({ calldata, address, storageAddress: address }), - }); - const bytecode = getAvmTestContractBytecode('set_read_storage_single'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - expect(results.output).toEqual([value]); - - // Test read trace - const worldState = context.persistableState.flush(); - const storageReadTrace = worldState.storageReads.get(address.toBigInt())!; - const slotReadTrace = storageReadTrace.get(slot); - expect(slotReadTrace).toEqual([value]); - - // Test write trace - const storageWriteTrace = worldState.storageWrites.get(address.toBigInt())!; - const slotWriteTrace = storageWriteTrace.get(slot); - expect(slotWriteTrace).toEqual([value]); + const context = initContext({ + env: initExecutionEnvironment({ storageAddress: address }), }); + jest + .spyOn(context.persistableState.hostStorage.publicStateDb, 'storageRead') + .mockImplementation((_address, slot) => Promise.resolve(storage.get(slot.toBigInt())!)); + const bytecode = getAvmTestContractBytecode('read_storage_single'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + // Get contract function artifact + expect(results.reverted).toBe(false); + expect(results.output).toEqual([value]); + + // Tracing + const worldState = context.persistableState.flush(); + const storageTrace = worldState.storageReads.get(address.toBigInt())!; + const slotTrace = storageTrace.get(slot); + expect(slotTrace).toEqual([value]); + }); + + it('Should set and read a value from storage (single)', async () => { + const slot = 1n; + const value = new Fr(12345); + const address = AztecAddress.fromField(new Fr(420)); + const calldata = [value]; - it('Should set a value in storage (list)', async () => { - const slot = 2n; - const sender = AztecAddress.fromField(new Fr(1)); - const address = AztecAddress.fromField(new Fr(420)); - const calldata = [new Fr(1), new Fr(2)]; - - const context = initContext({ - env: initExecutionEnvironment({ sender, address, calldata, storageAddress: address }), - }); - const bytecode = getAvmTestContractBytecode('set_storage_list'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - - const worldState = context.persistableState.flush(); - const storageSlot = worldState.currentStorageValue.get(address.toBigInt())!; - expect(storageSlot.get(slot)).toEqual(calldata[0]); - expect(storageSlot.get(slot + 1n)).toEqual(calldata[1]); - - // Tracing - const storageTrace = worldState.storageWrites.get(address.toBigInt())!; - expect(storageTrace.get(slot)).toEqual([calldata[0]]); - expect(storageTrace.get(slot + 1n)).toEqual([calldata[1]]); + const context = initContext({ + env: initExecutionEnvironment({ calldata, address, storageAddress: address }), }); + const bytecode = getAvmTestContractBytecode('set_read_storage_single'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + expect(results.reverted).toBe(false); + expect(results.output).toEqual([value]); + + // Test read trace + const worldState = context.persistableState.flush(); + const storageReadTrace = worldState.storageReads.get(address.toBigInt())!; + const slotReadTrace = storageReadTrace.get(slot); + expect(slotReadTrace).toEqual([value]); + + // Test write trace + const storageWriteTrace = worldState.storageWrites.get(address.toBigInt())!; + const slotWriteTrace = storageWriteTrace.get(slot); + expect(slotWriteTrace).toEqual([value]); + }); + + it('Should set a value in storage (list)', async () => { + const slot = 2n; + const sender = AztecAddress.fromField(new Fr(1)); + const address = AztecAddress.fromField(new Fr(420)); + const calldata = [new Fr(1), new Fr(2)]; - it('Should read a value in storage (list)', async () => { - const slot = 2n; - const address = AztecAddress.fromField(new Fr(420)); - const values = [new Fr(1), new Fr(2)]; - const storage = new Map([ - [slot, values[0]], - [slot + 1n, values[1]], - ]); - - const context = initContext({ - env: initExecutionEnvironment({ address, storageAddress: address }), - }); - jest - .spyOn(context.persistableState.hostStorage.publicStateDb, 'storageRead') - .mockImplementation((_address, slot) => Promise.resolve(storage.get(slot.toBigInt())!)); - const bytecode = getAvmTestContractBytecode('read_storage_list'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - expect(results.output).toEqual(values); - - // Tracing - const worldState = context.persistableState.flush(); - const storageTrace = worldState.storageReads.get(address.toBigInt())!; - expect(storageTrace.get(slot)).toEqual([values[0]]); - expect(storageTrace.get(slot + 1n)).toEqual([values[1]]); + const context = initContext({ + env: initExecutionEnvironment({ sender, address, calldata, storageAddress: address }), }); + const bytecode = getAvmTestContractBytecode('set_storage_list'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - it('Should set a value in storage (map)', async () => { - const address = AztecAddress.fromField(new Fr(420)); - const value = new Fr(12345); - const calldata = [address.toField(), value]; + expect(results.reverted).toBe(false); + + const worldState = context.persistableState.flush(); + const storageSlot = worldState.currentStorageValue.get(address.toBigInt())!; + expect(storageSlot.get(slot)).toEqual(calldata[0]); + expect(storageSlot.get(slot + 1n)).toEqual(calldata[1]); + + // Tracing + const storageTrace = worldState.storageWrites.get(address.toBigInt())!; + expect(storageTrace.get(slot)).toEqual([calldata[0]]); + expect(storageTrace.get(slot + 1n)).toEqual([calldata[1]]); + }); + + it('Should read a value in storage (list)', async () => { + const slot = 2n; + const address = AztecAddress.fromField(new Fr(420)); + const values = [new Fr(1), new Fr(2)]; + const storage = new Map([ + [slot, values[0]], + [slot + 1n, values[1]], + ]); + + const context = initContext({ + env: initExecutionEnvironment({ address, storageAddress: address }), + }); + jest + .spyOn(context.persistableState.hostStorage.publicStateDb, 'storageRead') + .mockImplementation((_address, slot) => Promise.resolve(storage.get(slot.toBigInt())!)); + const bytecode = getAvmTestContractBytecode('read_storage_list'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); - const context = initContext({ - env: initExecutionEnvironment({ address, calldata, storageAddress: address }), - }); - const bytecode = getAvmTestContractBytecode('set_storage_map'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); + expect(results.reverted).toBe(false); + expect(results.output).toEqual(values); - expect(results.reverted).toBe(false); - // returns the storage slot for modified key - const slotNumber = results.output[0].toBigInt(); + // Tracing + const worldState = context.persistableState.flush(); + const storageTrace = worldState.storageReads.get(address.toBigInt())!; + expect(storageTrace.get(slot)).toEqual([values[0]]); + expect(storageTrace.get(slot + 1n)).toEqual([values[1]]); + }); - const worldState = context.persistableState.flush(); - const storageSlot = worldState.currentStorageValue.get(address.toBigInt())!; - expect(storageSlot.get(slotNumber)).toEqual(value); + it('Should set a value in storage (map)', async () => { + const address = AztecAddress.fromField(new Fr(420)); + const value = new Fr(12345); + const calldata = [address.toField(), value]; - // Tracing - const storageTrace = worldState.storageWrites.get(address.toBigInt())!; - expect(storageTrace.get(slotNumber)).toEqual([value]); + const context = initContext({ + env: initExecutionEnvironment({ address, calldata, storageAddress: address }), }); + const bytecode = getAvmTestContractBytecode('set_storage_map'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + expect(results.reverted).toBe(false); + // returns the storage slot for modified key + const slotNumber = results.output[0].toBigInt(); + + const worldState = context.persistableState.flush(); + const storageSlot = worldState.currentStorageValue.get(address.toBigInt())!; + expect(storageSlot.get(slotNumber)).toEqual(value); - it('Should read-add-set a value in storage (map)', async () => { - const address = AztecAddress.fromField(new Fr(420)); - const value = new Fr(12345); - const calldata = [address.toField(), value]; - - const context = initContext({ - env: initExecutionEnvironment({ address, calldata, storageAddress: address }), - }); - const bytecode = getAvmTestContractBytecode('add_storage_map'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - expect(results.reverted).toBe(false); - // returns the storage slot for modified key - const slotNumber = results.output[0].toBigInt(); - - const worldState = context.persistableState.flush(); - const storageSlot = worldState.currentStorageValue.get(address.toBigInt())!; - expect(storageSlot.get(slotNumber)).toEqual(value); - - // Tracing - const storageReadTrace = worldState.storageReads.get(address.toBigInt())!; - expect(storageReadTrace.get(slotNumber)).toEqual([new Fr(0)]); - const storageWriteTrace = worldState.storageWrites.get(address.toBigInt())!; - expect(storageWriteTrace.get(slotNumber)).toEqual([value]); + // Tracing + const storageTrace = worldState.storageWrites.get(address.toBigInt())!; + expect(storageTrace.get(slotNumber)).toEqual([value]); + }); + + it('Should read-add-set a value in storage (map)', async () => { + const address = AztecAddress.fromField(new Fr(420)); + const value = new Fr(12345); + const calldata = [address.toField(), value]; + + const context = initContext({ + env: initExecutionEnvironment({ address, calldata, storageAddress: address }), }); + const bytecode = getAvmTestContractBytecode('add_storage_map'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + expect(results.reverted).toBe(false); + // returns the storage slot for modified key + const slotNumber = results.output[0].toBigInt(); + + const worldState = context.persistableState.flush(); + const storageSlot = worldState.currentStorageValue.get(address.toBigInt())!; + expect(storageSlot.get(slotNumber)).toEqual(value); + + // Tracing + const storageReadTrace = worldState.storageReads.get(address.toBigInt())!; + expect(storageReadTrace.get(slotNumber)).toEqual([new Fr(0)]); + const storageWriteTrace = worldState.storageWrites.get(address.toBigInt())!; + expect(storageWriteTrace.get(slotNumber)).toEqual([value]); + }); + + it('Should read value in storage (map)', async () => { + const value = new Fr(12345); + const address = AztecAddress.fromField(new Fr(420)); + const calldata = [address.toField()]; - it('Should read value in storage (map)', async () => { - const value = new Fr(12345); - const address = AztecAddress.fromField(new Fr(420)); - const calldata = [address.toField()]; - - const context = initContext({ - env: initExecutionEnvironment({ calldata, address, storageAddress: address }), - }); - jest - .spyOn(context.persistableState.hostStorage.publicStateDb, 'storageRead') - .mockReturnValue(Promise.resolve(value)); - const bytecode = getAvmTestContractBytecode('read_storage_map'); - const results = await new AvmSimulator(context).executeBytecode(bytecode); - - // Get contract function artifact - expect(results.reverted).toBe(false); - expect(results.output).toEqual([value]); - - // Tracing - const worldState = context.persistableState.flush(); - const storageTrace = worldState.storageReads.get(address.toBigInt())!; - expect([...storageTrace.values()]).toEqual([[value]]); + const context = initContext({ + env: initExecutionEnvironment({ calldata, address, storageAddress: address }), }); + jest + .spyOn(context.persistableState.hostStorage.publicStateDb, 'storageRead') + .mockReturnValue(Promise.resolve(value)); + const bytecode = getAvmTestContractBytecode('read_storage_map'); + const results = await new AvmSimulator(context).executeBytecode(bytecode); + + // Get contract function artifact + expect(results.reverted).toBe(false); + expect(results.output).toEqual([value]); + + // Tracing + const worldState = context.persistableState.flush(); + const storageTrace = worldState.storageReads.get(address.toBigInt())!; + expect([...storageTrace.values()]).toEqual([[value]]); }); }); }); diff --git a/yarn-project/types/src/abi/contract_artifact.ts b/yarn-project/types/src/abi/contract_artifact.ts index 04f820181948..fffccb5e33a9 100644 --- a/yarn-project/types/src/abi/contract_artifact.ts +++ b/yarn-project/types/src/abi/contract_artifact.ts @@ -115,6 +115,8 @@ function generateFunctionArtifact(fn: NoirCompiledContractFunction): FunctionArt let parameters = fn.abi.parameters.map(generateFunctionParameter); if (hasKernelFunctionInputs(parameters)) { parameters = parameters.slice(1); + } else if (hasAvmKernelFunctionInputs(parameters)) { + parameters = parameters.slice(0, parameters.length - 1); } // If the function is secret, the return is the public inputs, which should be omitted @@ -165,6 +167,11 @@ function hasKernelFunctionInputs(params: ABIParameter[]): boolean { return firstParam?.type.kind === 'struct' && firstParam.type.path.includes('ContextInputs'); } +function hasAvmKernelFunctionInputs(params: ABIParameter[]): boolean { + const lastParam = params[params.length - 1]; + return lastParam?.type.kind === 'struct' && lastParam.type.path.includes('ContextInputs'); +} + /** * Given a Nargo output generates an Aztec-compatible contract artifact. * @param compiled - Noir build output.