From 5c8154ddc99c2e76659678f78fdca6788a177349 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 30 Sep 2025 15:14:34 -0400 Subject: [PATCH] chore: finish the node components migration --- Cargo.toml | 9 +- crates/genesis/Cargo.toml | 17 + crates/genesis/README.md | 22 + crates/genesis/src/lib.rs | 152 ++++ crates/genesis/src/local.genesis.json | 186 +++++ crates/genesis/src/pecorino.genesis.json | 143 ++++ crates/node-config/Cargo.toml | 33 + crates/node-config/README.md | 8 + crates/node-config/src/core.rs | 261 ++++++ crates/node-config/src/lib.rs | 21 + crates/node-config/src/rpc.rs | 29 + crates/node-config/src/test_utils.rs | 30 + crates/node-tests/Cargo.toml | 40 + crates/node-tests/README.md | 15 + crates/node-tests/src/aliases.rs | 69 ++ crates/node-tests/src/constants.rs | 8 + crates/node-tests/src/context.rs | 642 +++++++++++++++ crates/node-tests/src/convert.rs | 132 +++ crates/node-tests/src/lib.rs | 38 + crates/node-tests/src/rpc.rs | 19 + crates/node-tests/src/utils.rs | 137 ++++ crates/node-tests/tests/artifacts/Counter.sol | 15 + .../node-tests/tests/artifacts/MyContract.bin | 4 + crates/node-tests/tests/artifacts/blob.json | 41 + .../node-tests/tests/artifacts/cl_blob.json | 1 + .../tests/artifacts/cl_blob_tx.json | 26 + .../tests/artifacts/pylon_blob.json | 1 + crates/node-tests/tests/basic.rs | 214 +++++ crates/node-tests/tests/db.rs | 26 + crates/node-tests/tests/exit.rs | 147 ++++ crates/node-tests/tests/host_events.rs | 536 ++++++++++++ crates/node-tests/tests/multiple-blocks.rs | 768 ++++++++++++++++++ crates/node-tests/tests/orders.rs | 460 +++++++++++ crates/node-tests/tests/rpc.rs | 559 +++++++++++++ crates/node-tests/tests/rpc_debug.rs | 78 ++ crates/node-tests/tests/submit-tx.rs | 82 ++ crates/node-types/Cargo.toml | 5 +- crates/node-types/src/block.rs | 26 + crates/node-types/src/lib.rs | 3 + crates/node/Cargo.toml | 31 + crates/node/README.md | 8 + crates/node/src/lib.rs | 17 + crates/node/src/node.rs | 663 +++++++++++++++ crates/node/src/rpc.rs | 39 + 44 files changed, 5759 insertions(+), 2 deletions(-) create mode 100644 crates/genesis/Cargo.toml create mode 100644 crates/genesis/README.md create mode 100644 crates/genesis/src/lib.rs create mode 100644 crates/genesis/src/local.genesis.json create mode 100644 crates/genesis/src/pecorino.genesis.json create mode 100644 crates/node-config/Cargo.toml create mode 100644 crates/node-config/README.md create mode 100644 crates/node-config/src/core.rs create mode 100644 crates/node-config/src/lib.rs create mode 100644 crates/node-config/src/rpc.rs create mode 100644 crates/node-config/src/test_utils.rs create mode 100644 crates/node-tests/Cargo.toml create mode 100644 crates/node-tests/README.md create mode 100644 crates/node-tests/src/aliases.rs create mode 100644 crates/node-tests/src/constants.rs create mode 100644 crates/node-tests/src/context.rs create mode 100644 crates/node-tests/src/convert.rs create mode 100644 crates/node-tests/src/lib.rs create mode 100644 crates/node-tests/src/rpc.rs create mode 100644 crates/node-tests/src/utils.rs create mode 100644 crates/node-tests/tests/artifacts/Counter.sol create mode 100644 crates/node-tests/tests/artifacts/MyContract.bin create mode 100644 crates/node-tests/tests/artifacts/blob.json create mode 100644 crates/node-tests/tests/artifacts/cl_blob.json create mode 100644 crates/node-tests/tests/artifacts/cl_blob_tx.json create mode 100644 crates/node-tests/tests/artifacts/pylon_blob.json create mode 100644 crates/node-tests/tests/basic.rs create mode 100644 crates/node-tests/tests/db.rs create mode 100644 crates/node-tests/tests/exit.rs create mode 100644 crates/node-tests/tests/host_events.rs create mode 100644 crates/node-tests/tests/multiple-blocks.rs create mode 100644 crates/node-tests/tests/orders.rs create mode 100644 crates/node-tests/tests/rpc.rs create mode 100644 crates/node-tests/tests/rpc_debug.rs create mode 100644 crates/node-tests/tests/submit-tx.rs create mode 100644 crates/node-types/src/block.rs create mode 100644 crates/node/Cargo.toml create mode 100644 crates/node/README.md create mode 100644 crates/node/src/lib.rs create mode 100644 crates/node/src/node.rs create mode 100644 crates/node/src/rpc.rs diff --git a/Cargo.toml b/Cargo.toml index 8755144..6a04ec7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.11.0" +version = "0.11.1" edition = "2024" rust-version = "1.88" authors = ["init4"] @@ -37,15 +37,21 @@ incremental = false signet-blobber = { version = "0.11", path = "crates/blobber" } signet-block-processor = { version = "0.11", path = "crates/block-processor" } signet-db = { version = "0.11", path = "crates/db" } +signet-genesis = { version = "0.11", path = "crates/genesis" } +signet-node = { version = "0.11", path = "crates/node" } +signet-node-config = { version = "0.11", path = "crates/node-config" } +signet-node-tests = { version = "0.11", path = "crates/node-tests" } signet-node-types = { version = "0.11", path = "crates/node-types" } signet-rpc = { version = "0.11", path = "crates/rpc" } + init4-bin-base = { version = "0.13.1", features = ["alloy"] } signet-bundle = "0.11.1" signet-constants = "0.11.1" signet-evm = "0.11.1" signet-extract = "0.11.1" +signet-test-utils = "0.11.1" signet-tx-cache = "0.11.1" signet-types = "0.11.1" signet-zenith = "0.11.1" @@ -124,6 +130,7 @@ tempfile = "3.17.0" # signet-constants = { path = "../sdk/crates/constants"} # signet-evm = { path = "../sdk/crates/evm"} # signet-extract = { path = "../sdk/crates/extract"} +# signet-test-utils = { path = "../sdk/crates/test-utils"} # signet-tx-cache = { path = "../sdk/crates/tx-cache"} # signet-types = { path = "../sdk/crates/types"} # signet-zenith = { path = "../sdk/crates/zenith"} diff --git a/crates/genesis/Cargo.toml b/crates/genesis/Cargo.toml new file mode 100644 index 0000000..c0d5c3c --- /dev/null +++ b/crates/genesis/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "signet-genesis" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +alloy = { workspace = true, features = ["genesis"] } +init4-bin-base.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +signet-constants.workspace = true +thiserror.workspace = true diff --git a/crates/genesis/README.md b/crates/genesis/README.md new file mode 100644 index 0000000..38a6fc4 --- /dev/null +++ b/crates/genesis/README.md @@ -0,0 +1,22 @@ +# Signet Genesis + +Genesis configuration and utilities for the Signet Node. + +This library contains the following: + +- `GenesisSpec` - An enum representing different genesis specifications, either + Pecorino, Test, or a custom genesis file path, which can be used to load + genesis data. +- `PECORINO_GENESIS` - The Pecorino genesis data. +- `TEST_GENESIS` - A local test genesis for testing purposes. +- `GenesisError` - Errors that can occur when loading or parsing genesis data. + +## Example + +``` +# use signet_genesis::GenesisSpec; +# fn _main() -> Result<(), Box> { +let genesis = GenesisSpec::Pecorino.load_genesis()?; +# Ok(()) +# } +``` diff --git a/crates/genesis/src/lib.rs b/crates/genesis/src/lib.rs new file mode 100644 index 0000000..76c61af --- /dev/null +++ b/crates/genesis/src/lib.rs @@ -0,0 +1,152 @@ +#![doc = include_str!("../README.md")] +#![warn( + missing_copy_implementations, + missing_debug_implementations, + missing_docs, + unreachable_pub, + clippy::missing_const_for_fn, + rustdoc::all +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![deny(unused_must_use, rust_2018_idioms)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +use alloy::genesis::Genesis; +use init4_bin_base::utils::from_env::{ + EnvItemInfo, FromEnv, FromEnvErr, FromEnvVar, parse_env_if_present, +}; +use signet_constants::KnownChains; +use std::{borrow::Cow, path::PathBuf, str::FromStr, sync::LazyLock}; + +/// Pecorino genesis file. +pub const PECORINO_GENESIS_JSON: &str = include_str!("./pecorino.genesis.json"); + +/// Local genesis file for testing purposes. +pub const TEST_GENESIS_JSON: &str = include_str!("./local.genesis.json"); + +/// Genesis for the Pecorino testnet. +pub static PECORINO_GENESIS: LazyLock = LazyLock::new(|| { + serde_json::from_str(PECORINO_GENESIS_JSON).expect("Failed to parse pecorino genesis") +}); + +/// Test genesis for local testing. +pub static TEST_GENESIS: LazyLock = LazyLock::new(|| { + serde_json::from_str(TEST_GENESIS_JSON).expect("Failed to parse test genesis") +}); + +/// Environment variable for specifying the genesis JSON file path. +const GENSIS_JSON_PATH: &str = "GENSIS_JSON_PATH"; + +/// Result type for genesis operations. +pub type Result = std::result::Result; + +/// Errors that can occur when loading the genesis file. +#[derive(Debug, thiserror::Error)] +pub enum GenesisError { + /// IO error when reading the genesis file. + #[error(transparent)] + Io(#[from] std::io::Error), + /// JSON parsing error when parsing the genesis file. + #[error(transparent)] + Json(#[from] serde_json::Error), +} + +/// Different genesis configurations available. +#[derive(Debug, Clone, serde::Deserialize)] +#[serde(untagged)] +pub enum GenesisSpec { + /// Pecorino testnet. + Pecorino, + /// Local testnet. + Test, + /// Custom path to a genesis file. + Path(PathBuf), +} + +impl GenesisSpec { + /// Load the genesis JSON from the specified source. + /// + /// This will alwys return a valid string for [`KnownChains`]. + pub fn load_raw_genesis(&self) -> Result> { + match self { + GenesisSpec::Pecorino => Ok(Cow::Borrowed(PECORINO_GENESIS_JSON)), + GenesisSpec::Test => Ok(Cow::Borrowed(TEST_GENESIS_JSON)), + GenesisSpec::Path(path) => { + std::fs::read_to_string(path).map(Cow::Owned).map_err(Into::into) + } + } + } + + /// Load the genesis from the specified source. + /// + /// This will always return a valid genesis for [`KnownChains`]. + pub fn load_genesis(&self) -> Result { + match self { + GenesisSpec::Pecorino => Ok(PECORINO_GENESIS.clone()), + GenesisSpec::Test => Ok(TEST_GENESIS.clone()), + GenesisSpec::Path(_) => self + .load_raw_genesis() + .and_then(|raw| serde_json::from_str(&raw).map_err(Into::into)), + } + } +} + +impl FromStr for GenesisSpec { + type Err = ::Err; + + fn from_str(s: &str) -> Result { + if let Ok(known) = KnownChains::from_str(s) { + return Ok(known.into()); + } + + Ok(GenesisSpec::Path(s.parse()?)) + } +} + +impl FromEnvVar for GenesisSpec { + type Error = ::Err; + + fn from_env_var(env_var: &str) -> Result> { + parse_env_if_present(env_var) + } +} + +impl FromEnv for GenesisSpec { + type Error = ::Err; + + fn inventory() -> Vec<&'static init4_bin_base::utils::from_env::EnvItemInfo> { + vec![ + &EnvItemInfo { + var: "CHAIN_NAME", + description: "The name of the chain. If set, the other environment variables are ignored.", + optional: true, + }, + &EnvItemInfo { + var: GENSIS_JSON_PATH, + description: "A filepath to the genesis JSON file. Required if CHAIN_NAME is not set.", + optional: true, + }, + ] + } + + fn from_env() -> Result> { + parse_env_if_present::("CHAIN_NAME") + .map(Into::into) + .or_else(|_| parse_env_if_present::(GENSIS_JSON_PATH).map(Into::into)) + } +} + +impl From for GenesisSpec { + fn from(known: KnownChains) -> Self { + match known { + KnownChains::Pecorino => GenesisSpec::Pecorino, + KnownChains::Test => GenesisSpec::Test, + } + } +} + +impl From for GenesisSpec { + fn from(path: PathBuf) -> Self { + GenesisSpec::Path(path) + } +} diff --git a/crates/genesis/src/local.genesis.json b/crates/genesis/src/local.genesis.json new file mode 100644 index 0000000..0ce95ab --- /dev/null +++ b/crates/genesis/src/local.genesis.json @@ -0,0 +1,186 @@ +{ + "config": { + "chainId": 15, + "homesteadBlock": "0x0", + "daoForkBlock": "0x0", + "daoForkSupport": false, + "eip150Block": "0x0", + "eip150Hash": null, + "eip155Block": "0x0", + "eip158Block": "0x0", + "byzantiumBlock": "0x0", + "constantinopleBlock": "0x0", + "petersburgBlock": "0x0", + "istanbulBlock": "0x0", + "muirGlacierBlock": "0x0", + "berlinBlock": "0x0", + "londonBlock": "0x0", + "arrowGlacierBlock": "0x0", + "grayGlacierBlock": "0x0", + "mergeNetsplitBlock": "0x0", + "shanghaiTime": "0x0", + "cancunTime": "0x0", + "pragueTime": "0x0", + "terminalTotalDifficulty": null, + "terminalTotalDifficultyPassed": false, + "ethash": null, + "clique": null, + "parlia": null, + "signetConstants": { + "host": { + "chainId": 1, + "deployHeight": 100, + "zenith": "0x1111111111111111111111111111111111111111", + "orders": "0x2222222222222222222222222222222222222222", + "passage": "0x3333333333333333333333333333333333333333", + "transactor": "0x4444444444444444444444444444444444444444", + "tokens": { + "usds": [ + { + "ticker": "USDC", + "decimals": 6, + "address": "0x5555555555555555555555555555555555555555" + }, + { + "ticker": "USDT", + "decimals": 12, + "address": "0x6666666666666666666666666666666666666666" + } + ], + "wbtc": "0x7777777777777777777777777777777777777777", + "weth": "0x8888888888888888888888888888888888888888" + } + }, + "rollup": { + "chainId": 15, + "orders": "0xC2D3Dac6B115564B10329697195656459BFb2c74", + "passage": "0xB043BdD3d91376A76078c361bb82496Fdb809aE2", + "baseFeeRecipient": "0xabababababababababababababababababababab", + "tokens": { + "wbtc": "0x9999999999999999999999999999999999999999", + "weth": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + } + } + }, + "extraFields": {}, + "depositContractAddress": null + }, + "nonce": "0x0", + "timestamp": "0x0", + "extraData": "0x", + "gasLimit": "0x1c9c380", + "difficulty": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02": { + "balance": "0x0", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500" + }, + "0x000000000022D473030F116dDEE9F6B43aC78BA3": { + "balance": "0x0", + "code": "0x6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000426903611b69577fbad4b5495ed53a4eb2d34dff3b0f78ec4fb5e14cc66295254a6d3d9afe35781590565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a" + }, + "0xB043BdD3d91376A76078c361bb82496Fdb809aE2": { + "balance": "0x0", + "code": "0x60806040526004361061004d575f3560e01c80633930e39114610066578063685114a21461009b578063b269a425146100ba578063b42652e9146100d9578063eba1f981146100ec5761005d565b3661005d5761005b3361010b565b005b61005b3361010b565b348015610071575f80fd5b5061008561008036600461076c565b61015b565b60405161009291906107c4565b60405180910390f35b3480156100a6575f80fd5b5061005b6100b53660046107f0565b61021a565b3480156100c5575f80fd5b5061005b6100d436600461082a565b61024f565b61005b6100e736600461087b565b61010b565b3480156100f7575f80fd5b5061008561010636600461087b565b610290565b345f036101155750565b806001600160a01b03167f22d324652c93739755cf4581508b60875ebdd78c20c0cff5cf8e23452b2996313460405161015091815260200190565b60405180910390a250565b604080518082019091525f8152606060208201527fc5d03356b54a64d088070694ab907941e70a5ea4ae772ff6df7f162d054037b66040518060400160405280858152602001846001600160a01b03168152506040516020016101de929190918252805160208084019190915201516001600160a01b0316604082015260600190565b60408051601f1981840301815291815281516020928301208352805160a08101909152607e80825290916109db90830139602082015292915050565b610222610338565b6102376001600160a01b0383163330846103a7565b610242838383610407565b61024a6104ba565b505050565b610257610338565b61026961026383610290565b826104e4565b6102848261027a602084018461087b565b6020840135610407565b61028c6104ba565b5050565b604080518082019091525f81526060602082015260408051602080820183526001600160a01b038516825291516102fd927fa91a2bac0243280e19cfd0a3ae9d7639a15fa41d49eab3e0bf320c8485cc66a9929101918252516001600160a01b0316602082015260400190565b60408051601f1981840301815291815281516020928301208352805160a0810190915260648082529091610a59908301396020820152919050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005c1561037857604051633ee5aeb560e01b815260040160405180910390fd5b6103a560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b906105ab565b565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526104019085906105b2565b50505050565b805f0361041357505050565b604051630852cd8d60e31b8152600481018290526001600160a01b038316906342966c68906024015f604051808303815f87803b158015610452575f80fd5b505af1158015610464573d5f803e3d5ffd5b50505050816001600160a01b0316836001600160a01b03167f4203bbd8ffd310b1341275d3ad6597e60a1ab2843f84e28c79e88d6f5da1c94d836040516104ad91815260200190565b60405180910390a3505050565b6103a55f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0061039f565b6001600160a01b037f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba31663137c29fe82610534602082013560408051808201909152308152602081019190915290565b61054460a086016080870161087b565b8651602088015161055860a0890189610894565b6040518863ffffffff1660e01b815260040161057a9796959493929190610906565b5f604051808303815f87803b158015610591575f80fd5b505af11580156105a3573d5f803e3d5ffd5b505050505050565b80825d5050565b5f6105c66001600160a01b03841683610618565b905080515f141580156105ea5750808060200190518101906105e891906109a5565b155b1561024a57604051635274afe760e01b81526001600160a01b03841660048201526024015b60405180910390fd5b606061062583835f61062c565b9392505050565b6060814710156106585760405163cf47918160e01b81524760048201526024810183905260440161060f565b5f80856001600160a01b0316848660405161067391906109c4565b5f6040518083038185875af1925050503d805f81146106ad576040519150601f19603f3d011682016040523d82523d5f602084013e6106b2565b606091505b50915091506106c28683836106cc565b9695505050505050565b6060826106e1576106dc82610728565b610625565b81511580156106f857506001600160a01b0384163b155b1561072157604051639996b31560e01b81526001600160a01b038516600482015260240161060f565b5080610625565b8051156107385780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b80356001600160a01b0381168114610767575f80fd5b919050565b5f806040838503121561077d575f80fd5b8235915061078d60208401610751565b90509250929050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60208152815160208201525f60208301516040808401526107e86060840182610796565b949350505050565b5f805f60608486031215610802575f80fd5b61080b84610751565b925061081960208501610751565b929592945050506040919091013590565b5f806040838503121561083b575f80fd5b61084483610751565b9150602083013567ffffffffffffffff81111561085f575f80fd5b830160c08186031215610870575f80fd5b809150509250929050565b5f6020828403121561088b575f80fd5b61062582610751565b5f808335601e198436030181126108a9575f80fd5b83018035915067ffffffffffffffff8211156108c3575f80fd5b6020019150368190038213156108d7575f80fd5b9250929050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b6001600160a01b0361091789610751565b168152602088810135818301526040808a0135908301526060808a01359083015287516001600160a01b0316608083015287015160a08201525f61096660c08301886001600160a01b03169052565b8560e0830152610140610100830152610983610140830186610796565b8281036101208401526109978185876108de565b9a9950505050505050505050565b5f602082840312156109b5575f80fd5b81518015158114610625575f80fd5b5f82518060208501845e5f92019182525091905056fe456e7465725769746e657373207769746e65737329456e7465725769746e6573732875696e7432353620726f6c6c7570436861696e49642c6164647265737320726f6c6c7570526563697069656e7429546f6b656e5065726d697373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f756e7429457869745769746e657373207769746e65737329457869745769746e657373286164647265737320686f7374526563697069656e7429546f6b656e5065726d697373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f756e7429a2646970667358221220a82b6f2ece68ba16cfccd79784985d20b0e5014e516fcd73930a3c56f491887b64736f6c634300081a0033" + }, + "0xC2D3Dac6B115564B10329697195656459BFb2c74": { + "balance": "0x0", + "code": "0x608060405260043610610054575f3560e01c80630828f139146100585780631bbf03a81461008d57806362c06767146100ae578063897bc0d6146100cd5780639181004e146100e0578063f9c50441146100ff575b5f80fd5b348015610063575f80fd5b50610077610072366004610fe9565b610112565b6040516100849190611050565b60405180910390f35b348015610098575f80fd5b506100ac6100a736600461108a565b61024e565b005b3480156100b9575f80fd5b506100ac6100c83660046110ed565b6102c8565b6100ac6100db366004610fe9565b610364565b3480156100eb575f80fd5b506100ac6100fa366004611127565b6103b7565b6100ac61010d366004611199565b610453565b604080518082019091525f81526060602082015281515f816001600160401b0381111561014157610141610e5c565b60405190808252806020026020018201604052801561016a578160200160208202803683370190505b5090505f5b828110156101fe577f988262d9186cf8a1cd1dd5e2cc7bfa353f55a542d86db1fcd06e076a6544250d8582815181106101aa576101aa61127d565b60200260200101516040516020016101c39291906112c8565b604051602081830303815290604052805190602001208282815181106101eb576101eb61127d565b602090810291909101015260010161016f565b508060405160200161021091906112dc565b60408051601f1981840301815291815281516020928301208552805160c081019091526084808252909161168f908301396020840152509092915050565b6102566104b8565b61028561026283610112565b61027f846102708580611311565b61027a908061132f565b610527565b83610709565b7f14b3027353aba71f468d178fdede9ac211a25ae484028823bce1e6700e58e624826040516102b491906113c0565b60405180910390a16102c46107bb565b5050565b6102d06104b8565b6001600160a01b0382166102f6576102f16001600160a01b038416826107e5565b61030a565b61030a6001600160a01b0383168483610884565b816001600160a01b0316836001600160a01b03167fed679328aebf74ede77ae09efcf36e90244f83643dadac1c2d9f0b21a46f6ab78360405161034f91815260200190565b60405180910390a361035f6107bb565b505050565b61036c6104b8565b610375816108e3565b7f14b3027353aba71f468d178fdede9ac211a25ae484028823bce1e6700e58e624816040516103a491906113c0565b60405180910390a16103b46107bb565b50565b6103bf6104b8565b6103e86103cb83610112565b61027f856103d98580611311565b6103e3908061132f565b610a28565b7f80c9b8738a5ff299b770efb55e4372a5fc655294aca7145b3c529c2d89732d626104138280611311565b604001356104336104248480611311565b61042e908061132f565b610af1565b84604051610443939291906113d2565b60405180910390a161035f6107bb565b61045b6104b8565b8242111561047c576040516362b439dd60e11b815260040160405180910390fd5b61048582610be8565b7f80c9b8738a5ff299b770efb55e4372a5fc655294aca7145b3c529c2d89732d62838383604051610443939291906113d2565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005c156104f857604051633ee5aeb560e01b815260040160405180910390fd5b61052560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b90610c78565b565b8251606090821461054e576040516001621398b960e31b0319815260040160405180910390fd5b816001600160401b0381111561056657610566610e5c565b6040519080825280602002602001820160405280156105aa57816020015b604080518082019091525f80825260208201528152602001906001900390816105845790505b5090505f5b82811015610701578481815181106105c9576105c961127d565b60200260200101515f01516001600160a01b03168484838181106105ef576105ef61127d565b6106059260206040909202019081019150611450565b6001600160a01b03161461062c57604051635f670cf360e11b815260040160405180910390fd5b84818151811061063e5761063e61127d565b60200260200101516020015184848381811061065c5761065c61127d565b905060400201602001351461068457604051635f670cf360e11b815260040160405180910390fd5b60405180604001604052808683815181106106a1576106a161127d565b6020026020010151604001516001600160a01b031681526020018683815181106106cd576106cd61127d565b6020026020010151602001518152508282815181106106ee576106ee61127d565b60209081029190910101526001016105af565b509392505050565b6001600160a01b037f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba31663fe8ec1a76107428380611311565b846107536040860160208701611450565b875160208901516107676040890189611469565b6040518863ffffffff1660e01b81526004016107899796959493929190611521565b5f604051808303815f87803b1580156107a0575f80fd5b505af11580156107b2573d5f803e3d5ffd5b50505050505050565b6105255f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0061051f565b804710156108145760405163cf47918160e01b8152476004820152602481018290526044015b60405180910390fd5b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f811461085d576040519150601f19603f3d011682016040523d82523d5f602084013e610862565b606091505b505090508061035f5760405163d6bda27560e01b815260040160405180910390fd5b6040516001600160a01b0383811660248301526044820183905261035f91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050610c7f565b345f5b825181101561035f575f6001600160a01b031683828151811061090b5761090b61127d565b60200260200101515f01516001600160a01b0316036109aa578281815181106109365761093661127d565b6020026020010151602001518261094d919061163a565b91506109a58382815181106109645761096461127d565b6020026020010151602001518483815181106109825761098261127d565b6020026020010151604001516001600160a01b03166107e590919063ffffffff16565b610a20565b610a20338483815181106109c0576109c061127d565b6020026020010151604001518584815181106109de576109de61127d565b6020026020010151602001518685815181106109fc576109fc61127d565b60200260200101515f01516001600160a01b0316610ce0909392919063ffffffff16565b6001016108e6565b6060816001600160401b03811115610a4257610a42610e5c565b604051908082528060200260200182016040528015610a8657816020015b604080518082019091525f8082526020820152815260200190600190039081610a605790505b5090505f5b82811015610701576040518060400160405280866001600160a01b03168152602001858584818110610abf57610abf61127d565b90506040020160200135815250828281518110610ade57610ade61127d565b6020908102919091010152600101610a8b565b6060816001600160401b03811115610b0b57610b0b610e5c565b604051908082528060200260200182016040528015610b4f57816020015b604080518082019091525f8082526020820152815260200190600190039081610b295790505b5090505f5b82811015610be1576040518060400160405280858584818110610b7957610b7961127d565b610b8f9260206040909202019081019150611450565b6001600160a01b03168152602001858584818110610baf57610baf61127d565b90506040020160200135815250828281518110610bce57610bce61127d565b6020908102919091010152600101610b54565b5092915050565b345f5b825181101561035f575f6001600160a01b0316838281518110610c1057610c1061127d565b60200260200101515f01516001600160a01b031603610c5957828181518110610c3b57610c3b61127d565b60200260200101516020015182610c52919061163a565b9150610c70565b610c7033308584815181106109de576109de61127d565b600101610beb565b80825d5050565b5f610c936001600160a01b03841683610d1f565b905080515f14158015610cb7575080806020019051810190610cb59190611659565b155b1561035f57604051635274afe760e01b81526001600160a01b038416600482015260240161080b565b6040516001600160a01b038481166024830152838116604483015260648201839052610d199186918216906323b872dd906084016108b1565b50505050565b6060610d2c83835f610d35565b90505b92915050565b606081471015610d615760405163cf47918160e01b81524760048201526024810183905260440161080b565b5f80856001600160a01b03168486604051610d7c9190611678565b5f6040518083038185875af1925050503d805f8114610db6576040519150601f19603f3d011682016040523d82523d5f602084013e610dbb565b606091505b5091509150610dcb868383610dd7565b925050505b9392505050565b606082610dec57610de782610e33565b610dd0565b8151158015610e0357506001600160a01b0384163b155b15610e2c57604051639996b31560e01b81526001600160a01b038516600482015260240161080b565b5080610dd0565b805115610e435780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b634e487b7160e01b5f52604160045260245ffd5b604051608081016001600160401b0381118282101715610e9257610e92610e5c565b60405290565b604080519081016001600160401b0381118282101715610e9257610e92610e5c565b604051601f8201601f191681016001600160401b0381118282101715610ee257610ee2610e5c565b604052919050565b5f6001600160401b03821115610f0257610f02610e5c565b5060051b60200190565b80356001600160a01b0381168114610f22575f80fd5b919050565b5f82601f830112610f36575f80fd5b8135610f49610f4482610eea565b610eba565b8082825260208201915060208360071b860101925085831115610f6a575f80fd5b602085015b83811015610fdf5760808188031215610f86575f80fd5b610f8e610e70565b610f9782610f0c565b815260208281013590820152610faf60408301610f0c565b6040820152606082013563ffffffff81168114610fca575f80fd5b60608201528352602090920191608001610f6f565b5095945050505050565b5f60208284031215610ff9575f80fd5b81356001600160401b0381111561100e575f80fd5b61101a84828501610f27565b949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60208152815160208201525f602083015160408084015261101a6060840182611022565b5f60608284031215611084575f80fd5b50919050565b5f806040838503121561109b575f80fd5b82356001600160401b038111156110b0575f80fd5b6110bc85828601610f27565b92505060208301356001600160401b038111156110d7575f80fd5b6110e385828601611074565b9150509250929050565b5f805f606084860312156110ff575f80fd5b61110884610f0c565b925061111660208501610f0c565b929592945050506040919091013590565b5f805f60608486031215611139575f80fd5b61114284610f0c565b925060208401356001600160401b0381111561115c575f80fd5b61116886828701610f27565b92505060408401356001600160401b03811115611183575f80fd5b61118f86828701611074565b9150509250925092565b5f805f606084860312156111ab575f80fd5b8335925060208401356001600160401b038111156111c7575f80fd5b8401601f810186136111d7575f80fd5b80356111e5610f4482610eea565b8082825260208201915060208360061b850101925088831115611206575f80fd5b6020840193505b82841015611254576040848a031215611224575f80fd5b61122c610e98565b61123585610f0c565b815260208581013581830152908352604090940193919091019061120d565b945050505060408401356001600160401b03811115611271575f80fd5b61118f86828701610f27565b634e487b7160e01b5f52603260045260245ffd5b80516001600160a01b039081168352602080830151908401526040808301519091169083015260609081015163ffffffff16910152565b82815260a08101610dd06020830184611291565b81515f90829060208501835b828110156113065781518452602093840193909101906001016112e8565b509195945050505050565b5f8235605e19833603018112611325575f80fd5b9190910192915050565b5f808335601e19843603018112611344575f80fd5b8301803591506001600160401b0382111561135d575f80fd5b6020019150600681901b3603821315611374575f80fd5b9250929050565b5f8151808452602084019350602083015f5b828110156113b6576113a0868351611291565b608095909501946020919091019060010161138d565b5093949350505050565b602081525f610d2c602083018461137b565b5f60608201858352606060208401528085518083526080850191506020870192505f5b818110156114315761141b83855180516001600160a01b03168252602090810151910152565b60209390930192604092909201916001016113f5565b50508381036040850152611445818661137b565b979650505050505050565b5f60208284031215611460575f80fd5b610d2c82610f0c565b5f808335601e1984360301811261147e575f80fd5b8301803591506001600160401b03821115611497575f80fd5b602001915036819003821315611374575f80fd5b5f8151808452602084019350602083015f5b828110156113b6576114e386835180516001600160a01b03168252602090810151910152565b60409590950194602091909101906001016114bd565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60c081525f61012082018935601e198b360301811261153e575f80fd5b8a016020810190356001600160401b03811115611559575f80fd5b8060061b360382131561156a575f80fd5b606060c086015291829052905f9061014085015b818310156115b7576001600160a01b0361159785610f0c565b16815260208481013590820152604093840193600193909301920161157e565b60208d81013560e088015260408e013561010088018190528783039188019190915293506115e5818d6114ab565b93505050506115ff60408401896001600160a01b03169052565b86606084015282810360808401526116178187611022565b905082810360a084015261162c8185876114f9565b9a9950505050505050505050565b81810381811115610d2f57634e487b7160e01b5f52601160045260245ffd5b5f60208284031215611669575f80fd5b81518015158114610dd0575f80fd5b5f82518060208501845e5f92019182525091905056fe4f75747075745b5d206f757470757473294f7574707574286164647265737320746f6b656e2c75696e7432353620616d6f756e742c6164647265737320726563697069656e742c75696e74333220636861696e496429546f6b656e5065726d697373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f756e7429a2646970667358221220322fe8b32453c17a0efd4f702e415163224990591aefcb85e698039547a4393764736f6c634300081a0033" + }, + "0x9999999999999999999999999999999999999999": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b50600436106100fb575f3560e01c806370a082311161009357806395d89b411161006357806395d89b4114610246578063a9059cbb1461024e578063dd62ed3e14610261578063f2fde38b14610299575f80fd5b806370a08231146101e8578063715018a61461021057806379cc6790146102185780638da5cb5b1461022b575f80fd5b8063313ce567116100ce578063313ce5671461016557806332424aa31461019957806340c10f19146101c057806342966c68146101d3575f80fd5b806306fdde03146100ff578063095ea7b31461011d57806318160ddd1461014057806323b872dd14610152575b5f80fd5b6101076102ac565b60405161011491906107f0565b60405180910390f35b61013061012b366004610840565b61033c565b6040519015158152602001610114565b6002545b604051908152602001610114565b610130610160366004610868565b610355565b7f00000000000000000000000000000000000000000000000000000000000000085b60405160ff9091168152602001610114565b6101877f000000000000000000000000000000000000000000000000000000000000000881565b6101306101ce366004610840565b610378565b6101e66101e13660046108a2565b610394565b005b6101446101f63660046108b9565b6001600160a01b03165f9081526020819052604090205490565b6101e66103a1565b6101e6610226366004610840565b6103b4565b6005546040516001600160a01b039091168152602001610114565b6101076103cd565b61013061025c366004610840565b6103dc565b61014461026f3660046108d9565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6101e66102a73660046108b9565b6103e9565b6060600380546102bb9061090a565b80601f01602080910402602001604051908101604052809291908181526020018280546102e79061090a565b80156103325780601f1061030957610100808354040283529160200191610332565b820191905f5260205f20905b81548152906001019060200180831161031557829003601f168201915b5050505050905090565b5f33610349818585610428565b60019150505b92915050565b5f3361036285828561043a565b61036d8585856104b5565b506001949350505050565b5f610381610512565b61038b838361053f565b50600192915050565b61039e3382610573565b50565b6103a9610512565b6103b25f6105a7565b565b6103bf82338361043a565b6103c98282610573565b5050565b6060600480546102bb9061090a565b5f336103498185856104b5565b6103f1610512565b6001600160a01b03811661041f57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b61039e816105a7565b61043583838360016105f8565b505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981146104af57818110156104a157604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610416565b6104af84848484035f6105f8565b50505050565b6001600160a01b0383166104de57604051634b637e8f60e11b81525f6004820152602401610416565b6001600160a01b0382166105075760405163ec442f0560e01b81525f6004820152602401610416565b6104358383836106ca565b6005546001600160a01b031633146103b25760405163118cdaa760e01b8152336004820152602401610416565b6001600160a01b0382166105685760405163ec442f0560e01b81525f6004820152602401610416565b6103c95f83836106ca565b6001600160a01b03821661059c57604051634b637e8f60e11b81525f6004820152602401610416565b6103c9825f836106ca565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6001600160a01b0384166106215760405163e602df0560e01b81525f6004820152602401610416565b6001600160a01b03831661064a57604051634a1406b160e11b81525f6004820152602401610416565b6001600160a01b038085165f90815260016020908152604080832093871683529290522082905580156104af57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516106bc91815260200190565b60405180910390a350505050565b6001600160a01b0383166106f4578060025f8282546106e99190610942565b909155506107649050565b6001600160a01b0383165f90815260208190526040902054818110156107465760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610416565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166107805760028054829003905561079e565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516107e391815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461083b575f80fd5b919050565b5f8060408385031215610851575f80fd5b61085a83610825565b946020939093013593505050565b5f805f6060848603121561087a575f80fd5b61088384610825565b925061089160208501610825565b929592945050506040919091013590565b5f602082840312156108b2575f80fd5b5035919050565b5f602082840312156108c9575f80fd5b6108d282610825565b9392505050565b5f80604083850312156108ea575f80fd5b6108f383610825565b915061090160208401610825565b90509250929050565b600181811c9082168061091e57607f821691505b60208210810361093c57634e487b7160e01b5f52602260045260245ffd5b50919050565b8082018082111561034f57634e487b7160e01b5f52601160045260245ffdfea2646970667358221220a373554eb2e797644d86447291ab79350d58226b5edc56a67e2d820f602062bb64736f6c634300081a0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x5772617070656420425443000000000000000000000000000000000000000016", + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5742544300000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000000000000000000000000746f6b656e61646d696e" + } + }, + "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b50600436106100fb575f3560e01c806370a082311161009357806395d89b411161006357806395d89b4114610246578063a9059cbb1461024e578063dd62ed3e14610261578063f2fde38b14610299575f80fd5b806370a08231146101e8578063715018a61461021057806379cc6790146102185780638da5cb5b1461022b575f80fd5b8063313ce567116100ce578063313ce5671461016557806332424aa31461019957806340c10f19146101c057806342966c68146101d3575f80fd5b806306fdde03146100ff578063095ea7b31461011d57806318160ddd1461014057806323b872dd14610152575b5f80fd5b6101076102ac565b60405161011491906107f0565b60405180910390f35b61013061012b366004610840565b61033c565b6040519015158152602001610114565b6002545b604051908152602001610114565b610130610160366004610868565b610355565b7f00000000000000000000000000000000000000000000000000000000000000125b60405160ff9091168152602001610114565b6101877f000000000000000000000000000000000000000000000000000000000000000681565b6101306101ce366004610840565b610378565b6101e66101e13660046108a2565b610394565b005b6101446101f63660046108b9565b6001600160a01b03165f9081526020819052604090205490565b6101e66103a1565b6101e6610226366004610840565b6103b4565b6005546040516001600160a01b039091168152602001610114565b6101076103cd565b61013061025c366004610840565b6103dc565b61014461026f3660046108d9565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6101e66102a73660046108b9565b6103e9565b6060600380546102bb9061090a565b80601f01602080910402602001604051908101604052809291908181526020018280546102e79061090a565b80156103325780601f1061030957610100808354040283529160200191610332565b820191905f5260205f20905b81548152906001019060200180831161031557829003601f168201915b5050505050905090565b5f33610349818585610428565b60019150505b92915050565b5f3361036285828561043a565b61036d8585856104b5565b506001949350505050565b5f610381610512565b61038b838361053f565b50600192915050565b61039e3382610573565b50565b6103a9610512565b6103b25f6105a7565b565b6103bf82338361043a565b6103c98282610573565b5050565b6060600480546102bb9061090a565b5f336103498185856104b5565b6103f1610512565b6001600160a01b03811661041f57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b61039e816105a7565b61043583838360016105f8565b505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981146104af57818110156104a157604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610416565b6104af84848484035f6105f8565b50505050565b6001600160a01b0383166104de57604051634b637e8f60e11b81525f6004820152602401610416565b6001600160a01b0382166105075760405163ec442f0560e01b81525f6004820152602401610416565b6104358383836106ca565b6005546001600160a01b031633146103b25760405163118cdaa760e01b8152336004820152602401610416565b6001600160a01b0382166105685760405163ec442f0560e01b81525f6004820152602401610416565b6103c95f83836106ca565b6001600160a01b03821661059c57604051634b637e8f60e11b81525f6004820152602401610416565b6103c9825f836106ca565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6001600160a01b0384166106215760405163e602df0560e01b81525f6004820152602401610416565b6001600160a01b03831661064a57604051634a1406b160e11b81525f6004820152602401610416565b6001600160a01b038085165f90815260016020908152604080832093871683529290522082905580156104af57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516106bc91815260200190565b60405180910390a350505050565b6001600160a01b0383166106f4578060025f8282546106e99190610942565b909155506107649050565b6001600160a01b0383165f90815260208190526040902054818110156107465760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610416565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166107805760028054829003905561079e565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516107e391815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461083b575f80fd5b919050565b5f8060408385031215610851575f80fd5b61085a83610825565b946020939093013593505050565b5f805f6060848603121561087a575f80fd5b61088384610825565b925061089160208501610825565b929592945050506040919091013590565b5f602082840312156108b2575f80fd5b5035919050565b5f602082840312156108c9575f80fd5b6108d282610825565b9392505050565b5f80604083850312156108ea575f80fd5b6108f383610825565b915061090160208401610825565b90509250929050565b600181811c9082168061091e57607f821691505b60208210810361093c57634e487b7160e01b5f52602260045260245ffd5b50919050565b8082018082111561034f57634e487b7160e01b5f52601160045260245ffdfea2646970667358221220a373554eb2e797644d86447291ab79350d58226b5edc56a67e2d820f602062bb64736f6c634300081a0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x577261707065642045746865720000000000000000000000000000000000001a", + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5745544800000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000000000000000000000000746f6b656e61646d696e" + } + }, + "0x8ff5C1D5233CA055cD536b2b87294d17f9160801": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b5060043610610055575f3560e01c80631688f0b9146100595780633408e4701461008957806353e5d93514610097578063d18af54d146100ac578063ec9e80bb146100bf575b5f80fd5b61006c610067366004610472565b6100d2565b6040516001600160a01b0390911681526020015b60405180910390f35b604051468152602001610080565b61009f610166565b60405161008091906104f6565b61006c6100ba36600461050f565b610190565b61006c6100cd366004610472565b61025f565b5f808380519060200120836040516020016100f7929190918252602082015260400190565b60405160208183030381529060405280519060200120905061011a858583610290565b6040516001600160a01b038781168252919350908316907f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2359060200160405180910390a2509392505050565b606060405180602001610178906103af565b601f1982820381018352601f90910116604052919050565b5f8083836040516020016101c092919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b604051602081830303815290604052805190602001205f1c90506101e58686836100d2565b91506001600160a01b03831615610256576040516303ca56a360e31b81526001600160a01b03841690631e52b518906102289085908a908a908a90600401610577565b5f604051808303815f87803b15801561023f575f80fd5b505af1158015610251573d5f803e3d5ffd5b505050505b50949350505050565b5f808380519060200120836102714690565b60408051602081019490945283019190915260608201526080016100f7565b5f833b6102e45760405162461bcd60e51b815260206004820152601f60248201527f53696e676c65746f6e20636f6e7472616374206e6f74206465706c6f7965640060448201526064015b60405180910390fd5b5f604051806020016102f5906103af565b601f1982820381018352601f90910116604081905261032291906001600160a01b038816906020016105b3565b6040516020818303038152906040529050828151826020015ff591506001600160a01b03821661038a5760405162461bcd60e51b815260206004820152601360248201527210dc99585d194c8818d85b1b0819985a5b1959606a1b60448201526064016102db565b8351156103a7575f805f8651602088015f875af1036103a7575f80fd5b509392505050565b610163806105ce83390190565b6001600160a01b03811681146103d0575f80fd5b50565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126103f6575f80fd5b813567ffffffffffffffff811115610410576104106103d3565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561043f5761043f6103d3565b604052818152838201602001851015610456575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f60608486031215610484575f80fd5b833561048f816103bc565b9250602084013567ffffffffffffffff8111156104aa575f80fd5b6104b6868287016103e7565b93969395505050506040919091013590565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61050860208301846104c8565b9392505050565b5f805f8060808587031215610522575f80fd5b843561052d816103bc565b9350602085013567ffffffffffffffff811115610548575f80fd5b610554878288016103e7565b93505060408501359150606085013561056c816103bc565b939692955090935050565b6001600160a01b038581168252841660208201526080604082018190525f906105a2908301856104c8565b905082606083015295945050505050565b5f83518060208601845e919091019182525060200191905056fe6080604052348015600e575f80fd5b50604051610163380380610163833981016040819052602b9160b2565b6001600160a01b038116608f5760405162461bcd60e51b815260206004820152602260248201527f496e76616c69642073696e676c65746f6e20616464726573732070726f766964604482015261195960f21b606482015260840160405180910390fd5b5f80546001600160a01b0319166001600160a01b039290921691909117905560dd565b5f6020828403121560c1575f80fd5b81516001600160a01b038116811460d6575f80fd5b9392505050565b607a806100e95f395ff3fe60806040525f80546001600160a01b03169035632cf35bc960e11b01602657805f5260205ff35b365f80375f80365f845af490503d5f803e80603f573d5ffd5b503d5ff3fea264697066735822122001deaa6568fd950b816ad3772ffe1e654dbb28263960bb86cfb313e8e93f6b6b64736f6c634300081a0033a26469706673582212204d02cb188c82949fc64f39d7729617fb7a5131ed975627a1123a88cce3793abc64736f6c634300081a0033" + }, + "0x2f2965efaCFc64Fb85dF1902260eB25C0c996195": { + "balance": "0x0", + "code": "0x6080604052600436106101d0575f3560e01c8063affed0e0116100f6578063e19a9dd911610094578063f08a032311610063578063f08a0323146105d2578063f698da25146105f1578063f8dc5dd914610605578063ffa1ad74146106245761020c565b8063e19a9dd914610561578063e318b52b14610580578063e75235b81461059f578063e86637db146105b35761020c565b8063cc2f8452116100d0578063cc2f8452146104d7578063d4d9bdcd14610504578063d8d11f7814610523578063e009cfde146105425761020c565b8063affed0e014610484578063b4faba0914610499578063b63e800d146104b85761020c565b80635624b25b1161016e5780636a7612021161013d5780636a761202146103fb5780637d8329741461040e578063934f3a1114610444578063a0e67e2b146104635761020c565b80635624b25b146103665780635ae6bd3714610392578063610b5925146103bd578063694e80c3146103dc5761020c565b80632f54bf6e116101aa5780632f54bf6e146102df5780633408e470146102fe578063468721a71461031a5780635229073f146103395761020c565b80630d582f131461026b57806312fb68e01461028c5780632d9ad53d146102ab5761020c565b3661020c5760405134815233907f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d9060200160405180910390a2005b348015610217575f80fd5b507f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d580548061024257005b365f80373360601b36525f80601436015f80855af190503d5f803e80610266573d5ffd5b503d5ff35b348015610276575f80fd5b5061028a6102853660046125fe565b610654565b005b348015610297575f80fd5b5061028a6102a63660046126c5565b6107a9565b3480156102b6575f80fd5b506102ca6102c5366004612738565b610c3a565b60405190151581526020015b60405180910390f35b3480156102ea575f80fd5b506102ca6102f9366004612738565b610c73565b348015610309575f80fd5b50465b6040519081526020016102d6565b348015610325575f80fd5b506102ca610334366004612761565b610ca9565b348015610344575f80fd5b50610358610353366004612761565b610cfe565b6040516102d69291906127f4565b348015610371575f80fd5b5061038561038036600461280e565b610d32565b6040516102d6919061282e565b34801561039d575f80fd5b5061030c6103ac366004612840565b60076020525f908152604090205481565b3480156103c8575f80fd5b5061028a6103d7366004612738565b610dab565b3480156103e7575f80fd5b5061028a6103f6366004612840565b610ee2565b6102ca61040936600461289b565b610f80565b348015610419575f80fd5b5061030c6104283660046125fe565b600860209081525f928352604080842090915290825290205481565b34801561044f575f80fd5b5061028a61045e36600461296b565b611027565b34801561046e575f80fd5b50610477611071565b6040516102d69190612a19565b34801561048f575f80fd5b5061030c60055481565b3480156104a4575f80fd5b5061028a6104b3366004612a2b565b61115e565b3480156104c3575f80fd5b5061028a6104d2366004612a77565b61117d565b3480156104e2575f80fd5b506104f66104f13660046125fe565b61127c565b6040516102d6929190612b66565b34801561050f575f80fd5b5061028a61051e366004612840565b611433565b34801561052e575f80fd5b5061030c61053d366004612b8f565b6114c6565b34801561054d575f80fd5b5061028a61055c366004612c4c565b6114f2565b34801561056c575f80fd5b5061028a61057b366004612738565b611612565b34801561058b575f80fd5b5061028a61059a366004612c83565b611725565b3480156105aa575f80fd5b5060045461030c565b3480156105be575f80fd5b506103856105cd366004612b8f565b6118fc565b3480156105dd575f80fd5b5061028a6105ec366004612738565b6119d3565b3480156105fc575f80fd5b5061030c611a1a565b348015610610575f80fd5b5061028a61061f366004612ccb565b611a70565b34801561062f575f80fd5b5061038560405180604001604052806005815260200164312e342e3160d81b81525081565b61065c611bd8565b6001600160a01b0382161580159061067e57506001600160a01b038216600114155b801561069357506001600160a01b0382163014155b6106b85760405162461bcd60e51b81526004016106af90612d09565b60405180910390fd5b6001600160a01b038281165f9081526002602052604090205416156106ef5760405162461bcd60e51b81526004016106af90612d28565b60026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e080546001600160a01b038481165f818152604081208054939094166001600160a01b03199384161790935560018352835490911617909155600380549161075b83612d5b565b90915550506040516001600160a01b038316907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26905f90a280600454146107a5576107a581610ee2565b5050565b6107b4816041611c11565b825110156107ec5760405162461bcd60e51b8152602060048201526005602482015264047533032360dc1b60448201526064016106af565b5f80805f805f5b86811015610c2e576041818102890160208101516040820151919092015160ff16955090935091505f8490036109fe57885160208a01208a146108605760405162461bcd60e51b8152602060048201526005602482015264475330323760d81b60448201526064016106af565b9193508391610870876041611c11565b8210156108a75760405162461bcd60e51b8152602060048201526005602482015264475330323160d81b60448201526064016106af565b87516108b4836020611c48565b11156108ea5760405162461bcd60e51b815260206004820152600560248201526423a998191960d91b60448201526064016106af565b60208289018101518951909161090d908390610907908790611c48565b90611c48565b11156109435760405162461bcd60e51b8152602060048201526005602482015264475330323360d81b60448201526064016106af565b6040516320c13b0b60e01b8082528a8501602001916001600160a01b038916906320c13b0b90610979908f908690600401612d73565b602060405180830381865afa158015610994573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109b89190612d97565b6001600160e01b031916146109f75760405162461bcd60e51b815260206004820152600560248201526411d4cc0c8d60da1b60448201526064016106af565b5050610b9e565b8360ff16600103610a7f579193508391336001600160a01b0384161480610a4657506001600160a01b0385165f9081526008602090815260408083208d845290915290205415155b610a7a5760405162461bcd60e51b8152602060048201526005602482015264475330323560d81b60448201526064016106af565b610b9e565b601e8460ff161115610b41576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018b9052600190605c0160405160208183030381529060405280519060200120600486610ae49190612dbe565b604080515f8152602081018083529390935260ff90911690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610b30573d5f803e3d5ffd5b505050602060405103519450610b9e565b604080515f8152602081018083528c905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610b91573d5f803e3d5ffd5b5050506020604051035194505b856001600160a01b0316856001600160a01b0316118015610bd757506001600160a01b038581165f908152600260205260409020541615155b8015610bed57506001600160a01b038516600114155b610c215760405162461bcd60e51b815260206004820152600560248201526423a998191b60d91b60448201526064016106af565b93945084936001016107f3565b50505050505050505050565b5f60016001600160a01b03831614801590610c6d57506001600160a01b038281165f908152600160205260409020541615155b92915050565b5f6001600160a01b038216600114801590610c6d5750506001600160a01b039081165f9081526002602052604090205416151590565b5f7fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051610ce1959493929190612e0b565b60405180910390a1610cf585858585611c62565b95945050505050565b5f6060610d0d86868686610ca9565b915060405160203d0181016040523d81523d5f602083013e8091505094509492505050565b60605f610d40836020612e56565b6001600160401b03811115610d5757610d57612628565b6040519080825280601f01601f191660200182016040528015610d81576020820181803683370190505b5090505f5b83811015610da35784810154602080830284010152600101610d86565b509392505050565b610db3611bd8565b6001600160a01b03811615801590610dd557506001600160a01b038116600114155b610e095760405162461bcd60e51b8152602060048201526005602482015264475331303160d81b60448201526064016106af565b6001600160a01b038181165f908152600160205260409020541615610e585760405162461bcd60e51b815260206004820152600560248201526423a998981960d91b60448201526064016106af565b600160208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b038481165f81815260408082208054949095166001600160a01b031994851617909455948552835490911681179092555190917fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844091a250565b610eea611bd8565b600354811115610f0c5760405162461bcd60e51b81526004016106af90612e6d565b6001811015610f455760405162461bcd60e51b815260206004820152600560248201526423a999181960d91b60448201526064016106af565b60048190556040518181527f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c939060200160405180910390a150565b60055460045460408051602081019390935233908301526060828101919091525f9160800160405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051610ffb9c9b9a99989796959493929190612eb4565b60405180910390a16110168d8d8d8d8d8d8d8d8d8d8d611d36565b9d9c50505050505050505050505050565b6004548061105f5760405162461bcd60e51b8152602060048201526005602482015264475330303160d81b60448201526064016106af565b61106b848484846107a9565b50505050565b60605f6003546001600160401b0381111561108e5761108e612628565b6040519080825280602002602001820160405280156110b7578160200160208202803683370190505b5060015f90815260026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e054919250906001600160a01b03165b6001600160a01b038116600114611156578083838151811061111757611117612f52565b6001600160a01b039283166020918202929092018101919091529181165f9081526002909252604090912054168161114e81612d5b565b9250506110f3565b509092915050565b5f80825160208401855af4805f52503d6020523d5f60403e60403d015ffd5b6111ba8a8a808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152508c925061206f915050565b6001600160a01b038416156111d2576111d284612245565b6112118787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506122a992505050565b811561122757611225825f600186856123d7565b505b336001600160a01b03167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b89604051611268959493929190612f66565b60405180910390a250505050505050505050565b60605f6001600160a01b0384166001148061129b575061129b84610c3a565b6112cf5760405162461bcd60e51b8152602060048201526005602482015264475331303560d81b60448201526064016106af565b5f83116113065760405162461bcd60e51b815260206004820152600560248201526423a998981b60d91b60448201526064016106af565b826001600160401b0381111561131e5761131e612628565b604051908082528060200260200182016040528015611347578160200160208202803683370190505b506001600160a01b038086165f90815260016020526040812054929450911691505b6001600160a01b0382161580159061138b57506001600160a01b038216600114155b801561139657508381105b156113f057818382815181106113ae576113ae612f52565b6001600160a01b039283166020918202929092018101919091529281165f908152600190935260409092205490911690806113e881612d5b565b915050611369565b6001600160a01b038216600114611428578261140d600183612fd1565b8151811061141d5761141d612f52565b602002602001015191505b808352509250929050565b335f908152600260205260409020546001600160a01b031661147f5760405162461bcd60e51b8152602060048201526005602482015264047533033360dc1b60448201526064016106af565b335f818152600860209081526040808320858452909152808220600190555183917ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c91a350565b5f6114da8c8c8c8c8c8c8c8c8c8c8c6118fc565b8051906020012090509b9a5050505050505050505050565b6114fa611bd8565b6001600160a01b0381161580159061151c57506001600160a01b038116600114155b6115505760405162461bcd60e51b8152602060048201526005602482015264475331303160d81b60448201526064016106af565b6001600160a01b038281165f908152600160205260409020548116908216146115a35760405162461bcd60e51b8152602060048201526005602482015264475331303360d81b60448201526064016106af565b6001600160a01b038181165f81815260016020526040808220805487861684528284208054919096166001600160a01b0319918216179095558383528054909416909355915190917faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427691a25050565b61161a611bd8565b6001600160a01b038116156116ca576040516301ffc9a760e01b815263736bd41d60e11b60048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015611672573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116969190612fe4565b6116ca5760405162461bcd60e51b8152602060048201526005602482015264047533330360dc1b60448201526064016106af565b7f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c88181556040516001600160a01b038316907f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2905f90a25050565b61172d611bd8565b6001600160a01b0381161580159061174f57506001600160a01b038116600114155b801561176457506001600160a01b0381163014155b6117805760405162461bcd60e51b81526004016106af90612d09565b6001600160a01b038181165f9081526002602052604090205416156117b75760405162461bcd60e51b81526004016106af90612d28565b6001600160a01b038216158015906117d957506001600160a01b038216600114155b6117f55760405162461bcd60e51b81526004016106af90612d09565b6001600160a01b038381165f908152600260205260409020548116908316146118485760405162461bcd60e51b8152602060048201526005602482015264475332303560d81b60448201526064016106af565b6001600160a01b038281165f81815260026020526040808220805486861680855283852080549288166001600160a01b03199384161790559589168452828420805482169096179095558383528054909416909355915190917ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf91a26040516001600160a01b038216907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26905f90a2505050565b60605f7fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d85f1b8d8d8d8d604051611934929190613003565b60405190819003812061195a949392918e908e908e908e908e908e908e90602001613012565b60408051601f1981840301815291905280516020909101209050601960f81b600160f81b611986611a1a565b6040516001600160f81b031993841660208201529290911660218301526022820152604281018290526062016040516020818303038152906040529150509b9a5050505050505050505050565b6119db611bd8565b6119e481612245565b6040516001600160a01b038216907f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b0905f90a250565b5f7f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b611a78611bd8565b806001600354611a889190612fd1565b1015611aa65760405162461bcd60e51b81526004016106af90612e6d565b6001600160a01b03821615801590611ac857506001600160a01b038216600114155b611ae45760405162461bcd60e51b81526004016106af90612d09565b6001600160a01b038381165f90815260026020526040902054811690831614611b375760405162461bcd60e51b8152602060048201526005602482015264475332303560d81b60448201526064016106af565b6001600160a01b038281165f81815260026020526040808220805488861684529183208054929095166001600160a01b03199283161790945591815282549091169091556003805491611b8983613084565b90915550506040516001600160a01b038316907ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf905f90a28060045414611bd357611bd381610ee2565b505050565b333014611c0f5760405162461bcd60e51b8152602060048201526005602482015264475330333160d81b60448201526064016106af565b565b5f825f03611c2057505f610c6d565b5f611c2b8385612e56565b905082611c388583613099565b14611c41575f80fd5b9392505050565b5f80611c5483856130b8565b905083811015611c41575f80fd5b5f33600114801590611c8a5750335f908152600160205260409020546001600160a01b031615155b611cbe5760405162461bcd60e51b815260206004820152600560248201526411d4cc4c0d60da1b60448201526064016106af565b611ccc858585855f196124db565b90508015611d035760405133907f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8905f90a2611d2e565b60405133907facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375905f90a25b949350505050565b5f805f611d4e8e8e8e8e8e8e8e8e8e8e6005546118fc565b600580549192505f611d5f83612d5b565b9091555050805160208201209150611d78828286611027565b505f611da27f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c85490565b90506001600160a01b03811615611e2357806001600160a01b03166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401611df59c9b9a999897969594939291906130cb565b5f604051808303815f87803b158015611e0c575f80fd5b505af1158015611e1e573d5f803e3d5ffd5b505050505b611e4f611e328a6109c46130b8565b603f611e3f8c6040612e56565b611e499190613099565b9061251d565b611e5b906101f46130b8565b5a1015611e925760405162461bcd60e51b8152602060048201526005602482015264047533031360dc1b60448201526064016106af565b5f5a9050611f008f8f8f8f8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508e8c5f14611eed578e6124db565b6109c45a611efb9190612fd1565b6124db565b9350611f0d5a8290612533565b90508380611f1a57508915155b80611f2457508715155b611f585760405162461bcd60e51b8152602060048201526005602482015264475330313360d81b60448201526064016106af565b5f8815611f6f57611f6c828b8b8b8b6123d7565b90505b8415611fb457837f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e82604051611fa791815260200190565b60405180910390a2611fef565b837f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d2382604051611fe691815260200190565b60405180910390a25b50506001600160a01b0381161561205e57604051631264e26d60e31b81526004810183905283151560248201526001600160a01b038216906393271368906044015f604051808303815f87803b158015612047575f80fd5b505af1158015612059573d5f803e3d5ffd5b505050505b50509b9a5050505050505050505050565b600454156120a75760405162461bcd60e51b8152602060048201526005602482015264047533230360dc1b60448201526064016106af565b81518111156120c85760405162461bcd60e51b81526004016106af90612e6d565b60018110156121015760405162461bcd60e51b815260206004820152600560248201526423a999181960d91b60448201526064016106af565b60015f5b8351811015612213575f84828151811061212157612121612f52565b602002602001015190505f6001600160a01b0316816001600160a01b03161415801561215757506001600160a01b038116600114155b801561216c57506001600160a01b0381163014155b801561218a5750806001600160a01b0316836001600160a01b031614155b6121a65760405162461bcd60e51b81526004016106af90612d09565b6001600160a01b038181165f9081526002602052604090205416156121dd5760405162461bcd60e51b81526004016106af90612d28565b6001600160a01b039283165f90815260026020526040902080546001600160a01b03191693821693909317909255600101612105565b506001600160a01b03165f90815260026020526040902080546001600160a01b03191660011790559051600355600455565b306001600160a01b038216036122855760405162461bcd60e51b8152602060048201526005602482015264047533430360dc1b60448201526064016106af565b7f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d555565b60015f8190526020527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f546001600160a01b0316156123125760405162461bcd60e51b8152602060048201526005602482015264047533130360dc1b60448201526064016106af565b60015f81905260208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b03191690911790556001600160a01b038216156107a557813b6123945760405162461bcd60e51b815260206004820152600560248201526423a998181960d91b60448201526064016106af565b6123a3825f8360015f196124db565b6107a55760405162461bcd60e51b8152602060048201526005602482015264047533030360dc1b60448201526064016106af565b5f806001600160a01b038316156123ee57826123f0565b325b90506001600160a01b038416612482576124223a8610612410573a612412565b855b61241c8989611c48565b90611c11565b6040519092506001600160a01b0382169083156108fc029084905f818181858888f1935050505061247d5760405162461bcd60e51b8152602060048201526005602482015264475330313160d81b60448201526064016106af565b6124d1565b6124908561241c8989611c48565b915061249d84828461254b565b6124d15760405162461bcd60e51b815260206004820152600560248201526423a998189960d91b60448201526064016106af565b5095945050505050565b5f60018360018111156124f0576124f0612dd7565b03612507575f808551602087018986f49050610cf5565b5f80855160208701888a87f19695505050505050565b5f8183101561252c5781611c41565b5090919050565b5f82821115612540575f80fd5b5f611d2e8385612fd1565b604080516001600160a01b03841660248201526044808201849052825180830390910181526064909101909152602080820180516001600160e01b031663a9059cbb60e01b17815282515f93929184919082896127105a03f13d80156125bb57602081146125c3575f93506125cd565b8193506125cd565b5f51158215171593505b5050509392505050565b6001600160a01b03811681146125eb575f80fd5b50565b80356125f9816125d7565b919050565b5f806040838503121561260f575f80fd5b823561261a816125d7565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f83011261264b575f80fd5b81356001600160401b0381111561266457612664612628565b604051601f8201601f19908116603f011681016001600160401b038111828210171561269257612692612628565b6040528181528382016020018510156126a9575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80608085870312156126d8575f80fd5b8435935060208501356001600160401b038111156126f4575f80fd5b6127008782880161263c565b93505060408501356001600160401b0381111561271b575f80fd5b6127278782880161263c565b949793965093946060013593505050565b5f60208284031215612748575f80fd5b8135611c41816125d7565b8035600281106125f9575f80fd5b5f805f8060808587031215612774575f80fd5b843561277f816125d7565b93506020850135925060408501356001600160401b038111156127a0575f80fd5b6127ac8782880161263c565b9250506127bb60608601612753565b905092959194509250565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8215158152604060208201525f611d2e60408301846127c6565b5f806040838503121561281f575f80fd5b50508035926020909101359150565b602081525f611c4160208301846127c6565b5f60208284031215612850575f80fd5b5035919050565b5f8083601f840112612867575f80fd5b5081356001600160401b0381111561287d575f80fd5b602083019150836020828501011115612894575f80fd5b9250929050565b5f805f805f805f805f805f6101408c8e0312156128b6575f80fd5b6128bf8c6125ee565b9a5060208c0135995060408c01356001600160401b038111156128e0575f80fd5b6128ec8e828f01612857565b909a5098506128ff905060608d01612753565b965060808c0135955060a08c0135945060c08c0135935061292260e08d016125ee565b92506129316101008d016125ee565b91506101208c01356001600160401b0381111561294c575f80fd5b6129588e828f0161263c565b9150509295989b509295989b9093969950565b5f805f6060848603121561297d575f80fd5b8335925060208401356001600160401b03811115612999575f80fd5b6129a58682870161263c565b92505060408401356001600160401b038111156129c0575f80fd5b6129cc8682870161263c565b9150509250925092565b5f8151808452602084019350602083015f5b82811015612a0f5781516001600160a01b03168652602095860195909101906001016129e8565b5093949350505050565b602081525f611c4160208301846129d6565b5f8060408385031215612a3c575f80fd5b8235612a47816125d7565b915060208301356001600160401b03811115612a61575f80fd5b612a6d8582860161263c565b9150509250929050565b5f805f805f805f805f806101008b8d031215612a91575f80fd5b8a356001600160401b03811115612aa6575f80fd5b8b01601f81018d13612ab6575f80fd5b80356001600160401b03811115612acb575f80fd5b8d60208260051b8401011115612adf575f80fd5b60209182019b5099508b01359750612af960408c016125ee565b965060608b01356001600160401b03811115612b13575f80fd5b612b1f8d828e01612857565b9097509550612b32905060808c016125ee565b9350612b4060a08c016125ee565b925060c08b01359150612b5560e08c016125ee565b90509295989b9194979a5092959850565b604081525f612b7860408301856129d6565b905060018060a01b03831660208301529392505050565b5f805f805f805f805f805f6101408c8e031215612baa575f80fd5b8b35612bb5816125d7565b9a5060208c0135995060408c01356001600160401b03811115612bd6575f80fd5b612be28e828f01612857565b909a509850612bf5905060608d01612753565b965060808c0135955060a08c0135945060c08c0135935060e08c0135612c1a816125d7565b92506101008c0135612c2b816125d7565b809250505f6101208d01359050809150509295989b509295989b9093969950565b5f8060408385031215612c5d575f80fd5b8235612c68816125d7565b91506020830135612c78816125d7565b809150509250929050565b5f805f60608486031215612c95575f80fd5b8335612ca0816125d7565b92506020840135612cb0816125d7565b91506040840135612cc0816125d7565b809150509250925092565b5f805f60608486031215612cdd575f80fd5b8335612ce8816125d7565b92506020840135612cf8816125d7565b929592945050506040919091013590565b602080825260059082015264475332303360d81b604082015260600190565b60208082526005908201526411d4cc8c0d60da1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f60018201612d6c57612d6c612d47565b5060010190565b604081525f612d8560408301856127c6565b8281036020840152610cf581856127c6565b5f60208284031215612da7575f80fd5b81516001600160e01b031981168114611c41575f80fd5b60ff8281168282160390811115610c6d57610c6d612d47565b634e487b7160e01b5f52602160045260245ffd5b60028110612e0757634e487b7160e01b5f52602160045260245ffd5b9052565b6001600160a01b038681168252851660208201526040810184905260a0606082018190525f90612e3d908301856127c6565b9050612e4c6080830184612deb565b9695505050505050565b8082028115828204841417610c6d57610c6d612d47565b602080825260059082015264475332303160d81b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60018060a01b038d1681528b602082015261016060408201525f612edd61016083018c8e612e8c565b612eea606084018c612deb565b608083018a905260a0830189905260c083018890526001600160a01b0387811660e08501528616610100840152828103610120840152612f2a81866127c6565b9050828103610140840152612f3f81856127c6565b9f9e505050505050505050505050505050565b634e487b7160e01b5f52603260045260245ffd5b608080825281018590525f8660a08301825b88811015612fa8578235612f8b816125d7565b6001600160a01b0316825260209283019290910190600101612f78565b50602084019690965250506001600160a01b039283166040820152911660609091015292915050565b81810381811115610c6d57610c6d612d47565b5f60208284031215612ff4575f80fd5b81518015158114611c41575f80fd5b818382375f9101908152919050565b8b81526001600160a01b038b166020820152604081018a9052606081018990526101608101613044608083018a612deb565b60a082019790975260c081019590955260e08501939093526001600160a01b03918216610100850152166101208301526101409091015295945050505050565b5f8161309257613092612d47565b505f190190565b5f826130b357634e487b7160e01b5f52601260045260245ffd5b500490565b80820180821115610c6d57610c6d612d47565b60018060a01b038d1681528b602082015261016060408201525f6130f461016083018c8e612e8c565b613101606084018c612deb565b608083018a905260a0830189905260c083018890526001600160a01b0387811660e0850152861661010084015282810361012084015261314181866127c6565b91505060018060a01b0383166101408301529d9c5050505050505050505050505056fea264697066735822122072f65bcceb63ee3acb0069e2374c764d8a5e2009eff69744f32e244b6f76c45064736f6c634300081a0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + }, + "0xe59838EB7f251489b50940BD640326215420B936": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b50600436106100b0575f3560e01c8063230316401161006e57806323031640146101755780636ac2478414610195578063b2494df3146101a8578063bc197c81146101bd578063bd61951d146101df578063f23a6e61146101f2575f80fd5b806223de29146100b457806301ffc9a7146100ce5780630a1028c4146100f6578063150b7a02146101175780631626ba7e1461014f57806320c13b0b14610162575b5f80fd5b6100cc6100c23660046106a9565b5050505050505050565b005b6100e16100dc36600461076b565b610212565b60405190151581526020015b60405180910390f35b610109610104366004610835565b610263565b6040519081526020016100ed565b61013661012536600461086e565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016100ed565b61013661015d3660046108db565b61026e565b610136610170366004610922565b610328565b610188610183366004610985565b610469565b6040516100ed91906109e9565b6101096101a3366004610985565b610577565b6101b0610591565b6040516100ed91906109fb565b6101366101cb366004610a86565b63bc197c8160e01b98975050505050505050565b6101886101ed366004610b26565b610607565b610136610200366004610b5d565b63f23a6e6160e01b9695505050505050565b5f6001600160e01b03198216630271189760e51b148061024257506001600160e01b03198216630a85bd0160e11b145b8061025d57506001600160e01b031982166301ffc9a760e01b145b92915050565b5f61025d3383610577565b60408051602080820186905282518083039091018152818301928390526320c13b0b60e01b9092525f913391839183916320c13b0b916102b49189908990604401610bd3565b602060405180830381865afa1580156102cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102f39190610c17565b90506001600160e01b031981166320c13b0b60e01b14610313575f61031c565b630b135d3f60e11b5b925050505b9392505050565b5f33816103358286610469565b805160208201208551919250905f036103fa57604051635ae6bd3760e01b8152600481018290526001600160a01b03841690635ae6bd3790602401602060405180830381865afa15801561038b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103af9190610c32565b5f036103f55760405162461bcd60e51b815260206004820152601160248201527012185cda081b9bdd08185c1c1c9bdd9959607a1b604482015260640160405180910390fd5b610457565b60405163934f3a1160e01b81526001600160a01b0384169063934f3a119061042a90849086908a90600401610c49565b5f6040518083038186803b158015610440575f80fd5b505afa158015610452573d5f803e3d5ffd5b505050505b506320c13b0b60e01b95945050505050565b60605f7f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca5f1b83805190602001206040516020016104b1929190918252602082015260400190565b604051602081830303815290604052805190602001209050601960f81b600160f81b856001600160a01b031663f698da256040518163ffffffff1660e01b8152600401602060405180830381865afa15801561050f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105339190610c32565b6040516001600160f81b0319938416602082015292909116602183015260228201526042810182905260620160405160208183030381529060405291505092915050565b5f6105828383610469565b80519060200120905092915050565b604051636617c22960e11b815260016004820152600a602482015260609033905f90829063cc2f8452906044015f60405180830381865afa1580156105d8573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526105ff9190810190610c8d565b509392505050565b606060405163b4faba0960e01b81526004360360048083013760205f36835f335af1505060203d036040519150808201604052806020833e505f5161032157805160208201fd5b6001600160a01b0381168114610662575f80fd5b50565b5f8083601f840112610675575f80fd5b5081356001600160401b0381111561068b575f80fd5b6020830191508360208285010111156106a2575f80fd5b9250929050565b5f805f805f805f8060c0898b0312156106c0575f80fd5b88356106cb8161064e565b975060208901356106db8161064e565b965060408901356106eb8161064e565b95506060890135945060808901356001600160401b0381111561070c575f80fd5b6107188b828c01610665565b90955093505060a08901356001600160401b03811115610736575f80fd5b6107428b828c01610665565b999c989b5096995094979396929594505050565b6001600160e01b031981168114610662575f80fd5b5f6020828403121561077b575f80fd5b813561032181610756565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156107c2576107c2610786565b604052919050565b5f82601f8301126107d9575f80fd5b81356001600160401b038111156107f2576107f2610786565b610805601f8201601f191660200161079a565b818152846020838601011115610819575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215610845575f80fd5b81356001600160401b0381111561085a575f80fd5b610866848285016107ca565b949350505050565b5f805f805f60808688031215610882575f80fd5b853561088d8161064e565b9450602086013561089d8161064e565b93506040860135925060608601356001600160401b038111156108be575f80fd5b6108ca88828901610665565b969995985093965092949392505050565b5f805f604084860312156108ed575f80fd5b8335925060208401356001600160401b03811115610909575f80fd5b61091586828701610665565b9497909650939450505050565b5f8060408385031215610933575f80fd5b82356001600160401b03811115610948575f80fd5b610954858286016107ca565b92505060208301356001600160401b0381111561096f575f80fd5b61097b858286016107ca565b9150509250929050565b5f8060408385031215610996575f80fd5b82356109a18161064e565b915060208301356001600160401b0381111561096f575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61032160208301846109bb565b602080825282518282018190525f918401906040840190835b81811015610a3b5783516001600160a01b0316835260209384019390920191600101610a14565b509095945050505050565b5f8083601f840112610a56575f80fd5b5081356001600160401b03811115610a6c575f80fd5b6020830191508360208260051b85010111156106a2575f80fd5b5f805f805f805f8060a0898b031215610a9d575f80fd5b8835610aa88161064e565b97506020890135610ab88161064e565b965060408901356001600160401b03811115610ad2575f80fd5b610ade8b828c01610a46565b90975095505060608901356001600160401b03811115610afc575f80fd5b610b088b828c01610a46565b90955093505060808901356001600160401b03811115610736575f80fd5b5f805f60408486031215610b38575f80fd5b8335610b438161064e565b925060208401356001600160401b03811115610909575f80fd5b5f805f805f8060a08789031215610b72575f80fd5b8635610b7d8161064e565b95506020870135610b8d8161064e565b9450604087013593506060870135925060808701356001600160401b03811115610bb5575f80fd5b610bc189828a01610665565b979a9699509497509295939492505050565b604081525f610be560408301866109bb565b8281036020840152838152838560208301375f602085830101526020601f19601f860116820101915050949350505050565b5f60208284031215610c27575f80fd5b815161032181610756565b5f60208284031215610c42575f80fd5b5051919050565b838152606060208201525f610c6160608301856109bb565b8281036040840152610c7381856109bb565b9695505050505050565b8051610c888161064e565b919050565b5f8060408385031215610c9e575f80fd5b82516001600160401b03811115610cb3575f80fd5b8301601f81018513610cc3575f80fd5b80516001600160401b03811115610cdc57610cdc610786565b8060051b610cec6020820161079a565b91825260208184018101929081019088841115610d07575f80fd5b6020850194505b83851015610d355784519250610d238361064e565b82825260209485019490910190610d0e565b8096505050505050610d4960208401610c7d565b9050925092905056fea26469706673582212207234b4eb35a19350f1ef1ac1dcfde24186fe0f559f21323992f580424784d70564736f6c634300081a0033" + }, + "0x6b3Ff43C7317308517b8786FEaDe35EE0E7FDf99": { + "balance": "0x0", + "code": "0x60806040525f80546001600160a01b03169035632cf35bc960e11b01602657805f5260205ff35b365f80375f80365f845af490503d5f803e80603f573d5ffd5b503d5ff3fea264697066735822122001deaa6568fd950b816ad3772ffe1e654dbb28263960bb86cfb313e8e93f6b6b64736f6c634300081a0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000002f2965efacfc64fb85df1902260eb25c0c996195", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0": "0x0000000000000000000000001111111111111111111111111111111111111111", + "0x06bb1b9bc4293ba066a12274418b7ea4df183c2e4e6b39591987369520ca3956": "0x0000000000000000000000002222222222222222222222222222222222222222", + "0x74b48303b668c996c09b610daf2f53f83448dd15b9ac57e9e8fb1ff2f745c71d": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5": "0x000000000000000000000000e59838eb7f251489b50940bd640326215420b936" + } + }, + + "0x61e5Ab7cD0CaDabcB502c2D2668754675F13e4C1": { + "balance": "0x0", + "code": "0x7361e5ab7cd0cadabcb502c2d2668754675f13e4c130146080604052600436106100355760003560e01c80636ccea6521461003a575b600080fd5b6101026004803603606081101561005057600080fd5b73ffffffffffffffffffffffffffffffffffffffff8235169160208101359181019060608101604082013564010000000081111561008d57600080fd5b82018360208201111561009f57600080fd5b803590602001918460018302840111640100000000831117156100c157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610116945050505050565b604080519115158252519081900360200190f35b600061012184610179565b610164578373ffffffffffffffffffffffffffffffffffffffff16610146848461017f565b73ffffffffffffffffffffffffffffffffffffffff16149050610172565b61016f848484610203565b90505b9392505050565b3b151590565b600081516041146101db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806106296023913960400191505060405180910390fd5b60208201516040830151606084015160001a6101f98682858561042d565b9695505050505050565b60008060608573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b86866040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561026f578181015183820152602001610257565b50505050905090810190601f16801561029c5780820380516001836020036101000a031916815260200191505b50604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009098169790971787525181519196909550859450925090508083835b6020831061036957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161032c565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d80600081146103c9576040519150601f19603f3d011682016040523d82523d6000602084013e6103ce565b606091505b50915091508180156103e257506020815110155b80156101f9575080517f1626ba7e00000000000000000000000000000000000000000000000000000000906020808401919081101561042057600080fd5b5051149695505050505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156104a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806106726026913960400191505060405180910390fd5b8360ff16601b141580156104c057508360ff16601c14155b15610516576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061064c6026913960400191505060405180910390fd5b600060018686868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610572573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661061f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45435265636f7665723a20696e76616c6964207369676e617475726500000000604482015290519081900360640190fd5b9594505050505056fe45435265636f7665723a20696e76616c6964207369676e6174757265206c656e67746845435265636f7665723a20696e76616c6964207369676e6174757265202776272076616c756545435265636f7665723a20696e76616c6964207369676e6174757265202773272076616c7565a2646970667358221220fc883ef3b50f607958f5dc584d21cf2984d25712b89b5e11c0d53a81068ace3664736f6c634300060c0033", + "storage": {} + }, + "0xEc24c7F79233b66929c0Cf43832782bd32303B03": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b506004361061036d5760003560e01c80638456cb59116101d3578063b7b7289911610104578063e3ee160e116100a2578063ef55bec61161007c578063ef55bec614611122578063f2fde38b1461118e578063f9f92be4146111c1578063fe575a87146111f45761036d565b8063e3ee160e14611075578063e5a6b10f146110e1578063e94a0102146110e95761036d565b8063d505accf116100de578063d505accf14610f64578063d608ea6414610fc2578063d916948714611032578063dd62ed3e1461103a5761036d565b8063b7b7289914610db0578063bd10243014610e78578063cf09299514610e805761036d565b8063a0cc6a6811610171578063aa20e1e41161014b578063aa20e1e414610cd4578063aa271e1a14610d07578063ad38bf2214610d3a578063b2118a8d14610d6d5761036d565b8063a0cc6a6814610c5a578063a457c2d714610c62578063a9059cbb14610c9b5761036d565b80638da5cb5b116101ad5780638da5cb5b14610b6a57806395d89b4114610b725780639fd0506d14610b7a5780639fd5a6cf14610b825761036d565b80638456cb5914610a4b57806388b7ab6314610a535780638a6db9c314610b375761036d565b806338a63183116102ad57806354fd4d501161024b5780635c975abb116102255780635c975abb146109d557806370a08231146109dd5780637ecebe0014610a105780637f2eecc314610a435761036d565b806354fd4d501461094c578063554bab3c146109545780635a049a70146109875761036d565b806340c10f191161028757806340c10f19146107fb57806342966c6814610834578063430239b4146108515780634e44d956146109135761036d565b806338a63183146107b257806339509351146107ba5780633f4ba83a146107f35761036d565b80632fc81e091161031a578063313ce567116102f4578063313ce5671461056f5780633357162b1461058d57806335d99f35146107795780633644e515146107aa5761036d565b80632fc81e09146105015780633092afd51461053457806330adf81f146105675761036d565b80631a8952661161034b5780631a8952661461045657806323b872dd1461048b5780632ab60045146104ce5761036d565b806306fdde0314610372578063095ea7b3146103ef57806318160ddd1461043c575b600080fd5b61037a611227565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103b457818101518382015260200161039c565b50505050905090810190601f1680156103e15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104286004803603604081101561040557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356112d3565b604080519115158252519081900360200190f35b610444611374565b60408051918252519081900360200190f35b6104896004803603602081101561046c57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661137a565b005b610428600480360360608110156104a157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135611437565b610489600480360360208110156104e457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166116f2565b6104896004803603602081101561051757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611853565b6104286004803603602081101561054a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166118bb565b6104446119b4565b6105776119d8565b6040805160ff9092168252519081900360200190f35b61048960048036036101008110156105a457600080fd5b8101906020810181356401000000008111156105bf57600080fd5b8201836020820111156105d157600080fd5b803590602001918460018302840111640100000000831117156105f357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561064657600080fd5b82018360208201111561065857600080fd5b8035906020019184600183028401116401000000008311171561067a57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156106cd57600080fd5b8201836020820111156106df57600080fd5b8035906020019184600183028401116401000000008311171561070157600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505050813560ff16925050602081013573ffffffffffffffffffffffffffffffffffffffff908116916040810135821691606082013581169160800135166119e1565b610781611d23565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b610444611d3f565b610781611d4e565b610428600480360360408110156107d057600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611d6a565b610489611e02565b6104286004803603604081101561081157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611ec5565b6104896004803603602081101561084a57600080fd5b5035612296565b6104896004803603604081101561086757600080fd5b81019060208101813564010000000081111561088257600080fd5b82018360208201111561089457600080fd5b803590602001918460208302840111640100000000831117156108b657600080fd5b9193909290916020810190356401000000008111156108d457600080fd5b8201836020820111156108e657600080fd5b8035906020019184600183028401116401000000008311171561090857600080fd5b509092509050612538565b6104286004803603604081101561092957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356126ef565b61037a612882565b6104896004803603602081101561096a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166128b9565b610489600480360360a081101561099d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060208101359060ff6040820135169060608101359060800135612a20565b610428612abe565b610444600480360360208110156109f357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612adf565b61044460048036036020811015610a2657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612af0565b610444612b18565b610489612b3c565b610489600480360360e0811015610a6957600080fd5b73ffffffffffffffffffffffffffffffffffffffff823581169260208101359091169160408201359160608101359160808201359160a08101359181019060e0810160c0820135640100000000811115610ac257600080fd5b820183602082011115610ad457600080fd5b80359060200191846001830284011164010000000083111715610af657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612c16945050505050565b61044460048036036020811015610b4d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612d7a565b610781612da2565b61037a612dbe565b610781612e37565b610489600480360360a0811015610b9857600080fd5b73ffffffffffffffffffffffffffffffffffffffff823581169260208101359091169160408201359160608101359181019060a081016080820135640100000000811115610be557600080fd5b820183602082011115610bf757600080fd5b80359060200191846001830284011164010000000083111715610c1957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612e53945050505050565b610444612eea565b61042860048036036040811015610c7857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612f0e565b61042860048036036040811015610cb157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612fa6565b61048960048036036020811015610cea57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613109565b61042860048036036020811015610d1d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613270565b61048960048036036020811015610d5057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661329b565b61048960048036036060811015610d8357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135613402565b61048960048036036060811015610dc657600080fd5b73ffffffffffffffffffffffffffffffffffffffff82351691602081013591810190606081016040820135640100000000811115610e0357600080fd5b820183602082011115610e1557600080fd5b80359060200191846001830284011164010000000083111715610e3757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613498945050505050565b61078161352d565b610489600480360360e0811015610e9657600080fd5b73ffffffffffffffffffffffffffffffffffffffff823581169260208101359091169160408201359160608101359160808201359160a08101359181019060e0810160c0820135640100000000811115610eef57600080fd5b820183602082011115610f0157600080fd5b80359060200191846001830284011164010000000083111715610f2357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613549945050505050565b610489600480360360e0811015610f7a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c001356136a2565b61048960048036036020811015610fd857600080fd5b810190602081018135640100000000811115610ff357600080fd5b82018360208201111561100557600080fd5b8035906020019184600183028401116401000000008311171561102757600080fd5b509092509050613744565b61044461382d565b6104446004803603604081101561105057600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516613851565b610489600480360361012081101561108c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060808101359060a08101359060ff60c0820135169060e0810135906101000135613889565b61037a6139f1565b610428600480360360408110156110ff57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135613a6a565b610489600480360361012081101561113957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060608101359060808101359060a08101359060ff60c0820135169060e0810135906101000135613aa2565b610489600480360360208110156111a457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613bfd565b610489600480360360208110156111d757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613d50565b6104286004803603602081101561120a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613e0d565b6004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156112cb5780601f106112a0576101008083540402835291602001916112cb565b820191906000526020600020905b8154815290600101906020018083116112ae57829003601f168201915b505050505081565b60015460009074010000000000000000000000000000000000000000900460ff161561136057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b61136b338484613e18565b50600192915050565b600b5490565b60025473ffffffffffffffffffffffffffffffffffffffff1633146113ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615824602c913960400191505060405180910390fd5b6113f381613f5f565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f117e3210bb9aa7d9baff172026820255c6f6c30ba8999d1c2fd88e2848137c4e90600090a250565b60015460009074010000000000000000000000000000000000000000900460ff16156114c457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b336114ce81613f6a565b15611524576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b8461152e81613f6a565b15611584576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b8461158e81613f6a565b156115e4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff87166000908152600a6020908152604080832033845290915290205485111561166d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806159146028913960400191505060405180910390fd5b611678878787613f98565b73ffffffffffffffffffffffffffffffffffffffff87166000908152600a602090815260408083203384529091529020546116b39086614163565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600a60209081526040808320338452909152902055600193505050509392505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461177857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81166117e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061575d602a913960400191505060405180910390fd5b600e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517fe475e580d85111348e40d8ca33cfdd74c30fe1655c2d8537a13abc10065ffa5a90600090a250565b60125460ff1660011461186557600080fd5b6000611870306141da565b9050801561188357611883308383613f98565b61188c30614224565b5050601280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166002179055565b60085460009073ffffffffffffffffffffffffffffffffffffffff16331461192e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806157fb6029913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000818152600c6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600d909152808220829055517fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb666929190a2506001919050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60065460ff1681565b60085474010000000000000000000000000000000000000000900460ff1615611a55576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061598f602a913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8416611ac1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001806158c1602f913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316611b2d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806157346029913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216611b99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018061593c602e913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116611c05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615a7c6028913960400191505060405180910390fd5b8751611c189060049060208b01906154cd565b508651611c2c9060059060208a01906154cd565b508551611c409060079060208901906154cd565b50600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8716179055600880547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff8781169190911790925560018054821686841617905560028054909116918416919091179055611cda8161422f565b5050600880547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b6000611d49614276565b905090565b600e5473ffffffffffffffffffffffffffffffffffffffff1690565b60015460009074010000000000000000000000000000000000000000900460ff1615611df757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b61136b33848461436b565b60015473ffffffffffffffffffffffffffffffffffffffff163314611e72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615a306022913960400191505060405180910390fd5b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1690556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3390600090a1565b60015460009074010000000000000000000000000000000000000000900460ff1615611f5257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b336000908152600c602052604090205460ff16611fba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806158a06021913960400191505060405180910390fd5b33611fc481613f6a565b1561201a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b8361202481613f6a565b1561207a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166120e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806156c96023913960400191505060405180910390fd5b6000841161213f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806157ac6029913960400191505060405180910390fd5b336000908152600d6020526040902054808511156121a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180615a02602e913960400191505060405180910390fd5b600b546121b590866143b5565b600b556121d4866121cf876121c9836141da565b906143b5565b614430565b6121de8186614163565b336000818152600d6020908152604091829020939093558051888152905173ffffffffffffffffffffffffffffffffffffffff8a16937fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8928290030190a360408051868152905173ffffffffffffffffffffffffffffffffffffffff8816916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350600195945050505050565b60015474010000000000000000000000000000000000000000900460ff161561232057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b336000908152600c602052604090205460ff16612388576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806158a06021913960400191505060405180910390fd5b3361239281613f6a565b156123e8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b60006123f3336141da565b90506000831161244e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806156a06029913960400191505060405180910390fd5b828110156124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061587a6026913960400191505060405180910390fd5b600b546124b49084614163565b600b556124c5336121cf8386614163565b60408051848152905133917fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5919081900360200190a260408051848152905160009133917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a3505050565b60125460ff1660021461254a57600080fd5b6125566005838361554b565b5060005b83811015612698576003600086868481811061257257fe5b6020908102929092013573ffffffffffffffffffffffffffffffffffffffff168352508101919091526040016000205460ff166125fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001806155ed603d913960400191505060405180910390fd5b61262b85858381811061260957fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff16614224565b6003600086868481811061263b57fe5b6020908102929092013573ffffffffffffffffffffffffffffffffffffffff1683525081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905560010161255a565b506126a230614224565b505030600090815260036020819052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009081169091556012805490911690911790555050565b60015460009074010000000000000000000000000000000000000000900460ff161561277c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b60085473ffffffffffffffffffffffffffffffffffffffff1633146127ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806157fb6029913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000818152600c6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600d825291829020859055815185815291517f46980fca912ef9bcdbd36877427b6b90e860769f604e89c0e67720cece530d209281900390910190a250600192915050565b60408051808201909152600181527f3200000000000000000000000000000000000000000000000000000000000000602082015290565b60005473ffffffffffffffffffffffffffffffffffffffff16331461293f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81166129ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061564d6028913960400191505060405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117918290556040519116907fb80482a293ca2e013eda8683c9bd7fc8347cfdaeea5ede58cba46df502c2a60490600090a250565b60015474010000000000000000000000000000000000000000900460ff1615612aaa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b612ab78585858585614531565b5050505050565b60015474010000000000000000000000000000000000000000900460ff1681565b6000612aea826141da565b92915050565b73ffffffffffffffffffffffffffffffffffffffff1660009081526011602052604090205490565b7fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de881565b60015473ffffffffffffffffffffffffffffffffffffffff163314612bac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615a306022913960400191505060405180910390fd5b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62590600090a1565b60015474010000000000000000000000000000000000000000900460ff1615612ca057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b86612caa81613f6a565b15612d00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b86612d0a81613f6a565b15612d60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b612d6f89898989898989614571565b505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff166000908152600d602052604090205490565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b6005805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156112cb5780601f106112a0576101008083540402835291602001916112cb565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60015474010000000000000000000000000000000000000000900460ff1615612edd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b612ab78585858585614692565b7f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226781565b60015460009074010000000000000000000000000000000000000000900460ff1615612f9b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b61136b338484614956565b60015460009074010000000000000000000000000000000000000000900460ff161561303357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b3361303d81613f6a565b15613093576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b8361309d81613f6a565b156130f3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b6130fe338686613f98565b506001949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461318f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff81166131fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001806158c1602f913960400191505060405180910390fd5b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117918290556040519116907fdb66dfa9c6b8f5226fe9aac7e51897ae8ee94ac31dc70bb6c9900b2574b707e690600090a250565b73ffffffffffffffffffffffffffffffffffffffff166000908152600c602052604090205460ff1690565b60005473ffffffffffffffffffffffffffffffffffffffff16331461332157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff811661338d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180615ad26032913960400191505060405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691909117918290556040519116907fc67398012c111ce95ecb7429b933096c977380ee6c421175a71a4a4c6c88c06e90600090a250565b600e5473ffffffffffffffffffffffffffffffffffffffff163314613472576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806158f06024913960400191505060405180910390fd5b61349373ffffffffffffffffffffffffffffffffffffffff841683836149b2565b505050565b60015474010000000000000000000000000000000000000000900460ff161561352257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b613493838383614a3f565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60015474010000000000000000000000000000000000000000900460ff16156135d357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b866135dd81613f6a565b15613633576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b8661363d81613f6a565b15613693576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b612d6f89898989898989614b49565b60015474010000000000000000000000000000000000000000900460ff161561372c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b61373b87878787878787614be7565b50505050505050565b60085474010000000000000000000000000000000000000000900460ff168015613771575060125460ff16155b61377a57600080fd5b6137866004838361554b565b506137fb82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600181527f320000000000000000000000000000000000000000000000000000000000000060208201529150614c299050565b600f555050601280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b7f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600a6020908152604080832093909416825291909152205490565b60015474010000000000000000000000000000000000000000900460ff161561391357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b8861391d81613f6a565b15613973576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b8861397d81613f6a565b156139d3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b6139e48b8b8b8b8b8b8b8b8b614c3f565b5050505050505050505050565b6007805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156112cb5780601f106112a0576101008083540402835291602001916112cb565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152601060209081526040808320938352929052205460ff1690565b60015474010000000000000000000000000000000000000000900460ff1615613b2c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015290519081900360640190fd5b88613b3681613f6a565b15613b8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b88613b9681613f6a565b15613bec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b046025913960400191505060405180910390fd5b6139e48b8b8b8b8b8b8b8b8b614c83565b60005473ffffffffffffffffffffffffffffffffffffffff163314613c8357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116613cef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806156ec6026913960400191505060405180910390fd5b6000546040805173ffffffffffffffffffffffffffffffffffffffff9283168152918316602083015280517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09281900390910190a1613d4d8161422f565b50565b60025473ffffffffffffffffffffffffffffffffffffffff163314613dc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180615824602c913960400191505060405180910390fd5b613dc981614224565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fffa4e6181777692565cf28528fc88fd1516ea86b56da075235fa575af6a4b85590600090a250565b6000612aea82613f6a565b73ffffffffffffffffffffffffffffffffffffffff8316613e84576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806159de6024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216613ef0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806157126022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8084166000818152600a6020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b613d4d816000614cc7565b73ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604090205460ff1c60011490565b73ffffffffffffffffffffffffffffffffffffffff8316614004576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806159b96025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216614070576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061562a6023913960400191505060405180910390fd5b614079836141da565b8111156140d1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806157d56026913960400191505060405180910390fd5b6140e8836121cf836140e2876141da565b90614163565b6140f9826121cf836121c9866141da565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b6000828211156141d457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b73ffffffffffffffffffffffffffffffffffffffff166000908152600960205260409020547f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690565b613d4d816001614cc7565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152600093611d4993919290918301828280156143235780601f106142f857610100808354040283529160200191614323565b820191906000526020600020905b81548152906001019060200180831161430657829003601f168201915b50505050506040518060400160405280600181526020017f3200000000000000000000000000000000000000000000000000000000000000815250614366614d50565b614d54565b73ffffffffffffffffffffffffffffffffffffffff8084166000908152600a602090815260408083209386168352929052205461349390849084906143b090856143b5565b613e18565b60008282018381101561442957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8111156144a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615850602a913960400191505060405180910390fd5b6144b282613f6a565b15614508576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806157876025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff909116600090815260096020526040902055565b612ab78585848487604051602001808481526020018381526020018260ff1660f81b81526001019350505050604051602081830303815290604052614a3f565b73ffffffffffffffffffffffffffffffffffffffff861633146145df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602581526020018061596a6025913960400191505060405180910390fd5b6145eb87838686614dc8565b604080517fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de860208083019190915273ffffffffffffffffffffffffffffffffffffffff808b1683850152891660608301526080820188905260a0820187905260c0820186905260e080830186905283518084039091018152610100909201909252805191012061467d90889083614e88565b6146878783615006565b61373b878787613f98565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214806146c05750428210155b61472b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a207065726d697420697320657870697265640000604482015290519081900360640190fd5b60006147d3614738614276565b73ffffffffffffffffffffffffffffffffffffffff80891660008181526011602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938b166060840152608083018a905260a083019390935260c08083018990528151808403909101815260e09092019052805191012061508b565b90507361e5ab7cd0cadabcb502c2d2668754675f13e4c1636ccea6528783856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015614860578181015183820152602001614848565b50505050905090810190601f16801561488d5780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b1580156148ac57600080fd5b505af41580156148c0573d6000803e3d6000fd5b505050506040513d60208110156148d657600080fd5b505161494357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f454950323631323a20696e76616c6964207369676e6174757265000000000000604482015290519081900360640190fd5b61494e868686613e18565b505050505050565b61349383836143b084604051806060016040528060258152602001615b4e6025913973ffffffffffffffffffffffffffffffffffffffff808a166000908152600a60209081526040808320938c168352929052205491906150c5565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052613493908490615176565b614a49838361524e565b614ac3837f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742960001b8585604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200193505050506040516020818303038152906040528051906020012083614e88565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260106020908152604080832086845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b614b5587838686614dc8565b604080517f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226760208083019190915273ffffffffffffffffffffffffffffffffffffffff808b1683850152891660608301526080820188905260a0820187905260c0820186905260e080830186905283518084039091018152610100909201909252805191012061467d90889083614e88565b61373b87878787868689604051602001808481526020018381526020018260ff1660f81b81526001019350505050604051602081830303815290604052614692565b600046614c37848483614d54565b949350505050565b612d6f89898989898988888b604051602001808481526020018381526020018260ff1660f81b81526001019350505050604051602081830303815290604052614b49565b612d6f89898989898988888b604051602001808481526020018381526020018260ff1660f81b81526001019350505050604051602081830303815290604052614571565b80614cda57614cd5826141da565b614d23565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600960205260409020547f8000000000000000000000000000000000000000000000000000000000000000175b73ffffffffffffffffffffffffffffffffffffffff90921660009081526009602052604090209190915550565b4690565b8251602093840120825192840192909220604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8187015280820194909452606084019190915260808301919091523060a0808401919091528151808403909101815260c09092019052805191012090565b814211614e20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180615675602b913960400191505060405180910390fd5b804210614e78576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180615b296025913960400191505060405180910390fd5b614e82848461524e565b50505050565b7361e5ab7cd0cadabcb502c2d2668754675f13e4c1636ccea65284614eb4614eae614276565b8661508b565b846040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015614f23578181015183820152602001614f0b565b50505050905090810190601f168015614f505780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015614f6f57600080fd5b505af4158015614f83573d6000803e3d6000fd5b505050506040513d6020811015614f9957600080fd5b505161349357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f46696174546f6b656e56323a20696e76616c6964207369676e61747572650000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260106020908152604080832085845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b6040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b6000818484111561516e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561513357818101518382015260200161511b565b50505050905090810190601f1680156151605780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60606151d8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166152dc9092919063ffffffff16565b805190915015613493578080602001905160208110156151f757600080fd5b5051613493576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615a52602a913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260106020908152604080832084845290915290205460ff16156152d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180615aa4602e913960400191505060405180910390fd5b5050565b6060614c378484600085856152f085615447565b61535b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106153c557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101615388565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615427576040519150601f19603f3d011682016040523d82523d6000602084013e61542c565b606091505b509150915061543c82828661544d565b979650505050505050565b3b151590565b6060831561545c575081614429565b82511561546c5782518084602001fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181815284516024840152845185939192839260440191908501908083836000831561513357818101518382015260200161511b565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061550e57805160ff191683800117855561553b565b8280016001018555821561553b579182015b8281111561553b578251825591602001919060010190615520565b506155479291506155d7565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106155aa578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082351617855561553b565b8280016001018555821561553b579182015b8281111561553b5782358255916020019190600101906155bc565b5b8082111561554757600081556001016155d856fe46696174546f6b656e56325f323a20426c61636b6c697374696e672070726576696f75736c7920756e626c61636b6c6973746564206163636f756e742145524332303a207472616e7366657220746f20746865207a65726f20616464726573735061757361626c653a206e65772070617573657220697320746865207a65726f206164647265737346696174546f6b656e56323a20617574686f72697a6174696f6e206973206e6f74207965742076616c696446696174546f6b656e3a206275726e20616d6f756e74206e6f742067726561746572207468616e203046696174546f6b656e3a206d696e7420746f20746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737346696174546f6b656e3a206e65772070617573657220697320746865207a65726f2061646472657373526573637561626c653a206e6577207265736375657220697320746865207a65726f206164647265737346696174546f6b656e56325f323a204163636f756e7420697320626c61636b6c697374656446696174546f6b656e3a206d696e7420616d6f756e74206e6f742067726561746572207468616e203045524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636546696174546f6b656e3a2063616c6c6572206973206e6f7420746865206d61737465724d696e746572426c61636b6c69737461626c653a2063616c6c6572206973206e6f742074686520626c61636b6c697374657246696174546f6b656e56325f323a2042616c616e636520657863656564732028325e323535202d20312946696174546f6b656e3a206275726e20616d6f756e7420657863656564732062616c616e636546696174546f6b656e3a2063616c6c6572206973206e6f742061206d696e74657246696174546f6b656e3a206e6577206d61737465724d696e74657220697320746865207a65726f2061646472657373526573637561626c653a2063616c6c6572206973206e6f7420746865207265736375657245524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636546696174546f6b656e3a206e657720626c61636b6c697374657220697320746865207a65726f206164647265737346696174546f6b656e56323a2063616c6c6572206d7573742062652074686520706179656546696174546f6b656e3a20636f6e747261637420697320616c726561647920696e697469616c697a656445524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737346696174546f6b656e3a206d696e7420616d6f756e742065786365656473206d696e746572416c6c6f77616e63655061757361626c653a2063616c6c6572206973206e6f7420746865207061757365725361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656446696174546f6b656e3a206e6577206f776e657220697320746865207a65726f206164647265737346696174546f6b656e56323a20617574686f72697a6174696f6e2069732075736564206f722063616e63656c6564426c61636b6c69737461626c653a206e657720626c61636b6c697374657220697320746865207a65726f2061646472657373426c61636b6c69737461626c653a206163636f756e7420697320626c61636b6c697374656446696174546f6b656e56323a20617574686f72697a6174696f6e206973206578706972656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212209fdc628f524744f6562e56a44baae9ab06eac104dd3cbd41ce9e4558822afc5664736f6c634300060c0033", + "storage": { + "0xd7aae47a190b276daefccc0b6c08e4d3500b90de4158a4601cfa23e0d69f3793": "0x8000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000012": "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000010000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000100", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000006b3ff43c7317308517b8786feade35ee0e7fdf99", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x000000000000000000000000000000000000000000000000000000000000000f": "0xddb40511a2dd51d8809e33333a07ca1a31882a5c08892321039809672d1e45b7" + } + }, + "0xcdA097909053fB8Ccd5e7539408604688baBA6E5": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100c95760003560e01c8063c011b1c311610081578063ea7215691161005b578063ea72156914610215578063f2fde38b1461021d578063f6a74ed714610250576100c9565b8063c011b1c31461018a578063c4faf7df146101bd578063cbf2b8bf146101f8576100c9565b80637c6b8ef5116100b25780637c6b8ef5146101345780638da5cb5b146101515780639398608b14610182576100c9565b806333db2ad2146100ce578063542fef91146100ff575b600080fd5b6100eb600480360360208110156100e457600080fd5b5035610283565b604080519115158252519081900360200190f35b6101326004803603602081101561011557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610573565b005b6100eb6004803603602081101561014a57600080fd5b5035610687565b61015961098b565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6101596109a7565b610159600480360360208110156101a057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166109c3565b610132600480360360408110156101d357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166109ee565b6100eb6004803603602081101561020e57600080fd5b5035610bc8565b6100eb610cb5565b6101326004803603602081101561023357600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610e2b565b6101326004803603602081101561026657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610f7e565b3360009081526001602052604081205473ffffffffffffffffffffffffffffffffffffffff166102fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001806113dc6035913960400191505060405180910390fd5b60008211610357576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180611411602a913960400191505060405180910390fd5b336000908152600160209081526040918290205460025483517faa271e1a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482018190529451929091169263aa271e1a92602480840193829003018186803b1580156103d957600080fd5b505afa1580156103ed573d6000803e3d6000fd5b505050506040513d602081101561040357600080fd5b505161045a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603981526020018061143b6039913960400191505060405180910390fd5b600254604080517f8a6db9c300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015291516000939290921691638a6db9c391602480820192602092909190829003018186803b1580156104d157600080fd5b505afa1580156104e5573d6000803e3d6000fd5b505050506040513d60208110156104fb57600080fd5b50519050600061050b8286611161565b6040805187815260208101839052815192935073ffffffffffffffffffffffffffffffffffffffff86169233927f3703d23abba1e61f32acc0682fc062ea5c710672c7d100af5ecd08485e983ad0928290030190a361056a83826111d5565b95945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105f957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60025460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f9992ea32e96992be98be5c833cd5b9fd77314819d2146b6f06ab9cfef957af1290600090a3600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b3360009081526001602052604081205473ffffffffffffffffffffffffffffffffffffffff16610702576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001806113dc6035913960400191505060405180910390fd5b6000821161075b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180611346602a913960400191505060405180910390fd5b336000908152600160209081526040918290205460025483517faa271e1a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482018190529451929091169263aa271e1a92602480840193829003018186803b1580156107dd57600080fd5b505afa1580156107f1573d6000803e3d6000fd5b505050506040513d602081101561080757600080fd5b505161085e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260398152602001806114746039913960400191505060405180910390fd5b600254604080517f8a6db9c300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015291516000939290921691638a6db9c391602480820192602092909190829003018186803b1580156108d557600080fd5b505afa1580156108e9573d6000803e3d6000fd5b505050506040513d60208110156108ff57600080fd5b5051905060008482116109125781610914565b845b905060006109228383611287565b6040805184815260208101839052815192935073ffffffffffffffffffffffffffffffffffffffff87169233927f3cc75d3bf58b0100659088c03539964108d5d06342e1bd8085ee43ad8ff6f69a928290030190a361098184826111d5565b9695505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b60025473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff9081166000908152600160205260409020541690565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a7457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8216610ae0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806113706025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610b4c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806113bb6021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82811660008181526001602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169486169485179055517fa56687ff5096e83f6e2c673cda0b677f56bbfcdf5fe0555d5830c407ede193cb9190a35050565b3360009081526001602052604081205473ffffffffffffffffffffffffffffffffffffffff16610c43576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001806113dc6035913960400191505060405180910390fd5b33600081815260016020908152604091829020548251868152925173ffffffffffffffffffffffffffffffffffffffff90911693849390927f5b0b60a4f757b33d9dcb8bd021b6aa371bb2e6f134086797aefcd8c0afab538c92918290030190a3610cae81846111d5565b9392505050565b3360009081526001602052604081205473ffffffffffffffffffffffffffffffffffffffff16610d30576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260358152602001806113dc6035913960400191505060405180910390fd5b3360008181526001602052604080822054905173ffffffffffffffffffffffffffffffffffffffff90911692839290917f4b5ef9a786cf64a7d82ebcf2d5132667edc9faef4ac36260d9a9e52c526b62329190a3600254604080517f3092afd500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015291519190921691633092afd59160248083019260209291908290030181600087803b158015610df957600080fd5b505af1158015610e0d573d6000803e3d6000fd5b505050506040513d6020811015610e2357600080fd5b505191505090565b60005473ffffffffffffffffffffffffffffffffffffffff163314610eb157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116610f1d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806113956026913960400191505060405180910390fd5b6000546040805173ffffffffffffffffffffffffffffffffffffffff9283168152918316602083015280517f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09281900390910190a1610f7b816112fe565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461100457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116611070576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806113706025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff818116600090815260016020526040902054166110ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806113bb6021913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811660008181526001602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055517f33d83959be2573f5453b12eb9d43b3499bc57d96bd2f067ba44803c859e811139190a250565b600082820183811015610cae57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600254604080517f4e44d95600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301526024820185905291516000939290921691634e44d9569160448082019260209290919082900301818787803b15801561125457600080fd5b505af1158015611268573d6000803e3d6000fd5b505050506040513d602081101561127e57600080fd5b50519392505050565b6000828211156112f857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905556fe416c6c6f77616e63652064656372656d656e74206d7573742062652067726561746572207468616e2030436f6e74726f6c6c6572206d7573742062652061206e6f6e2d7a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373576f726b6572206d7573742062652061206e6f6e2d7a65726f20616464726573735468652076616c7565206f6620636f6e74726f6c6c6572735b6d73672e73656e6465725d206d757374206265206e6f6e2d7a65726f416c6c6f77616e636520696e6372656d656e74206d7573742062652067726561746572207468616e203043616e206f6e6c7920696e6372656d656e7420616c6c6f77616e636520666f72206d696e7465727320696e206d696e7465724d616e6167657243616e206f6e6c792064656372656d656e7420616c6c6f77616e636520666f72206d696e7465727320696e206d696e7465724d616e61676572a2646970667358221220d77805bc1cda0d3a579277ceaf1a7a219b57ac3d01ee1948f34fea02402be1a264736f6c634300060c0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000006b3ff43c7317308517b8786feade35ee0e7fdf99", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000b8bc5e60ee10957e0d1a0d95598fa63e65605e2", + "0x4d4d5fb439985198036e545ddc439b111b0c6318d866bcca2d7b296229c51a23": "0x000000000000000000000000b043bdd3d91376a76078c361bb82496fdb809ae2" + } + }, + "0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44": { + "balance": "0x0", + "code": "0x6060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x5772617070656420555344000000000000000000000000000000000000000016", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x5755534400000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000012" + } + }, + "0x4e59b44847b379578588920cA78FbF26c0B4956C": { + "balance": "0x0", + "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" + } + }, + "baseFeePerGas": "0x3b9aca00", + "excessBlobGas": null, + "blobGasUsed": null, + "number": null +} diff --git a/crates/genesis/src/pecorino.genesis.json b/crates/genesis/src/pecorino.genesis.json new file mode 100644 index 0000000..235f1a7 --- /dev/null +++ b/crates/genesis/src/pecorino.genesis.json @@ -0,0 +1,143 @@ +{ + "config": { + "chainId": 14174, + "homesteadBlock": "0x0", + "daoForkBlock": "0x0", + "daoForkSupport": false, + "eip150Block": "0x0", + "eip150Hash": null, + "eip155Block": "0x0", + "eip158Block": "0x0", + "byzantiumBlock": "0x0", + "constantinopleBlock": "0x0", + "petersburgBlock": "0x0", + "istanbulBlock": "0x0", + "muirGlacierBlock": "0x0", + "berlinBlock": "0x0", + "londonBlock": "0x0", + "arrowGlacierBlock": "0x0", + "grayGlacierBlock": "0x0", + "mergeNetsplitBlock": "0x0", + "shanghaiTime": "0x0", + "cancunTime": "0x0", + "pragueTime": "0x2623A", + "terminalTotalDifficulty": null, + "terminalTotalDifficultyPassed": false, + "ethash": null, + "clique": null, + "parlia": null, + "signetConstants": { + "host": { + "chainId": 3151908, + "deployHeight": 366, + "zenith": "0xf17E98baF73F7C78a42D73DF4064de5B7A20EcA6", + "orders": "0x0A4f505364De0Aa46c66b15aBae44eBa12ab0380", + "passage": "0x12585352AA1057443D6163B539EfD4487f023182", + "transactor": "0x3903279B59D3F5194053dA8d1f0C7081C8892Ce4", + "tokens": { + "usds": [ + { + "ticker": "USDC", + "decimals": 6, + "address": "0x65fb255585458de1f9a246b476aa8d5c5516f6fd" + }, + { + "ticker": "USDT", + "decimals": 6, + "address": "0xb9df1b911b6cf6935b2a918ba03df2372e94e267" + } + ], + "wbtc": "0xfb29f7d7a4ce607d6038d44150315e5f69bea08a", + "weth": "0xd03d085B78067A18155d3B29D64914df3D19A53C" + } + }, + "rollup": { + "chainId": 14174, + "orders": "0x000000000000007369676e65742d6f7264657273", + "passage": "0x0000000000007369676e65742d70617373616765", + "baseFeeRecipient": "0xe0eDA3701D44511ce419344A4CeD30B52c9Ba231", + "tokens": { + "wbtc": "0x0000000000000000007369676e65742d77627463", + "weth": "0x0000000000000000007369676e65742d77657468" + } + } + }, + "extraFields": {}, + "depositContractAddress": null + }, + "nonce": "0x0", + "timestamp": "0x0", + "extraData": "0x", + "gasLimit": "0x1c9c380", + "difficulty": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02": { + "balance": "0x0", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500" + }, + "0x000000000022D473030F116dDEE9F6B43aC78BA3": { + "balance": "0x0", + "code": "0x6040608081526004908136101561001557600080fd5b600090813560e01c80630d58b1db1461126c578063137c29fe146110755780632a2d80d114610db75780632b67b57014610bde57806330f28b7a14610ade5780633644e51514610a9d57806336c7851614610a285780633ff9dcb1146109a85780634fe02b441461093f57806365d9723c146107ac57806387517c451461067a578063927da105146105c3578063cc53287f146104a3578063edd9444b1461033a5763fe8ec1a7146100c657600080fd5b346103365760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff833581811161033257610114903690860161164b565b60243582811161032e5761012b903690870161161a565b6101336114e6565b9160843585811161032a5761014b9036908a016115c1565b98909560a43590811161032657610164913691016115c1565b969095815190610173826113ff565b606b82527f5065726d697442617463685769746e6573735472616e7366657246726f6d285460208301527f6f6b656e5065726d697373696f6e735b5d207065726d69747465642c61646472838301527f657373207370656e6465722c75696e74323536206e6f6e63652c75696e74323560608301527f3620646561646c696e652c000000000000000000000000000000000000000000608083015282519a8b9181610222602085018096611f93565b918237018a8152039961025b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09b8c8101835282611437565b5190209085515161026b81611ebb565b908a5b8181106102f95750506102f6999a6102ed9183516102a081610294602082018095611f66565b03848101835282611437565b519020602089810151858b015195519182019687526040820192909252336060820152608081019190915260a081019390935260643560c08401528260e081015b03908101835282611437565b51902093611cf7565b80f35b8061031161030b610321938c5161175e565b51612054565b61031b828661175e565b52611f0a565b61026e565b8880fd5b8780fd5b8480fd5b8380fd5b5080fd5b5091346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103365767ffffffffffffffff9080358281116103325761038b903690830161164b565b60243583811161032e576103a2903690840161161a565b9390926103ad6114e6565b9160643590811161049f576103c4913691016115c1565b949093835151976103d489611ebb565b98885b81811061047d5750506102f697988151610425816103f9602082018095611f66565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282611437565b5190206020860151828701519083519260208401947ffcf35f5ac6a2c28868dc44c302166470266239195f02b0ee408334829333b7668652840152336060840152608083015260a082015260a081526102ed8161141b565b808b61031b8261049461030b61049a968d5161175e565b9261175e565b6103d7565b8680fd5b5082346105bf57602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103325780359067ffffffffffffffff821161032e576104f49136910161161a565b929091845b848110610504578580f35b8061051a610515600193888861196c565b61197c565b61052f84610529848a8a61196c565b0161197c565b3389528385528589209173ffffffffffffffffffffffffffffffffffffffff80911692838b528652868a20911690818a5285528589207fffffffffffffffffffffffff000000000000000000000000000000000000000081541690558551918252848201527f89b1add15eff56b3dfe299ad94e01f2b52fbcb80ae1a3baea6ae8c04cb2b98a4853392a2016104f9565b8280fd5b50346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610676816105ff6114a0565b936106086114c3565b6106106114e6565b73ffffffffffffffffffffffffffffffffffffffff968716835260016020908152848420928816845291825283832090871683528152919020549251938316845260a083901c65ffffffffffff169084015260d09190911c604083015281906060820190565b0390f35b50346103365760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336576106b26114a0565b906106bb6114c3565b916106c46114e6565b65ffffffffffff926064358481169081810361032a5779ffffffffffff0000000000000000000000000000000000000000947fda9fa7c1b00402c17d0161b249b1ab8bbec047c5a52207b9c112deffd817036b94338a5260016020527fffffffffffff0000000000000000000000000000000000000000000000000000858b209873ffffffffffffffffffffffffffffffffffffffff809416998a8d5260205283878d209b169a8b8d52602052868c209486156000146107a457504216925b8454921697889360a01b16911617179055815193845260208401523392a480f35b905092610783565b5082346105bf5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576107e56114a0565b906107ee6114c3565b9265ffffffffffff604435818116939084810361032a57338852602091600183528489209673ffffffffffffffffffffffffffffffffffffffff80911697888b528452858a20981697888a5283528489205460d01c93848711156109175761ffff9085840316116108f05750907f55eb90d810e1700b35a8e7e25395ff7f2b2259abd7415ca2284dfb1c246418f393929133895260018252838920878a528252838920888a5282528389209079ffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffff000000000000000000000000000000000000000000000000000083549260d01b16911617905582519485528401523392a480f35b84517f24d35a26000000000000000000000000000000000000000000000000000000008152fd5b5084517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b503461033657807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610336578060209273ffffffffffffffffffffffffffffffffffffffff61098f6114a0565b1681528084528181206024358252845220549051908152f35b5082346105bf57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf577f3704902f963766a4e561bbaab6e6cdc1b1dd12f6e9e99648da8843b3f46b918d90359160243533855284602052818520848652602052818520818154179055815193845260208401523392a280f35b8234610a9a5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610a9a57610a606114a0565b610a686114c3565b610a706114e6565b6064359173ffffffffffffffffffffffffffffffffffffffff8316830361032e576102f6936117a1565b80fd5b503461033657817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657602090610ad7611b1e565b9051908152f35b508290346105bf576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf57610b1a3661152a565b90807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c36011261033257610b4c611478565b9160e43567ffffffffffffffff8111610bda576102f694610b6f913691016115c1565b939092610b7c8351612054565b6020840151828501519083519260208401947f939c21a48a8dbe3a9a2404a1d46691e4d39f6583d6ec6b35714604c986d801068652840152336060840152608083015260a082015260a08152610bd18161141b565b51902091611c25565b8580fd5b509134610336576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033657610c186114a0565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc360160c08112610332576080855191610c51836113e3565b1261033257845190610c6282611398565b73ffffffffffffffffffffffffffffffffffffffff91602435838116810361049f578152604435838116810361049f57602082015265ffffffffffff606435818116810361032a5788830152608435908116810361049f576060820152815260a435938285168503610bda576020820194855260c4359087830182815260e43567ffffffffffffffff811161032657610cfe90369084016115c1565b929093804211610d88575050918591610d786102f6999a610d7e95610d238851611fbe565b90898c511690519083519260208401947ff3841cd1ff0085026a6327b620b67997ce40f282c88a8e905a7a5626e310f3d086528401526060830152608082015260808152610d70816113ff565b519020611bd9565b916120c7565b519251169161199d565b602492508a51917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b5091346103365760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc93818536011261033257610df36114a0565b9260249081359267ffffffffffffffff9788851161032a578590853603011261049f578051978589018981108282111761104a578252848301358181116103265785019036602383011215610326578382013591610e50836115ef565b90610e5d85519283611437565b838252602093878584019160071b83010191368311611046578801905b828210610fe9575050508a526044610e93868801611509565b96838c01978852013594838b0191868352604435908111610fe557610ebb90369087016115c1565b959096804211610fba575050508998995151610ed681611ebb565b908b5b818110610f9757505092889492610d7892610f6497958351610f02816103f98682018095611f66565b5190209073ffffffffffffffffffffffffffffffffffffffff9a8b8b51169151928551948501957faf1b0d30d2cab0380e68f0689007e3254993c596f2fdd0aaa7f4d04f794408638752850152830152608082015260808152610d70816113ff565b51169082515192845b848110610f78578580f35b80610f918585610f8b600195875161175e565b5161199d565b01610f6d565b80610311610fac8e9f9e93610fb2945161175e565b51611fbe565b9b9a9b610ed9565b8551917fcd21db4f000000000000000000000000000000000000000000000000000000008352820152fd5b8a80fd5b6080823603126110465785608091885161100281611398565b61100b85611509565b8152611018838601611509565b838201526110278a8601611607565b8a8201528d611037818701611607565b90820152815201910190610e7a565b8c80fd5b84896041867f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b5082346105bf576101407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126105bf576110b03661152a565b91807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c360112610332576110e2611478565b67ffffffffffffffff93906101043585811161049f5761110590369086016115c1565b90936101243596871161032a57611125610bd1966102f6983691016115c1565b969095825190611134826113ff565b606482527f5065726d69745769746e6573735472616e7366657246726f6d28546f6b656e5060208301527f65726d697373696f6e73207065726d69747465642c6164647265737320737065848301527f6e6465722c75696e74323536206e6f6e63652c75696e7432353620646561646c60608301527f696e652c0000000000000000000000000000000000000000000000000000000060808301528351948591816111e3602085018096611f93565b918237018b8152039361121c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095868101835282611437565b5190209261122a8651612054565b6020878101518589015195519182019687526040820192909252336060820152608081019190915260a081019390935260e43560c08401528260e081016102e1565b5082346105bf576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261033257813567ffffffffffffffff92838211610bda5736602383011215610bda5781013592831161032e576024906007368386831b8401011161049f57865b8581106112e5578780f35b80821b83019060807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc83360301126103265761139288876001946060835161132c81611398565b611368608461133c8d8601611509565b9485845261134c60448201611509565b809785015261135d60648201611509565b809885015201611509565b918291015273ffffffffffffffffffffffffffffffffffffffff80808093169516931691166117a1565b016112da565b6080810190811067ffffffffffffffff8211176113b457604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6060810190811067ffffffffffffffff8211176113b457604052565b60a0810190811067ffffffffffffffff8211176113b457604052565b60c0810190811067ffffffffffffffff8211176113b457604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176113b457604052565b60c4359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b6044359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361149b57565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01906080821261149b576040805190611563826113e3565b8082941261149b57805181810181811067ffffffffffffffff8211176113b457825260043573ffffffffffffffffffffffffffffffffffffffff8116810361149b578152602435602082015282526044356020830152606435910152565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020838186019501011161149b57565b67ffffffffffffffff81116113b45760051b60200190565b359065ffffffffffff8216820361149b57565b9181601f8401121561149b5782359167ffffffffffffffff831161149b576020808501948460061b01011161149b57565b91909160608184031261149b576040805191611666836113e3565b8294813567ffffffffffffffff9081811161149b57830182601f8201121561149b578035611693816115ef565b926116a087519485611437565b818452602094858086019360061b8501019381851161149b579086899897969594939201925b8484106116e3575050505050855280820135908501520135910152565b90919293949596978483031261149b578851908982019082821085831117611730578a928992845261171487611509565b81528287013583820152815201930191908897969594936116c6565b602460007f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b80518210156117725760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b92919273ffffffffffffffffffffffffffffffffffffffff604060008284168152600160205282828220961695868252602052818120338252602052209485549565ffffffffffff8760a01c16804211611884575082871696838803611812575b5050611810955016926118b5565b565b878484161160001461184f57602488604051907ff96fb0710000000000000000000000000000000000000000000000000000000082526004820152fd5b7fffffffffffffffffffffffff000000000000000000000000000000000000000084846118109a031691161790553880611802565b602490604051907fd81b2f2e0000000000000000000000000000000000000000000000000000000082526004820152fd5b9060006064926020958295604051947f23b872dd0000000000000000000000000000000000000000000000000000000086526004860152602485015260448401525af13d15601f3d116001600051141617161561190e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c45440000000000000000000000006044820152fd5b91908110156117725760061b0190565b3573ffffffffffffffffffffffffffffffffffffffff8116810361149b5790565b9065ffffffffffff908160608401511673ffffffffffffffffffffffffffffffffffffffff908185511694826020820151169280866040809401511695169560009187835260016020528383208984526020528383209916988983526020528282209184835460d01c03611af5579185611ace94927fc6a377bfc4eb120024a8ac08eef205be16b817020812c73223e81d1bdb9708ec98979694508715600014611ad35779ffffffffffff00000000000000000000000000000000000000009042165b60a01b167fffffffffffff00000000000000000000000000000000000000000000000000006001860160d01b1617179055519384938491604091949373ffffffffffffffffffffffffffffffffffffffff606085019616845265ffffffffffff809216602085015216910152565b0390a4565b5079ffffffffffff000000000000000000000000000000000000000087611a60565b600484517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b467f000000000000000000000000000000000000000000000000000000000000426903611b69577fbad4b5495ed53a4eb2d34dff3b0f78ec4fb5e14cc66295254a6d3d9afe35781590565b60405160208101907f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86682527f9ac997416e8ff9d2ff6bebeb7149f65cdae5e32e2b90440b566bb3044041d36a604082015246606082015230608082015260808152611bd3816113ff565b51902090565b611be1611b1e565b906040519060208201927f190100000000000000000000000000000000000000000000000000000000000084526022830152604282015260428152611bd381611398565b9192909360a435936040840151804211611cc65750602084510151808611611c955750918591610d78611c6594611c60602088015186611e47565b611bd9565b73ffffffffffffffffffffffffffffffffffffffff809151511692608435918216820361149b57611810936118b5565b602490604051907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b602490604051907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b959093958051519560409283830151804211611e175750848803611dee57611d2e918691610d7860209b611c608d88015186611e47565b60005b868110611d42575050505050505050565b611d4d81835161175e565b5188611d5a83878a61196c565b01359089810151808311611dbe575091818888886001968596611d84575b50505050505001611d31565b611db395611dad9273ffffffffffffffffffffffffffffffffffffffff6105159351169561196c565b916118b5565b803888888883611d78565b6024908651907f3728b83d0000000000000000000000000000000000000000000000000000000082526004820152fd5b600484517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b6024908551907fcd21db4f0000000000000000000000000000000000000000000000000000000082526004820152fd5b9073ffffffffffffffffffffffffffffffffffffffff600160ff83161b9216600052600060205260406000209060081c6000526020526040600020818154188091551615611e9157565b60046040517f756688fe000000000000000000000000000000000000000000000000000000008152fd5b90611ec5826115ef565b611ed26040519182611437565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611f0082946115ef565b0190602036910137565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611f375760010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b805160208092019160005b828110611f7f575050505090565b835185529381019392810192600101611f71565b9081519160005b838110611fab575050016000815290565b8060208092840101518185015201611f9a565b60405160208101917f65626cad6cb96493bf6f5ebea28756c966f023ab9e8a83a7101849d5573b3678835273ffffffffffffffffffffffffffffffffffffffff8082511660408401526020820151166060830152606065ffffffffffff9182604082015116608085015201511660a082015260a0815260c0810181811067ffffffffffffffff8211176113b45760405251902090565b6040516020808201927f618358ac3db8dc274f0cd8829da7e234bd48cd73c4a740aede1adec9846d06a1845273ffffffffffffffffffffffffffffffffffffffff81511660408401520151606082015260608152611bd381611398565b919082604091031261149b576020823592013590565b6000843b61222e5750604182036121ac576120e4828201826120b1565b939092604010156117725760209360009360ff6040608095013560f81c5b60405194855216868401526040830152606082015282805260015afa156121a05773ffffffffffffffffffffffffffffffffffffffff806000511691821561217657160361214c57565b60046040517f815e1d64000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8baa579f000000000000000000000000000000000000000000000000000000008152fd5b6040513d6000823e3d90fd5b60408203612204576121c0918101906120b1565b91601b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84169360ff1c019060ff8211611f375760209360009360ff608094612102565b60046040517f4be6321b000000000000000000000000000000000000000000000000000000008152fd5b929391601f928173ffffffffffffffffffffffffffffffffffffffff60646020957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0604051988997889687947f1626ba7e000000000000000000000000000000000000000000000000000000009e8f8752600487015260406024870152816044870152868601378b85828601015201168101030192165afa9081156123a857829161232a575b507fffffffff000000000000000000000000000000000000000000000000000000009150160361230057565b60046040517fb0669cbc000000000000000000000000000000000000000000000000000000008152fd5b90506020813d82116123a0575b8161234460209383611437565b810103126103365751907fffffffff0000000000000000000000000000000000000000000000000000000082168203610a9a57507fffffffff0000000000000000000000000000000000000000000000000000000090386122d4565b3d9150612337565b6040513d84823e3d90fdfea164736f6c6343000811000a" + }, + "0x0000000000007369676e65742d70617373616765": { + "balance": "0x0", + "code": "0x60806040526004361061004d575f3560e01c80633930e39114610066578063685114a21461009b578063b269a425146100ba578063b42652e9146100d9578063eba1f981146100ec5761005d565b3661005d5761005b3361010b565b005b61005b3361010b565b348015610071575f80fd5b5061008561008036600461076c565b61015b565b60405161009291906107c4565b60405180910390f35b3480156100a6575f80fd5b5061005b6100b53660046107f0565b61021a565b3480156100c5575f80fd5b5061005b6100d436600461082a565b61024f565b61005b6100e736600461087b565b61010b565b3480156100f7575f80fd5b5061008561010636600461087b565b610290565b345f036101155750565b806001600160a01b03167f22d324652c93739755cf4581508b60875ebdd78c20c0cff5cf8e23452b2996313460405161015091815260200190565b60405180910390a250565b604080518082019091525f8152606060208201527fc5d03356b54a64d088070694ab907941e70a5ea4ae772ff6df7f162d054037b66040518060400160405280858152602001846001600160a01b03168152506040516020016101de929190918252805160208084019190915201516001600160a01b0316604082015260600190565b60408051601f1981840301815291815281516020928301208352805160a08101909152607e80825290916109db90830139602082015292915050565b610222610338565b6102376001600160a01b0383163330846103a7565b610242838383610407565b61024a6104ba565b505050565b610257610338565b61026961026383610290565b826104e4565b6102848261027a602084018461087b565b6020840135610407565b61028c6104ba565b5050565b604080518082019091525f81526060602082015260408051602080820183526001600160a01b038516825291516102fd927fa91a2bac0243280e19cfd0a3ae9d7639a15fa41d49eab3e0bf320c8485cc66a9929101918252516001600160a01b0316602082015260400190565b60408051601f1981840301815291815281516020928301208352805160a0810190915260648082529091610a59908301396020820152919050565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005c1561037857604051633ee5aeb560e01b815260040160405180910390fd5b6103a560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b906105ab565b565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b1790526104019085906105b2565b50505050565b805f0361041357505050565b604051630852cd8d60e31b8152600481018290526001600160a01b038316906342966c68906024015f604051808303815f87803b158015610452575f80fd5b505af1158015610464573d5f803e3d5ffd5b50505050816001600160a01b0316836001600160a01b03167f4203bbd8ffd310b1341275d3ad6597e60a1ab2843f84e28c79e88d6f5da1c94d836040516104ad91815260200190565b60405180910390a3505050565b6103a55f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0061039f565b6001600160a01b037f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba31663137c29fe82610534602082013560408051808201909152308152602081019190915290565b61054460a086016080870161087b565b8651602088015161055860a0890189610894565b6040518863ffffffff1660e01b815260040161057a9796959493929190610906565b5f604051808303815f87803b158015610591575f80fd5b505af11580156105a3573d5f803e3d5ffd5b505050505050565b80825d5050565b5f6105c66001600160a01b03841683610618565b905080515f141580156105ea5750808060200190518101906105e891906109a5565b155b1561024a57604051635274afe760e01b81526001600160a01b03841660048201526024015b60405180910390fd5b606061062583835f61062c565b9392505050565b6060814710156106585760405163cf47918160e01b81524760048201526024810183905260440161060f565b5f80856001600160a01b0316848660405161067391906109c4565b5f6040518083038185875af1925050503d805f81146106ad576040519150601f19603f3d011682016040523d82523d5f602084013e6106b2565b606091505b50915091506106c28683836106cc565b9695505050505050565b6060826106e1576106dc82610728565b610625565b81511580156106f857506001600160a01b0384163b155b1561072157604051639996b31560e01b81526001600160a01b038516600482015260240161060f565b5080610625565b8051156107385780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b80356001600160a01b0381168114610767575f80fd5b919050565b5f806040838503121561077d575f80fd5b8235915061078d60208401610751565b90509250929050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60208152815160208201525f60208301516040808401526107e86060840182610796565b949350505050565b5f805f60608486031215610802575f80fd5b61080b84610751565b925061081960208501610751565b929592945050506040919091013590565b5f806040838503121561083b575f80fd5b61084483610751565b9150602083013567ffffffffffffffff81111561085f575f80fd5b830160c08186031215610870575f80fd5b809150509250929050565b5f6020828403121561088b575f80fd5b61062582610751565b5f808335601e198436030181126108a9575f80fd5b83018035915067ffffffffffffffff8211156108c3575f80fd5b6020019150368190038213156108d7575f80fd5b9250929050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b6001600160a01b0361091789610751565b168152602088810135818301526040808a0135908301526060808a01359083015287516001600160a01b0316608083015287015160a08201525f61096660c08301886001600160a01b03169052565b8560e0830152610140610100830152610983610140830186610796565b8281036101208401526109978185876108de565b9a9950505050505050505050565b5f602082840312156109b5575f80fd5b81518015158114610625575f80fd5b5f82518060208501845e5f92019182525091905056fe456e7465725769746e657373207769746e65737329456e7465725769746e6573732875696e7432353620726f6c6c7570436861696e49642c6164647265737320726f6c6c7570526563697069656e7429546f6b656e5065726d697373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f756e7429457869745769746e657373207769746e65737329457869745769746e657373286164647265737320686f7374526563697069656e7429546f6b656e5065726d697373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f756e7429a2646970667358221220a82b6f2ece68ba16cfccd79784985d20b0e5014e516fcd73930a3c56f491887b64736f6c634300081a0033" + }, + "0x000000000000007369676e65742d6f7264657273": { + "balance": "0x0", + "code": "0x608060405260043610610054575f3560e01c80630828f139146100585780631bbf03a81461008d57806362c06767146100ae578063897bc0d6146100cd5780639181004e146100e0578063f9c50441146100ff575b5f80fd5b348015610063575f80fd5b50610077610072366004610fe9565b610112565b6040516100849190611050565b60405180910390f35b348015610098575f80fd5b506100ac6100a736600461108a565b61024e565b005b3480156100b9575f80fd5b506100ac6100c83660046110ed565b6102c8565b6100ac6100db366004610fe9565b610364565b3480156100eb575f80fd5b506100ac6100fa366004611127565b6103b7565b6100ac61010d366004611199565b610453565b604080518082019091525f81526060602082015281515f816001600160401b0381111561014157610141610e5c565b60405190808252806020026020018201604052801561016a578160200160208202803683370190505b5090505f5b828110156101fe577f988262d9186cf8a1cd1dd5e2cc7bfa353f55a542d86db1fcd06e076a6544250d8582815181106101aa576101aa61127d565b60200260200101516040516020016101c39291906112c8565b604051602081830303815290604052805190602001208282815181106101eb576101eb61127d565b602090810291909101015260010161016f565b508060405160200161021091906112dc565b60408051601f1981840301815291815281516020928301208552805160c081019091526084808252909161168f908301396020840152509092915050565b6102566104b8565b61028561026283610112565b61027f846102708580611311565b61027a908061132f565b610527565b83610709565b7f14b3027353aba71f468d178fdede9ac211a25ae484028823bce1e6700e58e624826040516102b491906113c0565b60405180910390a16102c46107bb565b5050565b6102d06104b8565b6001600160a01b0382166102f6576102f16001600160a01b038416826107e5565b61030a565b61030a6001600160a01b0383168483610884565b816001600160a01b0316836001600160a01b03167fed679328aebf74ede77ae09efcf36e90244f83643dadac1c2d9f0b21a46f6ab78360405161034f91815260200190565b60405180910390a361035f6107bb565b505050565b61036c6104b8565b610375816108e3565b7f14b3027353aba71f468d178fdede9ac211a25ae484028823bce1e6700e58e624816040516103a491906113c0565b60405180910390a16103b46107bb565b50565b6103bf6104b8565b6103e86103cb83610112565b61027f856103d98580611311565b6103e3908061132f565b610a28565b7f80c9b8738a5ff299b770efb55e4372a5fc655294aca7145b3c529c2d89732d626104138280611311565b604001356104336104248480611311565b61042e908061132f565b610af1565b84604051610443939291906113d2565b60405180910390a161035f6107bb565b61045b6104b8565b8242111561047c576040516362b439dd60e11b815260040160405180910390fd5b61048582610be8565b7f80c9b8738a5ff299b770efb55e4372a5fc655294aca7145b3c529c2d89732d62838383604051610443939291906113d2565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005c156104f857604051633ee5aeb560e01b815260040160405180910390fd5b61052560017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f005b90610c78565b565b8251606090821461054e576040516001621398b960e31b0319815260040160405180910390fd5b816001600160401b0381111561056657610566610e5c565b6040519080825280602002602001820160405280156105aa57816020015b604080518082019091525f80825260208201528152602001906001900390816105845790505b5090505f5b82811015610701578481815181106105c9576105c961127d565b60200260200101515f01516001600160a01b03168484838181106105ef576105ef61127d565b6106059260206040909202019081019150611450565b6001600160a01b03161461062c57604051635f670cf360e11b815260040160405180910390fd5b84818151811061063e5761063e61127d565b60200260200101516020015184848381811061065c5761065c61127d565b905060400201602001351461068457604051635f670cf360e11b815260040160405180910390fd5b60405180604001604052808683815181106106a1576106a161127d565b6020026020010151604001516001600160a01b031681526020018683815181106106cd576106cd61127d565b6020026020010151602001518152508282815181106106ee576106ee61127d565b60209081029190910101526001016105af565b509392505050565b6001600160a01b037f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba31663fe8ec1a76107428380611311565b846107536040860160208701611450565b875160208901516107676040890189611469565b6040518863ffffffff1660e01b81526004016107899796959493929190611521565b5f604051808303815f87803b1580156107a0575f80fd5b505af11580156107b2573d5f803e3d5ffd5b50505050505050565b6105255f7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0061051f565b804710156108145760405163cf47918160e01b8152476004820152602481018290526044015b60405180910390fd5b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f811461085d576040519150601f19603f3d011682016040523d82523d5f602084013e610862565b606091505b505090508061035f5760405163d6bda27560e01b815260040160405180910390fd5b6040516001600160a01b0383811660248301526044820183905261035f91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050610c7f565b345f5b825181101561035f575f6001600160a01b031683828151811061090b5761090b61127d565b60200260200101515f01516001600160a01b0316036109aa578281815181106109365761093661127d565b6020026020010151602001518261094d919061163a565b91506109a58382815181106109645761096461127d565b6020026020010151602001518483815181106109825761098261127d565b6020026020010151604001516001600160a01b03166107e590919063ffffffff16565b610a20565b610a20338483815181106109c0576109c061127d565b6020026020010151604001518584815181106109de576109de61127d565b6020026020010151602001518685815181106109fc576109fc61127d565b60200260200101515f01516001600160a01b0316610ce0909392919063ffffffff16565b6001016108e6565b6060816001600160401b03811115610a4257610a42610e5c565b604051908082528060200260200182016040528015610a8657816020015b604080518082019091525f8082526020820152815260200190600190039081610a605790505b5090505f5b82811015610701576040518060400160405280866001600160a01b03168152602001858584818110610abf57610abf61127d565b90506040020160200135815250828281518110610ade57610ade61127d565b6020908102919091010152600101610a8b565b6060816001600160401b03811115610b0b57610b0b610e5c565b604051908082528060200260200182016040528015610b4f57816020015b604080518082019091525f8082526020820152815260200190600190039081610b295790505b5090505f5b82811015610be1576040518060400160405280858584818110610b7957610b7961127d565b610b8f9260206040909202019081019150611450565b6001600160a01b03168152602001858584818110610baf57610baf61127d565b90506040020160200135815250828281518110610bce57610bce61127d565b6020908102919091010152600101610b54565b5092915050565b345f5b825181101561035f575f6001600160a01b0316838281518110610c1057610c1061127d565b60200260200101515f01516001600160a01b031603610c5957828181518110610c3b57610c3b61127d565b60200260200101516020015182610c52919061163a565b9150610c70565b610c7033308584815181106109de576109de61127d565b600101610beb565b80825d5050565b5f610c936001600160a01b03841683610d1f565b905080515f14158015610cb7575080806020019051810190610cb59190611659565b155b1561035f57604051635274afe760e01b81526001600160a01b038416600482015260240161080b565b6040516001600160a01b038481166024830152838116604483015260648201839052610d199186918216906323b872dd906084016108b1565b50505050565b6060610d2c83835f610d35565b90505b92915050565b606081471015610d615760405163cf47918160e01b81524760048201526024810183905260440161080b565b5f80856001600160a01b03168486604051610d7c9190611678565b5f6040518083038185875af1925050503d805f8114610db6576040519150601f19603f3d011682016040523d82523d5f602084013e610dbb565b606091505b5091509150610dcb868383610dd7565b925050505b9392505050565b606082610dec57610de782610e33565b610dd0565b8151158015610e0357506001600160a01b0384163b155b15610e2c57604051639996b31560e01b81526001600160a01b038516600482015260240161080b565b5080610dd0565b805115610e435780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b634e487b7160e01b5f52604160045260245ffd5b604051608081016001600160401b0381118282101715610e9257610e92610e5c565b60405290565b604080519081016001600160401b0381118282101715610e9257610e92610e5c565b604051601f8201601f191681016001600160401b0381118282101715610ee257610ee2610e5c565b604052919050565b5f6001600160401b03821115610f0257610f02610e5c565b5060051b60200190565b80356001600160a01b0381168114610f22575f80fd5b919050565b5f82601f830112610f36575f80fd5b8135610f49610f4482610eea565b610eba565b8082825260208201915060208360071b860101925085831115610f6a575f80fd5b602085015b83811015610fdf5760808188031215610f86575f80fd5b610f8e610e70565b610f9782610f0c565b815260208281013590820152610faf60408301610f0c565b6040820152606082013563ffffffff81168114610fca575f80fd5b60608201528352602090920191608001610f6f565b5095945050505050565b5f60208284031215610ff9575f80fd5b81356001600160401b0381111561100e575f80fd5b61101a84828501610f27565b949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60208152815160208201525f602083015160408084015261101a6060840182611022565b5f60608284031215611084575f80fd5b50919050565b5f806040838503121561109b575f80fd5b82356001600160401b038111156110b0575f80fd5b6110bc85828601610f27565b92505060208301356001600160401b038111156110d7575f80fd5b6110e385828601611074565b9150509250929050565b5f805f606084860312156110ff575f80fd5b61110884610f0c565b925061111660208501610f0c565b929592945050506040919091013590565b5f805f60608486031215611139575f80fd5b61114284610f0c565b925060208401356001600160401b0381111561115c575f80fd5b61116886828701610f27565b92505060408401356001600160401b03811115611183575f80fd5b61118f86828701611074565b9150509250925092565b5f805f606084860312156111ab575f80fd5b8335925060208401356001600160401b038111156111c7575f80fd5b8401601f810186136111d7575f80fd5b80356111e5610f4482610eea565b8082825260208201915060208360061b850101925088831115611206575f80fd5b6020840193505b82841015611254576040848a031215611224575f80fd5b61122c610e98565b61123585610f0c565b815260208581013581830152908352604090940193919091019061120d565b945050505060408401356001600160401b03811115611271575f80fd5b61118f86828701610f27565b634e487b7160e01b5f52603260045260245ffd5b80516001600160a01b039081168352602080830151908401526040808301519091169083015260609081015163ffffffff16910152565b82815260a08101610dd06020830184611291565b81515f90829060208501835b828110156113065781518452602093840193909101906001016112e8565b509195945050505050565b5f8235605e19833603018112611325575f80fd5b9190910192915050565b5f808335601e19843603018112611344575f80fd5b8301803591506001600160401b0382111561135d575f80fd5b6020019150600681901b3603821315611374575f80fd5b9250929050565b5f8151808452602084019350602083015f5b828110156113b6576113a0868351611291565b608095909501946020919091019060010161138d565b5093949350505050565b602081525f610d2c602083018461137b565b5f60608201858352606060208401528085518083526080850191506020870192505f5b818110156114315761141b83855180516001600160a01b03168252602090810151910152565b60209390930192604092909201916001016113f5565b50508381036040850152611445818661137b565b979650505050505050565b5f60208284031215611460575f80fd5b610d2c82610f0c565b5f808335601e1984360301811261147e575f80fd5b8301803591506001600160401b03821115611497575f80fd5b602001915036819003821315611374575f80fd5b5f8151808452602084019350602083015f5b828110156113b6576114e386835180516001600160a01b03168252602090810151910152565b60409590950194602091909101906001016114bd565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60c081525f61012082018935601e198b360301811261153e575f80fd5b8a016020810190356001600160401b03811115611559575f80fd5b8060061b360382131561156a575f80fd5b606060c086015291829052905f9061014085015b818310156115b7576001600160a01b0361159785610f0c565b16815260208481013590820152604093840193600193909301920161157e565b60208d81013560e088015260408e013561010088018190528783039188019190915293506115e5818d6114ab565b93505050506115ff60408401896001600160a01b03169052565b86606084015282810360808401526116178187611022565b905082810360a084015261162c8185876114f9565b9a9950505050505050505050565b81810381811115610d2f57634e487b7160e01b5f52601160045260245ffd5b5f60208284031215611669575f80fd5b81518015158114610dd0575f80fd5b5f82518060208501845e5f92019182525091905056fe4f75747075745b5d206f757470757473294f7574707574286164647265737320746f6b656e2c75696e7432353620616d6f756e742c6164647265737320726563697069656e742c75696e74333220636861696e496429546f6b656e5065726d697373696f6e73286164647265737320746f6b656e2c75696e7432353620616d6f756e7429a2646970667358221220322fe8b32453c17a0efd4f702e415163224990591aefcb85e698039547a4393764736f6c634300081a0033" + }, + "0x0000000000000000007369676e65742d77627463": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b50600436106100fb575f3560e01c806370a082311161009357806395d89b411161006357806395d89b4114610246578063a9059cbb1461024e578063dd62ed3e14610261578063f2fde38b14610299575f80fd5b806370a08231146101e8578063715018a61461021057806379cc6790146102185780638da5cb5b1461022b575f80fd5b8063313ce567116100ce578063313ce5671461016557806332424aa31461019957806340c10f19146101c057806342966c68146101d3575f80fd5b806306fdde03146100ff578063095ea7b31461011d57806318160ddd1461014057806323b872dd14610152575b5f80fd5b6101076102ac565b60405161011491906107f0565b60405180910390f35b61013061012b366004610840565b61033c565b6040519015158152602001610114565b6002545b604051908152602001610114565b610130610160366004610868565b610355565b7f00000000000000000000000000000000000000000000000000000000000000085b60405160ff9091168152602001610114565b6101877f000000000000000000000000000000000000000000000000000000000000000881565b6101306101ce366004610840565b610378565b6101e66101e13660046108a2565b610394565b005b6101446101f63660046108b9565b6001600160a01b03165f9081526020819052604090205490565b6101e66103a1565b6101e6610226366004610840565b6103b4565b6005546040516001600160a01b039091168152602001610114565b6101076103cd565b61013061025c366004610840565b6103dc565b61014461026f3660046108d9565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b6101e66102a73660046108b9565b6103e9565b6060600380546102bb9061090a565b80601f01602080910402602001604051908101604052809291908181526020018280546102e79061090a565b80156103325780601f1061030957610100808354040283529160200191610332565b820191905f5260205f20905b81548152906001019060200180831161031557829003601f168201915b5050505050905090565b5f33610349818585610428565b60019150505b92915050565b5f3361036285828561043a565b61036d8585856104b5565b506001949350505050565b5f610381610512565b61038b838361053f565b50600192915050565b61039e3382610573565b50565b6103a9610512565b6103b25f6105a7565b565b6103bf82338361043a565b6103c98282610573565b5050565b6060600480546102bb9061090a565b5f336103498185856104b5565b6103f1610512565b6001600160a01b03811661041f57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b61039e816105a7565b61043583838360016105f8565b505050565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981146104af57818110156104a157604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610416565b6104af84848484035f6105f8565b50505050565b6001600160a01b0383166104de57604051634b637e8f60e11b81525f6004820152602401610416565b6001600160a01b0382166105075760405163ec442f0560e01b81525f6004820152602401610416565b6104358383836106ca565b6005546001600160a01b031633146103b25760405163118cdaa760e01b8152336004820152602401610416565b6001600160a01b0382166105685760405163ec442f0560e01b81525f6004820152602401610416565b6103c95f83836106ca565b6001600160a01b03821661059c57604051634b637e8f60e11b81525f6004820152602401610416565b6103c9825f836106ca565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6001600160a01b0384166106215760405163e602df0560e01b81525f6004820152602401610416565b6001600160a01b03831661064a57604051634a1406b160e11b81525f6004820152602401610416565b6001600160a01b038085165f90815260016020908152604080832093871683529290522082905580156104af57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516106bc91815260200190565b60405180910390a350505050565b6001600160a01b0383166106f4578060025f8282546106e99190610942565b909155506107649050565b6001600160a01b0383165f90815260208190526040902054818110156107465760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610416565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b0382166107805760028054829003905561079e565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516107e391815260200190565b60405180910390a3505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461083b575f80fd5b919050565b5f8060408385031215610851575f80fd5b61085a83610825565b946020939093013593505050565b5f805f6060848603121561087a575f80fd5b61088384610825565b925061089160208501610825565b929592945050506040919091013590565b5f602082840312156108b2575f80fd5b5035919050565b5f602082840312156108c9575f80fd5b6108d282610825565b9392505050565b5f80604083850312156108ea575f80fd5b6108f383610825565b915061090160208401610825565b90509250929050565b600181811c9082168061091e57607f821691505b60208210810361093c57634e487b7160e01b5f52602260045260245ffd5b50919050565b8082018082111561034f57634e487b7160e01b5f52601160045260245ffdfea2646970667358221220a373554eb2e797644d86447291ab79350d58226b5edc56a67e2d820f602062bb64736f6c634300081a0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x5772617070656420425443000000000000000000000000000000000000000016", + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5742544300000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000000000000000000000000746f6b656e61646d696e" + } + }, + "0x0000000000000000007369676e65742d77657468": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b50600436106100fe575f3560e01c806370a082311161009557806395d89b411161006457806395d89b411461029a578063a9059cbb146102b8578063dd62ed3e146102e8578063f2fde38b14610318576100fe565b806370a0823114610226578063715018a61461025657806379cc6790146102605780638da5cb5b1461027c576100fe565b8063313ce567116100d1578063313ce5671461019e57806332424aa3146101bc57806340c10f19146101da57806342966c681461020a576100fe565b806306fdde0314610102578063095ea7b31461012057806318160ddd1461015057806323b872dd1461016e575b5f80fd5b61010a610334565b6040516101179190610f2c565b60405180910390f35b61013a60048036038101906101359190610fdd565b6103c4565b6040516101479190611035565b60405180910390f35b6101586103e6565b604051610165919061105d565b60405180910390f35b61018860048036038101906101839190611076565b6103ef565b6040516101959190611035565b60405180910390f35b6101a661041d565b6040516101b391906110e1565b60405180910390f35b6101c4610444565b6040516101d191906110e1565b60405180910390f35b6101f460048036038101906101ef9190610fdd565b610468565b6040516102019190611035565b60405180910390f35b610224600480360381019061021f91906110fa565b610485565b005b610240600480360381019061023b9190611125565b610499565b60405161024d919061105d565b60405180910390f35b61025e6104de565b005b61027a60048036038101906102759190610fdd565b6104f1565b005b610284610511565b604051610291919061115f565b60405180910390f35b6102a2610539565b6040516102af9190610f2c565b60405180910390f35b6102d260048036038101906102cd9190610fdd565b6105c9565b6040516102df9190611035565b60405180910390f35b61030260048036038101906102fd9190611178565b6105eb565b60405161030f919061105d565b60405180910390f35b610332600480360381019061032d9190611125565b61066d565b005b606060038054610343906111e3565b80601f016020809104026020016040519081016040528092919081815260200182805461036f906111e3565b80156103ba5780601f10610391576101008083540402835291602001916103ba565b820191905f5260205f20905b81548152906001019060200180831161039d57829003601f168201915b5050505050905090565b5f806103ce6106f1565b90506103db8185856106f8565b600191505092915050565b5f600254905090565b5f806103f96106f1565b905061040685828561070a565b61041185858561079c565b60019150509392505050565b5f7f0000000000000000000000000000000000000000000000000000000000000012905090565b7f000000000000000000000000000000000000000000000000000000000000001281565b5f61047161088c565b61047b8383610913565b6001905092915050565b6104966104906106f1565b82610992565b50565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6104e661088c565b6104ef5f610a11565b565b610503826104fd6106f1565b8361070a565b61050d8282610992565b5050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054610548906111e3565b80601f0160208091040260200160405190810160405280929190818152602001828054610574906111e3565b80156105bf5780601f10610596576101008083540402835291602001916105bf565b820191905f5260205f20905b8154815290600101906020018083116105a257829003601f168201915b5050505050905090565b5f806105d36106f1565b90506105e081858561079c565b600191505092915050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b61067561088c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036106e5575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016106dc919061115f565b60405180910390fd5b6106ee81610a11565b50565b5f33905090565b6107058383836001610ad4565b505050565b5f61071584846105eb565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146107965781811015610787578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161077e93929190611213565b60405180910390fd5b61079584848484035f610ad4565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361080c575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401610803919061115f565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361087c575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401610873919061115f565b60405180910390fd5b610887838383610ca3565b505050565b6108946106f1565b73ffffffffffffffffffffffffffffffffffffffff166108b2610511565b73ffffffffffffffffffffffffffffffffffffffff1614610911576108d56106f1565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610908919061115f565b60405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610983575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040161097a919061115f565b60405180910390fd5b61098e5f8383610ca3565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610a02575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016109f9919061115f565b60405180910390fd5b610a0d825f83610ca3565b5050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610b44575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401610b3b919061115f565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610bb4575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401610bab919061115f565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015610c9d578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610c94919061105d565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610cf3578060025f828254610ce79190611275565b92505081905550610dc1565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610d7c578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401610d7393929190611213565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610e08578060025f8282540392505081905550610e52565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610eaf919061105d565b60405180910390a3505050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610efe82610ebc565b610f088185610ec6565b9350610f18818560208601610ed6565b610f2181610ee4565b840191505092915050565b5f6020820190508181035f830152610f448184610ef4565b905092915050565b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610f7982610f50565b9050919050565b610f8981610f6f565b8114610f93575f80fd5b50565b5f81359050610fa481610f80565b92915050565b5f819050919050565b610fbc81610faa565b8114610fc6575f80fd5b50565b5f81359050610fd781610fb3565b92915050565b5f8060408385031215610ff357610ff2610f4c565b5b5f61100085828601610f96565b925050602061101185828601610fc9565b9150509250929050565b5f8115159050919050565b61102f8161101b565b82525050565b5f6020820190506110485f830184611026565b92915050565b61105781610faa565b82525050565b5f6020820190506110705f83018461104e565b92915050565b5f805f6060848603121561108d5761108c610f4c565b5b5f61109a86828701610f96565b93505060206110ab86828701610f96565b92505060406110bc86828701610fc9565b9150509250925092565b5f60ff82169050919050565b6110db816110c6565b82525050565b5f6020820190506110f45f8301846110d2565b92915050565b5f6020828403121561110f5761110e610f4c565b5b5f61111c84828501610fc9565b91505092915050565b5f6020828403121561113a57611139610f4c565b5b5f61114784828501610f96565b91505092915050565b61115981610f6f565b82525050565b5f6020820190506111725f830184611150565b92915050565b5f806040838503121561118e5761118d610f4c565b5b5f61119b85828601610f96565b92505060206111ac85828601610f96565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806111fa57607f821691505b60208210810361120d5761120c6111b6565b5b50919050565b5f6060820190506112265f830186611150565b611233602083018561104e565b611240604083018461104e565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61127f82610faa565b915061128a83610faa565b92508282019050808211156112a2576112a1611248565b5b9291505056fea26469706673582212209f0a626b467641bcb285a9dc2ba081270a0aa581ef6aa1888924d1e43c7be0b764736f6c634300081a0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x577261707065642045746865720000000000000000000000000000000000001A", + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5745544800000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000000000000000000000000746f6b656e61646d696e" + } + }, + "0x8ff5C1D5233CA055cD536b2b87294d17f9160801": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b5060043610610055575f3560e01c80631688f0b9146100595780633408e4701461008957806353e5d93514610097578063d18af54d146100ac578063ec9e80bb146100bf575b5f80fd5b61006c610067366004610472565b6100d2565b6040516001600160a01b0390911681526020015b60405180910390f35b604051468152602001610080565b61009f610166565b60405161008091906104f6565b61006c6100ba36600461050f565b610190565b61006c6100cd366004610472565b61025f565b5f808380519060200120836040516020016100f7929190918252602082015260400190565b60405160208183030381529060405280519060200120905061011a858583610290565b6040516001600160a01b038781168252919350908316907f4f51faf6c4561ff95f067657e43439f0f856d97c04d9ec9070a6199ad418e2359060200160405180910390a2509392505050565b606060405180602001610178906103af565b601f1982820381018352601f90910116604052919050565b5f8083836040516020016101c092919091825260601b6bffffffffffffffffffffffff1916602082015260340190565b604051602081830303815290604052805190602001205f1c90506101e58686836100d2565b91506001600160a01b03831615610256576040516303ca56a360e31b81526001600160a01b03841690631e52b518906102289085908a908a908a90600401610577565b5f604051808303815f87803b15801561023f575f80fd5b505af1158015610251573d5f803e3d5ffd5b505050505b50949350505050565b5f808380519060200120836102714690565b60408051602081019490945283019190915260608201526080016100f7565b5f833b6102e45760405162461bcd60e51b815260206004820152601f60248201527f53696e676c65746f6e20636f6e7472616374206e6f74206465706c6f7965640060448201526064015b60405180910390fd5b5f604051806020016102f5906103af565b601f1982820381018352601f90910116604081905261032291906001600160a01b038816906020016105b3565b6040516020818303038152906040529050828151826020015ff591506001600160a01b03821661038a5760405162461bcd60e51b815260206004820152601360248201527210dc99585d194c8818d85b1b0819985a5b1959606a1b60448201526064016102db565b8351156103a7575f805f8651602088015f875af1036103a7575f80fd5b509392505050565b610163806105ce83390190565b6001600160a01b03811681146103d0575f80fd5b50565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126103f6575f80fd5b813567ffffffffffffffff811115610410576104106103d3565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561043f5761043f6103d3565b604052818152838201602001851015610456575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f60608486031215610484575f80fd5b833561048f816103bc565b9250602084013567ffffffffffffffff8111156104aa575f80fd5b6104b6868287016103e7565b93969395505050506040919091013590565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61050860208301846104c8565b9392505050565b5f805f8060808587031215610522575f80fd5b843561052d816103bc565b9350602085013567ffffffffffffffff811115610548575f80fd5b610554878288016103e7565b93505060408501359150606085013561056c816103bc565b939692955090935050565b6001600160a01b038581168252841660208201526080604082018190525f906105a2908301856104c8565b905082606083015295945050505050565b5f83518060208601845e919091019182525060200191905056fe6080604052348015600e575f80fd5b50604051610163380380610163833981016040819052602b9160b2565b6001600160a01b038116608f5760405162461bcd60e51b815260206004820152602260248201527f496e76616c69642073696e676c65746f6e20616464726573732070726f766964604482015261195960f21b606482015260840160405180910390fd5b5f80546001600160a01b0319166001600160a01b039290921691909117905560dd565b5f6020828403121560c1575f80fd5b81516001600160a01b038116811460d6575f80fd5b9392505050565b607a806100e95f395ff3fe60806040525f80546001600160a01b03169035632cf35bc960e11b01602657805f5260205ff35b365f80375f80365f845af490503d5f803e80603f573d5ffd5b503d5ff3fea264697066735822122001deaa6568fd950b816ad3772ffe1e654dbb28263960bb86cfb313e8e93f6b6b64736f6c634300081a0033a26469706673582212204d02cb188c82949fc64f39d7729617fb7a5131ed975627a1123a88cce3793abc64736f6c634300081a0033" + }, + "0x2f2965efaCFc64Fb85dF1902260eB25C0c996195": { + "balance": "0x0", + "code": "0x6080604052600436106101d0575f3560e01c8063affed0e0116100f6578063e19a9dd911610094578063f08a032311610063578063f08a0323146105d2578063f698da25146105f1578063f8dc5dd914610605578063ffa1ad74146106245761020c565b8063e19a9dd914610561578063e318b52b14610580578063e75235b81461059f578063e86637db146105b35761020c565b8063cc2f8452116100d0578063cc2f8452146104d7578063d4d9bdcd14610504578063d8d11f7814610523578063e009cfde146105425761020c565b8063affed0e014610484578063b4faba0914610499578063b63e800d146104b85761020c565b80635624b25b1161016e5780636a7612021161013d5780636a761202146103fb5780637d8329741461040e578063934f3a1114610444578063a0e67e2b146104635761020c565b80635624b25b146103665780635ae6bd3714610392578063610b5925146103bd578063694e80c3146103dc5761020c565b80632f54bf6e116101aa5780632f54bf6e146102df5780633408e470146102fe578063468721a71461031a5780635229073f146103395761020c565b80630d582f131461026b57806312fb68e01461028c5780632d9ad53d146102ab5761020c565b3661020c5760405134815233907f3d0ce9bfc3ed7d6862dbb28b2dea94561fe714a1b4d019aa8af39730d1ad7c3d9060200160405180910390a2005b348015610217575f80fd5b507f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d580548061024257005b365f80373360601b36525f80601436015f80855af190503d5f803e80610266573d5ffd5b503d5ff35b348015610276575f80fd5b5061028a6102853660046125fe565b610654565b005b348015610297575f80fd5b5061028a6102a63660046126c5565b6107a9565b3480156102b6575f80fd5b506102ca6102c5366004612738565b610c3a565b60405190151581526020015b60405180910390f35b3480156102ea575f80fd5b506102ca6102f9366004612738565b610c73565b348015610309575f80fd5b50465b6040519081526020016102d6565b348015610325575f80fd5b506102ca610334366004612761565b610ca9565b348015610344575f80fd5b50610358610353366004612761565b610cfe565b6040516102d69291906127f4565b348015610371575f80fd5b5061038561038036600461280e565b610d32565b6040516102d6919061282e565b34801561039d575f80fd5b5061030c6103ac366004612840565b60076020525f908152604090205481565b3480156103c8575f80fd5b5061028a6103d7366004612738565b610dab565b3480156103e7575f80fd5b5061028a6103f6366004612840565b610ee2565b6102ca61040936600461289b565b610f80565b348015610419575f80fd5b5061030c6104283660046125fe565b600860209081525f928352604080842090915290825290205481565b34801561044f575f80fd5b5061028a61045e36600461296b565b611027565b34801561046e575f80fd5b50610477611071565b6040516102d69190612a19565b34801561048f575f80fd5b5061030c60055481565b3480156104a4575f80fd5b5061028a6104b3366004612a2b565b61115e565b3480156104c3575f80fd5b5061028a6104d2366004612a77565b61117d565b3480156104e2575f80fd5b506104f66104f13660046125fe565b61127c565b6040516102d6929190612b66565b34801561050f575f80fd5b5061028a61051e366004612840565b611433565b34801561052e575f80fd5b5061030c61053d366004612b8f565b6114c6565b34801561054d575f80fd5b5061028a61055c366004612c4c565b6114f2565b34801561056c575f80fd5b5061028a61057b366004612738565b611612565b34801561058b575f80fd5b5061028a61059a366004612c83565b611725565b3480156105aa575f80fd5b5060045461030c565b3480156105be575f80fd5b506103856105cd366004612b8f565b6118fc565b3480156105dd575f80fd5b5061028a6105ec366004612738565b6119d3565b3480156105fc575f80fd5b5061030c611a1a565b348015610610575f80fd5b5061028a61061f366004612ccb565b611a70565b34801561062f575f80fd5b5061038560405180604001604052806005815260200164312e342e3160d81b81525081565b61065c611bd8565b6001600160a01b0382161580159061067e57506001600160a01b038216600114155b801561069357506001600160a01b0382163014155b6106b85760405162461bcd60e51b81526004016106af90612d09565b60405180910390fd5b6001600160a01b038281165f9081526002602052604090205416156106ef5760405162461bcd60e51b81526004016106af90612d28565b60026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e080546001600160a01b038481165f818152604081208054939094166001600160a01b03199384161790935560018352835490911617909155600380549161075b83612d5b565b90915550506040516001600160a01b038316907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26905f90a280600454146107a5576107a581610ee2565b5050565b6107b4816041611c11565b825110156107ec5760405162461bcd60e51b8152602060048201526005602482015264047533032360dc1b60448201526064016106af565b5f80805f805f5b86811015610c2e576041818102890160208101516040820151919092015160ff16955090935091505f8490036109fe57885160208a01208a146108605760405162461bcd60e51b8152602060048201526005602482015264475330323760d81b60448201526064016106af565b9193508391610870876041611c11565b8210156108a75760405162461bcd60e51b8152602060048201526005602482015264475330323160d81b60448201526064016106af565b87516108b4836020611c48565b11156108ea5760405162461bcd60e51b815260206004820152600560248201526423a998191960d91b60448201526064016106af565b60208289018101518951909161090d908390610907908790611c48565b90611c48565b11156109435760405162461bcd60e51b8152602060048201526005602482015264475330323360d81b60448201526064016106af565b6040516320c13b0b60e01b8082528a8501602001916001600160a01b038916906320c13b0b90610979908f908690600401612d73565b602060405180830381865afa158015610994573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109b89190612d97565b6001600160e01b031916146109f75760405162461bcd60e51b815260206004820152600560248201526411d4cc0c8d60da1b60448201526064016106af565b5050610b9e565b8360ff16600103610a7f579193508391336001600160a01b0384161480610a4657506001600160a01b0385165f9081526008602090815260408083208d845290915290205415155b610a7a5760405162461bcd60e51b8152602060048201526005602482015264475330323560d81b60448201526064016106af565b610b9e565b601e8460ff161115610b41576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018b9052600190605c0160405160208183030381529060405280519060200120600486610ae49190612dbe565b604080515f8152602081018083529390935260ff90911690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610b30573d5f803e3d5ffd5b505050602060405103519450610b9e565b604080515f8152602081018083528c905260ff861691810191909152606081018490526080810183905260019060a0016020604051602081039080840390855afa158015610b91573d5f803e3d5ffd5b5050506020604051035194505b856001600160a01b0316856001600160a01b0316118015610bd757506001600160a01b038581165f908152600260205260409020541615155b8015610bed57506001600160a01b038516600114155b610c215760405162461bcd60e51b815260206004820152600560248201526423a998191b60d91b60448201526064016106af565b93945084936001016107f3565b50505050505050505050565b5f60016001600160a01b03831614801590610c6d57506001600160a01b038281165f908152600160205260409020541615155b92915050565b5f6001600160a01b038216600114801590610c6d5750506001600160a01b039081165f9081526002602052604090205416151590565b5f7fb648d3644f584ed1c2232d53c46d87e693586486ad0d1175f8656013110b714e3386868686604051610ce1959493929190612e0b565b60405180910390a1610cf585858585611c62565b95945050505050565b5f6060610d0d86868686610ca9565b915060405160203d0181016040523d81523d5f602083013e8091505094509492505050565b60605f610d40836020612e56565b6001600160401b03811115610d5757610d57612628565b6040519080825280601f01601f191660200182016040528015610d81576020820181803683370190505b5090505f5b83811015610da35784810154602080830284010152600101610d86565b509392505050565b610db3611bd8565b6001600160a01b03811615801590610dd557506001600160a01b038116600114155b610e095760405162461bcd60e51b8152602060048201526005602482015264475331303160d81b60448201526064016106af565b6001600160a01b038181165f908152600160205260409020541615610e585760405162461bcd60e51b815260206004820152600560248201526423a998981960d91b60448201526064016106af565b600160208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b038481165f81815260408082208054949095166001600160a01b031994851617909455948552835490911681179092555190917fecdf3a3effea5783a3c4c2140e677577666428d44ed9d474a0b3a4c9943f844091a250565b610eea611bd8565b600354811115610f0c5760405162461bcd60e51b81526004016106af90612e6d565b6001811015610f455760405162461bcd60e51b815260206004820152600560248201526423a999181960d91b60448201526064016106af565b60048190556040518181527f610f7ff2b304ae8903c3de74c60c6ab1f7d6226b3f52c5161905bb5ad4039c939060200160405180910390a150565b60055460045460408051602081019390935233908301526060828101919091525f9160800160405160208183030381529060405290507f66753cd2356569ee081232e3be8909b950e0a76c1f8460c3a5e3c2be32b11bed8d8d8d8d8d8d8d8d8d8d8d8c604051610ffb9c9b9a99989796959493929190612eb4565b60405180910390a16110168d8d8d8d8d8d8d8d8d8d8d611d36565b9d9c50505050505050505050505050565b6004548061105f5760405162461bcd60e51b8152602060048201526005602482015264475330303160d81b60448201526064016106af565b61106b848484846107a9565b50505050565b60605f6003546001600160401b0381111561108e5761108e612628565b6040519080825280602002602001820160405280156110b7578160200160208202803683370190505b5060015f90815260026020527fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e054919250906001600160a01b03165b6001600160a01b038116600114611156578083838151811061111757611117612f52565b6001600160a01b039283166020918202929092018101919091529181165f9081526002909252604090912054168161114e81612d5b565b9250506110f3565b509092915050565b5f80825160208401855af4805f52503d6020523d5f60403e60403d015ffd5b6111ba8a8a808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152508c925061206f915050565b6001600160a01b038416156111d2576111d284612245565b6112118787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506122a992505050565b811561122757611225825f600186856123d7565b505b336001600160a01b03167f141df868a6331af528e38c83b7aa03edc19be66e37ae67f9285bf4f8e3c6a1a88b8b8b8b89604051611268959493929190612f66565b60405180910390a250505050505050505050565b60605f6001600160a01b0384166001148061129b575061129b84610c3a565b6112cf5760405162461bcd60e51b8152602060048201526005602482015264475331303560d81b60448201526064016106af565b5f83116113065760405162461bcd60e51b815260206004820152600560248201526423a998981b60d91b60448201526064016106af565b826001600160401b0381111561131e5761131e612628565b604051908082528060200260200182016040528015611347578160200160208202803683370190505b506001600160a01b038086165f90815260016020526040812054929450911691505b6001600160a01b0382161580159061138b57506001600160a01b038216600114155b801561139657508381105b156113f057818382815181106113ae576113ae612f52565b6001600160a01b039283166020918202929092018101919091529281165f908152600190935260409092205490911690806113e881612d5b565b915050611369565b6001600160a01b038216600114611428578261140d600183612fd1565b8151811061141d5761141d612f52565b602002602001015191505b808352509250929050565b335f908152600260205260409020546001600160a01b031661147f5760405162461bcd60e51b8152602060048201526005602482015264047533033360dc1b60448201526064016106af565b335f818152600860209081526040808320858452909152808220600190555183917ff2a0eb156472d1440255b0d7c1e19cc07115d1051fe605b0dce69acfec884d9c91a350565b5f6114da8c8c8c8c8c8c8c8c8c8c8c6118fc565b8051906020012090509b9a5050505050505050505050565b6114fa611bd8565b6001600160a01b0381161580159061151c57506001600160a01b038116600114155b6115505760405162461bcd60e51b8152602060048201526005602482015264475331303160d81b60448201526064016106af565b6001600160a01b038281165f908152600160205260409020548116908216146115a35760405162461bcd60e51b8152602060048201526005602482015264475331303360d81b60448201526064016106af565b6001600160a01b038181165f81815260016020526040808220805487861684528284208054919096166001600160a01b0319918216179095558383528054909416909355915190917faab4fa2b463f581b2b32cb3b7e3b704b9ce37cc209b5fb4d77e593ace405427691a25050565b61161a611bd8565b6001600160a01b038116156116ca576040516301ffc9a760e01b815263736bd41d60e11b60048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa158015611672573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116969190612fe4565b6116ca5760405162461bcd60e51b8152602060048201526005602482015264047533330360dc1b60448201526064016106af565b7f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c88181556040516001600160a01b038316907f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa2905f90a25050565b61172d611bd8565b6001600160a01b0381161580159061174f57506001600160a01b038116600114155b801561176457506001600160a01b0381163014155b6117805760405162461bcd60e51b81526004016106af90612d09565b6001600160a01b038181165f9081526002602052604090205416156117b75760405162461bcd60e51b81526004016106af90612d28565b6001600160a01b038216158015906117d957506001600160a01b038216600114155b6117f55760405162461bcd60e51b81526004016106af90612d09565b6001600160a01b038381165f908152600260205260409020548116908316146118485760405162461bcd60e51b8152602060048201526005602482015264475332303560d81b60448201526064016106af565b6001600160a01b038281165f81815260026020526040808220805486861680855283852080549288166001600160a01b03199384161790559589168452828420805482169096179095558383528054909416909355915190917ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf91a26040516001600160a01b038216907f9465fa0c962cc76958e6373a993326400c1c94f8be2fe3a952adfa7f60b2ea26905f90a2505050565b60605f7fbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d85f1b8d8d8d8d604051611934929190613003565b60405190819003812061195a949392918e908e908e908e908e908e908e90602001613012565b60408051601f1981840301815291905280516020909101209050601960f81b600160f81b611986611a1a565b6040516001600160f81b031993841660208201529290911660218301526022820152604281018290526062016040516020818303038152906040529150509b9a5050505050505050505050565b6119db611bd8565b6119e481612245565b6040516001600160a01b038216907f5ac6c46c93c8d0e53714ba3b53db3e7c046da994313d7ed0d192028bc7c228b0905f90a250565b5f7f47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a794692184660408051602081019390935282015230606082015260800160405160208183030381529060405280519060200120905090565b611a78611bd8565b806001600354611a889190612fd1565b1015611aa65760405162461bcd60e51b81526004016106af90612e6d565b6001600160a01b03821615801590611ac857506001600160a01b038216600114155b611ae45760405162461bcd60e51b81526004016106af90612d09565b6001600160a01b038381165f90815260026020526040902054811690831614611b375760405162461bcd60e51b8152602060048201526005602482015264475332303560d81b60448201526064016106af565b6001600160a01b038281165f81815260026020526040808220805488861684529183208054929095166001600160a01b03199283161790945591815282549091169091556003805491611b8983613084565b90915550506040516001600160a01b038316907ff8d49fc529812e9a7c5c50e69c20f0dccc0db8fa95c98bc58cc9a4f1c1299eaf905f90a28060045414611bd357611bd381610ee2565b505050565b333014611c0f5760405162461bcd60e51b8152602060048201526005602482015264475330333160d81b60448201526064016106af565b565b5f825f03611c2057505f610c6d565b5f611c2b8385612e56565b905082611c388583613099565b14611c41575f80fd5b9392505050565b5f80611c5483856130b8565b905083811015611c41575f80fd5b5f33600114801590611c8a5750335f908152600160205260409020546001600160a01b031615155b611cbe5760405162461bcd60e51b815260206004820152600560248201526411d4cc4c0d60da1b60448201526064016106af565b611ccc858585855f196124db565b90508015611d035760405133907f6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8905f90a2611d2e565b60405133907facd2c8702804128fdb0db2bb49f6d127dd0181c13fd45dbfe16de0930e2bd375905f90a25b949350505050565b5f805f611d4e8e8e8e8e8e8e8e8e8e8e6005546118fc565b600580549192505f611d5f83612d5b565b9091555050805160208201209150611d78828286611027565b505f611da27f4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c85490565b90506001600160a01b03811615611e2357806001600160a01b03166375f0bb528f8f8f8f8f8f8f8f8f8f8f336040518d63ffffffff1660e01b8152600401611df59c9b9a999897969594939291906130cb565b5f604051808303815f87803b158015611e0c575f80fd5b505af1158015611e1e573d5f803e3d5ffd5b505050505b611e4f611e328a6109c46130b8565b603f611e3f8c6040612e56565b611e499190613099565b9061251d565b611e5b906101f46130b8565b5a1015611e925760405162461bcd60e51b8152602060048201526005602482015264047533031360dc1b60448201526064016106af565b5f5a9050611f008f8f8f8f8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050508e8c5f14611eed578e6124db565b6109c45a611efb9190612fd1565b6124db565b9350611f0d5a8290612533565b90508380611f1a57508915155b80611f2457508715155b611f585760405162461bcd60e51b8152602060048201526005602482015264475330313360d81b60448201526064016106af565b5f8815611f6f57611f6c828b8b8b8b6123d7565b90505b8415611fb457837f442e715f626346e8c54381002da614f62bee8d27386535b2521ec8540898556e82604051611fa791815260200190565b60405180910390a2611fef565b837f23428b18acfb3ea64b08dc0c1d296ea9c09702c09083ca5272e64d115b687d2382604051611fe691815260200190565b60405180910390a25b50506001600160a01b0381161561205e57604051631264e26d60e31b81526004810183905283151560248201526001600160a01b038216906393271368906044015f604051808303815f87803b158015612047575f80fd5b505af1158015612059573d5f803e3d5ffd5b505050505b50509b9a5050505050505050505050565b600454156120a75760405162461bcd60e51b8152602060048201526005602482015264047533230360dc1b60448201526064016106af565b81518111156120c85760405162461bcd60e51b81526004016106af90612e6d565b60018110156121015760405162461bcd60e51b815260206004820152600560248201526423a999181960d91b60448201526064016106af565b60015f5b8351811015612213575f84828151811061212157612121612f52565b602002602001015190505f6001600160a01b0316816001600160a01b03161415801561215757506001600160a01b038116600114155b801561216c57506001600160a01b0381163014155b801561218a5750806001600160a01b0316836001600160a01b031614155b6121a65760405162461bcd60e51b81526004016106af90612d09565b6001600160a01b038181165f9081526002602052604090205416156121dd5760405162461bcd60e51b81526004016106af90612d28565b6001600160a01b039283165f90815260026020526040902080546001600160a01b03191693821693909317909255600101612105565b506001600160a01b03165f90815260026020526040902080546001600160a01b03191660011790559051600355600455565b306001600160a01b038216036122855760405162461bcd60e51b8152602060048201526005602482015264047533430360dc1b60448201526064016106af565b7f6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d555565b60015f8190526020527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f546001600160a01b0316156123125760405162461bcd60e51b8152602060048201526005602482015264047533130360dc1b60448201526064016106af565b60015f81905260208190527fcc69885fda6bcc1a4ace058b4a62bf5e179ea78fd58a1ccd71c22cc9b688792f80546001600160a01b03191690911790556001600160a01b038216156107a557813b6123945760405162461bcd60e51b815260206004820152600560248201526423a998181960d91b60448201526064016106af565b6123a3825f8360015f196124db565b6107a55760405162461bcd60e51b8152602060048201526005602482015264047533030360dc1b60448201526064016106af565b5f806001600160a01b038316156123ee57826123f0565b325b90506001600160a01b038416612482576124223a8610612410573a612412565b855b61241c8989611c48565b90611c11565b6040519092506001600160a01b0382169083156108fc029084905f818181858888f1935050505061247d5760405162461bcd60e51b8152602060048201526005602482015264475330313160d81b60448201526064016106af565b6124d1565b6124908561241c8989611c48565b915061249d84828461254b565b6124d15760405162461bcd60e51b815260206004820152600560248201526423a998189960d91b60448201526064016106af565b5095945050505050565b5f60018360018111156124f0576124f0612dd7565b03612507575f808551602087018986f49050610cf5565b5f80855160208701888a87f19695505050505050565b5f8183101561252c5781611c41565b5090919050565b5f82821115612540575f80fd5b5f611d2e8385612fd1565b604080516001600160a01b03841660248201526044808201849052825180830390910181526064909101909152602080820180516001600160e01b031663a9059cbb60e01b17815282515f93929184919082896127105a03f13d80156125bb57602081146125c3575f93506125cd565b8193506125cd565b5f51158215171593505b5050509392505050565b6001600160a01b03811681146125eb575f80fd5b50565b80356125f9816125d7565b919050565b5f806040838503121561260f575f80fd5b823561261a816125d7565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f83011261264b575f80fd5b81356001600160401b0381111561266457612664612628565b604051601f8201601f19908116603f011681016001600160401b038111828210171561269257612692612628565b6040528181528382016020018510156126a9575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80608085870312156126d8575f80fd5b8435935060208501356001600160401b038111156126f4575f80fd5b6127008782880161263c565b93505060408501356001600160401b0381111561271b575f80fd5b6127278782880161263c565b949793965093946060013593505050565b5f60208284031215612748575f80fd5b8135611c41816125d7565b8035600281106125f9575f80fd5b5f805f8060808587031215612774575f80fd5b843561277f816125d7565b93506020850135925060408501356001600160401b038111156127a0575f80fd5b6127ac8782880161263c565b9250506127bb60608601612753565b905092959194509250565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b8215158152604060208201525f611d2e60408301846127c6565b5f806040838503121561281f575f80fd5b50508035926020909101359150565b602081525f611c4160208301846127c6565b5f60208284031215612850575f80fd5b5035919050565b5f8083601f840112612867575f80fd5b5081356001600160401b0381111561287d575f80fd5b602083019150836020828501011115612894575f80fd5b9250929050565b5f805f805f805f805f805f6101408c8e0312156128b6575f80fd5b6128bf8c6125ee565b9a5060208c0135995060408c01356001600160401b038111156128e0575f80fd5b6128ec8e828f01612857565b909a5098506128ff905060608d01612753565b965060808c0135955060a08c0135945060c08c0135935061292260e08d016125ee565b92506129316101008d016125ee565b91506101208c01356001600160401b0381111561294c575f80fd5b6129588e828f0161263c565b9150509295989b509295989b9093969950565b5f805f6060848603121561297d575f80fd5b8335925060208401356001600160401b03811115612999575f80fd5b6129a58682870161263c565b92505060408401356001600160401b038111156129c0575f80fd5b6129cc8682870161263c565b9150509250925092565b5f8151808452602084019350602083015f5b82811015612a0f5781516001600160a01b03168652602095860195909101906001016129e8565b5093949350505050565b602081525f611c4160208301846129d6565b5f8060408385031215612a3c575f80fd5b8235612a47816125d7565b915060208301356001600160401b03811115612a61575f80fd5b612a6d8582860161263c565b9150509250929050565b5f805f805f805f805f806101008b8d031215612a91575f80fd5b8a356001600160401b03811115612aa6575f80fd5b8b01601f81018d13612ab6575f80fd5b80356001600160401b03811115612acb575f80fd5b8d60208260051b8401011115612adf575f80fd5b60209182019b5099508b01359750612af960408c016125ee565b965060608b01356001600160401b03811115612b13575f80fd5b612b1f8d828e01612857565b9097509550612b32905060808c016125ee565b9350612b4060a08c016125ee565b925060c08b01359150612b5560e08c016125ee565b90509295989b9194979a5092959850565b604081525f612b7860408301856129d6565b905060018060a01b03831660208301529392505050565b5f805f805f805f805f805f6101408c8e031215612baa575f80fd5b8b35612bb5816125d7565b9a5060208c0135995060408c01356001600160401b03811115612bd6575f80fd5b612be28e828f01612857565b909a509850612bf5905060608d01612753565b965060808c0135955060a08c0135945060c08c0135935060e08c0135612c1a816125d7565b92506101008c0135612c2b816125d7565b809250505f6101208d01359050809150509295989b509295989b9093969950565b5f8060408385031215612c5d575f80fd5b8235612c68816125d7565b91506020830135612c78816125d7565b809150509250929050565b5f805f60608486031215612c95575f80fd5b8335612ca0816125d7565b92506020840135612cb0816125d7565b91506040840135612cc0816125d7565b809150509250925092565b5f805f60608486031215612cdd575f80fd5b8335612ce8816125d7565b92506020840135612cf8816125d7565b929592945050506040919091013590565b602080825260059082015264475332303360d81b604082015260600190565b60208082526005908201526411d4cc8c0d60da1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b5f60018201612d6c57612d6c612d47565b5060010190565b604081525f612d8560408301856127c6565b8281036020840152610cf581856127c6565b5f60208284031215612da7575f80fd5b81516001600160e01b031981168114611c41575f80fd5b60ff8281168282160390811115610c6d57610c6d612d47565b634e487b7160e01b5f52602160045260245ffd5b60028110612e0757634e487b7160e01b5f52602160045260245ffd5b9052565b6001600160a01b038681168252851660208201526040810184905260a0606082018190525f90612e3d908301856127c6565b9050612e4c6080830184612deb565b9695505050505050565b8082028115828204841417610c6d57610c6d612d47565b602080825260059082015264475332303160d81b604082015260600190565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60018060a01b038d1681528b602082015261016060408201525f612edd61016083018c8e612e8c565b612eea606084018c612deb565b608083018a905260a0830189905260c083018890526001600160a01b0387811660e08501528616610100840152828103610120840152612f2a81866127c6565b9050828103610140840152612f3f81856127c6565b9f9e505050505050505050505050505050565b634e487b7160e01b5f52603260045260245ffd5b608080825281018590525f8660a08301825b88811015612fa8578235612f8b816125d7565b6001600160a01b0316825260209283019290910190600101612f78565b50602084019690965250506001600160a01b039283166040820152911660609091015292915050565b81810381811115610c6d57610c6d612d47565b5f60208284031215612ff4575f80fd5b81518015158114611c41575f80fd5b818382375f9101908152919050565b8b81526001600160a01b038b166020820152604081018a9052606081018990526101608101613044608083018a612deb565b60a082019790975260c081019590955260e08501939093526001600160a01b03918216610100850152166101208301526101409091015295945050505050565b5f8161309257613092612d47565b505f190190565b5f826130b357634e487b7160e01b5f52601260045260245ffd5b500490565b80820180821115610c6d57610c6d612d47565b60018060a01b038d1681528b602082015261016060408201525f6130f461016083018c8e612e8c565b613101606084018c612deb565b608083018a905260a0830189905260c083018890526001600160a01b0387811660e0850152861661010084015282810361012084015261314181866127c6565b91505060018060a01b0383166101408301529d9c5050505050505050505050505056fea264697066735822122072f65bcceb63ee3acb0069e2374c764d8a5e2009eff69744f32e244b6f76c45064736f6c634300081a0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + }, + "0xe59838EB7f251489b50940BD640326215420B936": { + "balance": "0x0", + "code": "0x608060405234801561000f575f80fd5b50600436106100b0575f3560e01c8063230316401161006e57806323031640146101755780636ac2478414610195578063b2494df3146101a8578063bc197c81146101bd578063bd61951d146101df578063f23a6e61146101f2575f80fd5b806223de29146100b457806301ffc9a7146100ce5780630a1028c4146100f6578063150b7a02146101175780631626ba7e1461014f57806320c13b0b14610162575b5f80fd5b6100cc6100c23660046106a9565b5050505050505050565b005b6100e16100dc36600461076b565b610212565b60405190151581526020015b60405180910390f35b610109610104366004610835565b610263565b6040519081526020016100ed565b61013661012536600461086e565b630a85bd0160e11b95945050505050565b6040516001600160e01b031990911681526020016100ed565b61013661015d3660046108db565b61026e565b610136610170366004610922565b610328565b610188610183366004610985565b610469565b6040516100ed91906109e9565b6101096101a3366004610985565b610577565b6101b0610591565b6040516100ed91906109fb565b6101366101cb366004610a86565b63bc197c8160e01b98975050505050505050565b6101886101ed366004610b26565b610607565b610136610200366004610b5d565b63f23a6e6160e01b9695505050505050565b5f6001600160e01b03198216630271189760e51b148061024257506001600160e01b03198216630a85bd0160e11b145b8061025d57506001600160e01b031982166301ffc9a760e01b145b92915050565b5f61025d3383610577565b60408051602080820186905282518083039091018152818301928390526320c13b0b60e01b9092525f913391839183916320c13b0b916102b49189908990604401610bd3565b602060405180830381865afa1580156102cf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102f39190610c17565b90506001600160e01b031981166320c13b0b60e01b14610313575f61031c565b630b135d3f60e11b5b925050505b9392505050565b5f33816103358286610469565b805160208201208551919250905f036103fa57604051635ae6bd3760e01b8152600481018290526001600160a01b03841690635ae6bd3790602401602060405180830381865afa15801561038b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103af9190610c32565b5f036103f55760405162461bcd60e51b815260206004820152601160248201527012185cda081b9bdd08185c1c1c9bdd9959607a1b604482015260640160405180910390fd5b610457565b60405163934f3a1160e01b81526001600160a01b0384169063934f3a119061042a90849086908a90600401610c49565b5f6040518083038186803b158015610440575f80fd5b505afa158015610452573d5f803e3d5ffd5b505050505b506320c13b0b60e01b95945050505050565b60605f7f60b3cbf8b4a223d68d641b3b6ddf9a298e7f33710cf3d3a9d1146b5a6150fbca5f1b83805190602001206040516020016104b1929190918252602082015260400190565b604051602081830303815290604052805190602001209050601960f81b600160f81b856001600160a01b031663f698da256040518163ffffffff1660e01b8152600401602060405180830381865afa15801561050f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105339190610c32565b6040516001600160f81b0319938416602082015292909116602183015260228201526042810182905260620160405160208183030381529060405291505092915050565b5f6105828383610469565b80519060200120905092915050565b604051636617c22960e11b815260016004820152600a602482015260609033905f90829063cc2f8452906044015f60405180830381865afa1580156105d8573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526105ff9190810190610c8d565b509392505050565b606060405163b4faba0960e01b81526004360360048083013760205f36835f335af1505060203d036040519150808201604052806020833e505f5161032157805160208201fd5b6001600160a01b0381168114610662575f80fd5b50565b5f8083601f840112610675575f80fd5b5081356001600160401b0381111561068b575f80fd5b6020830191508360208285010111156106a2575f80fd5b9250929050565b5f805f805f805f8060c0898b0312156106c0575f80fd5b88356106cb8161064e565b975060208901356106db8161064e565b965060408901356106eb8161064e565b95506060890135945060808901356001600160401b0381111561070c575f80fd5b6107188b828c01610665565b90955093505060a08901356001600160401b03811115610736575f80fd5b6107428b828c01610665565b999c989b5096995094979396929594505050565b6001600160e01b031981168114610662575f80fd5b5f6020828403121561077b575f80fd5b813561032181610756565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b03811182821017156107c2576107c2610786565b604052919050565b5f82601f8301126107d9575f80fd5b81356001600160401b038111156107f2576107f2610786565b610805601f8201601f191660200161079a565b818152846020838601011115610819575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215610845575f80fd5b81356001600160401b0381111561085a575f80fd5b610866848285016107ca565b949350505050565b5f805f805f60808688031215610882575f80fd5b853561088d8161064e565b9450602086013561089d8161064e565b93506040860135925060608601356001600160401b038111156108be575f80fd5b6108ca88828901610665565b969995985093965092949392505050565b5f805f604084860312156108ed575f80fd5b8335925060208401356001600160401b03811115610909575f80fd5b61091586828701610665565b9497909650939450505050565b5f8060408385031215610933575f80fd5b82356001600160401b03811115610948575f80fd5b610954858286016107ca565b92505060208301356001600160401b0381111561096f575f80fd5b61097b858286016107ca565b9150509250929050565b5f8060408385031215610996575f80fd5b82356109a18161064e565b915060208301356001600160401b0381111561096f575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61032160208301846109bb565b602080825282518282018190525f918401906040840190835b81811015610a3b5783516001600160a01b0316835260209384019390920191600101610a14565b509095945050505050565b5f8083601f840112610a56575f80fd5b5081356001600160401b03811115610a6c575f80fd5b6020830191508360208260051b85010111156106a2575f80fd5b5f805f805f805f8060a0898b031215610a9d575f80fd5b8835610aa88161064e565b97506020890135610ab88161064e565b965060408901356001600160401b03811115610ad2575f80fd5b610ade8b828c01610a46565b90975095505060608901356001600160401b03811115610afc575f80fd5b610b088b828c01610a46565b90955093505060808901356001600160401b03811115610736575f80fd5b5f805f60408486031215610b38575f80fd5b8335610b438161064e565b925060208401356001600160401b03811115610909575f80fd5b5f805f805f8060a08789031215610b72575f80fd5b8635610b7d8161064e565b95506020870135610b8d8161064e565b9450604087013593506060870135925060808701356001600160401b03811115610bb5575f80fd5b610bc189828a01610665565b979a9699509497509295939492505050565b604081525f610be560408301866109bb565b8281036020840152838152838560208301375f602085830101526020601f19601f860116820101915050949350505050565b5f60208284031215610c27575f80fd5b815161032181610756565b5f60208284031215610c42575f80fd5b5051919050565b838152606060208201525f610c6160608301856109bb565b8281036040840152610c7381856109bb565b9695505050505050565b8051610c888161064e565b919050565b5f8060408385031215610c9e575f80fd5b82516001600160401b03811115610cb3575f80fd5b8301601f81018513610cc3575f80fd5b80516001600160401b03811115610cdc57610cdc610786565b8060051b610cec6020820161079a565b91825260208184018101929081019088841115610d07575f80fd5b6020850194505b83851015610d355784519250610d238361064e565b82825260209485019490910190610d0e565b8096505050505050610d4960208401610c7d565b9050925092905056fea26469706673582212207234b4eb35a19350f1ef1ac1dcfde24186fe0f559f21323992f580424784d70564736f6c634300081a0033" + }, + "0x0000000000000000007369676e65742d77757364": { + "balance": "0x0", + "code": "0x6060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x5772617070656420555344000000000000000000000000000000000000000016", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x5755534400000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000012" + } + }, + "0x4e59b44847b379578588920cA78FbF26c0B4956C": { + "balance": "0x0", + "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" + } + }, + "baseFeePerGas": "0x3b9aca00", + "excessBlobGas": null, + "blobGasUsed": null, + "number": null +} diff --git a/crates/node-config/Cargo.toml b/crates/node-config/Cargo.toml new file mode 100644 index 0000000..0842f4b --- /dev/null +++ b/crates/node-config/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "signet-node-config" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +signet-blobber.workspace = true +signet-types.workspace = true + +init4-bin-base.workspace = true + +reth.workspace = true +reth-chainspec.workspace = true +reth-exex.workspace = true +reth-node-api.workspace = true +reth-db = { workspace = true, optional = true} + +alloy.workspace = true + +eyre.workspace = true +reqwest.workspace = true +serde.workspace = true +tracing.workspace = true +trevm.workspace = true +signet-genesis.workspace = true + +[features] +test_utils = ["dep:reth-db", "reth-db/test-utils"] diff --git a/crates/node-config/README.md b/crates/node-config/README.md new file mode 100644 index 0000000..15eae4d --- /dev/null +++ b/crates/node-config/README.md @@ -0,0 +1,8 @@ +# Signet Node Config + +Configuration objects for the Signet Node + +This library contains the following: + +- `SignetNodeConfig` - The main configuration object for a Signet Node. This + struct can be loaded from the environment, or deserialized from a JSON file. diff --git a/crates/node-config/src/core.rs b/crates/node-config/src/core.rs new file mode 100644 index 0000000..d0f5aa2 --- /dev/null +++ b/crates/node-config/src/core.rs @@ -0,0 +1,261 @@ +use alloy::genesis::Genesis; +use init4_bin_base::utils::{calc::SlotCalculator, from_env::FromEnv}; +use reth::providers::providers::StaticFileProvider; +use reth_chainspec::{ChainSpec, EthereumHardforks}; +use reth_node_api::NodePrimitives; +use signet_blobber::BlobFetcherConfig; +use signet_genesis::GenesisSpec; +use signet_types::constants::{ConfigError, SignetSystemConstants}; +use std::{ + borrow::Cow, + fmt::Display, + path::PathBuf, + sync::{Arc, OnceLock}, +}; +use tracing::warn; +use trevm::revm::primitives::hardfork::SpecId; + +/// Defines the default port for serving Signet Node JSON RPC requests over http. +pub const SIGNET_NODE_DEFAULT_HTTP_PORT: u16 = 5959u16; + +/// Configuration for a Signet Node instance. Contains system contract and signer +/// information. +#[derive(Debug, Clone, serde::Deserialize, FromEnv)] +#[serde(rename_all = "camelCase")] +pub struct SignetNodeConfig { + /// Configuration for the block extractor. + #[from_env(infallible)] + block_extractor: BlobFetcherConfig, + + /// Path to the static files for reth StaticFileProviders. + #[from_env(var = "SIGNET_STATIC_PATH", desc = "Path to the static files", infallible)] + static_path: Cow<'static, str>, + /// Path to the MDBX database. + #[from_env(var = "SIGNET_DATABASE_PATH", desc = "Path to the MDBX database", infallbile)] + database_path: Cow<'static, str>, + /// URL to which to forward raw transactions. + #[from_env( + var = "TX_FORWARD_URL", + desc = "URL to which to forward raw transactions", + infallible, + optional + )] + forward_url: Option>, + /// RPC port to serve JSON-RPC requests + #[from_env(var = "RPC_PORT", desc = "RPC port to serve JSON-RPC requests", optional)] + http_port: Option, + /// Websocket port to serve JSON-RPC requests + #[from_env(var = "WS_RPC_PORT", desc = "Websocket port to serve JSON-RPC requests", optional)] + ws_port: Option, + /// IPC endpoint to serve JSON-RPC requests + #[from_env( + var = "IPC_ENDPOINT", + desc = "IPC endpoint to serve JSON-RPC requests", + infallible, + optional + )] + ipc_endpoint: Option>, + + /// Configuration loaded from genesis file, or known genesis. + genesis: GenesisSpec, + + /// The slot calculator. + slot_calculator: SlotCalculator, +} + +impl Display for SignetNodeConfig { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SignetNodeConfig").finish_non_exhaustive() + } +} + +impl SignetNodeConfig { + /// Create a new Signet Node configuration. + #[allow(clippy::too_many_arguments)] + pub const fn new( + block_extractor: BlobFetcherConfig, + static_path: Cow<'static, str>, + database_path: Cow<'static, str>, + forward_url: Option>, + rpc_port: u16, + ws_port: u16, + ipc_endpoint: Option>, + genesis: GenesisSpec, + slot_calculator: SlotCalculator, + ) -> Self { + Self { + block_extractor, + static_path, + database_path, + forward_url, + http_port: Some(rpc_port), + ws_port: Some(ws_port), + ipc_endpoint, + genesis, + slot_calculator, + } + } + + /// Get the blob explorer URL. + pub fn blob_explorer_url(&self) -> &str { + self.block_extractor.blob_explorer_url() + } + + /// Get the block extractor configuration. + pub const fn block_extractor(&self) -> &BlobFetcherConfig { + &self.block_extractor + } + + /// Get the consensus layer URL. + pub fn cl_url(&self) -> Option<&str> { + self.block_extractor.cl_url() + } + + /// Get the pylon URL + pub fn pylon_url(&self) -> Option<&str> { + self.block_extractor.pylon_url() + } + + /// Get a [`SlotCalculator`] + pub const fn slot_calculator(&self) -> SlotCalculator { + self.slot_calculator + } + + /// Get the static path as a str. + pub fn static_path_str(&self) -> &str { + &self.static_path + } + + /// Get the static path. + pub fn static_path(&self) -> PathBuf { + self.static_path.as_ref().to_owned().into() + } + + /// Get the static file provider for read-only access. + pub fn static_file_ro(&self) -> eyre::Result> { + StaticFileProvider::read_only(self.static_path(), true).map_err(Into::into) + } + + /// Get the static file provider for read-write access. + pub fn static_file_rw(&self) -> eyre::Result> { + StaticFileProvider::read_write(self.static_path()).map_err(Into::into) + } + + /// Get the database path as a str. + pub fn database_path_str(&self) -> &str { + &self.database_path + } + + /// Get the database path. + pub fn database_path(&self) -> PathBuf { + self.database_path.as_ref().to_owned().into() + } + + /// Get the URL to which to forward raw transactions. + pub fn forward_url(&self) -> Option { + self.forward_url + .as_deref() + .map(reqwest::Url::parse)? + .inspect_err(|e| warn!(%e, "failed to parse forward URL")) + .ok() + } + + /// Returns the port for serving JSON RPC requests for Signet Node. + pub const fn http_port(&self) -> u16 { + if let Some(port) = self.http_port { + return port; + } + SIGNET_NODE_DEFAULT_HTTP_PORT + } + + /// Set the HTTP port for serving JSON RPC requests for Signet Node. + pub const fn set_http_port(&mut self, port: u16) { + self.http_port = Some(port); + } + + /// Returns the port for serving Websocket RPC requests for Signet Node. + pub const fn ws_port(&self) -> u16 { + if let Some(port) = self.ws_port { + return port; + } + SIGNET_NODE_DEFAULT_HTTP_PORT + 1 + } + + /// Set the websocket port for serving JSON RPC requests for Signet. + pub const fn set_ws_port(&mut self, port: u16) { + self.ws_port = Some(port); + } + + /// Returns the IPC endpoint for serving JSON RPC requests for Signet, if any. + pub fn ipc_endpoint(&self) -> Option<&str> { + self.ipc_endpoint.as_deref() + } + + /// Set the IPC endpoint for serving JSON RPC requests for Signet Node. + pub fn set_ipc_endpoint(&mut self, endpoint: Cow<'static, str>) { + self.ipc_endpoint = Some(endpoint); + } + + /// Returns the genesis configuration if any has been loaded + pub fn genesis(&self) -> &'static Genesis { + static ONCE: OnceLock = OnceLock::new(); + ONCE.get_or_init(|| self.genesis.load_genesis().expect("Failed to load genesis")) + } + + /// Create a new chain spec for the Signet Node chain. + pub fn chain_spec(&self) -> &Arc { + static SPEC: OnceLock> = OnceLock::new(); + SPEC.get_or_init(|| Arc::new(self.genesis().clone().into())) + } + + /// Get the system constants for the Signet Node chain. + pub fn constants(&self) -> Result { + SignetSystemConstants::try_from_genesis(self.genesis()) + } + + /// Get the current spec id for the Signet Node chain. + pub fn spec_id(&self, timestamp: u64) -> SpecId { + if self.chain_spec().is_prague_active_at_timestamp(timestamp) { + SpecId::PRAGUE + } else { + SpecId::CANCUN + } + } +} + +#[cfg(test)] +mod defaults { + use super::*; + + impl Default for SignetNodeConfig { + fn default() -> Self { + Self { + block_extractor: BlobFetcherConfig::new(Cow::Borrowed("")), + static_path: Cow::Borrowed(""), + database_path: Cow::Borrowed(""), + forward_url: None, + http_port: Some(SIGNET_NODE_DEFAULT_HTTP_PORT), + ws_port: Some(SIGNET_NODE_DEFAULT_HTTP_PORT + 1), + ipc_endpoint: None, + genesis: GenesisSpec::Test, + + slot_calculator: SlotCalculator::new(0, 0, 12), + } + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn loads_genesis() { + let config = SignetNodeConfig::default(); + let genesis = config.genesis(); + assert_eq!(genesis.gas_limit, 0x1c9c380); + assert_eq!(genesis.number, None); + assert_eq!(genesis.base_fee_per_gas, Some(0x3b9aca00)); + assert!(genesis.config.extra_fields.get("signetConstants").is_some()); + } +} diff --git a/crates/node-config/src/lib.rs b/crates/node-config/src/lib.rs new file mode 100644 index 0000000..99a8f3c --- /dev/null +++ b/crates/node-config/src/lib.rs @@ -0,0 +1,21 @@ +#![doc = include_str!("../README.md")] +#![warn( + missing_copy_implementations, + missing_debug_implementations, + missing_docs, + unreachable_pub, + clippy::missing_const_for_fn, + rustdoc::all +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![deny(unused_must_use, rust_2018_idioms)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +mod core; +pub use core::{SIGNET_NODE_DEFAULT_HTTP_PORT, SignetNodeConfig}; + +mod rpc; + +/// Test configuration for Signet Nodes. +#[cfg(feature = "test_utils")] +pub mod test_utils; diff --git a/crates/node-config/src/rpc.rs b/crates/node-config/src/rpc.rs new file mode 100644 index 0000000..44e4258 --- /dev/null +++ b/crates/node-config/src/rpc.rs @@ -0,0 +1,29 @@ +use crate::SignetNodeConfig; +use reth::args::RpcServerArgs; +use reth_exex::ExExContext; +use reth_node_api::FullNodeComponents; + +impl SignetNodeConfig { + /// Inherits the IP host address from the Reth RPC server configuration, + /// and change the configured port for the RPC server. If the host server + /// is configured to use IPC, Signet Node will use the endpoint specified by the + /// environment variable `IPC_ENDPOINT`. + fn modify_args(&self, sc: &RpcServerArgs) -> eyre::Result { + let mut args = sc.clone(); + + args.http_port = self.http_port(); + args.ws_port = self.ws_port(); + args.ipcpath = self.ipc_endpoint().map(ToOwned::to_owned).unwrap_or_default(); + + Ok(args) + } + + /// Merges Signet Node configurations over the transport and rpc server + /// configurations, and returns the modified configs. + pub fn merge_rpc_configs(&self, exex: &ExExContext) -> eyre::Result + where + Node: FullNodeComponents, + { + self.modify_args(&exex.config.rpc) + } +} diff --git a/crates/node-config/src/test_utils.rs b/crates/node-config/src/test_utils.rs new file mode 100644 index 0000000..6f6497a --- /dev/null +++ b/crates/node-config/src/test_utils.rs @@ -0,0 +1,30 @@ +use crate::SignetNodeConfig; +use init4_bin_base::utils::calc::SlotCalculator; +use reth_db::test_utils::tempdir_path; +use signet_blobber::BlobFetcherConfig; +use signet_genesis::GenesisSpec; +use std::borrow::Cow; + +/// Make a test config +pub fn test_config() -> SignetNodeConfig { + let mut tempdir = tempdir_path(); + tempdir.push("signet.ipc"); + + // Make a new test config with the IPC endpoint set to the tempdir. + let mut cfg = TEST_CONFIG; + cfg.set_ipc_endpoint(Cow::Owned(format!("{}", tempdir.to_string_lossy()))); + cfg +} + +/// Test SignetNodeConfig +const TEST_CONFIG: SignetNodeConfig = SignetNodeConfig::new( + BlobFetcherConfig::new(Cow::Borrowed("")), + Cow::Borrowed("NOP"), + Cow::Borrowed("NOP"), + None, + 31391, // NOP + 31392, // NOP + Some(Cow::Borrowed("/trethNOP")), + GenesisSpec::Test, + SlotCalculator::new(0, 0, 12), +); diff --git a/crates/node-tests/Cargo.toml b/crates/node-tests/Cargo.toml new file mode 100644 index 0000000..0577309 --- /dev/null +++ b/crates/node-tests/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "signet-node-tests" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +signet-node.workspace = true +signet-node-config = { workspace = true, features = ["test_utils"] } +signet-node-types.workspace = true +signet-db.workspace = true + +signet-constants.workspace = true +signet-evm.workspace = true +signet-test-utils.workspace = true +signet-types.workspace = true +signet-zenith.workspace = true + +alloy.workspace = true + +reth.workspace = true +reth-db.workspace = true +reth-exex.workspace = true +reth-exex-test-utils.workspace = true +reth-node-api.workspace = true + +eyre.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true +tokio.workspace = true + +[dev-dependencies] +signet-genesis.workspace = true + +serde_json.workspace = true +serial_test = "3.2.0" diff --git a/crates/node-tests/README.md b/crates/node-tests/README.md new file mode 100644 index 0000000..6b5b841 --- /dev/null +++ b/crates/node-tests/README.md @@ -0,0 +1,15 @@ +# Signet Node Tests + +Test scaffolding crate, and integration tests for the Signet Node. + +This library contains the following: + +- `SignetTestContext` - A running test node with alloy providers and the + ability to send transactions, query state, and mine blocks. +- `run_test` - A helper function to run async tests with a fresh + `SignetTestContext`. +- `rpc_test` - A wrapper around `run_test` for testing RPC methods. +- Assorted test utilities and constants + +The `tests/` directory contains a number of integration tests for the +Signet Node, using the above scaffolding. diff --git a/crates/node-tests/src/aliases.rs b/crates/node-tests/src/aliases.rs new file mode 100644 index 0000000..fc91343 --- /dev/null +++ b/crates/node-tests/src/aliases.rs @@ -0,0 +1,69 @@ +use alloy::{ + network::{Ethereum, EthereumWallet}, + providers::{ + Identity, RootProvider, + fillers::{ + BlobGasFiller, ChainIdFiller, FillProvider, GasFiller, JoinFill, NonceFiller, + SimpleNonceManager, WalletFiller, + }, + }, +}; + +/// The alloy provider type for the Signet Node test context +pub type CtxProvider = FillProvider< + JoinFill< + JoinFill< + JoinFill< + JoinFill, GasFiller>, + NonceFiller, + >, + ChainIdFiller, + >, + WalletFiller, + >, + RootProvider, +>; + +/// Counter contract instance type with the Signet test context's provider. +pub type TestCounterInstance = Counter::CounterInstance; + +/// Log contract instance type with the Signet test context's provider. +pub type TestLogInstance = Log::LogInstance; + +/// ERC20 contract instance type with the Signet test context's provider. +pub type TestErc20Instance = Erc20::Erc20Instance; + +pub use signet_test_utils::contracts::counter::Counter; + +alloy::sol! { + #[derive(Debug)] + #[sol(rpc)] + contract Erc20 { + function balanceOf(address) public view returns (uint256); + function approve(address, uint256) public returns (bool); + + function name() public view returns (string); + function symbol() public view returns (string); + function decimals() public view returns (uint8); + } +} + +// Codegen from embedded Solidity code and precompiled bytecode. +// solc v0.8.25 Log.sol --via-ir --optimize --bin +alloy::sol!( + #[allow(missing_docs)] + #[sol(rpc, bytecode = "6080806040523460135760c9908160188239f35b5f80fdfe6004361015600b575f80fd5b5f3560e01c80637b3ab2d014605f57639ee1a440146027575f80fd5b34605b575f366003190112605b577f2d67bb91f17bca05af6764ab411e86f4ddf757adb89fcec59a7d21c525d417125f80a1005b5f80fd5b34605b575f366003190112605b577fbcdfe0d5b27dd186282e187525415c57ea3077c34efb39148111e4d342e7ab0e5f80a100fea2646970667358221220f6b42b522bc9fb2b4c7d7e611c7c3e995d057ecab7fd7be4179712804c886b4f64736f6c63430008190033")] + contract Log { + #[derive(Debug)] + event Hello(); + event World(); + + function emitHello() public { + emit Hello(); + } + + function emitWorld() public { + emit World(); + } + } +); diff --git a/crates/node-tests/src/constants.rs b/crates/node-tests/src/constants.rs new file mode 100644 index 0000000..67099af --- /dev/null +++ b/crates/node-tests/src/constants.rs @@ -0,0 +1,8 @@ +use alloy::primitives::Address; +use signet_constants::SignetSystemConstants; + +/// The default test constants for the Signet system. +pub const TEST_CONSTANTS: SignetSystemConstants = SignetSystemConstants::test(); + +/// Default reward address used in tests when no other is specified. +pub const DEFAULT_REWARD_ADDRESS: Address = Address::repeat_byte(7); diff --git a/crates/node-tests/src/context.rs b/crates/node-tests/src/context.rs new file mode 100644 index 0000000..921bfd4 --- /dev/null +++ b/crates/node-tests/src/context.rs @@ -0,0 +1,642 @@ +use crate::{ + HostBlockSpec, NotificationSpec, NotificationWithSidecars, RuBlockSpec, + aliases::{CtxProvider, Log, TestCounterInstance, TestErc20Instance, TestLogInstance}, + convert::ToRethPrimitive, + utils::create_test_provider_factory_with_chain_spec, +}; +use alloy::{ + consensus::{BlockHeader, TxEnvelope, constants::ETH_TO_WEI}, + genesis::{Genesis, GenesisAccount}, + network::{Ethereum, EthereumWallet, TransactionBuilder as _}, + primitives::{Address, I256, Sign, U256, keccak256}, + providers::{ + Provider as _, ProviderBuilder, SendableTx, + fillers::{BlobGasFiller, SimpleNonceManager}, + }, + rpc::types::eth::{TransactionReceipt, TransactionRequest}, +}; +use reth::{ + primitives::Account, + providers::{AccountReader, BlockNumReader, ProviderFactory}, + transaction_pool::{TransactionOrigin, TransactionPool, test_utils::MockTransaction}, +}; +use reth_db::{PlainAccountState, transaction::DbTxMut}; +use reth_exex_test_utils::{Adapter, TestExExHandle, TmpDB as TmpDb}; +use reth_node_api::FullNodeComponents; +use signet_db::DbProviderExt; +use signet_node::SignetNode; +use signet_node_config::test_utils::test_config; +use signet_node_types::{NodeStatus, SignetNodeTypes}; +use signet_test_utils::contracts::counter::COUNTER_DEPLOY_CODE; +use signet_types::constants::{HostPermitted, RollupPermitted, SignetSystemConstants}; +use signet_zenith::{HostOrders::OrdersInstance, RollupPassage::RollupPassageInstance}; +use std::sync::{ + Arc, + atomic::{AtomicU64, Ordering}, +}; +use tokio::{sync::watch, task::JoinHandle}; +use tracing::instrument; + +/// Signet Node test context +/// +/// This contains the following: +/// +/// - Reth/ExEx context info +/// - The test exex handle, which is used to send notifications to the signet +/// instance. +/// - The components for the Signet Node instance +/// - A receiver for the node status (latest block processed) +/// - A DB provider factory +/// - An alloy provider connected to the Signet Node RPC, +/// - Configured with standard fillers +/// - A height, used to fill in block numbers for host block notifications +/// - A set of addresses for testing, each of which has a pre-existing balance +/// on the Signet Node chain. +pub struct SignetTestContext { + /// The test exex handle + pub handle: TestExExHandle, + + /// The components for the Signet Node instance + pub components: Adapter, + + /// The Signet Node status receiver + pub node_status: watch::Receiver, + + /// The provider factory for the Signet Node instance + pub factory: ProviderFactory>, + + /// An alloy provider connected to the Signet Node RPC. + pub alloy_provider: CtxProvider, + + /// The system constants for the Signet Node instance. + pub constants: SignetSystemConstants, + + /// The current host block height + pub height: AtomicU64, + + /// Test addreses, copied from [`signet_types::test_utils::TEST_USERS`] for + /// convenience + pub addresses: [Address; 10], +} + +impl core::fmt::Debug for SignetTestContext { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("SignetTestContext").finish() + } +} + +impl SignetTestContext { + /// Make a new test env + #[instrument] + pub async fn new() -> (Self, JoinHandle>) { + let cfg = test_config(); + let (ctx, handle) = reth_exex_test_utils::test_exex_context().await.unwrap(); + let components = ctx.components.clone(); + + // set up Signet Node db + let constants = cfg.constants().unwrap(); + let chain_spec: Arc<_> = cfg.chain_spec().clone(); + + let factory = create_test_provider_factory_with_chain_spec(chain_spec.clone()); + + // instantiate Signet Node, booting rpc + let (node, mut node_status) = + SignetNode::new(ctx, cfg.clone(), factory.clone(), Default::default()).unwrap(); + + // Spawn the node, and wait for it to indicate RPC readiness. + let node = tokio::spawn(node.start()); + node_status.changed().await.unwrap(); + + // set up some keys and addresses + let keys = &signet_test_utils::users::TEST_SIGNERS; + let addresses = *signet_test_utils::users::TEST_USERS; + + // register the signers on the alloy proider + let mut wallet = EthereumWallet::new(keys[0].clone()); + for key in keys.iter().skip(1) { + wallet.register_signer(key.clone()); + } + + let mint_amnt = U256::from(1_000) * U256::from(ETH_TO_WEI); + factory + .provider_rw() + .unwrap() + .update(|rw| { + for address in addresses.into_iter() { + let mut account = rw.basic_account(&address)?.unwrap_or_default(); + account.balance = account.balance.saturating_add(mint_amnt); + rw.tx_ref().put::(address, account)?; + } + Ok(()) + }) + .unwrap(); + + // after RPC booted, we can create the alloy provider + let alloy_provider = ProviderBuilder::new_with_network() + .disable_recommended_fillers() + .filler(BlobGasFiller) + .with_gas_estimation() + .with_nonce_management(SimpleNonceManager::default()) + .with_chain_id(constants.ru_chain_id()) + .wallet(wallet) + .connect(cfg.ipc_endpoint().unwrap()) + .await + .unwrap(); + + let this = Self { + handle, + components, + node_status, + factory, + alloy_provider, + constants, + height: AtomicU64::new(cfg.constants().unwrap().host_deploy_height()), + + addresses, + }; + + (this, node) + } + + /// Clone the Signet system constants + pub fn constants(&self) -> SignetSystemConstants { + self.constants.clone() + } + + /// Send a notification to the Signet Node instance + pub async fn send_notification(&self, notification: NotificationWithSidecars) { + let pool = self.components.pool(); + + // Put these into the pool so that Signet Node can find them + for (_, (sidecar, tx_signed)) in notification.sidecars { + let tx_hash = *tx_signed.hash(); + let mut tx = MockTransaction::eip4844_with_sidecar(sidecar.into()); + tx.set_hash(tx_hash); + pool.add_transaction(TransactionOrigin::Local, tx).await.unwrap(); + + assert!(pool.get_blob(tx_hash).unwrap().is_some(), "Missing blob we just inserted"); + } + + self.handle.notifications_tx.send(notification.notification.to_reth()).await.unwrap(); + } + + /// Send a notification to the Signet Node instance and wait for it to be + /// processed. Does not override block height with the current height. + async fn process_notification( + &self, + notification: NotificationWithSidecars, + ) -> Result<(), watch::error::RecvError> { + let mut recv = self.node_status.clone(); + async move { + let committed_chain = notification.notification.committed_chain(); + let reverted_chain = notification.notification.reverted_chain(); + + // the expected height is either the last committed block, or the + // first reverted block - 1, or 0 if neither exist + let expected_height = committed_chain + .and_then(|c| c.blocks.last().map(|b| b.number())) + .or_else(|| { + reverted_chain + .and_then(|c| c.blocks.first().map(|b| b.number().saturating_sub(1))) + }) + .unwrap_or(0) + .saturating_sub(self.constants().host_deploy_height()); + + recv.mark_unchanged(); + self.send_notification(notification).await; + recv.changed().await?; + + // cheeky little check that the RPC is correct :) + assert_eq!(self.alloy_provider.get_block_number().await.unwrap(), expected_height); + + Ok(()) + } + .await + } + + /// Send a single block to the signet node instance and wait for it to be + /// processed. Overrides block height with the current height. + pub async fn process_block(&self, block: HostBlockSpec) -> Result<(), watch::error::RecvError> { + block.set_block_number(self.height.fetch_add(1, Ordering::SeqCst) + 1); + + let notification = NotificationWithSidecars::commit_single_block(block); + + self.process_notification(notification).await + } + + /// Send multiple blocks to the signet node instance and wait for them to be + /// processed. Overrides block heights with the correct height. + pub async fn process_blocks( + &self, + blocks: Vec, + ) -> Result<(), watch::error::RecvError> { + let mut spec = NotificationSpec::default(); + for block in blocks.into_iter() { + block.set_block_number(self.height.fetch_add(1, Ordering::SeqCst) + 1); + spec = spec.commit(block); + } + + self.process_notification(spec.to_exex_notification()).await + } + + /// Revert a single block and wait for it to be processed. Overrides + /// block height with the current height. + pub async fn revert_block(&self, block: HostBlockSpec) -> Result<(), watch::error::RecvError> { + block.set_block_number(self.height.fetch_sub(1, Ordering::SeqCst)); + + let notification = NotificationWithSidecars::revert_single_block(block); + + self.process_notification(notification).await + } + + /// Get the current host height. + pub fn height(&self) -> u64 { + self.height.load(Ordering::SeqCst) + } + + /// Get the account for an address. + pub fn account(&self, address: Address) -> Option { + self.factory.provider().unwrap().basic_account(&address).unwrap() + } + + /// Get the nonce off an addresss. + pub fn nonce(&self, address: Address) -> u64 { + self.account(address).unwrap_or_default().nonce + } + + /// Get the balance of an address. + pub fn balance_of(&self, address: Address) -> U256 { + self.account(address).unwrap_or_default().balance + } + + /// Track the balance of an address in a [`BalanceChecks`] guard. + pub fn track_balance( + &self, + address: Address, + label: Option<&'static str>, + ) -> BalanceChecks<'_> { + BalanceChecks::new(self, address, label) + } + + /// Track the nonce of an address in a [`NonceChecks`] guard. + pub fn track_nonce(&self, address: Address, label: Option<&'static str>) -> NonceChecks<'_> { + NonceChecks::new(self, address, label) + } + + /// Fill an alloy transaction + pub async fn fill_alloy_tx(&self, tx: &TransactionRequest) -> eyre::Result { + let SendableTx::Envelope(tx) = self.alloy_provider.fill(tx.clone()).await? else { + panic!("tx not completely filled") + }; + Ok(tx) + } + + /// Deploy the test Counter contract and return its address. + pub async fn deploy_counter(&self, deployer: Address) -> TestCounterInstance { + let contract_address = deployer.create(self.nonce(deployer)); + let tx = TransactionRequest::default() + .from(deployer) + .gas_limit(21_000_000) + .with_deploy_code(COUNTER_DEPLOY_CODE); + + let (_tx, _receipt) = self.process_alloy_tx(&tx).await.unwrap(); + + TestCounterInstance::new(contract_address, self.alloy_provider.clone()) + } + + /// Deploy the test Log contract and return its address. + pub async fn deploy_log(&self, deployer: Address) -> TestLogInstance { + let contract_address = deployer.create(self.nonce(deployer)); + let tx = TransactionRequest::default() + .from(deployer) + .gas_limit(21_000_000) + .with_deploy_code(Log::BYTECODE.clone()); + + let (_tx, _receipt) = self.process_alloy_tx(&tx).await.unwrap(); + + TestLogInstance::new(contract_address, self.alloy_provider.clone()) + } + + /// Process an alloy transaction + #[must_use = "Don't forget to make assertions :)"] + pub async fn process_alloy_tx( + &self, + tx: &TransactionRequest, + ) -> eyre::Result<(TxEnvelope, TransactionReceipt)> { + let tx = self.fill_alloy_tx(tx).await?; + + let ru_block = RuBlockSpec::new(self.constants.clone()).alloy_tx(&tx); + let host_block = HostBlockSpec::new(self.constants.clone()).submit_block(ru_block); + + self.process_block(host_block).await?; + + let tx_hash = tx.tx_hash(); + let receipt = self + .alloy_provider + .get_transaction_receipt(*tx_hash) + .await? + .ok_or_else(|| eyre::eyre!("no receipt"))?; + + tracing::trace!( + ?tx, + ?receipt, + %tx_hash, + "Processed alloy tx" + ); + + Ok((tx, receipt)) + } + + /// Verify all the allocations in a genesis block. This will only make + /// assertions if run on the genesis block. If any other blocks have been + /// processed it will do nothing. + pub fn verify_allocs(&self, genesis: &Genesis) { + if self.factory.provider().unwrap().last_block_number().unwrap() != 0 { + return; + } + + for (acct, alloc) in genesis.alloc.iter() { + self.verify_alloc(*acct, alloc); + } + } + + #[track_caller] + fn verify_alloc(&self, address: Address, alloc: &GenesisAccount) { + let account = self.account(address).unwrap(); + assert_eq!(account.balance, alloc.balance); + assert_eq!(account.nonce, alloc.nonce.unwrap_or_default()); + + if let Some(ref code) = alloc.code { + assert_eq!(account.bytecode_hash, Some(keccak256(code))); + } else { + assert_eq!(account.bytecode_hash, None); + } + + if let Some(ref storage) = alloc.storage { + for (key, value) in storage { + assert_eq!( + self.factory.latest().unwrap().storage(address, *key).unwrap(), + Some((*value).into()) + ); + } + } + } + + /// Get the passage contract instance. + pub fn ru_passage_contract(&self) -> RollupPassageInstance { + RollupPassageInstance::new(self.constants.rollup().passage(), self.alloy_provider.clone()) + } + + /// Get the orders contract instance. + pub fn ru_orders_contract(&self) -> OrdersInstance { + OrdersInstance::new(self.constants.rollup().orders(), self.alloy_provider.clone()) + } + + /// Mint tokens for the user + pub async fn mint_token( + &self, + token: HostPermitted, + user: Address, + amount: usize, + ) -> eyre::Result<()> { + let host_token = self.constants.host().tokens().address_for(token); + let ru_token = self.constants.rollup().tokens().address_for(token.into()); + + let block = + HostBlockSpec::new(self.constants.clone()).enter_token(user, amount, host_token); + self.process_block(block).await.unwrap(); + + let ru_token = TestErc20Instance::new(ru_token, self.alloy_provider.clone()); + assert_eq!(ru_token.balanceOf(user).call().await.unwrap(), U256::from(amount)); + Ok(()) + } + + /// Get a token contract instance for a given rollup token. + pub fn token_instance(&self, rollup: RollupPermitted) -> TestErc20Instance { + let address = self.constants.rollup().tokens().address_for(rollup); + TestErc20Instance::new(address, self.alloy_provider.clone()) + } +} + +/// A guard that checks the nonce of an address +#[derive(Debug, Copy, Clone)] +pub struct NonceChecks<'a> { + ctx: &'a SignetTestContext, + address: Address, + stored: u64, + label: Option<&'static str>, +} + +impl<'a> NonceChecks<'a> { + /// Create a new nonce checks guard. + pub fn new(ctx: &'a SignetTestContext, address: Address, label: Option<&'static str>) -> Self { + let stored = ctx.nonce(address); + Self { ctx, address, stored, label } + } + + /// Format an error message with the address or label + fn fmt_err_str(&self, message: String) -> String { + let this = if let Some(label) = self.label { + label.to_owned() + } else { + format!("{}", self.address) + }; + + format!(r#"\nAssertion error for "{this}".\n{message}\n"#) + } + + /// Get the previous nonce of the address. + pub const fn previous_nonce(&self) -> u64 { + self.stored + } + + /// Update the stored nonce, returning the old value. + pub fn update_nonce(&mut self) -> u64 { + let current = self.stored; + self.stored = self.ctx.nonce(self.address); + current + } + + /// Assert that the nonce of the address has increased. + pub fn assert_increase_by(&mut self, amount: u64) { + let old_nonce = self.update_nonce(); + let expected = old_nonce + amount; + assert_eq!( + self.stored, + expected, + "{}", + self.fmt_err_str(format!( + "expected nonce increase to be {}. Got nonce {}", + expected, self.stored + )) + ); + } + + /// Assert that the nonce of the address has increased by 1. + pub fn assert_incremented(&mut self) { + self.assert_increase_by(1); + } +} + +/// A guard that checks the balance of an address +#[derive(Debug, Copy, Clone)] +pub struct BalanceChecks<'a> { + ctx: &'a SignetTestContext, + address: Address, + stored: U256, + label: Option<&'static str>, +} + +impl<'a> BalanceChecks<'a> { + /// Instantiate a new balance checks guard. + pub fn new(ctx: &'a SignetTestContext, address: Address, label: Option<&'static str>) -> Self { + let stored = ctx.balance_of(address); + Self { ctx, address, stored, label } + } + + fn fmt_err_str(&self, message: String) -> String { + let this = if let Some(label) = self.label { + label.to_owned() + } else { + format!("{}", self.address) + }; + + format!(r#"\nAssertion error for "{this}".\n{message}\n"#) + } + + /// Get the previous balance of the address. + pub const fn previous_balance(&self) -> U256 { + self.stored + } + + /// Update the stored balance, returning the old value. + pub fn update_balance(&mut self) -> U256 { + let current = self.stored; + self.stored = self.ctx.balance_of(self.address); + current + } + + /// Assert that the balance of the address has changed by a certain amount. + /// Update the previous balance to the new balance. + #[track_caller] + pub fn assert_change(&mut self, change: I256) { + let old_balance = self.update_balance(); + + let (sign, abs) = change.into_sign_and_abs(); + + let (actual_sign, actual) = if self.stored > old_balance { + (Sign::Positive, self.stored - old_balance) + } else { + (Sign::Negative, old_balance - self.stored) + }; + + assert_eq!( + (actual_sign, actual), + (sign, abs), + "{}", + self.fmt_err_str(format!( + "expected balance change of {}{}. Got balance change of {}{}", + sign, + abs, + actual_sign, + self.stored.abs_diff(old_balance) + )) + ); + } + + /// Assert that the balance has decreased. + #[track_caller] + pub fn assert_decrease(&mut self) { + let old_balance = self.update_balance(); + assert!( + self.stored < old_balance, + "{}", + self.fmt_err_str(format!( + "expected balance decrease. Got balance increase of {}", + self.stored.abs_diff(old_balance) + )) + ); + } + + /// Assert that the balance has decreased by at least a certain amount. + #[track_caller] + pub fn assert_decrease_at_least(&mut self, amount: U256) { + let old_balance = self.update_balance(); + assert!( + self.stored <= old_balance - amount, + "{}", + self.fmt_err_str(format!( + "expected balance decrease of at least {}. Got balance increase of {}", + amount, + self.stored.abs_diff(old_balance) + )) + ); + } + + /// Assert that the balance has decreased by exactly a certain amount. + #[track_caller] + pub fn assert_decrease_exact(&mut self, amount: U256) { + let change = I256::checked_from_sign_and_abs(Sign::Negative, amount).unwrap(); + self.assert_change(change) + } + + /// Assert that the balance has increased. + #[track_caller] + pub fn assert_increase(&mut self) { + let old_balance = self.update_balance(); + assert!( + self.stored > old_balance, + "{}", + self.fmt_err_str(format!( + "expected balance increase. Got balance decrease of {}", + self.stored.abs_diff(old_balance) + )) + ); + } + + /// Assert that the balance has increased by at least a certain amount. + #[track_caller] + pub fn assert_increase_at_least(&mut self, amount: U256) { + let old_balance = self.update_balance(); + assert!( + self.stored >= old_balance + amount, + "{}", + self.fmt_err_str(format!( + "expected balance increase of at least {}. Got balance decrease of {}", + amount, + self.stored.abs_diff(old_balance) + )) + ); + } + + /// Assert that the balance has increased by exactly a certain amount. + #[track_caller] + pub fn assert_increase_exact(&mut self, amount: U256) { + let change = I256::checked_from_sign_and_abs(Sign::Positive, amount).unwrap(); + self.assert_change(change) + } + + /// Assert that the balance has not changed. + #[track_caller] + pub fn assert_no_change(&mut self) { + let old_balance = self.update_balance(); + assert_eq!( + self.stored, + old_balance, + "{}", + self.fmt_err_str("expected no balance change".to_owned()) + ); + } + + /// Assert that the balance is equal to a certain value. + #[track_caller] + pub fn assert_eq(&mut self, expected: U256) { + let _old_balance = self.update_balance(); + assert_eq!( + self.stored, + expected, + "{}", + self.fmt_err_str(format!("expected balance of {expected}")) + ) + } +} diff --git a/crates/node-tests/src/convert.rs b/crates/node-tests/src/convert.rs new file mode 100644 index 0000000..2601a6e --- /dev/null +++ b/crates/node-tests/src/convert.rs @@ -0,0 +1,132 @@ +use alloy::consensus::ReceiptEnvelope; +use signet_evm::ExecutionOutcome; +use signet_types::primitives::{RecoveredBlock, SealedBlock}; +use std::sync::Arc; + +/// Utility trait to convert a type to a Reth primitive type. +/// This is used mainly where we need to convert to a reth primitive type +/// because reth does not support the alloy equivalents. +pub trait ToRethPrimitive { + /// The Reth primitive type that the type can be converted to. + type RethPrimitive; + + /// Convert the type to a Reth primitive type. + fn to_reth(self) -> Self::RethPrimitive; +} + +// Reth does not preserve envelope status for receipts, so +// the DB model will not support envelopes. +impl ToRethPrimitive for ReceiptEnvelope { + type RethPrimitive = reth::primitives::Receipt; + + fn to_reth(self) -> Self::RethPrimitive { + let success = self.is_success(); + let cumulative_gas_used = self.cumulative_gas_used(); + let tx_type = match self.tx_type() { + alloy::consensus::TxType::Legacy => reth::primitives::TxType::Legacy, + alloy::consensus::TxType::Eip2930 => reth::primitives::TxType::Eip2930, + alloy::consensus::TxType::Eip1559 => reth::primitives::TxType::Eip1559, + alloy::consensus::TxType::Eip4844 => reth::primitives::TxType::Eip4844, + alloy::consensus::TxType::Eip7702 => reth::primitives::TxType::Eip7702, + }; + + let r = match self { + ReceiptEnvelope::Legacy(r) + | ReceiptEnvelope::Eip2930(r) + | ReceiptEnvelope::Eip1559(r) + | ReceiptEnvelope::Eip4844(r) => r, + _ => panic!("unsupported receipt type"), + }; + + reth::primitives::Receipt { tx_type, success, cumulative_gas_used, logs: r.receipt.logs } + } +} + +impl ToRethPrimitive for SealedBlock { + type RethPrimitive = reth::primitives::SealedBlock; + + fn to_reth(self) -> Self::RethPrimitive { + let (hash, header) = self.header.split(); + reth::primitives::SealedBlock::new_unchecked( + reth::primitives::Block::new(header, self.body), + hash, + ) + } +} + +impl ToRethPrimitive for RecoveredBlock { + type RethPrimitive = reth::primitives::RecoveredBlock; + + fn to_reth(self) -> Self::RethPrimitive { + let hash = self.block.header.hash(); + reth::primitives::RecoveredBlock::new(self.block.to_reth().into_block(), self.senders, hash) + } +} + +impl ToRethPrimitive for signet_test_utils::chain::Chain { + type RethPrimitive = reth::providers::Chain; + + fn to_reth(self) -> Self::RethPrimitive { + reth::providers::Chain::new(self.blocks.to_reth(), self.execution_outcome.to_reth(), None) + } +} + +impl ToRethPrimitive for Vec +where + T: ToRethPrimitive, +{ + type RethPrimitive = Vec; + + fn to_reth(self) -> Self::RethPrimitive { + self.into_iter().map(ToRethPrimitive::to_reth).collect() + } +} + +impl ToRethPrimitive for ExecutionOutcome { + type RethPrimitive = reth::providers::ExecutionOutcome; + + fn to_reth(self) -> Self::RethPrimitive { + let (bundle, receipts, first_block) = self.into_parts(); + + reth::providers::ExecutionOutcome { + bundle, + receipts: receipts.into_iter().map(ToRethPrimitive::to_reth).collect(), + first_block, + requests: vec![], + } + } +} + +impl ToRethPrimitive for signet_test_utils::specs::ExExNotification { + type RethPrimitive = reth_exex::ExExNotification; + + fn to_reth(self) -> Self::RethPrimitive { + match self { + signet_test_utils::specs::ExExNotification::Committed { new } => { + reth_exex::ExExNotification::ChainCommitted { new: new.to_reth() } + } + signet_test_utils::specs::ExExNotification::Reorged { old, new } => { + reth_exex::ExExNotification::ChainReorged { old: old.to_reth(), new: new.to_reth() } + } + signet_test_utils::specs::ExExNotification::Reverted { old } => { + reth_exex::ExExNotification::ChainReverted { old: old.to_reth() } + } + } + } +} + +impl ToRethPrimitive for Arc { + type RethPrimitive = Arc; + + fn to_reth(self) -> Self::RethPrimitive { + Arc::new(ToRethPrimitive::to_reth((*self).clone())) + } +} + +impl ToRethPrimitive for &T { + type RethPrimitive = T::RethPrimitive; + + fn to_reth(self) -> Self::RethPrimitive { + ToRethPrimitive::to_reth(self.clone()) + } +} diff --git a/crates/node-tests/src/lib.rs b/crates/node-tests/src/lib.rs new file mode 100644 index 0000000..8a10d80 --- /dev/null +++ b/crates/node-tests/src/lib.rs @@ -0,0 +1,38 @@ +#![doc = include_str!("../README.md")] +#![warn( + missing_copy_implementations, + missing_debug_implementations, + missing_docs, + unreachable_pub, + clippy::missing_const_for_fn, + rustdoc::all +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![deny(unused_must_use, rust_2018_idioms)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +/// Test aliases and type definitions. +pub mod aliases; + +/// Test constants. +pub mod constants; + +/// Test context. +mod context; +pub use context::SignetTestContext; + +/// Bespoke conversion utilities for converting between alloy and reth types. +pub mod convert; + +/// Signet node RPC server utilities and helpers. +pub mod rpc; +pub use rpc::rpc_test; + +/// Utility functions and test harnesses. +pub mod utils; +pub use utils::run_test; + +pub use reth_exex_test_utils::{Adapter, TestExExContext, TmpDB as TmpDb}; +pub use signet_test_utils::specs::{ + HostBlockSpec, NotificationSpec, NotificationWithSidecars, RuBlockSpec, +}; diff --git a/crates/node-tests/src/rpc.rs b/crates/node-tests/src/rpc.rs new file mode 100644 index 0000000..2e55c86 --- /dev/null +++ b/crates/node-tests/src/rpc.rs @@ -0,0 +1,19 @@ +use crate::{aliases::TestCounterInstance, context::SignetTestContext, utils::run_test}; + +/// A test helper that sets up a Signet test context, deploys the Counter +/// contract, and then runs the provided async function `f` with the context and +/// the deployed contract instance. +pub async fn rpc_test(f: F) +where + F: FnOnce(SignetTestContext, TestCounterInstance) -> Fut + Send, + Fut: Future + Send, +{ + run_test(|ctx| async move { + let deployer = ctx.addresses[0]; + + let instance = ctx.deploy_counter(deployer).await; + + f(ctx, instance).await; + }) + .await; +} diff --git a/crates/node-tests/src/utils.rs b/crates/node-tests/src/utils.rs new file mode 100644 index 0000000..1fa980b --- /dev/null +++ b/crates/node-tests/src/utils.rs @@ -0,0 +1,137 @@ +use crate::{constants::TEST_CONSTANTS, context::SignetTestContext}; +use alloy::{ + consensus::{SignableTransaction, TxEip1559, constants::GWEI_TO_WEI}, + primitives::{Address, B256, FixedBytes, Sealable, TxKind, U256}, + signers::{SignerSync, local::PrivateKeySigner}, + uint, +}; +use reth::{ + chainspec::ChainSpec, + primitives::{Block, BlockBody, Header, RecoveredBlock, Transaction, TransactionSigned}, + providers::{ProviderFactory, providers::StaticFileProvider}, +}; +use reth_db::test_utils::{create_test_rw_db, create_test_static_files_dir}; +use reth_exex_test_utils::TmpDB; +use signet_node_types::SignetNodeTypes; +use signet_zenith::Zenith; +use std::{panic, sync::Once}; +use tracing_subscriber::EnvFilter; + +/// Make a fake block with a specific number. +pub fn fake_block(number: u64) -> RecoveredBlock { + let header = Header { + difficulty: U256::from(0x4000_0000), + number, + mix_hash: B256::repeat_byte(0xed), + nonce: FixedBytes::repeat_byte(0xbe), + timestamp: 1716555586, // the time when i wrote this function lol + excess_blob_gas: Some(0), + ..Default::default() + }; + let (header, hash) = header.seal_slow().into_parts(); + + let senders = vec![]; + RecoveredBlock::new( + Block::new(header, BlockBody { transactions: vec![], ommers: vec![], withdrawals: None }), + senders, + hash, + ) +} + +/// Sign a transaction with a wallet. +pub fn sign_tx_with_key_pair(wallet: &PrivateKeySigner, tx: Transaction) -> TransactionSigned { + let signature = wallet.sign_hash_sync(&tx.signature_hash()).unwrap(); + TransactionSigned::new_unhashed(tx, signature) +} + +/// Make a wallet with a deterministic keypair. +pub fn make_wallet(i: u8) -> PrivateKeySigner { + PrivateKeySigner::from_bytes(&B256::repeat_byte(i)).unwrap() +} + +/// Make a simple send transaction. +pub fn simple_send(to: Address, amount: U256, nonce: u64) -> Transaction { + TxEip1559 { + nonce, + gas_limit: 21_000, + to: TxKind::Call(to), + value: amount, + chain_id: TEST_CONSTANTS.ru_chain_id(), + max_fee_per_gas: GWEI_TO_WEI as u128 * 100, + max_priority_fee_per_gas: GWEI_TO_WEI as u128, + ..Default::default() + } + .into() +} + +/// Make a zenith header with a specific sequence number. +pub fn zenith_header(host_height: u64) -> Zenith::BlockHeader { + Zenith::BlockHeader { + rollupChainId: U256::from(TEST_CONSTANTS.ru_chain_id()), + hostBlockNumber: U256::from(host_height), + gasLimit: U256::from(100_000_000), + rewardAddress: Default::default(), + blockDataHash: Default::default(), + } +} + +/// Run a test with a context and Signet Node instance. +pub async fn run_test(f: F) +where + F: FnOnce(SignetTestContext) -> Fut, + Fut: std::future::Future + Send, +{ + static TRACING_INIT: Once = Once::new(); + + TRACING_INIT.call_once(|| { + tracing_subscriber::fmt::fmt() + .with_max_level(None) + .with_env_filter( + EnvFilter::from_default_env().add_directive("reth_tasks=off".parse().unwrap()), + ) + .init(); + }); + + let (ctx, signet) = SignetTestContext::new().await; + + f(ctx).await; + + signet.abort(); + match signet.await { + Ok(res) => res.unwrap(), + Err(err) => { + if let Ok(reason) = err.try_into_panic() { + panic::resume_unwind(reason); + } + } + } +} + +/// Adjust the amount of USD to the correct decimal places. +/// +/// This is calculated as `amount * 10^(18 - decimals)`. +pub fn adjust_usd_decimals_u256(amount: U256, decimals: u8) -> U256 { + uint! { + amount * 10_U256.pow(18_U256 - U256::from(decimals)) + } +} + +/// Adjust the amount of USD to the correct decimal places for a usize input. +/// +/// This is calculated as `amount * 10^(18 - decimals)`. +pub fn adjust_usd_decimals(amount: usize, decimals: u8) -> U256 { + adjust_usd_decimals_u256(U256::from(amount), decimals) +} + +/// Create a provider factory with a chain spec +pub fn create_test_provider_factory_with_chain_spec( + chain_spec: std::sync::Arc, +) -> ProviderFactory> { + let (static_dir, _) = create_test_static_files_dir(); + let db = create_test_rw_db(); + ProviderFactory::new( + db, + chain_spec, + StaticFileProvider::read_write(static_dir.keep()).expect("static file provider"), + ) +} diff --git a/crates/node-tests/tests/artifacts/Counter.sol b/crates/node-tests/tests/artifacts/Counter.sol new file mode 100644 index 0000000..bc83582 --- /dev/null +++ b/crates/node-tests/tests/artifacts/Counter.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract Counter { + uint256 public count; + event Count(uint256 indexed count); + + constructor() { + count = 0; + } + function increment() public { + count += 1; + emit Count(count); + } +} \ No newline at end of file diff --git a/crates/node-tests/tests/artifacts/MyContract.bin b/crates/node-tests/tests/artifacts/MyContract.bin new file mode 100644 index 0000000..f336aa2 --- /dev/null +++ b/crates/node-tests/tests/artifacts/MyContract.bin @@ -0,0 +1,4 @@ + +======= crates/test-utils/tests/Counter.sol:Counter ======= +Binary: +608080604052346016575f805560d79081601b8239f35b5f80fdfe60808060405260043610156011575f80fd5b5f3560e01c90816306661abd14608a575063d09de08a14602f575f80fd5b346086575f3660031901126086575f5460018101809111607257805f557face32e4392fafee7f8245a5ae6a32722dc74442d018c52e460835648cbeeeba15f80a2005b634e487b7160e01b5f52601160045260245ffd5b5f80fd5b346086575f3660031901126086576020905f548152f3fea264697066735822122027a064635c397ba96bfe6d499e93133378e80d56d94510a0ffa4a51969bcf09464736f6c634300081a0033 diff --git a/crates/node-tests/tests/artifacts/blob.json b/crates/node-tests/tests/artifacts/blob.json new file mode 100644 index 0000000..5878db1 --- /dev/null +++ b/crates/node-tests/tests/artifacts/blob.json @@ -0,0 +1,41 @@ +{ + "hash": "0x85228e97acb606c31a7bfeb00cefab34fcfeba41ca5aedf8500d62a6db8c5259", + "blockNumber": 2606448, + "blockTimestamp": "2024-10-25T18:53:12.000Z", + "blockHash": "0x4c726e829f7f1cc602166e7ca59007cc6c78c36f79ad6d835ee2886d6314204b", + "index": 17, + "from": "0x4c3e529d2359d8dbb1a4fc8be1555427efb32e7c", + "to": "0xf8c9d5a1b5ea87411fa72079f748441fedd08967", + "maxFeePerBlobGas": "1", + "blobGasUsed": "131072", + "blobAsCalldataGasUsed": "540848", + "category": "other", + "rollup": null, + "blobs": [ + { + "versionedHash": "0x0171cc60442260fc3ccd50f72c9f776bad6b74f1e96532aa0555000f829335b4", + "index": 0, + "data": "0x000000000000000562000000000000000000000000000000000000000000000000f9055ff8ad0281f86a818242698180010f81825208819481830f81ee3c81ce003561818b81b8274f6481a281b381c781ec7e818381b1819b81865a81f3107a004080818081c00181a081fd81f981e981bf81da81de6b81bf2181b781ad81a7003e51819c818a81bc81fa1181a181d72c81c72d81b981f75c8183156b81a56e0081a02c819c81a881d70e81cc8180374b818a81b681cb2781f681d669818e8100c881ef678186311e5d8198235081b581d081d581f781d0f8a30281f86a81820042698180010f81825208819481830f81ee3c81ce3561818b81b8274f6481a20081b381c781ec7e818381b1819b81865a81f3107a4080818081c00181a081d300051481fc818881912e81ad5581de4381b20b394381d56b4981da7e81ee81f3004581d73881f65e818e81ef475a4981a04b257881dd81b3819f7481e7818a80001a81a61e7d81e381fb1581d32081a4436a81a34f81ba2681eb81f081cc6f1c00818cf8b40281f8708182426981808183166c518183166c5c8182520881948100830f81ee3c81ce3561818b81b8274f6481a281b381c781ec7e818381b1819b0081872b81b281c881ea81bc81c080818081c0818081a01b7081de818c818f81009d81884c0c81a15181c681dd5d81d3819e81d181fe6c6b74819b4381d181f50081b746395b81c22481b8819f81ca81c71f3b819581d65e81c581c481d70e81009a81d16281ef5c653581ce81c181b8705c81a481cd3b819e6c1c81a920f8a20081f86a81808184773581948081825981d88194215c4d1b81b481a081e21c730081e43835819a3981c881dc81c681a8818276818517487681e8808180818281008481f581a01381ce1d81903781bc81e42381ff81b4065081f181bc1f81fe0d006153550481d86e3581b681aa81a6361081d4160a81a04b81d10f81e37d52650081c77d4681fb81cb81b181f3818981a87c81b5818539256d81a46f3106788100c581ab81d55350f8a80281f86a818242698180010f81825208819481830f8100ee3c81ce3561818b81b8274f6481a281b381c781ec7e818381b1819b81865a0081f3107a4080818081c00181a081c64881b32d81d56e81cd0a81c781fe438100a181890a819681bb81c2377681ce81fb81cc81c481f4107b6581eb1781b6790081f481a06081f98187103e81ea81bf7681c181f381d76c81d54381ed452f8100c87581f1515a3d81d581c781b515523e81f281ff81f2f8b30281f8738182420069818081843b819a81ca0781843b819a81ca07818252088194215c4d1b81b40081a081e21c7381e43835819a3981c881dc81c681a881827681870381a43d8100bc81f081f480818081c00181a08183494b5b3581da818a81c8818f0681f58100c681dc571b819181d53f128188818f81c181df818281ba81c181ba81dd0d8100ea4e7881a016819d6e81f3502b311281d181d42c604f658192546481de81fd004881b84b1112641e81993b76818e81d250f8a80281f86a818242698180010f0081825208819481830f81ee3c81ce3561818b81b8274f6481a281b381c781ec007e818381b1819b81865a81f3107a4080818081c00181a081a7819481a1038100fb819e6481ca5181ca6e81a3818881d381f8818081a21b3b81dc0c81c381b8001c777f81e4818181ab0381cb819881a04857265a81e481cd81c3576881f88100a281ab5581c1744481ca1c46818e81d23d81a281bc1681b54b81a27f81d31c0058f8a60281f86a818242698180010f81825208819481830f81ee3c81ce356100818b81b8274f6481a281b381c781ec7e818381b1819b81865a81f3107a408000818081c0818081a081af81833e81ae81a881f54881ae1681a981f9818b3d6100819f3d81cb5181a62a81b10b81e381a0819581ab818f1481ff4881bd4881a0006e048196819681f3214b81f96e736c0281a744470681b4182a734881cd428100fb818d81ce1d81db80819681f27a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "commitment": "0x9719a4289b599520cce61d829806e8db9b24af8b45fbcf6536bc17f1c92d052ae0fb2d47fef4686c3064768ae138b4fb", + "proof": "0x994b7b17e6a178275a330feb481bf0aabd714e95625e2b9cd68425a466bfac2c3fb79bab251bc29ab98844b9856635e0", + "size": 131072, + "dataStorageReferences": [ + { + "storage": "google", + "url": "https://storage.googleapis.com/blobscan-production/17000/01/71/cc/0171cc60442260fc3ccd50f72c9f776bad6b74f1e96532aa0555000f829335b4.txt" + } + ] + } + ], + "block": { + "blobGasUsed": "262144", + "blobAsCalldataGasUsed": "1065244", + "blobGasPrice": "1", + "excessBlobGas": "0", + "slot": 2831666 + }, + "decodedFields": { "type": "unknown", "payload": "{}" }, + "blobAsCalldataGasFee": "10435904459904", + "blobGasBaseFee": "131072", + "blobGasMaxFee": "131072" +} diff --git a/crates/node-tests/tests/artifacts/cl_blob.json b/crates/node-tests/tests/artifacts/cl_blob.json new file mode 100644 index 0000000..a3ad3cb --- /dev/null +++ b/crates/node-tests/tests/artifacts/cl_blob.json @@ -0,0 +1 @@ +{"data":[{"index":"0","blob":"0x0000000000000000ab000000000000000000000000000000000000000000000000f8a9f8a70281f86e8182375e8182130281846f81c23a81c081846f81c23a8100ce818275308194014081c781db330181d96781b07523024481ef5c731881850081e681e701818081c0818081a0156e133781d25581d7818481ef404b81b68100c37b5881cb355e2b81894681cc737981ac81c981998180362a5b81d381a07b0081b06d1481bf0e2281822881894a81e481bc7881a881d73d81e80681e381d70081d20881b60281a9448194353281a302000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","kzg_commitment":"0x901e6928af28e432e557b39451a3f159bf461fc74f8f66775812042a89b27c81185178ad6397aac606b8ffb03595742c","kzg_proof":"0x959f5841cddd0bedc6d8b5ba87725bedc3ed93c06750c4e7e7b46aaa97a0ec73304fbf578189f87273798f5508c4e7a0","signed_block_header":{"message":{"slot":"277733","proposer_index":"60","parent_root":"0xa70c4d0fa88bf3a6c63a275bfc04b6a75b99bd24bc54cf77e66bb7e79f98cb06","state_root":"0xece056b5a96ea20627fabea9d199c5f1dbb3ee57097d84008582332cea1d65b7","body_root":"0xacff9498dd1fc0ee07daf2149e385f47720c329b2361b979389655a122e39600"},"signature":"0x9180287859873829e1d15f7e6536077b48532d921626079beaabb35360ce3bfba4e283c3030fa98e5cc69de21d1349c00e43c12540b1b984c0659bd501e1878ddb19f348856defd6112a3935ab8d4b7b8c358c7b603b355ef6d747497c90ca0c"},"kzg_commitment_inclusion_proof":["0x0000000000000000000000000000000000000000000000000000000000000000","0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c","0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c","0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30","0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1","0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c","0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193","0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1","0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b","0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220","0x0100000000000000000000000000000000000000000000000000000000000000","0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535","0xf482ef6d9368cf575267f4a016583599a20fd8ac434aba5236f18cdbde25caae","0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71","0xb8c289deaa64a21cf9ef741d30162a5017271758e8e5100462b7b9f8aeda3298"]}]} \ No newline at end of file diff --git a/crates/node-tests/tests/artifacts/cl_blob_tx.json b/crates/node-tests/tests/artifacts/cl_blob_tx.json new file mode 100644 index 0000000..e1734d6 --- /dev/null +++ b/crates/node-tests/tests/artifacts/cl_blob_tx.json @@ -0,0 +1,26 @@ +{ + "type": "0x3", + "chainId": "0x301824", + "nonce": "0x1b25", + "gas": "0xf4240", + "maxFeePerGas": "0x1dcd650e", + "maxPriorityFeePerGas": "0x1dcd6500", + "to": "0xb393416a722fd48c3b0a9ab5fc2512ef0c55e4ca", + "value": "0x0", + "accessList": [], + "blobVersionedHashes": [ + "0x019cfbff3a7e089487a6d76096b526eca01ce1c005dde7459c955de95dac3287" + ], + "maxFeePerBlobGas": "0x1", + "input": "0x628db5210000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000375e0000000000000000000000000000000000000000000000000000000000043cda0000000000000000000000000000000000000000000000000000000001c9c380000000000000000000000000ecb32705b0b647dcd6cd6b79b80bfd03cdf0ac3dfd93968f4e7d4d4451f211980f2fec4f0c32e67fae63a70ca90024b54a70e9ee000000000000000000000000000000000000000000000000000000000000001b583b8e9c3154bb7ac4d8d78130402928dc76b4681a7a50dc1d2dafd156a88cdf2f4f09f564dbf25972c1d1cbbd33a3073a88cbbfaf51a6ca90cc1fcb24b1fd4a0000000000000000000000000000000000000000000000000000000000000000", + "r": "0x19f836dcea4e16652b7ebffc275e31b6dceaa44cae166f01069fbf65657193db", + "s": "0x3b55aad1cb708c0d8a770b37b0f70aaabccdba62cd60ed5b0843d0ac0e4b9099", + "yParity": "0x1", + "v": "0x1", + "hash": "0x73d1c682fae85c761528a0a7ec22fac613b25ede87b80f0ac052107f3444324f", + "blockHash": "0x1ef97f0fa61279e30711728acef83b8de7722b4e8861b46b3f5982ea1243b77f", + "blockNumber": "0x43cda", + "transactionIndex": "0x0", + "from": "0x4c3e529d2359d8dbb1a4fc8be1555427efb32e7c", + "gasPrice": "0x1dcd6507" +} diff --git a/crates/node-tests/tests/artifacts/pylon_blob.json b/crates/node-tests/tests/artifacts/pylon_blob.json new file mode 100644 index 0000000..2aa1264 --- /dev/null +++ b/crates/node-tests/tests/artifacts/pylon_blob.json @@ -0,0 +1 @@ +{"blobs":["0x0000000000000000ab000000000000000000000000000000000000000000000000f8a9f8a70281f86e8182375e8182130281846f81c23a81c081846f81c23a8100ce818275308194014081c781db330181d96781b07523024481ef5c731881850081e681e701818081c0818081a0156e133781d25581d7818481ef404b81b68100c37b5881cb355e2b81894681cc737981ac81c981998180362a5b81d381a07b0081b06d1481bf0e2281822881894a81e481bc7881a881d73d81e80681e381d70081d20881b60281a9448194353281a302000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"],"commitments":["0x901e6928af28e432e557b39451a3f159bf461fc74f8f66775812042a89b27c81185178ad6397aac606b8ffb03595742c"],"proofs":["0x959f5841cddd0bedc6d8b5ba87725bedc3ed93c06750c4e7e7b46aaa97a0ec73304fbf578189f87273798f5508c4e7a0"]} \ No newline at end of file diff --git a/crates/node-tests/tests/basic.rs b/crates/node-tests/tests/basic.rs new file mode 100644 index 0000000..382d90a --- /dev/null +++ b/crates/node-tests/tests/basic.rs @@ -0,0 +1,214 @@ +use alloy::{ + consensus::{ + SidecarBuilder, SimpleCoder, TxType, + constants::{ETH_TO_WEI, GWEI_TO_WEI}, + }, + network::{TransactionBuilder, TransactionBuilder4844, TransactionBuilder7702}, + primitives::{Address, B256, U256}, + providers::Provider, + rpc::types::eth::{AccessList, AccessListItem, TransactionRequest}, + signers::Signer, +}; +use serial_test::serial; +use signet_constants::RollupPermitted; +use signet_genesis::GenesisSpec; +use signet_node_tests::{HostBlockSpec, run_test, utils::adjust_usd_decimals}; + +const SOME_USER: Address = Address::repeat_byte(0x39); + +// Tests must be serial, as reth test exex context binds a peer discovery port +#[serial] +#[tokio::test] +async fn test_simple_enter() { + run_test(|ctx| async move { + let mut bal = ctx.track_balance(SOME_USER, Some("user")); + + let enter_amnt = 31999; + let block = HostBlockSpec::new(ctx.constants()).enter_token( + SOME_USER, + enter_amnt, + ctx.constants().host().tokens().usdc(), + ); + + ctx.process_block(block).await.unwrap(); + + let expected = adjust_usd_decimals(enter_amnt, 6); + + bal.assert_increase_exact(expected); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_basic_reorg() { + run_test(|ctx| async move { + let mut bal = ctx.track_balance(SOME_USER, Some("user")); + + let enter_amnt = 31999; + let block = HostBlockSpec::new(ctx.constants()).enter_token( + SOME_USER, + enter_amnt, + ctx.constants().host().tokens().usdc(), + ); + + ctx.process_block(block.clone()).await.unwrap(); + + let change = adjust_usd_decimals(enter_amnt, 6); + + bal.assert_increase_exact(change); + + ctx.revert_block(block).await.unwrap(); + + bal.assert_decrease_exact(change); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_genesis_allocs() { + run_test(|ctx| async move { + let genesis = GenesisSpec::Test.load_genesis().expect("Failed to load genesis"); + ctx.verify_allocs(&genesis); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_legacy_tx_support() { + run_test(|ctx| async move { + let send_val = U256::from(ETH_TO_WEI); + let mut bal = ctx.track_balance(ctx.addresses[1], Some("recipient")); + + let tx = TransactionRequest::default() + .from(ctx.addresses[0]) + .to(ctx.addresses[1]) + .value(send_val) + .gas_limit(21_000) + .with_gas_price(GWEI_TO_WEI as u128); + let (envelope, _receipt) = ctx.process_alloy_tx(&tx).await.unwrap(); + + assert_eq!(envelope.tx_type(), TxType::Legacy); + bal.assert_increase_exact(send_val); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_eip1559_tx_support() { + run_test(|ctx| async move { + let send_val = U256::from(ETH_TO_WEI); + let mut bal = ctx.track_balance(ctx.addresses[1], Some("recipient")); + + let tx = TransactionRequest::default() + .from(ctx.addresses[0]) + .to(ctx.addresses[1]) + .value(send_val) + .gas_limit(21_000); + let (envelope, _receipt) = ctx.process_alloy_tx(&tx).await.unwrap(); + + assert_eq!(envelope.tx_type(), TxType::Eip1559); + bal.assert_increase_exact(send_val); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_eip2930_tx_support() { + run_test(|ctx| async move { + let send_val = U256::from(ETH_TO_WEI); + let mut bal = ctx.track_balance(ctx.addresses[1], Some("recipient")); + + let tx = TransactionRequest::default() + .from(ctx.addresses[0]) + .to(ctx.addresses[1]) + .value(send_val) + .with_gas_price(GWEI_TO_WEI as u128) + .with_access_list(AccessList::from(vec![AccessListItem { + address: ctx.addresses[0], + storage_keys: vec![B256::repeat_byte(3)], + }])); + let (envelope, _receipt) = ctx.process_alloy_tx(&tx).await.unwrap(); + + assert_eq!(envelope.tx_type(), TxType::Eip2930); + bal.assert_increase_exact(send_val); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_eip4844_tx_unsupported() { + run_test(|ctx| async move { + let send_val = U256::from(ETH_TO_WEI); + + let sidecar = SidecarBuilder::::from_slice(&[1, 2, 3, 4]).build().unwrap(); + + let tx = TransactionRequest::default() + .from(ctx.addresses[0]) + .to(ctx.addresses[1]) + .value(send_val) + .with_blob_sidecar(sidecar); + + assert!(ctx.process_alloy_tx(&tx).await.is_err()); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_eip7702_tx_support() { + run_test(|ctx| async move { + let alice = signet_test_utils::users::TEST_SIGNERS[0].clone(); + let bob = signet_test_utils::users::TEST_SIGNERS[1].clone(); + + // Deploy the log contract + let log = ctx.deploy_log(alice.address()).await; + + // Create the authorization that bob will sign + let authorization = alloy::eips::eip7702::Authorization { + chain_id: U256::ZERO, + // Reference to the contract that will be set as code for the authority + address: *log.address(), + nonce: ctx.alloy_provider.get_transaction_count(bob.address()).await.unwrap(), + }; + + let signature = bob.sign_hash(&authorization.signature_hash()).await.unwrap(); + let authorization = authorization.into_signed(signature); + + let tx = TransactionRequest::default() + .from(alice.address()) + .to(bob.address()) + .with_authorization_list(vec![authorization]) + .with_input(log.emitHello().calldata().to_owned()); + + let (envelope, receipt) = ctx.process_alloy_tx(&tx).await.unwrap(); + + assert_eq!(envelope.tx_type(), TxType::Eip7702); + assert!(receipt.status()); + assert_eq!(receipt.logs().len(), 1); + assert_eq!(receipt.logs()[0].address(), bob.address()); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_predeployed_tokens() { + run_test(|ctx| async move { + let wbtc = ctx.token_instance(RollupPermitted::Wbtc); + assert_eq!(wbtc.name().call().await.unwrap(), "Wrapped BTC"); + assert_eq!(wbtc.symbol().call().await.unwrap(), "WBTC"); + assert_eq!(wbtc.decimals().call().await.unwrap(), 8); + + let weth = ctx.token_instance(RollupPermitted::Weth); + assert_eq!(weth.name().call().await.unwrap(), "Wrapped Ether"); + assert_eq!(weth.symbol().call().await.unwrap(), "WETH"); + assert_eq!(weth.decimals().call().await.unwrap(), 18); + }) + .await; +} diff --git a/crates/node-tests/tests/db.rs b/crates/node-tests/tests/db.rs new file mode 100644 index 0000000..0b26342 --- /dev/null +++ b/crates/node-tests/tests/db.rs @@ -0,0 +1,26 @@ +use alloy::primitives::hex; +use reth::providers::BlockReader; +use serial_test::serial; +use signet_node::SignetNode; +use signet_node_config::test_utils::test_config; +use signet_node_tests::utils::create_test_provider_factory_with_chain_spec; +use std::sync::Arc; + +#[serial] +#[tokio::test] +async fn test_genesis() { + let cfg = test_config(); + let consts = cfg.constants(); + let (ctx, _) = reth_exex_test_utils::test_exex_context().await.unwrap(); + + let chain_spec: Arc<_> = cfg.chain_spec().clone(); + assert_eq!(chain_spec.genesis().config.chain_id, consts.unwrap().ru_chain_id()); + + let factory = create_test_provider_factory_with_chain_spec(chain_spec.clone()); + let (_, _) = SignetNode::new(ctx, cfg.clone(), factory.clone(), Default::default()).unwrap(); + + let genesis_block = factory.provider().unwrap().block_by_number(0).unwrap().unwrap(); + + let want_hash = hex!("0x0000000000000000000000000000000000000000000000000000000000000000"); + assert_eq!(genesis_block.parent_hash, want_hash); +} diff --git a/crates/node-tests/tests/exit.rs b/crates/node-tests/tests/exit.rs new file mode 100644 index 0000000..c1517ee --- /dev/null +++ b/crates/node-tests/tests/exit.rs @@ -0,0 +1,147 @@ +use alloy::{ + eips::BlockNumberOrTag, primitives::U256, providers::Provider, + rpc::types::eth::TransactionRequest, sol_types::SolCall, +}; +use serial_test::serial; +use signet_node_tests::{HostBlockSpec, SignetTestContext, run_test}; +use signet_types::constants::HostPermitted; +use signet_zenith::RollupPassage; + +alloy::sol! { + #[derive(Debug)] + #[sol(rpc)] + contract Erc20 { + function balanceOf(address) public view returns (uint256); + function approve(address, uint256) public returns (bool); + function totalSupply() public returns (uint256); + function allowance(address, address) public view returns (uint256); + } +} + +#[serial] +#[tokio::test] +async fn test_simple_exit() { + run_test(|ctx| async move { + let user = ctx.addresses[0]; + + let mut bal = ctx.track_balance(user, Some("user")); + let mut passage_bal = ctx.track_balance(ctx.constants.rollup().passage(), Some("passage")); + passage_bal.assert_eq(U256::ZERO); + + let amount = U256::from(31999); + + let tx = TransactionRequest::default() + .from(user) + .to(ctx.constants.rollup().passage()) + .value(amount); + + ctx.process_alloy_tx(&tx).await.unwrap(); + + bal.assert_decrease_at_least(amount); + passage_bal.assert_no_change(); + + let block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .await + .unwrap() + .unwrap(); + + let tx = *block.transactions.as_hashes().unwrap().first().unwrap(); + + let passage = ctx.ru_passage_contract(); + let events = passage.Exit_filter().query().await.unwrap(); + let event = &events[0]; + + assert_eq!(event.1.transaction_hash, Some(tx)); + assert_eq!(event.0, RollupPassage::Exit { hostRecipient: user, amount }); + assert_eq!(event.0.hostRecipient, user); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_erc20_exits() { + run_test(|mut ctx| async move { + ctx = test_inner(ctx, HostPermitted::Weth).await; + test_inner(ctx, HostPermitted::Wbtc).await; + }) + .await; + + async fn test_inner(ctx: SignetTestContext, token: HostPermitted) -> SignetTestContext { + // setup + let amount = 100_000_000; + let passage = ctx.ru_passage_contract(); + let user_a = ctx.addresses[0]; + + let host_token = ctx.constants.host().tokens().address_for(token); + let ru_token = Erc20::Erc20Instance::new( + ctx.constants.rollup().tokens().address_for(token.into()), + ctx.alloy_provider.clone(), + ); + + // Mint some tokens on the rollup for the user + ctx.process_block( + HostBlockSpec::new(ctx.constants()).enter_token(user_a, amount, host_token), + ) + .await + .unwrap(); + + // Check that mint occurred + let mint_bal = ru_token.balanceOf(user_a).call().await.unwrap(); + assert_eq!(mint_bal, U256::from(amount)); + let pre_supply = ru_token.totalSupply().call().await.unwrap(); + + // Approve + let approve_tx = TransactionRequest::default().from(user_a).to(*ru_token.address()).input( + Erc20::approveCall { _0: *passage.address(), _1: U256::MAX }.abi_encode().into(), + ); + let (_, receipt) = ctx.process_alloy_tx(&approve_tx).await.unwrap(); + assert!(receipt.status(), "approval tx reverted"); + + // Now exit + let exit_tx = TransactionRequest::default().from(user_a).to(*passage.address()).input( + RollupPassage::exitTokenCall { + hostRecipient: user_a, + token: *ru_token.address(), + amount: U256::from(amount), + } + .abi_encode() + .into(), + ); + + ctx.process_alloy_tx(&exit_tx).await.unwrap(); + assert!(receipt.status(), "exit tx reverted"); + + // Burn occurred + assert_eq!(ru_token.balanceOf(user_a).call().await.unwrap(), U256::ZERO); + assert_eq!(ru_token.balanceOf(*passage.address()).call().await.unwrap(), U256::ZERO); + let post_supply = ru_token.totalSupply().call().await.unwrap(); + assert_eq!( + post_supply, + pre_supply - U256::from(amount), + "total supply should decrease by the amount burned" + ); + + // Check that RPC records the events + let get_block_by_number = ctx.alloy_provider.get_block_by_number(BlockNumberOrTag::Latest); + let block = get_block_by_number.await.unwrap().unwrap(); + let tx = block.transactions.as_hashes().unwrap()[0]; + + let events = passage.ExitToken_filter().query().await.unwrap(); + let event = &events[0]; + + assert_eq!(event.1.transaction_hash, Some(tx)); + assert_eq!( + event.0, + RollupPassage::ExitToken { + hostRecipient: user_a, + token: *ru_token.address(), + amount: U256::from(amount) + } + ); + + ctx + } +} diff --git a/crates/node-tests/tests/host_events.rs b/crates/node-tests/tests/host_events.rs new file mode 100644 index 0000000..8cff94f --- /dev/null +++ b/crates/node-tests/tests/host_events.rs @@ -0,0 +1,536 @@ +use alloy::{ + consensus::{ + Transaction, + constants::{ETH_TO_WEI, GWEI_TO_WEI}, + }, + eips::BlockNumberOrTag, + network::TransactionResponse, + primitives::{Bytes, U256}, + providers::Provider, + sol_types::SolCall, +}; +use reth::providers::{BlockNumReader, DBProvider, HeaderProvider}; +use serial_test::serial; +use signet_db::{DbSignetEvent, SignetEvents}; +use signet_node_tests::{ + HostBlockSpec, SignetTestContext, + aliases::{Counter, TestCounterInstance}, + constants::{DEFAULT_REWARD_ADDRESS, TEST_CONSTANTS}, + run_test, + utils::{adjust_usd_decimals, adjust_usd_decimals_u256}, +}; +use signet_test_utils::{chain::USDC_RECORD, contracts::counter::COUNTER_BYTECODE}; +use signet_types::constants::{HostPermitted, RollupPermitted}; +use signet_zenith::{MINTER_ADDRESS, Passage, Transactor, mintCall}; + +alloy::sol! { + #[derive(Debug)] + #[sol(rpc)] + contract Erc20 { + function balanceOf(address) public view returns (uint256); + } +} + +#[serial] +#[tokio::test] +async fn test_enter_token() { + run_test(|mut ctx| async move { + ctx = test_inner_usd(ctx, HostPermitted::Usdc).await; + ctx = test_inner_usd(ctx, HostPermitted::Usdt).await; + ctx = test_inner_non_usd(ctx, HostPermitted::Weth).await; + test_inner_non_usd(ctx, HostPermitted::Wbtc).await; + }) + .await; + + async fn test_inner_usd(ctx: SignetTestContext, token: HostPermitted) -> SignetTestContext { + let user_a = ctx.addresses[1]; + let host_token_addr = ctx.constants.host().tokens().address_for(token); + let mut bal = ctx.track_balance(user_a, Some("user_a")); + let mut nonce = ctx.track_nonce(MINTER_ADDRESS, Some("minter")); + + // Get the USD record for the host token, and compute the enter amount + let usd_record = ctx.constants.host().usd_record(host_token_addr).unwrap(); + let enter_amount = U256::from(10_000); + let expected_mint_amount = adjust_usd_decimals_u256(enter_amount, usd_record.decimals()); + + let block = + HostBlockSpec::new(ctx.constants()).enter_token(user_a, 10_000, host_token_addr); + ctx.process_block(block).await.unwrap(); + + nonce.assert_incremented(); + bal.assert_increase_exact(expected_mint_amount); + + let block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .full() + .await + .unwrap() + .unwrap(); + + let txns = block.transactions.as_transactions().unwrap(); + let enter_tx = &txns[0]; + + assert_eq!(enter_tx.from(), MINTER_ADDRESS); + assert_eq!(enter_tx.to().unwrap(), user_a); + assert_eq!(enter_tx.value(), expected_mint_amount); + assert_eq!(enter_tx.input(), &Bytes::default()); + + // NB: this check is probably redundant, but it ensures the RPC + // tx response matches the tx in the block + let rpc_tx = + ctx.alloy_provider.get_transaction_by_hash(enter_tx.tx_hash()).await.unwrap().unwrap(); + assert_eq!(&rpc_tx, enter_tx); + ctx + } + + async fn test_inner_non_usd(ctx: SignetTestContext, token: HostPermitted) -> SignetTestContext { + let user_a = ctx.addresses[0]; + let host_token = ctx.constants.host().tokens().address_for(token); + let ru_token = Erc20::Erc20Instance::new( + ctx.constants.rollup().tokens().address_for(token.into()), + ctx.alloy_provider.clone(), + ); + + // Track minter's nonce + let mut nonce = ctx.track_nonce(MINTER_ADDRESS, Some("minter")); + + let block = HostBlockSpec::new(ctx.constants()).enter_token(user_a, 10_000, host_token); + + // Track block fees + let mut base_fee_recipient = + ctx.track_balance(ctx.constants.base_fee_recipient(), Some("base_fee")); + let mut beneficiary = ctx.track_balance(DEFAULT_REWARD_ADDRESS, Some("beneficiary")); + + let pre_bal = ru_token.balanceOf(user_a).call().await.unwrap(); + + ctx.process_block(block).await.unwrap(); + + // Minter's nonce should increase + nonce.assert_incremented(); + + // User's token balance should increase + let balance = ru_token.balanceOf(user_a).call().await.unwrap(); + assert_eq!(balance, pre_bal + U256::from(10_000)); + + // No fee should be paid + base_fee_recipient.assert_no_change(); + beneficiary.assert_no_change(); + + // Block + let block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .full() + .await + .unwrap() + .unwrap(); + let tx = &block.transactions.as_transactions().unwrap()[0]; + assert_eq!(tx.from(), MINTER_ADDRESS); + assert_eq!(tx.to().unwrap(), *ru_token.address()); + assert_eq!(tx.value(), U256::ZERO); + assert_eq!( + tx.input().as_ref(), + signet_zenith::mintCall { to: user_a, amount: U256::from(10_000) }.abi_encode() + ); + + let tx = ctx.alloy_provider.get_transaction_by_hash(tx.tx_hash()).await.unwrap().unwrap(); + assert_eq!(tx.from(), MINTER_ADDRESS); + assert_eq!(tx.to().unwrap(), *ru_token.address()); + assert_eq!(tx.value(), U256::ZERO); + assert_eq!( + tx.input().as_ref(), + signet_zenith::mintCall { to: user_a, amount: U256::from(10_000) }.abi_encode() + ); + ctx + } +} + +#[serial] +#[tokio::test] +async fn test_enters() { + run_test(|ctx| async move { + test_enter_inner(ctx).await; + }) + .await; + + async fn test_enter_inner(ctx: SignetTestContext) -> SignetTestContext { + let mut nonce = ctx.track_nonce(MINTER_ADDRESS, Some("minter")); + let ru_token = Erc20::Erc20Instance::new( + ctx.constants.rollup().tokens().address_for(RollupPermitted::Weth), + ctx.alloy_provider.clone(), + ); + + let user_a = ctx.addresses[1]; + + let enter_amount = U256::from(31999); + let pre_bal = ru_token.balanceOf(user_a).call().await.unwrap(); + + let block = HostBlockSpec::new(ctx.constants()).enter(user_a, 31999); + + ctx.process_block(block).await.unwrap(); + + let balance = ru_token.balanceOf(user_a).call().await.unwrap(); + assert_eq!(balance, pre_bal + U256::from(enter_amount)); + + nonce.assert_incremented(); + + let block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .full() + .await + .unwrap() + .unwrap(); + + let txns = block.transactions.as_transactions().unwrap(); + let enter_tx = &txns[0]; + let to = ctx.addresses[1]; + + assert_eq!(enter_tx.from(), MINTER_ADDRESS); + assert_eq!(enter_tx.to().unwrap(), *ru_token.address()); + assert!(enter_tx.value().is_zero()); + assert_eq!(enter_tx.input(), &mintCall { to, amount: enter_amount }.abi_encode()); + + // NB: this check is probably redundant, but it ensures the RPC + // tx response matches the tx in the block + let rpc_tx = + ctx.alloy_provider.get_transaction_by_hash(enter_tx.tx_hash()).await.unwrap().unwrap(); + assert_eq!(&rpc_tx, enter_tx); + ctx + } +} + +#[serial] +#[tokio::test] +async fn test_transact() { + run_test(|ctx| async move { + // set up user + let user = ctx.addresses[0]; + let mut user_nonce = ctx.track_nonce(user, Some("user")); + let mut user_bal = ctx.track_balance(user, Some("user")); + + // Deploy a contract to interact with + let deployer = ctx.addresses[1]; + + // Assert that the counter is zero + let contract = ctx.deploy_counter(deployer).await; + let contract_addr = *contract.address(); + assert_eq!(contract.count().call().await.unwrap(), U256::ZERO); + + // Transact that calls the context and increments it. + let block = HostBlockSpec::new(ctx.constants()).simple_transact( + user, + contract_addr, + Counter::incrementCall::SELECTOR, + 0, + ); + + ctx.process_block(block).await.unwrap(); + + user_nonce.assert_incremented(); + user_bal.assert_decrease(); + + assert_eq!(contract.count().call().await.unwrap(), U256::from(1)); + + // check the RPC response + let block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .full() + .await + .unwrap() + .unwrap(); + + let txns = block.transactions.as_transactions().unwrap(); + let transact_tx = &txns[0]; + + assert_eq!(transact_tx.from(), user); + assert_eq!(transact_tx.to().unwrap(), contract_addr); + assert_eq!(transact_tx.value(), U256::ZERO); + assert_eq!(transact_tx.input(), &Bytes::from(Counter::incrementCall::SELECTOR)); + + let tx_hash = transact_tx.tx_hash(); + let transact_tx = + ctx.alloy_provider.get_transaction_by_hash(tx_hash).await.unwrap().unwrap(); + + assert_eq!(transact_tx.from(), user); + assert_eq!(transact_tx.to().unwrap(), contract_addr); + assert_eq!(transact_tx.value(), U256::ZERO); + assert_eq!(transact_tx.input(), &Bytes::from(Counter::incrementCall::SELECTOR)); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_transact_underfunded_gas() { + run_test(|ctx| async move { + // set up user + let user = ctx.addresses[0]; + let mut user_nonce = ctx.track_nonce(user, Some("user")); + let mut user_bal = ctx.track_balance(user, Some("user")); + + // Deploy a contract to interact with + let deployer = ctx.addresses[1]; + let contract = ctx.deploy_counter(deployer).await; + let contract_addr = *contract.address(); + assert_eq!(ctx.alloy_provider.get_code_at(contract_addr).await.unwrap(), COUNTER_BYTECODE,); + + // assert that the counter is zero + let contract = TestCounterInstance::new(contract_addr, ctx.alloy_provider.clone()); + assert_eq!(contract.count().call().await.unwrap(), U256::ZERO); + + // make a transact with a tiny gas limit so it will revert w/ OOG + let tiny_gas = 10u64; + let transact = Transactor::Transact { + rollupChainId: U256::from(ctx.constants().ru_chain_id()), + sender: user, + to: contract_addr, + data: Bytes::from(Counter::incrementCall::SELECTOR), + value: U256::ZERO, + gas: U256::from(tiny_gas), + maxFeePerGas: U256::from(GWEI_TO_WEI), + }; + + let block = HostBlockSpec::new(ctx.constants()).transact(transact); + + // process the block to commit the results + ctx.process_block(block).await.unwrap(); + + // nonce and balance should NOT change because the transact was discarded for OOG + let old_nonce = user_nonce.update_nonce(); + assert_eq!(user_nonce.previous_nonce(), old_nonce, "expected nonce not to change"); + user_bal.assert_no_change(); + + // contract state should not change because the call ran out of gas + assert_eq!(contract.count().call().await.unwrap(), U256::ZERO); + + // check signet events for the recorded transact and that the gas equals tiny_gas + let last = ctx.factory.provider().unwrap().last_block_number().unwrap(); + let events = ctx.factory.provider().unwrap().get::(last..last + 1).unwrap(); + + // Check that the block has no transactions, i.e. that the transact was + // discarded + let last_block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .await + .unwrap() + .unwrap(); + assert!(last_block.transactions.is_empty()); + + let found = events.iter().find(|(_, ev)| match ev { + DbSignetEvent::Transact(_, Transactor::Transact { sender, to, gas, .. }) => { + *sender == user && *to == contract_addr && *gas == U256::from(tiny_gas) + } + _ => false, + }); + + assert!(found.is_some(), "expected DbSignetEvent::Transact with tiny gas"); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_signet_events() { + run_test(|ctx| async move { + let user_a = ctx.addresses[0]; + let user_b = ctx.addresses[1]; + + #[allow(non_snake_case)] + let rollupChainId = U256::from(TEST_CONSTANTS.ru_chain_id()); + + let mut user_a_bal = ctx.track_balance(user_a, Some("user_a")); + let mut user_b_bal = ctx.track_balance(user_b, Some("user_b")); + + // First enter_token is 1 wbt to user_a + let wbtc_address = ctx.constants.host().tokens().wbtc(); + let wbtc_enter_amount = GWEI_TO_WEI as usize; + let wbtc_enter_amount_u256 = U256::from(wbtc_enter_amount); + + // Second enter_token is 1 USDC to user_a + // This is expected to mint 1 USD + let usdc_address = USDC_RECORD.address(); + let usdc_enter_amount = 10usize.pow(USDC_RECORD.decimals() as u32); + let expected_usd_minted = adjust_usd_decimals(usdc_enter_amount, USDC_RECORD.decimals()); + + // Third we enter 1 ETH to user_a + let eth_enter_amount = ETH_TO_WEI as usize; + let eth_enter_amount_u256 = U256::from(eth_enter_amount); + + // The last event is a transact from user_a to user_b for 1 USD with the data [0xab, 0xcd] + let input = Bytes::from(vec![0xab, 0xcd]); + + // Spec and process the block + let block = HostBlockSpec::new(ctx.constants()) + .enter_token(user_a, wbtc_enter_amount, wbtc_address) + .enter_token(user_a, usdc_enter_amount, usdc_address) + .enter(user_a, eth_enter_amount) + .simple_transact(user_a, user_b, input, expected_usd_minted.to()); + ctx.process_block(block.clone()).await.unwrap(); + + // Check the base fee + let base_fee = ctx + .factory + .header_by_number(1) + .unwrap() + .unwrap() + .base_fee_per_gas + .map(U256::from) + .unwrap(); + + // NB: + // user_a should have received 1 USD, + // user_a then paid base_fee * gas to send 1 USD to user_b, + // so user_a's balance decreases. The 1 in 1 out cancel out. So fee is + // the only change in user_a's balance. + // + // user_b should have received 1 USD + // + // the 100_000 here is the gas limit used by `simple_transact()` + user_a_bal.assert_decrease_exact(base_fee * U256::from(100_000)); + user_b_bal.assert_increase_exact(U256::from(expected_usd_minted)); + + // Process the block again. + ctx.process_block(block).await.unwrap(); + + // Check the base fee + let base_fee = ctx + .factory + .header_by_number(2) + .unwrap() + .unwrap() + .base_fee_per_gas + .map(U256::from) + .unwrap(); + + // This time works exactly the same as above. + user_a_bal.assert_decrease_exact(base_fee * U256::from(100_000)); + user_b_bal.assert_increase_exact(U256::from(expected_usd_minted)); + + let events = ctx.factory.provider().unwrap().get::(1..3).unwrap(); + assert_eq!(events.len(), 8); + + // The tuple is (block_number, event). + // We expect 4 events per block + assert_eq!(events[0].0, 1); + assert_eq!(events[1].0, 1); + assert_eq!(events[2].0, 1); + assert_eq!(events[3].0, 1); + assert_eq!(events[4].0, 2); + assert_eq!(events[5].0, 2); + assert_eq!(events[6].0, 2); + assert_eq!(events[7].0, 2); + + assert_eq!( + events[0].1, + DbSignetEvent::Transact( + 3, + Transactor::Transact { + rollupChainId, + sender: user_a, + to: user_b, + data: vec![0xab, 0xcd].into(), + value: U256::from(expected_usd_minted), + gas: U256::from(100_000), + maxFeePerGas: U256::from(GWEI_TO_WEI), + } + ) + ); + + assert_eq!( + events[1].1, + DbSignetEvent::Enter( + 0, + Passage::Enter { + rollupChainId, + rollupRecipient: user_a, + amount: eth_enter_amount_u256, + } + ) + ); + + assert_eq!( + events[2].1, + DbSignetEvent::EnterToken( + 1, + Passage::EnterToken { + rollupChainId, + rollupRecipient: user_a, + amount: wbtc_enter_amount_u256, + token: wbtc_address, + } + ) + ); + + assert_eq!( + events[3].1, + DbSignetEvent::EnterToken( + 2, + Passage::EnterToken { + rollupChainId, + rollupRecipient: user_a, + amount: U256::from(usdc_enter_amount), + token: usdc_address, + } + ) + ); + + assert_eq!( + events[4].1, + DbSignetEvent::Transact( + 3, + Transactor::Transact { + rollupChainId, + sender: user_a, + to: user_b, + data: vec![0xab, 0xcd].into(), + value: U256::from(expected_usd_minted), + gas: U256::from(100_000), + maxFeePerGas: U256::from(GWEI_TO_WEI), + } + ) + ); + + assert_eq!( + events[5].1, + DbSignetEvent::Enter( + 0, + Passage::Enter { + rollupChainId, + rollupRecipient: user_a, + amount: eth_enter_amount_u256, + } + ) + ); + + assert_eq!( + events[6].1, + DbSignetEvent::EnterToken( + 1, + Passage::EnterToken { + rollupChainId, + rollupRecipient: user_a, + amount: wbtc_enter_amount_u256, + token: wbtc_address, + } + ) + ); + + assert_eq!( + events[7].1, + DbSignetEvent::EnterToken( + 2, + Passage::EnterToken { + rollupChainId, + rollupRecipient: user_a, + amount: U256::from(usdc_enter_amount), + token: usdc_address, + } + ) + ); + }) + .await; +} diff --git a/crates/node-tests/tests/multiple-blocks.rs b/crates/node-tests/tests/multiple-blocks.rs new file mode 100644 index 0000000..d012220 --- /dev/null +++ b/crates/node-tests/tests/multiple-blocks.rs @@ -0,0 +1,768 @@ +use alloy::{ + consensus::constants::ETH_TO_WEI, + primitives::{Address, U256}, +}; +use reth::providers::AccountExtReader; +use reth_db::{ + AccountChangeSets, AccountsHistory, cursor::DbCursorRO, models::ShardedKey, transaction::DbTx, +}; +use serial_test::serial; +use signet_constants::test_utils::HOST_USDC; +use signet_node_tests::{HostBlockSpec, SignetTestContext, run_test, utils::adjust_usd_decimals}; +use signet_test_utils::chain::{USDC_RECORD, USDT_RECORD}; + +const USER_A: Address = Address::repeat_byte(0x39); +const USER_B: Address = Address::repeat_byte(0x40); +const USER_C: Address = Address::repeat_byte(0x41); +const USER_D: Address = Address::repeat_byte(0x42); +const USER_E: Address = Address::repeat_byte(0x43); +const USER_F: Address = Address::repeat_byte(0x44); + +const ONE_HOST_USDC: usize = 1_000_000; +const ONE_RU_USDC: u128 = ETH_TO_WEI; + +#[serial] +#[tokio::test] +async fn test_three_enters() { + run_test(|ctx| async move { + let usdc_record = USDC_RECORD; + let usdt_record = USDT_RECORD; + + let usdc = usdc_record.address(); + let usdt = usdt_record.address(); + + let usdc_decimals = usdc_record.decimals(); + let usdt_decimals = usdt_record.decimals(); + + let mut a_total = U256::ZERO; + let mut b_total = U256::ZERO; + let mut c_total = U256::ZERO; + + let block_one = HostBlockSpec::new(ctx.constants()) + .with_block_number(1) + .enter_token(USER_A, 100, usdc) + .enter_token(USER_B, 200, usdc) + .enter_token(USER_C, 300, usdc); + + a_total += adjust_usd_decimals(100, usdc_decimals); + b_total += adjust_usd_decimals(200, usdc_decimals); + c_total += adjust_usd_decimals(300, usdc_decimals); + + let block_two = HostBlockSpec::new(ctx.constants()) + .with_block_number(2) + .enter_token(USER_A, 1000, usdc) + .enter_token(USER_B, 2000, usdc) + .enter_token(USER_C, 3000, usdc); + + a_total += adjust_usd_decimals(1000, usdc_decimals); + b_total += adjust_usd_decimals(2000, usdc_decimals); + c_total += adjust_usd_decimals(3000, usdc_decimals); + + let block_three = HostBlockSpec::new(ctx.constants()) + .with_block_number(3) + .enter_token(USER_A, 10000, usdt) + .enter_token(USER_B, 20000, usdt) + .enter_token(USER_C, 30000, usdt); + + a_total += adjust_usd_decimals(10000, usdt_decimals); + b_total += adjust_usd_decimals(20000, usdt_decimals); + c_total += adjust_usd_decimals(30000, usdt_decimals); + + ctx.process_blocks(vec![block_one, block_two, block_three]).await.unwrap(); + + assert_eq!(ctx.balance_of(USER_A), a_total); + assert_eq!(ctx.balance_of(USER_B), b_total); + assert_eq!(ctx.balance_of(USER_C), c_total); + }) + .await; +} + +// Processes 5 blocks, setting up accounts with initial balances and histories. +// +// After this, A will have 500, B will have 1000, C will have 1500. They will +// also have accounthistories entries for blocks 1 to 5. +async fn setup_accounts_history(ctx: SignetTestContext) -> SignetTestContext { + let block = HostBlockSpec::new(ctx.constants()) + .enter_token(USER_A, ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_B, 2 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_C, 3 * ONE_HOST_USDC, HOST_USDC); + + ctx.process_blocks(vec![block.clone(); 5]).await.unwrap(); + + ctx +} + +#[serial] +#[tokio::test] +async fn test_write_account_histories() { + run_test(|ctx| async move { + let ctx = setup_accounts_history(ctx).await; + + let another_block = HostBlockSpec::new(ctx.constants()) + .enter_token(USER_D, 10 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_E, 20 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_F, 30 * ONE_HOST_USDC, HOST_USDC); + ctx.process_blocks(vec![another_block]).await.unwrap(); + + let provider = ctx.factory.provider().unwrap(); + + let a_key = ShardedKey::new(USER_A, u64::MAX); + let b_key = ShardedKey::new(USER_B, u64::MAX); + let c_key = ShardedKey::new(USER_C, u64::MAX); + let d_key = ShardedKey::new(USER_D, u64::MAX); + let e_key = ShardedKey::new(USER_E, u64::MAX); + let f_key = ShardedKey::new(USER_F, u64::MAX); + + let v = provider + .tx_ref() + .cursor_read::() + .unwrap() + .walk_range(a_key.clone()..=f_key.clone()) + .unwrap() + .collect::, _>>() + .unwrap(); + + assert_eq!(v.len(), 6); + assert_eq!(v[0].0, a_key); + assert_eq!(v[1].0, b_key); + assert_eq!(v[2].0, c_key); + for i in 1..5 { + assert!(v[0].1.contains(i)); + assert!(v[1].1.contains(i)); + assert!(v[2].1.contains(i)); + } + assert!(!v[0].1.contains(6)); + assert!(!v[1].1.contains(6)); + assert!(!v[2].1.contains(6)); + + assert_eq!(v[3].0, d_key); + assert_eq!(v[4].0, e_key); + assert_eq!(v[5].0, f_key); + for i in 1..5 { + assert!(!v[3].1.contains(i)); + assert!(!v[4].1.contains(i)); + assert!(!v[5].1.contains(i)); + } + assert!(v[3].1.contains(6)); + assert!(v[4].1.contains(6)); + assert!(v[5].1.contains(6)); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_write_account_histories_with_empty_block() { + run_test(|ctx| async move { + let ctx = setup_accounts_history(ctx).await; + + let another_block = HostBlockSpec::new(ctx.constants()) + .enter_token(USER_D, 10 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_E, 20 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_F, 30 * ONE_HOST_USDC, HOST_USDC); + ctx.process_blocks(vec![another_block]).await.unwrap(); + + let provider = ctx.factory.provider().unwrap(); + + let a_key = ShardedKey::new(USER_A, u64::MAX); + let b_key = ShardedKey::new(USER_B, u64::MAX); + let c_key = ShardedKey::new(USER_C, u64::MAX); + let d_key = ShardedKey::new(USER_D, u64::MAX); + let e_key = ShardedKey::new(USER_E, u64::MAX); + let f_key = ShardedKey::new(USER_F, u64::MAX); + + let v = provider + .tx_ref() + .cursor_read::() + .unwrap() + .walk_range(a_key.clone()..=f_key.clone()) + .unwrap() + .collect::, _>>() + .unwrap(); + + assert_eq!(v.len(), 6); + assert_eq!(v[0].0, a_key); + assert_eq!(v[1].0, b_key); + assert_eq!(v[2].0, c_key); + for i in 1..5 { + assert!(v[0].1.contains(i)); + assert!(v[1].1.contains(i)); + assert!(v[2].1.contains(i)); + } + assert!(!v[0].1.contains(6)); + assert!(!v[1].1.contains(6)); + assert!(!v[2].1.contains(6)); + + assert_eq!(v[3].0, d_key); + assert_eq!(v[4].0, e_key); + assert_eq!(v[5].0, f_key); + for i in 1..5 { + assert!(!v[3].1.contains(i)); + assert!(!v[4].1.contains(i)); + assert!(!v[5].1.contains(i)); + } + assert!(v[3].1.contains(6)); + assert!(v[4].1.contains(6)); + assert!(v[5].1.contains(6)); + + let empty_block = HostBlockSpec::new(ctx.constants()); + ctx.process_block(empty_block).await.unwrap(); + + // As we did not process a new RU block, the history should not change. + let v = provider + .tx_ref() + .cursor_read::() + .unwrap() + .walk_range(a_key.clone()..=f_key.clone()) + .unwrap() + .collect::, _>>() + .unwrap(); + + assert_eq!(v.len(), 6); + assert_eq!(v[0].0, a_key); + assert_eq!(v[1].0, b_key); + assert_eq!(v[2].0, c_key); + for i in 1..5 { + assert!(v[0].1.contains(i)); + assert!(v[1].1.contains(i)); + assert!(v[2].1.contains(i)); + } + assert!(!v[0].1.contains(6)); + assert!(!v[1].1.contains(6)); + assert!(!v[2].1.contains(6)); + + assert_eq!(v[3].0, d_key); + assert_eq!(v[4].0, e_key); + assert_eq!(v[5].0, f_key); + for i in 1..5 { + assert!(!v[3].1.contains(i)); + assert!(!v[4].1.contains(i)); + assert!(!v[5].1.contains(i)); + } + assert!(v[3].1.contains(6)); + assert!(v[4].1.contains(6)); + assert!(v[5].1.contains(6)); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_write_account_histories_with_reorg_and_empty_blocks() { + run_test(|ctx| async move { + let ctx = setup_accounts_history(ctx).await; + + let provider = ctx.factory.provider().unwrap(); + + let a_key = ShardedKey::new(USER_A, u64::MAX); + let b_key = ShardedKey::new(USER_B, u64::MAX); + let c_key = ShardedKey::new(USER_C, u64::MAX); + + let another_block = HostBlockSpec::new(ctx.constants()) + .enter_token(USER_A, 10 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_B, 2 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_C, 3 * ONE_HOST_USDC, HOST_USDC); + ctx.process_blocks(vec![another_block.clone()]).await.unwrap(); + + let v = provider + .tx_ref() + .cursor_read::() + .unwrap() + .walk_range(a_key.clone()..=c_key.clone()) + .unwrap() + .collect::, _>>() + .unwrap(); + + assert_eq!(v.len(), 3); + assert_eq!(v[0].0, a_key); + assert_eq!(v[1].0, b_key); + assert_eq!(v[2].0, c_key); + + for i in 1..6 { + assert!(v[0].1.contains(i)); + assert!(v[1].1.contains(i)); + assert!(v[2].1.contains(i)); + } + + // After reorg, the history should not contain the latest entries + ctx.revert_block(another_block).await.unwrap(); + + let v = provider + .tx_ref() + .cursor_read::() + .unwrap() + .walk_range(a_key.clone()..=c_key.clone()) + .unwrap() + .collect::, _>>() + .unwrap(); + + assert_eq!(v.len(), 3); + assert_eq!(v[0].0, a_key); + assert_eq!(v[1].0, b_key); + assert_eq!(v[2].0, c_key); + + for i in 1..5 { + assert!(v[0].1.contains(i)); + assert!(v[1].1.contains(i)); + assert!(v[2].1.contains(i)); + } + assert!(!v[0].1.contains(6)); + assert!(!v[1].1.contains(6)); + assert!(!v[2].1.contains(6)); + + // Now process an empty block. + let empty_block = HostBlockSpec::new(ctx.constants()); + ctx.process_block(empty_block).await.unwrap(); + + // As we did not process a new RU block, the history should not change. + let v = provider + .tx_ref() + .cursor_read::() + .unwrap() + .walk_range(a_key.clone()..=c_key.clone()) + .unwrap() + .collect::, _>>() + .unwrap(); + + assert_eq!(v.len(), 3); + assert_eq!(v[0].0, a_key); + assert_eq!(v[1].0, b_key); + assert_eq!(v[2].0, c_key); + + for i in 1..5 { + assert!(v[0].1.contains(i)); + assert!(v[1].1.contains(i)); + assert!(v[2].1.contains(i)); + } + assert!(!v[0].1.contains(6)); + assert!(!v[1].1.contains(6)); + assert!(!v[2].1.contains(6)); + + // re-process the reorged block. + let another_block = HostBlockSpec::new(ctx.constants()) + .enter_token(USER_A, 10 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_B, 2 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_C, 3 * ONE_HOST_USDC, HOST_USDC); + ctx.process_blocks(vec![another_block.clone()]).await.unwrap(); + + let v = provider + .tx_ref() + .cursor_read::() + .unwrap() + .walk_range(a_key.clone()..=c_key.clone()) + .unwrap() + .collect::, _>>() + .unwrap(); + + assert_eq!(v.len(), 3); + assert_eq!(v[0].0, a_key); + assert_eq!(v[1].0, b_key); + assert_eq!(v[2].0, c_key); + + for i in 1..6 { + assert!(v[0].1.contains(i)); + assert!(v[1].1.contains(i)); + assert!(v[2].1.contains(i)); + } + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_write_account_histories_with_reorg() { + run_test(|ctx| async move { + let ctx = setup_accounts_history(ctx).await; + + let provider = ctx.factory.provider().unwrap(); + + let a_key = ShardedKey::new(USER_A, u64::MAX); + let b_key = ShardedKey::new(USER_B, u64::MAX); + let c_key = ShardedKey::new(USER_C, u64::MAX); + + let another_block = HostBlockSpec::new(ctx.constants()) + .enter_token(USER_A, 10 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_B, 2 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_C, 3 * ONE_HOST_USDC, HOST_USDC); + ctx.process_blocks(vec![another_block.clone()]).await.unwrap(); + + let v = provider + .tx_ref() + .cursor_read::() + .unwrap() + .walk_range(a_key.clone()..=c_key.clone()) + .unwrap() + .collect::, _>>() + .unwrap(); + + assert_eq!(v.len(), 3); + assert_eq!(v[0].0, a_key); + assert_eq!(v[1].0, b_key); + assert_eq!(v[2].0, c_key); + + for i in 1..6 { + assert!(v[0].1.contains(i)); + assert!(v[1].1.contains(i)); + assert!(v[2].1.contains(i)); + } + + // After reorg, the history should not contain the latest entries + ctx.revert_block(another_block).await.unwrap(); + + let v = provider + .tx_ref() + .cursor_read::() + .unwrap() + .walk_range(a_key.clone()..=c_key.clone()) + .unwrap() + .collect::, _>>() + .unwrap(); + + assert_eq!(v.len(), 3); + assert_eq!(v[0].0, a_key); + assert_eq!(v[1].0, b_key); + assert_eq!(v[2].0, c_key); + + for i in 1..5 { + assert!(v[0].1.contains(i)); + assert!(v[1].1.contains(i)); + assert!(v[2].1.contains(i)); + } + assert!(!v[0].1.contains(6)); + assert!(!v[1].1.contains(6)); + assert!(!v[2].1.contains(6)); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_historical_state_provider(ctx: SignetTestContext) { + run_test(|ctx| async move { + let ctx = setup_accounts_history(ctx).await; + + let another_block = HostBlockSpec::new(ctx.constants()) + .enter_token(USER_A, 10 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_B, 20 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_C, 30 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_D, 40 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_E, 50 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_F, 60 * ONE_HOST_USDC, HOST_USDC); + ctx.process_blocks(vec![another_block]).await.unwrap(); + + let provider = ctx.factory.provider().unwrap(); + + // NB: It is bizarre that reth has completely different APIs for + // historical state and current state. basic_accounts is only on + // current while account_balance is only on historical. + let accounts = + provider.basic_accounts([USER_A, USER_B, USER_C, USER_D, USER_E, USER_F]).unwrap(); + + assert_eq!(accounts[0].1.as_ref().unwrap().balance, U256::from(15 * ONE_RU_USDC)); + assert_eq!(accounts[1].1.as_ref().unwrap().balance, U256::from(30 * ONE_RU_USDC)); + assert_eq!(accounts[2].1.as_ref().unwrap().balance, U256::from(45 * ONE_RU_USDC)); + assert_eq!(accounts[3].1.as_ref().unwrap().balance, U256::from(40 * ONE_RU_USDC)); + assert_eq!(accounts[4].1.as_ref().unwrap().balance, U256::from(50 * ONE_RU_USDC)); + assert_eq!(accounts[5].1.as_ref().unwrap().balance, U256::from(60 * ONE_RU_USDC)); + + let historical = ctx.factory.history_by_block_number(5).unwrap(); + assert_eq!( + historical.account_balance(&USER_A).unwrap().unwrap(), + U256::from(5 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_B).unwrap().unwrap(), + U256::from(10 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_C).unwrap().unwrap(), + U256::from(15 * ONE_RU_USDC) + ); + assert!(historical.account_balance(&USER_D).unwrap().is_none()); + assert!(historical.account_balance(&USER_E).unwrap().is_none()); + assert!(historical.account_balance(&USER_F).unwrap().is_none()); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_historical_state_provider_with_empty_blocks(ctx: SignetTestContext) { + run_test(|ctx| async move { + let ctx = setup_accounts_history(ctx).await; + + let another_block = HostBlockSpec::new(ctx.constants()) + .enter_token(USER_A, 10 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_B, 20 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_C, 30 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_D, 40 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_E, 50 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_F, 60 * ONE_HOST_USDC, HOST_USDC); + ctx.process_blocks(vec![another_block]).await.unwrap(); + + let provider = ctx.factory.provider().unwrap(); + + // NB: It is bizarre that reth has completely different APIs for + // historical state and current state. basic_accounts is only on + // current while account_balance is only on historical. + let accounts = + provider.basic_accounts([USER_A, USER_B, USER_C, USER_D, USER_E, USER_F]).unwrap(); + + assert_eq!(accounts[0].1.as_ref().unwrap().balance, U256::from(15 * ONE_RU_USDC)); + assert_eq!(accounts[1].1.as_ref().unwrap().balance, U256::from(30 * ONE_RU_USDC)); + assert_eq!(accounts[2].1.as_ref().unwrap().balance, U256::from(45 * ONE_RU_USDC)); + assert_eq!(accounts[3].1.as_ref().unwrap().balance, U256::from(40 * ONE_RU_USDC)); + assert_eq!(accounts[4].1.as_ref().unwrap().balance, U256::from(50 * ONE_RU_USDC)); + assert_eq!(accounts[5].1.as_ref().unwrap().balance, U256::from(60 * ONE_RU_USDC)); + + let historical = ctx.factory.history_by_block_number(5).unwrap(); + assert_eq!( + historical.account_balance(&USER_A).unwrap().unwrap(), + U256::from(5 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_B).unwrap().unwrap(), + U256::from(10 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_C).unwrap().unwrap(), + U256::from(15 * ONE_RU_USDC) + ); + assert!(historical.account_balance(&USER_D).unwrap().is_none()); + assert!(historical.account_balance(&USER_E).unwrap().is_none()); + assert!(historical.account_balance(&USER_F).unwrap().is_none()); + + let empty_block = HostBlockSpec::new(ctx.constants()); + ctx.process_blocks(vec![empty_block; 2]).await.unwrap(); + + // the historical state that we previously checked should not change, even after processing empty blocks. + let accounts = + provider.basic_accounts([USER_A, USER_B, USER_C, USER_D, USER_E, USER_F]).unwrap(); + + assert_eq!(accounts[0].1.as_ref().unwrap().balance, U256::from(15 * ONE_RU_USDC)); + assert_eq!(accounts[1].1.as_ref().unwrap().balance, U256::from(30 * ONE_RU_USDC)); + assert_eq!(accounts[2].1.as_ref().unwrap().balance, U256::from(45 * ONE_RU_USDC)); + assert_eq!(accounts[3].1.as_ref().unwrap().balance, U256::from(40 * ONE_RU_USDC)); + assert_eq!(accounts[4].1.as_ref().unwrap().balance, U256::from(50 * ONE_RU_USDC)); + assert_eq!(accounts[5].1.as_ref().unwrap().balance, U256::from(60 * ONE_RU_USDC)); + + let historical = ctx.factory.history_by_block_number(5).unwrap(); + assert_eq!( + historical.account_balance(&USER_A).unwrap().unwrap(), + U256::from(5 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_B).unwrap().unwrap(), + U256::from(10 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_C).unwrap().unwrap(), + U256::from(15 * ONE_RU_USDC) + ); + assert!(historical.account_balance(&USER_D).unwrap().is_none()); + assert!(historical.account_balance(&USER_E).unwrap().is_none()); + assert!(historical.account_balance(&USER_F).unwrap().is_none()); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_historical_state_provider_with_reorg() { + run_test(|ctx| async move { + let ctx = setup_accounts_history(ctx).await; + + let another_block = HostBlockSpec::new(ctx.constants()) + .enter_token(USER_A, 10 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_B, 20 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_C, 30 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_D, 40 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_E, 50 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_F, 60 * ONE_HOST_USDC, HOST_USDC); + ctx.process_blocks(vec![another_block.clone()]).await.unwrap(); + + let provider = ctx.factory.provider().unwrap(); + + // NB: It is bizarre that reth has completely different APIs for + // historical state and current state. basic_accounts is only on + // current while account_balance is only on historical. + let accounts = + provider.basic_accounts([USER_A, USER_B, USER_C, USER_D, USER_E, USER_F]).unwrap(); + + assert_eq!(accounts[0].1.as_ref().unwrap().balance, U256::from(15 * ONE_RU_USDC)); + assert_eq!(accounts[1].1.as_ref().unwrap().balance, U256::from(30 * ONE_RU_USDC)); + assert_eq!(accounts[2].1.as_ref().unwrap().balance, U256::from(45 * ONE_RU_USDC)); + assert_eq!(accounts[3].1.as_ref().unwrap().balance, U256::from(40 * ONE_RU_USDC)); + assert_eq!(accounts[4].1.as_ref().unwrap().balance, U256::from(50 * ONE_RU_USDC)); + assert_eq!(accounts[5].1.as_ref().unwrap().balance, U256::from(60 * ONE_RU_USDC)); + + let historical = ctx.factory.history_by_block_number(5).unwrap(); + assert_eq!( + historical.account_balance(&USER_A).unwrap().unwrap(), + U256::from(5 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_B).unwrap().unwrap(), + U256::from(10 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_C).unwrap().unwrap(), + U256::from(15 * ONE_RU_USDC) + ); + assert!(historical.account_balance(&USER_D).unwrap().is_none()); + assert!(historical.account_balance(&USER_E).unwrap().is_none()); + assert!(historical.account_balance(&USER_F).unwrap().is_none()); + + ctx.revert_block(another_block).await.unwrap(); + // Make the same assertions after reverting, the historical state should not change + assert_eq!( + historical.account_balance(&USER_A).unwrap().unwrap(), + U256::from(5 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_B).unwrap().unwrap(), + U256::from(10 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_C).unwrap().unwrap(), + U256::from(15 * ONE_RU_USDC) + ); + assert!(historical.account_balance(&USER_D).unwrap().is_none()); + assert!(historical.account_balance(&USER_E).unwrap().is_none()); + assert!(historical.account_balance(&USER_F).unwrap().is_none()); + + let new_block_6 = HostBlockSpec::new(ctx.constants()) + .enter_token(USER_A, 10 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_B, 20 * ONE_HOST_USDC, HOST_USDC) + .enter_token(USER_C, 30 * ONE_HOST_USDC, HOST_USDC); + + ctx.process_block(new_block_6).await.unwrap(); + + // new current state assertions + let provider = ctx.factory.provider().unwrap(); + let accounts = + provider.basic_accounts([USER_A, USER_B, USER_C, USER_D, USER_E, USER_F]).unwrap(); + assert_eq!(accounts[0].1.as_ref().unwrap().balance, U256::from(15 * ONE_RU_USDC)); + assert_eq!(accounts[1].1.as_ref().unwrap().balance, U256::from(30 * ONE_RU_USDC)); + assert_eq!(accounts[2].1.as_ref().unwrap().balance, U256::from(45 * ONE_RU_USDC)); + assert!(accounts[3].1.is_none()); + assert!(accounts[4].1.is_none()); + assert!(accounts[5].1.is_none()); + + // Make the same assertions after the new block 6, the historical state should not change + assert_eq!( + historical.account_balance(&USER_A).unwrap().unwrap(), + U256::from(5 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_B).unwrap().unwrap(), + U256::from(10 * ONE_RU_USDC) + ); + assert_eq!( + historical.account_balance(&USER_C).unwrap().unwrap(), + U256::from(15 * ONE_RU_USDC) + ); + assert!(historical.account_balance(&USER_D).unwrap().is_none()); + assert!(historical.account_balance(&USER_E).unwrap().is_none()); + assert!(historical.account_balance(&USER_F).unwrap().is_none()); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_write_changesets() { + run_test(|ctx| async move { + let ctx = setup_accounts_history(ctx).await; + + let provider = ctx.factory.provider().unwrap(); + + let mut cursor = provider.tx_ref().cursor_dup_read::().unwrap(); + + let entries_4 = + cursor.walk_range(4..5).unwrap().map(Result::unwrap).map(|t| t.1).collect::>(); + + let entry_a = entries_4.iter().find(|e| e.address == USER_A).unwrap(); + let entry_b = entries_4.iter().find(|e| e.address == USER_B).unwrap(); + let entry_c = entries_4.iter().find(|e| e.address == USER_C).unwrap(); + + assert_eq!(entry_a.info.as_ref().unwrap().balance, U256::from(3 * ONE_RU_USDC)); + assert_eq!(entry_b.info.as_ref().unwrap().balance, U256::from(6 * ONE_RU_USDC)); + assert_eq!(entry_c.info.as_ref().unwrap().balance, U256::from(9 * ONE_RU_USDC)); + + let entries_5 = + cursor.walk(Some(5)).unwrap().map(Result::unwrap).map(|t| t.1).collect::>(); + + let entry_a = entries_5.iter().find(|e| e.address == USER_A).unwrap(); + let entry_b = entries_5.iter().find(|e| e.address == USER_B).unwrap(); + let entry_c = entries_5.iter().find(|e| e.address == USER_C).unwrap(); + + assert_eq!(entry_a.info.as_ref().unwrap().balance, U256::from(4 * ONE_RU_USDC)); + assert_eq!(entry_b.info.as_ref().unwrap().balance, U256::from(8 * ONE_RU_USDC)); + assert_eq!(entry_c.info.as_ref().unwrap().balance, U256::from(12 * ONE_RU_USDC)); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_write_changesets_with_empty_blocks() { + run_test(|ctx| async move { + let ctx = setup_accounts_history(ctx).await; + + let provider = ctx.factory.provider().unwrap(); + + let mut cursor = provider.tx_ref().cursor_dup_read::().unwrap(); + + let entries_4 = + cursor.walk_range(4..5).unwrap().map(Result::unwrap).map(|t| t.1).collect::>(); + + let entry_a = entries_4.iter().find(|e| e.address == USER_A).unwrap(); + let entry_b = entries_4.iter().find(|e| e.address == USER_B).unwrap(); + let entry_c = entries_4.iter().find(|e| e.address == USER_C).unwrap(); + + assert_eq!(entry_a.info.as_ref().unwrap().balance, U256::from(3 * ONE_RU_USDC)); + assert_eq!(entry_b.info.as_ref().unwrap().balance, U256::from(6 * ONE_RU_USDC)); + assert_eq!(entry_c.info.as_ref().unwrap().balance, U256::from(9 * ONE_RU_USDC)); + + let entries_5 = + cursor.walk(Some(5)).unwrap().map(Result::unwrap).map(|t| t.1).collect::>(); + + let entry_a = entries_5.iter().find(|e| e.address == USER_A).unwrap(); + let entry_b = entries_5.iter().find(|e| e.address == USER_B).unwrap(); + let entry_c = entries_5.iter().find(|e| e.address == USER_C).unwrap(); + + assert_eq!(entry_a.info.as_ref().unwrap().balance, U256::from(4 * ONE_RU_USDC)); + assert_eq!(entry_b.info.as_ref().unwrap().balance, U256::from(8 * ONE_RU_USDC)); + assert_eq!(entry_c.info.as_ref().unwrap().balance, U256::from(12 * ONE_RU_USDC)); + + let empty_block = HostBlockSpec::new(ctx.constants()); + ctx.process_blocks(vec![empty_block; 2]).await.unwrap(); + + // Even after processing empty blocks, the changesets should not change. + let mut cursor = provider.tx_ref().cursor_dup_read::().unwrap(); + + let entries_4 = + cursor.walk_range(4..5).unwrap().map(Result::unwrap).map(|t| t.1).collect::>(); + + let entry_a = entries_4.iter().find(|e| e.address == USER_A).unwrap(); + let entry_b = entries_4.iter().find(|e| e.address == USER_B).unwrap(); + let entry_c = entries_4.iter().find(|e| e.address == USER_C).unwrap(); + + assert_eq!(entry_a.info.as_ref().unwrap().balance, U256::from(3 * ONE_RU_USDC)); + assert_eq!(entry_b.info.as_ref().unwrap().balance, U256::from(6 * ONE_RU_USDC)); + assert_eq!(entry_c.info.as_ref().unwrap().balance, U256::from(9 * ONE_RU_USDC)); + + let entries_5 = + cursor.walk(Some(5)).unwrap().map(Result::unwrap).map(|t| t.1).collect::>(); + + let entry_a = entries_5.iter().find(|e| e.address == USER_A).unwrap(); + let entry_b = entries_5.iter().find(|e| e.address == USER_B).unwrap(); + let entry_c = entries_5.iter().find(|e| e.address == USER_C).unwrap(); + + assert_eq!(entry_a.info.as_ref().unwrap().balance, U256::from(4 * ONE_RU_USDC)); + assert_eq!(entry_b.info.as_ref().unwrap().balance, U256::from(8 * ONE_RU_USDC)); + assert_eq!(entry_c.info.as_ref().unwrap().balance, U256::from(12 * ONE_RU_USDC)); + }) + .await; +} diff --git a/crates/node-tests/tests/orders.rs b/crates/node-tests/tests/orders.rs new file mode 100644 index 0000000..04b6dbc --- /dev/null +++ b/crates/node-tests/tests/orders.rs @@ -0,0 +1,460 @@ +use alloy::{ + consensus::constants::GWEI_TO_WEI, + eips::BlockNumberOrTag, + primitives::{Address, U256}, + providers::Provider, + rpc::types::eth::TransactionRequest, + sol_types::{SolCall, SolEvent}, +}; +use serial_test::serial; +use signet_node_tests::{ + HostBlockSpec, RuBlockSpec, SignetTestContext, + aliases::{Erc20, TestErc20Instance}, + run_test, +}; +use signet_types::constants::HostPermitted; +use signet_zenith::RollupOrders; + +#[serial] +#[tokio::test] +async fn test_eth_order_success() { + run_test(|ctx| async move { + let user = ctx.addresses[0]; + let host_token = Address::repeat_byte(0x38); + let host_token_amnt = U256::from(100_000_000); + let eth_in_amnt = U256::from(GWEI_TO_WEI); + + let mut bal = ctx.track_balance(user, Some("user")); + let mut order_bal = ctx.track_balance(ctx.constants.rollup().orders(), Some("orders")); + + let input = RollupOrders::Input { token: Address::ZERO, amount: eth_in_amnt }; + let output = RollupOrders::Output { + chainId: ctx.constants.host().chain_id() as u32, + recipient: user, + token: host_token, + amount: host_token_amnt, + }; + + let tx = TransactionRequest::default() + .from(user) + .to(ctx.constants.rollup().orders()) + .value(eth_in_amnt) + .input( + RollupOrders::initiateCall { + deadline: U256::MAX, + inputs: vec![input], + outputs: vec![output], + } + .abi_encode() + .into(), + ); + let tx = ctx.fill_alloy_tx(&tx).await.unwrap(); + + let block = HostBlockSpec::new(ctx.constants()) + .fill(host_token, user, 100_000_000) + .submit_block(RuBlockSpec::new(ctx.constants()).alloy_tx(&tx)); + + ctx.process_block(block).await.unwrap(); + + order_bal.assert_increase_exact(eth_in_amnt); + bal.assert_decrease_at_least(eth_in_amnt); + + let events = ctx.ru_orders_contract().Order_filter().query().await.unwrap(); + let order = &events[0].0; + assert_eq!(order.inputs[0], input); + assert_eq!(order.outputs[0], output); + + let block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .await + .unwrap() + .unwrap(); + let tx = *block.transactions.as_hashes().unwrap().first().unwrap(); + let receipt = ctx.alloy_provider.get_transaction_receipt(tx).await.unwrap().unwrap(); + + assert!(receipt.status()); + assert_eq!(receipt.inner.logs().len(), 1); + assert_eq!(receipt.inner.logs()[0].address(), *ctx.ru_orders_contract().address()); + assert_eq!(receipt.inner.logs()[0].topic0(), Some(&RollupOrders::Order::SIGNATURE_HASH)); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_eth_order_failure() { + run_test(|ctx| async move { + let user = ctx.addresses[0]; + let host_token = Address::repeat_byte(0x38); + let host_token_amnt = U256::from(100_000_000); + let eth_in_amnt = U256::from(GWEI_TO_WEI); + + let mut bal = ctx.track_balance(user, Some("user")); + let mut order_bal = ctx.track_balance(ctx.constants.rollup().orders(), Some("orders")); + + let input = RollupOrders::Input { token: Address::ZERO, amount: eth_in_amnt }; + let output = RollupOrders::Output { + chainId: ctx.constants.host().chain_id() as u32, + recipient: user, + token: host_token, + amount: host_token_amnt, + }; + + let tx = TransactionRequest::default() + .from(user) + .to(ctx.constants.rollup().orders()) + .value(eth_in_amnt) + .input( + RollupOrders::initiateCall { + deadline: U256::MAX, + inputs: vec![input], + outputs: vec![output], + } + .abi_encode() + .into(), + ); + + let e = ctx.process_alloy_tx(&tx).await.unwrap_err(); + assert!(e.to_string().contains("no receipt")); + + order_bal.assert_no_change(); + bal.assert_no_change(); + + let block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .await + .unwrap() + .unwrap(); + + // transaction did not occur + assert!(block.transactions.as_hashes().unwrap().is_empty()); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_token_order_success() { + run_test(|mut ctx| async move { + ctx = test_inner(ctx, HostPermitted::Weth).await; + test_inner(ctx, HostPermitted::Wbtc).await; + }) + .await; + + async fn test_inner(ctx: SignetTestContext, token: HostPermitted) -> SignetTestContext { + let user = ctx.addresses[0]; + let host_token_addr = ctx.constants.host().tokens().address_for(token); + let amount = U256::from(10_000); + + let ru_token_addr = ctx.constants.rollup().tokens().address_for(token.into()); + let ru_token = TestErc20Instance::new(ru_token_addr, ctx.alloy_provider.clone()); + + ctx.mint_token(token, user, amount.to()).await.unwrap(); + + let input = RollupOrders::Input { token: ru_token_addr, amount }; + let output = RollupOrders::Output { + chainId: ctx.constants.host().chain_id() as u32, + recipient: user, + token: host_token_addr, + amount, + }; + + // approve the orders contract to spend tokens + let approve_tx = TransactionRequest::default() + .from(user) + .to(ctx.constants.rollup().tokens().address_for(token.into())) + .input( + Erc20::approveCall { _0: ctx.constants.rollup().orders(), _1: U256::MAX } + .abi_encode() + .into(), + ); + ctx.process_alloy_tx(&approve_tx).await.unwrap(); + + let tx = + TransactionRequest::default().from(user).to(ctx.constants.rollup().orders()).input( + RollupOrders::initiateCall { + deadline: U256::MAX, + inputs: vec![input], + outputs: vec![output], + } + .abi_encode() + .into(), + ); + let tx = ctx.fill_alloy_tx(&tx).await.unwrap(); + + let block = HostBlockSpec::new(ctx.constants()) + .fill(host_token_addr, user, 100_000_000) + .submit_block(RuBlockSpec::new(ctx.constants()).alloy_tx(&tx)); + + ctx.process_block(block).await.unwrap(); + + // tokens are transferred to the orders contract + assert_eq!(ru_token.balanceOf(user).call().await.unwrap(), U256::ZERO); + assert_eq!( + ru_token.balanceOf(ctx.constants.rollup().orders()).call().await.unwrap(), + amount + ); + + // RPC shows the tx and receipt and event + let block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .await + .unwrap() + .unwrap(); + + let tx = *block.transactions.as_hashes().unwrap().first().unwrap(); + + let receipt = ctx.alloy_provider.get_transaction_receipt(tx).await.unwrap().unwrap(); + + assert!(receipt.status()); + assert!(receipt.inner.logs().len() > 1); + let order = receipt.inner.logs().last().unwrap(); + assert_eq!(order.address(), *ctx.ru_orders_contract().address()); + assert_eq!(order.topic0(), Some(&RollupOrders::Order::SIGNATURE_HASH)); + + ctx + } +} + +#[serial] +#[tokio::test] +async fn test_token_order_failure() { + run_test(|mut ctx| async move { + ctx = test_inner(ctx, HostPermitted::Weth).await; + test_inner(ctx, HostPermitted::Wbtc).await; + }) + .await; + + async fn test_inner(ctx: SignetTestContext, token: HostPermitted) -> SignetTestContext { + let user = ctx.addresses[0]; + let host_token_addr = ctx.constants.host().tokens().address_for(token); + let amount = U256::from(10_000); + + let ru_token_addr = ctx.constants.rollup().tokens().address_for(token.into()); + let ru_token = TestErc20Instance::new(ru_token_addr, ctx.alloy_provider.clone()); + + // mint some tokens + ctx.mint_token(token, user, amount.to()).await.unwrap(); + + // approve the orders contract to spend tokens + let approve_tx = TransactionRequest::default() + .from(user) + .to(ctx.constants.rollup().tokens().address_for(token.into())) + .input( + Erc20::approveCall { _0: ctx.constants.rollup().orders(), _1: U256::MAX } + .abi_encode() + .into(), + ); + ctx.process_alloy_tx(&approve_tx).await.unwrap(); + + // track bal before tx, after approve + let mut bal = ctx.track_balance(user, Some("user")); + + // initiate the order + let input = RollupOrders::Input { token: ru_token_addr, amount }; + let output = RollupOrders::Output { + chainId: ctx.constants.host().chain_id() as u32, + recipient: user, + token: host_token_addr, + amount, + }; + + let tx = + TransactionRequest::default().from(user).to(ctx.constants.rollup().orders()).input( + RollupOrders::initiateCall { + deadline: U256::MAX, + inputs: vec![input], + outputs: vec![output], + } + .abi_encode() + .into(), + ); + let e = ctx.process_alloy_tx(&tx).await.unwrap_err(); + assert!(e.to_string().contains("no receipt")); + + // user did not pay gas + bal.assert_no_change(); + + // tokens are not transferred to the orders contract + assert_eq!( + ru_token.balanceOf(ctx.constants.rollup().orders()).call().await.unwrap(), + U256::ZERO + ); + assert_eq!(ru_token.balanceOf(user).call().await.unwrap(), amount); + + let block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .await + .unwrap() + .unwrap(); + + // transaction is not in the block + assert!(block.transactions.as_hashes().unwrap().is_empty()); + + ctx + } +} + +#[serial] +#[tokio::test] +async fn fill_two_orders() { + run_test(|ctx| async move { + let user = ctx.addresses[0]; + let user_2 = ctx.addresses[1]; + + let host_token = Address::repeat_byte(0x38); + let host_token_amnt = U256::from(100_000_000); + + let eth_in_amnt = U256::from(GWEI_TO_WEI); + + // Note that both orders pay to the same recipient + let input = RollupOrders::Input { token: Address::ZERO, amount: eth_in_amnt }; + let output = RollupOrders::Output { + chainId: ctx.constants.host().chain_id() as u32, + recipient: user, + token: host_token, + amount: host_token_amnt, + }; + + let tx_1 = TransactionRequest::default() + .from(user) + .to(ctx.constants.rollup().orders()) + .value(eth_in_amnt) + .input( + RollupOrders::initiateCall { + deadline: U256::MAX, + inputs: vec![input], + outputs: vec![output], + } + .abi_encode() + .into(), + ); + let tx_1 = ctx.fill_alloy_tx(&tx_1).await.unwrap(); + + let tx_2 = TransactionRequest::default() + .from(user_2) + .to(ctx.constants.rollup().orders()) + .value(eth_in_amnt) + .input( + RollupOrders::initiateCall { + deadline: U256::MAX, + inputs: vec![input], + outputs: vec![output], + } + .abi_encode() + .into(), + ); + let tx_2 = ctx.fill_alloy_tx(&tx_2).await.unwrap(); + + // fill both orders at once + let block = HostBlockSpec::new(ctx.constants()) + .fill(host_token, user, 100_000_000 * 2) + .submit_block(RuBlockSpec::new(ctx.constants()).alloy_tx(&tx_1).alloy_tx(&tx_2)); + + ctx.process_block(block).await.unwrap(); + + // check that the orders executed + let events = ctx.ru_orders_contract().Order_filter().query().await.unwrap(); + let order_1 = &events[0].0; + let order_2 = &events[1].0; + + assert_eq!(order_1.inputs[0], input); + assert_eq!(order_1.outputs[0], output); + + assert_eq!(order_2.inputs[0], input); + assert_eq!(order_2.outputs[0], output); + }) + .await; +} + +// Test that if fill is insufficient, the first order will work, and the second +// won't +#[serial] +#[tokio::test] +async fn fill_two_orders_second_incomplete() { + run_test(|ctx| async move { + let user = ctx.addresses[0]; + let user_2 = ctx.addresses[1]; + + let host_token = Address::repeat_byte(0x38); + let host_token_amnt_1 = U256::from(100_000_000); + let host_token_amnt_2 = U256::from(50_000_000); + + let eth_in_amnt = U256::from(GWEI_TO_WEI); + + let input = RollupOrders::Input { token: Address::ZERO, amount: eth_in_amnt }; + + // Note that both orders pay to the same recipient + let output_1 = RollupOrders::Output { + chainId: ctx.constants.host().chain_id() as u32, + recipient: user, + token: host_token, + amount: host_token_amnt_1, + }; + let output_2 = RollupOrders::Output { + chainId: ctx.constants.host().chain_id() as u32, + recipient: user, + token: host_token, + amount: host_token_amnt_2, + }; + + let tx_1 = TransactionRequest::default() + .from(user) + .to(ctx.constants.rollup().orders()) + .value(eth_in_amnt) + .input( + RollupOrders::initiateCall { + deadline: U256::MAX, + inputs: vec![input], + outputs: vec![output_1], + } + .abi_encode() + .into(), + ); + + let tx_2 = TransactionRequest::default() + .from(user_2) + .to(ctx.constants.rollup().orders()) + .value(eth_in_amnt) + .input( + RollupOrders::initiateCall { + deadline: U256::MAX, + inputs: vec![input], + outputs: vec![output_2], + } + .abi_encode() + .into(), + ); + + let tx_1 = ctx.fill_alloy_tx(&tx_1).await.unwrap(); + let tx_2 = ctx.fill_alloy_tx(&tx_2).await.unwrap(); + + // the fill is sufficient for the first order, but not the second + let block = HostBlockSpec::new(ctx.constants()) + .fill(host_token, user, (host_token_amnt_1 + host_token_amnt_2 - U256::from(1)).to()) + .submit_block(RuBlockSpec::new(ctx.constants()).alloy_tx(&tx_1).alloy_tx(&tx_2)); + + ctx.process_block(block).await.unwrap(); + + let events = ctx.ru_orders_contract().Order_filter().query().await.unwrap(); + assert_eq!(events.len(), 1); + + let block = ctx + .alloy_provider + .get_block_by_number(BlockNumberOrTag::Latest) + .await + .unwrap() + .unwrap(); + + assert_eq!(block.transactions.as_hashes().unwrap().len(), 1); + let tx = *block.transactions.as_hashes().unwrap().first().unwrap(); + + let receipt = ctx.alloy_provider.get_transaction_receipt(tx).await.unwrap().unwrap(); + assert!(receipt.status()); + }) + .await; +} diff --git a/crates/node-tests/tests/rpc.rs b/crates/node-tests/tests/rpc.rs new file mode 100644 index 0000000..3aed297 --- /dev/null +++ b/crates/node-tests/tests/rpc.rs @@ -0,0 +1,559 @@ +#![allow(non_snake_case)] + +use alloy::{ + consensus::Transaction, + eips::BlockNumberOrTag, + network::TransactionResponse, + primitives::{Address, B256, Bytes, LogData, U256}, + providers::Provider, + pubsub::Subscription, + rpc::types::{ + Header, + eth::{Filter, FilterBlockOption, Log}, + }, + sol_types::SolEvent, +}; +use reth::providers::{BlockNumReader, BlockReader, TransactionsProvider}; +use serial_test::serial; +use signet_node_tests::{ + SignetTestContext, + aliases::{Counter, TestCounterInstance}, + constants::TEST_CONSTANTS, + rpc_test, +}; +use signet_test_utils::contracts::counter::{COUNTER_BYTECODE, COUNTER_DEPLOY_CODE}; +use tokio::try_join; + +#[serial] +#[tokio::test] +async fn test_basic_rpc_calls() { + rpc_test(|ctx, contract| async move { + tokio::join!( + test_eth_chainId(&ctx), + test_eth_gasPrice(&ctx), + test_eth_blockNumber(&ctx), + test_eth_getBalance(&ctx, &contract), + test_eth_getCode(&ctx, &contract), + test_eth_call(&contract), + test_eth_estimateGas(&ctx, &contract), + test_eth_getBlockByHash(&ctx, &contract), + test_eth_getBlockByNumber(&ctx, &contract), + test_eth_getTransactionByHash(&ctx, &contract), + test_eth_getTransactionReceipt(&ctx, &contract), + ); + ctx + }) + .await; +} + +async fn test_eth_chainId(ctx: &SignetTestContext) { + let chain_id = ctx.alloy_provider.get_chain_id().await.unwrap(); + assert_eq!(chain_id, TEST_CONSTANTS.ru_chain_id()); +} + +async fn test_eth_gasPrice(ctx: &SignetTestContext) { + let gas_price = ctx.alloy_provider.get_gas_price().await.unwrap(); + assert_eq!(gas_price, 1_875_000_000); +} + +async fn test_eth_blockNumber(ctx: &SignetTestContext) { + let (block_number, block) = try_join!( + ctx.alloy_provider.get_block_number(), + ctx.alloy_provider.get_block_by_number(BlockNumberOrTag::Latest) + ) + .unwrap(); + + let block = block.unwrap(); + assert_eq!(block_number, 1); + assert_eq!(block.header.number, block_number); +} + +async fn test_eth_getBalance(ctx: &SignetTestContext, contract: &TestCounterInstance) { + let balance = ctx.alloy_provider.get_balance(*contract.address()).await.unwrap(); + assert_eq!(balance, U256::ZERO); + + for address in ctx.addresses.iter() { + let actual = ctx.alloy_provider.get_balance(*address).await.unwrap(); + let expected = ctx.balance_of(*address); + assert_eq!(actual, expected); + } +} + +async fn test_eth_getCode(ctx: &SignetTestContext, contract: &TestCounterInstance) { + assert_eq!( + ctx.alloy_provider.get_code_at(*contract.address()).await.unwrap(), + COUNTER_BYTECODE + ); +} + +async fn test_eth_call(contract: &TestCounterInstance) { + let result = contract.count().call().await.unwrap(); + assert_eq!(result, U256::ZERO); +} + +async fn test_eth_estimateGas(ctx: &SignetTestContext, contract: &TestCounterInstance) { + let deployer = ctx.addresses[0]; + let tx = contract.increment().from(deployer).into_transaction_request(); + let gas = ctx.alloy_provider.estimate_gas(tx).await.unwrap(); + assert!(gas > 40_000); +} + +async fn test_eth_getBlockByHash(ctx: &SignetTestContext, _contract: &TestCounterInstance) { + let genesis = ctx.factory.block(0.into()).unwrap().unwrap(); + + let block = ctx.alloy_provider.get_block_by_hash(genesis.hash_slow()).await.unwrap().unwrap(); + assert_eq!(block.header.number, genesis.number); + assert_eq!(block.header.timestamp, genesis.timestamp); +} + +async fn test_eth_getBlockByNumber(ctx: &SignetTestContext, _contract: &TestCounterInstance) { + let db_block = ctx.factory.block(1.into()).unwrap().unwrap(); + + let rpc_block = + ctx.alloy_provider.get_block_by_number(db_block.number.into()).await.unwrap().unwrap(); + assert_eq!(rpc_block.header.number, db_block.number); + assert_eq!(rpc_block.header.timestamp, db_block.timestamp); + assert_eq!(rpc_block.header.hash, db_block.hash_slow()); +} + +async fn test_eth_getTransactionByHash(ctx: &SignetTestContext, _contract: &TestCounterInstance) { + let deployer = ctx.addresses[0]; + + let deploy_tx = &ctx.factory.transactions_by_block(1.into()).unwrap().unwrap()[0]; + let tx_hash = *deploy_tx.hash(); + + let rpc_tx = ctx.alloy_provider.get_transaction_by_hash(tx_hash).await.unwrap().unwrap(); + assert_eq!(rpc_tx.tx_hash(), tx_hash); + assert_eq!(rpc_tx.from(), deployer); + assert_eq!(rpc_tx.to(), None); + assert_eq!(rpc_tx.value(), U256::ZERO); + assert_eq!(rpc_tx.input(), &COUNTER_DEPLOY_CODE); + assert_eq!(rpc_tx.block_number, Some(1)); + assert_eq!(rpc_tx.transaction_index, Some(0)); +} + +async fn test_eth_getTransactionReceipt(ctx: &SignetTestContext, contract: &TestCounterInstance) { + let deployer = ctx.addresses[0]; + + let deploy_tx = &ctx.factory.transactions_by_block(1.into()).unwrap().unwrap()[0]; + let tx_hash = *deploy_tx.hash(); + + let receipt = ctx.alloy_provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap(); + + assert_eq!(receipt.transaction_hash, tx_hash); + assert_eq!(receipt.transaction_index.unwrap(), 0); + assert_eq!(receipt.block_number.unwrap(), 1); + assert_eq!(receipt.from, deployer); + assert_eq!(receipt.to, None); + assert_eq!(receipt.contract_address, Some(*contract.address())); + assert!(receipt.status()); +} + +// --- TESTS BELOW HERE RUN A TX --- +// These tests are split into pre-state assertions and post-state assertions. + +#[serial] +#[tokio::test] +// tests +// - eth_getStorageAt +// - eth_getTransactionCount +// - eth_newBlockFilter +// - eth_getFilterChanges +// - eth_newFilter +// - eth_getLogs +async fn test_stateful_rpc_calls() { + rpc_test(|ctx, contract| async move { + let deployer = ctx.addresses[0]; + + let (_, _, nonce, block_filter, event_filter) = tokio::join!( + withBlock_pre(&ctx, &contract), + getStorageAt_pre(&ctx, &contract), + getTransactionCount_pre(&ctx, deployer), + newBlockFilter_pre(&ctx), + newFilter_pre(&ctx, &contract), + ); + + let latest_block = ctx.alloy_provider.get_block_number().await.unwrap(); + tracing::info!(latest_block, "latest block"); + + let tx = contract.increment().from(deployer).into_transaction_request(); + let _ = ctx.process_alloy_tx(&tx).await.unwrap(); + + tokio::join!( + withBlock_post(&ctx, &contract), + getStorageAt_post(&ctx, &contract), + getTransactionCount_post(&ctx, deployer, nonce), + newBlockFilter_post(&ctx, block_filter), + newFilter_post(&ctx, &contract, event_filter), + getLogs_post(&ctx, &contract), + ); + + ctx + }) + .await; +} + +async fn getLogs_post(ctx: &SignetTestContext, contract: &TestCounterInstance) { + let latest_block = ctx.factory.last_block_number().unwrap(); + let latest_hash = ctx.factory.block(latest_block.into()).unwrap().unwrap().hash_slow(); + + let logs = ctx + .alloy_provider + .get_logs(&Filter { + block_option: FilterBlockOption::AtBlockHash(latest_hash), + address: (*contract.address()).into(), + topics: Default::default(), + }) + .await + .unwrap(); + + assert_eq!(logs.len(), 1); + let log_inner = &logs[0].inner; + assert_eq!(log_inner.address, *contract.address()); + assert_eq!(log_inner.topics(), &[Counter::Count::SIGNATURE_HASH, B256::with_last_byte(1)]); +} + +async fn newFilter_pre(ctx: &SignetTestContext, contract: &TestCounterInstance) -> U256 { + ctx.alloy_provider + .new_filter(&Filter { + block_option: Default::default(), + address: (*contract.address()).into(), + topics: Default::default(), + }) + .await + .unwrap() +} + +async fn newFilter_post(ctx: &SignetTestContext, contract: &TestCounterInstance, filter_id: U256) { + let logs: Vec> = ctx.alloy_provider.get_filter_changes(filter_id).await.unwrap(); + assert_eq!(logs.len(), 1); + let log_inner = &logs[0].inner; + assert_eq!(log_inner.address, *contract.address()); + assert_eq!(log_inner.topics(), &[Counter::Count::SIGNATURE_HASH, B256::with_last_byte(1)]); + assert_eq!(log_inner.data.data, Bytes::new()); +} + +async fn newBlockFilter_pre(ctx: &SignetTestContext) -> U256 { + ctx.alloy_provider.new_block_filter().await.unwrap() +} + +async fn newBlockFilter_post(ctx: &SignetTestContext, filter_id: U256) { + let blocks: Vec = ctx.alloy_provider.get_filter_changes(filter_id).await.unwrap(); + let latest_block = ctx.factory.last_block_number().unwrap(); + let latest_hash = ctx.factory.block(latest_block.into()).unwrap().unwrap().hash_slow(); + + tracing::info!(latest_block, "huh"); + + assert_eq!(blocks.len(), 1); + assert_eq!(blocks[0], latest_hash); +} + +async fn getTransactionCount_pre(ctx: &SignetTestContext, deployer: Address) -> u64 { + // rpc returns correct nonce + let nonce = ctx.nonce(deployer); + assert_eq!(ctx.alloy_provider.get_transaction_count(deployer).await.unwrap(), nonce); + nonce +} + +async fn getTransactionCount_post(ctx: &SignetTestContext, deployer: Address, nonce: u64) { + // nonce increased + assert_eq!(ctx.alloy_provider.get_transaction_count(deployer).await.unwrap(), nonce + 1); +} + +async fn getStorageAt_pre(ctx: &SignetTestContext, contract: &TestCounterInstance) { + // rpc returns correct storage + assert_eq!( + ctx.alloy_provider.get_storage_at(*contract.address(), U256::ZERO).await.unwrap(), + U256::ZERO + ); +} + +async fn getStorageAt_post(ctx: &SignetTestContext, contract: &TestCounterInstance) { + // storage updated + assert_eq!( + ctx.alloy_provider.get_storage_at(*contract.address(), U256::ZERO).await.unwrap(), + U256::from(1) + ); +} + +async fn withBlock_pre(ctx: &SignetTestContext, contract: &TestCounterInstance) { + // We should be at block 1 + assert_eq!(ctx.alloy_provider.get_block_number().await.unwrap(), 1); + + // Get the block hashes for block 0 and block 1 + let bh_0 = ctx.alloy_provider.get_block_by_number(0.into()).await.unwrap().unwrap().hash(); + let bh_1 = ctx.alloy_provider.get_block_by_number(1.into()).await.unwrap().unwrap().hash(); + + // Code at block 0, should be empty + assert!( + ctx.alloy_provider + .get_code_at(*contract.address()) + .block_id(0.into()) + .await + .unwrap() + .is_empty() + ); + assert!( + ctx.alloy_provider + .get_code_at(*contract.address()) + .block_id(bh_0.into()) + .await + .unwrap() + .is_empty() + ); + + // Code at block 1, should be the counter bytecode + assert_eq!( + ctx.alloy_provider.get_code_at(*contract.address()).await.unwrap(), + COUNTER_BYTECODE + ); + assert_eq!( + ctx.alloy_provider.get_code_at(*contract.address()).block_id(1.into()).await.unwrap(), + COUNTER_BYTECODE + ); + assert_eq!( + ctx.alloy_provider.get_code_at(*contract.address()).block_id(bh_1.into()).await.unwrap(), + COUNTER_BYTECODE + ); + + // The call at block 0 should fail + assert!(matches!( + contract.count().call().block(0.into()).await.unwrap_err(), + alloy::contract::Error::ZeroData(_, _,) + )); + assert!(matches!( + contract.count().call().block(bh_0.into()).await.unwrap_err(), + alloy::contract::Error::ZeroData(_, _,) + )); + + // The call at block 1 should return 0 + assert_eq!(contract.count().call().await.unwrap(), U256::ZERO); + assert_eq!(contract.count().call().block(1.into()).await.unwrap(), U256::ZERO); + assert_eq!(contract.count().call().block(bh_1.into()).await.unwrap(), U256::ZERO); +} + +async fn withBlock_post(ctx: &SignetTestContext, contract: &TestCounterInstance) { + // After the increment, we should be at block 2 + assert_eq!(ctx.alloy_provider.get_block_number().await.unwrap(), 2); + + // Get the block hashes for blocks 0..=2 + let bh_0 = ctx.alloy_provider.get_block_by_number(0.into()).await.unwrap().unwrap().hash(); + let bh_1 = ctx.alloy_provider.get_block_by_number(1.into()).await.unwrap().unwrap().hash(); + let bh_2 = ctx.alloy_provider.get_block_by_number(2.into()).await.unwrap().unwrap().hash(); + + // Code at block 0, should be empty + assert!( + ctx.alloy_provider + .get_code_at(*contract.address()) + .block_id(0.into()) + .await + .unwrap() + .is_empty() + ); + assert!( + ctx.alloy_provider + .get_code_at(*contract.address()) + .block_id(bh_0.into()) + .await + .unwrap() + .is_empty() + ); + + // Code at block 1, should be the counter bytecode + assert_eq!( + ctx.alloy_provider.get_code_at(*contract.address()).block_id(1.into()).await.unwrap(), + COUNTER_BYTECODE + ); + assert_eq!( + ctx.alloy_provider.get_code_at(*contract.address()).block_id(bh_1.into()).await.unwrap(), + COUNTER_BYTECODE + ); + + // Code at block 2, should be the counter bytecode + assert_eq!( + ctx.alloy_provider.get_code_at(*contract.address()).await.unwrap(), + COUNTER_BYTECODE + ); + assert_eq!( + ctx.alloy_provider.get_code_at(*contract.address()).block_id(2.into()).await.unwrap(), + COUNTER_BYTECODE + ); + assert_eq!( + ctx.alloy_provider.get_code_at(*contract.address()).block_id(bh_2.into()).await.unwrap(), + COUNTER_BYTECODE + ); + + // The call at block 0 should fail + assert!(matches!( + contract.count().call().block(0.into()).await.unwrap_err(), + alloy::contract::Error::ZeroData(_, _,) + )); + assert!(matches!( + contract.count().call().block(bh_0.into()).await.unwrap_err(), + alloy::contract::Error::ZeroData(_, _,) + )); + + // The call at block 1 should return 0 + assert_eq!(contract.count().call().block(1.into()).await.unwrap(), U256::ZERO); + assert_eq!(contract.count().call().block(bh_1.into()).await.unwrap(), U256::ZERO); + + // The call at block 2 should return 1 + assert_eq!(contract.count().call().await.unwrap(), U256::from(1)); + assert_eq!(contract.count().call().block(2.into()).await.unwrap(), U256::from(1)); + assert_eq!(contract.count().call().block(bh_2.into()).await.unwrap(), U256::from(1)); +} + +#[ignore = "This test is slow and should not run by default"] +#[serial] +#[tokio::test] +async fn test_withBlock_many_blocks() { + rpc_test(|ctx, contract| async move { + let deployer = ctx.addresses[0]; + + // Process 100 transactions + for i in 0..300 { + let tx = contract.increment().from(deployer).into_transaction_request(); + let _ = ctx.process_alloy_tx(&tx).await.unwrap(); + if i % 10 == 0 { + tracing::info!("Processed {} transactions", i); + } + } + + // We should have 10 blocks + let block_no = ctx.alloy_provider.get_block_number().await.unwrap(); + assert!(block_no >= 300); + + // Make an eth_call at latest + let counter = contract.count().call().await.unwrap(); + assert_eq!(counter, U256::from(300)); + + for i in 1..=300 { + let block_no = block_no - i; + let counter = contract.count().call().block(block_no.into()).await.unwrap(); + assert_eq!(counter, U256::from(300 - i)); + if i % 10 == 0 { + tracing::info!("Reverse {} transactions", i); + } + } + + ctx + }) + .await; +} + +// -- TESTS BELOW HERE TEST THE PUBSUB API -- + +#[serial] +#[tokio::test] +async fn test_rpc_pubsub() { + rpc_test(|ctx, contract| async move { + let deployer = ctx.addresses[0]; + + let (block_sub, event_sub) = + tokio::join!(subscribe_blocks_pre(&ctx), subscribe_logs_pre(&ctx, &contract),); + + let tx = contract.increment().from(deployer).into_transaction_request(); + let _ = ctx.process_alloy_tx(&tx).await.unwrap(); + + tokio::join!( + subscribe_blocks_post(&ctx, block_sub), + subscribe_logs_post(&contract, event_sub), + ); + + ctx + }) + .await; +} + +async fn subscribe_blocks_pre(ctx: &SignetTestContext) -> Subscription
{ + ctx.alloy_provider.subscribe_blocks().await.unwrap() +} + +async fn subscribe_blocks_post(ctx: &SignetTestContext, mut sub: Subscription
) { + let block = sub.recv().await.unwrap(); + + let latest_block = ctx.factory.last_block_number().unwrap(); + let latest_hash = ctx.factory.block(latest_block.into()).unwrap().unwrap().hash_slow(); + assert_eq!(block.number, latest_block); + assert_eq!(block.hash, latest_hash); +} + +async fn subscribe_logs_pre( + ctx: &SignetTestContext, + contract: &TestCounterInstance, +) -> Subscription { + ctx.alloy_provider + .subscribe_logs(&Filter { + block_option: Default::default(), + address: (*contract.address()).into(), + topics: Default::default(), + }) + .await + .unwrap() +} + +async fn subscribe_logs_post(contract: &TestCounterInstance, mut sub: Subscription) { + let log = sub.recv().await.unwrap(); + let log_inner = log.inner; + assert_eq!(log_inner.address, *contract.address()); + assert_eq!(log_inner.topics(), &[Counter::Count::SIGNATURE_HASH, B256::with_last_byte(1)]); + assert_eq!(log_inner.data.data, Bytes::new()); +} + +// -- THIS IS TO TEST FILTER EDGES ACROSS A RANGE OF BLOCKS -- +#[serial] +#[tokio::test] +async fn test_rpc_filter_edge_cases() { + rpc_test(|ctx, contract| async move { + let deployer = ctx.addresses[0]; + + let (block_filter, event_filter) = + tokio::join!(newBlockFilter_pre(&ctx), newFilter_pre(&ctx, &contract)); + + let tx = contract.increment().from(deployer).into_transaction_request(); + let _ = ctx.process_alloy_tx(&tx).await.unwrap(); + + // After this, each filter should have 1 item + let (blocks, logs) = tokio::try_join!( + ctx.alloy_provider.get_filter_changes::(block_filter), + ctx.alloy_provider.get_filter_changes::>(event_filter), + ) + .unwrap(); + + assert_eq!(blocks.len(), 1); + assert_eq!(logs.len(), 1); + // the counter in the event should be 1 + assert_eq!(logs[0].inner.topics()[1], B256::with_last_byte(1)); + + // Process 2 more transactions + let _ = ctx.process_alloy_tx(&tx).await.unwrap(); + let _ = ctx.process_alloy_tx(&tx).await.unwrap(); + + // After this, each filter should have 2 items + let (blocks, logs) = tokio::try_join!( + ctx.alloy_provider.get_filter_changes::(block_filter), + ctx.alloy_provider.get_filter_changes::>(event_filter), + ) + .unwrap(); + + assert_eq!(blocks.len(), 2); + assert_eq!(logs.len(), 2); + // the counters in the events should be 2 and 3 + assert_eq!(logs[0].inner.topics()[1], B256::with_last_byte(2)); + assert_eq!(logs[1].inner.topics()[1], B256::with_last_byte(3)); + + // Poll again + let (blocks, logs) = tokio::try_join!( + ctx.alloy_provider.get_filter_changes::(block_filter), + ctx.alloy_provider.get_filter_changes::>(event_filter), + ) + .unwrap(); + + // Now they should be empty + assert_eq!(blocks.len(), 0); + assert_eq!(logs.len(), 0); + + ctx + }) + .await; +} diff --git a/crates/node-tests/tests/rpc_debug.rs b/crates/node-tests/tests/rpc_debug.rs new file mode 100644 index 0000000..437ce0e --- /dev/null +++ b/crates/node-tests/tests/rpc_debug.rs @@ -0,0 +1,78 @@ +use alloy::{primitives::Bytes, providers::ext::DebugApi, sol_types::SolCall}; +use reth::{ + providers::TransactionsProvider, + rpc::types::trace::geth::{CallConfig, GethDebugTracingOptions}, +}; +use serial_test::serial; +use signet_node_tests::{aliases::Counter::incrementCall, rpc::rpc_test}; +use signet_test_utils::specs::{HostBlockSpec, RuBlockSpec}; + +#[serial] +#[tokio::test] +async fn test_debug_trace_transaction() { + rpc_test(|ctx, counter| async move { + let deployer = ctx.addresses[0]; + let deploy_tx = &ctx.factory.transactions_by_block(1.into()).unwrap().unwrap()[0]; + let tx_hash = *deploy_tx.hash(); + + let tracing_opts = GethDebugTracingOptions::call_tracer(CallConfig { + only_top_call: Some(false), + with_log: Some(true), + }); + + let trace = ctx + .alloy_provider + .debug_trace_transaction(tx_hash, tracing_opts) + .await + .expect("debug_traceTransaction failed") + .try_into_call_frame() + .unwrap(); + + assert_eq!(trace.typ, "CREATE"); + assert_eq!(trace.from, deployer); + assert_eq!(trace.to, Some(*counter.address())); + + ctx + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_debug_trace_block() { + rpc_test(|ctx, counter| async move { + let mut spec = RuBlockSpec::new(ctx.constants()); + + // We want 10 transactions in this block + for i in 0..10 { + let tx = counter.increment().into_transaction_request().from(ctx.addresses[i]); + + spec = spec.alloy_tx(&ctx.fill_alloy_tx(&tx).await.unwrap()); + } + + ctx.process_block(HostBlockSpec::new(ctx.constants()).submit_block(spec)).await.unwrap(); + + let tracing_opts = GethDebugTracingOptions::call_tracer(CallConfig { + only_top_call: Some(false), + with_log: Some(true), + }); + + let traces = ctx + .alloy_provider + .debug_trace_block_by_number(2.into(), tracing_opts) + .await + .expect("debug_traceBlock failed"); + + assert_eq!(traces.len(), 10); + + for trace in traces { + let trace = trace.success().unwrap().clone().try_into_call_frame().unwrap(); + assert_eq!(trace.typ, "CALL"); + assert_eq!(trace.to, Some(*counter.address())); + assert_eq!(trace.input, Bytes::from_static(&incrementCall::SELECTOR)); + } + + ctx + }) + .await; +} diff --git a/crates/node-tests/tests/submit-tx.rs b/crates/node-tests/tests/submit-tx.rs new file mode 100644 index 0000000..d8b3467 --- /dev/null +++ b/crates/node-tests/tests/submit-tx.rs @@ -0,0 +1,82 @@ +use alloy::{ + consensus::constants::GWEI_TO_WEI, + network::TransactionBuilder, + primitives::{Address, U256}, + providers::Provider, + rpc::types::eth::TransactionRequest, +}; +use serial_test::serial; +use signet_node_tests::{ + HostBlockSpec, RuBlockSpec, aliases::TestCounterInstance, utils::run_test, +}; +use signet_test_utils::contracts::counter::{COUNTER_BYTECODE, COUNTER_DEPLOY_CODE}; + +const USER_A: Address = Address::repeat_byte(0x39); + +#[serial] +#[tokio::test] +async fn test_submit_tx() { + let amnt = U256::from(100000); + + run_test(|ctx| async move { + let mut user_a_bal = ctx.track_balance(USER_A, Some("user")); + + let tx = TransactionRequest::default() + .from(ctx.addresses[0]) + .max_priority_fee_per_gas(GWEI_TO_WEI.into()) + .max_fee_per_gas(GWEI_TO_WEI.into()) + .gas_limit(21_000) + .to(USER_A) + .value(amnt); + + // Sign the transaction + let tx = ctx.fill_alloy_tx(&tx).await.unwrap(); + + let ru_block = RuBlockSpec::new(ctx.constants()).alloy_tx(&tx); + + let host_block = HostBlockSpec::new(ctx.constants()).submit_block(ru_block); + + ctx.process_block(host_block).await.unwrap(); + user_a_bal.assert_increase_exact(amnt); + }) + .await; +} + +#[serial] +#[tokio::test] +async fn test_deploy_contract() { + run_test(|ctx| async move { + let deployer = ctx.addresses[0]; + let mut deployer_bal = ctx.track_balance(deployer, Some("deployer")); + + let tx = TransactionRequest::default() + .to(Address::ZERO) + .from(deployer) + .max_priority_fee_per_gas(GWEI_TO_WEI.into()) + .max_fee_per_gas(GWEI_TO_WEI.into()) + .gas_limit(21_000_000) + .with_deploy_code(COUNTER_DEPLOY_CODE); + + let (tx, receipt) = ctx.process_alloy_tx(&tx).await.unwrap(); + deployer_bal.assert_decrease_exact(U256::from( + receipt.gas_used as u128 * receipt.effective_gas_price, + )); + + // calculate contract address and assert it exists + let nonce = tx.as_eip1559().unwrap().tx().nonce; + let contract_addr = deployer.create(nonce); + + assert_eq!(ctx.alloy_provider.get_code_at(contract_addr).await.unwrap(), COUNTER_BYTECODE,); + + let contract = TestCounterInstance::new(contract_addr, ctx.alloy_provider.clone()); + + assert_eq!(contract.count().call().await.unwrap(), U256::ZERO); + + // Now we increment it and assert the count changed + let tx = contract.increment().from(deployer).into_transaction_request(); + let _ = ctx.process_alloy_tx(&tx).await.unwrap(); + + assert_eq!(contract.count().call().await.unwrap(), U256::from(1)); + }) + .await; +} diff --git a/crates/node-types/Cargo.toml b/crates/node-types/Cargo.toml index 80a65f2..6db0b39 100644 --- a/crates/node-types/Cargo.toml +++ b/crates/node-types/Cargo.toml @@ -9,10 +9,13 @@ homepage.workspace = true repository.workspace = true [dependencies] +alloy.workspace = true reth.workspace = true reth-chainspec.workspace = true reth-db.workspace = true reth-node-api.workspace = true reth-node-ethereum.workspace = true +signet-zenith.workspace = true -tokio.workspace = true \ No newline at end of file +tokio.workspace = true +tracing.workspace = true diff --git a/crates/node-types/src/block.rs b/crates/node-types/src/block.rs new file mode 100644 index 0000000..29d4463 --- /dev/null +++ b/crates/node-types/src/block.rs @@ -0,0 +1,26 @@ +use alloy::eips::eip2718::{Decodable2718, Encodable2718}; +use reth::primitives::TransactionSigned; +use signet_zenith::Coder; +use tracing::trace; + +/// [signet_zenith::ZenithBlock] parameterized for use with reth. +pub type ZenithBlock = signet_zenith::ZenithBlock; + +/// [Coder] implementation for reth's 2718 impl +#[derive(Debug, Clone, Copy)] +pub struct Reth2718Coder; + +impl Coder for Reth2718Coder { + type Tx = TransactionSigned; + + fn encode(t: &TransactionSigned) -> Vec { + t.encoded_2718() + } + + fn decode(buf: &mut &[u8]) -> Option { + TransactionSigned::decode_2718(buf) + .inspect_err(|e| trace!(%e, "Discarding transaction due to failed decoding")) + .ok() + .filter(|tx| !tx.is_eip4844()) + } +} diff --git a/crates/node-types/src/lib.rs b/crates/node-types/src/lib.rs index 43a28a4..ba49628 100644 --- a/crates/node-types/src/lib.rs +++ b/crates/node-types/src/lib.rs @@ -11,6 +11,9 @@ #![deny(unused_must_use, rust_2018_idioms)] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +mod block; +pub use block::{Reth2718Coder, ZenithBlock}; + mod utils; pub use utils::{NodeTypesDbTrait, Pnt}; diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml new file mode 100644 index 0000000..aa5c404 --- /dev/null +++ b/crates/node/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "signet-node" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +alloy.workspace = true +eyre.workspace = true +futures-util = "0.3.31" +reqwest.workspace = true +reth.workspace = true +reth-chainspec.workspace = true +reth-db.workspace = true +reth-db-common.workspace = true +reth-exex.workspace = true +reth-node-api.workspace = true +signet-blobber.workspace = true +signet-block-processor.workspace = true +signet-db.workspace = true +signet-node-config.workspace = true +signet-node-types.workspace = true +signet-rpc.workspace = true +signet-tx-cache.workspace = true +signet-types.workspace = true +tokio.workspace = true +tracing.workspace = true diff --git a/crates/node/README.md b/crates/node/README.md new file mode 100644 index 0000000..8b82168 --- /dev/null +++ b/crates/node/README.md @@ -0,0 +1,8 @@ +# Signet Node + +The core `SignetNode` struct. This is the exex listener that handles incoming +notifications, and manages the lifecycle of the rest of the node components. + +This library contains the following: + +- `SignetNode` - The main node struct, which manages the lifecycle of the node. \ No newline at end of file diff --git a/crates/node/src/lib.rs b/crates/node/src/lib.rs new file mode 100644 index 0000000..8504b57 --- /dev/null +++ b/crates/node/src/lib.rs @@ -0,0 +1,17 @@ +#![doc = include_str!("../README.md")] +#![warn( + missing_copy_implementations, + missing_debug_implementations, + missing_docs, + unreachable_pub, + clippy::missing_const_for_fn, + rustdoc::all +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![deny(unused_must_use, rust_2018_idioms)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +mod node; +pub use node::{GENESIS_JOURNAL_HASH, SignetNode}; + +mod rpc; diff --git a/crates/node/src/node.rs b/crates/node/src/node.rs new file mode 100644 index 0000000..a1730e0 --- /dev/null +++ b/crates/node/src/node.rs @@ -0,0 +1,663 @@ +use alloy::{ + consensus::BlockHeader, + eips::NumHash, + primitives::{B256, b256}, +}; +use eyre::Context; +use futures_util::StreamExt; +use reth::{ + primitives::EthPrimitives, + providers::{ + BlockHashReader, BlockIdReader, BlockNumReader, BlockReader, CanonChainTracker, + CanonStateNotification, CanonStateNotifications, CanonStateSubscriptions, HeaderProvider, + NodePrimitivesProvider, ProviderFactory, providers::BlockchainProvider, + }, + rpc::types::engine::ForkchoiceState, +}; +use reth_chainspec::EthChainSpec; +use reth_db::transaction::DbTxMut; +use reth_db_common::init; +use reth_exex::{ExExContext, ExExEvent, ExExHead, ExExNotificationsStream}; +use reth_node_api::{FullNodeComponents, FullNodeTypes, NodeTypes}; +use signet_blobber::BlobFetcher; +use signet_block_processor::SignetBlockProcessorV1; +use signet_db::{DbProviderExt, RuChain, RuWriter}; +use signet_node_config::SignetNodeConfig; +use signet_node_types::{NodeStatus, NodeTypesDbTrait, SignetNodeTypes}; +use signet_rpc::RpcServerGuard; +use signet_types::{PairedHeights, constants::SignetSystemConstants}; +use std::{fmt, sync::Arc}; +use tokio::sync::watch; +use tracing::{debug, info, instrument}; + +/// The genesis journal hash for the signet chain. +pub const GENESIS_JOURNAL_HASH: B256 = + b256!("0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + +/// Make it easier to write some args +type PrimitivesOf = <::Types as NodeTypes>::Primitives; +type ExExNotification = reth_exex::ExExNotification>; +type Chain = reth::providers::Chain>; + +/// Signet context and configuration. +pub struct SignetNode +where + Host: FullNodeComponents, + Host::Types: NodeTypes, + Db: NodeTypesDbTrait, +{ + /// The host context, which manages provider access and notifications. + pub(crate) host: ExExContext, + + /// Signet node configuration. + pub(crate) config: Arc, + + /// A [`ProviderFactory`] instance to allow RU database access. + pub(crate) ru_provider: ProviderFactory>, + + /// A [`BlockchainProvider`] instance. Used to notify the RPC server of + /// changes to the canonical/safe/finalized head. + pub(crate) bp: BlockchainProvider>, + + /// The join handle for the RPC server. None if the RPC server is not + /// yet running. + pub(crate) rpc_handle: Option, + + /// Chain configuration constants. + pub(crate) constants: SignetSystemConstants, + + /// Status channel, currently used only for testing + pub(crate) status: watch::Sender, + + /// The block processor + pub(crate) processor: SignetBlockProcessorV1, + + /// A reqwest client, used by the blob fetch and the tx cache forwarder. + pub(crate) client: reqwest::Client, +} + +impl fmt::Debug for SignetNode +where + Host: FullNodeComponents, + Host::Types: NodeTypes, + Db: NodeTypesDbTrait, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SignetNode").field("config", &self.config).finish_non_exhaustive() + } +} + +impl NodePrimitivesProvider for SignetNode +where + Host: FullNodeComponents, + Host::Types: NodeTypes, + Db: NodeTypesDbTrait, +{ + type Primitives = EthPrimitives; +} + +impl CanonStateSubscriptions for SignetNode +where + Host: FullNodeComponents, + Host::Types: NodeTypes, + Db: NodeTypesDbTrait, +{ + fn subscribe_to_canonical_state(&self) -> CanonStateNotifications { + self.bp.subscribe_to_canonical_state() + } +} + +impl SignetNode +where + Host: FullNodeComponents, + Host::Types: NodeTypes, + Db: NodeTypesDbTrait, +{ + /// Create a new Signet instance. + /// + /// # Panics + /// + /// If invoked outside a tokio runtime. + pub fn new( + ctx: ExExContext, + config: SignetNodeConfig, + factory: ProviderFactory>, + client: reqwest::Client, + ) -> eyre::Result<(Self, tokio::sync::watch::Receiver)> { + let constants = + config.constants().wrap_err("failed to load signet constants from genesis")?; + + // This check appears redundant with the same check made in + // `init_genesis`, but is not. We init the genesis DB state but then we + // drop some of it, and reuse those tables for our own nefarious + // purposes. If we attempt to drop those tables AFTER we have reused + // them, we will get a key deser error (as the tables will contain keys + // the old schema does not permit). This check ensures we only attempt + // to drop the tables once. + if matches!( + factory.block_hash(0), + Ok(None) + | Err(reth::providers::ProviderError::MissingStaticFileBlock( + reth::primitives::StaticFileSegment::Headers, + 0 + )) + ) { + init::init_genesis(&factory)?; + + factory.provider_rw()?.update( + |writer: &mut reth::providers::DatabaseProviderRW>| { + writer.tx_mut().clear::()?; + writer.tx_mut().clear::()?; + writer.tx_mut().clear::()?; + + writer.tx_ref().put::(0, GENESIS_JOURNAL_HASH)?; + // we do not need to pre-populate the `ZenithHeaders` or + // `SignetEvents` tables, as missing data is legal in those + // tables + + Ok(()) + }, + )?; + } + + let bp: BlockchainProvider> = BlockchainProvider::new(factory.clone())?; + + let (status, receiver) = tokio::sync::watch::channel(NodeStatus::Booting); + + let blob_cacher = BlobFetcher::builder() + .with_config(config.block_extractor())? + .with_pool(ctx.pool().clone()) + .with_client(client.clone()) + .build_cache() + .wrap_err("failed to create blob cacher")? + .spawn(); + + let processor = SignetBlockProcessorV1::new( + constants.clone(), + config.chain_spec().clone(), + factory.clone(), + config.slot_calculator(), + blob_cacher, + ); + + let this = Self { + config: config.into(), + host: ctx, + ru_provider: factory.clone(), + bp, + + rpc_handle: None, + constants, + status, + + processor, + + client, + }; + Ok((this, receiver)) + } + + /// Start the Signet instance, listening for ExEx notifications. Trace any + /// errors. + #[instrument(skip(self), fields(host = ?self.host.config.chain.chain()))] + pub async fn start(mut self) -> eyre::Result<()> { + // This exists only to bypass the `tracing::instrument(err)` macro to + // ensure that full sources get reported. + self.start_inner().await.inspect_err(|err| { + // using `:#` invokes the alternate formatter, which for eyre + // includes cause reporting. + let err = format!("{err:#}"); + + let last_block = self.ru_provider.last_block_number().ok(); + let exex_head = last_block.and_then(|h| self.set_exex_head(h).ok()); + + tracing::error!(err, last_block, ?exex_head, "Signet node crashed"); + }) + } + + /// Start the Signet instance, listening for ExEx notifications. + async fn start_inner(&mut self) -> eyre::Result<()> { + debug!(constants = ?self.constants, "signet starting"); + + self.start_rpc().await?; + + // Determine the last block written to the database for backfill + let last_rollup_block: u64 = self.ru_provider.last_block_number()?; + + info!(last_rollup_block, "resuming execution from last rollup block found"); + + // Update the node status channel with last block height + self.status.send_modify(|s| *s = NodeStatus::AtHeight(last_rollup_block)); + + // Sets the ExEx head position relative to that last block + let exex_head = self.set_exex_head(last_rollup_block)?; + info!( + host_head = exex_head.block.number, + host_hash = %exex_head.block.hash, + rollup_head_height = last_rollup_block, + "signet listening for notifications" + ); + + // Handle incoming ExEx notifications + while let Some(notification) = self.host.notifications.next().await { + let notification = notification.wrap_err("error in reth host notifications stream")?; + self.on_notification(notification) + .await + .wrap_err("error while processing notification")?; + } + + info!("signet shutting down"); + Ok(()) + } + + /// Sets the head of the Exex chain from the last rollup block, handling genesis conditions if necessary. + fn set_exex_head(&mut self, last_rollup_block: u64) -> eyre::Result { + // If the last rollup block is 0, we can shortcut and just set the head to the host rollup deployment block. + if last_rollup_block == 0 { + let host_deployment_block = + self.host.provider().block_by_number(self.constants.host_deploy_height())?; + match host_deployment_block { + Some(genesis_block) => { + let exex_head = ExExHead { block: genesis_block.num_hash_slow() }; + self.host.notifications.set_with_head(exex_head); + return Ok(exex_head); + } + None => { + let host_ru_deploy_block = self.constants.host_deploy_height(); + debug!( + host_ru_deploy_block, + "Host deploy height not found. Falling back to genesis block" + ); + let genesis_block = self.host.provider().block_by_number(0)?; + match genesis_block { + Some(genesis_block) => { + let exex_head = ExExHead { block: genesis_block.num_hash_slow() }; + self.host.notifications.set_with_head(exex_head); + return Ok(exex_head); + } + None => panic!("failed to find genesis block"), + } + } + } + } + + // If the last rollup block is not 0, we need to find the corresponding host block. + // We do this by looking up the host block number for the rollup block number, and then + // looking up the host block for that number. + let host_height = self.constants.pair_ru(last_rollup_block).host; + + match self.host.provider().block_by_number(host_height)? { + Some(host_block) => { + debug!(host_height, "found host block for height"); + let exex_head = ExExHead { block: host_block.num_hash_slow() }; + self.host.notifications.set_with_head(exex_head); + Ok(exex_head) + } + None => { + debug!(host_height, "no host block found for host height"); + let genesis_block = self.host.provider().block_by_number(0)?; + match genesis_block { + Some(genesis_block) => { + let exex_head = ExExHead { block: genesis_block.num_hash_slow() }; + self.host.notifications.set_with_head(exex_head); + Ok(exex_head) + } + None => panic!("failed to find genesis block"), + } + } + } + } + + /// Runs on any notification received from the ExEx context. + #[instrument(parent = None, skip_all, fields( + reverted = notification.reverted_chain().map(|c| c.len()).unwrap_or_default(), + committed = notification.committed_chain().map(|c| c.len()).unwrap_or_default(), + ))] + pub async fn on_notification(&self, notification: ExExNotification) -> eyre::Result<()> { + // NB: REVERTS MUST RUN FIRST + let mut reverted = None; + if let Some(chain) = notification.reverted_chain() { + reverted = + self.on_host_revert(&chain).await.wrap_err("error encountered during revert")?; + } + + let mut committed = None; + if let Some(chain) = notification.committed_chain() { + committed = self + .processor + .on_host_commit::(&chain) + .await + .wrap_err("error encountered during commit")?; + } + + if committed.is_some() || reverted.is_some() { + // Update the status channel and canon heights, etc. + self.update_status(committed, reverted)?; + } + + Ok(()) + } + + /// Update the status channel and the latest block info. This is necessary + /// to keep the RPC node in sync with the latest block information. + fn update_status( + &self, + committed: Option, + reverted: Option, + ) -> eyre::Result<()> { + let ru_height = self.ru_provider.last_block_number()?; + + // Update the RPC's block information + self.update_canon_heights(ru_height)?; + + // We'll also emit the new chains as notifications on our canonstate + // notification channel, provided anyone is listening + self.update_canon_state(committed, reverted); + + // Update the status channel. This is used by the test-utils to watch + // notification processing, and may be removed in the future. + self.status.send_modify(|s| *s = NodeStatus::AtHeight(ru_height)); + + Ok(()) + } + + /// Update the canonical heights of the chain. This does two main things + /// - Update the RPC server's view of the forkchoice rule, setting the + /// tip and block labels + /// - Update the reth node that the ExEx has finished processing blocks up + /// to the finalized block. + /// + /// This is used by the RPC to resolve block tags including "latest", + /// "safe", and "finalized", as well as the number returned by + /// `eth_blockNumber`. + fn update_canon_heights(&self, ru_height: u64) -> eyre::Result<()> { + // Set the canonical head ("latest" label) + let latest_ru_block_header = self + .ru_provider + .sealed_header(ru_height)? + .expect("ru db inconsistent. no header for height"); + let latest_ru_block_hash = latest_ru_block_header.hash(); + self.bp.set_canonical_head(latest_ru_block_header); + + // This is our fallback safe and finalized, in case the host chain + // hasn't finalized more recent blocks + let genesis_ru_hash = self + .ru_provider + .sealed_header(0)? + .expect("ru db inconsistent. no header for height") + .hash(); + + // Load the safe block hash for both the host and the rollup. + // The safe block height of the rollup CANNOT be higher than the latest ru height, + // as we've already processed all the blocks up to the latest ru height. + let PairedHeights { host: _, rollup: safe_ru_height } = + self.load_safe_block_heights(ru_height)?; + let safe_ru_block_header = self + .ru_provider + .sealed_header(safe_ru_height)? + .expect("ru db inconsistent. no header for height"); + let safe_ru_block_hash = safe_ru_block_header.hash(); + + debug!(safe_ru_height, "calculated safe ru height"); + + // Update the safe rollup block hash iff it's not the genesis rollup block. + if safe_ru_block_hash != genesis_ru_hash { + self.bp.set_safe(safe_ru_block_header); + } + + // Load the finalized rollup block hash. + // The finalized rollup block height CANNOT be higher than the latest ru height, + // as we've already processed all the blocks up to the latest ru height. + let finalized_heights = self.load_finalized_block_heights(ru_height)?; + + debug!( + finalized_host_height = finalized_heights.host, + finalized_ru_height = finalized_heights.rollup, + "calculated finalized heights" + ); + + // Load the finalized RU block hash. It's the genesis hash if the host + // and rollup finalized heights are both 0. Otherwise, we load the finalized + // RU header and set the finalized block hash. + let finalized_ru_block_hash = + self.set_finalized_ru_block_hash(finalized_heights, genesis_ru_hash)?; + + // NB: + // We also need to notify the reth node that we are totally + // finished processing the host block before the finalized block now. + // We want to keep the finalized host block in case we reorg to the block + // immediately on top of it, and we need some state from the parent. + // + // If this errors, it means that the reth node has shut down and we + // should stop processing blocks. + // + // To do this, we grab the finalized host header to get its height and hash, + // so we can send the corresponding [`ExExEvent`]. + if finalized_ru_block_hash != genesis_ru_hash { + self.update_highest_processed_height(finalized_heights.host)?; + } + + // Update the RPC's forkchoice timestamp. + self.bp.on_forkchoice_update_received(&ForkchoiceState { + head_block_hash: latest_ru_block_hash, + safe_block_hash: safe_ru_block_hash, + finalized_block_hash: finalized_ru_block_hash, + }); + debug!( + %latest_ru_block_hash, %safe_ru_block_hash, %finalized_ru_block_hash, + "updated RPC block producer" + ); + Ok(()) + } + + /// Update the ExEx head to the finalized host block. + /// + /// If this errors, it means that the reth node has shut down and we + /// should stop processing blocks. + fn update_exex_head( + &self, + finalized_host_height: u64, + finalized_host_hash: B256, + ) -> eyre::Result<()> { + debug!(finalized_host_height, "Sending FinishedHeight notification"); + self.host.events.send(ExExEvent::FinishedHeight(NumHash { + number: finalized_host_height, + hash: finalized_host_hash, + }))?; + Ok(()) + } + + /// Send a canon state notification via the channel. + fn update_canon_state(&self, committed: Option, reverted: Option) { + let commit_count = committed.as_ref().map(|c| c.len()).unwrap_or_default(); + let revert_count = reverted.as_ref().map(|r| r.len()).unwrap_or_default(); + + let notif = match (committed, reverted) { + (None, None) => None, + (None, Some(r)) => Some(CanonStateNotification::Reorg { + old: Arc::new(r.inner), + new: Arc::new(Default::default()), + }), + (Some(c), None) => Some(CanonStateNotification::Commit { new: Arc::new(c.inner) }), + (Some(c), Some(r)) => Some(CanonStateNotification::Reorg { + old: Arc::new(r.inner), + new: Arc::new(c.inner), + }), + }; + if let Some(notif) = notif { + tracing::debug!(commit_count, revert_count, "sending canon state notification"); + // we don't care if it fails, we just want to send it + self.bp.canonical_in_memory_state().notify_canon_state(notif); + } + } + + /// Load the host chain "safe" block number and determine the rollup "safe" + /// block number. There are three cases: + /// + /// 1. The host chain "safe" block number is below the rollup genesis. + /// In this case, we'll use the host genesis block number as the "safe" + /// block number. This can happen if the rollup starts syncing while the + /// host still hasn't seen the rollup genesis block. + /// 2. The host safe "block", when converted to the equivalent rollup block, + /// is beyond the current rollup block. In this case, we'll use the current + /// rollup block as safe block. This can happen if the host chain is + /// synced beyond the current rollup block, but the rollup is still syncing + /// and catching up with the host head and therefore hasn't seen the host + /// safe block. + /// 3. The host safe block number is below the current rollup block. In this + /// case, we can use the safe host block number, converted to its rollup + /// equivalent, as the safe rollup block number. This is the expected case + /// when the rollup and host are both caught up and in live sync. + fn load_safe_block_heights(&self, ru_height: u64) -> eyre::Result { + // Load the host safe block number + let safe_host_height = self.host.provider().safe_block_number()?; + + // Convert the host safe block number to the rollup safe block number. + // If the host safe block number is below the rollup genesis, + // this will return None. + let safe_heights = safe_host_height + .and_then(|safe_host_height| self.constants.pair_host(safe_host_height)); + + // If we successfully converted the host safe block number to the rollup safe block number, + // then we'll compare it to the current rollup block height and use the smaller of the two. + if let Some(safe_heights) = safe_heights { + // We compare the safe ru height to the current ru height. If the safe ru height is + // beyond the current ru height, we're in case 2. + if safe_heights.rollup > ru_height { + // We are in case 2. + Ok(PairedHeights { + host: self.constants.rollup_block_to_host_block_num(ru_height), + rollup: ru_height, + }) + } else { + // If the safe ru height is below the current ru height, we're in case 3. + Ok(safe_heights) + } + } else { + // If the host safe block number is below the rollup genesis, + // we'll use the host genesis block number as the "safe" block number. + Ok(PairedHeights { host: 0, rollup: 0 }) + } + } + + /// Set the finalized RU block hash. + /// + /// Depending on the current rollup sync status, there are two cases: + /// 1. If we're syncing from scratch, we'll set the finalized RU block hash to the genesis hash. + /// 2. If we're syncing, or following the tip, we'll set the finalized RU block hash to the current RU block hash. + fn set_finalized_ru_block_hash( + &self, + finalized_heights: PairedHeights, + genesis_hash: B256, + ) -> eyre::Result { + // If both heights are 0, return genesis hash + if finalized_heights.host == 0 && finalized_heights.rollup == 0 { + return Ok(genesis_hash); + } + + // Load and set finalized RU header + let finalized_ru_header = self + .ru_provider + .sealed_header(finalized_heights.rollup)? + .expect("ru db inconsistent. no header for height"); + let finalized_ru_block_hash = finalized_ru_header.hash(); + self.bp.set_finalized(finalized_ru_header); + + Ok(finalized_ru_block_hash) + } + + /// Update the host node with the highest processed host height for the exex. + fn update_highest_processed_height(&self, finalized_host_height: u64) -> eyre::Result<()> { + let finalized_host_header = self + .host + .provider() + .sealed_header(finalized_host_height)? + .expect("db inconsistent. no host header for finalized height"); + + let adjusted_height = finalized_host_header.number.saturating_sub(1); + let hash = finalized_host_header.hash(); + + debug!(finalized_host_height = adjusted_height, "Sending FinishedHeight notification"); + self.update_exex_head(adjusted_height, hash) + } + + /// Load the host chain "finalized" block number and determine the rollup + /// "finalized" block number. If the host chain "finalized" block number is below the + /// rollup genesis, we'll use the genesis hash as the "finalized" block. + /// If the host chain "finalized" block number is beyond the current rollup block, + /// we'll use the current rollup block and its host equivalent as the "finalized" blocks. + /// + /// This returns a tuple of the host and rollup "finalized" block numbers. + /// + /// There are three cases: + /// 1. The host chain "finalized" block number is below the rollup genesis (and therefore the current rollup block). + /// In this case, we'll use the host genesis block number as the "finalized" block number, with the rollup syncing from scratch. + /// This can happen if the rollup starts syncing while the host still hasn't seen the rollup genesis block. + /// 2. The host chain "finalized" block number is beyond the current rollup block. + /// In this case, we'll use the current rollup block number as the "finalized" block number. + /// This can happen if the host chain is synced beyond the current rollup block, but the rollup is still syncing + /// and catching up with the host head and therefore hasn't seen the host finalized block. + /// 3. The host chain "finalized" block number is below the current rollup block. + /// In this case, we'll use the host chain "finalized" block number, converted to its rollup equivalent, as the "finalized" block number. + /// This is the expected case when the rollup and host are both caught up and in live sync. + fn load_finalized_block_heights(&self, ru_height: u64) -> eyre::Result { + // Load the host chain "finalized" block number + let finalized_host_block_number = self.host.provider().finalized_block_number()?; + + // Convert the host chain "finalized" block number to the rollup "finalized" block number. + // If the host chain "finalized" block number is below the rollup genesis, + // this will return None. + let finalized_ru_block_number = + finalized_host_block_number.and_then(|finalized_host_block_number| { + self.constants.host_block_to_rollup_block_num(finalized_host_block_number) + }); + + // If we successfully converted the host chain "finalized" block number to the rollup "finalized" block number, + // then we'll figure out which case we're in and return the appropriate heights. + if let Some(finalized_ru_block_number) = finalized_ru_block_number { + // We compare the finalized ru height to the current ru height. If the finalized ru height is + // beyond the current ru height, we're in case 2 (rollup is behind host). + if finalized_ru_block_number > ru_height { + Ok(self.constants.pair_ru(ru_height)) + } else { + // If the finalized ru height is below the current ru height, we're in case 3 (rollup is near or in sync with the host head). + Ok(self.constants.pair_ru(finalized_ru_block_number)) + } + } else { + // If we failed to convert the host chain "finalized" block number to the rollup "finalized" block number, + // then this means the host chain "finalized" block number is below the rollup genesis (and therefore the current rollup block). + // We'll use the genesis block number as the "finalized" block number. + Ok(PairedHeights { host: 0, rollup: 0 }) + } + } + + /// Called when the host chain has reverted a block or set of blocks. + #[instrument(skip_all, fields(first = chain.first().number(), tip = chain.tip().number()))] + pub async fn on_host_revert(&self, chain: &Arc>) -> eyre::Result> { + // If the end is before the RU genesis, we don't need to do anything at + // all. + if chain.tip().number() <= self.constants.host_deploy_height() { + return Ok(None); + } + + // The target is + // - the block BEFORE the first block in the chain + // - or block 0, if the first block is before the rollup deploy height + let target = self + .constants + .host_block_to_rollup_block_num(chain.first().number()) + .unwrap_or_default() // 0 if the block is before the deploy height + .saturating_sub(1); // still 0 if 0, otherwise the block BEFORE. + + let mut reverted = None; + self.ru_provider.provider_rw()?.update(|writer| { + reverted = Some(writer.ru_take_blocks_and_execution_above( + target, + reth::providers::StorageLocation::Both, + )?); + Ok(()) + })?; + + Ok(reverted) + } +} diff --git a/crates/node/src/rpc.rs b/crates/node/src/rpc.rs new file mode 100644 index 0000000..0536bfb --- /dev/null +++ b/crates/node/src/rpc.rs @@ -0,0 +1,39 @@ +use crate::SignetNode; +use reth::{primitives::EthPrimitives, rpc::builder::config::RethRpcServerConfig}; +use reth_node_api::{FullNodeComponents, NodeTypes}; +use signet_node_types::NodeTypesDbTrait; +use signet_rpc::{RpcCtx, RpcServerGuard, ServeConfig}; +use signet_tx_cache::client::TxCache; +use tracing::info; + +impl SignetNode +where + Host: FullNodeComponents, + Host::Types: NodeTypes, + Db: NodeTypesDbTrait, +{ + /// Start the RPC server. + pub async fn start_rpc(&mut self) -> eyre::Result<()> { + let guard = self.launch_rpc().await?; + self.rpc_handle = Some(guard); + info!("launched rpc server"); + Ok(()) + } + + async fn launch_rpc(&self) -> eyre::Result { + let tasks = self.host.task_executor(); + let forwarder = + self.config.forward_url().map(|url| TxCache::new_with_client(url, self.client.clone())); + let eth_config = self.host.config.rpc.eth_config(); + let router = signet_rpc::router().with_state(RpcCtx::new( + self.host.components.clone(), + self.constants.clone(), + self.bp.clone(), + eth_config, + forwarder, + tasks.clone(), + )?); + let serve_config: ServeConfig = self.config.merge_rpc_configs(&self.host)?.into(); + serve_config.serve(tasks, router).await + } +}