diff --git a/.cspell.config.yaml b/.cspell.config.yaml index 348d94da99..4e91dee24f 100644 --- a/.cspell.config.yaml +++ b/.cspell.config.yaml @@ -7,8 +7,6 @@ ignorePaths: - cmake/** - LICENSE.md - .clang-tidy - - src/test/app/wasm_fixtures/**/*.wat - - src/test/app/wasm_fixtures/*.c - nix/check-tools/*.txt # generated, and full of Nix store hashes language: en allowCompoundWords: true # TODO (#6334) diff --git a/.github/scripts/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt index 5577c363fd..e8ccb8a290 100644 --- a/.github/scripts/levelization/results/ordering.txt +++ b/.github/scripts/levelization/results/ordering.txt @@ -1,6 +1,9 @@ benchmarks.libxrpl > xrpl.basics benchmarks.libxrpl > xrpl.config benchmarks.libxrpl > xrpl.nodestore +benchmarks.libxrpl > xrpl.protocol +benchmarks.libxrpl > xrpl.protocol_autogen +benchmarks.libxrpl > xrpl.tx libxrpl.basics > xrpl.basics libxrpl.conditions > xrpl.basics libxrpl.conditions > xrpl.conditions diff --git a/cmake/XrplAddBenchmark.cmake b/cmake/XrplAddBenchmark.cmake index 921deb0658..a09db01c46 100644 --- a/cmake/XrplAddBenchmark.cmake +++ b/cmake/XrplAddBenchmark.cmake @@ -29,6 +29,14 @@ function(xrpl_add_benchmark name) # XrplCore.cmake. Each file compiles fine on its own. set_target_properties(${target} PROPERTIES UNITY_BUILD OFF) + # Land next to `xrpl_tests` in the build root rather than buried under + # `src/benchmarks/libxrpl/`. A benchmark is something a person runs by hand, + # repeatedly, and comparing two of them should not mean typing two long paths. + set_target_properties( + ${target} + PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" + ) + isolate_headers( ${target} "${CMAKE_SOURCE_DIR}/src" diff --git a/crates/Cargo.lock b/crates/Cargo.lock index ddfd05bc00..cecf09688b 100644 --- a/crates/Cargo.lock +++ b/crates/Cargo.lock @@ -348,9 +348,9 @@ dependencies = [ [[package]] name = "wasmi" -version = "2.0.0-beta.10" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab57cbb8db5ee46c6667b642544d7664adfbc0ea6a1ab219c92d734b795f36b1" +checksum = "78693fcdd618e0fc34af59c6b8efa9ac5d58c68df940beff4bedddb6acfe7c27" dependencies = [ "spin", "wasmi_collections", @@ -361,27 +361,27 @@ dependencies = [ [[package]] name = "wasmi_collections" -version = "2.0.0-beta.10" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ea3ee266456966465c55a1f440e33116caf2b05a4fc30da36cb0c9813059d5" +checksum = "8a8be2aa467cf2d29e96ff759472c36eeb44a3c81c67fc9cb76c9a24c519c557" dependencies = [ "string-interner", ] [[package]] name = "wasmi_core" -version = "2.0.0-beta.10" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f8285efe48a9e1afbcdfcc19cd807b3eb20129b7e199c7a99efd30ba192926b" +checksum = "69372d5fda3ea3d1e0aa6603c7888110e0187e88ea17cd8fc2e2df0a0e1f37fa" dependencies = [ "libm", ] [[package]] name = "wasmi_ir" -version = "2.0.0-beta.10" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6227be1aebba39b4815ab6a312d0528590f0db2473621ec9285606410889b0a6" +checksum = "8f17b774caa13c618c7244f1ee51fe23c5e7b8538a471fa46d9949779758aed6" dependencies = [ "wasmi_core", ] @@ -476,6 +476,7 @@ version = "0.1.0" dependencies = [ "cxx", "wat", + "xrpl-host-functions", ] [[package]] diff --git a/crates/xrpl-wasm-testkit/Cargo.toml b/crates/xrpl-wasm-testkit/Cargo.toml index 06c1e7c366..21b929bae1 100644 --- a/crates/xrpl-wasm-testkit/Cargo.toml +++ b/crates/xrpl-wasm-testkit/Cargo.toml @@ -9,3 +9,4 @@ crate-type = ["staticlib", "rlib"] [dependencies] cxx.workspace = true wat = "1" +xrpl-host-functions = { path = "../xrpl-host-functions" } diff --git a/crates/xrpl-wasm-testkit/src/lib.rs b/crates/xrpl-wasm-testkit/src/lib.rs index f503294c59..58c109dd61 100644 --- a/crates/xrpl-wasm-testkit/src/lib.rs +++ b/crates/xrpl-wasm-testkit/src/lib.rs @@ -19,6 +19,18 @@ mod ffi { /// Throws `rust::Error` on invalid input, which is what a test wants: a typo in a /// fixture should fail the test that holds it, at the line that holds it. fn compile_wat(wat: &str) -> Result>; + + /// The gas a host function is charged before it runs, by its guest import name. + /// + /// For the C++ gas benchmarks, which measure what a host call actually costs and + /// report it against what the table says it costs. Reading the declaration through + /// here rather than copying the numbers into C++ is the point: 61 transcribed + /// constants would drift from `lib.rs` the first time a price changed, and drift + /// silently, because a benchmark has nothing to fail. + /// + /// Throws `rust::Error` on an unknown name — a typo should fail loudly rather than + /// quietly compare against zero. + fn host_function_gas(wasm_name: &str) -> Result; } } @@ -26,9 +38,28 @@ fn compile_wat(wat: &str) -> Result, wat::Error> { wat::parse_str(wat) } +fn host_function_gas(wasm_name: &str) -> Result { + xrpl_host_functions::HostFunctionSpec::ALL + .iter() + .find(|op| op.wasm_name() == wasm_name) + .map(|op| op.gas()) + .ok_or_else(|| UnknownHostFunction(wasm_name.to_owned())) +} + +#[derive(Debug)] +struct UnknownHostFunction(String); + +impl std::fmt::Display for UnknownHostFunction { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "no host function is imported as `{}`", self.0) + } +} + +impl std::error::Error for UnknownHostFunction {} + #[cfg(test)] mod tests { - use super::compile_wat; + use super::*; #[test] fn a_module_assembles_to_something_beginning_with_the_wasm_magic() { @@ -37,6 +68,33 @@ mod tests { assert_eq!(&wasm[..4], b"\0asm"); } + #[test] + fn a_host_function_reports_the_gas_its_declaration_gives_it() { + // `trace` is the cheapest declaration in the table; the point is not the number but + // that the lookup reaches the same constant the engine charges from. + assert_eq!( + host_function_gas("trace").expect("trace is a host function"), + xrpl_host_functions::HostFunctionSpec::Trace.gas() + ); + } + + #[test] + fn every_host_function_is_reachable_by_its_import_name() { + for op in xrpl_host_functions::HostFunctionSpec::ALL { + assert_eq!( + host_function_gas(op.wasm_name()).expect("declared"), + op.gas(), + "{} must be reachable by name", + op.wasm_name() + ); + } + } + + #[test] + fn an_unknown_name_is_an_error_rather_than_zero_gas() { + host_function_gas("not_a_host_function").expect_err("must not resolve"); + } + #[test] fn a_typo_is_an_error_rather_than_a_module() { let error = compile_wat("(module (func (export").expect_err("must not assemble"); diff --git a/crates/xrpl-wasm-vm/Cargo.toml b/crates/xrpl-wasm-vm/Cargo.toml index 02c4ec15bb..dc01cd86e9 100644 --- a/crates/xrpl-wasm-vm/Cargo.toml +++ b/crates/xrpl-wasm-vm/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition.workspace = true [dependencies] -wasmi = { version = "2.0.0-beta.10", default-features = false, features = ["std", "validate", "portable-dispatch"] } +wasmi = { version = "2.0.0", default-features = false, features = ["std", "validate", "portable-dispatch"] } xrpl-host-functions = { path = "../xrpl-host-functions" } [dev-dependencies] diff --git a/crates/xrpl-wasm-vm/tests/host_calls.rs b/crates/xrpl-wasm-vm/tests/host_calls.rs index f5dd801c84..b6f1bd36d8 100644 --- a/crates/xrpl-wasm-vm/tests/host_calls.rs +++ b/crates/xrpl-wasm-vm/tests/host_calls.rs @@ -1247,3 +1247,142 @@ fn the_outcome_carries_whatever_the_guest_returned() { assert_eq!(outcome.result, value); } } + +/// The remaining binary operators marshal like `float_add`: both operands and the mode reach +/// the host, tagged by operator. +#[test] +fn float_sub_reads_both_operands_and_the_mode() { + let host = FakeHost::new().answering_float(support::Answer::filler(8)); + let wat = module( + &[import::FLOAT_SUB, ONE_PAGE], + "(call $float_sub (i32.const 0) (i32.const 8) (i32.const 8) (i32.const 8) (i32.const 64) (i32.const 8) (i32.const 2))", + ); + assert_eq!(status(&wat, &host), 8); + assert_eq!( + *host.float_binary_ops_asked.borrow(), + vec![("sub", vec![0u8; 8], vec![0u8; 8], 2)] + ); +} + +#[test] +fn float_mult_reads_both_operands_and_the_mode() { + let host = FakeHost::new().answering_float(support::Answer::filler(8)); + let wat = module( + &[import::FLOAT_MULT, ONE_PAGE], + "(call $float_mult (i32.const 0) (i32.const 8) (i32.const 8) (i32.const 8) (i32.const 64) (i32.const 8) (i32.const 2))", + ); + assert_eq!(status(&wat, &host), 8); + assert_eq!( + *host.float_binary_ops_asked.borrow(), + vec![("mult", vec![0u8; 8], vec![0u8; 8], 2)] + ); +} + +#[test] +fn float_div_reads_both_operands_and_the_mode() { + let host = FakeHost::new().answering_float(support::Answer::filler(8)); + let wat = module( + &[import::FLOAT_DIV, ONE_PAGE], + "(call $float_div (i32.const 0) (i32.const 8) (i32.const 8) (i32.const 8) (i32.const 64) (i32.const 8) (i32.const 2))", + ); + assert_eq!(status(&wat, &host), 8); + assert_eq!( + *host.float_binary_ops_asked.borrow(), + vec![("div", vec![0u8; 8], vec![0u8; 8], 2)] + ); +} + +#[test] +fn float_pow_reads_the_float_the_degree_and_the_mode() { + let host = FakeHost::new().answering_float(support::Answer::filler(8)); + let wat = module( + &[import::FLOAT_POW, ONE_PAGE], + "(call $float_pow (i32.const 0) (i32.const 8) (i32.const 3) (i32.const 64) (i32.const 8) (i32.const 1))", + ); + assert_eq!(status(&wat, &host), 8); + assert_eq!( + *host.float_unary_ops_asked.borrow(), + vec![("pow", vec![0u8; 8], 3, 1)] + ); +} + +/// The `ST*`-in operators read one serialized region and a mode, and write the float. +#[test] +fn float_from_stamount_reads_the_amount_and_the_mode() { + let host = FakeHost::new().answering_float(support::Answer::filler(8)); + let wat = module( + &[import::FLOAT_FROM_STAMOUNT, ONE_PAGE], + "(call $float_from_stamount (i32.const 0) (i32.const 8) (i32.const 64) (i32.const 8) (i32.const 2))", + ); + assert_eq!(status(&wat, &host), 8); + assert_eq!( + *host.float_from_stamount_asked.borrow(), + vec![(vec![0u8; 8], 2)] + ); +} + +#[test] +fn float_from_stnumber_reads_the_number_and_the_mode() { + let host = FakeHost::new().answering_float(support::Answer::filler(8)); + let wat = module( + &[import::FLOAT_FROM_STNUMBER, ONE_PAGE], + "(call $float_from_stnumber (i32.const 0) (i32.const 8) (i32.const 64) (i32.const 8) (i32.const 2))", + ); + assert_eq!(status(&wat, &host), 8); + assert_eq!( + *host.float_from_stnumber_asked.borrow(), + vec![(vec![0u8; 8], 2)] + ); +} + +/// `float_to_int` reads a float and a mode, writing the integer. +#[test] +fn float_to_int_reads_the_float_and_the_mode() { + let host = FakeHost::new().answering_float(support::Answer::filler(8)); + let wat = module( + &[import::FLOAT_TO_INT, ONE_PAGE], + "(call $float_to_int (i32.const 0) (i32.const 8) (i32.const 64) (i32.const 8) (i32.const 2))", + ); + assert_eq!(status(&wat, &host), 8); + assert_eq!(*host.float_to_int_asked.borrow(), vec![(vec![0u8; 8], 2)]); +} + +/// `float_from_mant_exp` passes two scalars (an i64 mantissa and an i32 exponent) and a mode. +#[test] +fn float_from_mant_exp_passes_the_mantissa_exponent_and_mode() { + let host = FakeHost::new().answering_float(support::Answer::filler(8)); + let wat = module( + &[import::FLOAT_FROM_MANT_EXP, ONE_PAGE], + "(call $float_from_mant_exp (i64.const 42) (i32.const 3) (i32.const 64) (i32.const 8) (i32.const 1))", + ); + assert_eq!(status(&wat, &host), 8); + assert_eq!(*host.float_from_mant_exp_asked.borrow(), vec![(42, 3, 1)]); +} + +/// A host input read from an unaligned pointer arrives intact: the host reads a byte slice, not +/// an aligned word, so a contract that hands it an odd offset is served the right bytes. (Ports +/// the old `bad_align` fixture, which exercised unaligned reads in the C-ABI wrapper.) +#[test] +fn an_unaligned_input_is_read_intact() { + let host = FakeHost::new().answering_float(support::Answer::filler(8)); + let stores: String = (0..8u8) + .map(|i| { + format!( + "(i32.store8 (i32.const {}) (i32.const {}))", + i + 1, + 0xa0 + i + ) + }) + .collect(); + let wat = module( + &[import::FLOAT_FROM_STAMOUNT, ONE_PAGE], + &format!( + "{stores} (call $float_from_stamount (i32.const 1) (i32.const 8) (i32.const 64) (i32.const 8) (i32.const 0))" + ), + ); + assert_eq!(status(&wat, &host), 8); + assert_eq!( + *host.float_from_stamount_asked.borrow(), + vec![((0xa0u8..0xa8u8).collect::>(), 0)] + ); +} diff --git a/crates/xrpl-wasm-vm/tests/preflight.rs b/crates/xrpl-wasm-vm/tests/preflight.rs index 705252e0e9..46a9bd5450 100644 --- a/crates/xrpl-wasm-vm/tests/preflight.rs +++ b/crates/xrpl-wasm-vm/tests/preflight.rs @@ -593,3 +593,61 @@ fn a_memory64_memory_is_refused_by_screening() { "{refusal}" ); } + +/// The corruption fixtures below are written as hex strings, which is how the old Beast suite +/// carried them — the bytes are deliberately malformed, so there is nothing to assemble them +/// from. +fn hex(s: &str) -> Vec { + (0..s.len()) + .step_by(2) + .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap()) + .collect() +} + +/// Malformed modules crafted to abuse the parser rather than merely be invalid — a vector +/// length that lies about its size, a section that overruns its payload, a locals-count bomb, +/// and a non-terminating LEB128 — are refused at compile like any other garbage. These guard +/// the parser against resource-exhaustion shapes (ported from the old Beast section-corruption +/// fixtures); the plainer "bad magic / wrong version" shapes are covered by `garbage_does_not_pass`. +#[test] +fn parser_abuse_shapes_are_refused() { + let cases = [ + ("vector length lies", "0061736d010000000105ffffffff0f"), + ("section overruns its payload", "0061736d01000000010a0160"), + ( + "locals-count bomb", + "0061736d01000000010401600000030201000a0f010d01ffffffff0f7f0b", + ), + ( + "non-terminating LEB128", + "0061736d0100000001058080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080", + ), + ]; + for (label, h) in cases { + let refusal = xrpl_wasm_vm::check(&hex(h), ENTRY).expect_err(label); + assert_stage!(refusal, CheckError::Compile(_)); + } +} + +/// The plain structurally-malformed modules from the old section-corruption fixtures — a +/// corrupt magic, a wrong version, a lying section length, sections out of order, junk after +/// the last section, an unknown section id — are all refused at compile. Belt-and-suspenders +/// alongside `garbage_does_not_pass`: guards against a wasmi upgrade loosening the validator. +#[test] +fn structurally_malformed_modules_are_refused() { + let cases = [ + ("corrupt magic number", "0161736d01000000"), + ("wrong version", "0061736d02000000"), + ("lying section length", "0061736d01000000018080808008"), + ("sections out of order", "0061736d010000000a02000b03020000"), + ( + "junk after last section", + "0061736d01000000010a01600000000000000000", + ), + ("unknown section id", "0061736d01000000ff0100"), + ]; + for (label, h) in cases { + let refusal = xrpl_wasm_vm::check(&hex(h), ENTRY).expect_err(label); + assert_stage!(refusal, CheckError::Compile(_)); + } +} diff --git a/crates/xrpl-wasm-vm/tests/vm_limits.rs b/crates/xrpl-wasm-vm/tests/vm_limits.rs index 52a8314a65..bcbfa7218d 100644 --- a/crates/xrpl-wasm-vm/tests/vm_limits.rs +++ b/crates/xrpl-wasm-vm/tests/vm_limits.rs @@ -598,3 +598,114 @@ fn a_memory64_module_is_rejected_at_compile() { "rejected before instantiation, so nothing is charged: {failure}" ); } + +/// A function declaring more parameters than wasm allows (1000) is refused at compile, so a +/// contract cannot smuggle an unbounded signature past screening. +#[test] +fn a_function_with_too_many_params_is_refused() { + let host = FakeHost::new(); + let params = " i32".repeat(1001); + let wat = format!( + "(module {ONE_PAGE} (func (param{params}) (result i32) (i32.const 0)) \ + (func (export \"finish\") (result i32) (i32.const 0)))" + ); + assert_stage!(failure(&wat, &host), RunError::Compile(_)); +} + +/// A function declaring more locals than wasm allows (50 000) is refused at compile. +#[test] +fn a_function_with_too_many_locals_is_refused() { + let host = FakeHost::new(); + let locals = format!("(local{})", " i32".repeat(50_001)); + let wat = module(&[ONE_PAGE], &format!("{locals} (i32.const 0)")); + assert_stage!(failure(&wat, &host), RunError::Compile(_)); +} + +/// Below the compile cap but past the engine's register frame, a locals-heavy function is +/// refused when the frame is built rather than at compile — still refused, just later. +#[test] +fn a_function_past_the_register_frame_is_refused() { + let host = FakeHost::new(); + let locals = format!("(local{})", " i32".repeat(40_000)); + let wat = module(&[ONE_PAGE], &format!("{locals} (i32.const 0)")); + assert_stage!(failure(&wat, &host), RunError::Trap(_)); +} + +/// Unbounded recursion is stopped by the engine's call-stack limit — it traps rather than +/// running the host's native stack off the end (the portable dispatcher makes loops safe; +/// this pins that guest *calls* are bounded too). +#[test] +fn unbounded_recursion_is_stopped_by_the_call_stack_limit() { + let host = FakeHost::new(); + let wat = format!( + "(module {ONE_PAGE} \ + (func $rec (param i32) (result i32) \ + (if (result i32) (i32.eqz (local.get 0)) (then (i32.const 0)) \ + (else (call $rec (i32.sub (local.get 0) (i32.const 1)))))) \ + (func (export \"finish\") (result i32) (call $rec (i32.const 1000000))))" + ); + assert_stage!(failure(&wat, &host), RunError::Trap(_)); +} + +/// A module with many functions currently compiles and runs: wasmi's only cap is its +/// 1,000,000 hard limit, so the ticket's ~24k-function module — a CodeMap-growth DoS, since +/// every validation appends to the engine's append-only CodeMap — is not refused here. +/// Enforcing a tighter bound (a function-count / average-bytes-per-function limit) belongs in +/// a future preflight pass that parses the module before the engine sees it. Ignored until +/// then, so this documents the gap without asserting it is acceptable. +#[test] +#[ignore = "CodeMap-DoS unmitigated; a function-count limit is deferred to preflight parsing"] +fn many_functions_currently_run_unbounded() { + let host = FakeHost::new(); + let funcs: String = (0..24_000) + .map(|i| format!("(func $f{i} (result i32) (i32.const {}))", i % 7)) + .collect(); + let wat = + format!("(module {ONE_PAGE} {funcs} (func (export \"finish\") (result i32) (call $f0)))"); + assert!( + run(&wat, &host).is_ok(), + "a large-function module currently compiles and runs" + ); +} + +/// The trap *kinds* wasmi distinguishes all reach the caller identically — a guest trap +/// charged as the contract's fault — so the `unreachable` representative pins the mapping. +/// These pin the individual kinds too, guarding against a wasmi upgrade reclassifying any of +/// them as something other than a trap. +#[test] +fn a_division_by_zero_traps() { + let host = FakeHost::new(); + let wat = module(&[ONE_PAGE], "(i32.div_s (i32.const 1) (i32.const 0))"); + assert_stage!(failure(&wat, &host), RunError::Trap(_)); +} + +#[test] +fn a_signed_integer_overflow_traps() { + let host = FakeHost::new(); + let wat = module( + &[ONE_PAGE], + "(i32.div_s (i32.const 0x80000000) (i32.const -1))", + ); + assert_stage!(failure(&wat, &host), RunError::Trap(_)); +} + +#[test] +fn an_indirect_call_to_a_null_table_entry_traps() { + let host = FakeHost::new(); + let wat = format!( + "(module {ONE_PAGE} (type $t (func (result i32))) (table 1 funcref) \ + (func (export \"finish\") (result i32) (call_indirect (type $t) (i32.const 0))))" + ); + assert_stage!(failure(&wat, &host), RunError::Trap(_)); +} + +#[test] +fn an_indirect_call_with_a_mismatched_signature_traps() { + let host = FakeHost::new(); + let wat = format!( + "(module {ONE_PAGE} (type $void (func)) (type $i32 (func (result i32))) \ + (table 1 funcref) (elem (i32.const 0) $f) (func $f (type $void)) \ + (func (export \"finish\") (result i32) (call_indirect (type $i32) (i32.const 0))))" + ); + assert_stage!(failure(&wat, &host), RunError::Trap(_)); +} diff --git a/src/benchmarks/libxrpl/CMakeLists.txt b/src/benchmarks/libxrpl/CMakeLists.txt index ac751a0413..ab3e68b87b 100644 --- a/src/benchmarks/libxrpl/CMakeLists.txt +++ b/src/benchmarks/libxrpl/CMakeLists.txt @@ -20,3 +20,20 @@ target_link_libraries( xrpl_add_benchmark(nodestore) target_link_libraries(xrpl.bench.nodestore PRIVATE xrpl.imports.bench) add_dependencies(xrpl.benchmarks xrpl.bench.nodestore) + +# Gas calibration for the wasm host functions. The ledger and real host come from +# `xrpl.testkit.wasm` (built with the tests, but framework-free), so this target links +# no GTest and no GMock. +if(TARGET xrpl.testkit.wasm) + xrpl_add_benchmark(wasm) + target_link_libraries( + xrpl.bench.wasm + PRIVATE xrpl.imports.bench xrpl.testkit.wasm + ) + add_dependencies(xrpl.benchmarks xrpl.bench.wasm) +else() + message( + STATUS + "xrpl.testkit.wasm not built (tests disabled); skipping xrpl.bench.wasm." + ) +endif() diff --git a/src/benchmarks/libxrpl/wasm/BenchFixtures.cpp b/src/benchmarks/libxrpl/wasm/BenchFixtures.cpp new file mode 100644 index 0000000000..3eb9c7e35b --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/BenchFixtures.cpp @@ -0,0 +1,175 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test::bench { + +Fixtures::Fixtures() + : alice_{ledger_.fund("benchAlice")} + , bob_{ledger_.fund("benchBob")} + , signerListOwner_{ledger_.fund("benchSigners")} + , escrow_{keylet::account(AccountID{})} + , signedMessage_{signMessage("the quick brown fox jumps over the lazy dog")} + , nftId_{NftIds::makeNftId(alice_.id())} +{ + ledger_.makeSignerList(signerListOwner_, 2, {{alice_, 1}, {bob_, 1}}); + + // The escrow has to be submitted after the accounts exist, which is why it is built here + // rather than in the initializer list: its keylet depends on the owner's sequence number at + // submission time. + auto const ownerSeq = ledger_.ledger.getAccountRoot(alice_.id()).getSequence(); + auto const created = ledger_.ledger.submit( + transactions::EscrowCreateBuilder{alice_.id(), bob_.id(), XRP(100)}.setFinishAfter( + 900'000'000), + alice_); + if (created.ter != tesSUCCESS) + { + fixtureFailed(std::string{"creating the escrow: "} + transToken(created.ter)); + } + ledger_.ledger.close(); + escrow_ = keylet::escrow(alice_.id(), SeqProxy::rawSequence(ownerSeq)); +} + +Account const& +Fixtures::alice() const +{ + return alice_; +} + +Account const& +Fixtures::bob() const +{ + return bob_; +} + +TxAssembler +Fixtures::memoTx() +{ + auto assembler = escrowFinishTx(ledger_.ledger, alice_); + assembler.build = [inner = std::move(assembler.build)](STObject& obj) { + inner(obj); + auto memos = STArray{}; + memos.push_back(makeMemo(WasmLedger::toBytes("hello"))); + memos.push_back(makeMemo(WasmLedger::toBytes("world"))); + obj.setFieldArray(sfMemos, memos); + }; + return assembler; +} + +FieldLocator +Fixtures::memoLocator() +{ + return FieldLocator{{sfMemos.getCode(), 0, sfMemoData.getCode()}}; +} + +WasmHost +Fixtures::host() +{ + auto assembler = memoTx(); + return ledger_.makeHost( + keylet::account(alice_.id()), assembler.type, std::move(assembler.build)); +} + +WasmHost +Fixtures::cachedHost() +{ + auto wasmHost = host(); + if (!wasmHost->cacheLedgerObj(keylet::account(alice_.id()).key, 1).has_value()) + { + fixtureFailed("caching the account root into slot 1"); + } + return wasmHost; +} + +WasmHost +Fixtures::signerListHost() +{ + auto assembler = bareTx(); + return ledger_.makeHost( + keylet::signerList(signerListOwner_.id()), assembler.type, std::move(assembler.build)); +} + +WasmHost +Fixtures::cachedSignerListHost() +{ + auto assembler = bareTx(); + auto wasmHost = + ledger_.makeHost(keylet::account(AccountID{}), assembler.type, std::move(assembler.build)); + if (!wasmHost->cacheLedgerObj(keylet::signerList(signerListOwner_.id()).key, 1).has_value()) + { + fixtureFailed("caching the signer list into slot 1"); + } + return wasmHost; +} + +WasmHost +Fixtures::tracingHost() +{ + return ledger_.makeTracingHost(); +} + +Keylet const& +Fixtures::escrow() const +{ + return escrow_; +} + +WasmHost +Fixtures::escrowHost() +{ + return ledger_.makeHost(escrow_); +} + +Slice +Fixtures::floatX() +{ + return FloatConstants::slice(FloatConstants::kPi); +} + +Slice +Fixtures::floatY() +{ + return FloatConstants::slice(FloatConstants::kTwo); +} + +SignedMessage const& +Fixtures::signedMessage() const +{ + return signedMessage_; +} + +uint256 const& +Fixtures::nftId() const +{ + return nftId_; +} + +Fixtures& +Fixtures::instance() +{ + static Fixtures kValue; + return kValue; +} + +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/BenchFixtures.h b/src/benchmarks/libxrpl/wasm/BenchFixtures.h new file mode 100644 index 0000000000..8693a13dfd --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/BenchFixtures.h @@ -0,0 +1,111 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include + +#include + +namespace xrpl::test::bench { + +// The ledger and canned inputs every `*.bench.cpp` measures against. +class Fixtures +{ +public: + // The one set of fixtures every benchmark shares, built on first use. + static Fixtures& + instance(); + + // A sequence number for the keylets that take one. Arbitrary — a keylet hashes whatever it + // is given, so the value cannot change the cost. + static constexpr std::uint32_t kSeq = 42; + + // Rounding mode 0 throughout the float family: modes select a tie-breaking rule, not a + // different algorithm, so they do not move the cost, and pinning one keeps the fourteen + // comparable. + static constexpr std::int32_t kRoundingMode = 0; + + // Two funded accounts, enough for every keylet shape and every object below. + [[nodiscard]] Account const& + alice() const; + [[nodiscard]] Account const& + bob() const; + + // The default host: its transaction carries a two-element memo array (something for the + // nested getters to walk to and the array-length getters to count) and its current object is + // Alice's account root. + [[nodiscard]] WasmHost + host(); + + // The same, with Alice's account root pinned to slot 1, for the `le_*` getters that read + // through a cache slot rather than the current object. + [[nodiscard]] WasmHost + cachedHost(); + + // An account root has no arrays, so the array-length getters that read a *ledger object* + // need a different one. A signer list has `sfSignerEntries`; without it those calls would + // answer `FieldNotFound` and the benchmark would time the rejection instead of the work. + [[nodiscard]] WasmHost + signerListHost(); + [[nodiscard]] WasmHost + cachedSignerListHost(); + + // A host whose `trace` output is captured rather than dropped, so the log-enabled path can + // be measured against the log-disabled one that `host()` gives. + [[nodiscard]] WasmHost + tracingHost(); + + // A real escrow, created through the real transactor — the current object for + // `home_le_field`, the one getter whose cost depends on the object it reads rather than on + // its arguments. + [[nodiscard]] Keylet const& + escrow() const; + [[nodiscard]] WasmHost + escrowHost(); + + // `sfMemos[0].sfMemoData` — a two-step locator path, the shape the nested getters are priced + // for. + [[nodiscard]] static FieldLocator + memoLocator(); + + // Canonical float operands. Zeroed bytes decode as a non-canonical float and would be + // refused before any arithmetic ran, so the whole family shares these two known-good values. + [[nodiscard]] static Slice + floatX(); + [[nodiscard]] static Slice + floatY(); + + // A signed message for `check_sig`. Signing is far more expensive than the verification + // being measured, so it happens once here rather than inside a timed loop. + [[nodiscard]] SignedMessage const& + signedMessage() const; + + // A well-formed NFToken id with the fixture's known taxon, flags, fee and sequence baked in, + // so the id-extractor getters have real fields to pull out rather than zeros. + [[nodiscard]] uint256 const& + nftId() const; + +private: + // Order matters, and that is the reason this is a constructor rather than a pile of lazy + // statics: the accounts have to be funded before the signer list and the escrow can be built + // on them. + Fixtures(); + + // The transaction the default host runs, carrying the memo array. + [[nodiscard]] TxAssembler + memoTx(); + + WasmLedger ledger_; + Account alice_; + Account bob_; + Account signerListOwner_; + Keylet escrow_; + SignedMessage signedMessage_; + uint256 nftId_; +}; + +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/Crossing.cpp b/src/benchmarks/libxrpl/wasm/Crossing.cpp new file mode 100644 index 0000000000..d764d051b7 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/Crossing.cpp @@ -0,0 +1,44 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +// The harness checking itself. +// +// This file holds no host function — it belongs to the wasm directory rather than +// `host_functions/` because it measures the two reference points every per-function number is read +// against, and neither is a host call. +// +// `GuestInstruction` runs a contract whose "host call" is a couple of guest instructions. Its +// `implied_gas` and `charged_gas` are then two independent measurements of the same quantity — one +// from wall time via `secondsPerGas`, one from the engine's own fuel meter — and they should agree +// closely. When they diverge, `secondsPerGas` has measured something other than a guest +// instruction and no other number in the run is trustworthy. Read this first. +// +// The crossing floor is the other reference point, and it lives in `host_functions/LedgerSqn`: +// `ldgr_index` takes no input and answers from a header already in hand, so its impl is as close +// to nothing as a host function gets, and whatever its `ThroughVm` case costs above its `Impl` +// case is the price of leaving the guest — paid by every one of the 61 functions before any of +// them does any work. +// +// So the reading order across the suite is: this file, then `LedgerSqn`'s pair for the floor, then +// a function's own `Impl` number. Those three should account for its `ThroughVm` number; where +// they do not, the gap is size-dependent copying, which the swept cases (`Sha512Half`, +// `UpdateData`) expose. + +void +guestInstruction(benchmark::State& state) +{ + static constexpr std::string_view kBody = "(i32.add (local.get $r) (i32.const 1))"; + // Empty import name: this case prices no host function, so there is nothing to look a + // declaration up for and it reports no `suggested_gas`. + benchmarkThroughVm(state, "", "", "", kBody, [] { return Fixtures::instance().host(); }); +} +BENCHMARK(guestInstruction)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/README.md b/src/benchmarks/libxrpl/wasm/README.md new file mode 100644 index 0000000000..65b7677762 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/README.md @@ -0,0 +1,180 @@ +# WASM host functions — gas calibration + +These are **not tests**: nothing asserts, and a number moving is not a build failure. They answer +the question the tests cannot — whether each `#[gas = N]` in +`crates/xrpl-host-functions/src/lib.rs` matches what the function actually costs. + +```bash +cmake --build build --target xrpl.bench.wasm +./build/xrpl.bench.wasm # everything (~2 min) +./build/xrpl.bench.wasm --benchmark_filter=sha512Half +./build/xrpl.bench.wasm --benchmark_repetitions=25 --benchmark_report_aggregates_only=true +``` + +**Build Release.** Debug inflates the crossing far more than the impls: `Impl`-to-`Impl` ratios +survive it, `suggested_gas` does not. + +## Reading the output + +| Counter | Meaning | +| ------------------- | ---------------------------------------------------------------------------------- | +| `suggested_gas` | **the answer** — what this function should be priced at | +| `host_function_gas` | what `lib.rs` says today, read through the `wasm_testkit` bridge so it can't drift | +| `price_ratio` | `host_function_gas / suggested_gas`. **1.0 is correct; below 1 is underpriced** | +| `rel_error` | relative uncertainty of `suggested_gas`. **Quote this one** — ~1.2% when quiet | +| `unreliable` | `1` means do not act on this row | +| `implied_gas` | the raw measurement, before the crossing is added back | +| `charged_gas` | what the engine actually billed; confirms the right call was measured | +| `ns_per_call` | raw wall time, for debugging a suspicious ratio | + +Sort by `price_ratio`. **Below 1 is the direction that matters** — an underpriced call is one a +contract can buy too cheaply, a denial-of-service vector rather than a rounding error: + +```bash +./build/xrpl.bench.wasm --benchmark_format=json | + jq -r '.benchmarks[] | select(.price_ratio) | [.price_ratio, .name] | @tsv' | sort -n +``` + +`unreliable=1` when `rel_error` exceeds 25%, or when `suggested_gas` falls below the crossing floor +— a call whose own cost is small next to the crossing is read off the difference of two nearly +equal numbers. + +### With `--benchmark_repetitions` + +Adds `_mean` / `_median` / `_stddev` / `_cv` rows. One trap worth knowing: + +**`cv` on `suggested_gas` for an `Impl` case is not an error bar.** The crossing floor is measured +once per process, so repetitions never resample it — and it is most of a cheap `Impl` case's value. +Over 25 repetitions on an idle machine, `Impl` `cv` reads **1.3%** against `ThroughVm`'s 2.3%, while +`rel_error` is 1.2% for both. The lowest number in the output is the least trustworthy one. + +Use repetitions to confirm the machine is quiet and to get a median; quote `rel_error`. Under load +the `Impl` cases inflate first (3.0% against 1.8% at load ~10), which makes the gap between the two +families a usable load detector. + +## How `suggested_gas` is measured + +Gas is wasmi fuel — `set_fuel(gas)` meters guest instructions and host charges from one pool — so +one gas is about one guest instruction and the question becomes a ratio. Every step is a +subtraction, so fixed costs cancel: + +``` +secondsPerGas = (time_busy − time_idle) / (fuel_busy − fuel_idle) # pure-wasm loop, N vs 0 +implied_gas = secondsPerCall / secondsPerGas +crossing_floor = (ldgr_index ThroughVm − ldgr_index Impl) / secondsPerGas + +suggested_gas = implied_gas # ThroughVm — the guest already paid the crossing +suggested_gas = implied_gas + crossing_floor # Impl — a guest cannot call without paying it +price_ratio = host_function_gas / suggested_gas + +rel_error = sqrt( ( sqrt((implied·caseErr)² + (floor·floorErr)²) / suggested )² + perGasErr² ) +``` + +`secondsPerCall` is itself a subtraction: a `ThroughVm` case runs a contract making N host calls +against a **byte-identical** one making none, so compilation, instantiation and the guest's own loop +cancel. An `Impl` case times `kCallsPerRun` direct calls and divides. + +`secondsPerGas` is measured **once** and shared by every case, deliberately — two routes to the same +price must divide by the same constant, and per-case calibration was tried and swung 6x between +runs. Its uncertainty is propagated arithmetically instead. See the comments in `WasmBench.cpp` for +why the three terms in `rel_error` do not all combine in quadrature. + +**`guestInstruction` is the self-test — read it first.** It runs the calibration's own loop body, so +its `implied_gas` (wall time) and `charged_gas` (the fuel meter) are two independent measurements of +one quantity. Quiet Release machine: **≈13.7 against 13.007, ~5% high.** A persistent gap much +beyond that means every other number in the run shares it. It has already caught an estimator +mismatch worth +40%, and the memory leak below. + +**`suggested_gas` for an `Impl`-only case is a lower bound** — the crossing floor is measured on a +call with no input, so a function that moves bytes pays more; `Sha512Half` and `UpdateData` sweep +that per-byte term. `ThroughVm` cases are deliberately one per crossing _shape_, not one per +function. + +## VM overhead (`Vm.cpp`) + +Everything above prices what a contract _asks for_. `Vm.cpp` prices getting it running at all. Of +the seven stages `runEscrowWasm` performs — compile, store, linker, instantiate, entry-point lookup, +call, fuel read — **only the call is metered**; the rest is wall time no transaction pays for. + +These cases report `ns_per_op` and `gas_equivalent` (that time over the same `secondsPerGas`, so an +unpriced stage reads on the same axis as a priced one), plus `module_bytes` and `gas_per_byte` on +size sweeps. + +| case | measures | +| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | +| `preflightMinimal` | compile plus the import/export walk. The narrowest view of compilation reachable from C++: no host, no instance | +| `preflightRejects` | the same on a module refused at the import walk. Against `preflightMinimal`, what refusing costs versus accepting | +| `runMinimal` | a whole run of a do-nothing contract — every stage. Minus `preflightMinimal`, the stages that are not compilation | +| `compileScaling/N` | compilation against module size: `N` unreachable filler functions, preflight only | +| `runScaling/N` | the same modules through a whole run. Paired with `compileScaling` per size, separates size-dependent stages from fixed ones | +| `instantiateScaling/pages` | declared memory at constant module size, so what moves is the host allocating and zeroing pages | + +Two of those pairings are the point of the file. `runMinimal − preflightMinimal` gives the fixed +cost of everything that is not compilation; `runScaling` against `compileScaling` shows compilation +appearing a second time, because the transactor validates and executes with no module cache between +them. The size sweeps matter more than the floor: a fixed cost is only a griefing concern if it is +large, but a slope against attacker-chosen module size is one at any height. + +Two caveats when reading a sweep. `gas_per_byte` is an **average** carrying the case's fixed cost, +not a marginal rate — it overestimates, and falls toward the true slope as the module grows, so read +the convergence rather than any single row. And the `/4096` points get few iterations and go noisy +first; compare `rel_error` across the sweep before quoting the largest one. + +The sweep stops at 4096 functions for want of a real cap to stop at — no maximum contract size is +enforced anywhere yet, the transactor not being wired. + +The linker rebuild and the fuel-metering overhead are **not** separable from here — C++ sees only +`runEscrowWasm` and `preflightEscrowWasm`. Both need benchmarks inside `xrpl-wasm-vm`, where +`compile` and `wasm_engine` are `pub(crate)`. + +### Compiling leaks — pin your iteration counts + +`wasm_engine()` is a process-global `LazyLock`, and what `Module::new` adds to it is never +released. Repeatedly preflighting one **60-byte** module: + +| `--benchmark_repetitions` | peak RSS | +| ------------------------- | -------- | +| 1 | 0.41 GB | +| 5 | 1.46 GB | +| 15 | 4.20 GB | + +Linear, at roughly **800 bytes per compile**. Within the suite this is why every `Vm.cpp` case pins +`->Iterations(...)`: automatic sizing ran `preflightMinimal` ~348k times per repetition, reaching +7.9 GB at 25 repetitions, after which every later case in the binary failed to compile — 720 errored +rows, all blaming cases that were innocent. + +**Outside the suite it is worth a look.** A validator compiles twice per programmable-escrow +transaction against that same static engine. Whether that is unbounded growth in production depends +on wasmi internals not checked here — this is the C++-visible symptom, not a diagnosis. + +## Gotchas, each of which has already cost someone an afternoon + +- **The wasm ABI is not the trait's argument order.** `float_add(x, y, mode, out)` in Rust is + `(x_ptr, x_len, y_ptr, y_len, out_ptr, out_len, mode)` on the wire — scalars move _after_ the + output region. Check `register.rs`, not `lib.rs`, when writing WAT. +- **A soft host error still "succeeds".** The run completes and gas is charged _before_ the body, so + a wrong-argument case reports a plausible, confidently wrong number. The harness requires the + contract's result to be `>= 0`; the tell is a `ThroughVm` case coming out _faster_ than its `Impl`. +- **A host serves exactly one run** (`checkSelf` in `WasmVM.cpp`), so a benchmark builds a fresh host + per run and cannot pre-cache a slot. +- **`MAX_FIELD_BYTES` is 1024** — nothing crosses the boundary above 1 KiB, so size sweeps stop there. +- **Do not compare timings across builds at the cheap end.** Two builds whose timed regions were + byte-identical measured 2.18 ns and 2.52 ns for the same case — ~15% apart, from code layout alone. + Use `price_ratio` within one run, and reason from the code when judging whether a change costs + anything. +- **Every case pins `->Iterations(...)`, for two different reasons.** Host-function cases must + because with `UseManualTime` automatic sizing reads only the tiny reported residue and would ask + for millions of iterations; `Vm.cpp` cases must because compiling leaks. + +## Layout + +One `.cpp` per host function under `host_functions/`, mirroring +`src/tests/libxrpl/tx/wasm/host_functions/`, so adding a host function is a two-file checklist +rather than a judgement call. `Crossing.cpp` holds the harness's own reference points, `Vm.cpp` the +per-run overhead around them, `WasmBench.*` the measurement machinery, `BenchFixtures.*` the shared +ledger (one ledger, funded once, for the whole binary). + +The ledger and real host come from `xrpl.testkit.wasm` — a framework-free library built alongside +the tests — so this target links **no GTest and no GMock**. See +`src/tests/libxrpl/tx/wasm/README.md` for how that library is split, and why its setup steps throw +rather than using `EXPECT_`. diff --git a/src/benchmarks/libxrpl/wasm/Vm.cpp b/src/benchmarks/libxrpl/wasm/Vm.cpp new file mode 100644 index 0000000000..dd5ec2e420 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/Vm.cpp @@ -0,0 +1,149 @@ +#include +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test::bench { +namespace { + +// What a run costs *around* the contract, rather than what its host calls cost. Only the guest's +// own execution is metered, so every stage measured here is wall time no transaction pays for. +// ../README.md has what each case measures and how to read `gas_equivalent`. +// +// **Every case must pin `->Iterations(...)`.** Compiling a module allocates against the +// process-global engine and is never reclaimed — roughly 800 bytes per compile — so Google +// Benchmark's automatic sizing, which targets a wall-clock budget rather than a compile count, +// reaches gigabytes resident and the whole binary stops being able to compile anything. + +// The smallest module the engine accepts. Everything a run does to it is overhead by construction. +std::string +minimalWat() +{ + return R"wat((module + (memory (export "memory") 1) + (func (export "escrow_finish") (result i32) + (i32.const 1))) +)wat"; +} + +// `count` unreachable functions on top of the minimal module: bigger without doing more. +// +// Each body is seeded with its own index so no two are identical and none folds to a constant the +// translator can drop — either would break the link between function count and byte count. +// Unreachable is fine: validation and translation visit every function a module declares, and that +// visit is exactly the cost being swept. +std::string +fillerWat(size_t count) +{ + auto out = std::string{"(module\n (memory (export \"memory\") 1)\n"}; + for (auto i = 0uz; i < count; ++i) + { + out += std::format( + " (func $f{0} (param i32) (result i32)\n" + " (i32.add (i32.mul (local.get 0) (i32.const {0})) (i32.const {0})))\n", + i); + } + out += " (func (export \"escrow_finish\") (result i32)\n (i32.const 1)))\n"; + return out; +} + +// The minimal module asking for `pages` of initial memory. `MAX_MEMORY_PAGES` is 128 (8 MiB), and a +// contract declares this for free — the host allocates and zeroes it before the first instruction. +std::string +pagesWat(size_t pages) +{ + return std::format( + "(module\n" + " (memory (export \"memory\") {})\n" + " (func (export \"escrow_finish\") (result i32)\n" + " (i32.const 1)))\n", + pages); +} + +// Compiles cleanly and is then refused: `env::malloc` is not a namespace the engine serves, so +// `check_imports` stops at it. +std::string +rejectedWat() +{ + return R"wat((module + (import "env" "malloc" (func $malloc (param i32) (result i32))) + (memory (export "memory") 1) + (func (export "escrow_finish") (result i32) + (i32.const 1))) +)wat"; +} + +void +preflightMinimal(benchmark::State& state) +{ + static auto const kWasm = assembleWat(minimalWat()); + benchmarkPreflight(state, kWasm); +} +BENCHMARK(preflightMinimal)->UseManualTime()->Iterations(kBenchIterations); + +void +preflightRejects(benchmark::State& state) +{ + static auto const kWasm = assembleWat(rejectedWat()); + benchmarkPreflight(state, kWasm, /*expectAccepted*/ false); +} +BENCHMARK(preflightRejects)->UseManualTime()->Iterations(kBenchIterations); + +void +runMinimal(benchmark::State& state) +{ + static auto const kWasm = assembleWat(minimalWat()); + benchmarkRun(state, kWasm, [] { return Fixtures::instance().host(); }); +} +BENCHMARK(runMinimal)->UseManualTime()->Iterations(kBenchIterations); + +void +compileScaling(benchmark::State& state) +{ + auto const wasm = assembleWat(fillerWat(static_cast(state.range(0)))); + benchmarkPreflight(state, wasm, /*expectAccepted*/ true, /*sizeSweep*/ true); +} +BENCHMARK(compileScaling) + ->UseManualTime() + ->Iterations(kBenchIterations) + ->Arg(1) + ->Arg(8) + ->Arg(64) + ->Arg(512) + ->Arg(4096); + +void +runScaling(benchmark::State& state) +{ + auto const wasm = assembleWat(fillerWat(static_cast(state.range(0)))); + benchmarkRun(state, wasm, [] { return Fixtures::instance().host(); }, /*sizeSweep*/ true); +} +BENCHMARK(runScaling) + ->UseManualTime() + ->Iterations(kBenchIterations) + ->Arg(1) + ->Arg(8) + ->Arg(64) + ->Arg(512) + ->Arg(4096); + +void +instantiateScaling(benchmark::State& state) +{ + auto const wasm = assembleWat(pagesWat(static_cast(state.range(0)))); + benchmarkRun(state, wasm, [] { return Fixtures::instance().host(); }); +} +BENCHMARK(instantiateScaling) + ->UseManualTime() + ->Iterations(kBenchIterations) + ->Arg(1) + ->Arg(8) + ->Arg(32) + ->Arg(128); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/WasmBench.cpp b/src/benchmarks/libxrpl/wasm/WasmBench.cpp new file mode 100644 index 0000000000..e5975f2403 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/WasmBench.cpp @@ -0,0 +1,397 @@ +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace xrpl::test::bench { + +int +callsWithinTransferBudget(std::int64_t bytesWrittenPerCall) +{ + // Writes nothing back to the guest, so the budget does not apply. + if (bytesWrittenPerCall <= 0) + { + return kCallsPerRun; + } + + auto const affordable = kTransferLimitBytes / bytesWrittenPerCall; + if (affordable < 1) + { + fixtureFailed("a single call would exceed the run's transfer budget"); + } + return static_cast(std::min(affordable, kCallsPerRun)); +} + +std::string +dataSegment(int offset, std::span bytes) +{ + return std::format(" (data (i32.const {}) \"{}\")\n", offset, watEscaped(bytes)); +} + +std::string +dataSegment(int offset, Bytes const& bytes) +{ + return dataSegment(offset, std::span{bytes.data(), bytes.size()}); +} + +std::string +makeLoopWat(std::string_view imports, std::string_view data, std::string_view body, int count) +{ + static constexpr auto kTemplate = R"wat((module +{} + (memory (export "memory") 1) +{} + (func (export "escrow_finish") (result i32) + (local $i i32) + (local $r i32) + (local.set $i (i32.const {})) + (block $done + (loop $again + (br_if $done (i32.eqz (local.get $i))) + (local.set $r {}) + (local.set $i (i32.sub (local.get $i) (i32.const 1))) + (br $again))) + (local.get $r))) +)wat"; + + return std::format(kTemplate, imports, data, count, body); +} + +Timing +timeRun(HostFunctions& host, Bytes const& wasm) +{ + auto const start = std::chrono::steady_clock::now(); + auto outcome = runEscrowWasm(wasm, host, kBenchGas); + auto const elapsed = std::chrono::steady_clock::now() - start; + + benchmark::DoNotOptimize(outcome); + return { + .seconds = std::chrono::duration(elapsed).count(), + .gas = outcome.has_value() ? outcome->cost : std::int64_t{0}}; +} + +StageTimer::StageTimer(benchmark::State& state, std::int64_t moduleBytes) + : state_{state}, moduleBytes_{moduleBytes} +{ +} + +void +StageTimer::add(double seconds) +{ + state_.SetIterationTime(seconds); + total_ += seconds; + sumSquares_ += seconds * seconds; + ++rounds_; +} + +void +StageTimer::report() +{ + if (rounds_ == 0) + { + return; + } + + auto const count = static_cast(rounds_); + auto const mean = total_ / count; + auto const variance = std::max(0.0, (sumSquares_ / count) - (mean * mean)); + auto const spread = mean > 0.0 ? std::sqrt(variance) / mean : 0.0; + + auto const& calibration = Calibration::instance(); + auto const perGas = calibration.secondsPerGas(); + auto const equivalent = perGas > 0.0 ? mean / perGas : 0.0; + + state_.counters["ns_per_op"] = mean * 1e9; + // What this stage would cost if it were charged at the rate the guest inside it is charged at. + // It is not charged, which is the point: this puts an unpriced stage in the host-function + // table's units. + state_.counters["gas_equivalent"] = equivalent; + + if (moduleBytes_ > 0) + { + state_.counters["module_bytes"] = static_cast(moduleBytes_); + // An average over the whole operation, not the marginal rate: it carries the case's fixed + // cost, so it overestimates and falls toward the true slope as the sweep grows. + state_.counters["gas_per_byte"] = equivalent / static_cast(moduleBytes_); + } + + // `gas_equivalent` divides by `secondsPerGas`, so the divisor's uncertainty is in every number + // here too. + auto const caseStdErr = spread / std::sqrt(count); + auto const perGasErr = calibration.secondsPerGasRelStdErr(); + auto const totalErr = std::sqrt((caseStdErr * caseStdErr) + (perGasErr * perGasErr)); + state_.counters["rel_error"] = totalErr; + state_.counters["unreliable"] = totalErr > kMaxRelativeSpread ? 1 : 0; +} + +void +benchmarkPreflight(benchmark::State& state, Bytes const& wasm, bool expectAccepted, bool sizeSweep) +{ + (void)Calibration::instance(); + + // Discarded: the reject case refuses on every iteration, and a real sink would put string + // formatting and I/O inside the measurement. + auto const journal = beast::Journal{beast::Journal::getNullSink()}; + + if (isTesSuccess(preflightEscrowWasm(wasm, journal)) != expectAccepted) + { + state.SkipWithError( + expectAccepted + ? "the module was refused; the case would be measuring the reject path" + : "the module was accepted; the case would be measuring the accept path"); + return; + } + + StageTimer timer{state, sizeSweep ? static_cast(wasm.size()) : 0}; + for (auto _ : state) + { + auto const start = std::chrono::steady_clock::now(); + auto verdict = preflightEscrowWasm(wasm, journal); + auto const elapsed = std::chrono::steady_clock::now() - start; + + benchmark::DoNotOptimize(verdict); + timer.add(std::chrono::duration(elapsed).count()); + } + timer.report(); +} + +namespace { + +// Seconds of wall time one unit of gas buys on this machine. +// +// The estimator must be the *same* one the cases use — a mean, with the same clamp at zero. Since +// `implied_gas = secondsPerCall / secondsPerGas`, any difference between how divisor and dividend +// are estimated lands in every reported number: calibrating with a best-of while measuring with a +// mean once biased the whole report +40%. +// +// `guestInstruction` in Crossing.cpp is the check that this holds — it runs this exact loop body. +double +measureSecondsPerGas(double& relativeStandardError) +{ + // A couple of guest instructions, no memory traffic, nothing the engine can fold away. + static constexpr auto kBody = std::string_view{"(i32.add (local.get $r) (i32.const 1))"}; + auto const busy = assembleWat(makeLoopWat("", "", kBody, kCallsPerRun)); + auto const idle = assembleWat(makeLoopWat("", "", kBody, 0)); + + auto fixture = WasmLedger{}; + + // Warm up, so the first-run penalty does not land on one side of the subtraction. + for (auto i = 0U; i < 8; ++i) + { + timeRun(*fixture.makeHost(), busy); + timeRun(*fixture.makeHost(), idle); + } + + auto total = 0.0; + auto sumSquares = 0.0; + // Fuel is exact and deterministic, so any pair gives the same delta. + auto gasDelta = std::int64_t{1}; + for (auto i = 0; i < kCalibrationPairs; ++i) + { + auto hotHost = fixture.makeHost(); + auto const hot = timeRun(*hotHost, busy); + auto coldHost = fixture.makeHost(); + auto const cold = timeRun(*coldHost, idle); + + auto const delta = std::max(0.0, hot.seconds - cold.seconds); + total += delta; + sumSquares += delta * delta; + gasDelta = std::max(std::int64_t{1}, hot.gas - cold.gas); + } + + auto const mean = total / kCalibrationPairs; + auto const variance = std::max(0.0, (sumSquares / kCalibrationPairs) - (mean * mean)); + relativeStandardError = mean > 0.0 ? std::sqrt(variance / kCalibrationPairs) / mean : 0.0; + + return mean / static_cast(gasDelta); +} + +// The crossing, in gas: `ldgr_index` through the VM minus `ldgr_index` called directly. +// +// Both halves are means, for the reason above: the VM half has to match `benchmarkThroughVm`'s +// estimator and the impl half `benchmarkImpl`'s. `secondsPerGas` is passed in rather than +// re-measured so it comes from the same snapshot. +double +measureCrossingFloorGas(double secondsPerGas, double& relativeStandardError) +{ + static constexpr std::string_view kImport = + R"( (import "host_lib" "ldgr_index" (func $ldgr_index (param i32 i32) (result i32))) +)"; + static constexpr std::string_view kBody = "(call $ldgr_index (i32.const 0) (i32.const 4))"; + + auto const loaded = assembleWat(makeLoopWat(kImport, "", kBody, kCallsPerRun)); + auto const baseline = assembleWat(makeLoopWat(kImport, "", kBody, 0)); + + auto fixture = WasmLedger{}; + + auto vmTotal = 0.0; + auto vmSquares = 0.0; + auto guestOverheadGas = 0.0; + for (auto i = 0; i < kBenchIterations; ++i) + { + auto hotHost = fixture.makeHost(); + auto const hot = timeRun(*hotHost, loaded); + auto coldHost = fixture.makeHost(); + auto const cold = timeRun(*coldHost, baseline); + + auto const perCall = std::max(0.0, hot.seconds - cold.seconds) / kCallsPerRun; + vmTotal += perCall; + vmSquares += perCall * perCall; + // Exact, from the fuel meter: what the guest burned per call beyond the call itself. + guestOverheadGas = + (static_cast(hot.gas - cold.gas) / kCallsPerRun) - declaredGas("ldgr_index"); + } + auto const vmSeconds = vmTotal / kBenchIterations; + + // The impl side is the same call without the VM. Subtracting it leaves the crossing. + auto implTotal = 0.0; + auto implSquares = 0.0; + auto host = fixture.makeHost(); + for (auto i = 0; i < kBenchIterations; ++i) + { + auto const start = std::chrono::steady_clock::now(); + for (auto c = 0U; c < kCallsPerRun; ++c) + { + auto result = host->getLedgerSqn(); + benchmark::DoNotOptimize(result); + } + auto const elapsed = std::chrono::steady_clock::now() - start; + + auto const perCall = std::chrono::duration(elapsed).count() / kCallsPerRun; + implTotal += perCall; + implSquares += perCall * perCall; + } + auto const implSeconds = implTotal / kBenchIterations; + + if (secondsPerGas <= 0.0) + { + return 0.0; + } + // Take the guest's loop bookkeeping off here too: `report` removes it from every `ThroughVm` + // number, so leaving it in would make the two routes to one price disagree by that amount. + auto const crossing = std::max(0.0, vmSeconds - implSeconds) / secondsPerGas; + auto const floor = std::max(0.0, crossing - std::max(0.0, guestOverheadGas)); + + // Relative to the *difference*, not to either half: both contribute their error, and the + // denominator is what survives the subtraction. Not divided by `secondsPerGas` — that error is + // common-mode with the rest of `suggested_gas` and is applied once, to the sum, in `report`. + auto const vmVariance = std::max(0.0, (vmSquares / kBenchIterations) - (vmSeconds * vmSeconds)); + auto const implVariance = + std::max(0.0, (implSquares / kBenchIterations) - (implSeconds * implSeconds)); + auto const vmStdErr = std::sqrt(vmVariance / kBenchIterations); + auto const implStdErr = std::sqrt(implVariance / kBenchIterations); + + auto const crossingSeconds = vmSeconds - implSeconds; + auto const crossingStdErr = std::sqrt((vmStdErr * vmStdErr) + (implStdErr * implStdErr)); + relativeStandardError = crossingSeconds > 0.0 ? crossingStdErr / crossingSeconds : 0.0; + + return floor; +} + +} // namespace + +Calibration const& +Calibration::instance() +{ + static Calibration const kValue; + return kValue; +} + +Calibration::Calibration() + : secondsPerGas_{measureSecondsPerGas(secondsPerGasRelStdErr_)} + , crossingFloorGas_{measureCrossingFloorGas(secondsPerGas_, crossingFloorRelStdErr_)} +{ +} + +double +declaredGas(std::string_view wasmName) +{ + return static_cast( + rs::wasm_testkit::host_function_gas(rust::Str{wasmName.data(), wasmName.size()})); +} + +void +report( + benchmark::State& state, + double secondsPerCall, + double chargedGas, + double guestOverheadGas, + double relativeSpread, + std::int64_t rounds, + std::string_view wasmName, + bool throughVm) +{ + auto const& calibration = Calibration::instance(); + auto const perGas = calibration.secondsPerGas(); + auto const measured = perGas > 0.0 ? secondsPerCall / perGas : 0.0; + + // The timed number covers the host call *and* whatever the guest ran around it. + // `guestOverheadGas` is exact, so taking it off removes a bias rather than trading estimates. + auto const implied = std::max(0.0, measured - guestOverheadGas); + auto const suggested = throughVm ? implied : implied + calibration.crossingFloorGas(); + + state.counters["implied_gas"] = implied; + state.counters["ns_per_call"] = secondsPerCall * 1e9; + state.counters["charged_gas"] = chargedGas; + + if (wasmName.empty()) + { + return; + } + + auto const declared = declaredGas(wasmName); + state.counters["host_function_gas"] = declared; + state.counters["suggested_gas"] = suggested; + // Below 1 is the direction that matters: an underpriced call is one a contract buys too + // cheaply. + state.counters["price_ratio"] = suggested > 0.0 ? declared / suggested : 0.0; + + // Uncertainty **of `suggested_gas`**, not of `implied_gas` — different numbers once the floor + // is added. `implied` and the floor are independent timings, so their absolute errors add in + // quadrature over the sum; but both divide by `secondsPerGas`, so that error is common-mode and + // applies once to the total. Adding it per-term would count it twice. + // + // For `ThroughVm` the floor term is zero and `suggested == implied`, so this reduces exactly to + // the plain `sqrt(caseErr² + perGasErr²)`. Only `Impl` cases move — and for a cheap one the + // floor is most of `suggested_gas`, so an error bar describing `implied` alone described + // little. + auto const caseStdErr = + rounds > 0 ? relativeSpread / std::sqrt(static_cast(rounds)) : relativeSpread; + + auto const impliedErr = implied * caseStdErr; + auto const floorErr = + throughVm ? 0.0 : calibration.crossingFloorGas() * calibration.crossingFloorRelStdErr(); + auto const independentErr = suggested > 0.0 + ? std::sqrt((impliedErr * impliedErr) + (floorErr * floorErr)) / suggested + : caseStdErr; + + auto const perGasErr = calibration.secondsPerGasRelStdErr(); + auto const totalErr = std::sqrt((independentErr * independentErr) + (perGasErr * perGasErr)); + state.counters["rel_error"] = totalErr; + + // A call whose own cost is small next to the crossing is read off the difference of two nearly + // equal numbers, so its `suggested_gas` is scatter rather than signal. + auto const floor = calibration.crossingFloorGas(); + state.counters["unreliable"] = + (totalErr > kMaxRelativeSpread || (floor > 0.0 && suggested < floor)) ? 1 : 0; +} + +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/WasmBench.h b/src/benchmarks/libxrpl/wasm/WasmBench.h new file mode 100644 index 0000000000..98f0921be7 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/WasmBench.h @@ -0,0 +1,369 @@ +#pragma once + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// The gas-calibration harness. What the numbers mean and how to read a report are in ../README.md. + +namespace xrpl::test::bench { + +// Enough that a benchmark loop never ends early; running out would measure something shorter. +inline constexpr std::int64_t kBenchGas = 2'000'000'000; + +// Host calls per run: enough that the per-call cost dominates the baseline subtraction's residue. +inline constexpr std::int32_t kCallsPerRun = 1000; + +// Timed iterations per case. Pinned because automatic sizing cannot work here: a case reports a +// residue of nanoseconds while the iteration producing it ran two contracts and cost milliseconds, +// so sizing would ask for millions. +inline constexpr std::int32_t kBenchIterations = 50; + +// Pairs the one-off calibration averages. Higher than `kBenchIterations` because `secondsPerGas` +// divides every reported number, and a bare wasm loop is cheap to repeat. +inline constexpr std::int32_t kCalibrationPairs = 400; + +// Above this relative uncertainty, `suggested_gas` is reported as unreliable. +inline constexpr double kMaxRelativeSpread = 0.25; + +// `TRANSFER_LIMIT_BYTES` in crates/xrpl-wasm-vm/src/vm.rs: what a run may write into guest memory +// before `charge_transfer` starts refusing calls. +inline constexpr std::int64_t kTransferLimitBytes = 1 << 20; + +// How many calls a run can afford, given the bytes each has the host **write into guest memory**. +// Output direction only — what the guest passes in is borrowed, and costs nothing against the +// budget. Never raises the count to meet a floor; a case that cannot afford one call fails loudly. +int +callsWithinTransferBudget(std::int64_t bytesWrittenPerCall); + +// One run of a contract: how long it took, and what the engine charged it. +struct Timing +{ + double seconds{}; + std::int64_t gas{}; +}; + +// A `(data ...)` segment placing `bytes` at `offset` in guest memory, so the timed loop measures +// the host call rather than the guest arranging its arguments. `watEscaped` in WasmRun.h says why +// zeroed memory will not do. +std::string +dataSegment(int offset, std::span bytes); + +std::string +dataSegment(int offset, Bytes const& bytes); + +// A contract that runs `body` `count` times and returns the last result. +std::string +makeLoopWat(std::string_view imports, std::string_view data, std::string_view body, int count); + +// Run pre-assembled `wasm` once through the real VM, reporting wall time and gas. +Timing +timeRun(HostFunctions& host, Bytes const& wasm); + +// What this machine costs, measured once and shared by every case: two cases pricing one function +// two ways (`Impl` + crossing floor, versus `ThroughVm`) must divide by the *same* `secondsPerGas` +// or they disagree for reasons unrelated to the function. +class Calibration +{ +public: + static Calibration const& + instance(); + + // Seconds of wall time one unit of gas buys here. + [[nodiscard]] double + secondsPerGas() const + { + return secondsPerGas_; + } + + // The gas a host call costs before it does anything: region decode, bounds checks, the cxx hop. + [[nodiscard]] double + crossingFloorGas() const + { + return crossingFloorGas_; + } + + // Propagated into every case's `rel_error`, which is what lets one snapshot stay shared: + // `--benchmark_repetitions` resamples per-case timings but never this divisor. + [[nodiscard]] double + secondsPerGasRelStdErr() const + { + return secondsPerGasRelStdErr_; + } + + // An additive term in every `Impl` case's `suggested_gas`, and most of the cheap ones. + [[nodiscard]] double + crossingFloorRelStdErr() const + { + return crossingFloorRelStdErr_; + } + +private: + Calibration(); + + double secondsPerGasRelStdErr_{}; + double crossingFloorRelStdErr_{}; + double secondsPerGas_{}; + double crossingFloorGas_{}; +}; + +// What the gas table declares for a host function, by guest import name, read through the +// `wasm_testkit` bridge so it cannot drift. +double +declaredGas(std::string_view wasmName); + +// Attach the calibration counters to a finished case. +// +// `guestOverheadGas` is fuel the guest burned around the call — loop bookkeeping and the +// `i32.const`s pushing arguments. From the fuel meter, so it is exact. Zero for `Impl` cases. +void +report( + benchmark::State& state, + double secondsPerCall, + double chargedGas, + double guestOverheadGas, + double relativeSpread, + std::int64_t rounds, + std::string_view wasmName, + bool throughVm); + +// Accumulates one whole-operation case and turns it into counters. +// +// The two harnesses below subtract setup away, amortizing over `kCallsPerRun` calls against a +// baseline. Here that is inverted: setup is the subject, timed whole, nothing amortized. +class StageTimer +{ +public: + // Pass zero for `moduleBytes` unless the case belongs to a sweep that *varies* module size — + // the per-byte counter it enables is an average over the whole operation, meaningless where the + // module is constant. + StageTimer(benchmark::State& state, std::int64_t moduleBytes); + + void + add(double seconds); + + // Attach the counters. Call once, after the loop. + void + report(); + +private: + benchmark::State& state_; + std::int64_t moduleBytes_{}; + double total_{}; + double sumSquares_{}; + std::int64_t rounds_{}; +}; + +// Measure `preflightEscrowWasm`: compile, then the walk over the module's imports and exports. +// +// `expectAccepted` is what the module *should* do. A refused module stops at the first fault and is +// far cheaper, so a case that silently flipped verdict would report a confident number for an +// operation it never performed. +void +benchmarkPreflight( + benchmark::State& state, + Bytes const& wasm, + bool expectAccepted = true, + bool sizeSweep = false); + +// Measure a whole `runEscrowWasm` — every stage, unamortized. +template +void +benchmarkRun(benchmark::State& state, Bytes const& wasm, SetUp&& setUp, bool sizeSweep = false) +{ + // Force the calibration and the engine's lazy construction before the clock starts, so the + // first case does not absorb them into its own first iteration. + [[maybe_unused]] auto const& calibration = Calibration::instance(); + + auto probe = setUp(); + if (auto const check = runEscrowWasm(wasm, *probe, kBenchGas); !check.has_value()) + { + state.SkipWithError("the benchmarked contract did not run to completion"); + return; + } + + auto timer = StageTimer{state, sizeSweep ? static_cast(wasm.size()) : 0}; + for (auto _ : state) + { + auto host = setUp(); + timer.add(timeRun(*host, wasm).seconds); + } + timer.report(); +} + +// Measure a host function through the whole stack — guest, VM, marshalling, real impl, real ledger +// — with everything but the host calls subtracted away. +template +void +benchmarkThroughVm( + benchmark::State& state, + std::string_view wasmName, + std::string_view imports, + std::string_view data, + std::string_view body, + SetUp&& setUp, + int calls = kCallsPerRun) +{ + auto const loaded = assembleWat(makeLoopWat(imports, data, body, calls)); + auto const baseline = assembleWat(makeLoopWat(imports, data, body, 0)); + + // A host serves exactly one run — `runEscrowWasm` asserts it was handed a clean one + // (`checkSelf` in WasmVM.cpp). Hence `setUp` being a factory rather than a host. + auto probe = setUp(); + + // A soft host error still completes the run, so require both that it completed and that the + // last host call returned a non-negative result, which every body leaves in `$r`. + auto const check = runEscrowWasm(loaded, *probe, kBenchGas); + if (!check.has_value()) + { + state.SkipWithError("the benchmarked contract did not run to completion"); + return; + } + if (check->result < 0) + { + state.SkipWithError( + "the benchmarked host call returned error code " + std::to_string(check->result) + + "; the case would be measuring the rejection path, not the work"); + return; + } + + auto totalSeconds = 0.0; + auto sumSquares = 0.0; + auto totalGas = 0.0; + auto rounds = std::int64_t{0}; + for (auto _ : state) + { + auto hotHost = setUp(); + auto const hot = timeRun(*hotHost, loaded); + auto coldHost = setUp(); + auto const cold = timeRun(*coldHost, baseline); + + // Clamped: on a noisy machine a pair can invert, and a negative iteration time would make + // Google Benchmark's statistics meaningless. + auto const perCall = std::max(0.0, hot.seconds - cold.seconds) / calls; + state.SetIterationTime(perCall); + + totalSeconds += perCall; + sumSquares += perCall * perCall; + totalGas += static_cast(hot.gas - cold.gas) / calls; + ++rounds; + } + + if (rounds > 0) + { + auto const meanSeconds = totalSeconds / rounds; + auto const variance = std::max(0.0, (sumSquares / rounds) - (meanSeconds * meanSeconds)); + auto const spread = meanSeconds > 0.0 ? std::sqrt(variance) / meanSeconds : 0.0; + + // Zero for the empty-name case — `guestInstruction`, which prices no host function. There + // is no host call to separate scaffolding *from*, and subtracting the full charge would + // leave `implied_gas = measured - charged`, ~0 by construction: it would turn the harness's + // one self-test into a tautology that cannot fail. + auto const chargedPerCall = totalGas / rounds; + auto const overhead = wasmName.empty() ? 0.0 : chargedPerCall - declaredGas(wasmName); + + report( + state, + meanSeconds, + chargedPerCall, + std::max(0.0, overhead), + spread, + rounds, + wasmName, + true); + } +} + +// Measure a host function's impl alone — no guest, no VM, no marshalling. Against the `ThroughVm` +// case for the same function, the difference is what crossing the boundary costs. +template +void +benchmarkImpl(benchmark::State& state, std::string_view wasmName, SetUp&& setUp, Call&& call) +{ + auto host = setUp(); + + // A call that errors returns early and is far cheaper than one that works, so a subtly wrong + // argument yields a confident and always *too low* price. Probed either side of the loop rather + // than inside it, where the branch would land in the measurement: *before* catches wrong + // arguments, *after* catches a call that stopped working once the loop exhausted something. + // + // The `requires` skips host functions that answer nothing (`trace`) or answer a bare value. + auto const checkSucceeds = [&](char const* when) { + if constexpr (requires { call(*host).has_value(); }) + { + if (auto const probe = call(*host); !probe.has_value()) + { + state.SkipWithError( + std::string{"the benchmarked host call returned error code "} + + std::to_string(static_cast(probe.error())) + " " + when + + " the timed loop; the case would be measuring the rejection path"); + return false; + } + } + return true; + }; + + if (!checkSucceeds("before")) + { + return; + } + + auto totalSeconds = 0.0; + auto sumSquares = 0.0; + auto rounds = std::int64_t{0}; + for (auto _ : state) + { + auto const start = std::chrono::steady_clock::now(); + for (int i = 0; i < kCallsPerRun; ++i) + { + // `trace` answers nothing, so `ClobberMemory` stands in for `DoNotOptimize`. + if constexpr (std::is_void_v) + { + call(*host); + benchmark::ClobberMemory(); + } + else + { + auto result = call(*host); + benchmark::DoNotOptimize(result); + } + } + auto const elapsed = std::chrono::steady_clock::now() - start; + + auto const perCall = std::chrono::duration(elapsed).count() / kCallsPerRun; + state.SetIterationTime(perCall); + + totalSeconds += perCall; + sumSquares += perCall * perCall; + ++rounds; + } + + if (!checkSucceeds("after")) + { + return; + } + + if (rounds > 0) + { + auto const meanSeconds = totalSeconds / rounds; + auto const variance = std::max(0.0, (sumSquares / rounds) - (meanSeconds * meanSeconds)); + auto const spread = meanSeconds > 0.0 ? std::sqrt(variance) / meanSeconds : 0.0; + + // Nothing charged and no guest scaffolding; `report` adds the crossing back in. + report(state, meanSeconds, 0.0, 0.0, spread, rounds, wasmName, false); + } +} + +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/AccountKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/AccountKeylet.cpp new file mode 100644 index 0000000000..5bd2c7c2e8 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/AccountKeylet.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +accountKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"accountroot_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.accountKeylet(Fixtures::instance().alice().id()); }); +} +BENCHMARK(accountKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/AmmKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/AmmKeylet.cpp new file mode 100644 index 0000000000..4cefc1c553 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/AmmKeylet.cpp @@ -0,0 +1,31 @@ +#include +#include +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +ammKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"amm_id"}; + + auto const usd = Asset{Issue{toCurrency("USD"), Fixtures::instance().alice().id()}}; + auto const xrp = Asset{xrpIssue()}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [&usd, &xrp](auto& host) { return host.ammKeylet(usd, xrp); }); +} +BENCHMARK(ammKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/BaseFee.cpp b/src/benchmarks/libxrpl/wasm/host_functions/BaseFee.cpp new file mode 100644 index 0000000000..b304beeb65 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/BaseFee.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +baseFeeImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"base_fee"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getBaseFee(); }); +} +BENCHMARK(baseFeeImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/CacheLedgerObj.cpp b/src/benchmarks/libxrpl/wasm/host_functions/CacheLedgerObj.cpp new file mode 100644 index 0000000000..b027396d1e --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/CacheLedgerObj.cpp @@ -0,0 +1,28 @@ +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +cacheLedgerObjImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"cache_le"}; + + auto const key = keylet::account(Fixtures::instance().alice().id()).key; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [&key](auto& host) { return host.cacheLedgerObj(key, 1); }); +} +BENCHMARK(cacheLedgerObjImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/CheckKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/CheckKeylet.cpp new file mode 100644 index 0000000000..24af99a6ac --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/CheckKeylet.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +checkKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"check_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.checkKeylet(Fixtures::instance().alice().id(), Fixtures::kSeq); + }); +} +BENCHMARK(checkKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/CheckSignature.cpp b/src/benchmarks/libxrpl/wasm/host_functions/CheckSignature.cpp new file mode 100644 index 0000000000..af7e333bc7 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/CheckSignature.cpp @@ -0,0 +1,63 @@ +#include + +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "check_sig"; + +constexpr std::string_view kImport = + R"( (import "host_lib" "check_sig" (func $check_sig (param i32 i32 i32 i32 i32 i32) (result i32))) +)"; + +constexpr std::int32_t kMessageOffset = 0; +constexpr std::int32_t kSignatureOffset = 256; +constexpr std::int32_t kPubkeyOffset = 512; + +void +checkSignatureThroughVm(benchmark::State& state) +{ + auto const& m = Fixtures::instance().signedMessage(); + static auto const kData = dataSegment(kMessageOffset, m.message) + + dataSegment(kSignatureOffset, m.signature) + dataSegment(kPubkeyOffset, m.publicKey); + static auto const kBody = std::format( + "(call $check_sig (i32.const {}) (i32.const {}) (i32.const {}) (i32.const {}) " + "(i32.const {}) (i32.const {}))", + kMessageOffset, + m.message.size(), + kSignatureOffset, + m.signature.size(), + kPubkeyOffset, + m.publicKey.size()); + + benchmarkThroughVm( + state, kWasmName, kImport, kData, kBody, [] { return Fixtures::instance().host(); }); +} +BENCHMARK(checkSignatureThroughVm)->UseManualTime()->Iterations(kBenchIterations); + +void +checkSignatureImpl(benchmark::State& state) +{ + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + auto const& m = Fixtures::instance().signedMessage(); + return host.checkSignature( + Slice{m.message.data(), m.message.size()}, + Slice{m.signature.data(), m.signature.size()}, + Slice{m.publicKey.data(), m.publicKey.size()}); + }); +} +BENCHMARK(checkSignatureImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/CredentialKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/CredentialKeylet.cpp new file mode 100644 index 0000000000..219cc9051c --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/CredentialKeylet.cpp @@ -0,0 +1,32 @@ +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +credentialKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"credential_id"}; + static constexpr auto kType = std::string_view{"termsandconditions"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.credentialKeylet( + Fixtures::instance().alice().id(), + Fixtures::instance().bob().id(), + Slice{kType.data(), kType.size()}); + }); +} +BENCHMARK(credentialKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjArrayLen.cpp b/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjArrayLen.cpp new file mode 100644 index 0000000000..4678749e84 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjArrayLen.cpp @@ -0,0 +1,26 @@ +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +currentLedgerObjArrayLenImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"home_le_arr_len"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().signerListHost(); }, + [](auto& host) { return host.getCurrentLedgerObjArrayLen(sfSignerEntries); }); +} +BENCHMARK(currentLedgerObjArrayLenImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjField.cpp b/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjField.cpp new file mode 100644 index 0000000000..5a441ffa42 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjField.cpp @@ -0,0 +1,41 @@ +#include + +#include +#include +#include + +#include +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "home_le_field"; +constexpr std::string_view kImport = + R"( (import "host_lib" "home_le_field" (func $home_le_field (param i32 i32 i32) (result i32))) +)"; + +void +currentLedgerObjFieldThroughVm(benchmark::State& state) +{ + static auto const kBody = std::format( + "(call $home_le_field (i32.const {}) (i32.const 0) (i32.const 32))", sfAccount.getCode()); + + benchmarkThroughVm( + state, kWasmName, kImport, "", kBody, [] { return Fixtures::instance().escrowHost(); }); +} +BENCHMARK(currentLedgerObjFieldThroughVm)->UseManualTime()->Iterations(kBenchIterations); + +void +currentLedgerObjFieldImpl(benchmark::State& state) +{ + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().escrowHost(); }, + [](auto& host) { return host.getCurrentLedgerObjField(sfAccount); }); +} +BENCHMARK(currentLedgerObjFieldImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjNestedArrayLen.cpp b/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjNestedArrayLen.cpp new file mode 100644 index 0000000000..e2c5d0ab73 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjNestedArrayLen.cpp @@ -0,0 +1,30 @@ +#include +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +currentLedgerObjNestedArrayLenImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"home_le_inner_arr_len"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().signerListHost(); }, + [](auto& host) { + return host.getCurrentLedgerObjNestedArrayLen( + FieldLocator{{sfSignerEntries.getCode()}}); + }); +} +BENCHMARK(currentLedgerObjNestedArrayLenImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjNestedField.cpp b/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjNestedField.cpp new file mode 100644 index 0000000000..fd0a7f96ed --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/CurrentLedgerObjNestedField.cpp @@ -0,0 +1,29 @@ +#include +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +currentLedgerObjNestedFieldImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"home_le_inner"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.getCurrentLedgerObjNestedField(FieldLocator{{sfAccount.getCode()}}); + }); +} +BENCHMARK(currentLedgerObjNestedFieldImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/DelegateKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/DelegateKeylet.cpp new file mode 100644 index 0000000000..6a66db420a --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/DelegateKeylet.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +delegateKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"delegate_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.delegateKeylet( + Fixtures::instance().alice().id(), Fixtures::instance().bob().id()); + }); +} +BENCHMARK(delegateKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/DepositPreauthKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/DepositPreauthKeylet.cpp new file mode 100644 index 0000000000..2931669c34 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/DepositPreauthKeylet.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +depositPreauthKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"deposit_preauth_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.depositPreauthKeylet( + Fixtures::instance().alice().id(), Fixtures::instance().bob().id()); + }); +} +BENCHMARK(depositPreauthKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/DidKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/DidKeylet.cpp new file mode 100644 index 0000000000..6402bf425a --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/DidKeylet.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +didKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"did_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.didKeylet(Fixtures::instance().alice().id()); }); +} +BENCHMARK(didKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/EscrowKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/EscrowKeylet.cpp new file mode 100644 index 0000000000..369388fb19 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/EscrowKeylet.cpp @@ -0,0 +1,55 @@ +#include + +#include +#include +#include +#include + +#include +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "escrow_id"; + +constexpr std::string_view kImport = + R"( (import "host_lib" "escrow_id" (func $escrow_id (param i32 i32 i32 i32 i32 i32) (result i32))) +)"; +constexpr std::string_view kBody = + "(call $escrow_id (i32.const 0) (i32.const 20) (i32.const 32) (i32.const 4) " + "(i32.const 64) (i32.const 32))"; + +void +escrowKeyletThroughVm(benchmark::State& state) +{ + static auto const kData = [] { + auto seq = Bytes(4); + for (auto i = 0U; i < 4; ++i) + { + seq[i] = static_cast((Fixtures::kSeq >> (8 * i)) & 0xFF); + } + return dataSegment(0, WasmLedger::toBytes(Fixtures::instance().alice().id())) + + dataSegment(32, seq); + }(); + + benchmarkThroughVm( + state, kWasmName, kImport, kData, kBody, [] { return Fixtures::instance().host(); }); +} +BENCHMARK(escrowKeyletThroughVm)->UseManualTime()->Iterations(kBenchIterations); + +void +escrowKeyletImpl(benchmark::State& state) +{ + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.escrowKeylet(Fixtures::instance().alice().id(), Fixtures::kSeq); + }); +} +BENCHMARK(escrowKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatAdd.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatAdd.cpp new file mode 100644 index 0000000000..e5fb2360f3 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatAdd.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "float_add"; + +constexpr std::string_view kImport = + R"( (import "host_lib" "float_add" (func $float_add (param i32 i32 i32 i32 i32 i32 i32) (result i32))) +)"; + +constexpr std::string_view kBody = + "(call $float_add (i32.const 0) (i32.const 12) (i32.const 16) (i32.const 12) " + "(i32.const 64) (i32.const 12) (i32.const 0))"; + +void +floatAddThroughVm(benchmark::State& state) +{ + static auto const kData = + dataSegment(0, FloatConstants::kPi) + dataSegment(16, FloatConstants::kTwo); + benchmarkThroughVm( + state, kWasmName, kImport, kData, kBody, [] { return Fixtures::instance().host(); }); +} +BENCHMARK(floatAddThroughVm)->UseManualTime()->Iterations(kBenchIterations); + +void +floatAddImpl(benchmark::State& state) +{ + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.floatAdd(Fixtures::floatX(), Fixtures::floatY(), Fixtures::kRoundingMode); + }); +} +BENCHMARK(floatAddImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatCompare.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatCompare.cpp new file mode 100644 index 0000000000..ea6c68c44f --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatCompare.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +floatCompareImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"float_cmp"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.floatCompare(Fixtures::floatX(), Fixtures::floatY()); }); +} +BENCHMARK(floatCompareImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatDivide.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatDivide.cpp new file mode 100644 index 0000000000..bdc802d4bc --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatDivide.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +floatDivideImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"float_div"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.floatDivide( + Fixtures::floatX(), Fixtures::floatY(), Fixtures::kRoundingMode); + }); +} +BENCHMARK(floatDivideImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatFromInt.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatFromInt.cpp new file mode 100644 index 0000000000..5edc05d000 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatFromInt.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +floatFromIntImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"float_from_int"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.floatFromInt(3141592653589793, Fixtures::kRoundingMode); }); +} +BENCHMARK(floatFromIntImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatFromMantExp.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatFromMantExp.cpp new file mode 100644 index 0000000000..6f60b16136 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatFromMantExp.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +floatFromMantExpImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"float_from_mant_exp"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.floatFromMantExp(3141592653589793, -15, Fixtures::kRoundingMode); + }); +} +BENCHMARK(floatFromMantExpImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatFromStAmount.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatFromStAmount.cpp new file mode 100644 index 0000000000..4cca4f48af --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatFromStAmount.cpp @@ -0,0 +1,31 @@ +#include +#include +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +floatFromStAmountImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"float_from_stamount"}; + + auto const amount = + STAmount{Issue{toCurrency("USD"), Fixtures::instance().alice().id()}, 1234567, -3}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [&amount](auto& host) { return host.floatFromSTAmount(amount, Fixtures::kRoundingMode); }); +} +BENCHMARK(floatFromStAmountImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatFromStNumber.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatFromStNumber.cpp new file mode 100644 index 0000000000..b5081550c9 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatFromStNumber.cpp @@ -0,0 +1,30 @@ +#include +#include +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +floatFromStNumberImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"float_from_stnumber"}; + + auto const number = STNumber{sfNumber, Number(3141592653589793, -15)}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [&number](auto& host) { return host.floatFromSTNumber(number, Fixtures::kRoundingMode); }); +} +BENCHMARK(floatFromStNumberImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatFromUint.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatFromUint.cpp new file mode 100644 index 0000000000..ffe04d409f --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatFromUint.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +floatFromUintImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"float_from_uint"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.floatFromUint(3141592653589793u, Fixtures::kRoundingMode); }); +} +BENCHMARK(floatFromUintImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatMultiply.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatMultiply.cpp new file mode 100644 index 0000000000..a2bcbbd06a --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatMultiply.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +floatMultiplyImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"float_mult"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.floatMultiply( + Fixtures::floatX(), Fixtures::floatY(), Fixtures::kRoundingMode); + }); +} +BENCHMARK(floatMultiplyImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatPower.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatPower.cpp new file mode 100644 index 0000000000..81b5134d2e --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatPower.cpp @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "float_pow"; + +constexpr std::string_view kImport = + R"( (import "host_lib" "float_pow" (func $float_pow (param i32 i32 i32 i32 i32 i32) (result i32))) +)"; + +constexpr std::string_view kBody = + "(call $float_pow (i32.const 0) (i32.const 12) (i32.const 7) " + "(i32.const 64) (i32.const 12) (i32.const 0))"; + +void +floatPowerThroughVm(benchmark::State& state) +{ + static auto const kData = dataSegment(0, FloatConstants::kPi); + benchmarkThroughVm( + state, kWasmName, kImport, kData, kBody, [] { return Fixtures::instance().host(); }); +} +BENCHMARK(floatPowerThroughVm)->UseManualTime()->Iterations(kBenchIterations); + +void +floatPowerImpl(benchmark::State& state) +{ + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.floatPower(Fixtures::floatX(), 7, Fixtures::kRoundingMode); }); +} +BENCHMARK(floatPowerImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatSubtract.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatSubtract.cpp new file mode 100644 index 0000000000..644aada775 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatSubtract.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +floatSubtractImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"float_sub"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.floatSubtract( + Fixtures::floatX(), Fixtures::floatY(), Fixtures::kRoundingMode); + }); +} +BENCHMARK(floatSubtractImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatToInt.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatToInt.cpp new file mode 100644 index 0000000000..e8e3179b36 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatToInt.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +floatToIntImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"float_to_int"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.floatToInt(Fixtures::floatX(), Fixtures::kRoundingMode); }); +} +BENCHMARK(floatToIntImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/FloatToMantExp.cpp b/src/benchmarks/libxrpl/wasm/host_functions/FloatToMantExp.cpp new file mode 100644 index 0000000000..50522b5e5c --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/FloatToMantExp.cpp @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "float_to_mant_exp"; + +constexpr std::string_view kImport = + R"( (import "host_lib" "float_to_mant_exp" (func $split (param i32 i32 i32 i32 i32 i32) (result i32))) +)"; +constexpr std::string_view kBody = + "(call $split (i32.const 0) (i32.const 12) (i32.const 64) (i32.const 8) " + "(i32.const 128) (i32.const 4))"; + +void +floatToMantExpThroughVm(benchmark::State& state) +{ + static auto const kData = dataSegment(0, FloatConstants::kPi); + benchmarkThroughVm( + state, kWasmName, kImport, kData, kBody, [] { return Fixtures::instance().host(); }); +} +BENCHMARK(floatToMantExpThroughVm)->UseManualTime()->Iterations(kBenchIterations); + +void +floatToMantExpImpl(benchmark::State& state) +{ + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.floatToMantExp(Fixtures::floatX()); }); +} +BENCHMARK(floatToMantExpImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/GetNFT.cpp b/src/benchmarks/libxrpl/wasm/host_functions/GetNFT.cpp new file mode 100644 index 0000000000..e28addfed0 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/GetNFT.cpp @@ -0,0 +1,34 @@ + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +getNFTImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"nft_uri"}; + + // A really minted token, so the lookup walks a real page rather than failing fast — a + // not-found answer would measure the rejection instead of the work. + static constexpr auto kUri = std::string_view{"ipfs://benchmark"}; + // Its own ledger rather than the shared `Fixtures`: minting mutates state, and the shared + // one is deliberately read-only after construction. + static auto nft = WasmLedger{}; + static auto const kOwner = nft.fund("benchNftOwner"); + static auto const kMinted = mintNft(nft, kOwner, kUri); + + benchmarkImpl( + state, + kWasmName, + [] { return nft.makeHost(); }, + [](auto& host) { return host.getNFT(kOwner.id(), kMinted); }); +} +BENCHMARK(getNFTImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/IsAmendmentEnabled.cpp b/src/benchmarks/libxrpl/wasm/host_functions/IsAmendmentEnabled.cpp new file mode 100644 index 0000000000..3fc49c706c --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/IsAmendmentEnabled.cpp @@ -0,0 +1,54 @@ +#include + +#include +#include +#include + +#include +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "amendment_enabled"; + +std::string const& +benchAmendment() +{ + static auto const kValue = std::string{"TokenEscrow"}; + return kValue; +} + +void +isAmendmentEnabledByIdImpl(benchmark::State& state) +{ + auto const feature = getRegisteredFeature(benchAmendment()); + if (!feature.has_value()) + { + state.SkipWithError("the benchmarked amendment is not registered"); + return; + } + auto const id = *feature; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [&id](auto& host) { return host.isAmendmentEnabled(id); }); +} +BENCHMARK(isAmendmentEnabledByIdImpl)->UseManualTime()->Iterations(kBenchIterations); + +void +isAmendmentEnabledByNameImpl(benchmark::State& state) +{ + // The gap over the id form is precisely what the shared price of 100 asserts does not exist. + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.isAmendmentEnabled(std::string_view{benchAmendment()}); }); +} +BENCHMARK(isAmendmentEnabledByNameImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjArrayLen.cpp b/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjArrayLen.cpp new file mode 100644 index 0000000000..89b14997da --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjArrayLen.cpp @@ -0,0 +1,26 @@ +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +ledgerObjArrayLenImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"le_arr_len"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().cachedSignerListHost(); }, + [](auto& host) { return host.getLedgerObjArrayLen(1, sfSignerEntries); }); +} +BENCHMARK(ledgerObjArrayLenImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjField.cpp b/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjField.cpp new file mode 100644 index 0000000000..2f707b6cb8 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjField.cpp @@ -0,0 +1,26 @@ +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +ledgerObjFieldImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"le_field"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().cachedHost(); }, + [](auto& host) { return host.getLedgerObjField(1, sfAccount); }); +} +BENCHMARK(ledgerObjFieldImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjNestedArrayLen.cpp b/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjNestedArrayLen.cpp new file mode 100644 index 0000000000..b51460e664 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjNestedArrayLen.cpp @@ -0,0 +1,29 @@ +#include +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +ledgerObjNestedArrayLenImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"le_inner_arr_len"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().cachedSignerListHost(); }, + [](auto& host) { + return host.getLedgerObjNestedArrayLen(1, FieldLocator{{sfSignerEntries.getCode()}}); + }); +} +BENCHMARK(ledgerObjNestedArrayLenImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjNestedField.cpp b/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjNestedField.cpp new file mode 100644 index 0000000000..757b3118c5 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/LedgerObjNestedField.cpp @@ -0,0 +1,29 @@ +#include +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +ledgerObjNestedFieldImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"le_inner"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().cachedHost(); }, + [](auto& host) { + return host.getLedgerObjNestedField(1, FieldLocator{{sfAccount.getCode()}}); + }); +} +BENCHMARK(ledgerObjNestedFieldImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/LedgerSqn.cpp b/src/benchmarks/libxrpl/wasm/host_functions/LedgerSqn.cpp new file mode 100644 index 0000000000..130cea3cd2 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/LedgerSqn.cpp @@ -0,0 +1,38 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "ldgr_index"; + +constexpr std::string_view kImport = + R"( (import "host_lib" "ldgr_index" (func $ldgr_index (param i32 i32) (result i32))) +)"; + +void +ledgerSqnThroughVm(benchmark::State& state) +{ + benchmarkThroughVm( + state, kWasmName, kImport, "", "(call $ldgr_index (i32.const 0) (i32.const 4))", [] { + return Fixtures::instance().host(); + }); +} +BENCHMARK(ledgerSqnThroughVm)->UseManualTime()->Iterations(kBenchIterations); + +void +ledgerSqnImpl(benchmark::State& state) +{ + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getLedgerSqn(); }); +} +BENCHMARK(ledgerSqnImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/MptokenIssuanceKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/MptokenIssuanceKeylet.cpp new file mode 100644 index 0000000000..bda4c979be --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/MptokenIssuanceKeylet.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +mptokenIssuanceKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"mpt_issuance_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.mptokenIssuanceKeylet(Fixtures::instance().alice().id(), Fixtures::kSeq); + }); +} +BENCHMARK(mptokenIssuanceKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/MptokenKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/MptokenKeylet.cpp new file mode 100644 index 0000000000..b1e289181d --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/MptokenKeylet.cpp @@ -0,0 +1,31 @@ + +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +mptokenKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"mptoken_id"}; + + auto const mptid = makeMptID(1, Fixtures::instance().alice().id()); + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [&mptid](auto& host) { + return host.mptokenKeylet(mptid, Fixtures::instance().bob().id()); + }); +} +BENCHMARK(mptokenKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/NFTFlags.cpp b/src/benchmarks/libxrpl/wasm/host_functions/NFTFlags.cpp new file mode 100644 index 0000000000..270f8337fa --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/NFTFlags.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +nftFlagsImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"nft_flags"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getNFTFlags(Fixtures::instance().nftId()); }); +} +BENCHMARK(nftFlagsImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/NFTIssuer.cpp b/src/benchmarks/libxrpl/wasm/host_functions/NFTIssuer.cpp new file mode 100644 index 0000000000..bcb960e6ee --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/NFTIssuer.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +nftIssuerImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"nft_issuer"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getNFTIssuer(Fixtures::instance().nftId()); }); +} +BENCHMARK(nftIssuerImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/NFTSequence.cpp b/src/benchmarks/libxrpl/wasm/host_functions/NFTSequence.cpp new file mode 100644 index 0000000000..f30a8d2348 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/NFTSequence.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +nftSequenceImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"nft_serial"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getNFTSequence(Fixtures::instance().nftId()); }); +} +BENCHMARK(nftSequenceImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/NFTTaxon.cpp b/src/benchmarks/libxrpl/wasm/host_functions/NFTTaxon.cpp new file mode 100644 index 0000000000..8a4bc91790 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/NFTTaxon.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +nftTaxonImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"nft_taxon"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getNFTTaxon(Fixtures::instance().nftId()); }); +} +BENCHMARK(nftTaxonImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/NFTTransferFee.cpp b/src/benchmarks/libxrpl/wasm/host_functions/NFTTransferFee.cpp new file mode 100644 index 0000000000..c574ccab9d --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/NFTTransferFee.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +nftTransferFeeImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"nft_xfer_fee"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getNFTTransferFee(Fixtures::instance().nftId()); }); +} +BENCHMARK(nftTransferFeeImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/NftokenOfferKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/NftokenOfferKeylet.cpp new file mode 100644 index 0000000000..46a3b074a8 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/NftokenOfferKeylet.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +nftokenOfferKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"nft_offer_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.nftokenOfferKeylet(Fixtures::instance().alice().id(), Fixtures::kSeq); + }); +} +BENCHMARK(nftokenOfferKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/OfferKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/OfferKeylet.cpp new file mode 100644 index 0000000000..7cd61c2b69 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/OfferKeylet.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +offerKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"offer_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.offerKeylet(Fixtures::instance().alice().id(), Fixtures::kSeq); + }); +} +BENCHMARK(offerKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/OracleKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/OracleKeylet.cpp new file mode 100644 index 0000000000..8a7679322c --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/OracleKeylet.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +oracleKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"oracle_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.oracleKeylet(Fixtures::instance().alice().id(), Fixtures::kSeq); + }); +} +BENCHMARK(oracleKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/ParentLedgerHash.cpp b/src/benchmarks/libxrpl/wasm/host_functions/ParentLedgerHash.cpp new file mode 100644 index 0000000000..8f3210d101 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/ParentLedgerHash.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +parentLedgerHashImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"parent_ldgr_hash"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getParentLedgerHash(); }); +} +BENCHMARK(parentLedgerHashImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/ParentLedgerTime.cpp b/src/benchmarks/libxrpl/wasm/host_functions/ParentLedgerTime.cpp new file mode 100644 index 0000000000..fa800c7520 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/ParentLedgerTime.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +parentLedgerTimeImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"parent_ldgr_time"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getParentLedgerTime(); }); +} +BENCHMARK(parentLedgerTimeImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/PaychannelKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/PaychannelKeylet.cpp new file mode 100644 index 0000000000..0892fdfbde --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/PaychannelKeylet.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +paychannelKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"paychan_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.paychannelKeylet( + Fixtures::instance().alice().id(), Fixtures::instance().bob().id(), Fixtures::kSeq); + }); +} +BENCHMARK(paychannelKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/PermissionedDomainedKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/PermissionedDomainedKeylet.cpp new file mode 100644 index 0000000000..d97d35afba --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/PermissionedDomainedKeylet.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +permissionedDomainKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"permissioned_domain_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.permissionedDomainKeylet(Fixtures::instance().alice().id(), Fixtures::kSeq); + }); +} +BENCHMARK(permissionedDomainKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/Sha512Half.cpp b/src/benchmarks/libxrpl/wasm/host_functions/Sha512Half.cpp new file mode 100644 index 0000000000..0894956d8e --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/Sha512Half.cpp @@ -0,0 +1,69 @@ +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "sha512_half"; + +constexpr std::string_view kImport = + R"( (import "host_lib" "sha512_half" (func $sha512_half (param i32 i32 i32 i32) (result i32))) +)"; + +void +sha512HalfThroughVm(benchmark::State& state) +{ + // Zeroed guest memory is a perfectly good hash input: `sha512_half` validates nothing about + // its bytes, so there is no data segment to seed. + auto const body = std::format( + "(call $sha512_half (i32.const 0) (i32.const {}) (i32.const 8192) (i32.const 32))", + state.range(0)); + + // A hash is 32 bytes back to the guest whatever the input length, and the transfer budget + // counts only what the host writes — so the input sweep does not shrink the call count. + benchmarkThroughVm( + state, + kWasmName, + kImport, + "", + body, + [] { return Fixtures::instance().host(); }, + callsWithinTransferBudget(32)); + state.SetBytesProcessed(state.iterations() * state.range(0)); +} +BENCHMARK(sha512HalfThroughVm) + ->RangeMultiplier(8) + ->Range(8, xrpl::kMaxWasmDataLength) + ->UseManualTime() + ->Iterations(kBenchIterations); + +void +sha512HalfImpl(benchmark::State& state) +{ + auto const data = Bytes(static_cast(state.range(0)), 0x42); + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [&data](auto& host) { + return host.computeSha512HalfHash(Slice{data.data(), data.size()}); + }); + state.SetBytesProcessed(state.iterations() * state.range(0)); +} +BENCHMARK(sha512HalfImpl) + ->RangeMultiplier(8) + ->Range(8, xrpl::kMaxWasmDataLength) + ->UseManualTime() + ->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/SignerListKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/SignerListKeylet.cpp new file mode 100644 index 0000000000..0764bd140c --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/SignerListKeylet.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +signerListKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"signers_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.signerListKeylet(Fixtures::instance().alice().id()); }); +} +BENCHMARK(signerListKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/TicketKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/TicketKeylet.cpp new file mode 100644 index 0000000000..78791a7d2c --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/TicketKeylet.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +ticketKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"ticket_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.ticketKeylet(Fixtures::instance().alice().id(), Fixtures::kSeq); + }); +} +BENCHMARK(ticketKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/Trace.cpp b/src/benchmarks/libxrpl/wasm/host_functions/Trace.cpp new file mode 100644 index 0000000000..c0eec7a2d6 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/Trace.cpp @@ -0,0 +1,40 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "trace"; +constexpr std::string_view kMessage = "benchmark trace message"; +constexpr std::string_view kData = "0123456789abcdef"; + +// The path a validator actually runs: journal pointed at a null sink. +void +traceDisabledImpl(benchmark::State& state) +{ + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.trace(kMessage, kData); }); +} +BENCHMARK(traceDisabledImpl)->UseManualTime()->Iterations(kBenchIterations); + +// The same call against a host whose sink records what it is given. The gap over the case above +// is the cost the flat 30 does not cover. +void +traceEnabledImpl(benchmark::State& state) +{ + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().tracingHost(); }, + [](auto& host) { return host.trace(kMessage, kData); }); +} +BENCHMARK(traceEnabledImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/TrustLineKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/TrustLineKeylet.cpp new file mode 100644 index 0000000000..ffb09dc65c --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/TrustLineKeylet.cpp @@ -0,0 +1,31 @@ +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +trustLineKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"trustline_id"}; + + auto const currency = toCurrency("USD"); + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [¤cy](auto& host) { + return host.trustLineKeylet( + Fixtures::instance().alice().id(), Fixtures::instance().bob().id(), currency); + }); +} +BENCHMARK(trustLineKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/TxArrayLen.cpp b/src/benchmarks/libxrpl/wasm/host_functions/TxArrayLen.cpp new file mode 100644 index 0000000000..a4b1b94811 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/TxArrayLen.cpp @@ -0,0 +1,26 @@ +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +txArrayLenImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"tx_arr_len"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getTxArrayLen(sfMemos); }); +} +BENCHMARK(txArrayLenImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/TxField.cpp b/src/benchmarks/libxrpl/wasm/host_functions/TxField.cpp new file mode 100644 index 0000000000..afe0dcaf8d --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/TxField.cpp @@ -0,0 +1,26 @@ +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +txFieldImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"tx_field"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getTxField(sfAccount); }); +} +BENCHMARK(txFieldImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/TxNestedArrayLen.cpp b/src/benchmarks/libxrpl/wasm/host_functions/TxNestedArrayLen.cpp new file mode 100644 index 0000000000..de7b4d4a4a --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/TxNestedArrayLen.cpp @@ -0,0 +1,27 @@ +#include +#include + +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +txNestedArrayLenImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"tx_inner_arr_len"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getTxNestedArrayLen(FieldLocator{{sfMemos.getCode()}}); }); +} +BENCHMARK(txNestedArrayLenImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/TxNestedField.cpp b/src/benchmarks/libxrpl/wasm/host_functions/TxNestedField.cpp new file mode 100644 index 0000000000..3707a55ee7 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/TxNestedField.cpp @@ -0,0 +1,55 @@ +#include +#include + +#include +#include +#include + +#include +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "tx_inner"; +constexpr std::string_view kImport = + R"( (import "host_lib" "tx_inner" (func $tx_inner (param i32 i32 i32 i32) (result i32))) +)"; +constexpr std::string_view kBody = + "(call $tx_inner (i32.const 0) (i32.const 12) (i32.const 64) (i32.const 64))"; + +void +txNestedFieldThroughVm(benchmark::State& state) +{ + // The locator bytes are seeded rather than stored by the guest, so the loop measures the host + // call and not three `i32.store`s. + static auto const kData = dataSegment(0, [] { + auto bytes = Bytes{}; + for (auto const step : {sfMemos.getCode(), 0, sfMemoData.getCode()}) + { + for (auto i = 0U; i < 4; ++i) + { + bytes.push_back(static_cast((step >> (8 * i)) & 0xFF)); + } + } + return bytes; + }()); + + benchmarkThroughVm( + state, kWasmName, kImport, kData, kBody, [] { return Fixtures::instance().host(); }); +} +BENCHMARK(txNestedFieldThroughVm)->UseManualTime()->Iterations(kBenchIterations); + +void +txNestedFieldImpl(benchmark::State& state) +{ + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { return host.getTxNestedField(Fixtures::memoLocator()); }); +} +BENCHMARK(txNestedFieldImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/UpdateData.cpp b/src/benchmarks/libxrpl/wasm/host_functions/UpdateData.cpp new file mode 100644 index 0000000000..0cc8a19249 --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/UpdateData.cpp @@ -0,0 +1,62 @@ +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test::bench { +namespace { + +constexpr std::string_view kWasmName = "set_data"; +constexpr std::string_view kImport = + R"( (import "host_lib" "set_data" (func $set_data (param i32 i32) (result i32))) +)"; + +void +updateDataThroughVm(benchmark::State& state) +{ + auto const body = std::format("(call $set_data (i32.const 0) (i32.const {}))", state.range(0)); + + benchmarkThroughVm( + state, + kWasmName, + kImport, + "", + body, + [] { return Fixtures::instance().host(); }, + // `set_data` answers a scalar and writes nothing into guest memory, so the + // transfer budget does not constrain it however large the input gets. + callsWithinTransferBudget(0)); + state.SetBytesProcessed(state.iterations() * state.range(0)); +} +BENCHMARK(updateDataThroughVm) + ->RangeMultiplier(4) + ->Range(8, kMaxWasmDataLength) + ->UseManualTime() + ->Iterations(kBenchIterations); + +void +updateDataImpl(benchmark::State& state) +{ + auto const data = Bytes(static_cast(state.range(0)), 0x42); + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [&data](auto& host) { return host.updateData(Slice{data.data(), data.size()}); }); + state.SetBytesProcessed(state.iterations() * state.range(0)); +} +BENCHMARK(updateDataImpl) + ->RangeMultiplier(4) + ->Range(8, kMaxWasmDataLength) + ->UseManualTime() + ->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/benchmarks/libxrpl/wasm/host_functions/VaultKeylet.cpp b/src/benchmarks/libxrpl/wasm/host_functions/VaultKeylet.cpp new file mode 100644 index 0000000000..32b7feabac --- /dev/null +++ b/src/benchmarks/libxrpl/wasm/host_functions/VaultKeylet.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +#include + +namespace xrpl::test::bench { +namespace { + +void +vaultKeyletImpl(benchmark::State& state) +{ + static constexpr auto kWasmName = std::string_view{"vault_id"}; + + benchmarkImpl( + state, + kWasmName, + [] { return Fixtures::instance().host(); }, + [](auto& host) { + return host.vaultKeylet(Fixtures::instance().alice().id(), Fixtures::kSeq); + }); +} +BENCHMARK(vaultKeyletImpl)->UseManualTime()->Iterations(kBenchIterations); + +} // namespace +} // namespace xrpl::test::bench diff --git a/src/test/app/TestHostFunctions.h b/src/test/app/TestHostFunctions.h deleted file mode 100644 index a38e284f40..0000000000 --- a/src/test/app/TestHostFunctions.h +++ /dev/null @@ -1,488 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace xrpl::test { - -class TestLedgerDataProvider : public HostFunctions -{ - jtx::Env& env_; - -public: - TestLedgerDataProvider(jtx::Env& env) : HostFunctions(env.journal), env_(env) - { - } - - [[nodiscard]] std::expected - getLedgerSqn() const override - { - return env_.current()->seq(); - } -}; - -class TestHostFunctions : public HostFunctions -{ -protected: - test::jtx::Env& env_; - AccountID accountID_; - Bytes data_; - -public: - TestHostFunctions(test::jtx::Env& env) : HostFunctions(env.journal), env_(env) - { - accountID_ = env.master.id(); - std::string t = "10000"; - data_ = Bytes{t.begin(), t.end()}; - } - - [[nodiscard]] std::expected - getLedgerSqn() const override - { - return 12345; - } - - [[nodiscard]] std::expected - getParentLedgerTime() const override - { - return 67890; - } - - [[nodiscard]] std::expected - getParentLedgerHash() const override - { - return env_.current()->header().parentHash; - } - - [[nodiscard]] std::expected - getBaseFee() const override - { - return 10; - } - - [[nodiscard]] std::expected - isAmendmentEnabled(uint256 const& amendmentId) const override - { - return 1; - } - - [[nodiscard]] std::expected - isAmendmentEnabled(std::string_view const& amendmentName) const override - { - return 1; - } - - std::expected - cacheLedgerObj(uint256 const& objId, int32_t cacheIdx) override - { - return 1; - } - - [[nodiscard]] std::expected - getTxField(SField const& fname) const override - { - if (fname == sfAccount) - return Bytes(accountID_.begin(), accountID_.end()); - - if (fname == sfFee) - { - int64_t x = 235; - auto const* p = reinterpret_cast(&x); - return Bytes{p, p + sizeof(x)}; - } - - if (fname == sfSequence) - { - auto const x = getLedgerSqn(); - if (!x) - return std::unexpected(x.error()); - std::uint32_t const data = x.value(); - auto const* b = reinterpret_cast(&data); - auto const* e = reinterpret_cast(&data + 1); - return Bytes{b, e}; - } - - return Bytes(); - } - - [[nodiscard]] std::expected - getCurrentLedgerObjField(SField const& fname) const override - { - auto const& sn = fname.getName(); - if (sn == "Destination" || sn == "Account") - return Bytes(accountID_.begin(), accountID_.end()); - if (sn == "Data") - return data_; - if (sn == "FinishAfter") - { - auto t = env_.current()->parentCloseTime().time_since_epoch().count(); - std::string s = std::to_string(t); - return Bytes{s.begin(), s.end()}; - } - - // FieldNotFound is a guest-returnable code (the contract handles a negative result); - // Unimplemented now maps to a fatal Fault::Internal (tecINTERNAL) that stops the run. - return std::unexpected(HostFunctionError::FieldNotFound); - } - - [[nodiscard]] std::expected - getLedgerObjField(int32_t, SField const& fname) const override - { - if (fname == sfBalance) - { - int64_t x = 10'000; - auto const* p = reinterpret_cast(&x); - return Bytes{p, p + sizeof(x)}; - } - - if (fname == sfAccount) - return Bytes(accountID_.begin(), accountID_.end()); - - return data_; - } - - [[nodiscard]] std::expected - getTxNestedField(FieldLocator const& locator) const override - { - if (locator.size() == 1) - { - int32_t const* l = locator.data(); - int32_t const sfield = l[0]; - if (sfield == sfAccount.getCode()) - return Bytes(accountID_.begin(), accountID_.end()); - } - - uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2, - 0x45, 0x9f, 0xa4, 0xa0, 0x34, 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, - 0xfc, 0xee, 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; - return Bytes(&a[0], &a[sizeof(a)]); - } - - [[nodiscard]] std::expected - getCurrentLedgerObjNestedField(FieldLocator const& locator) const override - { - if (locator.size() == 1) - { - int32_t const* l = locator.data(); - int32_t const sfield = l[0]; - if (sfield == sfAccount.getCode()) - return Bytes(accountID_.begin(), accountID_.end()); - } - - uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2, - 0x45, 0x9f, 0xa4, 0xa0, 0x34, 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, - 0xfc, 0xee, 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; - return Bytes(&a[0], &a[sizeof(a)]); - } - - [[nodiscard]] std::expected - getLedgerObjNestedField(int32_t cacheIdx, FieldLocator const& locator) const override - { - if (locator.size() == 1) - { - int32_t const* l = locator.data(); - int32_t const sfield = l[0]; - if (sfield == sfAccount.getCode()) - return Bytes(accountID_.begin(), accountID_.end()); - } - - uint8_t const a[] = {0x2b, 0x6a, 0x23, 0x2a, 0xa4, 0xc4, 0xbe, 0x41, 0xbf, 0x49, 0xd2, - 0x45, 0x9f, 0xa4, 0xa0, 0x34, 0x7e, 0x1b, 0x54, 0x3a, 0x4c, 0x92, - 0xfc, 0xee, 0x08, 0x21, 0xc0, 0x20, 0x1e, 0x2e, 0x9a, 0x00}; - return Bytes(&a[0], &a[sizeof(a)]); - } - - [[nodiscard]] std::expected - getTxArrayLen(SField const& fname) const override - { - return 32; - } - - [[nodiscard]] std::expected - getCurrentLedgerObjArrayLen(SField const& fname) const override - { - return 32; - } - - [[nodiscard]] std::expected - getLedgerObjArrayLen(int32_t cacheIdx, SField const& fname) const override - { - return 32; - } - - [[nodiscard]] std::expected - getTxNestedArrayLen(FieldLocator const& locator) const override - { - return 32; - } - - [[nodiscard]] std::expected - getCurrentLedgerObjNestedArrayLen(FieldLocator const& locator) const override - { - return 32; - } - - [[nodiscard]] std::expected - getLedgerObjNestedArrayLen(int32_t cacheIdx, FieldLocator const& locator) const override - { - return 32; - } - - std::expected - updateData(Slice const& data) override - { - return data.size(); - } - - [[nodiscard]] std::expected - checkSignature(Slice const& message, Slice const& signature, Slice const& pubkey) const override - { - return 1; - } - - [[nodiscard]] std::expected - computeSha512HalfHash(Slice const& data) const override - { - return env_.current()->header().parentHash; - } - - [[nodiscard]] std::expected - accountKeylet(AccountID const& account) const override - { - if (!account) - return std::unexpected(HostFunctionError::InvalidAccount); - auto const keylet = keylet::account(account); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - [[nodiscard]] std::expected - ammKeylet(Asset const& issue1, Asset const& issue2) const override - { - if (issue1 == issue2) - return std::unexpected(HostFunctionError::InvalidParams); - if (issue1.holds() || issue2.holds()) - return std::unexpected(HostFunctionError::InvalidParams); - auto const keylet = keylet::amm(issue1, issue2); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - [[nodiscard]] std::expected - checkKeylet(AccountID const& account, std::uint32_t seq) const override - { - if (!account) - return std::unexpected(HostFunctionError::InvalidAccount); - auto const keylet = keylet::check(account, SeqProxy::rawSequence(seq)); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - [[nodiscard]] std::expected - credentialKeylet(AccountID const& subject, AccountID const& issuer, Slice const& credentialType) - const override - { - if (!subject || !issuer || credentialType.empty() || - credentialType.size() > kMaxCredentialTypeLength) - return std::unexpected(HostFunctionError::InvalidAccount); - auto const keylet = keylet::credential(subject, issuer, credentialType); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - [[nodiscard]] std::expected - escrowKeylet(AccountID const& account, std::uint32_t seq) const override - { - if (!account) - return std::unexpected(HostFunctionError::InvalidAccount); - auto const keylet = keylet::escrow(account, SeqProxy::rawSequence(seq)); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - [[nodiscard]] std::expected - oracleKeylet(AccountID const& account, std::uint32_t documentId) const override - { - if (!account) - return std::unexpected(HostFunctionError::InvalidAccount); - auto const keylet = keylet::oracle(account, documentId); - return Bytes{keylet.key.begin(), keylet.key.end()}; - } - - [[nodiscard]] std::expected - getNFT(AccountID const& account, uint256 const& nftId) const override - { - if (!account || !nftId) - return std::unexpected(HostFunctionError::InvalidParams); - - std::string s = "https://ripple.com"; - return Bytes(s.begin(), s.end()); - } - - [[nodiscard]] std::expected - getNFTIssuer(uint256 const& nftId) const override - { - return Bytes(accountID_.begin(), accountID_.end()); - } - - [[nodiscard]] std::expected - getNFTTaxon(uint256 const& nftId) const override - { - return 4; - } - - [[nodiscard]] std::expected - getNFTFlags(uint256 const& nftId) const override - { - return 8; - } - - [[nodiscard]] std::expected - getNFTTransferFee(uint256 const& nftId) const override - { - return 10; - } - - [[nodiscard]] std::expected - getNFTSequence(uint256 const& nftId) const override - { - return 4; - } - - template - void - log(std::string_view const& msg, F&& dataFn) const - { -#ifdef DEBUG_OUTPUT - auto& j = std::cerr; -#else - if (!getJournal().active(beast::Severity::Trace)) - return; - auto j = getJournal().trace(); -#endif - j << "WasmTrace: " << msg << " " << dataFn(); - -#ifdef DEBUG_OUTPUT - j << std::endl; -#endif - } - - void - trace(std::string_view const& msg, std::string_view const& data) const override - { - log(msg, [&data] { return data; }); - } - - [[nodiscard]] std::expected - floatFromInt(int64_t x, int32_t mode) const override - { - return wasm_float::floatFromIntImpl(x, mode); - } - - [[nodiscard]] std::expected - floatFromUint(uint64_t x, int32_t mode) const override - { - return wasm_float::floatFromUintImpl(x, mode); - } - - [[nodiscard]] std::expected - floatFromSTAmount(STAmount const& x, int32_t mode) const override - { - return wasm_float::floatFromSTAmountImpl(x, mode); - } - - [[nodiscard]] std::expected - floatFromSTNumber(STNumber const& x, int32_t mode) const override - { - return wasm_float::floatFromSTNumberImpl(x, mode); - } - - [[nodiscard]] std::expected - floatToInt(Slice const& x, int32_t mode) const override - { - return wasm_float::floatToIntImpl(x, mode); - } - - [[nodiscard]] std::expected - floatToMantExp(Slice const& x) const override - { - return wasm_float::floatToMantExpImpl(x); - } - - [[nodiscard]] std::expected - floatFromMantExp(int64_t mantissa, int32_t exponent, int32_t mode) const override - { - return wasm_float::floatFromMantExpImpl(mantissa, exponent, mode); - } - - [[nodiscard]] std::expected - floatCompare(Slice const& x, Slice const& y) const override - { - return wasm_float::floatCompareImpl(x, y); - } - - [[nodiscard]] std::expected - floatAdd(Slice const& x, Slice const& y, int32_t mode) const override - { - return wasm_float::floatAddImpl(x, y, mode); - } - - [[nodiscard]] std::expected - floatSubtract(Slice const& x, Slice const& y, int32_t mode) const override - { - return wasm_float::floatSubtractImpl(x, y, mode); - } - - [[nodiscard]] std::expected - floatMultiply(Slice const& x, Slice const& y, int32_t mode) const override - { - return wasm_float::floatMultiplyImpl(x, y, mode); - } - - [[nodiscard]] std::expected - floatDivide(Slice const& x, Slice const& y, int32_t mode) const override - { - return wasm_float::floatDivideImpl(x, y, mode); - } - - [[nodiscard]] std::expected - floatPower(Slice const& x, int32_t n, int32_t mode) const override - { - return wasm_float::floatPowerImpl(x, n, mode); - } -}; - -class TestHostFunctionsSink : public TestHostFunctions -{ - test::StreamSink sink_; - -public: - explicit TestHostFunctionsSink(test::jtx::Env& env) - : TestHostFunctions(env), sink_(beast::Severity::Debug) - { - j_ = beast::Journal(sink_); - } - - test::StreamSink& - getSink() - { - return sink_; - } -}; - -} // namespace xrpl::test diff --git a/src/test/app/Wasm_test.cpp b/src/test/app/Wasm_test.cpp index 8a0cef686e..3706428098 100644 --- a/src/test/app/Wasm_test.cpp +++ b/src/test/app/Wasm_test.cpp @@ -1,3 +1,4 @@ +#if 0 #include #ifdef _DEBUG // #define DEBUG_OUTPUT 1 @@ -1430,3 +1431,4 @@ struct Wasm_test : public beast::unit_test::Suite BEAST_DEFINE_TESTSUITE(Wasm, app, xrpl); } // namespace xrpl::test +#endif diff --git a/src/test/app/wasm_fixtures/.gitignore b/src/test/app/wasm_fixtures/.gitignore deleted file mode 100644 index 08b2e8a256..0000000000 --- a/src/test/app/wasm_fixtures/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -**/target -**/debug -*.wasm diff --git a/src/test/app/wasm_fixtures/all_host_functions/Cargo.lock b/src/test/app/wasm_fixtures/all_host_functions/Cargo.lock deleted file mode 100644 index 5240e9b0f0..0000000000 --- a/src/test/app/wasm_fixtures/all_host_functions/Cargo.lock +++ /dev/null @@ -1,180 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "all_host_functions" -version = "0.1.0" -dependencies = [ - "xrpl-common-stdlib", - "xrpl-escrow-stdlib", -] - -[[package]] -name = "block-buffer" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "digest" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", -] - -[[package]] -name = "hybrid-array" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" -dependencies = [ - "typenum", -] - -[[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "sha2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "syn" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "typenum" -version = "1.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "xrpl-common-stdlib" -version = "0.8.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=error-and-trace#b008b097237ce0d1a2dffc72ba39dd9fc50020a9" -dependencies = [ - "xrpl-macros", -] - -[[package]] -name = "xrpl-escrow-stdlib" -version = "0.1.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=error-and-trace#b008b097237ce0d1a2dffc72ba39dd9fc50020a9" -dependencies = [ - "xrpl-common-stdlib", -] - -[[package]] -name = "xrpl-macros" -version = "0.1.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=error-and-trace#b008b097237ce0d1a2dffc72ba39dd9fc50020a9" -dependencies = [ - "bs58", - "proc-macro2", - "quote", - "sha2", - "syn", -] diff --git a/src/test/app/wasm_fixtures/all_host_functions/Cargo.toml b/src/test/app/wasm_fixtures/all_host_functions/Cargo.toml deleted file mode 100644 index 71ad3ba9c6..0000000000 --- a/src/test/app/wasm_fixtures/all_host_functions/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "all_host_functions" -version = "0.1.0" -edition = "2024" - -# This empty workspace definition keeps this project independent of the parent workspace -[workspace] - -[lib] -crate-type = ["cdylib"] - -[dependencies] -xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-common-stdlib", branch = "error-and-trace" } -xrpl-escrow = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-escrow-stdlib", branch = "error-and-trace" } - -[profile.dev] -panic = "abort" - -[profile.release] -panic = "abort" -opt-level = "z" -lto = true diff --git a/src/test/app/wasm_fixtures/all_host_functions/src/lib.rs b/src/test/app/wasm_fixtures/all_host_functions/src/lib.rs deleted file mode 100644 index a593f3cb83..0000000000 --- a/src/test/app/wasm_fixtures/all_host_functions/src/lib.rs +++ /dev/null @@ -1,760 +0,0 @@ -#![cfg_attr(target_arch = "wasm32", no_std)] - -#[cfg(not(target_arch = "wasm32"))] -extern crate std; - -// -// Host Functions Test -// Tests 26 host functions (across 7 categories) -// -// With craft you can run this test with: -// craft test --project host_functions_test --test-case host_functions_test -// -// Amount Format Update: -// - XRP amounts now return as 8-byte serialized rippled objects -// - IOU and MPT amounts return in variable-length serialized format -// - Format details: https://xrpl.org/docs/references/protocol/binary-format#amount-fields -// -// Error Code Ranges: -// -100 to -199: Ledger Header Functions (3 functions) -// -200 to -299: Transaction Data Functions (5 functions) -// -300 to -399: Current Ledger Object Functions (4 functions) -// -400 to -499: Any Ledger Object Functions (5 functions) -// -500 to -599: Keylet Generation Functions (4 functions) -// -600 to -699: Utility Functions (4 functions) -// -700 to -799: Data Update Functions (1 function) -// - -use xrpl_escrow::current_tx::escrow_finish::EscrowFinish; -use xrpl_std::current_tx::traits::TransactionCommonFields; -use xrpl_std::host; -use xrpl_std::host::trace::TraceDataType; -use xrpl_std::host::trace::{trace, trace_acct_buf, trace_hex, trace_num}; -use xrpl_std::sfield; - -#[unsafe(no_mangle)] -pub extern "C" fn escrow_finish() -> i32 { - let _ = trace("=== HOST FUNCTIONS TEST ==="); - let _ = trace("Testing 26 host functions"); - - // Category 1: Ledger Header Data Functions (3 functions) - // Error range: -100 to -199 - match test_ledger_header_functions() { - 0 => (), - err => return err, - } - - // Category 2: Transaction Data Functions (5 functions) - // Error range: -200 to -299 - match test_transaction_data_functions() { - 0 => (), - err => return err, - } - - // Category 3: Current Ledger Object Functions (4 functions) - // Error range: -300 to -399 - match test_current_ledger_object_functions() { - 0 => (), - err => return err, - } - - // Category 4: Any Ledger Object Functions (5 functions) - // Error range: -400 to -499 - match test_any_ledger_object_functions() { - 0 => (), - err => return err, - } - - // Category 5: Keylet Generation Functions (4 functions) - // Error range: -500 to -599 - match test_keylet_generation_functions() { - 0 => (), - err => return err, - } - - // Category 6: Utility Functions (4 functions) - // Error range: -600 to -699 - match test_utility_functions() { - 0 => (), - err => return err, - } - - // Category 7: Data Update Functions (1 function) - // Error range: -700 to -799 - match test_data_update_functions() { - 0 => (), - err => return err, - } - - let _ = trace("SUCCESS: All host function tests passed!"); - 1 // Success return code for WASM finish function -} - -/// Test Category 1: Ledger Header Data Functions (3 functions) -/// - get_ledger_sqn() - Get ledger sequence number -/// - get_parent_ledger_time() - Get parent ledger timestamp -/// - get_parent_ledger_hash() - Get parent ledger hash -fn test_ledger_header_functions() -> i32 { - let _ = trace("--- Category 1: Ledger Header Functions ---"); - - // Test 1.1: get_ledger_sqn() - should return current ledger sequence number - let mut sqn_buffer = [0u8; 4]; - let sqn_result = unsafe { host::ldgr_index(sqn_buffer.as_mut_ptr(), sqn_buffer.len()) }; - - if sqn_result <= 0 { - let _ = trace_num("ERROR: get_ledger_sqn failed:", sqn_result as i64); - return -101; // Ledger sequence number test failed - } - let ledger_sqn = u32::from_be_bytes(sqn_buffer); - let _ = trace_num("Ledger sequence number:", ledger_sqn as i64); - - // Test 1.2: get_parent_ledger_time() - should return parent ledger timestamp - let mut time_buffer = [0u8; 4]; - let time_result = - unsafe { host::parent_ldgr_time(time_buffer.as_mut_ptr(), time_buffer.len()) }; - - if time_result <= 0 { - let _ = trace_num("ERROR: get_parent_ledger_time failed:", time_result as i64); - return -102; // Parent ledger time test failed - } - let parent_ledger_time = u32::from_be_bytes(time_buffer); - let _ = trace_num("Parent ledger time:", parent_ledger_time as i64); - - // Test 1.3: get_parent_ledger_hash() - should return parent ledger hash (32 bytes) - let mut hash_buffer = [0u8; 32]; - let hash_result = - unsafe { host::parent_ldgr_hash(hash_buffer.as_mut_ptr(), hash_buffer.len()) }; - - if hash_result != 32 { - let _ = trace_num( - "ERROR: get_parent_ledger_hash wrong length:", - hash_result as i64, - ); - return -103; // Parent ledger hash test failed - should be exactly 32 bytes - } - let _ = trace_hex("Parent ledger hash:", &hash_buffer); - - let _ = trace("SUCCESS: Ledger header functions"); - 0 -} - -/// Test Category 2: Transaction Data Functions (5 functions) -/// Tests all functions for accessing current transaction data -fn test_transaction_data_functions() -> i32 { - let _ = trace("--- Category 2: Transaction Data Functions ---"); - - // Test 2.1: get_tx_field() - Basic transaction field access - // Test with Account field (required, 20 bytes) - let mut account_buffer = [0u8; 20]; - let account_len = unsafe { - host::tx_field( - sfield::Account.into(), - account_buffer.as_mut_ptr(), - account_buffer.len(), - ) - }; - - if account_len != 20 { - let _ = trace_num( - "ERROR: get_tx_field(Account) wrong length:", - account_len as i64, - ); - return -201; // Basic transaction field test failed - } - let _ = trace_acct_buf("Transaction Account:", &account_buffer); - - // Test with Fee field (XRP amount - 8 bytes in new serialized format) - // New format: XRP amounts are always 8 bytes (positive: value | cPositive flag, negative: just value) - let mut fee_buffer = [0u8; 8]; - let fee_len = unsafe { - host::tx_field( - sfield::Fee.into(), - fee_buffer.as_mut_ptr(), - fee_buffer.len(), - ) - }; - - if fee_len != 8 { - let _ = trace_num( - "ERROR: get_tx_field(Fee) wrong length (expected 8 bytes for XRP):", - fee_len as i64, - ); - return -202; // Fee field test failed - XRP amounts should be exactly 8 bytes - } - let _ = trace_num("Transaction Fee length:", fee_len as i64); - let _ = trace_hex("Transaction Fee (serialized XRP amount):", &fee_buffer); - - // Test with Sequence field (required, 4 bytes uint32) - let mut seq_buffer = [0u8; 4]; - let seq_len = unsafe { - host::tx_field( - sfield::Sequence.into(), - seq_buffer.as_mut_ptr(), - seq_buffer.len(), - ) - }; - - if seq_len != 4 { - let _ = trace_num( - "ERROR: get_tx_field(Sequence) wrong length:", - seq_len as i64, - ); - return -203; // Sequence field test failed - } - let _ = trace_hex("Transaction Sequence:", &seq_buffer); - - // NOTE: get_tx_field2() through get_tx_field6() have been deprecated. - // Use get_tx_field() with appropriate parameters for all transaction field access. - - // Test 2.2: get_tx_nested_field() - Nested field access with locator - let locator = [ - 0x01_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, - ]; // Two int32s in little-endian: [1, 0] - let mut nested_buffer = [0u8; 32]; - let nested_result = unsafe { - host::tx_inner( - locator.as_ptr(), - locator.len(), - nested_buffer.as_mut_ptr(), - nested_buffer.len(), - ) - }; - - if nested_result < 0 { - let _ = trace_num( - "INFO: get_tx_nested_field not applicable:", - nested_result as i64, - ); - // Expected - locator may not match transaction structure - } else { - let _ = trace_num("Nested field length:", nested_result as i64); - let _ = trace_hex("Nested field:", &nested_buffer[..nested_result as usize]); - } - - // Test 2.3: get_tx_array_len() - Get array length - let signers_len = unsafe { host::tx_arr_len(sfield::Signers.into()) }; - let _ = trace_num("Signers array length:", signers_len as i64); - - let memos_len = unsafe { host::tx_arr_len(sfield::Memos.into()) }; - let _ = trace_num("Memos array length:", memos_len as i64); - - // Test 2.4: get_tx_nested_array_len() - Get nested array length with locator - let nested_array_len = unsafe { host::tx_inner_arr_len(locator.as_ptr(), locator.len()) }; - - if nested_array_len < 0 { - let _ = trace_num( - "INFO: get_tx_nested_array_len not applicable:", - nested_array_len as i64, - ); - } else { - let _ = trace_num("Nested array length:", nested_array_len as i64); - } - - let _ = trace("SUCCESS: Transaction data functions"); - 0 -} - -/// Test Category 3: Current Ledger Object Functions (4 functions) -/// Tests functions that access the current ledger object being processed -fn test_current_ledger_object_functions() -> i32 { - let _ = trace("--- Category 3: Current Ledger Object Functions ---"); - - // Test 3.1: get_current_ledger_obj_field() - Access field from current ledger object - // Test with Balance field (XRP amount - 8 bytes in new serialized format) - let mut balance_buffer = [0u8; 8]; - let balance_result = unsafe { - host::home_le_field( - sfield::Balance.into(), - balance_buffer.as_mut_ptr(), - balance_buffer.len(), - ) - }; - - if balance_result <= 0 { - let _ = trace_num( - "INFO: get_current_ledger_obj_field(Balance) failed (may be expected):", - balance_result as i64, - ); - // This might fail if current ledger object doesn't have balance field - } else if balance_result == 8 { - let _ = trace_num( - "Current object balance length (XRP amount):", - balance_result as i64, - ); - let _ = trace_hex( - "Current object balance (serialized XRP amount):", - &balance_buffer, - ); - } else { - let _ = trace_num( - "Current object balance length (non-XRP amount):", - balance_result as i64, - ); - let _ = trace_hex( - "Current object balance:", - &balance_buffer[..balance_result as usize], - ); - } - - // Test with Account field - let mut current_account_buffer = [0u8; 20]; - let current_account_result = unsafe { - host::home_le_field( - sfield::Account.into(), - current_account_buffer.as_mut_ptr(), - current_account_buffer.len(), - ) - }; - - if current_account_result <= 0 { - let _ = trace_num( - "INFO: get_current_ledger_obj_field(Account) failed:", - current_account_result as i64, - ); - } else { - let _ = trace_acct_buf("Current ledger object account:", ¤t_account_buffer); - } - - // Test 3.2: get_current_ledger_obj_nested_field() - Nested field access - let locator = [ - 0x01_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, - ]; // Two int32s in little-endian: [1, 0] - let mut current_nested_buffer = [0u8; 32]; - let current_nested_result = unsafe { - host::home_le_inner( - locator.as_ptr(), - locator.len(), - current_nested_buffer.as_mut_ptr(), - current_nested_buffer.len(), - ) - }; - - if current_nested_result < 0 { - let _ = trace_num( - "INFO: get_current_ledger_obj_nested_field not applicable:", - current_nested_result as i64, - ); - } else { - let _ = trace_num("Current nested field length:", current_nested_result as i64); - let _ = trace_hex( - "Current nested field:", - ¤t_nested_buffer[..current_nested_result as usize], - ); - } - - // Test 3.3: get_current_ledger_obj_array_len() - Array length in current object - let current_array_len = unsafe { host::home_le_arr_len(sfield::Signers.into()) }; - let _ = trace_num( - "Current object Signers array length:", - current_array_len as i64, - ); - - // Test 3.4: get_current_ledger_obj_nested_array_len() - Nested array length - let current_nested_array_len = - unsafe { host::home_le_inner_arr_len(locator.as_ptr(), locator.len()) }; - - if current_nested_array_len < 0 { - let _ = trace_num( - "INFO: get_current_ledger_obj_nested_array_len not applicable:", - current_nested_array_len as i64, - ); - } else { - let _ = trace_num( - "Current nested array length:", - current_nested_array_len as i64, - ); - } - - let _ = trace("SUCCESS: Current ledger object functions"); - 0 -} - -/// Test Category 4: Any Ledger Object Functions (5 functions) -/// Tests functions that work with cached ledger objects -fn test_any_ledger_object_functions() -> i32 { - let _ = trace("--- Category 4: Any Ledger Object Functions ---"); - - // First we need to cache a ledger object to test the other functions - // Get the account from transaction and generate its keylet - let escrow_finish = EscrowFinish; - let account_id = escrow_finish.get_account().unwrap(); - - // Test 4.1: cache_le() - Cache a ledger object - let mut keylet_buffer = [0u8; 32]; - let keylet_result = unsafe { - host::accountroot_id( - account_id.0.as_ptr(), - account_id.0.len(), - keylet_buffer.as_mut_ptr(), - keylet_buffer.len(), - ) - }; - - if keylet_result != 32 { - let _ = trace_num( - "ERROR: accountroot_id failed for caching test:", - keylet_result as i64, - ); - return -401; // Keylet generation failed for caching test - } - - let cache_result = unsafe { host::cache_le(keylet_buffer.as_ptr(), keylet_result as usize, 0) }; - - if cache_result <= 0 { - let _ = trace_num( - "INFO: cache_le failed (expected with test fixtures):", - cache_result as i64, - ); - // Test fixtures may not contain the account object - this is expected - // We'll test the interface but expect failures - - // Test 4.2-4.5 with invalid slot (should fail gracefully) - let mut test_buffer = [0u8; 32]; - - // Test le_field with invalid slot - let field_result = unsafe { - host::le_field( - 1, - sfield::Balance.into(), - test_buffer.as_mut_ptr(), - test_buffer.len(), - ) - }; - if field_result < 0 { - let _ = trace_num( - "INFO: le_field failed as expected (no cached object):", - field_result as i64, - ); - } - - // Test le_inner_field with invalid slot - let locator = [ - 0x01_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, - ]; // Two int32s in little-endian: [1, 0] - let nested_result = unsafe { - host::le_inner( - 1, - locator.as_ptr(), - locator.len(), - test_buffer.as_mut_ptr(), - test_buffer.len(), - ) - }; - if nested_result < 0 { - let _ = trace_num( - "INFO: le_inner_field failed as expected:", - nested_result as i64, - ); - } - - // Test le_inner_arr_len with invalid slot - let array_result = unsafe { host::le_arr_len(1, sfield::Signers.into()) }; - if array_result < 0 { - let _ = trace_num( - "INFO: le_inner_arr_len failed as expected:", - array_result as i64, - ); - } - - // Test get_ledger_obj_nested_array_len with invalid slot - let nested_array_result = - unsafe { host::le_inner_arr_len(1, locator.as_ptr(), locator.len()) }; - if nested_array_result < 0 { - let _ = trace_num( - "INFO: get_ledger_obj_nested_array_len failed as expected:", - nested_array_result as i64, - ); - } - - let _ = trace("SUCCESS: Any ledger object functions (interface tested)"); - return 0; - } - - // If we successfully cached an object, test the access functions - let slot = cache_result; - let _ = trace_num("Successfully cached object in slot:", slot as i64); - - // Test 4.2: le_field() - Access field from cached object - let mut cached_balance_buffer = [0u8; 8]; - let cached_balance_result = unsafe { - host::le_field( - slot, - sfield::Balance.into(), - cached_balance_buffer.as_mut_ptr(), - cached_balance_buffer.len(), - ) - }; - - if cached_balance_result <= 0 { - let _ = trace_num( - "INFO: le_field(Balance) failed:", - cached_balance_result as i64, - ); - } else if cached_balance_result == 8 { - let _ = trace_num( - "Cached object balance length (XRP amount):", - cached_balance_result as i64, - ); - let _ = trace_hex( - "Cached object balance (serialized XRP amount):", - &cached_balance_buffer, - ); - } else { - let _ = trace_num( - "Cached object balance length (non-XRP amount):", - cached_balance_result as i64, - ); - let _ = trace_hex( - "Cached object balance:", - &cached_balance_buffer[..cached_balance_result as usize], - ); - } - - // Test 4.3: le_inner_field() - Nested field from cached object - let locator = [ - 0x01_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, - ]; // Two int32s in little-endian: [1, 0] - let mut cached_nested_buffer = [0u8; 32]; - let cached_nested_result = unsafe { - host::le_inner( - slot, - locator.as_ptr(), - locator.len(), - cached_nested_buffer.as_mut_ptr(), - cached_nested_buffer.len(), - ) - }; - - if cached_nested_result < 0 { - let _ = trace_num( - "INFO: le_inner_field not applicable:", - cached_nested_result as i64, - ); - } else { - let _ = trace_num("Cached nested field length:", cached_nested_result as i64); - let _ = trace_hex( - "Cached nested field:", - &cached_nested_buffer[..cached_nested_result as usize], - ); - } - - // Test 4.4: le_inner_arr_len() - Array length from cached object - let cached_array_len = unsafe { host::le_arr_len(slot, sfield::Signers.into()) }; - let _ = trace_num( - "Cached object Signers array length:", - cached_array_len as i64, - ); - - // Test 4.5: get_ledger_obj_nested_array_len() - Nested array length from cached object - let cached_nested_array_len = - unsafe { host::le_inner_arr_len(slot, locator.as_ptr(), locator.len()) }; - - if cached_nested_array_len < 0 { - let _ = trace_num( - "INFO: get_ledger_obj_nested_array_len not applicable:", - cached_nested_array_len as i64, - ); - } else { - let _ = trace_num( - "Cached nested array length:", - cached_nested_array_len as i64, - ); - } - - let _ = trace("SUCCESS: Any ledger object functions"); - 0 -} - -/// Test Category 5: Keylet Generation Functions (4 functions) -/// Tests keylet generation functions for different ledger entry types -fn test_keylet_generation_functions() -> i32 { - let _ = trace("--- Category 5: Keylet Generation Functions ---"); - - let escrow_finish = EscrowFinish; - let account_id = escrow_finish.get_account().unwrap(); - - // Test 5.1: accountroot_id() - Generate keylet for account - let mut accountroot_id_buffer = [0u8; 32]; - let accountroot_id_result = unsafe { - host::accountroot_id( - account_id.0.as_ptr(), - account_id.0.len(), - accountroot_id_buffer.as_mut_ptr(), - accountroot_id_buffer.len(), - ) - }; - - if accountroot_id_result != 32 { - let _ = trace_num( - "ERROR: accountroot_id failed:", - accountroot_id_result as i64, - ); - return -501; // Account keylet generation failed - } - let _ = trace_hex("Account keylet:", &accountroot_id_buffer); - - // Test 5.2: credential_keylet() - Generate keylet for credential - let mut credential_keylet_buffer = [0u8; 32]; - let credential_keylet_result = unsafe { - host::credential_id( - account_id.0.as_ptr(), // Subject - account_id.0.len(), - account_id.0.as_ptr(), // Issuer - same account for test - account_id.0.len(), - b"TestType".as_ptr(), // Credential type - 9usize, // Length of "TestType" - credential_keylet_buffer.as_mut_ptr(), - credential_keylet_buffer.len(), - ) - }; - - if credential_keylet_result <= 0 { - let _ = trace_num( - "INFO: credential_keylet failed (expected - interface issue):", - credential_keylet_result as i64, - ); - // This is expected to fail due to unusual parameter types - } else { - let _ = trace_hex( - "Credential keylet:", - &credential_keylet_buffer[..credential_keylet_result as usize], - ); - } - - // Test 5.3: escrow_keylet() - Generate keylet for escrow - let mut escrow_keylet_buffer = [0u8; 32]; - let sequence_number: i32 = 1000; - let sequence_number_bytes = sequence_number.to_be_bytes(); - let escrow_keylet_result = unsafe { - host::escrow_id( - account_id.0.as_ptr(), - account_id.0.len(), - sequence_number_bytes.as_ptr(), - sequence_number_bytes.len(), - escrow_keylet_buffer.as_mut_ptr(), - escrow_keylet_buffer.len(), - ) - }; - - if escrow_keylet_result != 32 { - let _ = trace_num("ERROR: escrow_keylet failed:", escrow_keylet_result as i64); - return -503; // Escrow keylet generation failed - } - let _ = trace_hex("Escrow keylet:", &escrow_keylet_buffer); - - // Test 5.4: oracle_keylet() - Generate keylet for oracle - let mut oracle_keylet_buffer = [0u8; 32]; - let document_id: i32 = 42; - let document_id_bytes = document_id.to_be_bytes(); - let oracle_keylet_result = unsafe { - host::oracle_id( - account_id.0.as_ptr(), - account_id.0.len(), - document_id_bytes.as_ptr(), - document_id_bytes.len(), - oracle_keylet_buffer.as_mut_ptr(), - oracle_keylet_buffer.len(), - ) - }; - - if oracle_keylet_result != 32 { - let _ = trace_num("ERROR: oracle_keylet failed:", oracle_keylet_result as i64); - return -504; // Oracle keylet generation failed - } - let _ = trace_hex("Oracle keylet:", &oracle_keylet_buffer); - - let _ = trace("SUCCESS: Keylet generation functions"); - 0 -} - -/// Test Category 6: Utility Functions (4 functions) -/// Tests utility functions for hashing, NFT access, and tracing -fn test_utility_functions() -> i32 { - let _ = trace("--- Category 6: Utility Functions ---"); - - // Test 6.1: compute_sha512_half() - SHA512 hash computation (first 32 bytes) - let test_data = b"Hello, XRPL WASM world!"; - let mut hash_output = [0u8; 32]; - let hash_result = unsafe { - host::sha512_half( - test_data.as_ptr(), - test_data.len(), - hash_output.as_mut_ptr(), - hash_output.len(), - ) - }; - - if hash_result != 32 { - let _ = trace_num("ERROR: compute_sha512_half failed:", hash_result as i64); - return -601; // SHA512 half computation failed - } - let _ = trace_hex("Input data:", test_data); - let _ = trace_hex("SHA512 half hash:", &hash_output); - - // Test 6.2: get_nft() - NFT data retrieval - let escrow_finish = EscrowFinish; - let account_id = escrow_finish.get_account().unwrap(); - let nft_id = [0u8; 32]; // Dummy NFT ID for testing - let mut nft_buffer = [0u8; 256]; - let nft_result = unsafe { - host::nft_uri( - account_id.0.as_ptr(), - account_id.0.len(), - nft_id.as_ptr(), - nft_id.len(), - nft_buffer.as_mut_ptr(), - nft_buffer.len(), - ) - }; - - if nft_result <= 0 { - let _ = trace_num( - "INFO: get_nft failed (expected - no such NFT):", - nft_result as i64, - ); - // This is expected - test account likely doesn't own the dummy NFT - } else { - let _ = trace_num("NFT data length:", nft_result as i64); - let _ = trace_hex("NFT data:", &nft_buffer[..nft_result as usize]); - } - - // Test 6.3: trace() - Debug logging with data - let trace_message = b"Test trace message"; - let trace_data_payload = b"payload"; - unsafe { - host::trace( - trace_message.as_ptr(), - trace_message.len(), - TraceDataType::AsHex as i32, - trace_data_payload.as_ptr(), - trace_data_payload.len(), - ) - }; - - // Test 6.4: trace_num() - Debug logging with number - let test_number = 42i64; - trace_num("Test number trace", test_number); - - let _ = trace("SUCCESS: Utility functions"); - 0 -} - -/// Test Category 7: Data Update Functions (1 function) -/// Tests the function for modifying the current ledger entry -fn test_data_update_functions() -> i32 { - let _ = trace("--- Category 7: Data Update Functions ---"); - - // Test 7.1: update_data() - Update current ledger entry data - let update_payload = b"Updated ledger entry data from WASM test"; - - let update_result = unsafe { host::set_data(update_payload.as_ptr(), update_payload.len()) }; - - if update_result != update_payload.len() as i32 { - let _ = trace_num("ERROR: update_data failed:", update_result as i64); - return -701; // Data update failed - } - - let _ = trace_hex("Successfully updated ledger entry with:", update_payload); - let _ = trace("SUCCESS: Data update functions"); - 0 -} diff --git a/src/test/app/wasm_fixtures/all_keylets/Cargo.lock b/src/test/app/wasm_fixtures/all_keylets/Cargo.lock deleted file mode 100644 index 5da5b26f66..0000000000 --- a/src/test/app/wasm_fixtures/all_keylets/Cargo.lock +++ /dev/null @@ -1,171 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "all_keylets" -version = "0.0.1" -dependencies = [ - "xrpl-wasm-stdlib", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "syn" -version = "2.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "typenum" -version = "1.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "xrpl-macros" -version = "0.1.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=renames#21c522f34a24b460297ebb6be1822680459bf37e" -dependencies = [ - "bs58", - "quote", - "sha2", - "syn", -] - -[[package]] -name = "xrpl-wasm-stdlib" -version = "0.8.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=renames#21c522f34a24b460297ebb6be1822680459bf37e" -dependencies = [ - "xrpl-macros", -] diff --git a/src/test/app/wasm_fixtures/all_keylets/Cargo.toml b/src/test/app/wasm_fixtures/all_keylets/Cargo.toml deleted file mode 100644 index ad53fd62b1..0000000000 --- a/src/test/app/wasm_fixtures/all_keylets/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -edition = "2024" -name = "all_keylets" -version = "0.0.1" - -# This empty workspace definition keeps this project independent of the parent workspace -[workspace] - -[lib] -crate-type = ["cdylib"] - -[profile.release] -lto = true -opt-level = 's' -panic = "abort" - -[dependencies] -xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-wasm-stdlib", branch = "renames" } - -[profile.dev] -panic = "abort" diff --git a/src/test/app/wasm_fixtures/all_keylets/src/lib.rs b/src/test/app/wasm_fixtures/all_keylets/src/lib.rs deleted file mode 100644 index f0a4e5abb5..0000000000 --- a/src/test/app/wasm_fixtures/all_keylets/src/lib.rs +++ /dev/null @@ -1,176 +0,0 @@ -#![cfg_attr(target_arch = "wasm32", no_std)] - -#[cfg(not(target_arch = "wasm32"))] -extern crate std; - -use crate::host::{Error, Result, Result::Err, Result::Ok}; -use xrpl_std::core::keylets; -use xrpl_std::core::ledger_objects::current_escrow::get_current_escrow; -use xrpl_std::core::ledger_objects::current_escrow::CurrentEscrow; -use xrpl_std::core::ledger_objects::ledger_object; -use xrpl_std::core::ledger_objects::traits::CurrentEscrowFields; -use xrpl_std::core::ledger_objects::LedgerObjectFieldGetter; -use xrpl_std::core::types::currency::Currency; -use xrpl_std::core::types::issue::{IouIssue, Issue, XrpIssue}; -use xrpl_std::core::types::mpt_id::MptId; -use xrpl_std::host; -use xrpl_std::host::trace::{trace, trace_acct, trace_data, trace_num, DataRepr}; -use xrpl_std::sfield; - -pub fn object_exists( - keylet_result: Result, - keylet_type: &str, - sfield: sfield::SField, -) -> Result { - let field = CODE; - match keylet_result { - Ok(keylet) => { - let _ = trace_data(keylet_type, &keylet, DataRepr::AsHex); - - let slot = unsafe { host::cache_le(keylet.as_ptr(), keylet.len(), 0) }; - if slot <= 0 { - let _ = trace_num("Error: ", slot.into()); - return Err(Error::from_code(slot)); - } - if field == 0 { - let new_field = sfield::PreviousTxnID; - let _ = trace_num("Getting field: ", new_field.clone().into()); - match ledger_object::get_field(slot, new_field) { - Ok(data) => { - let _ = trace_data("Field data: ", &data.0, DataRepr::AsHex); - } - Err(result_code) => { - let _ = trace_num("Error getting field: ", result_code.into()); - return Err(result_code); - } - } - } else { - let _ = trace_num("Getting field: ", field.into()); - match ledger_object::get_field(slot, sfield) { - Ok(_data) => { - let _ = trace("Field data: retrieved"); - } - Err(result_code) => { - let _ = trace_num("Error getting field: ", result_code.into()); - return Err(result_code); - } - } - } - - Ok(true) - } - Err(error) => { - let _ = trace_num("Error getting keylet: ", error.into()); - Err(error) - } - } -} - -#[unsafe(no_mangle)] -pub extern "C" fn escrow_finish() -> i32 { - let _ = trace("$$$$$ STARTING WASM EXECUTION $$$$$"); - - let escrow: CurrentEscrow = get_current_escrow(); - - let account = escrow.get_account().unwrap_or_panic(); - let _ = trace_acct("Account:", &account); - - let destination = escrow.get_destination().unwrap_or_panic(); - let _ = trace_acct("Destination:", &destination); - - let mut seq = 5; - - macro_rules! check_object_exists { - ($keylet:expr, $type:expr, $field:expr) => { - match object_exists($keylet, $type, $field) { - Ok(_exists) => { - // false isn't returned - let _ = trace(concat!( - $type, - " object exists, proceeding with escrow finish." - )); - } - Err(error) => { - let _ = trace_num("Current seq value:", seq.try_into().unwrap()); - return error.code(); - } - } - }; - } - - let accountroot_id = keylets::accountroot_id(&account); - check_object_exists!(accountroot_id, "Account", sfield::Account); - - let currency_code: &[u8; 3] = b"USD"; - let currency: Currency = Currency::from(*currency_code); - let trustline_id = keylets::trustline_id(&account, &destination, ¤cy); - check_object_exists!(trustline_id, "Trustline", sfield::Generic); - seq += 1; - - let asset1 = Issue::XRP(XrpIssue {}); - let asset2 = Issue::IOU(IouIssue::new(destination, currency)); - check_object_exists!(keylets::amm_id(&asset1, &asset2), "AMM", sfield::Account); - - let check_id = keylets::check_id(&account, seq); - check_object_exists!(check_id, "Check", sfield::Account); - seq += 1; - - let cred_type: &[u8] = b"termsandconditions"; - let credential_id = keylets::credential_id(&account, &account, cred_type); - check_object_exists!(credential_id, "Credential", sfield::Subject); - seq += 1; - - let delegate_id = keylets::delegate_id(&account, &destination); - check_object_exists!(delegate_id, "Delegate", sfield::Account); - seq += 1; - - let deposit_preauth_id = keylets::deposit_preauth_id(&account, &destination); - check_object_exists!(deposit_preauth_id, "DepositPreauth", sfield::Account); - seq += 1; - - let did_id = keylets::did_id(&account); - check_object_exists!(did_id, "DID", sfield::Account); - seq += 1; - - let escrow_id = keylets::escrow_id(&account, seq); - check_object_exists!(escrow_id, "Escrow", sfield::Account); - seq += 1; - - let mpt_issuance_id = keylets::mpt_issuance_id(&account, seq); - let mpt_id = MptId::new(seq.try_into().unwrap(), account); - check_object_exists!(mpt_issuance_id, "MPTIssuance", sfield::Issuer); - seq += 1; - - let mptoken_id = keylets::mptoken_id(&mpt_id, &destination); - check_object_exists!(mptoken_id, "MPToken", sfield::Account); - - let nft_offer_id = keylets::nft_offer_id(&destination, 6); - check_object_exists!(nft_offer_id, "NFTokenOffer", sfield::Owner); - - let offer_id = keylets::offer_id(&account, seq); - check_object_exists!(offer_id, "Offer", sfield::Account); - seq += 1; - - let paychan_id = keylets::paychan_id(&account, &destination, seq); - check_object_exists!(paychan_id, "PayChannel", sfield::Account); - seq += 1; - - let pd_id = keylets::permissioned_domain_id(&account, seq); - check_object_exists!(pd_id, "PermissionedDomain", sfield::Owner); - seq += 1; - - let signers_id = keylets::signers_id(&account); - check_object_exists!(signers_id, "SignerList", sfield::Generic); - seq += 1; - - seq += 1; // ticket sequence number is one greater - let ticket_id = keylets::ticket_id(&account, seq); - check_object_exists!(ticket_id, "Ticket", sfield::Account); - seq += 1; - - let vault_id = keylets::vault_id(&account, seq); - check_object_exists!(vault_id, "Vault", sfield::Account); - // seq += 1; - - 1 // All keylets exist, finish the escrow. -} diff --git a/src/test/app/wasm_fixtures/bad_align.c b/src/test/app/wasm_fixtures/bad_align.c deleted file mode 100644 index 560245e762..0000000000 --- a/src/test/app/wasm_fixtures/bad_align.c +++ /dev/null @@ -1,42 +0,0 @@ -#include - -int32_t float_from_uint(uint8_t const *, int32_t, uint8_t *, int32_t, int32_t); -int32_t check_id(uint8_t const *, int32_t, uint8_t const *, int32_t, uint8_t *, - int32_t); - -uint8_t e_data1[32 * 1024]; -uint8_t e_data2[32 * 1024]; - -int32_t test1() -{ - e_data1[1] = 0xFF; - e_data1[2] = 0xFF; - e_data1[3] = 0xFF; - e_data1[4] = 0xFF; - e_data1[5] = 0xFF; - e_data1[6] = 0xFF; - e_data1[7] = 0xFF; - e_data1[8] = 0xFF; - int32_t result = float_from_uint(&e_data1[1], 8, &e_data1[35], 12, 0); - return result >= 0 ? *((int32_t *)(&e_data1[36])) : result; -} - -int32_t test2() -{ - // Set up misaligned uint32 (seq) at offset 1 - e_data2[1] = 0xFF; - e_data2[2] = 0xFF; - e_data2[3] = 0xFF; - e_data2[4] = 0xFF; - // Set up valid non-zero AccountID (20 bytes) at offset 10 - for (int i = 0; i < 20; i++) - e_data2[10 + i] = i + 1; - // Call check_id with misaligned uint32 at &e_data2[1] to hit line 72 in - // HostFuncWrapper.cpp - int32_t result = check_id(&e_data2[10], 20, &e_data2[1], 4, &e_data2[35], 32); - // Return the misaligned value directly to validate it was read correctly (-1 - // if all 0xFF) - return result >= 0 ? *((int32_t *)(&e_data2[36])) : result; -} - -int32_t test() { return test1() + test2(); } diff --git a/src/test/app/wasm_fixtures/codecov_tests/Cargo.lock b/src/test/app/wasm_fixtures/codecov_tests/Cargo.lock deleted file mode 100644 index 6e82e804a7..0000000000 --- a/src/test/app/wasm_fixtures/codecov_tests/Cargo.lock +++ /dev/null @@ -1,180 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "block-buffer" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "codecov_tests" -version = "0.0.1" -dependencies = [ - "xrpl-common-stdlib", - "xrpl-escrow-stdlib", -] - -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "digest" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", -] - -[[package]] -name = "hybrid-array" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" -dependencies = [ - "typenum", -] - -[[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "sha2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "syn" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "typenum" -version = "1.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "xrpl-common-stdlib" -version = "0.9.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#e88dc32a48fac9d0eb6e7239c8a38693221657f6" -dependencies = [ - "xrpl-macros", -] - -[[package]] -name = "xrpl-escrow-stdlib" -version = "0.9.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#e88dc32a48fac9d0eb6e7239c8a38693221657f6" -dependencies = [ - "xrpl-common-stdlib", -] - -[[package]] -name = "xrpl-macros" -version = "0.9.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#e88dc32a48fac9d0eb6e7239c8a38693221657f6" -dependencies = [ - "bs58", - "proc-macro2", - "quote", - "sha2", - "syn", -] diff --git a/src/test/app/wasm_fixtures/codecov_tests/Cargo.toml b/src/test/app/wasm_fixtures/codecov_tests/Cargo.toml deleted file mode 100644 index 7a81244620..0000000000 --- a/src/test/app/wasm_fixtures/codecov_tests/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -edition = "2024" -name = "codecov_tests" -version = "0.0.1" - -# This empty workspace definition keeps this project independent of the parent workspace -[workspace] - -[lib] -crate-type = ["cdylib"] - -[profile.release] -lto = true -opt-level = 's' -panic = "abort" - -[dependencies] -xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-common-stdlib" } -xrpl-escrow = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-escrow-stdlib" } diff --git a/src/test/app/wasm_fixtures/codecov_tests/src/host_bindings_loose.rs b/src/test/app/wasm_fixtures/codecov_tests/src/host_bindings_loose.rs deleted file mode 100644 index 7b42f747a8..0000000000 --- a/src/test/app/wasm_fixtures/codecov_tests/src/host_bindings_loose.rs +++ /dev/null @@ -1,56 +0,0 @@ -//TODO add docs after discussing the interface -//Note that Craft currently does not honor the rounding modes -#[allow(unused)] -pub const FLOAT_ROUNDING_MODES_TO_NEAREST: i32 = 0; -#[allow(unused)] -pub const FLOAT_ROUNDING_MODES_TOWARDS_ZERO: i32 = 1; -#[allow(unused)] -pub const FLOAT_ROUNDING_MODES_DOWNWARD: i32 = 2; -#[allow(unused)] -pub const FLOAT_ROUNDING_MODES_UPWARD: i32 = 3; - -// pub enum RippledRoundingModes{ -// ToNearest = 0, -// TowardsZero = 1, -// DOWNWARD = 2, -// UPWARD = 3 -// } - -#[allow(unused)] -#[link(wasm_import_module = "host_lib")] -unsafe extern "C" { - pub fn parent_ldgr_hash(out_buff_ptr: i32, out_buff_len: i32) -> i32; - - pub fn cache_le(keylet_ptr: i32, keylet_len: i32, cache_num: i32) -> i32; - - pub fn tx_inner_arr_len(locator_ptr: i32, locator_len: i32) -> i32; - - pub fn accountroot_id( - account_ptr: i32, - account_len: i32, - out_buff_ptr: *mut u8, - out_buff_len: usize, - ) -> i32; - - pub fn trustline_id( - account1_ptr: *const u8, - account1_len: usize, - account2_ptr: *const u8, - account2_len: usize, - currency_ptr: i32, - currency_len: i32, - out_buff_ptr: *mut u8, - out_buff_len: usize, - ) -> i32; - - // Same wasm functype as the real binding, so this is not a second import of - // host_lib.trace. Loose i32 pointers exercise the out-of-bounds path. - #[link_name = "trace"] - pub fn trace_loose( - msg_read_ptr: i32, - msg_read_len: i32, - data_type: i32, - data_read_ptr: i32, - data_read_len: i32, - ); -} diff --git a/src/test/app/wasm_fixtures/codecov_tests/src/lib.rs b/src/test/app/wasm_fixtures/codecov_tests/src/lib.rs deleted file mode 100644 index ef8f7b10de..0000000000 --- a/src/test/app/wasm_fixtures/codecov_tests/src/lib.rs +++ /dev/null @@ -1,1728 +0,0 @@ -#![cfg_attr(target_arch = "wasm32", no_std)] - -#[cfg(not(target_arch = "wasm32"))] -extern crate std; - -use core::panic; -use xrpl_escrow::current_tx::escrow_finish::{get_current_escrow_finish, EscrowFinish}; -use xrpl_std::current_tx::traits::TransactionCommonFields; -use xrpl_std::fields::locator::Locator; -use xrpl_std::host; -use xrpl_std::host::error_codes; -use xrpl_std::host::trace::TraceDataType; -use xrpl_std::host::trace::{trace, trace_num as trace_number}; -use xrpl_std::ledger_entry_ids; -use xrpl_std::sfield; -use xrpl_std::types::blob::DEFAULT_BLOB_SIZE; -use xrpl_std::types::contract_data::XRPL_CONTRACT_DATA_SIZE; -use xrpl_std::types::issue::Issue; -use xrpl_std::types::issue::XrpIssue; -use xrpl_std::types::mpt_id::MptId; - -mod host_bindings_loose; -include!("host_bindings_loose.rs"); - -fn check_result(result: i32, expected: i32, test_name: &'static str) { - match result { - code if code == expected => { - let _ = trace_number(test_name, code.into()); - } - code if code >= 0 => { - let _ = trace(test_name); - let _ = trace_number("TEST FAILED", code.into()); - panic!("Unexpected success code: {}", code); - } - code => { - let _ = trace(test_name); - let _ = trace_number("TEST FAILED", code.into()); - panic!("Error code: {}", code); - } - } -} - -fn with_buffer(mut f: F) -> R -where - F: FnMut(*mut u8, usize) -> R, -{ - let mut buf = [0u8; N]; - f(buf.as_mut_ptr(), buf.len()) -} - -#[unsafe(no_mangle)] -pub extern "C" fn escrow_finish() -> i32 { - let _ = trace("$$$$$ STARTING WASM EXECUTION $$$$$"); - - // ######################################## - // Step #1: Test all host function happy paths - // Note: not testing all the keylet functions, - // that's in a separate test file (all_keylets). - // The float tests are also in a separate file (float_tests). - // ######################################## - with_buffer::<4, _, _>(|ptr, len| { - check_result(unsafe { host::ldgr_index(ptr, len) }, 4, "ldgr_index"); - }); - with_buffer::<4, _, _>(|ptr, len| { - check_result( - unsafe { host::parent_ldgr_time(ptr, len) }, - 4, - "parent_ldgr_time", - ); - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { host::parent_ldgr_hash(ptr, len) }, - 32, - "parent_ldgr_hash", - ); - }); - with_buffer::<4, _, _>(|ptr, len| { - check_result(unsafe { host::base_fee(ptr, len) }, 4, "base_fee"); - }); - let amendment_name: &[u8] = b"test_amendment"; - let amendment_id: [u8; 32] = [1; 32]; - check_result( - unsafe { host::amendment_enabled(amendment_name.as_ptr(), amendment_name.len()) }, - 1, - "amendment_enabled", - ); - check_result( - unsafe { host::amendment_enabled(amendment_id.as_ptr(), amendment_id.len()) }, - 1, - "amendment_enabled", - ); - let tx: EscrowFinish = get_current_escrow_finish(); - let account = tx.get_account().unwrap_or_panic(); // get_tx_field under the hood - let keylet = ledger_entry_ids::accountroot_id(&account).unwrap_or_panic(); // accountroot_id under the hood - check_result( - unsafe { host::cache_le(keylet.as_ptr(), keylet.len(), 0) }, - 1, - "cache_le", - ); - with_buffer::<20, _, _>(|ptr, len| { - check_result( - unsafe { host::home_le_field(sfield::Account.into(), ptr, len) }, - 20, - "home_le_field", - ); - }); - with_buffer::<20, _, _>(|ptr, len| { - check_result( - unsafe { host::le_field(1, sfield::Account.into(), ptr, len) }, - 20, - "le_field", - ); - }); - let mut locator = Locator::new(); - locator.pack(sfield::Account); - with_buffer::<20, _, _>(|ptr, len| { - check_result( - unsafe { host::tx_inner(locator.as_ptr(), locator.len(), ptr, len) }, - 20, - "tx_inner", - ); - }); - with_buffer::<20, _, _>(|ptr, len| { - check_result( - unsafe { host::home_le_inner(locator.as_ptr(), locator.len(), ptr, len) }, - 20, - "home_le_inner", - ); - }); - with_buffer::<20, _, _>(|ptr, len| { - check_result( - unsafe { host::le_inner(1, locator.as_ptr(), locator.len(), ptr, len) }, - 20, - "le_inner", - ); - }); - check_result( - unsafe { host::tx_arr_len(sfield::Memos.into()) }, - 32, - "tx_arr_len", - ); - check_result( - unsafe { host::home_le_arr_len(sfield::Memos.into()) }, - 32, - "home_le_arr_len", - ); - check_result( - unsafe { host::le_arr_len(1, sfield::Memos.into()) }, - 32, - "le_arr_len", - ); - check_result( - unsafe { host::tx_inner_arr_len(locator.as_ptr(), locator.len()) }, - 32, - "tx_inner_arr_len", - ); - check_result( - unsafe { host::home_le_inner_arr_len(locator.as_ptr(), locator.len()) }, - 32, - "home_le_inner_arr_len", - ); - check_result( - unsafe { host::le_inner_arr_len(1, locator.as_ptr(), locator.len()) }, - 32, - "le_inner_arr_len", - ); - check_result( - unsafe { host::set_data(account.0.as_ptr(), account.0.len()) }, - 20, - "set_data", - ); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { host::sha512_half(locator.as_ptr(), locator.len(), ptr, len) }, - 32, - "sha512_half", - ); - }); - let message: &[u8] = b"test message"; - let pubkey: &[u8] = b"test pubkey"; //tx.get_public_key().unwrap_or_panic(); - let signature: &[u8] = b"test signature"; - check_result( - unsafe { - host::check_sig( - message.as_ptr(), - message.len(), - pubkey.as_ptr(), - pubkey.len(), - signature.as_ptr(), - signature.len(), - ) - }, - 1, - "check_sig", - ); - - let nft_id: [u8; 32] = amendment_id; - with_buffer::<18, _, _>(|ptr, len| { - check_result( - unsafe { - host::nft_uri( - account.0.as_ptr(), - account.0.len(), - nft_id.as_ptr(), - nft_id.len(), - ptr, - len, - ) - }, - 18, - "nft_uri", - ) - }); - with_buffer::<20, _, _>(|ptr, len| { - check_result( - unsafe { host::nft_issuer(nft_id.as_ptr(), nft_id.len(), ptr, len) }, - 20, - "nft_issuer", - ) - }); - with_buffer::<4, _, _>(|ptr, len| { - check_result( - unsafe { host::nft_taxon(nft_id.as_ptr(), nft_id.len(), ptr, len) }, - 4, - "nft_taxon", - ) - }); - check_result( - unsafe { host::nft_flags(nft_id.as_ptr(), nft_id.len()) }, - 8, - "nft_flags", - ); - check_result( - unsafe { host::nft_xfer_fee(nft_id.as_ptr(), nft_id.len()) }, - 10, - "nft_xfer_fee", - ); - with_buffer::<4, _, _>(|ptr, len| { - check_result( - unsafe { host::nft_serial(nft_id.as_ptr(), nft_id.len(), ptr, len) }, - 4, - "nft_serial", - ) - }); - let message = "testing trace"; - unsafe { - host::trace( - message.as_ptr(), - message.len(), - TraceDataType::Account as i32, - account.0.as_ptr(), - account.0.len(), - ) - }; - let amount = &[0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F]; // 95 drops of XRP - unsafe { - host::trace( - message.as_ptr(), - message.len(), - TraceDataType::Amount as i32, - amount.as_ptr(), - amount.len(), - ) - }; - let amount = &[0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; // 0 drops of XRP - unsafe { - host::trace( - message.as_ptr(), - message.len(), - TraceDataType::Amount as i32, - amount.as_ptr(), - amount.len(), - ) - }; - - // ######################################## - // Step #2: Test set_data edge cases - // ######################################## - check_result( - unsafe { host_bindings_loose::parent_ldgr_hash(-1, 4) }, - error_codes::INVALID_PARAMS, - "parent_ldgr_hash_neg_ptr", - ); - with_buffer::<4, _, _>(|ptr, _len| { - check_result( - unsafe { host_bindings_loose::parent_ldgr_hash(ptr as i32, -1) }, - error_codes::INVALID_PARAMS, - "parent_ldgr_hash_neg_len", - ) - }); - with_buffer::<3, _, _>(|ptr, len| { - check_result( - unsafe { host_bindings_loose::parent_ldgr_hash(ptr as i32, len as i32) }, - error_codes::BUFFER_TOO_SMALL, - "parent_ldgr_hash_buf_too_small", - ) - }); - with_buffer::<4, _, _>(|ptr, _len| { - check_result( - unsafe { host_bindings_loose::parent_ldgr_hash(ptr as i32, 1_000_000_000) }, - error_codes::POINTER_OUT_OF_BOUNDS, - "parent_ldgr_hash_len_too_long", - ) - }); - - // ######################################## - // Step #3: Test getData[Type] edge cases - // ######################################## - - // SField - check_result( - unsafe { host::tx_arr_len(2) }, // not a valid SField value - error_codes::INVALID_FIELD, - "tx_arr_len_invalid_sfield", - ); - - // Slice - check_result( - unsafe { host_bindings_loose::tx_inner_arr_len(-1, locator.len() as i32) }, - error_codes::INVALID_PARAMS, - "tx_inner_arr_len_neg_ptr", - ); - check_result( - unsafe { host_bindings_loose::tx_inner_arr_len(locator.as_ptr() as i32, -1) }, - error_codes::INVALID_PARAMS, - "tx_inner_arr_len_neg_len", - ); - let long_len = DEFAULT_BLOB_SIZE + 1; - check_result( - unsafe { host_bindings_loose::tx_inner_arr_len(locator.as_ptr() as i32, long_len as i32) }, - error_codes::DATA_FIELD_TOO_LARGE, - "tx_inner_arr_len_too_long", - ); - check_result( - unsafe { - host_bindings_loose::tx_inner_arr_len( - locator.as_ptr() as i32 + 1_000_000_000, - locator.len() as i32, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "tx_inner_arr_len_ptr_oob", - ); - - // uint32 - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::check_id( - account.0.as_ptr(), - account.0.len(), - locator.as_ptr().wrapping_add(1_000_000_000), - 8, - ptr, - len, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "check_id_oob_len_u32", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::check_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "check_id_wrong_len_u32", - ) - }); - - // uint64 - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_from_uint( - locator.as_ptr().wrapping_add(1_000_000_000), - 8, - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_from_uint_len_oob", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_from_uint( - locator.as_ptr(), - locator.len(), - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::INVALID_PARAMS, - "float_from_uint_wrong_len_uint64", - ) - }); - - // uint256 - check_result( - unsafe { - host_bindings_loose::cache_le( - locator.as_ptr() as i32 + 1_000_000_000, - locator.len() as i32, - 1, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "cache_le_ptr_oob", - ); - check_result( - unsafe { host_bindings_loose::cache_le(locator.as_ptr() as i32, locator.len() as i32, 1) }, - error_codes::INVALID_PARAMS, - "cache_le_wrong_len", - ); - - // AccountID - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host_bindings_loose::accountroot_id( - locator.as_ptr() as i32 + 1_000_000_000, - locator.len() as i32, - ptr, - len, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "accountroot_id_len_oob", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host_bindings_loose::accountroot_id( - locator.as_ptr() as i32, - locator.len() as i32, - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "accountroot_id_wrong_len", - ) - }); - - // Currency - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host_bindings_loose::trustline_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - locator.as_ptr() as i32 + 1_000_000_000, - locator.len() as i32, - ptr, - len, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "trustline_id_len_oob_currency", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host_bindings_loose::trustline_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - locator.as_ptr() as i32, - locator.len() as i32, - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "trustline_id_wrong_len_currency", - ) - }); - - // Issue - let asset1_bytes = Issue::XRP(XrpIssue {}).as_bytes(); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::amm_id( - asset1_bytes.as_ptr(), - asset1_bytes.len(), - locator.as_ptr().wrapping_add(1_000_000_000), - locator.len(), - ptr, - len, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "amm_id_len_oob_asset2", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::amm_id( - asset1_bytes.as_ptr(), - asset1_bytes.len(), - locator.as_ptr(), - locator.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "amm_id_len_wrong_len_asset2", - ) - }); - let currency: &[u8] = b"USD00000000000000000"; // 20 bytes - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::amm_id( - asset1_bytes.as_ptr(), - asset1_bytes.len(), - currency.as_ptr(), - currency.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "amm_id_len_wrong_non_xrp_currency_len", - ) - }); - let xrp_issue: &[u8] = &[0; 40]; // 40 bytes - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::amm_id( - xrp_issue.as_ptr(), - xrp_issue.len(), - asset1_bytes.as_ptr(), - asset1_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "amm_id_len_wrong_xrp_currency_len", - ) - }); - let mptid = MptId::new(1, account); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::amm_id( - mptid.as_ptr(), - mptid.len(), - asset1_bytes.as_ptr(), - asset1_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "amm_id_mpt", - ) - }); - - // Out-of-bounds message pointer; nothing to assert on now that trace is void. - let num_bytes = 42i64.to_le_bytes(); - unsafe { - host_bindings_loose::trace_loose( - locator.as_ptr() as i32 + 1_000_000_000, - locator.len() as i32, - TraceDataType::Int64 as i32, - num_bytes.as_ptr() as i32, - num_bytes.len() as i32, - ) - }; - - // ######################################## - // Step #4: Test other host function edge cases - // ######################################## - - // invalid SFields - - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::tx_field(2, ptr, len) }, - error_codes::INVALID_FIELD, - "tx_field_invalid_sfield", - ); - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::home_le_field(2, ptr, len) }, - error_codes::INVALID_FIELD, - "home_le_field_invalid_sfield", - ); - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::le_field(1, 2, ptr, len) }, - error_codes::INVALID_FIELD, - "le_field_invalid_sfield", - ); - }); - check_result( - unsafe { host::tx_arr_len(2) }, - error_codes::INVALID_FIELD, - "tx_arr_len_invalid_sfield", - ); - check_result( - unsafe { host::home_le_arr_len(2) }, - error_codes::INVALID_FIELD, - "home_le_arr_len_invalid_sfield", - ); - check_result( - unsafe { host::le_arr_len(1, 2) }, - error_codes::INVALID_FIELD, - "le_arr_len_invalid_sfield", - ); - - // invalid Slice - - check_result( - unsafe { host::amendment_enabled(amendment_name.as_ptr(), long_len) }, - error_codes::DATA_FIELD_TOO_LARGE, - "amendment_enabled_too_big_slice", - ); - check_result( - unsafe { host::amendment_enabled(amendment_name.as_ptr(), 65) }, - error_codes::DATA_FIELD_TOO_LARGE, - "amendment_enabled_too_long", - ); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::tx_inner(locator.as_ptr(), long_len, ptr, len) }, - error_codes::DATA_FIELD_TOO_LARGE, - "tx_inner_too_big_slice", - ); - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::home_le_inner(locator.as_ptr(), long_len, ptr, len) }, - error_codes::DATA_FIELD_TOO_LARGE, - "home_le_inner_too_big_slice", - ); - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::le_inner(1, locator.as_ptr(), long_len, ptr, len) }, - error_codes::DATA_FIELD_TOO_LARGE, - "le_inner_too_big_slice", - ); - }); - check_result( - unsafe { host::tx_inner_arr_len(locator.as_ptr(), long_len) }, - error_codes::DATA_FIELD_TOO_LARGE, - "tx_inner_arr_len_too_big_slice", - ); - check_result( - unsafe { host::home_le_inner_arr_len(locator.as_ptr(), long_len) }, - error_codes::DATA_FIELD_TOO_LARGE, - "home_le_inner_arr_len_too_big_slice", - ); - check_result( - unsafe { host::le_inner_arr_len(1, locator.as_ptr(), long_len) }, - error_codes::DATA_FIELD_TOO_LARGE, - "le_inner_arr_len_too_big_slice", - ); - let too_big_data_len = XRPL_CONTRACT_DATA_SIZE + 1; - check_result( - unsafe { host::set_data(locator.as_ptr(), too_big_data_len) }, - error_codes::DATA_FIELD_TOO_LARGE, - "set_data_too_big_slice", - ); - check_result( - unsafe { - host::check_sig( - message.as_ptr(), - long_len, - pubkey.as_ptr(), - pubkey.len(), - signature.as_ptr(), - signature.len(), - ) - }, - error_codes::DATA_FIELD_TOO_LARGE, - "check_sig", - ); - check_result( - unsafe { - host::check_sig( - message.as_ptr(), - message.len(), - pubkey.as_ptr(), - long_len, - signature.as_ptr(), - signature.len(), - ) - }, - error_codes::DATA_FIELD_TOO_LARGE, - "check_sig", - ); - check_result( - unsafe { - host::check_sig( - message.as_ptr(), - message.len(), - pubkey.as_ptr(), - pubkey.len(), - signature.as_ptr(), - long_len, - ) - }, - error_codes::DATA_FIELD_TOO_LARGE, - "check_sig", - ); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::sha512_half(locator.as_ptr(), long_len, ptr, len) }, - error_codes::DATA_FIELD_TOO_LARGE, - "sha512_half_too_big_slice", - ); - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::amm_id( - asset1_bytes.as_ptr(), - long_len, - asset1_bytes.as_ptr(), - asset1_bytes.len(), - ptr, - len, - ) - }, - error_codes::DATA_FIELD_TOO_LARGE, - "amm_id_too_big_slice", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::credential_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - locator.as_ptr(), - long_len, - ptr, - len, - ) - }, - error_codes::DATA_FIELD_TOO_LARGE, - "credential_id_too_big_slice", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::mptoken_id( - mptid.as_ptr(), - long_len, - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::DATA_FIELD_TOO_LARGE, - "mptoken_id_too_big_slice_mptid", - ) - }); - unsafe { - host::trace( - message.as_ptr(), - message.len(), - TraceDataType::AsText as i32, - locator.as_ptr().wrapping_add(1_000_000_000), - locator.len(), - ) - }; - let float: [u8; 8] = [0xD4, 0x83, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00]; - unsafe { - host::trace( - message.as_ptr(), - message.len(), - TraceDataType::Xfloat as i32, - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - ) - }; - unsafe { - host::trace( - message.as_ptr(), - message.len(), - TraceDataType::Amount as i32, - locator.as_ptr().wrapping_add(1_000_000_000), - locator.len(), - ) - }; - check_result( - unsafe { - host::float_cmp( - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - float.as_ptr(), - float.len(), - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_cmp_oob_slice1", - ); - check_result( - unsafe { - host::float_cmp( - float.as_ptr(), - float.len(), - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_cmp_oob_slice2", - ); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_add( - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - float.as_ptr(), - float.len(), - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_add_oob_slice1", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_add( - float.as_ptr(), - float.len(), - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_add_oob_slice2", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_sub( - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - float.as_ptr(), - float.len(), - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_sub_oob_slice1", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_sub( - float.as_ptr(), - float.len(), - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_sub_oob_slice2", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_mult( - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - float.as_ptr(), - float.len(), - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_mult_oob_slice1", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_mult( - float.as_ptr(), - float.len(), - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_mult_oob_slice2", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_div( - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - float.as_ptr(), - float.len(), - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_div_oob_slice1", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_div( - float.as_ptr(), - float.len(), - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_div_oob_slice2", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::float_pow( - float.as_ptr().wrapping_add(1_000_000_000), - float.len(), - 3, - ptr, - len, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }, - error_codes::POINTER_OUT_OF_BOUNDS, - "float_pow_oob_slice", - ) - }); - - // invalid UInt32 - - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::escrow_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "escrow_id_wrong_size_uint32", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::mpt_issuance_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "mpt_issuance_id_wrong_size_uint32", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::nft_offer_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "nft_offer_id_wrong_size_uint32", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::offer_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "offer_id_wrong_size_uint32", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::oracle_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "oracle_id_wrong_size_uint32", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::paychan_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "paychan_id_wrong_size_uint32", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::permissioned_domain_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "permissioned_domain_id_wrong_size_uint32", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::ticket_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "ticket_id_wrong_size_uint32", - ) - }); - with_buffer::<32, _, _>(|ptr, len| { - check_result( - unsafe { - host::vault_id( - account.0.as_ptr(), - account.0.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "vault_id_wrong_size_uint32", - ) - }); - - // invalid UInt256 - - check_result( - unsafe { host::cache_le(locator.as_ptr(), locator.len(), 0) }, - error_codes::INVALID_PARAMS, - "cache_le_wrong_size_uint256", - ); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::nft_uri( - account.0.as_ptr(), - account.0.len(), - locator.as_ptr(), - locator.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "nft_uri_wrong_size_uint256", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::nft_issuer(locator.as_ptr(), locator.len(), ptr, len) }, - error_codes::INVALID_PARAMS, - "nft_issuer_wrong_size_uint256", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::nft_taxon(locator.as_ptr(), locator.len(), ptr, len) }, - error_codes::INVALID_PARAMS, - "nft_taxon_wrong_size_uint256", - ) - }); - check_result( - unsafe { host::nft_flags(locator.as_ptr(), locator.len()) }, - error_codes::INVALID_PARAMS, - "nft_flags_wrong_size_uint256", - ); - check_result( - unsafe { host::nft_xfer_fee(locator.as_ptr(), locator.len()) }, - error_codes::INVALID_PARAMS, - "nft_xfer_fee_wrong_size_uint256", - ); - with_buffer::<4, _, _>(|ptr, len| { - check_result( - unsafe { host::nft_serial(locator.as_ptr(), locator.len(), ptr, len) }, - error_codes::INVALID_PARAMS, - "nft_serial_wrong_size_uint256", - ) - }); - - // invalid AccountID - - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::accountroot_id(locator.as_ptr(), locator.len(), ptr, len) }, - error_codes::INVALID_PARAMS, - "accountroot_id_wrong_size_account_id", - ) - }); - let seq: i32 = 1; - let seq_bytes = seq.to_be_bytes(); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::check_id( - locator.as_ptr(), - locator.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "check_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::credential_id( - locator.as_ptr(), // invalid AccountID size - locator.len(), - account.0.as_ptr(), - account.0.len(), - locator.as_ptr(), // valid slice size - locator.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "credential_id_wrong_size_account_id1", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::credential_id( - account.0.as_ptr(), - account.0.len(), - locator.as_ptr(), // invalid AccountID size - locator.len(), - locator.as_ptr(), // valid slice size - locator.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "credential_id_wrong_size_account_id2", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::delegate_id( - locator.as_ptr(), // invalid AccountID size - locator.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "delegate_id_wrong_size_account_id1", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::delegate_id( - account.0.as_ptr(), - account.0.len(), - locator.as_ptr(), // invalid AccountID size - locator.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "delegate_id_wrong_size_account_id2", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::deposit_preauth_id( - locator.as_ptr(), // invalid AccountID size - locator.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "deposit_preauth_id_wrong_size_account_id1", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::deposit_preauth_id( - account.0.as_ptr(), - account.0.len(), - locator.as_ptr(), // invalid AccountID size - locator.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "deposit_preauth_id_wrong_size_account_id2", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::did_id(locator.as_ptr(), locator.len(), ptr, len) }, - error_codes::INVALID_PARAMS, - "did_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::escrow_id( - locator.as_ptr(), - locator.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "escrow_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::trustline_id( - locator.as_ptr(), // invalid AccountID size - locator.len(), - account.0.as_ptr(), - account.0.len(), - currency.as_ptr(), - currency.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "trustline_id_wrong_size_account_id1", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::trustline_id( - account.0.as_ptr(), - account.0.len(), - locator.as_ptr(), // invalid AccountID size - locator.len(), - currency.as_ptr(), - currency.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "trustline_id_wrong_size_account_id2", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::mpt_issuance_id( - locator.as_ptr(), - locator.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "mpt_issuance_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::mptoken_id( - mptid.as_ptr(), - mptid.len(), - locator.as_ptr(), - locator.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "mptoken_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::nft_offer_id( - locator.as_ptr(), - locator.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "nft_offer_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::offer_id( - locator.as_ptr(), - locator.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "offer_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::oracle_id( - locator.as_ptr(), - locator.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "oracle_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::paychan_id( - locator.as_ptr(), // invalid AccountID size - locator.len(), - account.0.as_ptr(), - account.0.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "paychan_id_wrong_size_account_id1", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::paychan_id( - account.0.as_ptr(), - account.0.len(), - locator.as_ptr(), // invalid AccountID size - locator.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "paychan_id_wrong_size_account_id2", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::permissioned_domain_id( - locator.as_ptr(), - locator.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "permissioned_domain_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { host::signers_id(locator.as_ptr(), locator.len(), ptr, len) }, - error_codes::INVALID_PARAMS, - "signers_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::ticket_id( - locator.as_ptr(), - locator.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "ticket_id_wrong_size_account_id", - ) - }); - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::vault_id( - locator.as_ptr(), - locator.len(), - seq_bytes.as_ptr(), - seq_bytes.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "vault_id_wrong_size_account_id", - ) - }); - let uint256: &[u8] = b"00000000000000000000000000000001"; - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::nft_uri( - locator.as_ptr(), - locator.len(), - uint256.as_ptr(), - uint256.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "nft_uri_wrong_size_account_id", - ) - }); - unsafe { - host::trace( - message.as_ptr(), - message.len(), - TraceDataType::Account as i32, - locator.as_ptr(), - locator.len(), - ) - }; - - // invalid Currency was already tested above - // invalid string - - unsafe { - host::trace( - message.as_ptr().wrapping_add(1_000_000_000), - message.len(), - TraceDataType::AsText as i32, - uint256.as_ptr(), - uint256.len(), - ) - }; - unsafe { - host::trace( - message.as_ptr().wrapping_add(1_000_000_000), - message.len(), - TraceDataType::Xfloat as i32, - float.as_ptr(), - float.len(), - ) - }; - unsafe { - host::trace( - message.as_ptr().wrapping_add(1_000_000_000), - message.len(), - TraceDataType::Account as i32, - account.0.as_ptr(), - account.0.len(), - ) - }; - unsafe { - host::trace( - message.as_ptr().wrapping_add(1_000_000_000), - message.len(), - TraceDataType::Amount as i32, - amount.as_ptr(), - amount.len(), - ) - }; - - // trace too large - - unsafe { - host::trace( - locator.as_ptr(), - locator.len(), - TraceDataType::AsText as i32, - locator.as_ptr(), - long_len, - ) - }; - let too_long_num = 1i64.to_le_bytes(); - unsafe { - host::trace( - locator.as_ptr(), - long_len, - TraceDataType::Int64 as i32, - too_long_num.as_ptr(), - too_long_num.len(), - ) - }; - unsafe { - host::trace( - message.as_ptr(), - long_len, - TraceDataType::Xfloat as i32, - float.as_ptr(), - float.len(), - ) - }; - unsafe { - host::trace( - message.as_ptr(), - long_len, - TraceDataType::Account as i32, - account.0.as_ptr(), - account.0.len(), - ) - }; - unsafe { - host::trace( - message.as_ptr(), - long_len, - TraceDataType::Amount as i32, - amount.as_ptr(), - amount.len(), - ) - }; - - // trace amount errors - - unsafe { - host::trace( - message.as_ptr(), - message.len(), - TraceDataType::Amount as i32, - locator.as_ptr(), - locator.len(), - ) - }; - - // other misc errors - - with_buffer::<2, _, _>(|ptr, len| { - check_result( - unsafe { - host::mptoken_id( - locator.as_ptr(), - locator.len(), - account.0.as_ptr(), - account.0.len(), - ptr, - len, - ) - }, - error_codes::INVALID_PARAMS, - "mptoken_id_mptid_wrong_length", - ) - }); - // Unknown data_type: the host logs "invalid arguments" and returns. - unsafe { - host::trace( - message.as_ptr(), - message.len(), - 99, - locator.as_ptr(), - locator.len(), - ) - }; - - // ensure that the Slice index desync issue is fixed - let empty: &[u8] = b""; - unsafe { - host::trace( - empty.as_ptr(), - empty.len(), - TraceDataType::Account as i32, - account.0.as_ptr(), - account.0.len(), - ) - }; - - 1 // <-- If we get here, finish the escrow. -} diff --git a/src/test/app/wasm_fixtures/copyFixtures.py b/src/test/app/wasm_fixtures/copyFixtures.py deleted file mode 100644 index 23d116cbef..0000000000 --- a/src/test/app/wasm_fixtures/copyFixtures.py +++ /dev/null @@ -1,302 +0,0 @@ -# cspell: disable -import os -import re -import shlex -import subprocess -import sys -import tempfile -import zipfile -from difflib import get_close_matches - -OPT = "-Oz" -BASE_PATH = os.path.abspath(os.path.dirname(__file__)) - - -def pascal_case(name): - return "".join(word[:1].upper() + word[1:] for word in re.split(r"[_\W]+", name)) - - -def normalize_name(name): - name = re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", name) - return re.sub(r"[^a-z0-9]", "", name.lower()) - - -def fixture_key(name): - name = normalize_name(name).removeprefix("k") - return name.removesuffix("wasmhex").removesuffix("hex") - - -def declared_fixtures(): - h_path = os.path.join(BASE_PATH, "fixtures.h") - with open(h_path, "r", encoding="utf8") as f: - return re.findall( - r"extern std::string const ([A-Za-z_][A-Za-z0-9_]*);", f.read() - ) - - -def find_fixture_name(project_name, suffix): - default = re.sub(r"_([a-z])", lambda m: m.group(1).upper(), project_name) + suffix - k_default = f"k{pascal_case(project_name)}{suffix}" - declarations = declared_fixtures() - normalized = {normalize_name(name): name for name in declarations} - fixture_keys = {fixture_key(name): name for name in declarations} - - for name in (default, k_default): - if normalize_name(name) in normalized: - return normalized[normalize_name(name)] - - project_key = normalize_name(project_name) - matches = [ - name - for key, name in fixture_keys.items() - if key.endswith(project_key) - or key.startswith(project_key) - or project_key.endswith(key) - or project_key.startswith(key) - ] - if len(matches) == 1: - return matches[0] - - close = get_close_matches(project_key, fixture_keys.keys(), n=1, cutoff=0.82) - if close: - return fixture_keys[close[0]] - - return k_default - - -def fixture_cpp_path(fixture_name): - pattern = rf"extern std::string const {fixture_name} =" - for file_name in os.listdir(BASE_PATH): - if not file_name.endswith(".cpp"): - continue - cpp_path = os.path.join(BASE_PATH, file_name) - with open(cpp_path, "r", encoding="utf8") as f: - if re.search(pattern, f.read()): - return cpp_path - return os.path.join(BASE_PATH, "fixtures.cpp") - - -def update_fixture(project_name, wasm, suffix="WasmHex"): - fixture_name = find_fixture_name(project_name, suffix) - print(f"Updating fixture: {fixture_name}") - - cpp_path = fixture_cpp_path(fixture_name) - h_path = os.path.join(BASE_PATH, "fixtures.h") - with open(cpp_path, "r", encoding="utf8") as f: - cpp_content = f.read() - - pattern = rf'extern std::string const {fixture_name} =[ \n]+"[^;]*;' - if re.search(pattern, cpp_content, flags=re.MULTILINE): - updated_cpp_content = re.sub( - pattern, - f'extern std::string const {fixture_name} = "{wasm}";', - cpp_content, - flags=re.MULTILINE, - ) - else: - with open(h_path, "r", encoding="utf8") as f: - h_content = f.read() - updated_h_content = ( - h_content.rstrip() + f"\n\nextern std::string const {fixture_name};\n" - ) - with open(h_path, "w", encoding="utf8") as f: - f.write(updated_h_content) - updated_cpp_content = ( - cpp_content.rstrip() - + f'\n\nextern std::string const {fixture_name} = "{wasm}";\n' - ) - - with open(cpp_path, "w", encoding="utf8") as f: - f.write(updated_cpp_content) - - -def read_wasm_hex(path): - with open(path, "rb") as f: - return f.read().hex() - - -def process_rust(project_name): - project_path = os.path.join(BASE_PATH, project_name) - wasm_location = os.path.join( - project_path, "target", "wasm32v1-none", "release", f"{project_name}.wasm" - ) - try: - subprocess.run( - ["cargo", "build", "--target", "wasm32v1-none", "--release"], - cwd=project_path, - check=True, - ) - subprocess.run( - ["wasm-opt", wasm_location, OPT, "-o", wasm_location], check=True - ) - print(f"WASM file for {project_name} has been built and optimized.") - except FileNotFoundError as e: - print(f"exec error: {e.filename} is required to build Rust fixtures") - sys.exit(1) - except subprocess.CalledProcessError as e: - print(f"exec error: {e}") - sys.exit(1) - - update_fixture(project_name, read_wasm_hex(wasm_location)) - - -def process_c(project_name): - project_path = os.path.join(BASE_PATH, f"{project_name}.c") - wasm_path = os.path.join(BASE_PATH, f"{project_name}.wasm") - cc = os.environ.get("CC") - sysroot = os.environ.get("SYSROOT") - if not cc or not sysroot: - print("exec error: CC and SYSROOT are required to build C fixtures") - sys.exit(1) - - build_cmd = [ - *shlex.split(cc), - f"--sysroot={sysroot}", - "-O3", - "-ffast-math", - "--target=wasm32", - "-fno-exceptions", - "-fno-threadsafe-statics", - "-fvisibility=default", - "-Wl,--export-all", - "-Wl,--no-entry", - "-Wl,--allow-undefined", - "-DNDEBUG", - "--no-standard-libraries", - "-fno-builtin-memset", - "-o", - wasm_path, - project_path, - ] - try: - subprocess.run(build_cmd, check=True) - subprocess.run(["wasm-opt", wasm_path, OPT, "-o", wasm_path], check=True) - print( - f"WASM file for {project_name} has been built with WASI support using clang." - ) - except FileNotFoundError as e: - print(f"exec error: {e.filename} is required to build C fixtures") - sys.exit(1) - except subprocess.CalledProcessError as e: - print(f"exec error: {e}") - sys.exit(1) - - update_fixture(project_name, read_wasm_hex(wasm_path)) - - -def wat_to_wasm(wat_path, wasm_path): - build_cmd = ["wat2wasm", "--enable-all", wat_path, "-o", wasm_path] - try: - subprocess.run(build_cmd, check=True) - print(f"WASM file for {os.path.basename(wat_path)} has been built.") - return - except FileNotFoundError: - print("exec error: wat2wasm is required to build WAT fixtures") - sys.exit(1) - except subprocess.CalledProcessError: - # wat2wasm (wabt) does not support some proposal text syntax such as - # the GC instructions, so fall back to wasm-tools which does. - pass - - fallback_cmd = ["wasm-tools", "parse", wat_path, "-o", wasm_path] - try: - subprocess.run(fallback_cmd, check=True) - print( - f"WASM file for {os.path.basename(wat_path)} has been built with wasm-tools." - ) - except FileNotFoundError: - print("exec error: wasm-tools is required to build this WAT fixture") - sys.exit(1) - except subprocess.CalledProcessError as e: - print(f"exec error: {e}") - sys.exit(1) - - -def process_wat_file(wat_path): - project_name = os.path.splitext(os.path.basename(wat_path))[0] - with open(wat_path, "r", encoding="utf8") as f: - if "(module" not in f.read(): - print(f"Skipping WAT fixture without a module: {project_name}") - return - - with tempfile.TemporaryDirectory() as tmpdir: - wasm_path = os.path.join(tmpdir, f"{project_name}.wasm") - wat_to_wasm(wat_path, wasm_path) - update_fixture(project_name, read_wasm_hex(wasm_path), "Hex") - - -def process_wat_zip(zip_path): - project_name = os.path.splitext(os.path.basename(zip_path))[0] - with tempfile.TemporaryDirectory() as tmpdir: - with zipfile.ZipFile(zip_path) as archive: - wat_names = [name for name in archive.namelist() if name.endswith(".wat")] - if len(wat_names) != 1: - print(f"exec error: expected one .wat file in {zip_path}") - sys.exit(1) - archive.extract(wat_names[0], tmpdir) - - wasm_path = os.path.join(tmpdir, f"{project_name}.wasm") - wat_to_wasm(os.path.join(tmpdir, wat_names[0]), wasm_path) - update_fixture(project_name, read_wasm_hex(wasm_path), "Hex") - - -def process_wat(project_name): - candidates = [ - os.path.join(BASE_PATH, f"{project_name}.wat"), - os.path.join(BASE_PATH, "wat", f"{project_name}.wat"), - os.path.join(BASE_PATH, "wat", f"{project_name}.zip"), - ] - for path in candidates: - if os.path.isfile(path): - if path.endswith(".zip"): - process_wat_zip(path) - else: - process_wat_file(path) - return - - print(f"exec error: fixture {project_name} not found") - sys.exit(1) - - -if __name__ == "__main__": - if len(sys.argv) > 2: - print("Usage: python copyFixtures.py []") - sys.exit(1) - - if len(sys.argv) == 2: - project_name = os.path.splitext(os.path.basename(sys.argv[1]))[0] - if os.path.isfile(os.path.join(BASE_PATH, project_name, "Cargo.toml")): - process_rust(project_name) - elif os.path.isfile(os.path.join(BASE_PATH, f"{project_name}.c")): - process_c(project_name) - else: - process_wat(project_name) - print("Fixture has been processed.") - else: - dirs = [ - d - for d in os.listdir(BASE_PATH) - if os.path.isfile(os.path.join(BASE_PATH, d, "Cargo.toml")) - ] - c_files = [f for f in os.listdir(BASE_PATH) if f.endswith(".c")] - wat_files = [f for f in os.listdir(BASE_PATH) if f.endswith(".wat")] - wat_path = os.path.join(BASE_PATH, "wat") - wat_fixture_files = [ - f - for f in (os.listdir(wat_path) if os.path.isdir(wat_path) else []) - if f.endswith((".wat", ".zip")) - ] - - for d in sorted(dirs): - process_rust(d) - for c in sorted(c_files): - process_c(c[:-2]) - for wat in sorted(wat_files): - process_wat_file(os.path.join(BASE_PATH, wat)) - for wat_fixture in sorted(wat_fixture_files): - path = os.path.join(wat_path, wat_fixture) - if wat_fixture.endswith(".zip"): - process_wat_zip(path) - else: - process_wat_file(path) - print("All fixtures have been processed.") diff --git a/src/test/app/wasm_fixtures/disableFloat.wat b/src/test/app/wasm_fixtures/disableFloat.wat deleted file mode 100644 index 5e09371ee9..0000000000 --- a/src/test/app/wasm_fixtures/disableFloat.wat +++ /dev/null @@ -1,34 +0,0 @@ -(module - (type (;0;) (func)) - (type (;1;) (func (result i32))) - (func (;0;) (type 0)) - (func (;1;) (type 1) (result i32) - f32.const -2048 - f32.const 2050 - f32.sub - drop - i32.const 1) - (memory (;0;) 2) - (global (;0;) i32 (i32.const 1024)) - (global (;1;) i32 (i32.const 1024)) - (global (;2;) i32 (i32.const 2048)) - (global (;3;) i32 (i32.const 2048)) - (global (;4;) i32 (i32.const 67584)) - (global (;5;) i32 (i32.const 1024)) - (global (;6;) i32 (i32.const 67584)) - (global (;7;) i32 (i32.const 131072)) - (global (;8;) i32 (i32.const 0)) - (global (;9;) i32 (i32.const 1)) - (export "memory" (memory 0)) - (export "__wasm_call_ctors" (func 0)) - (export "escrow_finish" (func 1)) - (export "buf" (global 0)) - (export "__dso_handle" (global 1)) - (export "__data_end" (global 2)) - (export "__stack_low" (global 3)) - (export "__stack_high" (global 4)) - (export "__global_base" (global 5)) - (export "__heap_base" (global 6)) - (export "__heap_end" (global 7)) - (export "__memory_base" (global 8)) - (export "__table_base" (global 9))) diff --git a/src/test/app/wasm_fixtures/fib.c b/src/test/app/wasm_fixtures/fib.c deleted file mode 100644 index e45cc4fe6c..0000000000 --- a/src/test/app/wasm_fixtures/fib.c +++ /dev/null @@ -1,11 +0,0 @@ -// typedef long long mint; -typedef int mint; - -mint fib(mint n) -{ - if (!n) - return 0; - if (n <= 2) - return 1; - return fib(n - 1) + fib(n - 2); -} diff --git a/src/test/app/wasm_fixtures/fixture_functions_5k.cpp b/src/test/app/wasm_fixtures/fixture_functions_5k.cpp deleted file mode 100644 index d65f602eec..0000000000 --- a/src/test/app/wasm_fixtures/fixture_functions_5k.cpp +++ /dev/null @@ -1,2240 +0,0 @@ -// TODO: consider moving these to separate files (and figure out the build) - -#include - -#include - -extern std::string const kFunctions5kHex = - "0061736d0100000001070160027f7f017f038a27882700000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000000000000000000007e2d303882708" - "7465737430303030000008746573743030303100010874657374303030320002087465737430303033000308746573" - "7430303034000408746573743030303500050874657374303030360006087465737430303037000708746573743030" - "303800080874657374303030390009087465737430303130000a087465737430303131000b08746573743030313200" - "0c087465737430303133000d087465737430303134000e087465737430303135000f08746573743030313600100874" - "6573743030313700110874657374303031380012087465737430303139001308746573743030323000140874657374" - "3030323100150874657374303032320016087465737430303233001708746573743030323400180874657374303032" - "350019087465737430303236001a087465737430303237001b087465737430303238001c087465737430303239001d" - "087465737430303330001e087465737430303331001f08746573743030333200200874657374303033330021087465" - "7374303033340022087465737430303335002308746573743030333600240874657374303033370025087465737430" - "3033380026087465737430303339002708746573743030343000280874657374303034310029087465737430303432" - "002a087465737430303433002b087465737430303434002c087465737430303435002d087465737430303436002e08" - "7465737430303437002f08746573743030343800300874657374303034390031087465737430303530003208746573" - "7430303531003308746573743030353200340874657374303035330035087465737430303534003608746573743030" - "3535003708746573743030353600380874657374303035370039087465737430303538003a08746573743030353900" - "3b087465737430303630003c087465737430303631003d087465737430303632003e087465737430303633003f0874" - "6573743030363400400874657374303036350041087465737430303636004208746573743030363700430874657374" - "3030363800440874657374303036390045087465737430303730004608746573743030373100470874657374303037" - "3200480874657374303037330049087465737430303734004a087465737430303735004b087465737430303736004c" - "087465737430303737004d087465737430303738004e087465737430303739004f0874657374303038300050087465" - "7374303038310051087465737430303832005208746573743030383300530874657374303038340054087465737430" - "3038350055087465737430303836005608746573743030383700570874657374303038380058087465737430303839" - "0059087465737430303930005a087465737430303931005b087465737430303932005c087465737430303933005d08" - "7465737430303934005e087465737430303935005f0874657374303039360060087465737430303937006108746573" - "7430303938006208746573743030393900630874657374303130300064087465737430313031006508746573743031" - "3032006608746573743031303300670874657374303130340068087465737430313035006908746573743031303600" - "6a087465737430313037006b087465737430313038006c087465737430313039006d087465737430313130006e0874" - "65737430313131006f0874657374303131320070087465737430313133007108746573743031313400720874657374" - "3031313500730874657374303131360074087465737430313137007508746573743031313800760874657374303131" - "39007708746573743031323000780874657374303132310079087465737430313232007a087465737430313233007b" - "087465737430313234007c087465737430313235007d087465737430313236007e087465737430313237007f087465" - "7374303132380080010874657374303132390081010874657374303133300082010874657374303133310083010874" - "6573743031333200840108746573743031333300850108746573743031333400860108746573743031333500870108" - "7465737430313336008801087465737430313337008901087465737430313338008a01087465737430313339008b01" - "087465737430313430008c01087465737430313431008d01087465737430313432008e01087465737430313433008f" - "0108746573743031343400900108746573743031343500910108746573743031343600920108746573743031343700" - "9301087465737430313438009401087465737430313439009501087465737430313530009601087465737430313531" - "009701087465737430313532009801087465737430313533009901087465737430313534009a010874657374303135" - "35009b01087465737430313536009c01087465737430313537009d01087465737430313538009e0108746573743031" - "3539009f0108746573743031363000a00108746573743031363100a10108746573743031363200a201087465737430" - "31363300a30108746573743031363400a40108746573743031363500a50108746573743031363600a6010874657374" - "3031363700a70108746573743031363800a80108746573743031363900a90108746573743031373000aa0108746573" - "743031373100ab0108746573743031373200ac0108746573743031373300ad0108746573743031373400ae01087465" - "73743031373500af0108746573743031373600b00108746573743031373700b10108746573743031373800b2010874" - "6573743031373900b30108746573743031383000b40108746573743031383100b50108746573743031383200b60108" - "746573743031383300b70108746573743031383400b80108746573743031383500b90108746573743031383600ba01" - "08746573743031383700bb0108746573743031383800bc0108746573743031383900bd0108746573743031393000be" - "0108746573743031393100bf0108746573743031393200c00108746573743031393300c10108746573743031393400" - "c20108746573743031393500c30108746573743031393600c40108746573743031393700c501087465737430313938" - "00c60108746573743031393900c70108746573743032303000c80108746573743032303100c9010874657374303230" - "3200ca0108746573743032303300cb0108746573743032303400cc0108746573743032303500cd0108746573743032" - "303600ce0108746573743032303700cf0108746573743032303800d00108746573743032303900d101087465737430" - "32313000d20108746573743032313100d30108746573743032313200d40108746573743032313300d5010874657374" - "3032313400d60108746573743032313500d70108746573743032313600d80108746573743032313700d90108746573" - "743032313800da0108746573743032313900db0108746573743032323000dc0108746573743032323100dd01087465" - "73743032323200de0108746573743032323300df0108746573743032323400e00108746573743032323500e1010874" - "6573743032323600e20108746573743032323700e30108746573743032323800e40108746573743032323900e50108" - "746573743032333000e60108746573743032333100e70108746573743032333200e80108746573743032333300e901" - "08746573743032333400ea0108746573743032333500eb0108746573743032333600ec0108746573743032333700ed" - "0108746573743032333800ee0108746573743032333900ef0108746573743032343000f00108746573743032343100" - "f10108746573743032343200f20108746573743032343300f30108746573743032343400f401087465737430323435" - "00f50108746573743032343600f60108746573743032343700f70108746573743032343800f8010874657374303234" - "3900f90108746573743032353000fa0108746573743032353100fb0108746573743032353200fc0108746573743032" - "353300fd0108746573743032353400fe0108746573743032353500ff01087465737430323536008002087465737430" - "3235370081020874657374303235380082020874657374303235390083020874657374303236300084020874657374" - "3032363100850208746573743032363200860208746573743032363300870208746573743032363400880208746573" - "7430323635008902087465737430323636008a02087465737430323637008b02087465737430323638008c02087465" - "737430323639008d02087465737430323730008e02087465737430323731008f020874657374303237320090020874" - "6573743032373300910208746573743032373400920208746573743032373500930208746573743032373600940208" - "7465737430323737009502087465737430323738009602087465737430323739009702087465737430323830009802" - "087465737430323831009902087465737430323832009a02087465737430323833009b02087465737430323834009c" - "02087465737430323835009d02087465737430323836009e02087465737430323837009f0208746573743032383800" - "a00208746573743032383900a10208746573743032393000a20208746573743032393100a302087465737430323932" - "00a40208746573743032393300a50208746573743032393400a60208746573743032393500a7020874657374303239" - "3600a80208746573743032393700a90208746573743032393800aa0208746573743032393900ab0208746573743033" - "303000ac0208746573743033303100ad0208746573743033303200ae0208746573743033303300af02087465737430" - "33303400b00208746573743033303500b10208746573743033303600b20208746573743033303700b3020874657374" - "3033303800b40208746573743033303900b50208746573743033313000b60208746573743033313100b70208746573" - "743033313200b80208746573743033313300b90208746573743033313400ba0208746573743033313500bb02087465" - "73743033313600bc0208746573743033313700bd0208746573743033313800be0208746573743033313900bf020874" - "6573743033323000c00208746573743033323100c10208746573743033323200c20208746573743033323300c30208" - "746573743033323400c40208746573743033323500c50208746573743033323600c60208746573743033323700c702" - "08746573743033323800c80208746573743033323900c90208746573743033333000ca0208746573743033333100cb" - "0208746573743033333200cc0208746573743033333300cd0208746573743033333400ce0208746573743033333500" - "cf0208746573743033333600d00208746573743033333700d10208746573743033333800d202087465737430333339" - "00d30208746573743033343000d40208746573743033343100d50208746573743033343200d6020874657374303334" - "3300d70208746573743033343400d80208746573743033343500d90208746573743033343600da0208746573743033" - "343700db0208746573743033343800dc0208746573743033343900dd0208746573743033353000de02087465737430" - "33353100df0208746573743033353200e00208746573743033353300e10208746573743033353400e2020874657374" - "3033353500e30208746573743033353600e40208746573743033353700e50208746573743033353800e60208746573" - "743033353900e70208746573743033363000e80208746573743033363100e90208746573743033363200ea02087465" - "73743033363300eb0208746573743033363400ec0208746573743033363500ed0208746573743033363600ee020874" - "6573743033363700ef0208746573743033363800f00208746573743033363900f10208746573743033373000f20208" - "746573743033373100f30208746573743033373200f40208746573743033373300f50208746573743033373400f602" - "08746573743033373500f70208746573743033373600f80208746573743033373700f90208746573743033373800fa" - "0208746573743033373900fb0208746573743033383000fc0208746573743033383100fd0208746573743033383200" - "fe0208746573743033383300ff02087465737430333834008003087465737430333835008103087465737430333836" - "0082030874657374303338370083030874657374303338380084030874657374303338390085030874657374303339" - "3000860308746573743033393100870308746573743033393200880308746573743033393300890308746573743033" - "3934008a03087465737430333935008b03087465737430333936008c03087465737430333937008d03087465737430" - "333938008e03087465737430333939008f030874657374303430300090030874657374303430310091030874657374" - "3034303200920308746573743034303300930308746573743034303400940308746573743034303500950308746573" - "7430343036009603087465737430343037009703087465737430343038009803087465737430343039009903087465" - "737430343130009a03087465737430343131009b03087465737430343132009c03087465737430343133009d030874" - "65737430343134009e03087465737430343135009f0308746573743034313600a00308746573743034313700a10308" - "746573743034313800a20308746573743034313900a30308746573743034323000a40308746573743034323100a503" - "08746573743034323200a60308746573743034323300a70308746573743034323400a80308746573743034323500a9" - "0308746573743034323600aa0308746573743034323700ab0308746573743034323800ac0308746573743034323900" - "ad0308746573743034333000ae0308746573743034333100af0308746573743034333200b003087465737430343333" - "00b10308746573743034333400b20308746573743034333500b30308746573743034333600b4030874657374303433" - "3700b50308746573743034333800b60308746573743034333900b70308746573743034343000b80308746573743034" - "343100b90308746573743034343200ba0308746573743034343300bb0308746573743034343400bc03087465737430" - "34343500bd0308746573743034343600be0308746573743034343700bf0308746573743034343800c0030874657374" - "3034343900c10308746573743034353000c20308746573743034353100c30308746573743034353200c40308746573" - "743034353300c50308746573743034353400c60308746573743034353500c70308746573743034353600c803087465" - "73743034353700c90308746573743034353800ca0308746573743034353900cb0308746573743034363000cc030874" - "6573743034363100cd0308746573743034363200ce0308746573743034363300cf0308746573743034363400d00308" - "746573743034363500d10308746573743034363600d20308746573743034363700d30308746573743034363800d403" - "08746573743034363900d50308746573743034373000d60308746573743034373100d70308746573743034373200d8" - "0308746573743034373300d90308746573743034373400da0308746573743034373500db0308746573743034373600" - "dc0308746573743034373700dd0308746573743034373800de0308746573743034373900df03087465737430343830" - "00e00308746573743034383100e10308746573743034383200e20308746573743034383300e3030874657374303438" - "3400e40308746573743034383500e50308746573743034383600e60308746573743034383700e70308746573743034" - "383800e80308746573743034383900e90308746573743034393000ea0308746573743034393100eb03087465737430" - "34393200ec0308746573743034393300ed0308746573743034393400ee0308746573743034393500ef030874657374" - "3034393600f00308746573743034393700f10308746573743034393800f20308746573743034393900f30308746573" - "743035303000f40308746573743035303100f50308746573743035303200f60308746573743035303300f703087465" - "73743035303400f80308746573743035303500f90308746573743035303600fa0308746573743035303700fb030874" - "6573743035303800fc0308746573743035303900fd0308746573743035313000fe0308746573743035313100ff0308" - "7465737430353132008004087465737430353133008104087465737430353134008204087465737430353135008304" - "0874657374303531360084040874657374303531370085040874657374303531380086040874657374303531390087" - "04087465737430353230008804087465737430353231008904087465737430353232008a0408746573743035323300" - "8b04087465737430353234008c04087465737430353235008d04087465737430353236008e04087465737430353237" - "008f040874657374303532380090040874657374303532390091040874657374303533300092040874657374303533" - "3100930408746573743035333200940408746573743035333300950408746573743035333400960408746573743035" - "3335009704087465737430353336009804087465737430353337009904087465737430353338009a04087465737430" - "353339009b04087465737430353430009c04087465737430353431009d04087465737430353432009e040874657374" - "30353433009f0408746573743035343400a00408746573743035343500a10408746573743035343600a20408746573" - "743035343700a30408746573743035343800a40408746573743035343900a50408746573743035353000a604087465" - "73743035353100a70408746573743035353200a80408746573743035353300a90408746573743035353400aa040874" - "6573743035353500ab0408746573743035353600ac0408746573743035353700ad0408746573743035353800ae0408" - "746573743035353900af0408746573743035363000b00408746573743035363100b10408746573743035363200b204" - "08746573743035363300b30408746573743035363400b40408746573743035363500b50408746573743035363600b6" - "0408746573743035363700b70408746573743035363800b80408746573743035363900b90408746573743035373000" - "ba0408746573743035373100bb0408746573743035373200bc0408746573743035373300bd04087465737430353734" - "00be0408746573743035373500bf0408746573743035373600c00408746573743035373700c1040874657374303537" - "3800c20408746573743035373900c30408746573743035383000c40408746573743035383100c50408746573743035" - "383200c60408746573743035383300c70408746573743035383400c80408746573743035383500c904087465737430" - "35383600ca0408746573743035383700cb0408746573743035383800cc0408746573743035383900cd040874657374" - "3035393000ce0408746573743035393100cf0408746573743035393200d00408746573743035393300d10408746573" - "743035393400d20408746573743035393500d30408746573743035393600d40408746573743035393700d504087465" - "73743035393800d60408746573743035393900d70408746573743036303000d80408746573743036303100d9040874" - "6573743036303200da0408746573743036303300db0408746573743036303400dc0408746573743036303500dd0408" - "746573743036303600de0408746573743036303700df0408746573743036303800e00408746573743036303900e104" - "08746573743036313000e20408746573743036313100e30408746573743036313200e40408746573743036313300e5" - "0408746573743036313400e60408746573743036313500e70408746573743036313600e80408746573743036313700" - "e90408746573743036313800ea0408746573743036313900eb0408746573743036323000ec04087465737430363231" - "00ed0408746573743036323200ee0408746573743036323300ef0408746573743036323400f0040874657374303632" - "3500f10408746573743036323600f20408746573743036323700f30408746573743036323800f40408746573743036" - "323900f50408746573743036333000f60408746573743036333100f70408746573743036333200f804087465737430" - "36333300f90408746573743036333400fa0408746573743036333500fb0408746573743036333600fc040874657374" - "3036333700fd0408746573743036333800fe0408746573743036333900ff0408746573743036343000800508746573" - "7430363431008105087465737430363432008205087465737430363433008305087465737430363434008405087465" - "7374303634350085050874657374303634360086050874657374303634370087050874657374303634380088050874" - "65737430363439008905087465737430363530008a05087465737430363531008b05087465737430363532008c0508" - "7465737430363533008d05087465737430363534008e05087465737430363535008f05087465737430363536009005" - "0874657374303635370091050874657374303635380092050874657374303635390093050874657374303636300094" - "0508746573743036363100950508746573743036363200960508746573743036363300970508746573743036363400" - "9805087465737430363635009905087465737430363636009a05087465737430363637009b05087465737430363638" - "009c05087465737430363639009d05087465737430363730009e05087465737430363731009f050874657374303637" - "3200a00508746573743036373300a10508746573743036373400a20508746573743036373500a30508746573743036" - "373600a40508746573743036373700a50508746573743036373800a60508746573743036373900a705087465737430" - "36383000a80508746573743036383100a90508746573743036383200aa0508746573743036383300ab050874657374" - "3036383400ac0508746573743036383500ad0508746573743036383600ae0508746573743036383700af0508746573" - "743036383800b00508746573743036383900b10508746573743036393000b20508746573743036393100b305087465" - "73743036393200b40508746573743036393300b50508746573743036393400b60508746573743036393500b7050874" - "6573743036393600b80508746573743036393700b90508746573743036393800ba0508746573743036393900bb0508" - "746573743037303000bc0508746573743037303100bd0508746573743037303200be0508746573743037303300bf05" - "08746573743037303400c00508746573743037303500c10508746573743037303600c20508746573743037303700c3" - "0508746573743037303800c40508746573743037303900c50508746573743037313000c60508746573743037313100" - "c70508746573743037313200c80508746573743037313300c90508746573743037313400ca05087465737430373135" - "00cb0508746573743037313600cc0508746573743037313700cd0508746573743037313800ce050874657374303731" - "3900cf0508746573743037323000d00508746573743037323100d10508746573743037323200d20508746573743037" - "323300d30508746573743037323400d40508746573743037323500d50508746573743037323600d605087465737430" - "37323700d70508746573743037323800d80508746573743037323900d90508746573743037333000da050874657374" - "3037333100db0508746573743037333200dc0508746573743037333300dd0508746573743037333400de0508746573" - "743037333500df0508746573743037333600e00508746573743037333700e10508746573743037333800e205087465" - "73743037333900e30508746573743037343000e40508746573743037343100e50508746573743037343200e6050874" - "6573743037343300e70508746573743037343400e80508746573743037343500e90508746573743037343600ea0508" - "746573743037343700eb0508746573743037343800ec0508746573743037343900ed0508746573743037353000ee05" - "08746573743037353100ef0508746573743037353200f00508746573743037353300f10508746573743037353400f2" - "0508746573743037353500f30508746573743037353600f40508746573743037353700f50508746573743037353800" - "f60508746573743037353900f70508746573743037363000f80508746573743037363100f905087465737430373632" - "00fa0508746573743037363300fb0508746573743037363400fc0508746573743037363500fd050874657374303736" - "3600fe0508746573743037363700ff0508746573743037363800800608746573743037363900810608746573743037" - "3730008206087465737430373731008306087465737430373732008406087465737430373733008506087465737430" - "3737340086060874657374303737350087060874657374303737360088060874657374303737370089060874657374" - "30373738008a06087465737430373739008b06087465737430373830008c06087465737430373831008d0608746573" - "7430373832008e06087465737430373833008f06087465737430373834009006087465737430373835009106087465" - "7374303738360092060874657374303738370093060874657374303738380094060874657374303738390095060874" - "6573743037393000960608746573743037393100970608746573743037393200980608746573743037393300990608" - "7465737430373934009a06087465737430373935009b06087465737430373936009c06087465737430373937009d06" - "087465737430373938009e06087465737430373939009f0608746573743038303000a00608746573743038303100a1" - "0608746573743038303200a20608746573743038303300a30608746573743038303400a40608746573743038303500" - "a50608746573743038303600a60608746573743038303700a70608746573743038303800a806087465737430383039" - "00a90608746573743038313000aa0608746573743038313100ab0608746573743038313200ac060874657374303831" - "3300ad0608746573743038313400ae0608746573743038313500af0608746573743038313600b00608746573743038" - "313700b10608746573743038313800b20608746573743038313900b30608746573743038323000b406087465737430" - "38323100b50608746573743038323200b60608746573743038323300b70608746573743038323400b8060874657374" - "3038323500b90608746573743038323600ba0608746573743038323700bb0608746573743038323800bc0608746573" - "743038323900bd0608746573743038333000be0608746573743038333100bf0608746573743038333200c006087465" - "73743038333300c10608746573743038333400c20608746573743038333500c30608746573743038333600c4060874" - "6573743038333700c50608746573743038333800c60608746573743038333900c70608746573743038343000c80608" - "746573743038343100c90608746573743038343200ca0608746573743038343300cb0608746573743038343400cc06" - "08746573743038343500cd0608746573743038343600ce0608746573743038343700cf0608746573743038343800d0" - "0608746573743038343900d10608746573743038353000d20608746573743038353100d30608746573743038353200" - "d40608746573743038353300d50608746573743038353400d60608746573743038353500d706087465737430383536" - "00d80608746573743038353700d90608746573743038353800da0608746573743038353900db060874657374303836" - "3000dc0608746573743038363100dd0608746573743038363200de0608746573743038363300df0608746573743038" - "363400e00608746573743038363500e10608746573743038363600e20608746573743038363700e306087465737430" - "38363800e40608746573743038363900e50608746573743038373000e60608746573743038373100e7060874657374" - "3038373200e80608746573743038373300e90608746573743038373400ea0608746573743038373500eb0608746573" - "743038373600ec0608746573743038373700ed0608746573743038373800ee0608746573743038373900ef06087465" - "73743038383000f00608746573743038383100f10608746573743038383200f20608746573743038383300f3060874" - "6573743038383400f40608746573743038383500f50608746573743038383600f60608746573743038383700f70608" - "746573743038383800f80608746573743038383900f90608746573743038393000fa0608746573743038393100fb06" - "08746573743038393200fc0608746573743038393300fd0608746573743038393400fe0608746573743038393500ff" - "0608746573743038393600800708746573743038393700810708746573743038393800820708746573743038393900" - "8307087465737430393030008407087465737430393031008507087465737430393032008607087465737430393033" - "008707087465737430393034008807087465737430393035008907087465737430393036008a070874657374303930" - "37008b07087465737430393038008c07087465737430393039008d07087465737430393130008e0708746573743039" - "3131008f07087465737430393132009007087465737430393133009107087465737430393134009207087465737430" - "3931350093070874657374303931360094070874657374303931370095070874657374303931380096070874657374" - "30393139009707087465737430393230009807087465737430393231009907087465737430393232009a0708746573" - "7430393233009b07087465737430393234009c07087465737430393235009d07087465737430393236009e07087465" - "737430393237009f0708746573743039323800a00708746573743039323900a10708746573743039333000a2070874" - "6573743039333100a30708746573743039333200a40708746573743039333300a50708746573743039333400a60708" - "746573743039333500a70708746573743039333600a80708746573743039333700a90708746573743039333800aa07" - "08746573743039333900ab0708746573743039343000ac0708746573743039343100ad0708746573743039343200ae" - "0708746573743039343300af0708746573743039343400b00708746573743039343500b10708746573743039343600" - "b20708746573743039343700b30708746573743039343800b40708746573743039343900b507087465737430393530" - "00b60708746573743039353100b70708746573743039353200b80708746573743039353300b9070874657374303935" - "3400ba0708746573743039353500bb0708746573743039353600bc0708746573743039353700bd0708746573743039" - "353800be0708746573743039353900bf0708746573743039363000c00708746573743039363100c107087465737430" - "39363200c20708746573743039363300c30708746573743039363400c40708746573743039363500c5070874657374" - "3039363600c60708746573743039363700c70708746573743039363800c80708746573743039363900c90708746573" - "743039373000ca0708746573743039373100cb0708746573743039373200cc0708746573743039373300cd07087465" - "73743039373400ce0708746573743039373500cf0708746573743039373600d00708746573743039373700d1070874" - "6573743039373800d20708746573743039373900d30708746573743039383000d40708746573743039383100d50708" - "746573743039383200d60708746573743039383300d70708746573743039383400d80708746573743039383500d907" - "08746573743039383600da0708746573743039383700db0708746573743039383800dc0708746573743039383900dd" - "0708746573743039393000de0708746573743039393100df0708746573743039393200e00708746573743039393300" - "e10708746573743039393400e20708746573743039393500e30708746573743039393600e407087465737430393937" - "00e50708746573743039393800e60708746573743039393900e70708746573743130303000e8070874657374313030" - "3100e90708746573743130303200ea0708746573743130303300eb0708746573743130303400ec0708746573743130" - "303500ed0708746573743130303600ee0708746573743130303700ef0708746573743130303800f007087465737431" - "30303900f10708746573743130313000f20708746573743130313100f30708746573743130313200f4070874657374" - "3130313300f50708746573743130313400f60708746573743130313500f70708746573743130313600f80708746573" - "743130313700f90708746573743130313800fa0708746573743130313900fb0708746573743130323000fc07087465" - "73743130323100fd0708746573743130323200fe0708746573743130323300ff070874657374313032340080080874" - "6573743130323500810808746573743130323600820808746573743130323700830808746573743130323800840808" - "7465737431303239008508087465737431303330008608087465737431303331008708087465737431303332008808" - "087465737431303333008908087465737431303334008a08087465737431303335008b08087465737431303336008c" - "08087465737431303337008d08087465737431303338008e08087465737431303339008f0808746573743130343000" - "9008087465737431303431009108087465737431303432009208087465737431303433009308087465737431303434" - "0094080874657374313034350095080874657374313034360096080874657374313034370097080874657374313034" - "38009808087465737431303439009908087465737431303530009a08087465737431303531009b0808746573743130" - "3532009c08087465737431303533009d08087465737431303534009e08087465737431303535009f08087465737431" - "30353600a00808746573743130353700a10808746573743130353800a20808746573743130353900a3080874657374" - "3130363000a40808746573743130363100a50808746573743130363200a60808746573743130363300a70808746573" - "743130363400a80808746573743130363500a90808746573743130363600aa0808746573743130363700ab08087465" - "73743130363800ac0808746573743130363900ad0808746573743130373000ae0808746573743130373100af080874" - "6573743130373200b00808746573743130373300b10808746573743130373400b20808746573743130373500b30808" - "746573743130373600b40808746573743130373700b50808746573743130373800b60808746573743130373900b708" - "08746573743130383000b80808746573743130383100b90808746573743130383200ba0808746573743130383300bb" - "0808746573743130383400bc0808746573743130383500bd0808746573743130383600be0808746573743130383700" - "bf0808746573743130383800c00808746573743130383900c10808746573743130393000c208087465737431303931" - "00c30808746573743130393200c40808746573743130393300c50808746573743130393400c6080874657374313039" - "3500c70808746573743130393600c80808746573743130393700c90808746573743130393800ca0808746573743130" - "393900cb0808746573743131303000cc0808746573743131303100cd0808746573743131303200ce08087465737431" - "31303300cf0808746573743131303400d00808746573743131303500d10808746573743131303600d2080874657374" - "3131303700d30808746573743131303800d40808746573743131303900d50808746573743131313000d60808746573" - "743131313100d70808746573743131313200d80808746573743131313300d90808746573743131313400da08087465" - "73743131313500db0808746573743131313600dc0808746573743131313700dd0808746573743131313800de080874" - "6573743131313900df0808746573743131323000e00808746573743131323100e10808746573743131323200e20808" - "746573743131323300e30808746573743131323400e40808746573743131323500e50808746573743131323600e608" - "08746573743131323700e70808746573743131323800e80808746573743131323900e90808746573743131333000ea" - "0808746573743131333100eb0808746573743131333200ec0808746573743131333300ed0808746573743131333400" - "ee0808746573743131333500ef0808746573743131333600f00808746573743131333700f108087465737431313338" - "00f20808746573743131333900f30808746573743131343000f40808746573743131343100f5080874657374313134" - "3200f60808746573743131343300f70808746573743131343400f80808746573743131343500f90808746573743131" - "343600fa0808746573743131343700fb0808746573743131343800fc0808746573743131343900fd08087465737431" - "31353000fe0808746573743131353100ff080874657374313135320080090874657374313135330081090874657374" - "3131353400820908746573743131353500830908746573743131353600840908746573743131353700850908746573" - "7431313538008609087465737431313539008709087465737431313630008809087465737431313631008909087465" - "737431313632008a09087465737431313633008b09087465737431313634008c09087465737431313635008d090874" - "65737431313636008e09087465737431313637008f0908746573743131363800900908746573743131363900910908" - "7465737431313730009209087465737431313731009309087465737431313732009409087465737431313733009509" - "0874657374313137340096090874657374313137350097090874657374313137360098090874657374313137370099" - "09087465737431313738009a09087465737431313739009b09087465737431313830009c0908746573743131383100" - "9d09087465737431313832009e09087465737431313833009f0908746573743131383400a009087465737431313835" - "00a10908746573743131383600a20908746573743131383700a30908746573743131383800a4090874657374313138" - "3900a50908746573743131393000a60908746573743131393100a70908746573743131393200a80908746573743131" - "393300a90908746573743131393400aa0908746573743131393500ab0908746573743131393600ac09087465737431" - "31393700ad0908746573743131393800ae0908746573743131393900af0908746573743132303000b0090874657374" - "3132303100b10908746573743132303200b20908746573743132303300b30908746573743132303400b40908746573" - "743132303500b50908746573743132303600b60908746573743132303700b70908746573743132303800b809087465" - "73743132303900b90908746573743132313000ba0908746573743132313100bb0908746573743132313200bc090874" - "6573743132313300bd0908746573743132313400be0908746573743132313500bf0908746573743132313600c00908" - "746573743132313700c10908746573743132313800c20908746573743132313900c30908746573743132323000c409" - "08746573743132323100c50908746573743132323200c60908746573743132323300c70908746573743132323400c8" - "0908746573743132323500c90908746573743132323600ca0908746573743132323700cb0908746573743132323800" - "cc0908746573743132323900cd0908746573743132333000ce0908746573743132333100cf09087465737431323332" - "00d00908746573743132333300d10908746573743132333400d20908746573743132333500d3090874657374313233" - "3600d40908746573743132333700d50908746573743132333800d60908746573743132333900d70908746573743132" - "343000d80908746573743132343100d90908746573743132343200da0908746573743132343300db09087465737431" - "32343400dc0908746573743132343500dd0908746573743132343600de0908746573743132343700df090874657374" - "3132343800e00908746573743132343900e10908746573743132353000e20908746573743132353100e30908746573" - "743132353200e40908746573743132353300e50908746573743132353400e60908746573743132353500e709087465" - "73743132353600e80908746573743132353700e90908746573743132353800ea0908746573743132353900eb090874" - "6573743132363000ec0908746573743132363100ed0908746573743132363200ee0908746573743132363300ef0908" - "746573743132363400f00908746573743132363500f10908746573743132363600f20908746573743132363700f309" - "08746573743132363800f40908746573743132363900f50908746573743132373000f60908746573743132373100f7" - "0908746573743132373200f80908746573743132373300f90908746573743132373400fa0908746573743132373500" - "fb0908746573743132373600fc0908746573743132373700fd0908746573743132373800fe09087465737431323739" - "00ff0908746573743132383000800a08746573743132383100810a08746573743132383200820a0874657374313238" - "3300830a08746573743132383400840a08746573743132383500850a08746573743132383600860a08746573743132" - "383700870a08746573743132383800880a08746573743132383900890a087465737431323930008a0a087465737431" - "323931008b0a087465737431323932008c0a087465737431323933008d0a087465737431323934008e0a0874657374" - "31323935008f0a08746573743132393600900a08746573743132393700910a08746573743132393800920a08746573" - "743132393900930a08746573743133303000940a08746573743133303100950a08746573743133303200960a087465" - "73743133303300970a08746573743133303400980a08746573743133303500990a087465737431333036009a0a0874" - "65737431333037009b0a087465737431333038009c0a087465737431333039009d0a087465737431333130009e0a08" - "7465737431333131009f0a08746573743133313200a00a08746573743133313300a10a08746573743133313400a20a" - "08746573743133313500a30a08746573743133313600a40a08746573743133313700a50a08746573743133313800a6" - "0a08746573743133313900a70a08746573743133323000a80a08746573743133323100a90a08746573743133323200" - "aa0a08746573743133323300ab0a08746573743133323400ac0a08746573743133323500ad0a087465737431333236" - "00ae0a08746573743133323700af0a08746573743133323800b00a08746573743133323900b10a0874657374313333" - "3000b20a08746573743133333100b30a08746573743133333200b40a08746573743133333300b50a08746573743133" - "333400b60a08746573743133333500b70a08746573743133333600b80a08746573743133333700b90a087465737431" - "33333800ba0a08746573743133333900bb0a08746573743133343000bc0a08746573743133343100bd0a0874657374" - "3133343200be0a08746573743133343300bf0a08746573743133343400c00a08746573743133343500c10a08746573" - "743133343600c20a08746573743133343700c30a08746573743133343800c40a08746573743133343900c50a087465" - "73743133353000c60a08746573743133353100c70a08746573743133353200c80a08746573743133353300c90a0874" - "6573743133353400ca0a08746573743133353500cb0a08746573743133353600cc0a08746573743133353700cd0a08" - "746573743133353800ce0a08746573743133353900cf0a08746573743133363000d00a08746573743133363100d10a" - "08746573743133363200d20a08746573743133363300d30a08746573743133363400d40a08746573743133363500d5" - "0a08746573743133363600d60a08746573743133363700d70a08746573743133363800d80a08746573743133363900" - "d90a08746573743133373000da0a08746573743133373100db0a08746573743133373200dc0a087465737431333733" - "00dd0a08746573743133373400de0a08746573743133373500df0a08746573743133373600e00a0874657374313337" - "3700e10a08746573743133373800e20a08746573743133373900e30a08746573743133383000e40a08746573743133" - "383100e50a08746573743133383200e60a08746573743133383300e70a08746573743133383400e80a087465737431" - "33383500e90a08746573743133383600ea0a08746573743133383700eb0a08746573743133383800ec0a0874657374" - "3133383900ed0a08746573743133393000ee0a08746573743133393100ef0a08746573743133393200f00a08746573" - "743133393300f10a08746573743133393400f20a08746573743133393500f30a08746573743133393600f40a087465" - "73743133393700f50a08746573743133393800f60a08746573743133393900f70a08746573743134303000f80a0874" - "6573743134303100f90a08746573743134303200fa0a08746573743134303300fb0a08746573743134303400fc0a08" - "746573743134303500fd0a08746573743134303600fe0a08746573743134303700ff0a08746573743134303800800b" - "08746573743134303900810b08746573743134313000820b08746573743134313100830b0874657374313431320084" - "0b08746573743134313300850b08746573743134313400860b08746573743134313500870b08746573743134313600" - "880b08746573743134313700890b087465737431343138008a0b087465737431343139008b0b087465737431343230" - "008c0b087465737431343231008d0b087465737431343232008e0b087465737431343233008f0b0874657374313432" - "3400900b08746573743134323500910b08746573743134323600920b08746573743134323700930b08746573743134" - "323800940b08746573743134323900950b08746573743134333000960b08746573743134333100970b087465737431" - "34333200980b08746573743134333300990b087465737431343334009a0b087465737431343335009b0b0874657374" - "31343336009c0b087465737431343337009d0b087465737431343338009e0b087465737431343339009f0b08746573" - "743134343000a00b08746573743134343100a10b08746573743134343200a20b08746573743134343300a30b087465" - "73743134343400a40b08746573743134343500a50b08746573743134343600a60b08746573743134343700a70b0874" - "6573743134343800a80b08746573743134343900a90b08746573743134353000aa0b08746573743134353100ab0b08" - "746573743134353200ac0b08746573743134353300ad0b08746573743134353400ae0b08746573743134353500af0b" - "08746573743134353600b00b08746573743134353700b10b08746573743134353800b20b08746573743134353900b3" - "0b08746573743134363000b40b08746573743134363100b50b08746573743134363200b60b08746573743134363300" - "b70b08746573743134363400b80b08746573743134363500b90b08746573743134363600ba0b087465737431343637" - "00bb0b08746573743134363800bc0b08746573743134363900bd0b08746573743134373000be0b0874657374313437" - "3100bf0b08746573743134373200c00b08746573743134373300c10b08746573743134373400c20b08746573743134" - "373500c30b08746573743134373600c40b08746573743134373700c50b08746573743134373800c60b087465737431" - "34373900c70b08746573743134383000c80b08746573743134383100c90b08746573743134383200ca0b0874657374" - "3134383300cb0b08746573743134383400cc0b08746573743134383500cd0b08746573743134383600ce0b08746573" - "743134383700cf0b08746573743134383800d00b08746573743134383900d10b08746573743134393000d20b087465" - "73743134393100d30b08746573743134393200d40b08746573743134393300d50b08746573743134393400d60b0874" - "6573743134393500d70b08746573743134393600d80b08746573743134393700d90b08746573743134393800da0b08" - "746573743134393900db0b08746573743135303000dc0b08746573743135303100dd0b08746573743135303200de0b" - "08746573743135303300df0b08746573743135303400e00b08746573743135303500e10b08746573743135303600e2" - "0b08746573743135303700e30b08746573743135303800e40b08746573743135303900e50b08746573743135313000" - "e60b08746573743135313100e70b08746573743135313200e80b08746573743135313300e90b087465737431353134" - "00ea0b08746573743135313500eb0b08746573743135313600ec0b08746573743135313700ed0b0874657374313531" - "3800ee0b08746573743135313900ef0b08746573743135323000f00b08746573743135323100f10b08746573743135" - "323200f20b08746573743135323300f30b08746573743135323400f40b08746573743135323500f50b087465737431" - "35323600f60b08746573743135323700f70b08746573743135323800f80b08746573743135323900f90b0874657374" - "3135333000fa0b08746573743135333100fb0b08746573743135333200fc0b08746573743135333300fd0b08746573" - "743135333400fe0b08746573743135333500ff0b08746573743135333600800c08746573743135333700810c087465" - "73743135333800820c08746573743135333900830c08746573743135343000840c08746573743135343100850c0874" - "6573743135343200860c08746573743135343300870c08746573743135343400880c08746573743135343500890c08" - "7465737431353436008a0c087465737431353437008b0c087465737431353438008c0c087465737431353439008d0c" - "087465737431353530008e0c087465737431353531008f0c08746573743135353200900c0874657374313535330091" - "0c08746573743135353400920c08746573743135353500930c08746573743135353600940c08746573743135353700" - "950c08746573743135353800960c08746573743135353900970c08746573743135363000980c087465737431353631" - "00990c087465737431353632009a0c087465737431353633009b0c087465737431353634009c0c0874657374313536" - "35009d0c087465737431353636009e0c087465737431353637009f0c08746573743135363800a00c08746573743135" - "363900a10c08746573743135373000a20c08746573743135373100a30c08746573743135373200a40c087465737431" - "35373300a50c08746573743135373400a60c08746573743135373500a70c08746573743135373600a80c0874657374" - "3135373700a90c08746573743135373800aa0c08746573743135373900ab0c08746573743135383000ac0c08746573" - "743135383100ad0c08746573743135383200ae0c08746573743135383300af0c08746573743135383400b00c087465" - "73743135383500b10c08746573743135383600b20c08746573743135383700b30c08746573743135383800b40c0874" - "6573743135383900b50c08746573743135393000b60c08746573743135393100b70c08746573743135393200b80c08" - "746573743135393300b90c08746573743135393400ba0c08746573743135393500bb0c08746573743135393600bc0c" - "08746573743135393700bd0c08746573743135393800be0c08746573743135393900bf0c08746573743136303000c0" - "0c08746573743136303100c10c08746573743136303200c20c08746573743136303300c30c08746573743136303400" - "c40c08746573743136303500c50c08746573743136303600c60c08746573743136303700c70c087465737431363038" - "00c80c08746573743136303900c90c08746573743136313000ca0c08746573743136313100cb0c0874657374313631" - "3200cc0c08746573743136313300cd0c08746573743136313400ce0c08746573743136313500cf0c08746573743136" - "313600d00c08746573743136313700d10c08746573743136313800d20c08746573743136313900d30c087465737431" - "36323000d40c08746573743136323100d50c08746573743136323200d60c08746573743136323300d70c0874657374" - "3136323400d80c08746573743136323500d90c08746573743136323600da0c08746573743136323700db0c08746573" - "743136323800dc0c08746573743136323900dd0c08746573743136333000de0c08746573743136333100df0c087465" - "73743136333200e00c08746573743136333300e10c08746573743136333400e20c08746573743136333500e30c0874" - "6573743136333600e40c08746573743136333700e50c08746573743136333800e60c08746573743136333900e70c08" - "746573743136343000e80c08746573743136343100e90c08746573743136343200ea0c08746573743136343300eb0c" - "08746573743136343400ec0c08746573743136343500ed0c08746573743136343600ee0c08746573743136343700ef" - "0c08746573743136343800f00c08746573743136343900f10c08746573743136353000f20c08746573743136353100" - "f30c08746573743136353200f40c08746573743136353300f50c08746573743136353400f60c087465737431363535" - "00f70c08746573743136353600f80c08746573743136353700f90c08746573743136353800fa0c0874657374313635" - "3900fb0c08746573743136363000fc0c08746573743136363100fd0c08746573743136363200fe0c08746573743136" - "363300ff0c08746573743136363400800d08746573743136363500810d08746573743136363600820d087465737431" - "36363700830d08746573743136363800840d08746573743136363900850d08746573743136373000860d0874657374" - "3136373100870d08746573743136373200880d08746573743136373300890d087465737431363734008a0d08746573" - "7431363735008b0d087465737431363736008c0d087465737431363737008d0d087465737431363738008e0d087465" - "737431363739008f0d08746573743136383000900d08746573743136383100910d08746573743136383200920d0874" - "6573743136383300930d08746573743136383400940d08746573743136383500950d08746573743136383600960d08" - "746573743136383700970d08746573743136383800980d08746573743136383900990d087465737431363930009a0d" - "087465737431363931009b0d087465737431363932009c0d087465737431363933009d0d087465737431363934009e" - "0d087465737431363935009f0d08746573743136393600a00d08746573743136393700a10d08746573743136393800" - "a20d08746573743136393900a30d08746573743137303000a40d08746573743137303100a50d087465737431373032" - "00a60d08746573743137303300a70d08746573743137303400a80d08746573743137303500a90d0874657374313730" - "3600aa0d08746573743137303700ab0d08746573743137303800ac0d08746573743137303900ad0d08746573743137" - "313000ae0d08746573743137313100af0d08746573743137313200b00d08746573743137313300b10d087465737431" - "37313400b20d08746573743137313500b30d08746573743137313600b40d08746573743137313700b50d0874657374" - "3137313800b60d08746573743137313900b70d08746573743137323000b80d08746573743137323100b90d08746573" - "743137323200ba0d08746573743137323300bb0d08746573743137323400bc0d08746573743137323500bd0d087465" - "73743137323600be0d08746573743137323700bf0d08746573743137323800c00d08746573743137323900c10d0874" - "6573743137333000c20d08746573743137333100c30d08746573743137333200c40d08746573743137333300c50d08" - "746573743137333400c60d08746573743137333500c70d08746573743137333600c80d08746573743137333700c90d" - "08746573743137333800ca0d08746573743137333900cb0d08746573743137343000cc0d08746573743137343100cd" - "0d08746573743137343200ce0d08746573743137343300cf0d08746573743137343400d00d08746573743137343500" - "d10d08746573743137343600d20d08746573743137343700d30d08746573743137343800d40d087465737431373439" - "00d50d08746573743137353000d60d08746573743137353100d70d08746573743137353200d80d0874657374313735" - "3300d90d08746573743137353400da0d08746573743137353500db0d08746573743137353600dc0d08746573743137" - "353700dd0d08746573743137353800de0d08746573743137353900df0d08746573743137363000e00d087465737431" - "37363100e10d08746573743137363200e20d08746573743137363300e30d08746573743137363400e40d0874657374" - "3137363500e50d08746573743137363600e60d08746573743137363700e70d08746573743137363800e80d08746573" - "743137363900e90d08746573743137373000ea0d08746573743137373100eb0d08746573743137373200ec0d087465" - "73743137373300ed0d08746573743137373400ee0d08746573743137373500ef0d08746573743137373600f00d0874" - "6573743137373700f10d08746573743137373800f20d08746573743137373900f30d08746573743137383000f40d08" - "746573743137383100f50d08746573743137383200f60d08746573743137383300f70d08746573743137383400f80d" - "08746573743137383500f90d08746573743137383600fa0d08746573743137383700fb0d08746573743137383800fc" - "0d08746573743137383900fd0d08746573743137393000fe0d08746573743137393100ff0d08746573743137393200" - "800e08746573743137393300810e08746573743137393400820e08746573743137393500830e087465737431373936" - "00840e08746573743137393700850e08746573743137393800860e08746573743137393900870e0874657374313830" - "3000880e08746573743138303100890e087465737431383032008a0e087465737431383033008b0e08746573743138" - "3034008c0e087465737431383035008d0e087465737431383036008e0e087465737431383037008f0e087465737431" - "38303800900e08746573743138303900910e08746573743138313000920e08746573743138313100930e0874657374" - "3138313200940e08746573743138313300950e08746573743138313400960e08746573743138313500970e08746573" - "743138313600980e08746573743138313700990e087465737431383138009a0e087465737431383139009b0e087465" - "737431383230009c0e087465737431383231009d0e087465737431383232009e0e087465737431383233009f0e0874" - "6573743138323400a00e08746573743138323500a10e08746573743138323600a20e08746573743138323700a30e08" - "746573743138323800a40e08746573743138323900a50e08746573743138333000a60e08746573743138333100a70e" - "08746573743138333200a80e08746573743138333300a90e08746573743138333400aa0e08746573743138333500ab" - "0e08746573743138333600ac0e08746573743138333700ad0e08746573743138333800ae0e08746573743138333900" - "af0e08746573743138343000b00e08746573743138343100b10e08746573743138343200b20e087465737431383433" - "00b30e08746573743138343400b40e08746573743138343500b50e08746573743138343600b60e0874657374313834" - "3700b70e08746573743138343800b80e08746573743138343900b90e08746573743138353000ba0e08746573743138" - "353100bb0e08746573743138353200bc0e08746573743138353300bd0e08746573743138353400be0e087465737431" - "38353500bf0e08746573743138353600c00e08746573743138353700c10e08746573743138353800c20e0874657374" - "3138353900c30e08746573743138363000c40e08746573743138363100c50e08746573743138363200c60e08746573" - "743138363300c70e08746573743138363400c80e08746573743138363500c90e08746573743138363600ca0e087465" - "73743138363700cb0e08746573743138363800cc0e08746573743138363900cd0e08746573743138373000ce0e0874" - "6573743138373100cf0e08746573743138373200d00e08746573743138373300d10e08746573743138373400d20e08" - "746573743138373500d30e08746573743138373600d40e08746573743138373700d50e08746573743138373800d60e" - "08746573743138373900d70e08746573743138383000d80e08746573743138383100d90e08746573743138383200da" - "0e08746573743138383300db0e08746573743138383400dc0e08746573743138383500dd0e08746573743138383600" - "de0e08746573743138383700df0e08746573743138383800e00e08746573743138383900e10e087465737431383930" - "00e20e08746573743138393100e30e08746573743138393200e40e08746573743138393300e50e0874657374313839" - "3400e60e08746573743138393500e70e08746573743138393600e80e08746573743138393700e90e08746573743138" - "393800ea0e08746573743138393900eb0e08746573743139303000ec0e08746573743139303100ed0e087465737431" - "39303200ee0e08746573743139303300ef0e08746573743139303400f00e08746573743139303500f10e0874657374" - "3139303600f20e08746573743139303700f30e08746573743139303800f40e08746573743139303900f50e08746573" - "743139313000f60e08746573743139313100f70e08746573743139313200f80e08746573743139313300f90e087465" - "73743139313400fa0e08746573743139313500fb0e08746573743139313600fc0e08746573743139313700fd0e0874" - "6573743139313800fe0e08746573743139313900ff0e08746573743139323000800f08746573743139323100810f08" - "746573743139323200820f08746573743139323300830f08746573743139323400840f08746573743139323500850f" - "08746573743139323600860f08746573743139323700870f08746573743139323800880f0874657374313932390089" - "0f087465737431393330008a0f087465737431393331008b0f087465737431393332008c0f08746573743139333300" - "8d0f087465737431393334008e0f087465737431393335008f0f08746573743139333600900f087465737431393337" - "00910f08746573743139333800920f08746573743139333900930f08746573743139343000940f0874657374313934" - "3100950f08746573743139343200960f08746573743139343300970f08746573743139343400980f08746573743139" - "343500990f087465737431393436009a0f087465737431393437009b0f087465737431393438009c0f087465737431" - "393439009d0f087465737431393530009e0f087465737431393531009f0f08746573743139353200a00f0874657374" - "3139353300a10f08746573743139353400a20f08746573743139353500a30f08746573743139353600a40f08746573" - "743139353700a50f08746573743139353800a60f08746573743139353900a70f08746573743139363000a80f087465" - "73743139363100a90f08746573743139363200aa0f08746573743139363300ab0f08746573743139363400ac0f0874" - "6573743139363500ad0f08746573743139363600ae0f08746573743139363700af0f08746573743139363800b00f08" - "746573743139363900b10f08746573743139373000b20f08746573743139373100b30f08746573743139373200b40f" - "08746573743139373300b50f08746573743139373400b60f08746573743139373500b70f08746573743139373600b8" - "0f08746573743139373700b90f08746573743139373800ba0f08746573743139373900bb0f08746573743139383000" - "bc0f08746573743139383100bd0f08746573743139383200be0f08746573743139383300bf0f087465737431393834" - "00c00f08746573743139383500c10f08746573743139383600c20f08746573743139383700c30f0874657374313938" - "3800c40f08746573743139383900c50f08746573743139393000c60f08746573743139393100c70f08746573743139" - "393200c80f08746573743139393300c90f08746573743139393400ca0f08746573743139393500cb0f087465737431" - "39393600cc0f08746573743139393700cd0f08746573743139393800ce0f08746573743139393900cf0f0874657374" - "3230303000d00f08746573743230303100d10f08746573743230303200d20f08746573743230303300d30f08746573" - "743230303400d40f08746573743230303500d50f08746573743230303600d60f08746573743230303700d70f087465" - "73743230303800d80f08746573743230303900d90f08746573743230313000da0f08746573743230313100db0f0874" - "6573743230313200dc0f08746573743230313300dd0f08746573743230313400de0f08746573743230313500df0f08" - "746573743230313600e00f08746573743230313700e10f08746573743230313800e20f08746573743230313900e30f" - "08746573743230323000e40f08746573743230323100e50f08746573743230323200e60f08746573743230323300e7" - "0f08746573743230323400e80f08746573743230323500e90f08746573743230323600ea0f08746573743230323700" - "eb0f08746573743230323800ec0f08746573743230323900ed0f08746573743230333000ee0f087465737432303331" - "00ef0f08746573743230333200f00f08746573743230333300f10f08746573743230333400f20f0874657374323033" - "3500f30f08746573743230333600f40f08746573743230333700f50f08746573743230333800f60f08746573743230" - "333900f70f08746573743230343000f80f08746573743230343100f90f08746573743230343200fa0f087465737432" - "30343300fb0f08746573743230343400fc0f08746573743230343500fd0f08746573743230343600fe0f0874657374" - "3230343700ff0f08746573743230343800801008746573743230343900811008746573743230353000821008746573" - "7432303531008310087465737432303532008410087465737432303533008510087465737432303534008610087465" - "737432303535008710087465737432303536008810087465737432303537008910087465737432303538008a100874" - "65737432303539008b10087465737432303630008c10087465737432303631008d10087465737432303632008e1008" - "7465737432303633008f10087465737432303634009010087465737432303635009110087465737432303636009210" - "0874657374323036370093100874657374323036380094100874657374323036390095100874657374323037300096" - "1008746573743230373100971008746573743230373200981008746573743230373300991008746573743230373400" - "9a10087465737432303735009b10087465737432303736009c10087465737432303737009d10087465737432303738" - "009e10087465737432303739009f1008746573743230383000a01008746573743230383100a1100874657374323038" - "3200a21008746573743230383300a31008746573743230383400a41008746573743230383500a51008746573743230" - "383600a61008746573743230383700a71008746573743230383800a81008746573743230383900a910087465737432" - "30393000aa1008746573743230393100ab1008746573743230393200ac1008746573743230393300ad100874657374" - "3230393400ae1008746573743230393500af1008746573743230393600b01008746573743230393700b11008746573" - "743230393800b21008746573743230393900b31008746573743231303000b41008746573743231303100b510087465" - "73743231303200b61008746573743231303300b71008746573743231303400b81008746573743231303500b9100874" - "6573743231303600ba1008746573743231303700bb1008746573743231303800bc1008746573743231303900bd1008" - "746573743231313000be1008746573743231313100bf1008746573743231313200c01008746573743231313300c110" - "08746573743231313400c21008746573743231313500c31008746573743231313600c41008746573743231313700c5" - "1008746573743231313800c61008746573743231313900c71008746573743231323000c81008746573743231323100" - "c91008746573743231323200ca1008746573743231323300cb1008746573743231323400cc10087465737432313235" - "00cd1008746573743231323600ce1008746573743231323700cf1008746573743231323800d0100874657374323132" - "3900d11008746573743231333000d21008746573743231333100d31008746573743231333200d41008746573743231" - "333300d51008746573743231333400d61008746573743231333500d71008746573743231333600d810087465737432" - "31333700d91008746573743231333800da1008746573743231333900db1008746573743231343000dc100874657374" - "3231343100dd1008746573743231343200de1008746573743231343300df1008746573743231343400e01008746573" - "743231343500e11008746573743231343600e21008746573743231343700e31008746573743231343800e410087465" - "73743231343900e51008746573743231353000e61008746573743231353100e71008746573743231353200e8100874" - "6573743231353300e91008746573743231353400ea1008746573743231353500eb1008746573743231353600ec1008" - "746573743231353700ed1008746573743231353800ee1008746573743231353900ef1008746573743231363000f010" - "08746573743231363100f11008746573743231363200f21008746573743231363300f31008746573743231363400f4" - "1008746573743231363500f51008746573743231363600f61008746573743231363700f71008746573743231363800" - "f81008746573743231363900f91008746573743231373000fa1008746573743231373100fb10087465737432313732" - "00fc1008746573743231373300fd1008746573743231373400fe1008746573743231373500ff100874657374323137" - "3600801108746573743231373700811108746573743231373800821108746573743231373900831108746573743231" - "3830008411087465737432313831008511087465737432313832008611087465737432313833008711087465737432" - "313834008811087465737432313835008911087465737432313836008a11087465737432313837008b110874657374" - "32313838008c11087465737432313839008d11087465737432313930008e11087465737432313931008f1108746573" - "7432313932009011087465737432313933009111087465737432313934009211087465737432313935009311087465" - "7374323139360094110874657374323139370095110874657374323139380096110874657374323139390097110874" - "65737432323030009811087465737432323031009911087465737432323032009a11087465737432323033009b1108" - "7465737432323034009c11087465737432323035009d11087465737432323036009e11087465737432323037009f11" - "08746573743232303800a01108746573743232303900a11108746573743232313000a21108746573743232313100a3" - "1108746573743232313200a41108746573743232313300a51108746573743232313400a61108746573743232313500" - "a71108746573743232313600a81108746573743232313700a91108746573743232313800aa11087465737432323139" - "00ab1108746573743232323000ac1108746573743232323100ad1108746573743232323200ae110874657374323232" - "3300af1108746573743232323400b01108746573743232323500b11108746573743232323600b21108746573743232" - "323700b31108746573743232323800b41108746573743232323900b51108746573743232333000b611087465737432" - "32333100b71108746573743232333200b81108746573743232333300b91108746573743232333400ba110874657374" - "3232333500bb1108746573743232333600bc1108746573743232333700bd1108746573743232333800be1108746573" - "743232333900bf1108746573743232343000c01108746573743232343100c11108746573743232343200c211087465" - "73743232343300c31108746573743232343400c41108746573743232343500c51108746573743232343600c6110874" - "6573743232343700c71108746573743232343800c81108746573743232343900c91108746573743232353000ca1108" - "746573743232353100cb1108746573743232353200cc1108746573743232353300cd1108746573743232353400ce11" - "08746573743232353500cf1108746573743232353600d01108746573743232353700d11108746573743232353800d2" - "1108746573743232353900d31108746573743232363000d41108746573743232363100d51108746573743232363200" - "d61108746573743232363300d71108746573743232363400d81108746573743232363500d911087465737432323636" - "00da1108746573743232363700db1108746573743232363800dc1108746573743232363900dd110874657374323237" - "3000de1108746573743232373100df1108746573743232373200e01108746573743232373300e11108746573743232" - "373400e21108746573743232373500e31108746573743232373600e41108746573743232373700e511087465737432" - "32373800e61108746573743232373900e71108746573743232383000e81108746573743232383100e9110874657374" - "3232383200ea1108746573743232383300eb1108746573743232383400ec1108746573743232383500ed1108746573" - "743232383600ee1108746573743232383700ef1108746573743232383800f01108746573743232383900f111087465" - "73743232393000f21108746573743232393100f31108746573743232393200f41108746573743232393300f5110874" - "6573743232393400f61108746573743232393500f71108746573743232393600f81108746573743232393700f91108" - "746573743232393800fa1108746573743232393900fb1108746573743233303000fc1108746573743233303100fd11" - "08746573743233303200fe1108746573743233303300ff110874657374323330340080120874657374323330350081" - "1208746573743233303600821208746573743233303700831208746573743233303800841208746573743233303900" - "8512087465737432333130008612087465737432333131008712087465737432333132008812087465737432333133" - "008912087465737432333134008a12087465737432333135008b12087465737432333136008c120874657374323331" - "37008d12087465737432333138008e12087465737432333139008f1208746573743233323000901208746573743233" - "3231009112087465737432333232009212087465737432333233009312087465737432333234009412087465737432" - "3332350095120874657374323332360096120874657374323332370097120874657374323332380098120874657374" - "32333239009912087465737432333330009a12087465737432333331009b12087465737432333332009c1208746573" - "7432333333009d12087465737432333334009e12087465737432333335009f1208746573743233333600a012087465" - "73743233333700a11208746573743233333800a21208746573743233333900a31208746573743233343000a4120874" - "6573743233343100a51208746573743233343200a61208746573743233343300a71208746573743233343400a81208" - "746573743233343500a91208746573743233343600aa1208746573743233343700ab1208746573743233343800ac12" - "08746573743233343900ad1208746573743233353000ae1208746573743233353100af1208746573743233353200b0" - "1208746573743233353300b11208746573743233353400b21208746573743233353500b31208746573743233353600" - "b41208746573743233353700b51208746573743233353800b61208746573743233353900b712087465737432333630" - "00b81208746573743233363100b91208746573743233363200ba1208746573743233363300bb120874657374323336" - "3400bc1208746573743233363500bd1208746573743233363600be1208746573743233363700bf1208746573743233" - "363800c01208746573743233363900c11208746573743233373000c21208746573743233373100c312087465737432" - "33373200c41208746573743233373300c51208746573743233373400c61208746573743233373500c7120874657374" - "3233373600c81208746573743233373700c91208746573743233373800ca1208746573743233373900cb1208746573" - "743233383000cc1208746573743233383100cd1208746573743233383200ce1208746573743233383300cf12087465" - "73743233383400d01208746573743233383500d11208746573743233383600d21208746573743233383700d3120874" - "6573743233383800d41208746573743233383900d51208746573743233393000d61208746573743233393100d71208" - "746573743233393200d81208746573743233393300d91208746573743233393400da1208746573743233393500db12" - "08746573743233393600dc1208746573743233393700dd1208746573743233393800de1208746573743233393900df" - "1208746573743234303000e01208746573743234303100e11208746573743234303200e21208746573743234303300" - "e31208746573743234303400e41208746573743234303500e51208746573743234303600e612087465737432343037" - "00e71208746573743234303800e81208746573743234303900e91208746573743234313000ea120874657374323431" - "3100eb1208746573743234313200ec1208746573743234313300ed1208746573743234313400ee1208746573743234" - "313500ef1208746573743234313600f01208746573743234313700f11208746573743234313800f212087465737432" - "34313900f31208746573743234323000f41208746573743234323100f51208746573743234323200f6120874657374" - "3234323300f71208746573743234323400f81208746573743234323500f91208746573743234323600fa1208746573" - "743234323700fb1208746573743234323800fc1208746573743234323900fd1208746573743234333000fe12087465" - "73743234333100ff120874657374323433320080130874657374323433330081130874657374323433340082130874" - "6573743234333500831308746573743234333600841308746573743234333700851308746573743234333800861308" - "7465737432343339008713087465737432343430008813087465737432343431008913087465737432343432008a13" - "087465737432343433008b13087465737432343434008c13087465737432343435008d13087465737432343436008e" - "13087465737432343437008f1308746573743234343800901308746573743234343900911308746573743234353000" - "9213087465737432343531009313087465737432343532009413087465737432343533009513087465737432343534" - "0096130874657374323435350097130874657374323435360098130874657374323435370099130874657374323435" - "38009a13087465737432343539009b13087465737432343630009c13087465737432343631009d1308746573743234" - "3632009e13087465737432343633009f1308746573743234363400a01308746573743234363500a113087465737432" - "34363600a21308746573743234363700a31308746573743234363800a41308746573743234363900a5130874657374" - "3234373000a61308746573743234373100a71308746573743234373200a81308746573743234373300a91308746573" - "743234373400aa1308746573743234373500ab1308746573743234373600ac1308746573743234373700ad13087465" - "73743234373800ae1308746573743234373900af1308746573743234383000b01308746573743234383100b1130874" - "6573743234383200b21308746573743234383300b31308746573743234383400b41308746573743234383500b51308" - "746573743234383600b61308746573743234383700b71308746573743234383800b81308746573743234383900b913" - "08746573743234393000ba1308746573743234393100bb1308746573743234393200bc1308746573743234393300bd" - "1308746573743234393400be1308746573743234393500bf1308746573743234393600c01308746573743234393700" - "c11308746573743234393800c21308746573743234393900c31308746573743235303000c413087465737432353031" - "00c51308746573743235303200c61308746573743235303300c71308746573743235303400c8130874657374323530" - "3500c91308746573743235303600ca1308746573743235303700cb1308746573743235303800cc1308746573743235" - "303900cd1308746573743235313000ce1308746573743235313100cf1308746573743235313200d013087465737432" - "35313300d11308746573743235313400d21308746573743235313500d31308746573743235313600d4130874657374" - "3235313700d51308746573743235313800d61308746573743235313900d71308746573743235323000d81308746573" - "743235323100d91308746573743235323200da1308746573743235323300db1308746573743235323400dc13087465" - "73743235323500dd1308746573743235323600de1308746573743235323700df1308746573743235323800e0130874" - "6573743235323900e11308746573743235333000e21308746573743235333100e31308746573743235333200e41308" - "746573743235333300e51308746573743235333400e61308746573743235333500e71308746573743235333600e813" - "08746573743235333700e91308746573743235333800ea1308746573743235333900eb1308746573743235343000ec" - "1308746573743235343100ed1308746573743235343200ee1308746573743235343300ef1308746573743235343400" - "f01308746573743235343500f11308746573743235343600f21308746573743235343700f313087465737432353438" - "00f41308746573743235343900f51308746573743235353000f61308746573743235353100f7130874657374323535" - "3200f81308746573743235353300f91308746573743235353400fa1308746573743235353500fb1308746573743235" - "353600fc1308746573743235353700fd1308746573743235353800fe1308746573743235353900ff13087465737432" - "3536300080140874657374323536310081140874657374323536320082140874657374323536330083140874657374" - "3235363400841408746573743235363500851408746573743235363600861408746573743235363700871408746573" - "7432353638008814087465737432353639008914087465737432353730008a14087465737432353731008b14087465" - "737432353732008c14087465737432353733008d14087465737432353734008e14087465737432353735008f140874" - "6573743235373600901408746573743235373700911408746573743235373800921408746573743235373900931408" - "7465737432353830009414087465737432353831009514087465737432353832009614087465737432353833009714" - "087465737432353834009814087465737432353835009914087465737432353836009a14087465737432353837009b" - "14087465737432353838009c14087465737432353839009d14087465737432353930009e1408746573743235393100" - "9f1408746573743235393200a01408746573743235393300a11408746573743235393400a214087465737432353935" - "00a31408746573743235393600a41408746573743235393700a51408746573743235393800a6140874657374323539" - "3900a71408746573743236303000a81408746573743236303100a91408746573743236303200aa1408746573743236" - "303300ab1408746573743236303400ac1408746573743236303500ad1408746573743236303600ae14087465737432" - "36303700af1408746573743236303800b01408746573743236303900b11408746573743236313000b2140874657374" - "3236313100b31408746573743236313200b41408746573743236313300b51408746573743236313400b61408746573" - "743236313500b71408746573743236313600b81408746573743236313700b91408746573743236313800ba14087465" - "73743236313900bb1408746573743236323000bc1408746573743236323100bd1408746573743236323200be140874" - "6573743236323300bf1408746573743236323400c01408746573743236323500c11408746573743236323600c21408" - "746573743236323700c31408746573743236323800c41408746573743236323900c51408746573743236333000c614" - "08746573743236333100c71408746573743236333200c81408746573743236333300c91408746573743236333400ca" - "1408746573743236333500cb1408746573743236333600cc1408746573743236333700cd1408746573743236333800" - "ce1408746573743236333900cf1408746573743236343000d01408746573743236343100d114087465737432363432" - "00d21408746573743236343300d31408746573743236343400d41408746573743236343500d5140874657374323634" - "3600d61408746573743236343700d71408746573743236343800d81408746573743236343900d91408746573743236" - "353000da1408746573743236353100db1408746573743236353200dc1408746573743236353300dd14087465737432" - "36353400de1408746573743236353500df1408746573743236353600e01408746573743236353700e1140874657374" - "3236353800e21408746573743236353900e31408746573743236363000e41408746573743236363100e51408746573" - "743236363200e61408746573743236363300e71408746573743236363400e81408746573743236363500e914087465" - "73743236363600ea1408746573743236363700eb1408746573743236363800ec1408746573743236363900ed140874" - "6573743236373000ee1408746573743236373100ef1408746573743236373200f01408746573743236373300f11408" - "746573743236373400f21408746573743236373500f31408746573743236373600f41408746573743236373700f514" - "08746573743236373800f61408746573743236373900f71408746573743236383000f81408746573743236383100f9" - "1408746573743236383200fa1408746573743236383300fb1408746573743236383400fc1408746573743236383500" - "fd1408746573743236383600fe1408746573743236383700ff14087465737432363838008015087465737432363839" - "0081150874657374323639300082150874657374323639310083150874657374323639320084150874657374323639" - "3300851508746573743236393400861508746573743236393500871508746573743236393600881508746573743236" - "3937008915087465737432363938008a15087465737432363939008b15087465737432373030008c15087465737432" - "373031008d15087465737432373032008e15087465737432373033008f150874657374323730340090150874657374" - "3237303500911508746573743237303600921508746573743237303700931508746573743237303800941508746573" - "7432373039009515087465737432373130009615087465737432373131009715087465737432373132009815087465" - "737432373133009915087465737432373134009a15087465737432373135009b15087465737432373136009c150874" - "65737432373137009d15087465737432373138009e15087465737432373139009f1508746573743237323000a01508" - "746573743237323100a11508746573743237323200a21508746573743237323300a31508746573743237323400a415" - "08746573743237323500a51508746573743237323600a61508746573743237323700a71508746573743237323800a8" - "1508746573743237323900a91508746573743237333000aa1508746573743237333100ab1508746573743237333200" - "ac1508746573743237333300ad1508746573743237333400ae1508746573743237333500af15087465737432373336" - "00b01508746573743237333700b11508746573743237333800b21508746573743237333900b3150874657374323734" - "3000b41508746573743237343100b51508746573743237343200b61508746573743237343300b71508746573743237" - "343400b81508746573743237343500b91508746573743237343600ba1508746573743237343700bb15087465737432" - "37343800bc1508746573743237343900bd1508746573743237353000be1508746573743237353100bf150874657374" - "3237353200c01508746573743237353300c11508746573743237353400c21508746573743237353500c31508746573" - "743237353600c41508746573743237353700c51508746573743237353800c61508746573743237353900c715087465" - "73743237363000c81508746573743237363100c91508746573743237363200ca1508746573743237363300cb150874" - "6573743237363400cc1508746573743237363500cd1508746573743237363600ce1508746573743237363700cf1508" - "746573743237363800d01508746573743237363900d11508746573743237373000d21508746573743237373100d315" - "08746573743237373200d41508746573743237373300d51508746573743237373400d61508746573743237373500d7" - "1508746573743237373600d81508746573743237373700d91508746573743237373800da1508746573743237373900" - "db1508746573743237383000dc1508746573743237383100dd1508746573743237383200de15087465737432373833" - "00df1508746573743237383400e01508746573743237383500e11508746573743237383600e2150874657374323738" - "3700e31508746573743237383800e41508746573743237383900e51508746573743237393000e61508746573743237" - "393100e71508746573743237393200e81508746573743237393300e91508746573743237393400ea15087465737432" - "37393500eb1508746573743237393600ec1508746573743237393700ed1508746573743237393800ee150874657374" - "3237393900ef1508746573743238303000f01508746573743238303100f11508746573743238303200f21508746573" - "743238303300f31508746573743238303400f41508746573743238303500f51508746573743238303600f615087465" - "73743238303700f71508746573743238303800f81508746573743238303900f91508746573743238313000fa150874" - "6573743238313100fb1508746573743238313200fc1508746573743238313300fd1508746573743238313400fe1508" - "746573743238313500ff15087465737432383136008016087465737432383137008116087465737432383138008216" - "0874657374323831390083160874657374323832300084160874657374323832310085160874657374323832320086" - "1608746573743238323300871608746573743238323400881608746573743238323500891608746573743238323600" - "8a16087465737432383237008b16087465737432383238008c16087465737432383239008d16087465737432383330" - "008e16087465737432383331008f160874657374323833320090160874657374323833330091160874657374323833" - "3400921608746573743238333500931608746573743238333600941608746573743238333700951608746573743238" - "3338009616087465737432383339009716087465737432383430009816087465737432383431009916087465737432" - "383432009a16087465737432383433009b16087465737432383434009c16087465737432383435009d160874657374" - "32383436009e16087465737432383437009f1608746573743238343800a01608746573743238343900a11608746573" - "743238353000a21608746573743238353100a31608746573743238353200a41608746573743238353300a516087465" - "73743238353400a61608746573743238353500a71608746573743238353600a81608746573743238353700a9160874" - "6573743238353800aa1608746573743238353900ab1608746573743238363000ac1608746573743238363100ad1608" - "746573743238363200ae1608746573743238363300af1608746573743238363400b01608746573743238363500b116" - "08746573743238363600b21608746573743238363700b31608746573743238363800b41608746573743238363900b5" - "1608746573743238373000b61608746573743238373100b71608746573743238373200b81608746573743238373300" - "b91608746573743238373400ba1608746573743238373500bb1608746573743238373600bc16087465737432383737" - "00bd1608746573743238373800be1608746573743238373900bf1608746573743238383000c0160874657374323838" - "3100c11608746573743238383200c21608746573743238383300c31608746573743238383400c41608746573743238" - "383500c51608746573743238383600c61608746573743238383700c71608746573743238383800c816087465737432" - "38383900c91608746573743238393000ca1608746573743238393100cb1608746573743238393200cc160874657374" - "3238393300cd1608746573743238393400ce1608746573743238393500cf1608746573743238393600d01608746573" - "743238393700d11608746573743238393800d21608746573743238393900d31608746573743239303000d416087465" - "73743239303100d51608746573743239303200d61608746573743239303300d71608746573743239303400d8160874" - "6573743239303500d91608746573743239303600da1608746573743239303700db1608746573743239303800dc1608" - "746573743239303900dd1608746573743239313000de1608746573743239313100df1608746573743239313200e016" - "08746573743239313300e11608746573743239313400e21608746573743239313500e31608746573743239313600e4" - "1608746573743239313700e51608746573743239313800e61608746573743239313900e71608746573743239323000" - "e81608746573743239323100e91608746573743239323200ea1608746573743239323300eb16087465737432393234" - "00ec1608746573743239323500ed1608746573743239323600ee1608746573743239323700ef160874657374323932" - "3800f01608746573743239323900f11608746573743239333000f21608746573743239333100f31608746573743239" - "333200f41608746573743239333300f51608746573743239333400f61608746573743239333500f716087465737432" - "39333600f81608746573743239333700f91608746573743239333800fa1608746573743239333900fb160874657374" - "3239343000fc1608746573743239343100fd1608746573743239343200fe1608746573743239343300ff1608746573" - "7432393434008017087465737432393435008117087465737432393436008217087465737432393437008317087465" - "7374323934380084170874657374323934390085170874657374323935300086170874657374323935310087170874" - "65737432393532008817087465737432393533008917087465737432393534008a17087465737432393535008b1708" - "7465737432393536008c17087465737432393537008d17087465737432393538008e17087465737432393539008f17" - "0874657374323936300090170874657374323936310091170874657374323936320092170874657374323936330093" - "1708746573743239363400941708746573743239363500951708746573743239363600961708746573743239363700" - "9717087465737432393638009817087465737432393639009917087465737432393730009a17087465737432393731" - "009b17087465737432393732009c17087465737432393733009d17087465737432393734009e170874657374323937" - "35009f1708746573743239373600a01708746573743239373700a11708746573743239373800a21708746573743239" - "373900a31708746573743239383000a41708746573743239383100a51708746573743239383200a617087465737432" - "39383300a71708746573743239383400a81708746573743239383500a91708746573743239383600aa170874657374" - "3239383700ab1708746573743239383800ac1708746573743239383900ad1708746573743239393000ae1708746573" - "743239393100af1708746573743239393200b01708746573743239393300b11708746573743239393400b217087465" - "73743239393500b31708746573743239393600b41708746573743239393700b51708746573743239393800b6170874" - "6573743239393900b71708746573743330303000b81708746573743330303100b91708746573743330303200ba1708" - "746573743330303300bb1708746573743330303400bc1708746573743330303500bd1708746573743330303600be17" - "08746573743330303700bf1708746573743330303800c01708746573743330303900c11708746573743330313000c2" - "1708746573743330313100c31708746573743330313200c41708746573743330313300c51708746573743330313400" - "c61708746573743330313500c71708746573743330313600c81708746573743330313700c917087465737433303138" - "00ca1708746573743330313900cb1708746573743330323000cc1708746573743330323100cd170874657374333032" - "3200ce1708746573743330323300cf1708746573743330323400d01708746573743330323500d11708746573743330" - "323600d21708746573743330323700d31708746573743330323800d41708746573743330323900d517087465737433" - "30333000d61708746573743330333100d71708746573743330333200d81708746573743330333300d9170874657374" - "3330333400da1708746573743330333500db1708746573743330333600dc1708746573743330333700dd1708746573" - "743330333800de1708746573743330333900df1708746573743330343000e01708746573743330343100e117087465" - "73743330343200e21708746573743330343300e31708746573743330343400e41708746573743330343500e5170874" - "6573743330343600e61708746573743330343700e71708746573743330343800e81708746573743330343900e91708" - "746573743330353000ea1708746573743330353100eb1708746573743330353200ec1708746573743330353300ed17" - "08746573743330353400ee1708746573743330353500ef1708746573743330353600f01708746573743330353700f1" - "1708746573743330353800f21708746573743330353900f31708746573743330363000f41708746573743330363100" - "f51708746573743330363200f61708746573743330363300f71708746573743330363400f817087465737433303635" - "00f91708746573743330363600fa1708746573743330363700fb1708746573743330363800fc170874657374333036" - "3900fd1708746573743330373000fe1708746573743330373100ff1708746573743330373200801808746573743330" - "3733008118087465737433303734008218087465737433303735008318087465737433303736008418087465737433" - "3037370085180874657374333037380086180874657374333037390087180874657374333038300088180874657374" - "33303831008918087465737433303832008a18087465737433303833008b18087465737433303834008c1808746573" - "7433303835008d18087465737433303836008e18087465737433303837008f18087465737433303838009018087465" - "7374333038390091180874657374333039300092180874657374333039310093180874657374333039320094180874" - "6573743330393300951808746573743330393400961808746573743330393500971808746573743330393600981808" - "7465737433303937009918087465737433303938009a18087465737433303939009b18087465737433313030009c18" - "087465737433313031009d18087465737433313032009e18087465737433313033009f1808746573743331303400a0" - "1808746573743331303500a11808746573743331303600a21808746573743331303700a31808746573743331303800" - "a41808746573743331303900a51808746573743331313000a61808746573743331313100a718087465737433313132" - "00a81808746573743331313300a91808746573743331313400aa1808746573743331313500ab180874657374333131" - "3600ac1808746573743331313700ad1808746573743331313800ae1808746573743331313900af1808746573743331" - "323000b01808746573743331323100b11808746573743331323200b21808746573743331323300b318087465737433" - "31323400b41808746573743331323500b51808746573743331323600b61808746573743331323700b7180874657374" - "3331323800b81808746573743331323900b91808746573743331333000ba1808746573743331333100bb1808746573" - "743331333200bc1808746573743331333300bd1808746573743331333400be1808746573743331333500bf18087465" - "73743331333600c01808746573743331333700c11808746573743331333800c21808746573743331333900c3180874" - "6573743331343000c41808746573743331343100c51808746573743331343200c61808746573743331343300c71808" - "746573743331343400c81808746573743331343500c91808746573743331343600ca1808746573743331343700cb18" - "08746573743331343800cc1808746573743331343900cd1808746573743331353000ce1808746573743331353100cf" - "1808746573743331353200d01808746573743331353300d11808746573743331353400d21808746573743331353500" - "d31808746573743331353600d41808746573743331353700d51808746573743331353800d618087465737433313539" - "00d71808746573743331363000d81808746573743331363100d91808746573743331363200da180874657374333136" - "3300db1808746573743331363400dc1808746573743331363500dd1808746573743331363600de1808746573743331" - "363700df1808746573743331363800e01808746573743331363900e11808746573743331373000e218087465737433" - "31373100e31808746573743331373200e41808746573743331373300e51808746573743331373400e6180874657374" - "3331373500e71808746573743331373600e81808746573743331373700e91808746573743331373800ea1808746573" - "743331373900eb1808746573743331383000ec1808746573743331383100ed1808746573743331383200ee18087465" - "73743331383300ef1808746573743331383400f01808746573743331383500f11808746573743331383600f2180874" - "6573743331383700f31808746573743331383800f41808746573743331383900f51808746573743331393000f61808" - "746573743331393100f71808746573743331393200f81808746573743331393300f91808746573743331393400fa18" - "08746573743331393500fb1808746573743331393600fc1808746573743331393700fd1808746573743331393800fe" - "1808746573743331393900ff1808746573743332303000801908746573743332303100811908746573743332303200" - "8219087465737433323033008319087465737433323034008419087465737433323035008519087465737433323036" - "0086190874657374333230370087190874657374333230380088190874657374333230390089190874657374333231" - "30008a19087465737433323131008b19087465737433323132008c19087465737433323133008d1908746573743332" - "3134008e19087465737433323135008f19087465737433323136009019087465737433323137009119087465737433" - "3231380092190874657374333231390093190874657374333232300094190874657374333232310095190874657374" - "3332323200961908746573743332323300971908746573743332323400981908746573743332323500991908746573" - "7433323236009a19087465737433323237009b19087465737433323238009c19087465737433323239009d19087465" - "737433323330009e19087465737433323331009f1908746573743332333200a01908746573743332333300a1190874" - "6573743332333400a21908746573743332333500a31908746573743332333600a41908746573743332333700a51908" - "746573743332333800a61908746573743332333900a71908746573743332343000a81908746573743332343100a919" - "08746573743332343200aa1908746573743332343300ab1908746573743332343400ac1908746573743332343500ad" - "1908746573743332343600ae1908746573743332343700af1908746573743332343800b01908746573743332343900" - "b11908746573743332353000b21908746573743332353100b31908746573743332353200b419087465737433323533" - "00b51908746573743332353400b61908746573743332353500b71908746573743332353600b8190874657374333235" - "3700b91908746573743332353800ba1908746573743332353900bb1908746573743332363000bc1908746573743332" - "363100bd1908746573743332363200be1908746573743332363300bf1908746573743332363400c019087465737433" - "32363500c11908746573743332363600c21908746573743332363700c31908746573743332363800c4190874657374" - "3332363900c51908746573743332373000c61908746573743332373100c71908746573743332373200c81908746573" - "743332373300c91908746573743332373400ca1908746573743332373500cb1908746573743332373600cc19087465" - "73743332373700cd1908746573743332373800ce1908746573743332373900cf1908746573743332383000d0190874" - "6573743332383100d11908746573743332383200d21908746573743332383300d31908746573743332383400d41908" - "746573743332383500d51908746573743332383600d61908746573743332383700d71908746573743332383800d819" - "08746573743332383900d91908746573743332393000da1908746573743332393100db1908746573743332393200dc" - "1908746573743332393300dd1908746573743332393400de1908746573743332393500df1908746573743332393600" - "e01908746573743332393700e11908746573743332393800e21908746573743332393900e319087465737433333030" - "00e41908746573743333303100e51908746573743333303200e61908746573743333303300e7190874657374333330" - "3400e81908746573743333303500e91908746573743333303600ea1908746573743333303700eb1908746573743333" - "303800ec1908746573743333303900ed1908746573743333313000ee1908746573743333313100ef19087465737433" - "33313200f01908746573743333313300f11908746573743333313400f21908746573743333313500f3190874657374" - "3333313600f41908746573743333313700f51908746573743333313800f61908746573743333313900f71908746573" - "743333323000f81908746573743333323100f91908746573743333323200fa1908746573743333323300fb19087465" - "73743333323400fc1908746573743333323500fd1908746573743333323600fe1908746573743333323700ff190874" - "6573743333323800801a08746573743333323900811a08746573743333333000821a08746573743333333100831a08" - "746573743333333200841a08746573743333333300851a08746573743333333400861a08746573743333333500871a" - "08746573743333333600881a08746573743333333700891a087465737433333338008a1a087465737433333339008b" - "1a087465737433333430008c1a087465737433333431008d1a087465737433333432008e1a08746573743333343300" - "8f1a08746573743333343400901a08746573743333343500911a08746573743333343600921a087465737433333437" - "00931a08746573743333343800941a08746573743333343900951a08746573743333353000961a0874657374333335" - "3100971a08746573743333353200981a08746573743333353300991a087465737433333534009a1a08746573743333" - "3535009b1a087465737433333536009c1a087465737433333537009d1a087465737433333538009e1a087465737433" - "333539009f1a08746573743333363000a01a08746573743333363100a11a08746573743333363200a21a0874657374" - "3333363300a31a08746573743333363400a41a08746573743333363500a51a08746573743333363600a61a08746573" - "743333363700a71a08746573743333363800a81a08746573743333363900a91a08746573743333373000aa1a087465" - "73743333373100ab1a08746573743333373200ac1a08746573743333373300ad1a08746573743333373400ae1a0874" - "6573743333373500af1a08746573743333373600b01a08746573743333373700b11a08746573743333373800b21a08" - "746573743333373900b31a08746573743333383000b41a08746573743333383100b51a08746573743333383200b61a" - "08746573743333383300b71a08746573743333383400b81a08746573743333383500b91a08746573743333383600ba" - "1a08746573743333383700bb1a08746573743333383800bc1a08746573743333383900bd1a08746573743333393000" - "be1a08746573743333393100bf1a08746573743333393200c01a08746573743333393300c11a087465737433333934" - "00c21a08746573743333393500c31a08746573743333393600c41a08746573743333393700c51a0874657374333339" - "3800c61a08746573743333393900c71a08746573743334303000c81a08746573743334303100c91a08746573743334" - "303200ca1a08746573743334303300cb1a08746573743334303400cc1a08746573743334303500cd1a087465737433" - "34303600ce1a08746573743334303700cf1a08746573743334303800d01a08746573743334303900d11a0874657374" - "3334313000d21a08746573743334313100d31a08746573743334313200d41a08746573743334313300d51a08746573" - "743334313400d61a08746573743334313500d71a08746573743334313600d81a08746573743334313700d91a087465" - "73743334313800da1a08746573743334313900db1a08746573743334323000dc1a08746573743334323100dd1a0874" - "6573743334323200de1a08746573743334323300df1a08746573743334323400e01a08746573743334323500e11a08" - "746573743334323600e21a08746573743334323700e31a08746573743334323800e41a08746573743334323900e51a" - "08746573743334333000e61a08746573743334333100e71a08746573743334333200e81a08746573743334333300e9" - "1a08746573743334333400ea1a08746573743334333500eb1a08746573743334333600ec1a08746573743334333700" - "ed1a08746573743334333800ee1a08746573743334333900ef1a08746573743334343000f01a087465737433343431" - "00f11a08746573743334343200f21a08746573743334343300f31a08746573743334343400f41a0874657374333434" - "3500f51a08746573743334343600f61a08746573743334343700f71a08746573743334343800f81a08746573743334" - "343900f91a08746573743334353000fa1a08746573743334353100fb1a08746573743334353200fc1a087465737433" - "34353300fd1a08746573743334353400fe1a08746573743334353500ff1a08746573743334353600801b0874657374" - "3334353700811b08746573743334353800821b08746573743334353900831b08746573743334363000841b08746573" - "743334363100851b08746573743334363200861b08746573743334363300871b08746573743334363400881b087465" - "73743334363500891b087465737433343636008a1b087465737433343637008b1b087465737433343638008c1b0874" - "65737433343639008d1b087465737433343730008e1b087465737433343731008f1b08746573743334373200901b08" - "746573743334373300911b08746573743334373400921b08746573743334373500931b08746573743334373600941b" - "08746573743334373700951b08746573743334373800961b08746573743334373900971b0874657374333438300098" - "1b08746573743334383100991b087465737433343832009a1b087465737433343833009b1b08746573743334383400" - "9c1b087465737433343835009d1b087465737433343836009e1b087465737433343837009f1b087465737433343838" - "00a01b08746573743334383900a11b08746573743334393000a21b08746573743334393100a31b0874657374333439" - "3200a41b08746573743334393300a51b08746573743334393400a61b08746573743334393500a71b08746573743334" - "393600a81b08746573743334393700a91b08746573743334393800aa1b08746573743334393900ab1b087465737433" - "35303000ac1b08746573743335303100ad1b08746573743335303200ae1b08746573743335303300af1b0874657374" - "3335303400b01b08746573743335303500b11b08746573743335303600b21b08746573743335303700b31b08746573" - "743335303800b41b08746573743335303900b51b08746573743335313000b61b08746573743335313100b71b087465" - "73743335313200b81b08746573743335313300b91b08746573743335313400ba1b08746573743335313500bb1b0874" - "6573743335313600bc1b08746573743335313700bd1b08746573743335313800be1b08746573743335313900bf1b08" - "746573743335323000c01b08746573743335323100c11b08746573743335323200c21b08746573743335323300c31b" - "08746573743335323400c41b08746573743335323500c51b08746573743335323600c61b08746573743335323700c7" - "1b08746573743335323800c81b08746573743335323900c91b08746573743335333000ca1b08746573743335333100" - "cb1b08746573743335333200cc1b08746573743335333300cd1b08746573743335333400ce1b087465737433353335" - "00cf1b08746573743335333600d01b08746573743335333700d11b08746573743335333800d21b0874657374333533" - "3900d31b08746573743335343000d41b08746573743335343100d51b08746573743335343200d61b08746573743335" - "343300d71b08746573743335343400d81b08746573743335343500d91b08746573743335343600da1b087465737433" - "35343700db1b08746573743335343800dc1b08746573743335343900dd1b08746573743335353000de1b0874657374" - "3335353100df1b08746573743335353200e01b08746573743335353300e11b08746573743335353400e21b08746573" - "743335353500e31b08746573743335353600e41b08746573743335353700e51b08746573743335353800e61b087465" - "73743335353900e71b08746573743335363000e81b08746573743335363100e91b08746573743335363200ea1b0874" - "6573743335363300eb1b08746573743335363400ec1b08746573743335363500ed1b08746573743335363600ee1b08" - "746573743335363700ef1b08746573743335363800f01b08746573743335363900f11b08746573743335373000f21b" - "08746573743335373100f31b08746573743335373200f41b08746573743335373300f51b08746573743335373400f6" - "1b08746573743335373500f71b08746573743335373600f81b08746573743335373700f91b08746573743335373800" - "fa1b08746573743335373900fb1b08746573743335383000fc1b08746573743335383100fd1b087465737433353832" - "00fe1b08746573743335383300ff1b08746573743335383400801c08746573743335383500811c0874657374333538" - "3600821c08746573743335383700831c08746573743335383800841c08746573743335383900851c08746573743335" - "393000861c08746573743335393100871c08746573743335393200881c08746573743335393300891c087465737433" - "353934008a1c087465737433353935008b1c087465737433353936008c1c087465737433353937008d1c0874657374" - "33353938008e1c087465737433353939008f1c08746573743336303000901c08746573743336303100911c08746573" - "743336303200921c08746573743336303300931c08746573743336303400941c08746573743336303500951c087465" - "73743336303600961c08746573743336303700971c08746573743336303800981c08746573743336303900991c0874" - "65737433363130009a1c087465737433363131009b1c087465737433363132009c1c087465737433363133009d1c08" - "7465737433363134009e1c087465737433363135009f1c08746573743336313600a01c08746573743336313700a11c" - "08746573743336313800a21c08746573743336313900a31c08746573743336323000a41c08746573743336323100a5" - "1c08746573743336323200a61c08746573743336323300a71c08746573743336323400a81c08746573743336323500" - "a91c08746573743336323600aa1c08746573743336323700ab1c08746573743336323800ac1c087465737433363239" - "00ad1c08746573743336333000ae1c08746573743336333100af1c08746573743336333200b01c0874657374333633" - "3300b11c08746573743336333400b21c08746573743336333500b31c08746573743336333600b41c08746573743336" - "333700b51c08746573743336333800b61c08746573743336333900b71c08746573743336343000b81c087465737433" - "36343100b91c08746573743336343200ba1c08746573743336343300bb1c08746573743336343400bc1c0874657374" - "3336343500bd1c08746573743336343600be1c08746573743336343700bf1c08746573743336343800c01c08746573" - "743336343900c11c08746573743336353000c21c08746573743336353100c31c08746573743336353200c41c087465" - "73743336353300c51c08746573743336353400c61c08746573743336353500c71c08746573743336353600c81c0874" - "6573743336353700c91c08746573743336353800ca1c08746573743336353900cb1c08746573743336363000cc1c08" - "746573743336363100cd1c08746573743336363200ce1c08746573743336363300cf1c08746573743336363400d01c" - "08746573743336363500d11c08746573743336363600d21c08746573743336363700d31c08746573743336363800d4" - "1c08746573743336363900d51c08746573743336373000d61c08746573743336373100d71c08746573743336373200" - "d81c08746573743336373300d91c08746573743336373400da1c08746573743336373500db1c087465737433363736" - "00dc1c08746573743336373700dd1c08746573743336373800de1c08746573743336373900df1c0874657374333638" - "3000e01c08746573743336383100e11c08746573743336383200e21c08746573743336383300e31c08746573743336" - "383400e41c08746573743336383500e51c08746573743336383600e61c08746573743336383700e71c087465737433" - "36383800e81c08746573743336383900e91c08746573743336393000ea1c08746573743336393100eb1c0874657374" - "3336393200ec1c08746573743336393300ed1c08746573743336393400ee1c08746573743336393500ef1c08746573" - "743336393600f01c08746573743336393700f11c08746573743336393800f21c08746573743336393900f31c087465" - "73743337303000f41c08746573743337303100f51c08746573743337303200f61c08746573743337303300f71c0874" - "6573743337303400f81c08746573743337303500f91c08746573743337303600fa1c08746573743337303700fb1c08" - "746573743337303800fc1c08746573743337303900fd1c08746573743337313000fe1c08746573743337313100ff1c" - "08746573743337313200801d08746573743337313300811d08746573743337313400821d0874657374333731350083" - "1d08746573743337313600841d08746573743337313700851d08746573743337313800861d08746573743337313900" - "871d08746573743337323000881d08746573743337323100891d087465737433373232008a1d087465737433373233" - "008b1d087465737433373234008c1d087465737433373235008d1d087465737433373236008e1d0874657374333732" - "37008f1d08746573743337323800901d08746573743337323900911d08746573743337333000921d08746573743337" - "333100931d08746573743337333200941d08746573743337333300951d08746573743337333400961d087465737433" - "37333500971d08746573743337333600981d08746573743337333700991d087465737433373338009a1d0874657374" - "33373339009b1d087465737433373430009c1d087465737433373431009d1d087465737433373432009e1d08746573" - "7433373433009f1d08746573743337343400a01d08746573743337343500a11d08746573743337343600a21d087465" - "73743337343700a31d08746573743337343800a41d08746573743337343900a51d08746573743337353000a61d0874" - "6573743337353100a71d08746573743337353200a81d08746573743337353300a91d08746573743337353400aa1d08" - "746573743337353500ab1d08746573743337353600ac1d08746573743337353700ad1d08746573743337353800ae1d" - "08746573743337353900af1d08746573743337363000b01d08746573743337363100b11d08746573743337363200b2" - "1d08746573743337363300b31d08746573743337363400b41d08746573743337363500b51d08746573743337363600" - "b61d08746573743337363700b71d08746573743337363800b81d08746573743337363900b91d087465737433373730" - "00ba1d08746573743337373100bb1d08746573743337373200bc1d08746573743337373300bd1d0874657374333737" - "3400be1d08746573743337373500bf1d08746573743337373600c01d08746573743337373700c11d08746573743337" - "373800c21d08746573743337373900c31d08746573743337383000c41d08746573743337383100c51d087465737433" - "37383200c61d08746573743337383300c71d08746573743337383400c81d08746573743337383500c91d0874657374" - "3337383600ca1d08746573743337383700cb1d08746573743337383800cc1d08746573743337383900cd1d08746573" - "743337393000ce1d08746573743337393100cf1d08746573743337393200d01d08746573743337393300d11d087465" - "73743337393400d21d08746573743337393500d31d08746573743337393600d41d08746573743337393700d51d0874" - "6573743337393800d61d08746573743337393900d71d08746573743338303000d81d08746573743338303100d91d08" - "746573743338303200da1d08746573743338303300db1d08746573743338303400dc1d08746573743338303500dd1d" - "08746573743338303600de1d08746573743338303700df1d08746573743338303800e01d08746573743338303900e1" - "1d08746573743338313000e21d08746573743338313100e31d08746573743338313200e41d08746573743338313300" - "e51d08746573743338313400e61d08746573743338313500e71d08746573743338313600e81d087465737433383137" - "00e91d08746573743338313800ea1d08746573743338313900eb1d08746573743338323000ec1d0874657374333832" - "3100ed1d08746573743338323200ee1d08746573743338323300ef1d08746573743338323400f01d08746573743338" - "323500f11d08746573743338323600f21d08746573743338323700f31d08746573743338323800f41d087465737433" - "38323900f51d08746573743338333000f61d08746573743338333100f71d08746573743338333200f81d0874657374" - "3338333300f91d08746573743338333400fa1d08746573743338333500fb1d08746573743338333600fc1d08746573" - "743338333700fd1d08746573743338333800fe1d08746573743338333900ff1d08746573743338343000801e087465" - "73743338343100811e08746573743338343200821e08746573743338343300831e08746573743338343400841e0874" - "6573743338343500851e08746573743338343600861e08746573743338343700871e08746573743338343800881e08" - "746573743338343900891e087465737433383530008a1e087465737433383531008b1e087465737433383532008c1e" - "087465737433383533008d1e087465737433383534008e1e087465737433383535008f1e0874657374333835360090" - "1e08746573743338353700911e08746573743338353800921e08746573743338353900931e08746573743338363000" - "941e08746573743338363100951e08746573743338363200961e08746573743338363300971e087465737433383634" - "00981e08746573743338363500991e087465737433383636009a1e087465737433383637009b1e0874657374333836" - "38009c1e087465737433383639009d1e087465737433383730009e1e087465737433383731009f1e08746573743338" - "373200a01e08746573743338373300a11e08746573743338373400a21e08746573743338373500a31e087465737433" - "38373600a41e08746573743338373700a51e08746573743338373800a61e08746573743338373900a71e0874657374" - "3338383000a81e08746573743338383100a91e08746573743338383200aa1e08746573743338383300ab1e08746573" - "743338383400ac1e08746573743338383500ad1e08746573743338383600ae1e08746573743338383700af1e087465" - "73743338383800b01e08746573743338383900b11e08746573743338393000b21e08746573743338393100b31e0874" - "6573743338393200b41e08746573743338393300b51e08746573743338393400b61e08746573743338393500b71e08" - "746573743338393600b81e08746573743338393700b91e08746573743338393800ba1e08746573743338393900bb1e" - "08746573743339303000bc1e08746573743339303100bd1e08746573743339303200be1e08746573743339303300bf" - "1e08746573743339303400c01e08746573743339303500c11e08746573743339303600c21e08746573743339303700" - "c31e08746573743339303800c41e08746573743339303900c51e08746573743339313000c61e087465737433393131" - "00c71e08746573743339313200c81e08746573743339313300c91e08746573743339313400ca1e0874657374333931" - "3500cb1e08746573743339313600cc1e08746573743339313700cd1e08746573743339313800ce1e08746573743339" - "313900cf1e08746573743339323000d01e08746573743339323100d11e08746573743339323200d21e087465737433" - "39323300d31e08746573743339323400d41e08746573743339323500d51e08746573743339323600d61e0874657374" - "3339323700d71e08746573743339323800d81e08746573743339323900d91e08746573743339333000da1e08746573" - "743339333100db1e08746573743339333200dc1e08746573743339333300dd1e08746573743339333400de1e087465" - "73743339333500df1e08746573743339333600e01e08746573743339333700e11e08746573743339333800e21e0874" - "6573743339333900e31e08746573743339343000e41e08746573743339343100e51e08746573743339343200e61e08" - "746573743339343300e71e08746573743339343400e81e08746573743339343500e91e08746573743339343600ea1e" - "08746573743339343700eb1e08746573743339343800ec1e08746573743339343900ed1e08746573743339353000ee" - "1e08746573743339353100ef1e08746573743339353200f01e08746573743339353300f11e08746573743339353400" - "f21e08746573743339353500f31e08746573743339353600f41e08746573743339353700f51e087465737433393538" - "00f61e08746573743339353900f71e08746573743339363000f81e08746573743339363100f91e0874657374333936" - "3200fa1e08746573743339363300fb1e08746573743339363400fc1e08746573743339363500fd1e08746573743339" - "363600fe1e08746573743339363700ff1e08746573743339363800801f08746573743339363900811f087465737433" - "39373000821f08746573743339373100831f08746573743339373200841f08746573743339373300851f0874657374" - "3339373400861f08746573743339373500871f08746573743339373600881f08746573743339373700891f08746573" - "7433393738008a1f087465737433393739008b1f087465737433393830008c1f087465737433393831008d1f087465" - "737433393832008e1f087465737433393833008f1f08746573743339383400901f08746573743339383500911f0874" - "6573743339383600921f08746573743339383700931f08746573743339383800941f08746573743339383900951f08" - "746573743339393000961f08746573743339393100971f08746573743339393200981f08746573743339393300991f" - "087465737433393934009a1f087465737433393935009b1f087465737433393936009c1f087465737433393937009d" - "1f087465737433393938009e1f087465737433393939009f1f08746573743430303000a01f08746573743430303100" - "a11f08746573743430303200a21f08746573743430303300a31f08746573743430303400a41f087465737434303035" - "00a51f08746573743430303600a61f08746573743430303700a71f08746573743430303800a81f0874657374343030" - "3900a91f08746573743430313000aa1f08746573743430313100ab1f08746573743430313200ac1f08746573743430" - "313300ad1f08746573743430313400ae1f08746573743430313500af1f08746573743430313600b01f087465737434" - "30313700b11f08746573743430313800b21f08746573743430313900b31f08746573743430323000b41f0874657374" - "3430323100b51f08746573743430323200b61f08746573743430323300b71f08746573743430323400b81f08746573" - "743430323500b91f08746573743430323600ba1f08746573743430323700bb1f08746573743430323800bc1f087465" - "73743430323900bd1f08746573743430333000be1f08746573743430333100bf1f08746573743430333200c01f0874" - "6573743430333300c11f08746573743430333400c21f08746573743430333500c31f08746573743430333600c41f08" - "746573743430333700c51f08746573743430333800c61f08746573743430333900c71f08746573743430343000c81f" - "08746573743430343100c91f08746573743430343200ca1f08746573743430343300cb1f08746573743430343400cc" - "1f08746573743430343500cd1f08746573743430343600ce1f08746573743430343700cf1f08746573743430343800" - "d01f08746573743430343900d11f08746573743430353000d21f08746573743430353100d31f087465737434303532" - "00d41f08746573743430353300d51f08746573743430353400d61f08746573743430353500d71f0874657374343035" - "3600d81f08746573743430353700d91f08746573743430353800da1f08746573743430353900db1f08746573743430" - "363000dc1f08746573743430363100dd1f08746573743430363200de1f08746573743430363300df1f087465737434" - "30363400e01f08746573743430363500e11f08746573743430363600e21f08746573743430363700e31f0874657374" - "3430363800e41f08746573743430363900e51f08746573743430373000e61f08746573743430373100e71f08746573" - "743430373200e81f08746573743430373300e91f08746573743430373400ea1f08746573743430373500eb1f087465" - "73743430373600ec1f08746573743430373700ed1f08746573743430373800ee1f08746573743430373900ef1f0874" - "6573743430383000f01f08746573743430383100f11f08746573743430383200f21f08746573743430383300f31f08" - "746573743430383400f41f08746573743430383500f51f08746573743430383600f61f08746573743430383700f71f" - "08746573743430383800f81f08746573743430383900f91f08746573743430393000fa1f08746573743430393100fb" - "1f08746573743430393200fc1f08746573743430393300fd1f08746573743430393400fe1f08746573743430393500" - "ff1f087465737434303936008020087465737434303937008120087465737434303938008220087465737434303939" - "0083200874657374343130300084200874657374343130310085200874657374343130320086200874657374343130" - "33008720087465737434313034008820087465737434313035008920087465737434313036008a2008746573743431" - "3037008b20087465737434313038008c20087465737434313039008d20087465737434313130008e20087465737434" - "313131008f200874657374343131320090200874657374343131330091200874657374343131340092200874657374" - "3431313500932008746573743431313600942008746573743431313700952008746573743431313800962008746573" - "7434313139009720087465737434313230009820087465737434313231009920087465737434313232009a20087465" - "737434313233009b20087465737434313234009c20087465737434313235009d20087465737434313236009e200874" - "65737434313237009f2008746573743431323800a02008746573743431323900a12008746573743431333000a22008" - "746573743431333100a32008746573743431333200a42008746573743431333300a52008746573743431333400a620" - "08746573743431333500a72008746573743431333600a82008746573743431333700a92008746573743431333800aa" - "2008746573743431333900ab2008746573743431343000ac2008746573743431343100ad2008746573743431343200" - "ae2008746573743431343300af2008746573743431343400b02008746573743431343500b120087465737434313436" - "00b22008746573743431343700b32008746573743431343800b42008746573743431343900b5200874657374343135" - "3000b62008746573743431353100b72008746573743431353200b82008746573743431353300b92008746573743431" - "353400ba2008746573743431353500bb2008746573743431353600bc2008746573743431353700bd20087465737434" - "31353800be2008746573743431353900bf2008746573743431363000c02008746573743431363100c1200874657374" - "3431363200c22008746573743431363300c32008746573743431363400c42008746573743431363500c52008746573" - "743431363600c62008746573743431363700c72008746573743431363800c82008746573743431363900c920087465" - "73743431373000ca2008746573743431373100cb2008746573743431373200cc2008746573743431373300cd200874" - "6573743431373400ce2008746573743431373500cf2008746573743431373600d02008746573743431373700d12008" - "746573743431373800d22008746573743431373900d32008746573743431383000d42008746573743431383100d520" - "08746573743431383200d62008746573743431383300d72008746573743431383400d82008746573743431383500d9" - "2008746573743431383600da2008746573743431383700db2008746573743431383800dc2008746573743431383900" - "dd2008746573743431393000de2008746573743431393100df2008746573743431393200e020087465737434313933" - "00e12008746573743431393400e22008746573743431393500e32008746573743431393600e4200874657374343139" - "3700e52008746573743431393800e62008746573743431393900e72008746573743432303000e82008746573743432" - "303100e92008746573743432303200ea2008746573743432303300eb2008746573743432303400ec20087465737434" - "32303500ed2008746573743432303600ee2008746573743432303700ef2008746573743432303800f0200874657374" - "3432303900f12008746573743432313000f22008746573743432313100f32008746573743432313200f42008746573" - "743432313300f52008746573743432313400f62008746573743432313500f72008746573743432313600f820087465" - "73743432313700f92008746573743432313800fa2008746573743432313900fb2008746573743432323000fc200874" - "6573743432323100fd2008746573743432323200fe2008746573743432323300ff2008746573743432323400802108" - "7465737434323235008121087465737434323236008221087465737434323237008321087465737434323238008421" - "0874657374343232390085210874657374343233300086210874657374343233310087210874657374343233320088" - "21087465737434323333008921087465737434323334008a21087465737434323335008b2108746573743432333600" - "8c21087465737434323337008d21087465737434323338008e21087465737434323339008f21087465737434323430" - "0090210874657374343234310091210874657374343234320092210874657374343234330093210874657374343234" - "3400942108746573743432343500952108746573743432343600962108746573743432343700972108746573743432" - "3438009821087465737434323439009921087465737434323530009a21087465737434323531009b21087465737434" - "323532009c21087465737434323533009d21087465737434323534009e21087465737434323535009f210874657374" - "3432353600a02108746573743432353700a12108746573743432353800a22108746573743432353900a32108746573" - "743432363000a42108746573743432363100a52108746573743432363200a62108746573743432363300a721087465" - "73743432363400a82108746573743432363500a92108746573743432363600aa2108746573743432363700ab210874" - "6573743432363800ac2108746573743432363900ad2108746573743432373000ae2108746573743432373100af2108" - "746573743432373200b02108746573743432373300b12108746573743432373400b22108746573743432373500b321" - "08746573743432373600b42108746573743432373700b52108746573743432373800b62108746573743432373900b7" - "2108746573743432383000b82108746573743432383100b92108746573743432383200ba2108746573743432383300" - "bb2108746573743432383400bc2108746573743432383500bd2108746573743432383600be21087465737434323837" - "00bf2108746573743432383800c02108746573743432383900c12108746573743432393000c2210874657374343239" - "3100c32108746573743432393200c42108746573743432393300c52108746573743432393400c62108746573743432" - "393500c72108746573743432393600c82108746573743432393700c92108746573743432393800ca21087465737434" - "32393900cb2108746573743433303000cc2108746573743433303100cd2108746573743433303200ce210874657374" - "3433303300cf2108746573743433303400d02108746573743433303500d12108746573743433303600d22108746573" - "743433303700d32108746573743433303800d42108746573743433303900d52108746573743433313000d621087465" - "73743433313100d72108746573743433313200d82108746573743433313300d92108746573743433313400da210874" - "6573743433313500db2108746573743433313600dc2108746573743433313700dd2108746573743433313800de2108" - "746573743433313900df2108746573743433323000e02108746573743433323100e12108746573743433323200e221" - "08746573743433323300e32108746573743433323400e42108746573743433323500e52108746573743433323600e6" - "2108746573743433323700e72108746573743433323800e82108746573743433323900e92108746573743433333000" - "ea2108746573743433333100eb2108746573743433333200ec2108746573743433333300ed21087465737434333334" - "00ee2108746573743433333500ef2108746573743433333600f02108746573743433333700f1210874657374343333" - "3800f22108746573743433333900f32108746573743433343000f42108746573743433343100f52108746573743433" - "343200f62108746573743433343300f72108746573743433343400f82108746573743433343500f921087465737434" - "33343600fa2108746573743433343700fb2108746573743433343800fc2108746573743433343900fd210874657374" - "3433353000fe2108746573743433353100ff2108746573743433353200802208746573743433353300812208746573" - "7434333534008222087465737434333535008322087465737434333536008422087465737434333537008522087465" - "7374343335380086220874657374343335390087220874657374343336300088220874657374343336310089220874" - "65737434333632008a22087465737434333633008b22087465737434333634008c22087465737434333635008d2208" - "7465737434333636008e22087465737434333637008f22087465737434333638009022087465737434333639009122" - "0874657374343337300092220874657374343337310093220874657374343337320094220874657374343337330095" - "2208746573743433373400962208746573743433373500972208746573743433373600982208746573743433373700" - "9922087465737434333738009a22087465737434333739009b22087465737434333830009c22087465737434333831" - "009d22087465737434333832009e22087465737434333833009f2208746573743433383400a0220874657374343338" - "3500a12208746573743433383600a22208746573743433383700a32208746573743433383800a42208746573743433" - "383900a52208746573743433393000a62208746573743433393100a72208746573743433393200a822087465737434" - "33393300a92208746573743433393400aa2208746573743433393500ab2208746573743433393600ac220874657374" - "3433393700ad2208746573743433393800ae2208746573743433393900af2208746573743434303000b02208746573" - "743434303100b12208746573743434303200b22208746573743434303300b32208746573743434303400b422087465" - "73743434303500b52208746573743434303600b62208746573743434303700b72208746573743434303800b8220874" - "6573743434303900b92208746573743434313000ba2208746573743434313100bb2208746573743434313200bc2208" - "746573743434313300bd2208746573743434313400be2208746573743434313500bf2208746573743434313600c022" - "08746573743434313700c12208746573743434313800c22208746573743434313900c32208746573743434323000c4" - "2208746573743434323100c52208746573743434323200c62208746573743434323300c72208746573743434323400" - "c82208746573743434323500c92208746573743434323600ca2208746573743434323700cb22087465737434343238" - "00cc2208746573743434323900cd2208746573743434333000ce2208746573743434333100cf220874657374343433" - "3200d02208746573743434333300d12208746573743434333400d22208746573743434333500d32208746573743434" - "333600d42208746573743434333700d52208746573743434333800d62208746573743434333900d722087465737434" - "34343000d82208746573743434343100d92208746573743434343200da2208746573743434343300db220874657374" - "3434343400dc2208746573743434343500dd2208746573743434343600de2208746573743434343700df2208746573" - "743434343800e02208746573743434343900e12208746573743434353000e22208746573743434353100e322087465" - "73743434353200e42208746573743434353300e52208746573743434353400e62208746573743434353500e7220874" - "6573743434353600e82208746573743434353700e92208746573743434353800ea2208746573743434353900eb2208" - "746573743434363000ec2208746573743434363100ed2208746573743434363200ee2208746573743434363300ef22" - "08746573743434363400f02208746573743434363500f12208746573743434363600f22208746573743434363700f3" - "2208746573743434363800f42208746573743434363900f52208746573743434373000f62208746573743434373100" - "f72208746573743434373200f82208746573743434373300f92208746573743434373400fa22087465737434343735" - "00fb2208746573743434373600fc2208746573743434373700fd2208746573743434373800fe220874657374343437" - "3900ff2208746573743434383000802308746573743434383100812308746573743434383200822308746573743434" - "3833008323087465737434343834008423087465737434343835008523087465737434343836008623087465737434" - "343837008723087465737434343838008823087465737434343839008923087465737434343930008a230874657374" - "34343931008b23087465737434343932008c23087465737434343933008d23087465737434343934008e2308746573" - "7434343935008f23087465737434343936009023087465737434343937009123087465737434343938009223087465" - "7374343439390093230874657374343530300094230874657374343530310095230874657374343530320096230874" - "65737434353033009723087465737434353034009823087465737434353035009923087465737434353036009a2308" - "7465737434353037009b23087465737434353038009c23087465737434353039009d23087465737434353130009e23" - "087465737434353131009f2308746573743435313200a02308746573743435313300a12308746573743435313400a2" - "2308746573743435313500a32308746573743435313600a42308746573743435313700a52308746573743435313800" - "a62308746573743435313900a72308746573743435323000a82308746573743435323100a923087465737434353232" - "00aa2308746573743435323300ab2308746573743435323400ac2308746573743435323500ad230874657374343532" - "3600ae2308746573743435323700af2308746573743435323800b02308746573743435323900b12308746573743435" - "333000b22308746573743435333100b32308746573743435333200b42308746573743435333300b523087465737434" - "35333400b62308746573743435333500b72308746573743435333600b82308746573743435333700b9230874657374" - "3435333800ba2308746573743435333900bb2308746573743435343000bc2308746573743435343100bd2308746573" - "743435343200be2308746573743435343300bf2308746573743435343400c02308746573743435343500c123087465" - "73743435343600c22308746573743435343700c32308746573743435343800c42308746573743435343900c5230874" - "6573743435353000c62308746573743435353100c72308746573743435353200c82308746573743435353300c92308" - "746573743435353400ca2308746573743435353500cb2308746573743435353600cc2308746573743435353700cd23" - "08746573743435353800ce2308746573743435353900cf2308746573743435363000d02308746573743435363100d1" - "2308746573743435363200d22308746573743435363300d32308746573743435363400d42308746573743435363500" - "d52308746573743435363600d62308746573743435363700d72308746573743435363800d823087465737434353639" - "00d92308746573743435373000da2308746573743435373100db2308746573743435373200dc230874657374343537" - "3300dd2308746573743435373400de2308746573743435373500df2308746573743435373600e02308746573743435" - "373700e12308746573743435373800e22308746573743435373900e32308746573743435383000e423087465737434" - "35383100e52308746573743435383200e62308746573743435383300e72308746573743435383400e8230874657374" - "3435383500e92308746573743435383600ea2308746573743435383700eb2308746573743435383800ec2308746573" - "743435383900ed2308746573743435393000ee2308746573743435393100ef2308746573743435393200f023087465" - "73743435393300f12308746573743435393400f22308746573743435393500f32308746573743435393600f4230874" - "6573743435393700f52308746573743435393800f62308746573743435393900f72308746573743436303000f82308" - "746573743436303100f92308746573743436303200fa2308746573743436303300fb2308746573743436303400fc23" - "08746573743436303500fd2308746573743436303600fe2308746573743436303700ff230874657374343630380080" - "2408746573743436303900812408746573743436313000822408746573743436313100832408746573743436313200" - "8424087465737434363133008524087465737434363134008624087465737434363135008724087465737434363136" - "008824087465737434363137008924087465737434363138008a24087465737434363139008b240874657374343632" - "30008c24087465737434363231008d24087465737434363232008e24087465737434363233008f2408746573743436" - "3234009024087465737434363235009124087465737434363236009224087465737434363237009324087465737434" - "3632380094240874657374343632390095240874657374343633300096240874657374343633310097240874657374" - "34363332009824087465737434363333009924087465737434363334009a24087465737434363335009b2408746573" - "7434363336009c24087465737434363337009d24087465737434363338009e24087465737434363339009f24087465" - "73743436343000a02408746573743436343100a12408746573743436343200a22408746573743436343300a3240874" - "6573743436343400a42408746573743436343500a52408746573743436343600a62408746573743436343700a72408" - "746573743436343800a82408746573743436343900a92408746573743436353000aa2408746573743436353100ab24" - "08746573743436353200ac2408746573743436353300ad2408746573743436353400ae2408746573743436353500af" - "2408746573743436353600b02408746573743436353700b12408746573743436353800b22408746573743436353900" - "b32408746573743436363000b42408746573743436363100b52408746573743436363200b624087465737434363633" - "00b72408746573743436363400b82408746573743436363500b92408746573743436363600ba240874657374343636" - "3700bb2408746573743436363800bc2408746573743436363900bd2408746573743436373000be2408746573743436" - "373100bf2408746573743436373200c02408746573743436373300c12408746573743436373400c224087465737434" - "36373500c32408746573743436373600c42408746573743436373700c52408746573743436373800c6240874657374" - "3436373900c72408746573743436383000c82408746573743436383100c92408746573743436383200ca2408746573" - "743436383300cb2408746573743436383400cc2408746573743436383500cd2408746573743436383600ce24087465" - "73743436383700cf2408746573743436383800d02408746573743436383900d12408746573743436393000d2240874" - "6573743436393100d32408746573743436393200d42408746573743436393300d52408746573743436393400d62408" - "746573743436393500d72408746573743436393600d82408746573743436393700d92408746573743436393800da24" - "08746573743436393900db2408746573743437303000dc2408746573743437303100dd2408746573743437303200de" - "2408746573743437303300df2408746573743437303400e02408746573743437303500e12408746573743437303600" - "e22408746573743437303700e32408746573743437303800e42408746573743437303900e524087465737434373130" - "00e62408746573743437313100e72408746573743437313200e82408746573743437313300e9240874657374343731" - "3400ea2408746573743437313500eb2408746573743437313600ec2408746573743437313700ed2408746573743437" - "313800ee2408746573743437313900ef2408746573743437323000f02408746573743437323100f124087465737434" - "37323200f22408746573743437323300f32408746573743437323400f42408746573743437323500f5240874657374" - "3437323600f62408746573743437323700f72408746573743437323800f82408746573743437323900f92408746573" - "743437333000fa2408746573743437333100fb2408746573743437333200fc2408746573743437333300fd24087465" - "73743437333400fe2408746573743437333500ff240874657374343733360080250874657374343733370081250874" - "6573743437333800822508746573743437333900832508746573743437343000842508746573743437343100852508" - "7465737434373432008625087465737434373433008725087465737434373434008825087465737434373435008925" - "087465737434373436008a25087465737434373437008b25087465737434373438008c25087465737434373439008d" - "25087465737434373530008e25087465737434373531008f2508746573743437353200902508746573743437353300" - "9125087465737434373534009225087465737434373535009325087465737434373536009425087465737434373537" - "0095250874657374343735380096250874657374343735390097250874657374343736300098250874657374343736" - "31009925087465737434373632009a25087465737434373633009b25087465737434373634009c2508746573743437" - "3635009d25087465737434373636009e25087465737434373637009f2508746573743437363800a025087465737434" - "37363900a12508746573743437373000a22508746573743437373100a32508746573743437373200a4250874657374" - "3437373300a52508746573743437373400a62508746573743437373500a72508746573743437373600a82508746573" - "743437373700a92508746573743437373800aa2508746573743437373900ab2508746573743437383000ac25087465" - "73743437383100ad2508746573743437383200ae2508746573743437383300af2508746573743437383400b0250874" - "6573743437383500b12508746573743437383600b22508746573743437383700b32508746573743437383800b42508" - "746573743437383900b52508746573743437393000b62508746573743437393100b72508746573743437393200b825" - "08746573743437393300b92508746573743437393400ba2508746573743437393500bb2508746573743437393600bc" - "2508746573743437393700bd2508746573743437393800be2508746573743437393900bf2508746573743438303000" - "c02508746573743438303100c12508746573743438303200c22508746573743438303300c325087465737434383034" - "00c42508746573743438303500c52508746573743438303600c62508746573743438303700c7250874657374343830" - "3800c82508746573743438303900c92508746573743438313000ca2508746573743438313100cb2508746573743438" - "313200cc2508746573743438313300cd2508746573743438313400ce2508746573743438313500cf25087465737434" - "38313600d02508746573743438313700d12508746573743438313800d22508746573743438313900d3250874657374" - "3438323000d42508746573743438323100d52508746573743438323200d62508746573743438323300d72508746573" - "743438323400d82508746573743438323500d92508746573743438323600da2508746573743438323700db25087465" - "73743438323800dc2508746573743438323900dd2508746573743438333000de2508746573743438333100df250874" - "6573743438333200e02508746573743438333300e12508746573743438333400e22508746573743438333500e32508" - "746573743438333600e42508746573743438333700e52508746573743438333800e62508746573743438333900e725" - "08746573743438343000e82508746573743438343100e92508746573743438343200ea2508746573743438343300eb" - "2508746573743438343400ec2508746573743438343500ed2508746573743438343600ee2508746573743438343700" - "ef2508746573743438343800f02508746573743438343900f12508746573743438353000f225087465737434383531" - "00f32508746573743438353200f42508746573743438353300f52508746573743438353400f6250874657374343835" - "3500f72508746573743438353600f82508746573743438353700f92508746573743438353800fa2508746573743438" - "353900fb2508746573743438363000fc2508746573743438363100fd2508746573743438363200fe25087465737434" - "38363300ff250874657374343836340080260874657374343836350081260874657374343836360082260874657374" - "3438363700832608746573743438363800842608746573743438363900852608746573743438373000862608746573" - "7434383731008726087465737434383732008826087465737434383733008926087465737434383734008a26087465" - "737434383735008b26087465737434383736008c26087465737434383737008d26087465737434383738008e260874" - "65737434383739008f2608746573743438383000902608746573743438383100912608746573743438383200922608" - "7465737434383833009326087465737434383834009426087465737434383835009526087465737434383836009626" - "087465737434383837009726087465737434383838009826087465737434383839009926087465737434383930009a" - "26087465737434383931009b26087465737434383932009c26087465737434383933009d2608746573743438393400" - "9e26087465737434383935009f2608746573743438393600a02608746573743438393700a126087465737434383938" - "00a22608746573743438393900a32608746573743439303000a42608746573743439303100a5260874657374343930" - "3200a62608746573743439303300a72608746573743439303400a82608746573743439303500a92608746573743439" - "303600aa2608746573743439303700ab2608746573743439303800ac2608746573743439303900ad26087465737434" - "39313000ae2608746573743439313100af2608746573743439313200b02608746573743439313300b1260874657374" - "3439313400b22608746573743439313500b32608746573743439313600b42608746573743439313700b52608746573" - "743439313800b62608746573743439313900b72608746573743439323000b82608746573743439323100b926087465" - "73743439323200ba2608746573743439323300bb2608746573743439323400bc2608746573743439323500bd260874" - "6573743439323600be2608746573743439323700bf2608746573743439323800c02608746573743439323900c12608" - "746573743439333000c22608746573743439333100c32608746573743439333200c42608746573743439333300c526" - "08746573743439333400c62608746573743439333500c72608746573743439333600c82608746573743439333700c9" - "2608746573743439333800ca2608746573743439333900cb2608746573743439343000cc2608746573743439343100" - "cd2608746573743439343200ce2608746573743439343300cf2608746573743439343400d026087465737434393435" - "00d12608746573743439343600d22608746573743439343700d32608746573743439343800d4260874657374343934" - "3900d52608746573743439353000d62608746573743439353100d72608746573743439353200d82608746573743439" - "353300d92608746573743439353400da2608746573743439353500db2608746573743439353600dc26087465737434" - "39353700dd2608746573743439353800de2608746573743439353900df2608746573743439363000e0260874657374" - "3439363100e12608746573743439363200e22608746573743439363300e32608746573743439363400e42608746573" - "743439363500e52608746573743439363600e62608746573743439363700e72608746573743439363800e826087465" - "73743439363900e92608746573743439373000ea2608746573743439373100eb2608746573743439373200ec260874" - "6573743439373300ed2608746573743439373400ee2608746573743439373500ef2608746573743439373600f02608" - "746573743439373700f12608746573743439373800f22608746573743439373900f32608746573743439383000f426" - "08746573743439383100f52608746573743439383200f62608746573743439383300f72608746573743439383400f8" - "2608746573743439383500f92608746573743439383600fa2608746573743439383700fb2608746573743439383800" - "fc2608746573743439383900fd2608746573743439393000fe2608746573743439393100ff26087465737434393932" - "0080270874657374343939330081270874657374343939340082270874657374343939350083270874657374343939" - "360084270874657374343939370085270874657374343939380086270874657374343939390087270ac2b802882707" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020" - "016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07002000" - "20016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020" - "0020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700" - "200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b07" - "00200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b" - "0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a" - "0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b0700200020016a0b070020002001" - "6a0b"; diff --git a/src/test/app/wasm_fixtures/fixture_locals_10k.cpp b/src/test/app/wasm_fixtures/fixture_locals_10k.cpp deleted file mode 100644 index 75a799243d..0000000000 --- a/src/test/app/wasm_fixtures/fixture_locals_10k.cpp +++ /dev/null @@ -1,2128 +0,0 @@ -// TODO: consider moving these to separate files (and figure out the build) - -#include - -#include - -extern std::string const kLocals10kHex = - "0061736d0100000001070160027f7f017f03020100070801047465737400000a9b8a0601978a06018e4e7f20002001" - "6a2102200120026a2103200220036a2104200320046a2105200420056a2106200520066a2107200620076a21082007" - "20086a2109200820096a210a2009200a6a210b200a200b6a210c200b200c6a210d200c200d6a210e200d200e6a210f" - "200e200f6a2110200f20106a2111201020116a2112201120126a2113201220136a2114201320146a2115201420156a" - "2116201520166a2117201620176a2118201720186a2119201820196a211a2019201a6a211b201a201b6a211c201b20" - "1c6a211d201c201d6a211e201d201e6a211f201e201f6a2120201f20206a2121202020216a2122202120226a212320" - "2220236a2124202320246a2125202420256a2126202520266a2127202620276a2128202720286a2129202820296a21" - "2a2029202a6a212b202a202b6a212c202b202c6a212d202c202d6a212e202d202e6a212f202e202f6a2130202f2030" - "6a2131203020316a2132203120326a2133203220336a2134203320346a2135203420356a2136203520366a21372036" - "20376a2138203720386a2139203820396a213a2039203a6a213b203a203b6a213c203b203c6a213d203c203d6a213e" - "203d203e6a213f203e203f6a2140203f20406a2141204020416a2142204120426a2143204220436a2144204320446a" - "2145204420456a2146204520466a2147204620476a2148204720486a2149204820496a214a2049204a6a214b204a20" - "4b6a214c204b204c6a214d204c204d6a214e204d204e6a214f204e204f6a2150204f20506a2151205020516a215220" - "5120526a2153205220536a2154205320546a2155205420556a2156205520566a2157205620576a2158205720586a21" - "59205820596a215a2059205a6a215b205a205b6a215c205b205c6a215d205c205d6a215e205d205e6a215f205e205f" - "6a2160205f20606a2161206020616a2162206120626a2163206220636a2164206320646a2165206420656a21662065" - "20666a2167206620676a2168206720686a2169206820696a216a2069206a6a216b206a206b6a216c206b206c6a216d" - "206c206d6a216e206d206e6a216f206e206f6a2170206f20706a2171207020716a2172207120726a2173207220736a" - "2174207320746a2175207420756a2176207520766a2177207620776a2178207720786a2179207820796a217a207920" - "7a6a217b207a207b6a217c207b207c6a217d207c207d6a217e207d207e6a217f207e207f6a218001207f2080016a21" - "81012080012081016a2182012081012082016a2183012082012083016a2184012083012084016a2185012084012085" - "016a2186012085012086016a2187012086012087016a2188012087012088016a2189012088012089016a218a012089" - "01208a016a218b01208a01208b016a218c01208b01208c016a218d01208c01208d016a218e01208d01208e016a218f" - "01208e01208f016a219001208f012090016a2191012090012091016a2192012091012092016a219301209201209301" - "6a2194012093012094016a2195012094012095016a2196012095012096016a2197012096012097016a219801209701" - "2098016a2199012098012099016a219a01209901209a016a219b01209a01209b016a219c01209b01209c016a219d01" - "209c01209d016a219e01209d01209e016a219f01209e01209f016a21a001209f0120a0016a21a10120a00120a1016a" - "21a20120a10120a2016a21a30120a20120a3016a21a40120a30120a4016a21a50120a40120a5016a21a60120a50120" - "a6016a21a70120a60120a7016a21a80120a70120a8016a21a90120a80120a9016a21aa0120a90120aa016a21ab0120" - "aa0120ab016a21ac0120ab0120ac016a21ad0120ac0120ad016a21ae0120ad0120ae016a21af0120ae0120af016a21" - "b00120af0120b0016a21b10120b00120b1016a21b20120b10120b2016a21b30120b20120b3016a21b40120b30120b4" - "016a21b50120b40120b5016a21b60120b50120b6016a21b70120b60120b7016a21b80120b70120b8016a21b90120b8" - "0120b9016a21ba0120b90120ba016a21bb0120ba0120bb016a21bc0120bb0120bc016a21bd0120bc0120bd016a21be" - "0120bd0120be016a21bf0120be0120bf016a21c00120bf0120c0016a21c10120c00120c1016a21c20120c10120c201" - "6a21c30120c20120c3016a21c40120c30120c4016a21c50120c40120c5016a21c60120c50120c6016a21c70120c601" - "20c7016a21c80120c70120c8016a21c90120c80120c9016a21ca0120c90120ca016a21cb0120ca0120cb016a21cc01" - "20cb0120cc016a21cd0120cc0120cd016a21ce0120cd0120ce016a21cf0120ce0120cf016a21d00120cf0120d0016a" - "21d10120d00120d1016a21d20120d10120d2016a21d30120d20120d3016a21d40120d30120d4016a21d50120d40120" - "d5016a21d60120d50120d6016a21d70120d60120d7016a21d80120d70120d8016a21d90120d80120d9016a21da0120" - "d90120da016a21db0120da0120db016a21dc0120db0120dc016a21dd0120dc0120dd016a21de0120dd0120de016a21" - "df0120de0120df016a21e00120df0120e0016a21e10120e00120e1016a21e20120e10120e2016a21e30120e20120e3" - "016a21e40120e30120e4016a21e50120e40120e5016a21e60120e50120e6016a21e70120e60120e7016a21e80120e7" - "0120e8016a21e90120e80120e9016a21ea0120e90120ea016a21eb0120ea0120eb016a21ec0120eb0120ec016a21ed" - "0120ec0120ed016a21ee0120ed0120ee016a21ef0120ee0120ef016a21f00120ef0120f0016a21f10120f00120f101" - "6a21f20120f10120f2016a21f30120f20120f3016a21f40120f30120f4016a21f50120f40120f5016a21f60120f501" - "20f6016a21f70120f60120f7016a21f80120f70120f8016a21f90120f80120f9016a21fa0120f90120fa016a21fb01" - "20fa0120fb016a21fc0120fb0120fc016a21fd0120fc0120fd016a21fe0120fd0120fe016a21ff0120fe0120ff016a" - "21800220ff012080026a2181022080022081026a2182022081022082026a2183022082022083026a21840220830220" - "84026a2185022084022085026a2186022085022086026a2187022086022087026a2188022087022088026a21890220" - "88022089026a218a02208902208a026a218b02208a02208b026a218c02208b02208c026a218d02208c02208d026a21" - "8e02208d02208e026a218f02208e02208f026a219002208f022090026a2191022090022091026a2192022091022092" - "026a2193022092022093026a2194022093022094026a2195022094022095026a2196022095022096026a2197022096" - "022097026a2198022097022098026a2199022098022099026a219a02209902209a026a219b02209a02209b026a219c" - "02209b02209c026a219d02209c02209d026a219e02209d02209e026a219f02209e02209f026a21a002209f0220a002" - "6a21a10220a00220a1026a21a20220a10220a2026a21a30220a20220a3026a21a40220a30220a4026a21a50220a402" - "20a5026a21a60220a50220a6026a21a70220a60220a7026a21a80220a70220a8026a21a90220a80220a9026a21aa02" - "20a90220aa026a21ab0220aa0220ab026a21ac0220ab0220ac026a21ad0220ac0220ad026a21ae0220ad0220ae026a" - "21af0220ae0220af026a21b00220af0220b0026a21b10220b00220b1026a21b20220b10220b2026a21b30220b20220" - "b3026a21b40220b30220b4026a21b50220b40220b5026a21b60220b50220b6026a21b70220b60220b7026a21b80220" - "b70220b8026a21b90220b80220b9026a21ba0220b90220ba026a21bb0220ba0220bb026a21bc0220bb0220bc026a21" - "bd0220bc0220bd026a21be0220bd0220be026a21bf0220be0220bf026a21c00220bf0220c0026a21c10220c00220c1" - "026a21c20220c10220c2026a21c30220c20220c3026a21c40220c30220c4026a21c50220c40220c5026a21c60220c5" - "0220c6026a21c70220c60220c7026a21c80220c70220c8026a21c90220c80220c9026a21ca0220c90220ca026a21cb" - "0220ca0220cb026a21cc0220cb0220cc026a21cd0220cc0220cd026a21ce0220cd0220ce026a21cf0220ce0220cf02" - "6a21d00220cf0220d0026a21d10220d00220d1026a21d20220d10220d2026a21d30220d20220d3026a21d40220d302" - "20d4026a21d50220d40220d5026a21d60220d50220d6026a21d70220d60220d7026a21d80220d70220d8026a21d902" - "20d80220d9026a21da0220d90220da026a21db0220da0220db026a21dc0220db0220dc026a21dd0220dc0220dd026a" - "21de0220dd0220de026a21df0220de0220df026a21e00220df0220e0026a21e10220e00220e1026a21e20220e10220" - "e2026a21e30220e20220e3026a21e40220e30220e4026a21e50220e40220e5026a21e60220e50220e6026a21e70220" - "e60220e7026a21e80220e70220e8026a21e90220e80220e9026a21ea0220e90220ea026a21eb0220ea0220eb026a21" - "ec0220eb0220ec026a21ed0220ec0220ed026a21ee0220ed0220ee026a21ef0220ee0220ef026a21f00220ef0220f0" - "026a21f10220f00220f1026a21f20220f10220f2026a21f30220f20220f3026a21f40220f30220f4026a21f50220f4" - "0220f5026a21f60220f50220f6026a21f70220f60220f7026a21f80220f70220f8026a21f90220f80220f9026a21fa" - "0220f90220fa026a21fb0220fa0220fb026a21fc0220fb0220fc026a21fd0220fc0220fd026a21fe0220fd0220fe02" - "6a21ff0220fe0220ff026a21800320ff022080036a2181032080032081036a2182032081032082036a218303208203" - "2083036a2184032083032084036a2185032084032085036a2186032085032086036a2187032086032087036a218803" - "2087032088036a2189032088032089036a218a03208903208a036a218b03208a03208b036a218c03208b03208c036a" - "218d03208c03208d036a218e03208d03208e036a218f03208e03208f036a219003208f032090036a21910320900320" - "91036a2192032091032092036a2193032092032093036a2194032093032094036a2195032094032095036a21960320" - "95032096036a2197032096032097036a2198032097032098036a2199032098032099036a219a03209903209a036a21" - "9b03209a03209b036a219c03209b03209c036a219d03209c03209d036a219e03209d03209e036a219f03209e03209f" - "036a21a003209f0320a0036a21a10320a00320a1036a21a20320a10320a2036a21a30320a20320a3036a21a40320a3" - "0320a4036a21a50320a40320a5036a21a60320a50320a6036a21a70320a60320a7036a21a80320a70320a8036a21a9" - "0320a80320a9036a21aa0320a90320aa036a21ab0320aa0320ab036a21ac0320ab0320ac036a21ad0320ac0320ad03" - "6a21ae0320ad0320ae036a21af0320ae0320af036a21b00320af0320b0036a21b10320b00320b1036a21b20320b103" - "20b2036a21b30320b20320b3036a21b40320b30320b4036a21b50320b40320b5036a21b60320b50320b6036a21b703" - "20b60320b7036a21b80320b70320b8036a21b90320b80320b9036a21ba0320b90320ba036a21bb0320ba0320bb036a" - "21bc0320bb0320bc036a21bd0320bc0320bd036a21be0320bd0320be036a21bf0320be0320bf036a21c00320bf0320" - "c0036a21c10320c00320c1036a21c20320c10320c2036a21c30320c20320c3036a21c40320c30320c4036a21c50320" - "c40320c5036a21c60320c50320c6036a21c70320c60320c7036a21c80320c70320c8036a21c90320c80320c9036a21" - "ca0320c90320ca036a21cb0320ca0320cb036a21cc0320cb0320cc036a21cd0320cc0320cd036a21ce0320cd0320ce" - "036a21cf0320ce0320cf036a21d00320cf0320d0036a21d10320d00320d1036a21d20320d10320d2036a21d30320d2" - "0320d3036a21d40320d30320d4036a21d50320d40320d5036a21d60320d50320d6036a21d70320d60320d7036a21d8" - "0320d70320d8036a21d90320d80320d9036a21da0320d90320da036a21db0320da0320db036a21dc0320db0320dc03" - "6a21dd0320dc0320dd036a21de0320dd0320de036a21df0320de0320df036a21e00320df0320e0036a21e10320e003" - "20e1036a21e20320e10320e2036a21e30320e20320e3036a21e40320e30320e4036a21e50320e40320e5036a21e603" - "20e50320e6036a21e70320e60320e7036a21e80320e70320e8036a21e90320e80320e9036a21ea0320e90320ea036a" - "21eb0320ea0320eb036a21ec0320eb0320ec036a21ed0320ec0320ed036a21ee0320ed0320ee036a21ef0320ee0320" - "ef036a21f00320ef0320f0036a21f10320f00320f1036a21f20320f10320f2036a21f30320f20320f3036a21f40320" - "f30320f4036a21f50320f40320f5036a21f60320f50320f6036a21f70320f60320f7036a21f80320f70320f8036a21" - "f90320f80320f9036a21fa0320f90320fa036a21fb0320fa0320fb036a21fc0320fb0320fc036a21fd0320fc0320fd" - "036a21fe0320fd0320fe036a21ff0320fe0320ff036a21800420ff032080046a2181042080042081046a2182042081" - "042082046a2183042082042083046a2184042083042084046a2185042084042085046a2186042085042086046a2187" - "042086042087046a2188042087042088046a2189042088042089046a218a04208904208a046a218b04208a04208b04" - "6a218c04208b04208c046a218d04208c04208d046a218e04208d04208e046a218f04208e04208f046a219004208f04" - "2090046a2191042090042091046a2192042091042092046a2193042092042093046a2194042093042094046a219504" - "2094042095046a2196042095042096046a2197042096042097046a2198042097042098046a2199042098042099046a" - "219a04209904209a046a219b04209a04209b046a219c04209b04209c046a219d04209c04209d046a219e04209d0420" - "9e046a219f04209e04209f046a21a004209f0420a0046a21a10420a00420a1046a21a20420a10420a2046a21a30420" - "a20420a3046a21a40420a30420a4046a21a50420a40420a5046a21a60420a50420a6046a21a70420a60420a7046a21" - "a80420a70420a8046a21a90420a80420a9046a21aa0420a90420aa046a21ab0420aa0420ab046a21ac0420ab0420ac" - "046a21ad0420ac0420ad046a21ae0420ad0420ae046a21af0420ae0420af046a21b00420af0420b0046a21b10420b0" - "0420b1046a21b20420b10420b2046a21b30420b20420b3046a21b40420b30420b4046a21b50420b40420b5046a21b6" - "0420b50420b6046a21b70420b60420b7046a21b80420b70420b8046a21b90420b80420b9046a21ba0420b90420ba04" - "6a21bb0420ba0420bb046a21bc0420bb0420bc046a21bd0420bc0420bd046a21be0420bd0420be046a21bf0420be04" - "20bf046a21c00420bf0420c0046a21c10420c00420c1046a21c20420c10420c2046a21c30420c20420c3046a21c404" - "20c30420c4046a21c50420c40420c5046a21c60420c50420c6046a21c70420c60420c7046a21c80420c70420c8046a" - "21c90420c80420c9046a21ca0420c90420ca046a21cb0420ca0420cb046a21cc0420cb0420cc046a21cd0420cc0420" - "cd046a21ce0420cd0420ce046a21cf0420ce0420cf046a21d00420cf0420d0046a21d10420d00420d1046a21d20420" - "d10420d2046a21d30420d20420d3046a21d40420d30420d4046a21d50420d40420d5046a21d60420d50420d6046a21" - "d70420d60420d7046a21d80420d70420d8046a21d90420d80420d9046a21da0420d90420da046a21db0420da0420db" - "046a21dc0420db0420dc046a21dd0420dc0420dd046a21de0420dd0420de046a21df0420de0420df046a21e00420df" - "0420e0046a21e10420e00420e1046a21e20420e10420e2046a21e30420e20420e3046a21e40420e30420e4046a21e5" - "0420e40420e5046a21e60420e50420e6046a21e70420e60420e7046a21e80420e70420e8046a21e90420e80420e904" - "6a21ea0420e90420ea046a21eb0420ea0420eb046a21ec0420eb0420ec046a21ed0420ec0420ed046a21ee0420ed04" - "20ee046a21ef0420ee0420ef046a21f00420ef0420f0046a21f10420f00420f1046a21f20420f10420f2046a21f304" - "20f20420f3046a21f40420f30420f4046a21f50420f40420f5046a21f60420f50420f6046a21f70420f60420f7046a" - "21f80420f70420f8046a21f90420f80420f9046a21fa0420f90420fa046a21fb0420fa0420fb046a21fc0420fb0420" - "fc046a21fd0420fc0420fd046a21fe0420fd0420fe046a21ff0420fe0420ff046a21800520ff042080056a21810520" - "80052081056a2182052081052082056a2183052082052083056a2184052083052084056a2185052084052085056a21" - "86052085052086056a2187052086052087056a2188052087052088056a2189052088052089056a218a05208905208a" - "056a218b05208a05208b056a218c05208b05208c056a218d05208c05208d056a218e05208d05208e056a218f05208e" - "05208f056a219005208f052090056a2191052090052091056a2192052091052092056a2193052092052093056a2194" - "052093052094056a2195052094052095056a2196052095052096056a2197052096052097056a219805209705209805" - "6a2199052098052099056a219a05209905209a056a219b05209a05209b056a219c05209b05209c056a219d05209c05" - "209d056a219e05209d05209e056a219f05209e05209f056a21a005209f0520a0056a21a10520a00520a1056a21a205" - "20a10520a2056a21a30520a20520a3056a21a40520a30520a4056a21a50520a40520a5056a21a60520a50520a6056a" - "21a70520a60520a7056a21a80520a70520a8056a21a90520a80520a9056a21aa0520a90520aa056a21ab0520aa0520" - "ab056a21ac0520ab0520ac056a21ad0520ac0520ad056a21ae0520ad0520ae056a21af0520ae0520af056a21b00520" - "af0520b0056a21b10520b00520b1056a21b20520b10520b2056a21b30520b20520b3056a21b40520b30520b4056a21" - "b50520b40520b5056a21b60520b50520b6056a21b70520b60520b7056a21b80520b70520b8056a21b90520b80520b9" - "056a21ba0520b90520ba056a21bb0520ba0520bb056a21bc0520bb0520bc056a21bd0520bc0520bd056a21be0520bd" - "0520be056a21bf0520be0520bf056a21c00520bf0520c0056a21c10520c00520c1056a21c20520c10520c2056a21c3" - "0520c20520c3056a21c40520c30520c4056a21c50520c40520c5056a21c60520c50520c6056a21c70520c60520c705" - "6a21c80520c70520c8056a21c90520c80520c9056a21ca0520c90520ca056a21cb0520ca0520cb056a21cc0520cb05" - "20cc056a21cd0520cc0520cd056a21ce0520cd0520ce056a21cf0520ce0520cf056a21d00520cf0520d0056a21d105" - "20d00520d1056a21d20520d10520d2056a21d30520d20520d3056a21d40520d30520d4056a21d50520d40520d5056a" - "21d60520d50520d6056a21d70520d60520d7056a21d80520d70520d8056a21d90520d80520d9056a21da0520d90520" - "da056a21db0520da0520db056a21dc0520db0520dc056a21dd0520dc0520dd056a21de0520dd0520de056a21df0520" - "de0520df056a21e00520df0520e0056a21e10520e00520e1056a21e20520e10520e2056a21e30520e20520e3056a21" - "e40520e30520e4056a21e50520e40520e5056a21e60520e50520e6056a21e70520e60520e7056a21e80520e70520e8" - "056a21e90520e80520e9056a21ea0520e90520ea056a21eb0520ea0520eb056a21ec0520eb0520ec056a21ed0520ec" - "0520ed056a21ee0520ed0520ee056a21ef0520ee0520ef056a21f00520ef0520f0056a21f10520f00520f1056a21f2" - "0520f10520f2056a21f30520f20520f3056a21f40520f30520f4056a21f50520f40520f5056a21f60520f50520f605" - "6a21f70520f60520f7056a21f80520f70520f8056a21f90520f80520f9056a21fa0520f90520fa056a21fb0520fa05" - "20fb056a21fc0520fb0520fc056a21fd0520fc0520fd056a21fe0520fd0520fe056a21ff0520fe0520ff056a218006" - "20ff052080066a2181062080062081066a2182062081062082066a2183062082062083066a2184062083062084066a" - "2185062084062085066a2186062085062086066a2187062086062087066a2188062087062088066a21890620880620" - "89066a218a06208906208a066a218b06208a06208b066a218c06208b06208c066a218d06208c06208d066a218e0620" - "8d06208e066a218f06208e06208f066a219006208f062090066a2191062090062091066a2192062091062092066a21" - "93062092062093066a2194062093062094066a2195062094062095066a2196062095062096066a2197062096062097" - "066a2198062097062098066a2199062098062099066a219a06209906209a066a219b06209a06209b066a219c06209b" - "06209c066a219d06209c06209d066a219e06209d06209e066a219f06209e06209f066a21a006209f0620a0066a21a1" - "0620a00620a1066a21a20620a10620a2066a21a30620a20620a3066a21a40620a30620a4066a21a50620a40620a506" - "6a21a60620a50620a6066a21a70620a60620a7066a21a80620a70620a8066a21a90620a80620a9066a21aa0620a906" - "20aa066a21ab0620aa0620ab066a21ac0620ab0620ac066a21ad0620ac0620ad066a21ae0620ad0620ae066a21af06" - "20ae0620af066a21b00620af0620b0066a21b10620b00620b1066a21b20620b10620b2066a21b30620b20620b3066a" - "21b40620b30620b4066a21b50620b40620b5066a21b60620b50620b6066a21b70620b60620b7066a21b80620b70620" - "b8066a21b90620b80620b9066a21ba0620b90620ba066a21bb0620ba0620bb066a21bc0620bb0620bc066a21bd0620" - "bc0620bd066a21be0620bd0620be066a21bf0620be0620bf066a21c00620bf0620c0066a21c10620c00620c1066a21" - "c20620c10620c2066a21c30620c20620c3066a21c40620c30620c4066a21c50620c40620c5066a21c60620c50620c6" - "066a21c70620c60620c7066a21c80620c70620c8066a21c90620c80620c9066a21ca0620c90620ca066a21cb0620ca" - "0620cb066a21cc0620cb0620cc066a21cd0620cc0620cd066a21ce0620cd0620ce066a21cf0620ce0620cf066a21d0" - "0620cf0620d0066a21d10620d00620d1066a21d20620d10620d2066a21d30620d20620d3066a21d40620d30620d406" - "6a21d50620d40620d5066a21d60620d50620d6066a21d70620d60620d7066a21d80620d70620d8066a21d90620d806" - "20d9066a21da0620d90620da066a21db0620da0620db066a21dc0620db0620dc066a21dd0620dc0620dd066a21de06" - "20dd0620de066a21df0620de0620df066a21e00620df0620e0066a21e10620e00620e1066a21e20620e10620e2066a" - "21e30620e20620e3066a21e40620e30620e4066a21e50620e40620e5066a21e60620e50620e6066a21e70620e60620" - "e7066a21e80620e70620e8066a21e90620e80620e9066a21ea0620e90620ea066a21eb0620ea0620eb066a21ec0620" - "eb0620ec066a21ed0620ec0620ed066a21ee0620ed0620ee066a21ef0620ee0620ef066a21f00620ef0620f0066a21" - "f10620f00620f1066a21f20620f10620f2066a21f30620f20620f3066a21f40620f30620f4066a21f50620f40620f5" - "066a21f60620f50620f6066a21f70620f60620f7066a21f80620f70620f8066a21f90620f80620f9066a21fa0620f9" - "0620fa066a21fb0620fa0620fb066a21fc0620fb0620fc066a21fd0620fc0620fd066a21fe0620fd0620fe066a21ff" - "0620fe0620ff066a21800720ff062080076a2181072080072081076a2182072081072082076a218307208207208307" - "6a2184072083072084076a2185072084072085076a2186072085072086076a2187072086072087076a218807208707" - "2088076a2189072088072089076a218a07208907208a076a218b07208a07208b076a218c07208b07208c076a218d07" - "208c07208d076a218e07208d07208e076a218f07208e07208f076a219007208f072090076a2191072090072091076a" - "2192072091072092076a2193072092072093076a2194072093072094076a2195072094072095076a21960720950720" - "96076a2197072096072097076a2198072097072098076a2199072098072099076a219a07209907209a076a219b0720" - "9a07209b076a219c07209b07209c076a219d07209c07209d076a219e07209d07209e076a219f07209e07209f076a21" - "a007209f0720a0076a21a10720a00720a1076a21a20720a10720a2076a21a30720a20720a3076a21a40720a30720a4" - "076a21a50720a40720a5076a21a60720a50720a6076a21a70720a60720a7076a21a80720a70720a8076a21a90720a8" - "0720a9076a21aa0720a90720aa076a21ab0720aa0720ab076a21ac0720ab0720ac076a21ad0720ac0720ad076a21ae" - "0720ad0720ae076a21af0720ae0720af076a21b00720af0720b0076a21b10720b00720b1076a21b20720b10720b207" - "6a21b30720b20720b3076a21b40720b30720b4076a21b50720b40720b5076a21b60720b50720b6076a21b70720b607" - "20b7076a21b80720b70720b8076a21b90720b80720b9076a21ba0720b90720ba076a21bb0720ba0720bb076a21bc07" - "20bb0720bc076a21bd0720bc0720bd076a21be0720bd0720be076a21bf0720be0720bf076a21c00720bf0720c0076a" - "21c10720c00720c1076a21c20720c10720c2076a21c30720c20720c3076a21c40720c30720c4076a21c50720c40720" - "c5076a21c60720c50720c6076a21c70720c60720c7076a21c80720c70720c8076a21c90720c80720c9076a21ca0720" - "c90720ca076a21cb0720ca0720cb076a21cc0720cb0720cc076a21cd0720cc0720cd076a21ce0720cd0720ce076a21" - "cf0720ce0720cf076a21d00720cf0720d0076a21d10720d00720d1076a21d20720d10720d2076a21d30720d20720d3" - "076a21d40720d30720d4076a21d50720d40720d5076a21d60720d50720d6076a21d70720d60720d7076a21d80720d7" - "0720d8076a21d90720d80720d9076a21da0720d90720da076a21db0720da0720db076a21dc0720db0720dc076a21dd" - "0720dc0720dd076a21de0720dd0720de076a21df0720de0720df076a21e00720df0720e0076a21e10720e00720e107" - "6a21e20720e10720e2076a21e30720e20720e3076a21e40720e30720e4076a21e50720e40720e5076a21e60720e507" - "20e6076a21e70720e60720e7076a21e80720e70720e8076a21e90720e80720e9076a21ea0720e90720ea076a21eb07" - "20ea0720eb076a21ec0720eb0720ec076a21ed0720ec0720ed076a21ee0720ed0720ee076a21ef0720ee0720ef076a" - "21f00720ef0720f0076a21f10720f00720f1076a21f20720f10720f2076a21f30720f20720f3076a21f40720f30720" - "f4076a21f50720f40720f5076a21f60720f50720f6076a21f70720f60720f7076a21f80720f70720f8076a21f90720" - "f80720f9076a21fa0720f90720fa076a21fb0720fa0720fb076a21fc0720fb0720fc076a21fd0720fc0720fd076a21" - "fe0720fd0720fe076a21ff0720fe0720ff076a21800820ff072080086a2181082080082081086a2182082081082082" - "086a2183082082082083086a2184082083082084086a2185082084082085086a2186082085082086086a2187082086" - "082087086a2188082087082088086a2189082088082089086a218a08208908208a086a218b08208a08208b086a218c" - "08208b08208c086a218d08208c08208d086a218e08208d08208e086a218f08208e08208f086a219008208f08209008" - "6a2191082090082091086a2192082091082092086a2193082092082093086a2194082093082094086a219508209408" - "2095086a2196082095082096086a2197082096082097086a2198082097082098086a2199082098082099086a219a08" - "209908209a086a219b08209a08209b086a219c08209b08209c086a219d08209c08209d086a219e08209d08209e086a" - "219f08209e08209f086a21a008209f0820a0086a21a10820a00820a1086a21a20820a10820a2086a21a30820a20820" - "a3086a21a40820a30820a4086a21a50820a40820a5086a21a60820a50820a6086a21a70820a60820a7086a21a80820" - "a70820a8086a21a90820a80820a9086a21aa0820a90820aa086a21ab0820aa0820ab086a21ac0820ab0820ac086a21" - "ad0820ac0820ad086a21ae0820ad0820ae086a21af0820ae0820af086a21b00820af0820b0086a21b10820b00820b1" - "086a21b20820b10820b2086a21b30820b20820b3086a21b40820b30820b4086a21b50820b40820b5086a21b60820b5" - "0820b6086a21b70820b60820b7086a21b80820b70820b8086a21b90820b80820b9086a21ba0820b90820ba086a21bb" - "0820ba0820bb086a21bc0820bb0820bc086a21bd0820bc0820bd086a21be0820bd0820be086a21bf0820be0820bf08" - "6a21c00820bf0820c0086a21c10820c00820c1086a21c20820c10820c2086a21c30820c20820c3086a21c40820c308" - "20c4086a21c50820c40820c5086a21c60820c50820c6086a21c70820c60820c7086a21c80820c70820c8086a21c908" - "20c80820c9086a21ca0820c90820ca086a21cb0820ca0820cb086a21cc0820cb0820cc086a21cd0820cc0820cd086a" - "21ce0820cd0820ce086a21cf0820ce0820cf086a21d00820cf0820d0086a21d10820d00820d1086a21d20820d10820" - "d2086a21d30820d20820d3086a21d40820d30820d4086a21d50820d40820d5086a21d60820d50820d6086a21d70820" - "d60820d7086a21d80820d70820d8086a21d90820d80820d9086a21da0820d90820da086a21db0820da0820db086a21" - "dc0820db0820dc086a21dd0820dc0820dd086a21de0820dd0820de086a21df0820de0820df086a21e00820df0820e0" - "086a21e10820e00820e1086a21e20820e10820e2086a21e30820e20820e3086a21e40820e30820e4086a21e50820e4" - "0820e5086a21e60820e50820e6086a21e70820e60820e7086a21e80820e70820e8086a21e90820e80820e9086a21ea" - "0820e90820ea086a21eb0820ea0820eb086a21ec0820eb0820ec086a21ed0820ec0820ed086a21ee0820ed0820ee08" - "6a21ef0820ee0820ef086a21f00820ef0820f0086a21f10820f00820f1086a21f20820f10820f2086a21f30820f208" - "20f3086a21f40820f30820f4086a21f50820f40820f5086a21f60820f50820f6086a21f70820f60820f7086a21f808" - "20f70820f8086a21f90820f80820f9086a21fa0820f90820fa086a21fb0820fa0820fb086a21fc0820fb0820fc086a" - "21fd0820fc0820fd086a21fe0820fd0820fe086a21ff0820fe0820ff086a21800920ff082080096a21810920800920" - "81096a2182092081092082096a2183092082092083096a2184092083092084096a2185092084092085096a21860920" - "85092086096a2187092086092087096a2188092087092088096a2189092088092089096a218a09208909208a096a21" - "8b09208a09208b096a218c09208b09208c096a218d09208c09208d096a218e09208d09208e096a218f09208e09208f" - "096a219009208f092090096a2191092090092091096a2192092091092092096a2193092092092093096a2194092093" - "092094096a2195092094092095096a2196092095092096096a2197092096092097096a2198092097092098096a2199" - "092098092099096a219a09209909209a096a219b09209a09209b096a219c09209b09209c096a219d09209c09209d09" - "6a219e09209d09209e096a219f09209e09209f096a21a009209f0920a0096a21a10920a00920a1096a21a20920a109" - "20a2096a21a30920a20920a3096a21a40920a30920a4096a21a50920a40920a5096a21a60920a50920a6096a21a709" - "20a60920a7096a21a80920a70920a8096a21a90920a80920a9096a21aa0920a90920aa096a21ab0920aa0920ab096a" - "21ac0920ab0920ac096a21ad0920ac0920ad096a21ae0920ad0920ae096a21af0920ae0920af096a21b00920af0920" - "b0096a21b10920b00920b1096a21b20920b10920b2096a21b30920b20920b3096a21b40920b30920b4096a21b50920" - "b40920b5096a21b60920b50920b6096a21b70920b60920b7096a21b80920b70920b8096a21b90920b80920b9096a21" - "ba0920b90920ba096a21bb0920ba0920bb096a21bc0920bb0920bc096a21bd0920bc0920bd096a21be0920bd0920be" - "096a21bf0920be0920bf096a21c00920bf0920c0096a21c10920c00920c1096a21c20920c10920c2096a21c30920c2" - "0920c3096a21c40920c30920c4096a21c50920c40920c5096a21c60920c50920c6096a21c70920c60920c7096a21c8" - "0920c70920c8096a21c90920c80920c9096a21ca0920c90920ca096a21cb0920ca0920cb096a21cc0920cb0920cc09" - "6a21cd0920cc0920cd096a21ce0920cd0920ce096a21cf0920ce0920cf096a21d00920cf0920d0096a21d10920d009" - "20d1096a21d20920d10920d2096a21d30920d20920d3096a21d40920d30920d4096a21d50920d40920d5096a21d609" - "20d50920d6096a21d70920d60920d7096a21d80920d70920d8096a21d90920d80920d9096a21da0920d90920da096a" - "21db0920da0920db096a21dc0920db0920dc096a21dd0920dc0920dd096a21de0920dd0920de096a21df0920de0920" - "df096a21e00920df0920e0096a21e10920e00920e1096a21e20920e10920e2096a21e30920e20920e3096a21e40920" - "e30920e4096a21e50920e40920e5096a21e60920e50920e6096a21e70920e60920e7096a21e80920e70920e8096a21" - "e90920e80920e9096a21ea0920e90920ea096a21eb0920ea0920eb096a21ec0920eb0920ec096a21ed0920ec0920ed" - "096a21ee0920ed0920ee096a21ef0920ee0920ef096a21f00920ef0920f0096a21f10920f00920f1096a21f20920f1" - "0920f2096a21f30920f20920f3096a21f40920f30920f4096a21f50920f40920f5096a21f60920f50920f6096a21f7" - "0920f60920f7096a21f80920f70920f8096a21f90920f80920f9096a21fa0920f90920fa096a21fb0920fa0920fb09" - "6a21fc0920fb0920fc096a21fd0920fc0920fd096a21fe0920fd0920fe096a21ff0920fe0920ff096a21800a20ff09" - "20800a6a21810a20800a20810a6a21820a20810a20820a6a21830a20820a20830a6a21840a20830a20840a6a21850a" - "20840a20850a6a21860a20850a20860a6a21870a20860a20870a6a21880a20870a20880a6a21890a20880a20890a6a" - "218a0a20890a208a0a6a218b0a208a0a208b0a6a218c0a208b0a208c0a6a218d0a208c0a208d0a6a218e0a208d0a20" - "8e0a6a218f0a208e0a208f0a6a21900a208f0a20900a6a21910a20900a20910a6a21920a20910a20920a6a21930a20" - "920a20930a6a21940a20930a20940a6a21950a20940a20950a6a21960a20950a20960a6a21970a20960a20970a6a21" - "980a20970a20980a6a21990a20980a20990a6a219a0a20990a209a0a6a219b0a209a0a209b0a6a219c0a209b0a209c" - "0a6a219d0a209c0a209d0a6a219e0a209d0a209e0a6a219f0a209e0a209f0a6a21a00a209f0a20a00a6a21a10a20a0" - "0a20a10a6a21a20a20a10a20a20a6a21a30a20a20a20a30a6a21a40a20a30a20a40a6a21a50a20a40a20a50a6a21a6" - "0a20a50a20a60a6a21a70a20a60a20a70a6a21a80a20a70a20a80a6a21a90a20a80a20a90a6a21aa0a20a90a20aa0a" - "6a21ab0a20aa0a20ab0a6a21ac0a20ab0a20ac0a6a21ad0a20ac0a20ad0a6a21ae0a20ad0a20ae0a6a21af0a20ae0a" - "20af0a6a21b00a20af0a20b00a6a21b10a20b00a20b10a6a21b20a20b10a20b20a6a21b30a20b20a20b30a6a21b40a" - "20b30a20b40a6a21b50a20b40a20b50a6a21b60a20b50a20b60a6a21b70a20b60a20b70a6a21b80a20b70a20b80a6a" - "21b90a20b80a20b90a6a21ba0a20b90a20ba0a6a21bb0a20ba0a20bb0a6a21bc0a20bb0a20bc0a6a21bd0a20bc0a20" - "bd0a6a21be0a20bd0a20be0a6a21bf0a20be0a20bf0a6a21c00a20bf0a20c00a6a21c10a20c00a20c10a6a21c20a20" - "c10a20c20a6a21c30a20c20a20c30a6a21c40a20c30a20c40a6a21c50a20c40a20c50a6a21c60a20c50a20c60a6a21" - "c70a20c60a20c70a6a21c80a20c70a20c80a6a21c90a20c80a20c90a6a21ca0a20c90a20ca0a6a21cb0a20ca0a20cb" - "0a6a21cc0a20cb0a20cc0a6a21cd0a20cc0a20cd0a6a21ce0a20cd0a20ce0a6a21cf0a20ce0a20cf0a6a21d00a20cf" - "0a20d00a6a21d10a20d00a20d10a6a21d20a20d10a20d20a6a21d30a20d20a20d30a6a21d40a20d30a20d40a6a21d5" - "0a20d40a20d50a6a21d60a20d50a20d60a6a21d70a20d60a20d70a6a21d80a20d70a20d80a6a21d90a20d80a20d90a" - "6a21da0a20d90a20da0a6a21db0a20da0a20db0a6a21dc0a20db0a20dc0a6a21dd0a20dc0a20dd0a6a21de0a20dd0a" - "20de0a6a21df0a20de0a20df0a6a21e00a20df0a20e00a6a21e10a20e00a20e10a6a21e20a20e10a20e20a6a21e30a" - "20e20a20e30a6a21e40a20e30a20e40a6a21e50a20e40a20e50a6a21e60a20e50a20e60a6a21e70a20e60a20e70a6a" - "21e80a20e70a20e80a6a21e90a20e80a20e90a6a21ea0a20e90a20ea0a6a21eb0a20ea0a20eb0a6a21ec0a20eb0a20" - "ec0a6a21ed0a20ec0a20ed0a6a21ee0a20ed0a20ee0a6a21ef0a20ee0a20ef0a6a21f00a20ef0a20f00a6a21f10a20" - "f00a20f10a6a21f20a20f10a20f20a6a21f30a20f20a20f30a6a21f40a20f30a20f40a6a21f50a20f40a20f50a6a21" - "f60a20f50a20f60a6a21f70a20f60a20f70a6a21f80a20f70a20f80a6a21f90a20f80a20f90a6a21fa0a20f90a20fa" - "0a6a21fb0a20fa0a20fb0a6a21fc0a20fb0a20fc0a6a21fd0a20fc0a20fd0a6a21fe0a20fd0a20fe0a6a21ff0a20fe" - "0a20ff0a6a21800b20ff0a20800b6a21810b20800b20810b6a21820b20810b20820b6a21830b20820b20830b6a2184" - "0b20830b20840b6a21850b20840b20850b6a21860b20850b20860b6a21870b20860b20870b6a21880b20870b20880b" - "6a21890b20880b20890b6a218a0b20890b208a0b6a218b0b208a0b208b0b6a218c0b208b0b208c0b6a218d0b208c0b" - "208d0b6a218e0b208d0b208e0b6a218f0b208e0b208f0b6a21900b208f0b20900b6a21910b20900b20910b6a21920b" - "20910b20920b6a21930b20920b20930b6a21940b20930b20940b6a21950b20940b20950b6a21960b20950b20960b6a" - "21970b20960b20970b6a21980b20970b20980b6a21990b20980b20990b6a219a0b20990b209a0b6a219b0b209a0b20" - "9b0b6a219c0b209b0b209c0b6a219d0b209c0b209d0b6a219e0b209d0b209e0b6a219f0b209e0b209f0b6a21a00b20" - "9f0b20a00b6a21a10b20a00b20a10b6a21a20b20a10b20a20b6a21a30b20a20b20a30b6a21a40b20a30b20a40b6a21" - "a50b20a40b20a50b6a21a60b20a50b20a60b6a21a70b20a60b20a70b6a21a80b20a70b20a80b6a21a90b20a80b20a9" - "0b6a21aa0b20a90b20aa0b6a21ab0b20aa0b20ab0b6a21ac0b20ab0b20ac0b6a21ad0b20ac0b20ad0b6a21ae0b20ad" - "0b20ae0b6a21af0b20ae0b20af0b6a21b00b20af0b20b00b6a21b10b20b00b20b10b6a21b20b20b10b20b20b6a21b3" - "0b20b20b20b30b6a21b40b20b30b20b40b6a21b50b20b40b20b50b6a21b60b20b50b20b60b6a21b70b20b60b20b70b" - "6a21b80b20b70b20b80b6a21b90b20b80b20b90b6a21ba0b20b90b20ba0b6a21bb0b20ba0b20bb0b6a21bc0b20bb0b" - "20bc0b6a21bd0b20bc0b20bd0b6a21be0b20bd0b20be0b6a21bf0b20be0b20bf0b6a21c00b20bf0b20c00b6a21c10b" - "20c00b20c10b6a21c20b20c10b20c20b6a21c30b20c20b20c30b6a21c40b20c30b20c40b6a21c50b20c40b20c50b6a" - "21c60b20c50b20c60b6a21c70b20c60b20c70b6a21c80b20c70b20c80b6a21c90b20c80b20c90b6a21ca0b20c90b20" - "ca0b6a21cb0b20ca0b20cb0b6a21cc0b20cb0b20cc0b6a21cd0b20cc0b20cd0b6a21ce0b20cd0b20ce0b6a21cf0b20" - "ce0b20cf0b6a21d00b20cf0b20d00b6a21d10b20d00b20d10b6a21d20b20d10b20d20b6a21d30b20d20b20d30b6a21" - "d40b20d30b20d40b6a21d50b20d40b20d50b6a21d60b20d50b20d60b6a21d70b20d60b20d70b6a21d80b20d70b20d8" - "0b6a21d90b20d80b20d90b6a21da0b20d90b20da0b6a21db0b20da0b20db0b6a21dc0b20db0b20dc0b6a21dd0b20dc" - "0b20dd0b6a21de0b20dd0b20de0b6a21df0b20de0b20df0b6a21e00b20df0b20e00b6a21e10b20e00b20e10b6a21e2" - "0b20e10b20e20b6a21e30b20e20b20e30b6a21e40b20e30b20e40b6a21e50b20e40b20e50b6a21e60b20e50b20e60b" - "6a21e70b20e60b20e70b6a21e80b20e70b20e80b6a21e90b20e80b20e90b6a21ea0b20e90b20ea0b6a21eb0b20ea0b" - "20eb0b6a21ec0b20eb0b20ec0b6a21ed0b20ec0b20ed0b6a21ee0b20ed0b20ee0b6a21ef0b20ee0b20ef0b6a21f00b" - "20ef0b20f00b6a21f10b20f00b20f10b6a21f20b20f10b20f20b6a21f30b20f20b20f30b6a21f40b20f30b20f40b6a" - "21f50b20f40b20f50b6a21f60b20f50b20f60b6a21f70b20f60b20f70b6a21f80b20f70b20f80b6a21f90b20f80b20" - "f90b6a21fa0b20f90b20fa0b6a21fb0b20fa0b20fb0b6a21fc0b20fb0b20fc0b6a21fd0b20fc0b20fd0b6a21fe0b20" - "fd0b20fe0b6a21ff0b20fe0b20ff0b6a21800c20ff0b20800c6a21810c20800c20810c6a21820c20810c20820c6a21" - "830c20820c20830c6a21840c20830c20840c6a21850c20840c20850c6a21860c20850c20860c6a21870c20860c2087" - "0c6a21880c20870c20880c6a21890c20880c20890c6a218a0c20890c208a0c6a218b0c208a0c208b0c6a218c0c208b" - "0c208c0c6a218d0c208c0c208d0c6a218e0c208d0c208e0c6a218f0c208e0c208f0c6a21900c208f0c20900c6a2191" - "0c20900c20910c6a21920c20910c20920c6a21930c20920c20930c6a21940c20930c20940c6a21950c20940c20950c" - "6a21960c20950c20960c6a21970c20960c20970c6a21980c20970c20980c6a21990c20980c20990c6a219a0c20990c" - "209a0c6a219b0c209a0c209b0c6a219c0c209b0c209c0c6a219d0c209c0c209d0c6a219e0c209d0c209e0c6a219f0c" - "209e0c209f0c6a21a00c209f0c20a00c6a21a10c20a00c20a10c6a21a20c20a10c20a20c6a21a30c20a20c20a30c6a" - "21a40c20a30c20a40c6a21a50c20a40c20a50c6a21a60c20a50c20a60c6a21a70c20a60c20a70c6a21a80c20a70c20" - "a80c6a21a90c20a80c20a90c6a21aa0c20a90c20aa0c6a21ab0c20aa0c20ab0c6a21ac0c20ab0c20ac0c6a21ad0c20" - "ac0c20ad0c6a21ae0c20ad0c20ae0c6a21af0c20ae0c20af0c6a21b00c20af0c20b00c6a21b10c20b00c20b10c6a21" - "b20c20b10c20b20c6a21b30c20b20c20b30c6a21b40c20b30c20b40c6a21b50c20b40c20b50c6a21b60c20b50c20b6" - "0c6a21b70c20b60c20b70c6a21b80c20b70c20b80c6a21b90c20b80c20b90c6a21ba0c20b90c20ba0c6a21bb0c20ba" - "0c20bb0c6a21bc0c20bb0c20bc0c6a21bd0c20bc0c20bd0c6a21be0c20bd0c20be0c6a21bf0c20be0c20bf0c6a21c0" - "0c20bf0c20c00c6a21c10c20c00c20c10c6a21c20c20c10c20c20c6a21c30c20c20c20c30c6a21c40c20c30c20c40c" - "6a21c50c20c40c20c50c6a21c60c20c50c20c60c6a21c70c20c60c20c70c6a21c80c20c70c20c80c6a21c90c20c80c" - "20c90c6a21ca0c20c90c20ca0c6a21cb0c20ca0c20cb0c6a21cc0c20cb0c20cc0c6a21cd0c20cc0c20cd0c6a21ce0c" - "20cd0c20ce0c6a21cf0c20ce0c20cf0c6a21d00c20cf0c20d00c6a21d10c20d00c20d10c6a21d20c20d10c20d20c6a" - "21d30c20d20c20d30c6a21d40c20d30c20d40c6a21d50c20d40c20d50c6a21d60c20d50c20d60c6a21d70c20d60c20" - "d70c6a21d80c20d70c20d80c6a21d90c20d80c20d90c6a21da0c20d90c20da0c6a21db0c20da0c20db0c6a21dc0c20" - "db0c20dc0c6a21dd0c20dc0c20dd0c6a21de0c20dd0c20de0c6a21df0c20de0c20df0c6a21e00c20df0c20e00c6a21" - "e10c20e00c20e10c6a21e20c20e10c20e20c6a21e30c20e20c20e30c6a21e40c20e30c20e40c6a21e50c20e40c20e5" - "0c6a21e60c20e50c20e60c6a21e70c20e60c20e70c6a21e80c20e70c20e80c6a21e90c20e80c20e90c6a21ea0c20e9" - "0c20ea0c6a21eb0c20ea0c20eb0c6a21ec0c20eb0c20ec0c6a21ed0c20ec0c20ed0c6a21ee0c20ed0c20ee0c6a21ef" - "0c20ee0c20ef0c6a21f00c20ef0c20f00c6a21f10c20f00c20f10c6a21f20c20f10c20f20c6a21f30c20f20c20f30c" - "6a21f40c20f30c20f40c6a21f50c20f40c20f50c6a21f60c20f50c20f60c6a21f70c20f60c20f70c6a21f80c20f70c" - "20f80c6a21f90c20f80c20f90c6a21fa0c20f90c20fa0c6a21fb0c20fa0c20fb0c6a21fc0c20fb0c20fc0c6a21fd0c" - "20fc0c20fd0c6a21fe0c20fd0c20fe0c6a21ff0c20fe0c20ff0c6a21800d20ff0c20800d6a21810d20800d20810d6a" - "21820d20810d20820d6a21830d20820d20830d6a21840d20830d20840d6a21850d20840d20850d6a21860d20850d20" - "860d6a21870d20860d20870d6a21880d20870d20880d6a21890d20880d20890d6a218a0d20890d208a0d6a218b0d20" - "8a0d208b0d6a218c0d208b0d208c0d6a218d0d208c0d208d0d6a218e0d208d0d208e0d6a218f0d208e0d208f0d6a21" - "900d208f0d20900d6a21910d20900d20910d6a21920d20910d20920d6a21930d20920d20930d6a21940d20930d2094" - "0d6a21950d20940d20950d6a21960d20950d20960d6a21970d20960d20970d6a21980d20970d20980d6a21990d2098" - "0d20990d6a219a0d20990d209a0d6a219b0d209a0d209b0d6a219c0d209b0d209c0d6a219d0d209c0d209d0d6a219e" - "0d209d0d209e0d6a219f0d209e0d209f0d6a21a00d209f0d20a00d6a21a10d20a00d20a10d6a21a20d20a10d20a20d" - "6a21a30d20a20d20a30d6a21a40d20a30d20a40d6a21a50d20a40d20a50d6a21a60d20a50d20a60d6a21a70d20a60d" - "20a70d6a21a80d20a70d20a80d6a21a90d20a80d20a90d6a21aa0d20a90d20aa0d6a21ab0d20aa0d20ab0d6a21ac0d" - "20ab0d20ac0d6a21ad0d20ac0d20ad0d6a21ae0d20ad0d20ae0d6a21af0d20ae0d20af0d6a21b00d20af0d20b00d6a" - "21b10d20b00d20b10d6a21b20d20b10d20b20d6a21b30d20b20d20b30d6a21b40d20b30d20b40d6a21b50d20b40d20" - "b50d6a21b60d20b50d20b60d6a21b70d20b60d20b70d6a21b80d20b70d20b80d6a21b90d20b80d20b90d6a21ba0d20" - "b90d20ba0d6a21bb0d20ba0d20bb0d6a21bc0d20bb0d20bc0d6a21bd0d20bc0d20bd0d6a21be0d20bd0d20be0d6a21" - "bf0d20be0d20bf0d6a21c00d20bf0d20c00d6a21c10d20c00d20c10d6a21c20d20c10d20c20d6a21c30d20c20d20c3" - "0d6a21c40d20c30d20c40d6a21c50d20c40d20c50d6a21c60d20c50d20c60d6a21c70d20c60d20c70d6a21c80d20c7" - "0d20c80d6a21c90d20c80d20c90d6a21ca0d20c90d20ca0d6a21cb0d20ca0d20cb0d6a21cc0d20cb0d20cc0d6a21cd" - "0d20cc0d20cd0d6a21ce0d20cd0d20ce0d6a21cf0d20ce0d20cf0d6a21d00d20cf0d20d00d6a21d10d20d00d20d10d" - "6a21d20d20d10d20d20d6a21d30d20d20d20d30d6a21d40d20d30d20d40d6a21d50d20d40d20d50d6a21d60d20d50d" - "20d60d6a21d70d20d60d20d70d6a21d80d20d70d20d80d6a21d90d20d80d20d90d6a21da0d20d90d20da0d6a21db0d" - "20da0d20db0d6a21dc0d20db0d20dc0d6a21dd0d20dc0d20dd0d6a21de0d20dd0d20de0d6a21df0d20de0d20df0d6a" - "21e00d20df0d20e00d6a21e10d20e00d20e10d6a21e20d20e10d20e20d6a21e30d20e20d20e30d6a21e40d20e30d20" - "e40d6a21e50d20e40d20e50d6a21e60d20e50d20e60d6a21e70d20e60d20e70d6a21e80d20e70d20e80d6a21e90d20" - "e80d20e90d6a21ea0d20e90d20ea0d6a21eb0d20ea0d20eb0d6a21ec0d20eb0d20ec0d6a21ed0d20ec0d20ed0d6a21" - "ee0d20ed0d20ee0d6a21ef0d20ee0d20ef0d6a21f00d20ef0d20f00d6a21f10d20f00d20f10d6a21f20d20f10d20f2" - "0d6a21f30d20f20d20f30d6a21f40d20f30d20f40d6a21f50d20f40d20f50d6a21f60d20f50d20f60d6a21f70d20f6" - "0d20f70d6a21f80d20f70d20f80d6a21f90d20f80d20f90d6a21fa0d20f90d20fa0d6a21fb0d20fa0d20fb0d6a21fc" - "0d20fb0d20fc0d6a21fd0d20fc0d20fd0d6a21fe0d20fd0d20fe0d6a21ff0d20fe0d20ff0d6a21800e20ff0d20800e" - "6a21810e20800e20810e6a21820e20810e20820e6a21830e20820e20830e6a21840e20830e20840e6a21850e20840e" - "20850e6a21860e20850e20860e6a21870e20860e20870e6a21880e20870e20880e6a21890e20880e20890e6a218a0e" - "20890e208a0e6a218b0e208a0e208b0e6a218c0e208b0e208c0e6a218d0e208c0e208d0e6a218e0e208d0e208e0e6a" - "218f0e208e0e208f0e6a21900e208f0e20900e6a21910e20900e20910e6a21920e20910e20920e6a21930e20920e20" - "930e6a21940e20930e20940e6a21950e20940e20950e6a21960e20950e20960e6a21970e20960e20970e6a21980e20" - "970e20980e6a21990e20980e20990e6a219a0e20990e209a0e6a219b0e209a0e209b0e6a219c0e209b0e209c0e6a21" - "9d0e209c0e209d0e6a219e0e209d0e209e0e6a219f0e209e0e209f0e6a21a00e209f0e20a00e6a21a10e20a00e20a1" - "0e6a21a20e20a10e20a20e6a21a30e20a20e20a30e6a21a40e20a30e20a40e6a21a50e20a40e20a50e6a21a60e20a5" - "0e20a60e6a21a70e20a60e20a70e6a21a80e20a70e20a80e6a21a90e20a80e20a90e6a21aa0e20a90e20aa0e6a21ab" - "0e20aa0e20ab0e6a21ac0e20ab0e20ac0e6a21ad0e20ac0e20ad0e6a21ae0e20ad0e20ae0e6a21af0e20ae0e20af0e" - "6a21b00e20af0e20b00e6a21b10e20b00e20b10e6a21b20e20b10e20b20e6a21b30e20b20e20b30e6a21b40e20b30e" - "20b40e6a21b50e20b40e20b50e6a21b60e20b50e20b60e6a21b70e20b60e20b70e6a21b80e20b70e20b80e6a21b90e" - "20b80e20b90e6a21ba0e20b90e20ba0e6a21bb0e20ba0e20bb0e6a21bc0e20bb0e20bc0e6a21bd0e20bc0e20bd0e6a" - "21be0e20bd0e20be0e6a21bf0e20be0e20bf0e6a21c00e20bf0e20c00e6a21c10e20c00e20c10e6a21c20e20c10e20" - "c20e6a21c30e20c20e20c30e6a21c40e20c30e20c40e6a21c50e20c40e20c50e6a21c60e20c50e20c60e6a21c70e20" - "c60e20c70e6a21c80e20c70e20c80e6a21c90e20c80e20c90e6a21ca0e20c90e20ca0e6a21cb0e20ca0e20cb0e6a21" - "cc0e20cb0e20cc0e6a21cd0e20cc0e20cd0e6a21ce0e20cd0e20ce0e6a21cf0e20ce0e20cf0e6a21d00e20cf0e20d0" - "0e6a21d10e20d00e20d10e6a21d20e20d10e20d20e6a21d30e20d20e20d30e6a21d40e20d30e20d40e6a21d50e20d4" - "0e20d50e6a21d60e20d50e20d60e6a21d70e20d60e20d70e6a21d80e20d70e20d80e6a21d90e20d80e20d90e6a21da" - "0e20d90e20da0e6a21db0e20da0e20db0e6a21dc0e20db0e20dc0e6a21dd0e20dc0e20dd0e6a21de0e20dd0e20de0e" - "6a21df0e20de0e20df0e6a21e00e20df0e20e00e6a21e10e20e00e20e10e6a21e20e20e10e20e20e6a21e30e20e20e" - "20e30e6a21e40e20e30e20e40e6a21e50e20e40e20e50e6a21e60e20e50e20e60e6a21e70e20e60e20e70e6a21e80e" - "20e70e20e80e6a21e90e20e80e20e90e6a21ea0e20e90e20ea0e6a21eb0e20ea0e20eb0e6a21ec0e20eb0e20ec0e6a" - "21ed0e20ec0e20ed0e6a21ee0e20ed0e20ee0e6a21ef0e20ee0e20ef0e6a21f00e20ef0e20f00e6a21f10e20f00e20" - "f10e6a21f20e20f10e20f20e6a21f30e20f20e20f30e6a21f40e20f30e20f40e6a21f50e20f40e20f50e6a21f60e20" - "f50e20f60e6a21f70e20f60e20f70e6a21f80e20f70e20f80e6a21f90e20f80e20f90e6a21fa0e20f90e20fa0e6a21" - "fb0e20fa0e20fb0e6a21fc0e20fb0e20fc0e6a21fd0e20fc0e20fd0e6a21fe0e20fd0e20fe0e6a21ff0e20fe0e20ff" - "0e6a21800f20ff0e20800f6a21810f20800f20810f6a21820f20810f20820f6a21830f20820f20830f6a21840f2083" - "0f20840f6a21850f20840f20850f6a21860f20850f20860f6a21870f20860f20870f6a21880f20870f20880f6a2189" - "0f20880f20890f6a218a0f20890f208a0f6a218b0f208a0f208b0f6a218c0f208b0f208c0f6a218d0f208c0f208d0f" - "6a218e0f208d0f208e0f6a218f0f208e0f208f0f6a21900f208f0f20900f6a21910f20900f20910f6a21920f20910f" - "20920f6a21930f20920f20930f6a21940f20930f20940f6a21950f20940f20950f6a21960f20950f20960f6a21970f" - "20960f20970f6a21980f20970f20980f6a21990f20980f20990f6a219a0f20990f209a0f6a219b0f209a0f209b0f6a" - "219c0f209b0f209c0f6a219d0f209c0f209d0f6a219e0f209d0f209e0f6a219f0f209e0f209f0f6a21a00f209f0f20" - "a00f6a21a10f20a00f20a10f6a21a20f20a10f20a20f6a21a30f20a20f20a30f6a21a40f20a30f20a40f6a21a50f20" - "a40f20a50f6a21a60f20a50f20a60f6a21a70f20a60f20a70f6a21a80f20a70f20a80f6a21a90f20a80f20a90f6a21" - "aa0f20a90f20aa0f6a21ab0f20aa0f20ab0f6a21ac0f20ab0f20ac0f6a21ad0f20ac0f20ad0f6a21ae0f20ad0f20ae" - "0f6a21af0f20ae0f20af0f6a21b00f20af0f20b00f6a21b10f20b00f20b10f6a21b20f20b10f20b20f6a21b30f20b2" - "0f20b30f6a21b40f20b30f20b40f6a21b50f20b40f20b50f6a21b60f20b50f20b60f6a21b70f20b60f20b70f6a21b8" - "0f20b70f20b80f6a21b90f20b80f20b90f6a21ba0f20b90f20ba0f6a21bb0f20ba0f20bb0f6a21bc0f20bb0f20bc0f" - "6a21bd0f20bc0f20bd0f6a21be0f20bd0f20be0f6a21bf0f20be0f20bf0f6a21c00f20bf0f20c00f6a21c10f20c00f" - "20c10f6a21c20f20c10f20c20f6a21c30f20c20f20c30f6a21c40f20c30f20c40f6a21c50f20c40f20c50f6a21c60f" - "20c50f20c60f6a21c70f20c60f20c70f6a21c80f20c70f20c80f6a21c90f20c80f20c90f6a21ca0f20c90f20ca0f6a" - "21cb0f20ca0f20cb0f6a21cc0f20cb0f20cc0f6a21cd0f20cc0f20cd0f6a21ce0f20cd0f20ce0f6a21cf0f20ce0f20" - "cf0f6a21d00f20cf0f20d00f6a21d10f20d00f20d10f6a21d20f20d10f20d20f6a21d30f20d20f20d30f6a21d40f20" - "d30f20d40f6a21d50f20d40f20d50f6a21d60f20d50f20d60f6a21d70f20d60f20d70f6a21d80f20d70f20d80f6a21" - "d90f20d80f20d90f6a21da0f20d90f20da0f6a21db0f20da0f20db0f6a21dc0f20db0f20dc0f6a21dd0f20dc0f20dd" - "0f6a21de0f20dd0f20de0f6a21df0f20de0f20df0f6a21e00f20df0f20e00f6a21e10f20e00f20e10f6a21e20f20e1" - "0f20e20f6a21e30f20e20f20e30f6a21e40f20e30f20e40f6a21e50f20e40f20e50f6a21e60f20e50f20e60f6a21e7" - "0f20e60f20e70f6a21e80f20e70f20e80f6a21e90f20e80f20e90f6a21ea0f20e90f20ea0f6a21eb0f20ea0f20eb0f" - "6a21ec0f20eb0f20ec0f6a21ed0f20ec0f20ed0f6a21ee0f20ed0f20ee0f6a21ef0f20ee0f20ef0f6a21f00f20ef0f" - "20f00f6a21f10f20f00f20f10f6a21f20f20f10f20f20f6a21f30f20f20f20f30f6a21f40f20f30f20f40f6a21f50f" - "20f40f20f50f6a21f60f20f50f20f60f6a21f70f20f60f20f70f6a21f80f20f70f20f80f6a21f90f20f80f20f90f6a" - "21fa0f20f90f20fa0f6a21fb0f20fa0f20fb0f6a21fc0f20fb0f20fc0f6a21fd0f20fc0f20fd0f6a21fe0f20fd0f20" - "fe0f6a21ff0f20fe0f20ff0f6a21801020ff0f2080106a2181102080102081106a2182102081102082106a21831020" - "82102083106a2184102083102084106a2185102084102085106a2186102085102086106a2187102086102087106a21" - "88102087102088106a2189102088102089106a218a10208910208a106a218b10208a10208b106a218c10208b10208c" - "106a218d10208c10208d106a218e10208d10208e106a218f10208e10208f106a219010208f102090106a2191102090" - "102091106a2192102091102092106a2193102092102093106a2194102093102094106a2195102094102095106a2196" - "102095102096106a2197102096102097106a2198102097102098106a2199102098102099106a219a10209910209a10" - "6a219b10209a10209b106a219c10209b10209c106a219d10209c10209d106a219e10209d10209e106a219f10209e10" - "209f106a21a010209f1020a0106a21a11020a01020a1106a21a21020a11020a2106a21a31020a21020a3106a21a410" - "20a31020a4106a21a51020a41020a5106a21a61020a51020a6106a21a71020a61020a7106a21a81020a71020a8106a" - "21a91020a81020a9106a21aa1020a91020aa106a21ab1020aa1020ab106a21ac1020ab1020ac106a21ad1020ac1020" - "ad106a21ae1020ad1020ae106a21af1020ae1020af106a21b01020af1020b0106a21b11020b01020b1106a21b21020" - "b11020b2106a21b31020b21020b3106a21b41020b31020b4106a21b51020b41020b5106a21b61020b51020b6106a21" - "b71020b61020b7106a21b81020b71020b8106a21b91020b81020b9106a21ba1020b91020ba106a21bb1020ba1020bb" - "106a21bc1020bb1020bc106a21bd1020bc1020bd106a21be1020bd1020be106a21bf1020be1020bf106a21c01020bf" - "1020c0106a21c11020c01020c1106a21c21020c11020c2106a21c31020c21020c3106a21c41020c31020c4106a21c5" - "1020c41020c5106a21c61020c51020c6106a21c71020c61020c7106a21c81020c71020c8106a21c91020c81020c910" - "6a21ca1020c91020ca106a21cb1020ca1020cb106a21cc1020cb1020cc106a21cd1020cc1020cd106a21ce1020cd10" - "20ce106a21cf1020ce1020cf106a21d01020cf1020d0106a21d11020d01020d1106a21d21020d11020d2106a21d310" - "20d21020d3106a21d41020d31020d4106a21d51020d41020d5106a21d61020d51020d6106a21d71020d61020d7106a" - "21d81020d71020d8106a21d91020d81020d9106a21da1020d91020da106a21db1020da1020db106a21dc1020db1020" - "dc106a21dd1020dc1020dd106a21de1020dd1020de106a21df1020de1020df106a21e01020df1020e0106a21e11020" - "e01020e1106a21e21020e11020e2106a21e31020e21020e3106a21e41020e31020e4106a21e51020e41020e5106a21" - "e61020e51020e6106a21e71020e61020e7106a21e81020e71020e8106a21e91020e81020e9106a21ea1020e91020ea" - "106a21eb1020ea1020eb106a21ec1020eb1020ec106a21ed1020ec1020ed106a21ee1020ed1020ee106a21ef1020ee" - "1020ef106a21f01020ef1020f0106a21f11020f01020f1106a21f21020f11020f2106a21f31020f21020f3106a21f4" - "1020f31020f4106a21f51020f41020f5106a21f61020f51020f6106a21f71020f61020f7106a21f81020f71020f810" - "6a21f91020f81020f9106a21fa1020f91020fa106a21fb1020fa1020fb106a21fc1020fb1020fc106a21fd1020fc10" - "20fd106a21fe1020fd1020fe106a21ff1020fe1020ff106a21801120ff102080116a2181112080112081116a218211" - "2081112082116a2183112082112083116a2184112083112084116a2185112084112085116a2186112085112086116a" - "2187112086112087116a2188112087112088116a2189112088112089116a218a11208911208a116a218b11208a1120" - "8b116a218c11208b11208c116a218d11208c11208d116a218e11208d11208e116a218f11208e11208f116a21901120" - "8f112090116a2191112090112091116a2192112091112092116a2193112092112093116a2194112093112094116a21" - "95112094112095116a2196112095112096116a2197112096112097116a2198112097112098116a2199112098112099" - "116a219a11209911209a116a219b11209a11209b116a219c11209b11209c116a219d11209c11209d116a219e11209d" - "11209e116a219f11209e11209f116a21a011209f1120a0116a21a11120a01120a1116a21a21120a11120a2116a21a3" - "1120a21120a3116a21a41120a31120a4116a21a51120a41120a5116a21a61120a51120a6116a21a71120a61120a711" - "6a21a81120a71120a8116a21a91120a81120a9116a21aa1120a91120aa116a21ab1120aa1120ab116a21ac1120ab11" - "20ac116a21ad1120ac1120ad116a21ae1120ad1120ae116a21af1120ae1120af116a21b01120af1120b0116a21b111" - "20b01120b1116a21b21120b11120b2116a21b31120b21120b3116a21b41120b31120b4116a21b51120b41120b5116a" - "21b61120b51120b6116a21b71120b61120b7116a21b81120b71120b8116a21b91120b81120b9116a21ba1120b91120" - "ba116a21bb1120ba1120bb116a21bc1120bb1120bc116a21bd1120bc1120bd116a21be1120bd1120be116a21bf1120" - "be1120bf116a21c01120bf1120c0116a21c11120c01120c1116a21c21120c11120c2116a21c31120c21120c3116a21" - "c41120c31120c4116a21c51120c41120c5116a21c61120c51120c6116a21c71120c61120c7116a21c81120c71120c8" - "116a21c91120c81120c9116a21ca1120c91120ca116a21cb1120ca1120cb116a21cc1120cb1120cc116a21cd1120cc" - "1120cd116a21ce1120cd1120ce116a21cf1120ce1120cf116a21d01120cf1120d0116a21d11120d01120d1116a21d2" - "1120d11120d2116a21d31120d21120d3116a21d41120d31120d4116a21d51120d41120d5116a21d61120d51120d611" - "6a21d71120d61120d7116a21d81120d71120d8116a21d91120d81120d9116a21da1120d91120da116a21db1120da11" - "20db116a21dc1120db1120dc116a21dd1120dc1120dd116a21de1120dd1120de116a21df1120de1120df116a21e011" - "20df1120e0116a21e11120e01120e1116a21e21120e11120e2116a21e31120e21120e3116a21e41120e31120e4116a" - "21e51120e41120e5116a21e61120e51120e6116a21e71120e61120e7116a21e81120e71120e8116a21e91120e81120" - "e9116a21ea1120e91120ea116a21eb1120ea1120eb116a21ec1120eb1120ec116a21ed1120ec1120ed116a21ee1120" - "ed1120ee116a21ef1120ee1120ef116a21f01120ef1120f0116a21f11120f01120f1116a21f21120f11120f2116a21" - "f31120f21120f3116a21f41120f31120f4116a21f51120f41120f5116a21f61120f51120f6116a21f71120f61120f7" - "116a21f81120f71120f8116a21f91120f81120f9116a21fa1120f91120fa116a21fb1120fa1120fb116a21fc1120fb" - "1120fc116a21fd1120fc1120fd116a21fe1120fd1120fe116a21ff1120fe1120ff116a21801220ff112080126a2181" - "122080122081126a2182122081122082126a2183122082122083126a2184122083122084126a218512208412208512" - "6a2186122085122086126a2187122086122087126a2188122087122088126a2189122088122089126a218a12208912" - "208a126a218b12208a12208b126a218c12208b12208c126a218d12208c12208d126a218e12208d12208e126a218f12" - "208e12208f126a219012208f122090126a2191122090122091126a2192122091122092126a2193122092122093126a" - "2194122093122094126a2195122094122095126a2196122095122096126a2197122096122097126a21981220971220" - "98126a2199122098122099126a219a12209912209a126a219b12209a12209b126a219c12209b12209c126a219d1220" - "9c12209d126a219e12209d12209e126a219f12209e12209f126a21a012209f1220a0126a21a11220a01220a1126a21" - "a21220a11220a2126a21a31220a21220a3126a21a41220a31220a4126a21a51220a41220a5126a21a61220a51220a6" - "126a21a71220a61220a7126a21a81220a71220a8126a21a91220a81220a9126a21aa1220a91220aa126a21ab1220aa" - "1220ab126a21ac1220ab1220ac126a21ad1220ac1220ad126a21ae1220ad1220ae126a21af1220ae1220af126a21b0" - "1220af1220b0126a21b11220b01220b1126a21b21220b11220b2126a21b31220b21220b3126a21b41220b31220b412" - "6a21b51220b41220b5126a21b61220b51220b6126a21b71220b61220b7126a21b81220b71220b8126a21b91220b812" - "20b9126a21ba1220b91220ba126a21bb1220ba1220bb126a21bc1220bb1220bc126a21bd1220bc1220bd126a21be12" - "20bd1220be126a21bf1220be1220bf126a21c01220bf1220c0126a21c11220c01220c1126a21c21220c11220c2126a" - "21c31220c21220c3126a21c41220c31220c4126a21c51220c41220c5126a21c61220c51220c6126a21c71220c61220" - "c7126a21c81220c71220c8126a21c91220c81220c9126a21ca1220c91220ca126a21cb1220ca1220cb126a21cc1220" - "cb1220cc126a21cd1220cc1220cd126a21ce1220cd1220ce126a21cf1220ce1220cf126a21d01220cf1220d0126a21" - "d11220d01220d1126a21d21220d11220d2126a21d31220d21220d3126a21d41220d31220d4126a21d51220d41220d5" - "126a21d61220d51220d6126a21d71220d61220d7126a21d81220d71220d8126a21d91220d81220d9126a21da1220d9" - "1220da126a21db1220da1220db126a21dc1220db1220dc126a21dd1220dc1220dd126a21de1220dd1220de126a21df" - "1220de1220df126a21e01220df1220e0126a21e11220e01220e1126a21e21220e11220e2126a21e31220e21220e312" - "6a21e41220e31220e4126a21e51220e41220e5126a21e61220e51220e6126a21e71220e61220e7126a21e81220e712" - "20e8126a21e91220e81220e9126a21ea1220e91220ea126a21eb1220ea1220eb126a21ec1220eb1220ec126a21ed12" - "20ec1220ed126a21ee1220ed1220ee126a21ef1220ee1220ef126a21f01220ef1220f0126a21f11220f01220f1126a" - "21f21220f11220f2126a21f31220f21220f3126a21f41220f31220f4126a21f51220f41220f5126a21f61220f51220" - "f6126a21f71220f61220f7126a21f81220f71220f8126a21f91220f81220f9126a21fa1220f91220fa126a21fb1220" - "fa1220fb126a21fc1220fb1220fc126a21fd1220fc1220fd126a21fe1220fd1220fe126a21ff1220fe1220ff126a21" - "801320ff122080136a2181132080132081136a2182132081132082136a2183132082132083136a2184132083132084" - "136a2185132084132085136a2186132085132086136a2187132086132087136a2188132087132088136a2189132088" - "132089136a218a13208913208a136a218b13208a13208b136a218c13208b13208c136a218d13208c13208d136a218e" - "13208d13208e136a218f13208e13208f136a219013208f132090136a2191132090132091136a219213209113209213" - "6a2193132092132093136a2194132093132094136a2195132094132095136a2196132095132096136a219713209613" - "2097136a2198132097132098136a2199132098132099136a219a13209913209a136a219b13209a13209b136a219c13" - "209b13209c136a219d13209c13209d136a219e13209d13209e136a219f13209e13209f136a21a013209f1320a0136a" - "21a11320a01320a1136a21a21320a11320a2136a21a31320a21320a3136a21a41320a31320a4136a21a51320a41320" - "a5136a21a61320a51320a6136a21a71320a61320a7136a21a81320a71320a8136a21a91320a81320a9136a21aa1320" - "a91320aa136a21ab1320aa1320ab136a21ac1320ab1320ac136a21ad1320ac1320ad136a21ae1320ad1320ae136a21" - "af1320ae1320af136a21b01320af1320b0136a21b11320b01320b1136a21b21320b11320b2136a21b31320b21320b3" - "136a21b41320b31320b4136a21b51320b41320b5136a21b61320b51320b6136a21b71320b61320b7136a21b81320b7" - "1320b8136a21b91320b81320b9136a21ba1320b91320ba136a21bb1320ba1320bb136a21bc1320bb1320bc136a21bd" - "1320bc1320bd136a21be1320bd1320be136a21bf1320be1320bf136a21c01320bf1320c0136a21c11320c01320c113" - "6a21c21320c11320c2136a21c31320c21320c3136a21c41320c31320c4136a21c51320c41320c5136a21c61320c513" - "20c6136a21c71320c61320c7136a21c81320c71320c8136a21c91320c81320c9136a21ca1320c91320ca136a21cb13" - "20ca1320cb136a21cc1320cb1320cc136a21cd1320cc1320cd136a21ce1320cd1320ce136a21cf1320ce1320cf136a" - "21d01320cf1320d0136a21d11320d01320d1136a21d21320d11320d2136a21d31320d21320d3136a21d41320d31320" - "d4136a21d51320d41320d5136a21d61320d51320d6136a21d71320d61320d7136a21d81320d71320d8136a21d91320" - "d81320d9136a21da1320d91320da136a21db1320da1320db136a21dc1320db1320dc136a21dd1320dc1320dd136a21" - "de1320dd1320de136a21df1320de1320df136a21e01320df1320e0136a21e11320e01320e1136a21e21320e11320e2" - "136a21e31320e21320e3136a21e41320e31320e4136a21e51320e41320e5136a21e61320e51320e6136a21e71320e6" - "1320e7136a21e81320e71320e8136a21e91320e81320e9136a21ea1320e91320ea136a21eb1320ea1320eb136a21ec" - "1320eb1320ec136a21ed1320ec1320ed136a21ee1320ed1320ee136a21ef1320ee1320ef136a21f01320ef1320f013" - "6a21f11320f01320f1136a21f21320f11320f2136a21f31320f21320f3136a21f41320f31320f4136a21f51320f413" - "20f5136a21f61320f51320f6136a21f71320f61320f7136a21f81320f71320f8136a21f91320f81320f9136a21fa13" - "20f91320fa136a21fb1320fa1320fb136a21fc1320fb1320fc136a21fd1320fc1320fd136a21fe1320fd1320fe136a" - "21ff1320fe1320ff136a21801420ff132080146a2181142080142081146a2182142081142082146a21831420821420" - "83146a2184142083142084146a2185142084142085146a2186142085142086146a2187142086142087146a21881420" - "87142088146a2189142088142089146a218a14208914208a146a218b14208a14208b146a218c14208b14208c146a21" - "8d14208c14208d146a218e14208d14208e146a218f14208e14208f146a219014208f142090146a2191142090142091" - "146a2192142091142092146a2193142092142093146a2194142093142094146a2195142094142095146a2196142095" - "142096146a2197142096142097146a2198142097142098146a2199142098142099146a219a14209914209a146a219b" - "14209a14209b146a219c14209b14209c146a219d14209c14209d146a219e14209d14209e146a219f14209e14209f14" - "6a21a014209f1420a0146a21a11420a01420a1146a21a21420a11420a2146a21a31420a21420a3146a21a41420a314" - "20a4146a21a51420a41420a5146a21a61420a51420a6146a21a71420a61420a7146a21a81420a71420a8146a21a914" - "20a81420a9146a21aa1420a91420aa146a21ab1420aa1420ab146a21ac1420ab1420ac146a21ad1420ac1420ad146a" - "21ae1420ad1420ae146a21af1420ae1420af146a21b01420af1420b0146a21b11420b01420b1146a21b21420b11420" - "b2146a21b31420b21420b3146a21b41420b31420b4146a21b51420b41420b5146a21b61420b51420b6146a21b71420" - "b61420b7146a21b81420b71420b8146a21b91420b81420b9146a21ba1420b91420ba146a21bb1420ba1420bb146a21" - "bc1420bb1420bc146a21bd1420bc1420bd146a21be1420bd1420be146a21bf1420be1420bf146a21c01420bf1420c0" - "146a21c11420c01420c1146a21c21420c11420c2146a21c31420c21420c3146a21c41420c31420c4146a21c51420c4" - "1420c5146a21c61420c51420c6146a21c71420c61420c7146a21c81420c71420c8146a21c91420c81420c9146a21ca" - "1420c91420ca146a21cb1420ca1420cb146a21cc1420cb1420cc146a21cd1420cc1420cd146a21ce1420cd1420ce14" - "6a21cf1420ce1420cf146a21d01420cf1420d0146a21d11420d01420d1146a21d21420d11420d2146a21d31420d214" - "20d3146a21d41420d31420d4146a21d51420d41420d5146a21d61420d51420d6146a21d71420d61420d7146a21d814" - "20d71420d8146a21d91420d81420d9146a21da1420d91420da146a21db1420da1420db146a21dc1420db1420dc146a" - "21dd1420dc1420dd146a21de1420dd1420de146a21df1420de1420df146a21e01420df1420e0146a21e11420e01420" - "e1146a21e21420e11420e2146a21e31420e21420e3146a21e41420e31420e4146a21e51420e41420e5146a21e61420" - "e51420e6146a21e71420e61420e7146a21e81420e71420e8146a21e91420e81420e9146a21ea1420e91420ea146a21" - "eb1420ea1420eb146a21ec1420eb1420ec146a21ed1420ec1420ed146a21ee1420ed1420ee146a21ef1420ee1420ef" - "146a21f01420ef1420f0146a21f11420f01420f1146a21f21420f11420f2146a21f31420f21420f3146a21f41420f3" - "1420f4146a21f51420f41420f5146a21f61420f51420f6146a21f71420f61420f7146a21f81420f71420f8146a21f9" - "1420f81420f9146a21fa1420f91420fa146a21fb1420fa1420fb146a21fc1420fb1420fc146a21fd1420fc1420fd14" - "6a21fe1420fd1420fe146a21ff1420fe1420ff146a21801520ff142080156a2181152080152081156a218215208115" - "2082156a2183152082152083156a2184152083152084156a2185152084152085156a2186152085152086156a218715" - "2086152087156a2188152087152088156a2189152088152089156a218a15208915208a156a218b15208a15208b156a" - "218c15208b15208c156a218d15208c15208d156a218e15208d15208e156a218f15208e15208f156a219015208f1520" - "90156a2191152090152091156a2192152091152092156a2193152092152093156a2194152093152094156a21951520" - "94152095156a2196152095152096156a2197152096152097156a2198152097152098156a2199152098152099156a21" - "9a15209915209a156a219b15209a15209b156a219c15209b15209c156a219d15209c15209d156a219e15209d15209e" - "156a219f15209e15209f156a21a015209f1520a0156a21a11520a01520a1156a21a21520a11520a2156a21a31520a2" - "1520a3156a21a41520a31520a4156a21a51520a41520a5156a21a61520a51520a6156a21a71520a61520a7156a21a8" - "1520a71520a8156a21a91520a81520a9156a21aa1520a91520aa156a21ab1520aa1520ab156a21ac1520ab1520ac15" - "6a21ad1520ac1520ad156a21ae1520ad1520ae156a21af1520ae1520af156a21b01520af1520b0156a21b11520b015" - "20b1156a21b21520b11520b2156a21b31520b21520b3156a21b41520b31520b4156a21b51520b41520b5156a21b615" - "20b51520b6156a21b71520b61520b7156a21b81520b71520b8156a21b91520b81520b9156a21ba1520b91520ba156a" - "21bb1520ba1520bb156a21bc1520bb1520bc156a21bd1520bc1520bd156a21be1520bd1520be156a21bf1520be1520" - "bf156a21c01520bf1520c0156a21c11520c01520c1156a21c21520c11520c2156a21c31520c21520c3156a21c41520" - "c31520c4156a21c51520c41520c5156a21c61520c51520c6156a21c71520c61520c7156a21c81520c71520c8156a21" - "c91520c81520c9156a21ca1520c91520ca156a21cb1520ca1520cb156a21cc1520cb1520cc156a21cd1520cc1520cd" - "156a21ce1520cd1520ce156a21cf1520ce1520cf156a21d01520cf1520d0156a21d11520d01520d1156a21d21520d1" - "1520d2156a21d31520d21520d3156a21d41520d31520d4156a21d51520d41520d5156a21d61520d51520d6156a21d7" - "1520d61520d7156a21d81520d71520d8156a21d91520d81520d9156a21da1520d91520da156a21db1520da1520db15" - "6a21dc1520db1520dc156a21dd1520dc1520dd156a21de1520dd1520de156a21df1520de1520df156a21e01520df15" - "20e0156a21e11520e01520e1156a21e21520e11520e2156a21e31520e21520e3156a21e41520e31520e4156a21e515" - "20e41520e5156a21e61520e51520e6156a21e71520e61520e7156a21e81520e71520e8156a21e91520e81520e9156a" - "21ea1520e91520ea156a21eb1520ea1520eb156a21ec1520eb1520ec156a21ed1520ec1520ed156a21ee1520ed1520" - "ee156a21ef1520ee1520ef156a21f01520ef1520f0156a21f11520f01520f1156a21f21520f11520f2156a21f31520" - "f21520f3156a21f41520f31520f4156a21f51520f41520f5156a21f61520f51520f6156a21f71520f61520f7156a21" - "f81520f71520f8156a21f91520f81520f9156a21fa1520f91520fa156a21fb1520fa1520fb156a21fc1520fb1520fc" - "156a21fd1520fc1520fd156a21fe1520fd1520fe156a21ff1520fe1520ff156a21801620ff152080166a2181162080" - "162081166a2182162081162082166a2183162082162083166a2184162083162084166a2185162084162085166a2186" - "162085162086166a2187162086162087166a2188162087162088166a2189162088162089166a218a16208916208a16" - "6a218b16208a16208b166a218c16208b16208c166a218d16208c16208d166a218e16208d16208e166a218f16208e16" - "208f166a219016208f162090166a2191162090162091166a2192162091162092166a2193162092162093166a219416" - "2093162094166a2195162094162095166a2196162095162096166a2197162096162097166a2198162097162098166a" - "2199162098162099166a219a16209916209a166a219b16209a16209b166a219c16209b16209c166a219d16209c1620" - "9d166a219e16209d16209e166a219f16209e16209f166a21a016209f1620a0166a21a11620a01620a1166a21a21620" - "a11620a2166a21a31620a21620a3166a21a41620a31620a4166a21a51620a41620a5166a21a61620a51620a6166a21" - "a71620a61620a7166a21a81620a71620a8166a21a91620a81620a9166a21aa1620a91620aa166a21ab1620aa1620ab" - "166a21ac1620ab1620ac166a21ad1620ac1620ad166a21ae1620ad1620ae166a21af1620ae1620af166a21b01620af" - "1620b0166a21b11620b01620b1166a21b21620b11620b2166a21b31620b21620b3166a21b41620b31620b4166a21b5" - "1620b41620b5166a21b61620b51620b6166a21b71620b61620b7166a21b81620b71620b8166a21b91620b81620b916" - "6a21ba1620b91620ba166a21bb1620ba1620bb166a21bc1620bb1620bc166a21bd1620bc1620bd166a21be1620bd16" - "20be166a21bf1620be1620bf166a21c01620bf1620c0166a21c11620c01620c1166a21c21620c11620c2166a21c316" - "20c21620c3166a21c41620c31620c4166a21c51620c41620c5166a21c61620c51620c6166a21c71620c61620c7166a" - "21c81620c71620c8166a21c91620c81620c9166a21ca1620c91620ca166a21cb1620ca1620cb166a21cc1620cb1620" - "cc166a21cd1620cc1620cd166a21ce1620cd1620ce166a21cf1620ce1620cf166a21d01620cf1620d0166a21d11620" - "d01620d1166a21d21620d11620d2166a21d31620d21620d3166a21d41620d31620d4166a21d51620d41620d5166a21" - "d61620d51620d6166a21d71620d61620d7166a21d81620d71620d8166a21d91620d81620d9166a21da1620d91620da" - "166a21db1620da1620db166a21dc1620db1620dc166a21dd1620dc1620dd166a21de1620dd1620de166a21df1620de" - "1620df166a21e01620df1620e0166a21e11620e01620e1166a21e21620e11620e2166a21e31620e21620e3166a21e4" - "1620e31620e4166a21e51620e41620e5166a21e61620e51620e6166a21e71620e61620e7166a21e81620e71620e816" - "6a21e91620e81620e9166a21ea1620e91620ea166a21eb1620ea1620eb166a21ec1620eb1620ec166a21ed1620ec16" - "20ed166a21ee1620ed1620ee166a21ef1620ee1620ef166a21f01620ef1620f0166a21f11620f01620f1166a21f216" - "20f11620f2166a21f31620f21620f3166a21f41620f31620f4166a21f51620f41620f5166a21f61620f51620f6166a" - "21f71620f61620f7166a21f81620f71620f8166a21f91620f81620f9166a21fa1620f91620fa166a21fb1620fa1620" - "fb166a21fc1620fb1620fc166a21fd1620fc1620fd166a21fe1620fd1620fe166a21ff1620fe1620ff166a21801720" - "ff162080176a2181172080172081176a2182172081172082176a2183172082172083176a2184172083172084176a21" - "85172084172085176a2186172085172086176a2187172086172087176a2188172087172088176a2189172088172089" - "176a218a17208917208a176a218b17208a17208b176a218c17208b17208c176a218d17208c17208d176a218e17208d" - "17208e176a218f17208e17208f176a219017208f172090176a2191172090172091176a2192172091172092176a2193" - "172092172093176a2194172093172094176a2195172094172095176a2196172095172096176a219717209617209717" - "6a2198172097172098176a2199172098172099176a219a17209917209a176a219b17209a17209b176a219c17209b17" - "209c176a219d17209c17209d176a219e17209d17209e176a219f17209e17209f176a21a017209f1720a0176a21a117" - "20a01720a1176a21a21720a11720a2176a21a31720a21720a3176a21a41720a31720a4176a21a51720a41720a5176a" - "21a61720a51720a6176a21a71720a61720a7176a21a81720a71720a8176a21a91720a81720a9176a21aa1720a91720" - "aa176a21ab1720aa1720ab176a21ac1720ab1720ac176a21ad1720ac1720ad176a21ae1720ad1720ae176a21af1720" - "ae1720af176a21b01720af1720b0176a21b11720b01720b1176a21b21720b11720b2176a21b31720b21720b3176a21" - "b41720b31720b4176a21b51720b41720b5176a21b61720b51720b6176a21b71720b61720b7176a21b81720b71720b8" - "176a21b91720b81720b9176a21ba1720b91720ba176a21bb1720ba1720bb176a21bc1720bb1720bc176a21bd1720bc" - "1720bd176a21be1720bd1720be176a21bf1720be1720bf176a21c01720bf1720c0176a21c11720c01720c1176a21c2" - "1720c11720c2176a21c31720c21720c3176a21c41720c31720c4176a21c51720c41720c5176a21c61720c51720c617" - "6a21c71720c61720c7176a21c81720c71720c8176a21c91720c81720c9176a21ca1720c91720ca176a21cb1720ca17" - "20cb176a21cc1720cb1720cc176a21cd1720cc1720cd176a21ce1720cd1720ce176a21cf1720ce1720cf176a21d017" - "20cf1720d0176a21d11720d01720d1176a21d21720d11720d2176a21d31720d21720d3176a21d41720d31720d4176a" - "21d51720d41720d5176a21d61720d51720d6176a21d71720d61720d7176a21d81720d71720d8176a21d91720d81720" - "d9176a21da1720d91720da176a21db1720da1720db176a21dc1720db1720dc176a21dd1720dc1720dd176a21de1720" - "dd1720de176a21df1720de1720df176a21e01720df1720e0176a21e11720e01720e1176a21e21720e11720e2176a21" - "e31720e21720e3176a21e41720e31720e4176a21e51720e41720e5176a21e61720e51720e6176a21e71720e61720e7" - "176a21e81720e71720e8176a21e91720e81720e9176a21ea1720e91720ea176a21eb1720ea1720eb176a21ec1720eb" - "1720ec176a21ed1720ec1720ed176a21ee1720ed1720ee176a21ef1720ee1720ef176a21f01720ef1720f0176a21f1" - "1720f01720f1176a21f21720f11720f2176a21f31720f21720f3176a21f41720f31720f4176a21f51720f41720f517" - "6a21f61720f51720f6176a21f71720f61720f7176a21f81720f71720f8176a21f91720f81720f9176a21fa1720f917" - "20fa176a21fb1720fa1720fb176a21fc1720fb1720fc176a21fd1720fc1720fd176a21fe1720fd1720fe176a21ff17" - "20fe1720ff176a21801820ff172080186a2181182080182081186a2182182081182082186a2183182082182083186a" - "2184182083182084186a2185182084182085186a2186182085182086186a2187182086182087186a21881820871820" - "88186a2189182088182089186a218a18208918208a186a218b18208a18208b186a218c18208b18208c186a218d1820" - "8c18208d186a218e18208d18208e186a218f18208e18208f186a219018208f182090186a2191182090182091186a21" - "92182091182092186a2193182092182093186a2194182093182094186a2195182094182095186a2196182095182096" - "186a2197182096182097186a2198182097182098186a2199182098182099186a219a18209918209a186a219b18209a" - "18209b186a219c18209b18209c186a219d18209c18209d186a219e18209d18209e186a219f18209e18209f186a21a0" - "18209f1820a0186a21a11820a01820a1186a21a21820a11820a2186a21a31820a21820a3186a21a41820a31820a418" - "6a21a51820a41820a5186a21a61820a51820a6186a21a71820a61820a7186a21a81820a71820a8186a21a91820a818" - "20a9186a21aa1820a91820aa186a21ab1820aa1820ab186a21ac1820ab1820ac186a21ad1820ac1820ad186a21ae18" - "20ad1820ae186a21af1820ae1820af186a21b01820af1820b0186a21b11820b01820b1186a21b21820b11820b2186a" - "21b31820b21820b3186a21b41820b31820b4186a21b51820b41820b5186a21b61820b51820b6186a21b71820b61820" - "b7186a21b81820b71820b8186a21b91820b81820b9186a21ba1820b91820ba186a21bb1820ba1820bb186a21bc1820" - "bb1820bc186a21bd1820bc1820bd186a21be1820bd1820be186a21bf1820be1820bf186a21c01820bf1820c0186a21" - "c11820c01820c1186a21c21820c11820c2186a21c31820c21820c3186a21c41820c31820c4186a21c51820c41820c5" - "186a21c61820c51820c6186a21c71820c61820c7186a21c81820c71820c8186a21c91820c81820c9186a21ca1820c9" - "1820ca186a21cb1820ca1820cb186a21cc1820cb1820cc186a21cd1820cc1820cd186a21ce1820cd1820ce186a21cf" - "1820ce1820cf186a21d01820cf1820d0186a21d11820d01820d1186a21d21820d11820d2186a21d31820d21820d318" - "6a21d41820d31820d4186a21d51820d41820d5186a21d61820d51820d6186a21d71820d61820d7186a21d81820d718" - "20d8186a21d91820d81820d9186a21da1820d91820da186a21db1820da1820db186a21dc1820db1820dc186a21dd18" - "20dc1820dd186a21de1820dd1820de186a21df1820de1820df186a21e01820df1820e0186a21e11820e01820e1186a" - "21e21820e11820e2186a21e31820e21820e3186a21e41820e31820e4186a21e51820e41820e5186a21e61820e51820" - "e6186a21e71820e61820e7186a21e81820e71820e8186a21e91820e81820e9186a21ea1820e91820ea186a21eb1820" - "ea1820eb186a21ec1820eb1820ec186a21ed1820ec1820ed186a21ee1820ed1820ee186a21ef1820ee1820ef186a21" - "f01820ef1820f0186a21f11820f01820f1186a21f21820f11820f2186a21f31820f21820f3186a21f41820f31820f4" - "186a21f51820f41820f5186a21f61820f51820f6186a21f71820f61820f7186a21f81820f71820f8186a21f91820f8" - "1820f9186a21fa1820f91820fa186a21fb1820fa1820fb186a21fc1820fb1820fc186a21fd1820fc1820fd186a21fe" - "1820fd1820fe186a21ff1820fe1820ff186a21801920ff182080196a2181192080192081196a218219208119208219" - "6a2183192082192083196a2184192083192084196a2185192084192085196a2186192085192086196a218719208619" - "2087196a2188192087192088196a2189192088192089196a218a19208919208a196a218b19208a19208b196a218c19" - "208b19208c196a218d19208c19208d196a218e19208d19208e196a218f19208e19208f196a219019208f192090196a" - "2191192090192091196a2192192091192092196a2193192092192093196a2194192093192094196a21951920941920" - "95196a2196192095192096196a2197192096192097196a2198192097192098196a2199192098192099196a219a1920" - "9919209a196a219b19209a19209b196a219c19209b19209c196a219d19209c19209d196a219e19209d19209e196a21" - "9f19209e19209f196a21a019209f1920a0196a21a11920a01920a1196a21a21920a11920a2196a21a31920a21920a3" - "196a21a41920a31920a4196a21a51920a41920a5196a21a61920a51920a6196a21a71920a61920a7196a21a81920a7" - "1920a8196a21a91920a81920a9196a21aa1920a91920aa196a21ab1920aa1920ab196a21ac1920ab1920ac196a21ad" - "1920ac1920ad196a21ae1920ad1920ae196a21af1920ae1920af196a21b01920af1920b0196a21b11920b01920b119" - "6a21b21920b11920b2196a21b31920b21920b3196a21b41920b31920b4196a21b51920b41920b5196a21b61920b519" - "20b6196a21b71920b61920b7196a21b81920b71920b8196a21b91920b81920b9196a21ba1920b91920ba196a21bb19" - "20ba1920bb196a21bc1920bb1920bc196a21bd1920bc1920bd196a21be1920bd1920be196a21bf1920be1920bf196a" - "21c01920bf1920c0196a21c11920c01920c1196a21c21920c11920c2196a21c31920c21920c3196a21c41920c31920" - "c4196a21c51920c41920c5196a21c61920c51920c6196a21c71920c61920c7196a21c81920c71920c8196a21c91920" - "c81920c9196a21ca1920c91920ca196a21cb1920ca1920cb196a21cc1920cb1920cc196a21cd1920cc1920cd196a21" - "ce1920cd1920ce196a21cf1920ce1920cf196a21d01920cf1920d0196a21d11920d01920d1196a21d21920d11920d2" - "196a21d31920d21920d3196a21d41920d31920d4196a21d51920d41920d5196a21d61920d51920d6196a21d71920d6" - "1920d7196a21d81920d71920d8196a21d91920d81920d9196a21da1920d91920da196a21db1920da1920db196a21dc" - "1920db1920dc196a21dd1920dc1920dd196a21de1920dd1920de196a21df1920de1920df196a21e01920df1920e019" - "6a21e11920e01920e1196a21e21920e11920e2196a21e31920e21920e3196a21e41920e31920e4196a21e51920e419" - "20e5196a21e61920e51920e6196a21e71920e61920e7196a21e81920e71920e8196a21e91920e81920e9196a21ea19" - "20e91920ea196a21eb1920ea1920eb196a21ec1920eb1920ec196a21ed1920ec1920ed196a21ee1920ed1920ee196a" - "21ef1920ee1920ef196a21f01920ef1920f0196a21f11920f01920f1196a21f21920f11920f2196a21f31920f21920" - "f3196a21f41920f31920f4196a21f51920f41920f5196a21f61920f51920f6196a21f71920f61920f7196a21f81920" - "f71920f8196a21f91920f81920f9196a21fa1920f91920fa196a21fb1920fa1920fb196a21fc1920fb1920fc196a21" - "fd1920fc1920fd196a21fe1920fd1920fe196a21ff1920fe1920ff196a21801a20ff1920801a6a21811a20801a2081" - "1a6a21821a20811a20821a6a21831a20821a20831a6a21841a20831a20841a6a21851a20841a20851a6a21861a2085" - "1a20861a6a21871a20861a20871a6a21881a20871a20881a6a21891a20881a20891a6a218a1a20891a208a1a6a218b" - "1a208a1a208b1a6a218c1a208b1a208c1a6a218d1a208c1a208d1a6a218e1a208d1a208e1a6a218f1a208e1a208f1a" - "6a21901a208f1a20901a6a21911a20901a20911a6a21921a20911a20921a6a21931a20921a20931a6a21941a20931a" - "20941a6a21951a20941a20951a6a21961a20951a20961a6a21971a20961a20971a6a21981a20971a20981a6a21991a" - "20981a20991a6a219a1a20991a209a1a6a219b1a209a1a209b1a6a219c1a209b1a209c1a6a219d1a209c1a209d1a6a" - "219e1a209d1a209e1a6a219f1a209e1a209f1a6a21a01a209f1a20a01a6a21a11a20a01a20a11a6a21a21a20a11a20" - "a21a6a21a31a20a21a20a31a6a21a41a20a31a20a41a6a21a51a20a41a20a51a6a21a61a20a51a20a61a6a21a71a20" - "a61a20a71a6a21a81a20a71a20a81a6a21a91a20a81a20a91a6a21aa1a20a91a20aa1a6a21ab1a20aa1a20ab1a6a21" - "ac1a20ab1a20ac1a6a21ad1a20ac1a20ad1a6a21ae1a20ad1a20ae1a6a21af1a20ae1a20af1a6a21b01a20af1a20b0" - "1a6a21b11a20b01a20b11a6a21b21a20b11a20b21a6a21b31a20b21a20b31a6a21b41a20b31a20b41a6a21b51a20b4" - "1a20b51a6a21b61a20b51a20b61a6a21b71a20b61a20b71a6a21b81a20b71a20b81a6a21b91a20b81a20b91a6a21ba" - "1a20b91a20ba1a6a21bb1a20ba1a20bb1a6a21bc1a20bb1a20bc1a6a21bd1a20bc1a20bd1a6a21be1a20bd1a20be1a" - "6a21bf1a20be1a20bf1a6a21c01a20bf1a20c01a6a21c11a20c01a20c11a6a21c21a20c11a20c21a6a21c31a20c21a" - "20c31a6a21c41a20c31a20c41a6a21c51a20c41a20c51a6a21c61a20c51a20c61a6a21c71a20c61a20c71a6a21c81a" - "20c71a20c81a6a21c91a20c81a20c91a6a21ca1a20c91a20ca1a6a21cb1a20ca1a20cb1a6a21cc1a20cb1a20cc1a6a" - "21cd1a20cc1a20cd1a6a21ce1a20cd1a20ce1a6a21cf1a20ce1a20cf1a6a21d01a20cf1a20d01a6a21d11a20d01a20" - "d11a6a21d21a20d11a20d21a6a21d31a20d21a20d31a6a21d41a20d31a20d41a6a21d51a20d41a20d51a6a21d61a20" - "d51a20d61a6a21d71a20d61a20d71a6a21d81a20d71a20d81a6a21d91a20d81a20d91a6a21da1a20d91a20da1a6a21" - "db1a20da1a20db1a6a21dc1a20db1a20dc1a6a21dd1a20dc1a20dd1a6a21de1a20dd1a20de1a6a21df1a20de1a20df" - "1a6a21e01a20df1a20e01a6a21e11a20e01a20e11a6a21e21a20e11a20e21a6a21e31a20e21a20e31a6a21e41a20e3" - "1a20e41a6a21e51a20e41a20e51a6a21e61a20e51a20e61a6a21e71a20e61a20e71a6a21e81a20e71a20e81a6a21e9" - "1a20e81a20e91a6a21ea1a20e91a20ea1a6a21eb1a20ea1a20eb1a6a21ec1a20eb1a20ec1a6a21ed1a20ec1a20ed1a" - "6a21ee1a20ed1a20ee1a6a21ef1a20ee1a20ef1a6a21f01a20ef1a20f01a6a21f11a20f01a20f11a6a21f21a20f11a" - "20f21a6a21f31a20f21a20f31a6a21f41a20f31a20f41a6a21f51a20f41a20f51a6a21f61a20f51a20f61a6a21f71a" - "20f61a20f71a6a21f81a20f71a20f81a6a21f91a20f81a20f91a6a21fa1a20f91a20fa1a6a21fb1a20fa1a20fb1a6a" - "21fc1a20fb1a20fc1a6a21fd1a20fc1a20fd1a6a21fe1a20fd1a20fe1a6a21ff1a20fe1a20ff1a6a21801b20ff1a20" - "801b6a21811b20801b20811b6a21821b20811b20821b6a21831b20821b20831b6a21841b20831b20841b6a21851b20" - "841b20851b6a21861b20851b20861b6a21871b20861b20871b6a21881b20871b20881b6a21891b20881b20891b6a21" - "8a1b20891b208a1b6a218b1b208a1b208b1b6a218c1b208b1b208c1b6a218d1b208c1b208d1b6a218e1b208d1b208e" - "1b6a218f1b208e1b208f1b6a21901b208f1b20901b6a21911b20901b20911b6a21921b20911b20921b6a21931b2092" - "1b20931b6a21941b20931b20941b6a21951b20941b20951b6a21961b20951b20961b6a21971b20961b20971b6a2198" - "1b20971b20981b6a21991b20981b20991b6a219a1b20991b209a1b6a219b1b209a1b209b1b6a219c1b209b1b209c1b" - "6a219d1b209c1b209d1b6a219e1b209d1b209e1b6a219f1b209e1b209f1b6a21a01b209f1b20a01b6a21a11b20a01b" - "20a11b6a21a21b20a11b20a21b6a21a31b20a21b20a31b6a21a41b20a31b20a41b6a21a51b20a41b20a51b6a21a61b" - "20a51b20a61b6a21a71b20a61b20a71b6a21a81b20a71b20a81b6a21a91b20a81b20a91b6a21aa1b20a91b20aa1b6a" - "21ab1b20aa1b20ab1b6a21ac1b20ab1b20ac1b6a21ad1b20ac1b20ad1b6a21ae1b20ad1b20ae1b6a21af1b20ae1b20" - "af1b6a21b01b20af1b20b01b6a21b11b20b01b20b11b6a21b21b20b11b20b21b6a21b31b20b21b20b31b6a21b41b20" - "b31b20b41b6a21b51b20b41b20b51b6a21b61b20b51b20b61b6a21b71b20b61b20b71b6a21b81b20b71b20b81b6a21" - "b91b20b81b20b91b6a21ba1b20b91b20ba1b6a21bb1b20ba1b20bb1b6a21bc1b20bb1b20bc1b6a21bd1b20bc1b20bd" - "1b6a21be1b20bd1b20be1b6a21bf1b20be1b20bf1b6a21c01b20bf1b20c01b6a21c11b20c01b20c11b6a21c21b20c1" - "1b20c21b6a21c31b20c21b20c31b6a21c41b20c31b20c41b6a21c51b20c41b20c51b6a21c61b20c51b20c61b6a21c7" - "1b20c61b20c71b6a21c81b20c71b20c81b6a21c91b20c81b20c91b6a21ca1b20c91b20ca1b6a21cb1b20ca1b20cb1b" - "6a21cc1b20cb1b20cc1b6a21cd1b20cc1b20cd1b6a21ce1b20cd1b20ce1b6a21cf1b20ce1b20cf1b6a21d01b20cf1b" - "20d01b6a21d11b20d01b20d11b6a21d21b20d11b20d21b6a21d31b20d21b20d31b6a21d41b20d31b20d41b6a21d51b" - "20d41b20d51b6a21d61b20d51b20d61b6a21d71b20d61b20d71b6a21d81b20d71b20d81b6a21d91b20d81b20d91b6a" - "21da1b20d91b20da1b6a21db1b20da1b20db1b6a21dc1b20db1b20dc1b6a21dd1b20dc1b20dd1b6a21de1b20dd1b20" - "de1b6a21df1b20de1b20df1b6a21e01b20df1b20e01b6a21e11b20e01b20e11b6a21e21b20e11b20e21b6a21e31b20" - "e21b20e31b6a21e41b20e31b20e41b6a21e51b20e41b20e51b6a21e61b20e51b20e61b6a21e71b20e61b20e71b6a21" - "e81b20e71b20e81b6a21e91b20e81b20e91b6a21ea1b20e91b20ea1b6a21eb1b20ea1b20eb1b6a21ec1b20eb1b20ec" - "1b6a21ed1b20ec1b20ed1b6a21ee1b20ed1b20ee1b6a21ef1b20ee1b20ef1b6a21f01b20ef1b20f01b6a21f11b20f0" - "1b20f11b6a21f21b20f11b20f21b6a21f31b20f21b20f31b6a21f41b20f31b20f41b6a21f51b20f41b20f51b6a21f6" - "1b20f51b20f61b6a21f71b20f61b20f71b6a21f81b20f71b20f81b6a21f91b20f81b20f91b6a21fa1b20f91b20fa1b" - "6a21fb1b20fa1b20fb1b6a21fc1b20fb1b20fc1b6a21fd1b20fc1b20fd1b6a21fe1b20fd1b20fe1b6a21ff1b20fe1b" - "20ff1b6a21801c20ff1b20801c6a21811c20801c20811c6a21821c20811c20821c6a21831c20821c20831c6a21841c" - "20831c20841c6a21851c20841c20851c6a21861c20851c20861c6a21871c20861c20871c6a21881c20871c20881c6a" - "21891c20881c20891c6a218a1c20891c208a1c6a218b1c208a1c208b1c6a218c1c208b1c208c1c6a218d1c208c1c20" - "8d1c6a218e1c208d1c208e1c6a218f1c208e1c208f1c6a21901c208f1c20901c6a21911c20901c20911c6a21921c20" - "911c20921c6a21931c20921c20931c6a21941c20931c20941c6a21951c20941c20951c6a21961c20951c20961c6a21" - "971c20961c20971c6a21981c20971c20981c6a21991c20981c20991c6a219a1c20991c209a1c6a219b1c209a1c209b" - "1c6a219c1c209b1c209c1c6a219d1c209c1c209d1c6a219e1c209d1c209e1c6a219f1c209e1c209f1c6a21a01c209f" - "1c20a01c6a21a11c20a01c20a11c6a21a21c20a11c20a21c6a21a31c20a21c20a31c6a21a41c20a31c20a41c6a21a5" - "1c20a41c20a51c6a21a61c20a51c20a61c6a21a71c20a61c20a71c6a21a81c20a71c20a81c6a21a91c20a81c20a91c" - "6a21aa1c20a91c20aa1c6a21ab1c20aa1c20ab1c6a21ac1c20ab1c20ac1c6a21ad1c20ac1c20ad1c6a21ae1c20ad1c" - "20ae1c6a21af1c20ae1c20af1c6a21b01c20af1c20b01c6a21b11c20b01c20b11c6a21b21c20b11c20b21c6a21b31c" - "20b21c20b31c6a21b41c20b31c20b41c6a21b51c20b41c20b51c6a21b61c20b51c20b61c6a21b71c20b61c20b71c6a" - "21b81c20b71c20b81c6a21b91c20b81c20b91c6a21ba1c20b91c20ba1c6a21bb1c20ba1c20bb1c6a21bc1c20bb1c20" - "bc1c6a21bd1c20bc1c20bd1c6a21be1c20bd1c20be1c6a21bf1c20be1c20bf1c6a21c01c20bf1c20c01c6a21c11c20" - "c01c20c11c6a21c21c20c11c20c21c6a21c31c20c21c20c31c6a21c41c20c31c20c41c6a21c51c20c41c20c51c6a21" - "c61c20c51c20c61c6a21c71c20c61c20c71c6a21c81c20c71c20c81c6a21c91c20c81c20c91c6a21ca1c20c91c20ca" - "1c6a21cb1c20ca1c20cb1c6a21cc1c20cb1c20cc1c6a21cd1c20cc1c20cd1c6a21ce1c20cd1c20ce1c6a21cf1c20ce" - "1c20cf1c6a21d01c20cf1c20d01c6a21d11c20d01c20d11c6a21d21c20d11c20d21c6a21d31c20d21c20d31c6a21d4" - "1c20d31c20d41c6a21d51c20d41c20d51c6a21d61c20d51c20d61c6a21d71c20d61c20d71c6a21d81c20d71c20d81c" - "6a21d91c20d81c20d91c6a21da1c20d91c20da1c6a21db1c20da1c20db1c6a21dc1c20db1c20dc1c6a21dd1c20dc1c" - "20dd1c6a21de1c20dd1c20de1c6a21df1c20de1c20df1c6a21e01c20df1c20e01c6a21e11c20e01c20e11c6a21e21c" - "20e11c20e21c6a21e31c20e21c20e31c6a21e41c20e31c20e41c6a21e51c20e41c20e51c6a21e61c20e51c20e61c6a" - "21e71c20e61c20e71c6a21e81c20e71c20e81c6a21e91c20e81c20e91c6a21ea1c20e91c20ea1c6a21eb1c20ea1c20" - "eb1c6a21ec1c20eb1c20ec1c6a21ed1c20ec1c20ed1c6a21ee1c20ed1c20ee1c6a21ef1c20ee1c20ef1c6a21f01c20" - "ef1c20f01c6a21f11c20f01c20f11c6a21f21c20f11c20f21c6a21f31c20f21c20f31c6a21f41c20f31c20f41c6a21" - "f51c20f41c20f51c6a21f61c20f51c20f61c6a21f71c20f61c20f71c6a21f81c20f71c20f81c6a21f91c20f81c20f9" - "1c6a21fa1c20f91c20fa1c6a21fb1c20fa1c20fb1c6a21fc1c20fb1c20fc1c6a21fd1c20fc1c20fd1c6a21fe1c20fd" - "1c20fe1c6a21ff1c20fe1c20ff1c6a21801d20ff1c20801d6a21811d20801d20811d6a21821d20811d20821d6a2183" - "1d20821d20831d6a21841d20831d20841d6a21851d20841d20851d6a21861d20851d20861d6a21871d20861d20871d" - "6a21881d20871d20881d6a21891d20881d20891d6a218a1d20891d208a1d6a218b1d208a1d208b1d6a218c1d208b1d" - "208c1d6a218d1d208c1d208d1d6a218e1d208d1d208e1d6a218f1d208e1d208f1d6a21901d208f1d20901d6a21911d" - "20901d20911d6a21921d20911d20921d6a21931d20921d20931d6a21941d20931d20941d6a21951d20941d20951d6a" - "21961d20951d20961d6a21971d20961d20971d6a21981d20971d20981d6a21991d20981d20991d6a219a1d20991d20" - "9a1d6a219b1d209a1d209b1d6a219c1d209b1d209c1d6a219d1d209c1d209d1d6a219e1d209d1d209e1d6a219f1d20" - "9e1d209f1d6a21a01d209f1d20a01d6a21a11d20a01d20a11d6a21a21d20a11d20a21d6a21a31d20a21d20a31d6a21" - "a41d20a31d20a41d6a21a51d20a41d20a51d6a21a61d20a51d20a61d6a21a71d20a61d20a71d6a21a81d20a71d20a8" - "1d6a21a91d20a81d20a91d6a21aa1d20a91d20aa1d6a21ab1d20aa1d20ab1d6a21ac1d20ab1d20ac1d6a21ad1d20ac" - "1d20ad1d6a21ae1d20ad1d20ae1d6a21af1d20ae1d20af1d6a21b01d20af1d20b01d6a21b11d20b01d20b11d6a21b2" - "1d20b11d20b21d6a21b31d20b21d20b31d6a21b41d20b31d20b41d6a21b51d20b41d20b51d6a21b61d20b51d20b61d" - "6a21b71d20b61d20b71d6a21b81d20b71d20b81d6a21b91d20b81d20b91d6a21ba1d20b91d20ba1d6a21bb1d20ba1d" - "20bb1d6a21bc1d20bb1d20bc1d6a21bd1d20bc1d20bd1d6a21be1d20bd1d20be1d6a21bf1d20be1d20bf1d6a21c01d" - "20bf1d20c01d6a21c11d20c01d20c11d6a21c21d20c11d20c21d6a21c31d20c21d20c31d6a21c41d20c31d20c41d6a" - "21c51d20c41d20c51d6a21c61d20c51d20c61d6a21c71d20c61d20c71d6a21c81d20c71d20c81d6a21c91d20c81d20" - "c91d6a21ca1d20c91d20ca1d6a21cb1d20ca1d20cb1d6a21cc1d20cb1d20cc1d6a21cd1d20cc1d20cd1d6a21ce1d20" - "cd1d20ce1d6a21cf1d20ce1d20cf1d6a21d01d20cf1d20d01d6a21d11d20d01d20d11d6a21d21d20d11d20d21d6a21" - "d31d20d21d20d31d6a21d41d20d31d20d41d6a21d51d20d41d20d51d6a21d61d20d51d20d61d6a21d71d20d61d20d7" - "1d6a21d81d20d71d20d81d6a21d91d20d81d20d91d6a21da1d20d91d20da1d6a21db1d20da1d20db1d6a21dc1d20db" - "1d20dc1d6a21dd1d20dc1d20dd1d6a21de1d20dd1d20de1d6a21df1d20de1d20df1d6a21e01d20df1d20e01d6a21e1" - "1d20e01d20e11d6a21e21d20e11d20e21d6a21e31d20e21d20e31d6a21e41d20e31d20e41d6a21e51d20e41d20e51d" - "6a21e61d20e51d20e61d6a21e71d20e61d20e71d6a21e81d20e71d20e81d6a21e91d20e81d20e91d6a21ea1d20e91d" - "20ea1d6a21eb1d20ea1d20eb1d6a21ec1d20eb1d20ec1d6a21ed1d20ec1d20ed1d6a21ee1d20ed1d20ee1d6a21ef1d" - "20ee1d20ef1d6a21f01d20ef1d20f01d6a21f11d20f01d20f11d6a21f21d20f11d20f21d6a21f31d20f21d20f31d6a" - "21f41d20f31d20f41d6a21f51d20f41d20f51d6a21f61d20f51d20f61d6a21f71d20f61d20f71d6a21f81d20f71d20" - "f81d6a21f91d20f81d20f91d6a21fa1d20f91d20fa1d6a21fb1d20fa1d20fb1d6a21fc1d20fb1d20fc1d6a21fd1d20" - "fc1d20fd1d6a21fe1d20fd1d20fe1d6a21ff1d20fe1d20ff1d6a21801e20ff1d20801e6a21811e20801e20811e6a21" - "821e20811e20821e6a21831e20821e20831e6a21841e20831e20841e6a21851e20841e20851e6a21861e20851e2086" - "1e6a21871e20861e20871e6a21881e20871e20881e6a21891e20881e20891e6a218a1e20891e208a1e6a218b1e208a" - "1e208b1e6a218c1e208b1e208c1e6a218d1e208c1e208d1e6a218e1e208d1e208e1e6a218f1e208e1e208f1e6a2190" - "1e208f1e20901e6a21911e20901e20911e6a21921e20911e20921e6a21931e20921e20931e6a21941e20931e20941e" - "6a21951e20941e20951e6a21961e20951e20961e6a21971e20961e20971e6a21981e20971e20981e6a21991e20981e" - "20991e6a219a1e20991e209a1e6a219b1e209a1e209b1e6a219c1e209b1e209c1e6a219d1e209c1e209d1e6a219e1e" - "209d1e209e1e6a219f1e209e1e209f1e6a21a01e209f1e20a01e6a21a11e20a01e20a11e6a21a21e20a11e20a21e6a" - "21a31e20a21e20a31e6a21a41e20a31e20a41e6a21a51e20a41e20a51e6a21a61e20a51e20a61e6a21a71e20a61e20" - "a71e6a21a81e20a71e20a81e6a21a91e20a81e20a91e6a21aa1e20a91e20aa1e6a21ab1e20aa1e20ab1e6a21ac1e20" - "ab1e20ac1e6a21ad1e20ac1e20ad1e6a21ae1e20ad1e20ae1e6a21af1e20ae1e20af1e6a21b01e20af1e20b01e6a21" - "b11e20b01e20b11e6a21b21e20b11e20b21e6a21b31e20b21e20b31e6a21b41e20b31e20b41e6a21b51e20b41e20b5" - "1e6a21b61e20b51e20b61e6a21b71e20b61e20b71e6a21b81e20b71e20b81e6a21b91e20b81e20b91e6a21ba1e20b9" - "1e20ba1e6a21bb1e20ba1e20bb1e6a21bc1e20bb1e20bc1e6a21bd1e20bc1e20bd1e6a21be1e20bd1e20be1e6a21bf" - "1e20be1e20bf1e6a21c01e20bf1e20c01e6a21c11e20c01e20c11e6a21c21e20c11e20c21e6a21c31e20c21e20c31e" - "6a21c41e20c31e20c41e6a21c51e20c41e20c51e6a21c61e20c51e20c61e6a21c71e20c61e20c71e6a21c81e20c71e" - "20c81e6a21c91e20c81e20c91e6a21ca1e20c91e20ca1e6a21cb1e20ca1e20cb1e6a21cc1e20cb1e20cc1e6a21cd1e" - "20cc1e20cd1e6a21ce1e20cd1e20ce1e6a21cf1e20ce1e20cf1e6a21d01e20cf1e20d01e6a21d11e20d01e20d11e6a" - "21d21e20d11e20d21e6a21d31e20d21e20d31e6a21d41e20d31e20d41e6a21d51e20d41e20d51e6a21d61e20d51e20" - "d61e6a21d71e20d61e20d71e6a21d81e20d71e20d81e6a21d91e20d81e20d91e6a21da1e20d91e20da1e6a21db1e20" - "da1e20db1e6a21dc1e20db1e20dc1e6a21dd1e20dc1e20dd1e6a21de1e20dd1e20de1e6a21df1e20de1e20df1e6a21" - "e01e20df1e20e01e6a21e11e20e01e20e11e6a21e21e20e11e20e21e6a21e31e20e21e20e31e6a21e41e20e31e20e4" - "1e6a21e51e20e41e20e51e6a21e61e20e51e20e61e6a21e71e20e61e20e71e6a21e81e20e71e20e81e6a21e91e20e8" - "1e20e91e6a21ea1e20e91e20ea1e6a21eb1e20ea1e20eb1e6a21ec1e20eb1e20ec1e6a21ed1e20ec1e20ed1e6a21ee" - "1e20ed1e20ee1e6a21ef1e20ee1e20ef1e6a21f01e20ef1e20f01e6a21f11e20f01e20f11e6a21f21e20f11e20f21e" - "6a21f31e20f21e20f31e6a21f41e20f31e20f41e6a21f51e20f41e20f51e6a21f61e20f51e20f61e6a21f71e20f61e" - "20f71e6a21f81e20f71e20f81e6a21f91e20f81e20f91e6a21fa1e20f91e20fa1e6a21fb1e20fa1e20fb1e6a21fc1e" - "20fb1e20fc1e6a21fd1e20fc1e20fd1e6a21fe1e20fd1e20fe1e6a21ff1e20fe1e20ff1e6a21801f20ff1e20801f6a" - "21811f20801f20811f6a21821f20811f20821f6a21831f20821f20831f6a21841f20831f20841f6a21851f20841f20" - "851f6a21861f20851f20861f6a21871f20861f20871f6a21881f20871f20881f6a21891f20881f20891f6a218a1f20" - "891f208a1f6a218b1f208a1f208b1f6a218c1f208b1f208c1f6a218d1f208c1f208d1f6a218e1f208d1f208e1f6a21" - "8f1f208e1f208f1f6a21901f208f1f20901f6a21911f20901f20911f6a21921f20911f20921f6a21931f20921f2093" - "1f6a21941f20931f20941f6a21951f20941f20951f6a21961f20951f20961f6a21971f20961f20971f6a21981f2097" - "1f20981f6a21991f20981f20991f6a219a1f20991f209a1f6a219b1f209a1f209b1f6a219c1f209b1f209c1f6a219d" - "1f209c1f209d1f6a219e1f209d1f209e1f6a219f1f209e1f209f1f6a21a01f209f1f20a01f6a21a11f20a01f20a11f" - "6a21a21f20a11f20a21f6a21a31f20a21f20a31f6a21a41f20a31f20a41f6a21a51f20a41f20a51f6a21a61f20a51f" - "20a61f6a21a71f20a61f20a71f6a21a81f20a71f20a81f6a21a91f20a81f20a91f6a21aa1f20a91f20aa1f6a21ab1f" - "20aa1f20ab1f6a21ac1f20ab1f20ac1f6a21ad1f20ac1f20ad1f6a21ae1f20ad1f20ae1f6a21af1f20ae1f20af1f6a" - "21b01f20af1f20b01f6a21b11f20b01f20b11f6a21b21f20b11f20b21f6a21b31f20b21f20b31f6a21b41f20b31f20" - "b41f6a21b51f20b41f20b51f6a21b61f20b51f20b61f6a21b71f20b61f20b71f6a21b81f20b71f20b81f6a21b91f20" - "b81f20b91f6a21ba1f20b91f20ba1f6a21bb1f20ba1f20bb1f6a21bc1f20bb1f20bc1f6a21bd1f20bc1f20bd1f6a21" - "be1f20bd1f20be1f6a21bf1f20be1f20bf1f6a21c01f20bf1f20c01f6a21c11f20c01f20c11f6a21c21f20c11f20c2" - "1f6a21c31f20c21f20c31f6a21c41f20c31f20c41f6a21c51f20c41f20c51f6a21c61f20c51f20c61f6a21c71f20c6" - "1f20c71f6a21c81f20c71f20c81f6a21c91f20c81f20c91f6a21ca1f20c91f20ca1f6a21cb1f20ca1f20cb1f6a21cc" - "1f20cb1f20cc1f6a21cd1f20cc1f20cd1f6a21ce1f20cd1f20ce1f6a21cf1f20ce1f20cf1f6a21d01f20cf1f20d01f" - "6a21d11f20d01f20d11f6a21d21f20d11f20d21f6a21d31f20d21f20d31f6a21d41f20d31f20d41f6a21d51f20d41f" - "20d51f6a21d61f20d51f20d61f6a21d71f20d61f20d71f6a21d81f20d71f20d81f6a21d91f20d81f20d91f6a21da1f" - "20d91f20da1f6a21db1f20da1f20db1f6a21dc1f20db1f20dc1f6a21dd1f20dc1f20dd1f6a21de1f20dd1f20de1f6a" - "21df1f20de1f20df1f6a21e01f20df1f20e01f6a21e11f20e01f20e11f6a21e21f20e11f20e21f6a21e31f20e21f20" - "e31f6a21e41f20e31f20e41f6a21e51f20e41f20e51f6a21e61f20e51f20e61f6a21e71f20e61f20e71f6a21e81f20" - "e71f20e81f6a21e91f20e81f20e91f6a21ea1f20e91f20ea1f6a21eb1f20ea1f20eb1f6a21ec1f20eb1f20ec1f6a21" - "ed1f20ec1f20ed1f6a21ee1f20ed1f20ee1f6a21ef1f20ee1f20ef1f6a21f01f20ef1f20f01f6a21f11f20f01f20f1" - "1f6a21f21f20f11f20f21f6a21f31f20f21f20f31f6a21f41f20f31f20f41f6a21f51f20f41f20f51f6a21f61f20f5" - "1f20f61f6a21f71f20f61f20f71f6a21f81f20f71f20f81f6a21f91f20f81f20f91f6a21fa1f20f91f20fa1f6a21fb" - "1f20fa1f20fb1f6a21fc1f20fb1f20fc1f6a21fd1f20fc1f20fd1f6a21fe1f20fd1f20fe1f6a21ff1f20fe1f20ff1f" - "6a21802020ff1f2080206a2181202080202081206a2182202081202082206a2183202082202083206a218420208320" - "2084206a2185202084202085206a2186202085202086206a2187202086202087206a2188202087202088206a218920" - "2088202089206a218a20208920208a206a218b20208a20208b206a218c20208b20208c206a218d20208c20208d206a" - "218e20208d20208e206a218f20208e20208f206a219020208f202090206a2191202090202091206a21922020912020" - "92206a2193202092202093206a2194202093202094206a2195202094202095206a2196202095202096206a21972020" - "96202097206a2198202097202098206a2199202098202099206a219a20209920209a206a219b20209a20209b206a21" - "9c20209b20209c206a219d20209c20209d206a219e20209d20209e206a219f20209e20209f206a21a020209f2020a0" - "206a21a12020a02020a1206a21a22020a12020a2206a21a32020a22020a3206a21a42020a32020a4206a21a52020a4" - "2020a5206a21a62020a52020a6206a21a72020a62020a7206a21a82020a72020a8206a21a92020a82020a9206a21aa" - "2020a92020aa206a21ab2020aa2020ab206a21ac2020ab2020ac206a21ad2020ac2020ad206a21ae2020ad2020ae20" - "6a21af2020ae2020af206a21b02020af2020b0206a21b12020b02020b1206a21b22020b12020b2206a21b32020b220" - "20b3206a21b42020b32020b4206a21b52020b42020b5206a21b62020b52020b6206a21b72020b62020b7206a21b820" - "20b72020b8206a21b92020b82020b9206a21ba2020b92020ba206a21bb2020ba2020bb206a21bc2020bb2020bc206a" - "21bd2020bc2020bd206a21be2020bd2020be206a21bf2020be2020bf206a21c02020bf2020c0206a21c12020c02020" - "c1206a21c22020c12020c2206a21c32020c22020c3206a21c42020c32020c4206a21c52020c42020c5206a21c62020" - "c52020c6206a21c72020c62020c7206a21c82020c72020c8206a21c92020c82020c9206a21ca2020c92020ca206a21" - "cb2020ca2020cb206a21cc2020cb2020cc206a21cd2020cc2020cd206a21ce2020cd2020ce206a21cf2020ce2020cf" - "206a21d02020cf2020d0206a21d12020d02020d1206a21d22020d12020d2206a21d32020d22020d3206a21d42020d3" - "2020d4206a21d52020d42020d5206a21d62020d52020d6206a21d72020d62020d7206a21d82020d72020d8206a21d9" - "2020d82020d9206a21da2020d92020da206a21db2020da2020db206a21dc2020db2020dc206a21dd2020dc2020dd20" - "6a21de2020dd2020de206a21df2020de2020df206a21e02020df2020e0206a21e12020e02020e1206a21e22020e120" - "20e2206a21e32020e22020e3206a21e42020e32020e4206a21e52020e42020e5206a21e62020e52020e6206a21e720" - "20e62020e7206a21e82020e72020e8206a21e92020e82020e9206a21ea2020e92020ea206a21eb2020ea2020eb206a" - "21ec2020eb2020ec206a21ed2020ec2020ed206a21ee2020ed2020ee206a21ef2020ee2020ef206a21f02020ef2020" - "f0206a21f12020f02020f1206a21f22020f12020f2206a21f32020f22020f3206a21f42020f32020f4206a21f52020" - "f42020f5206a21f62020f52020f6206a21f72020f62020f7206a21f82020f72020f8206a21f92020f82020f9206a21" - "fa2020f92020fa206a21fb2020fa2020fb206a21fc2020fb2020fc206a21fd2020fc2020fd206a21fe2020fd2020fe" - "206a21ff2020fe2020ff206a21802120ff202080216a2181212080212081216a2182212081212082216a2183212082" - "212083216a2184212083212084216a2185212084212085216a2186212085212086216a2187212086212087216a2188" - "212087212088216a2189212088212089216a218a21208921208a216a218b21208a21208b216a218c21208b21208c21" - "6a218d21208c21208d216a218e21208d21208e216a218f21208e21208f216a219021208f212090216a219121209021" - "2091216a2192212091212092216a2193212092212093216a2194212093212094216a2195212094212095216a219621" - "2095212096216a2197212096212097216a2198212097212098216a2199212098212099216a219a21209921209a216a" - "219b21209a21209b216a219c21209b21209c216a219d21209c21209d216a219e21209d21209e216a219f21209e2120" - "9f216a21a021209f2120a0216a21a12120a02120a1216a21a22120a12120a2216a21a32120a22120a3216a21a42120" - "a32120a4216a21a52120a42120a5216a21a62120a52120a6216a21a72120a62120a7216a21a82120a72120a8216a21" - "a92120a82120a9216a21aa2120a92120aa216a21ab2120aa2120ab216a21ac2120ab2120ac216a21ad2120ac2120ad" - "216a21ae2120ad2120ae216a21af2120ae2120af216a21b02120af2120b0216a21b12120b02120b1216a21b22120b1" - "2120b2216a21b32120b22120b3216a21b42120b32120b4216a21b52120b42120b5216a21b62120b52120b6216a21b7" - "2120b62120b7216a21b82120b72120b8216a21b92120b82120b9216a21ba2120b92120ba216a21bb2120ba2120bb21" - "6a21bc2120bb2120bc216a21bd2120bc2120bd216a21be2120bd2120be216a21bf2120be2120bf216a21c02120bf21" - "20c0216a21c12120c02120c1216a21c22120c12120c2216a21c32120c22120c3216a21c42120c32120c4216a21c521" - "20c42120c5216a21c62120c52120c6216a21c72120c62120c7216a21c82120c72120c8216a21c92120c82120c9216a" - "21ca2120c92120ca216a21cb2120ca2120cb216a21cc2120cb2120cc216a21cd2120cc2120cd216a21ce2120cd2120" - "ce216a21cf2120ce2120cf216a21d02120cf2120d0216a21d12120d02120d1216a21d22120d12120d2216a21d32120" - "d22120d3216a21d42120d32120d4216a21d52120d42120d5216a21d62120d52120d6216a21d72120d62120d7216a21" - "d82120d72120d8216a21d92120d82120d9216a21da2120d92120da216a21db2120da2120db216a21dc2120db2120dc" - "216a21dd2120dc2120dd216a21de2120dd2120de216a21df2120de2120df216a21e02120df2120e0216a21e12120e0" - "2120e1216a21e22120e12120e2216a21e32120e22120e3216a21e42120e32120e4216a21e52120e42120e5216a21e6" - "2120e52120e6216a21e72120e62120e7216a21e82120e72120e8216a21e92120e82120e9216a21ea2120e92120ea21" - "6a21eb2120ea2120eb216a21ec2120eb2120ec216a21ed2120ec2120ed216a21ee2120ed2120ee216a21ef2120ee21" - "20ef216a21f02120ef2120f0216a21f12120f02120f1216a21f22120f12120f2216a21f32120f22120f3216a21f421" - "20f32120f4216a21f52120f42120f5216a21f62120f52120f6216a21f72120f62120f7216a21f82120f72120f8216a" - "21f92120f82120f9216a21fa2120f92120fa216a21fb2120fa2120fb216a21fc2120fb2120fc216a21fd2120fc2120" - "fd216a21fe2120fd2120fe216a21ff2120fe2120ff216a21802220ff212080226a2181222080222081226a21822220" - "81222082226a2183222082222083226a2184222083222084226a2185222084222085226a2186222085222086226a21" - "87222086222087226a2188222087222088226a2189222088222089226a218a22208922208a226a218b22208a22208b" - "226a218c22208b22208c226a218d22208c22208d226a218e22208d22208e226a218f22208e22208f226a219022208f" - "222090226a2191222090222091226a2192222091222092226a2193222092222093226a2194222093222094226a2195" - "222094222095226a2196222095222096226a2197222096222097226a2198222097222098226a219922209822209922" - "6a219a22209922209a226a219b22209a22209b226a219c22209b22209c226a219d22209c22209d226a219e22209d22" - "209e226a219f22209e22209f226a21a022209f2220a0226a21a12220a02220a1226a21a22220a12220a2226a21a322" - "20a22220a3226a21a42220a32220a4226a21a52220a42220a5226a21a62220a52220a6226a21a72220a62220a7226a" - "21a82220a72220a8226a21a92220a82220a9226a21aa2220a92220aa226a21ab2220aa2220ab226a21ac2220ab2220" - "ac226a21ad2220ac2220ad226a21ae2220ad2220ae226a21af2220ae2220af226a21b02220af2220b0226a21b12220" - "b02220b1226a21b22220b12220b2226a21b32220b22220b3226a21b42220b32220b4226a21b52220b42220b5226a21" - "b62220b52220b6226a21b72220b62220b7226a21b82220b72220b8226a21b92220b82220b9226a21ba2220b92220ba" - "226a21bb2220ba2220bb226a21bc2220bb2220bc226a21bd2220bc2220bd226a21be2220bd2220be226a21bf2220be" - "2220bf226a21c02220bf2220c0226a21c12220c02220c1226a21c22220c12220c2226a21c32220c22220c3226a21c4" - "2220c32220c4226a21c52220c42220c5226a21c62220c52220c6226a21c72220c62220c7226a21c82220c72220c822" - "6a21c92220c82220c9226a21ca2220c92220ca226a21cb2220ca2220cb226a21cc2220cb2220cc226a21cd2220cc22" - "20cd226a21ce2220cd2220ce226a21cf2220ce2220cf226a21d02220cf2220d0226a21d12220d02220d1226a21d222" - "20d12220d2226a21d32220d22220d3226a21d42220d32220d4226a21d52220d42220d5226a21d62220d52220d6226a" - "21d72220d62220d7226a21d82220d72220d8226a21d92220d82220d9226a21da2220d92220da226a21db2220da2220" - "db226a21dc2220db2220dc226a21dd2220dc2220dd226a21de2220dd2220de226a21df2220de2220df226a21e02220" - "df2220e0226a21e12220e02220e1226a21e22220e12220e2226a21e32220e22220e3226a21e42220e32220e4226a21" - "e52220e42220e5226a21e62220e52220e6226a21e72220e62220e7226a21e82220e72220e8226a21e92220e82220e9" - "226a21ea2220e92220ea226a21eb2220ea2220eb226a21ec2220eb2220ec226a21ed2220ec2220ed226a21ee2220ed" - "2220ee226a21ef2220ee2220ef226a21f02220ef2220f0226a21f12220f02220f1226a21f22220f12220f2226a21f3" - "2220f22220f3226a21f42220f32220f4226a21f52220f42220f5226a21f62220f52220f6226a21f72220f62220f722" - "6a21f82220f72220f8226a21f92220f82220f9226a21fa2220f92220fa226a21fb2220fa2220fb226a21fc2220fb22" - "20fc226a21fd2220fc2220fd226a21fe2220fd2220fe226a21ff2220fe2220ff226a21802320ff222080236a218123" - "2080232081236a2182232081232082236a2183232082232083236a2184232083232084236a2185232084232085236a" - "2186232085232086236a2187232086232087236a2188232087232088236a2189232088232089236a218a2320892320" - "8a236a218b23208a23208b236a218c23208b23208c236a218d23208c23208d236a218e23208d23208e236a218f2320" - "8e23208f236a219023208f232090236a2191232090232091236a2192232091232092236a2193232092232093236a21" - "94232093232094236a2195232094232095236a2196232095232096236a2197232096232097236a2198232097232098" - "236a2199232098232099236a219a23209923209a236a219b23209a23209b236a219c23209b23209c236a219d23209c" - "23209d236a219e23209d23209e236a219f23209e23209f236a21a023209f2320a0236a21a12320a02320a1236a21a2" - "2320a12320a2236a21a32320a22320a3236a21a42320a32320a4236a21a52320a42320a5236a21a62320a52320a623" - "6a21a72320a62320a7236a21a82320a72320a8236a21a92320a82320a9236a21aa2320a92320aa236a21ab2320aa23" - "20ab236a21ac2320ab2320ac236a21ad2320ac2320ad236a21ae2320ad2320ae236a21af2320ae2320af236a21b023" - "20af2320b0236a21b12320b02320b1236a21b22320b12320b2236a21b32320b22320b3236a21b42320b32320b4236a" - "21b52320b42320b5236a21b62320b52320b6236a21b72320b62320b7236a21b82320b72320b8236a21b92320b82320" - "b9236a21ba2320b92320ba236a21bb2320ba2320bb236a21bc2320bb2320bc236a21bd2320bc2320bd236a21be2320" - "bd2320be236a21bf2320be2320bf236a21c02320bf2320c0236a21c12320c02320c1236a21c22320c12320c2236a21" - "c32320c22320c3236a21c42320c32320c4236a21c52320c42320c5236a21c62320c52320c6236a21c72320c62320c7" - "236a21c82320c72320c8236a21c92320c82320c9236a21ca2320c92320ca236a21cb2320ca2320cb236a21cc2320cb" - "2320cc236a21cd2320cc2320cd236a21ce2320cd2320ce236a21cf2320ce2320cf236a21d02320cf2320d0236a21d1" - "2320d02320d1236a21d22320d12320d2236a21d32320d22320d3236a21d42320d32320d4236a21d52320d42320d523" - "6a21d62320d52320d6236a21d72320d62320d7236a21d82320d72320d8236a21d92320d82320d9236a21da2320d923" - "20da236a21db2320da2320db236a21dc2320db2320dc236a21dd2320dc2320dd236a21de2320dd2320de236a21df23" - "20de2320df236a21e02320df2320e0236a21e12320e02320e1236a21e22320e12320e2236a21e32320e22320e3236a" - "21e42320e32320e4236a21e52320e42320e5236a21e62320e52320e6236a21e72320e62320e7236a21e82320e72320" - "e8236a21e92320e82320e9236a21ea2320e92320ea236a21eb2320ea2320eb236a21ec2320eb2320ec236a21ed2320" - "ec2320ed236a21ee2320ed2320ee236a21ef2320ee2320ef236a21f02320ef2320f0236a21f12320f02320f1236a21" - "f22320f12320f2236a21f32320f22320f3236a21f42320f32320f4236a21f52320f42320f5236a21f62320f52320f6" - "236a21f72320f62320f7236a21f82320f72320f8236a21f92320f82320f9236a21fa2320f92320fa236a21fb2320fa" - "2320fb236a21fc2320fb2320fc236a21fd2320fc2320fd236a21fe2320fd2320fe236a21ff2320fe2320ff236a2180" - "2420ff232080246a2181242080242081246a2182242081242082246a2183242082242083246a218424208324208424" - "6a2185242084242085246a2186242085242086246a2187242086242087246a2188242087242088246a218924208824" - "2089246a218a24208924208a246a218b24208a24208b246a218c24208b24208c246a218d24208c24208d246a218e24" - "208d24208e246a218f24208e24208f246a219024208f242090246a2191242090242091246a2192242091242092246a" - "2193242092242093246a2194242093242094246a2195242094242095246a2196242095242096246a21972420962420" - "97246a2198242097242098246a2199242098242099246a219a24209924209a246a219b24209a24209b246a219c2420" - "9b24209c246a219d24209c24209d246a219e24209d24209e246a219f24209e24209f246a21a024209f2420a0246a21" - "a12420a02420a1246a21a22420a12420a2246a21a32420a22420a3246a21a42420a32420a4246a21a52420a42420a5" - "246a21a62420a52420a6246a21a72420a62420a7246a21a82420a72420a8246a21a92420a82420a9246a21aa2420a9" - "2420aa246a21ab2420aa2420ab246a21ac2420ab2420ac246a21ad2420ac2420ad246a21ae2420ad2420ae246a21af" - "2420ae2420af246a21b02420af2420b0246a21b12420b02420b1246a21b22420b12420b2246a21b32420b22420b324" - "6a21b42420b32420b4246a21b52420b42420b5246a21b62420b52420b6246a21b72420b62420b7246a21b82420b724" - "20b8246a21b92420b82420b9246a21ba2420b92420ba246a21bb2420ba2420bb246a21bc2420bb2420bc246a21bd24" - "20bc2420bd246a21be2420bd2420be246a21bf2420be2420bf246a21c02420bf2420c0246a21c12420c02420c1246a" - "21c22420c12420c2246a21c32420c22420c3246a21c42420c32420c4246a21c52420c42420c5246a21c62420c52420" - "c6246a21c72420c62420c7246a21c82420c72420c8246a21c92420c82420c9246a21ca2420c92420ca246a21cb2420" - "ca2420cb246a21cc2420cb2420cc246a21cd2420cc2420cd246a21ce2420cd2420ce246a21cf2420ce2420cf246a21" - "d02420cf2420d0246a21d12420d02420d1246a21d22420d12420d2246a21d32420d22420d3246a21d42420d32420d4" - "246a21d52420d42420d5246a21d62420d52420d6246a21d72420d62420d7246a21d82420d72420d8246a21d92420d8" - "2420d9246a21da2420d92420da246a21db2420da2420db246a21dc2420db2420dc246a21dd2420dc2420dd246a21de" - "2420dd2420de246a21df2420de2420df246a21e02420df2420e0246a21e12420e02420e1246a21e22420e12420e224" - "6a21e32420e22420e3246a21e42420e32420e4246a21e52420e42420e5246a21e62420e52420e6246a21e72420e624" - "20e7246a21e82420e72420e8246a21e92420e82420e9246a21ea2420e92420ea246a21eb2420ea2420eb246a21ec24" - "20eb2420ec246a21ed2420ec2420ed246a21ee2420ed2420ee246a21ef2420ee2420ef246a21f02420ef2420f0246a" - "21f12420f02420f1246a21f22420f12420f2246a21f32420f22420f3246a21f42420f32420f4246a21f52420f42420" - "f5246a21f62420f52420f6246a21f72420f62420f7246a21f82420f72420f8246a21f92420f82420f9246a21fa2420" - "f92420fa246a21fb2420fa2420fb246a21fc2420fb2420fc246a21fd2420fc2420fd246a21fe2420fd2420fe246a21" - "ff2420fe2420ff246a21802520ff242080256a2181252080252081256a2182252081252082256a2183252082252083" - "256a2184252083252084256a2185252084252085256a2186252085252086256a2187252086252087256a2188252087" - "252088256a2189252088252089256a218a25208925208a256a218b25208a25208b256a218c25208b25208c256a218d" - "25208c25208d256a218e25208d25208e256a218f25208e25208f256a219025208f252090256a219125209025209125" - "6a2192252091252092256a2193252092252093256a2194252093252094256a2195252094252095256a219625209525" - "2096256a2197252096252097256a2198252097252098256a2199252098252099256a219a25209925209a256a219b25" - "209a25209b256a219c25209b25209c256a219d25209c25209d256a219e25209d25209e256a219f25209e25209f256a" - "21a025209f2520a0256a21a12520a02520a1256a21a22520a12520a2256a21a32520a22520a3256a21a42520a32520" - "a4256a21a52520a42520a5256a21a62520a52520a6256a21a72520a62520a7256a21a82520a72520a8256a21a92520" - "a82520a9256a21aa2520a92520aa256a21ab2520aa2520ab256a21ac2520ab2520ac256a21ad2520ac2520ad256a21" - "ae2520ad2520ae256a21af2520ae2520af256a21b02520af2520b0256a21b12520b02520b1256a21b22520b12520b2" - "256a21b32520b22520b3256a21b42520b32520b4256a21b52520b42520b5256a21b62520b52520b6256a21b72520b6" - "2520b7256a21b82520b72520b8256a21b92520b82520b9256a21ba2520b92520ba256a21bb2520ba2520bb256a21bc" - "2520bb2520bc256a21bd2520bc2520bd256a21be2520bd2520be256a21bf2520be2520bf256a21c02520bf2520c025" - "6a21c12520c02520c1256a21c22520c12520c2256a21c32520c22520c3256a21c42520c32520c4256a21c52520c425" - "20c5256a21c62520c52520c6256a21c72520c62520c7256a21c82520c72520c8256a21c92520c82520c9256a21ca25" - "20c92520ca256a21cb2520ca2520cb256a21cc2520cb2520cc256a21cd2520cc2520cd256a21ce2520cd2520ce256a" - "21cf2520ce2520cf256a21d02520cf2520d0256a21d12520d02520d1256a21d22520d12520d2256a21d32520d22520" - "d3256a21d42520d32520d4256a21d52520d42520d5256a21d62520d52520d6256a21d72520d62520d7256a21d82520" - "d72520d8256a21d92520d82520d9256a21da2520d92520da256a21db2520da2520db256a21dc2520db2520dc256a21" - "dd2520dc2520dd256a21de2520dd2520de256a21df2520de2520df256a21e02520df2520e0256a21e12520e02520e1" - "256a21e22520e12520e2256a21e32520e22520e3256a21e42520e32520e4256a21e52520e42520e5256a21e62520e5" - "2520e6256a21e72520e62520e7256a21e82520e72520e8256a21e92520e82520e9256a21ea2520e92520ea256a21eb" - "2520ea2520eb256a21ec2520eb2520ec256a21ed2520ec2520ed256a21ee2520ed2520ee256a21ef2520ee2520ef25" - "6a21f02520ef2520f0256a21f12520f02520f1256a21f22520f12520f2256a21f32520f22520f3256a21f42520f325" - "20f4256a21f52520f42520f5256a21f62520f52520f6256a21f72520f62520f7256a21f82520f72520f8256a21f925" - "20f82520f9256a21fa2520f92520fa256a21fb2520fa2520fb256a21fc2520fb2520fc256a21fd2520fc2520fd256a" - "21fe2520fd2520fe256a21ff2520fe2520ff256a21802620ff252080266a2181262080262081266a21822620812620" - "82266a2183262082262083266a2184262083262084266a2185262084262085266a2186262085262086266a21872620" - "86262087266a2188262087262088266a2189262088262089266a218a26208926208a266a218b26208a26208b266a21" - "8c26208b26208c266a218d26208c26208d266a218e26208d26208e266a218f26208e26208f266a219026208f262090" - "266a2191262090262091266a2192262091262092266a2193262092262093266a2194262093262094266a2195262094" - "262095266a2196262095262096266a2197262096262097266a2198262097262098266a2199262098262099266a219a" - "26209926209a266a219b26209a26209b266a219c26209b26209c266a219d26209c26209d266a219e26209d26209e26" - "6a219f26209e26209f266a21a026209f2620a0266a21a12620a02620a1266a21a22620a12620a2266a21a32620a226" - "20a3266a21a42620a32620a4266a21a52620a42620a5266a21a62620a52620a6266a21a72620a62620a7266a21a826" - "20a72620a8266a21a92620a82620a9266a21aa2620a92620aa266a21ab2620aa2620ab266a21ac2620ab2620ac266a" - "21ad2620ac2620ad266a21ae2620ad2620ae266a21af2620ae2620af266a21b02620af2620b0266a21b12620b02620" - "b1266a21b22620b12620b2266a21b32620b22620b3266a21b42620b32620b4266a21b52620b42620b5266a21b62620" - "b52620b6266a21b72620b62620b7266a21b82620b72620b8266a21b92620b82620b9266a21ba2620b92620ba266a21" - "bb2620ba2620bb266a21bc2620bb2620bc266a21bd2620bc2620bd266a21be2620bd2620be266a21bf2620be2620bf" - "266a21c02620bf2620c0266a21c12620c02620c1266a21c22620c12620c2266a21c32620c22620c3266a21c42620c3" - "2620c4266a21c52620c42620c5266a21c62620c52620c6266a21c72620c62620c7266a21c82620c72620c8266a21c9" - "2620c82620c9266a21ca2620c92620ca266a21cb2620ca2620cb266a21cc2620cb2620cc266a21cd2620cc2620cd26" - "6a21ce2620cd2620ce266a21cf2620ce2620cf266a21d02620cf2620d0266a21d12620d02620d1266a21d22620d126" - "20d2266a21d32620d22620d3266a21d42620d32620d4266a21d52620d42620d5266a21d62620d52620d6266a21d726" - "20d62620d7266a21d82620d72620d8266a21d92620d82620d9266a21da2620d92620da266a21db2620da2620db266a" - "21dc2620db2620dc266a21dd2620dc2620dd266a21de2620dd2620de266a21df2620de2620df266a21e02620df2620" - "e0266a21e12620e02620e1266a21e22620e12620e2266a21e32620e22620e3266a21e42620e32620e4266a21e52620" - "e42620e5266a21e62620e52620e6266a21e72620e62620e7266a21e82620e72620e8266a21e92620e82620e9266a21" - "ea2620e92620ea266a21eb2620ea2620eb266a21ec2620eb2620ec266a21ed2620ec2620ed266a21ee2620ed2620ee" - "266a21ef2620ee2620ef266a21f02620ef2620f0266a21f12620f02620f1266a21f22620f12620f2266a21f32620f2" - "2620f3266a21f42620f32620f4266a21f52620f42620f5266a21f62620f52620f6266a21f72620f62620f7266a21f8" - "2620f72620f8266a21f92620f82620f9266a21fa2620f92620fa266a21fb2620fa2620fb266a21fc2620fb2620fc26" - "6a21fd2620fc2620fd266a21fe2620fd2620fe266a21ff2620fe2620ff266a21802720ff262080276a218127208027" - "2081276a2182272081272082276a2183272082272083276a2184272083272084276a2185272084272085276a218627" - "2085272086276a2187272086272087276a2188272087272088276a2189272088272089276a218a27208927208a276a" - "218b27208a27208b276a218c27208b27208c276a218d27208c27208d276a218e27208d27208e276a218f27208e2720" - "8f276a219027208f272090276a2191272090272091276a2192272091272092276a2193272092272093276a21942720" - "93272094276a2195272094272095276a2196272095272096276a2197272096272097276a2198272097272098276a21" - "99272098272099276a219a27209927209a276a219b27209a27209b276a219c27209b27209c276a219d27209c27209d" - "276a219e27209d27209e276a219f27209e27209f276a21a027209f2720a0276a21a12720a02720a1276a21a22720a1" - "2720a2276a21a32720a22720a3276a21a42720a32720a4276a21a52720a42720a5276a21a62720a52720a6276a21a7" - "2720a62720a7276a21a82720a72720a8276a21a92720a82720a9276a21aa2720a92720aa276a21ab2720aa2720ab27" - "6a21ac2720ab2720ac276a21ad2720ac2720ad276a21ae2720ad2720ae276a21af2720ae2720af276a21b02720af27" - "20b0276a21b12720b02720b1276a21b22720b12720b2276a21b32720b22720b3276a21b42720b32720b4276a21b527" - "20b42720b5276a21b62720b52720b6276a21b72720b62720b7276a21b82720b72720b8276a21b92720b82720b9276a" - "21ba2720b92720ba276a21bb2720ba2720bb276a21bc2720bb2720bc276a21bd2720bc2720bd276a21be2720bd2720" - "be276a21bf2720be2720bf276a21c02720bf2720c0276a21c12720c02720c1276a21c22720c12720c2276a21c32720" - "c22720c3276a21c42720c32720c4276a21c52720c42720c5276a21c62720c52720c6276a21c72720c62720c7276a21" - "c82720c72720c8276a21c92720c82720c9276a21ca2720c92720ca276a21cb2720ca2720cb276a21cc2720cb2720cc" - "276a21cd2720cc2720cd276a21ce2720cd2720ce276a21cf2720ce2720cf276a21d02720cf2720d0276a21d12720d0" - "2720d1276a21d22720d12720d2276a21d32720d22720d3276a21d42720d32720d4276a21d52720d42720d5276a21d6" - "2720d52720d6276a21d72720d62720d7276a21d82720d72720d8276a21d92720d82720d9276a21da2720d92720da27" - "6a21db2720da2720db276a21dc2720db2720dc276a21dd2720dc2720dd276a21de2720dd2720de276a21df2720de27" - "20df276a21e02720df2720e0276a21e12720e02720e1276a21e22720e12720e2276a21e32720e22720e3276a21e427" - "20e32720e4276a21e52720e42720e5276a21e62720e52720e6276a21e72720e62720e7276a21e82720e72720e8276a" - "21e92720e82720e9276a21ea2720e92720ea276a21eb2720ea2720eb276a21ec2720eb2720ec276a21ed2720ec2720" - "ed276a21ee2720ed2720ee276a21ef2720ee2720ef276a21f02720ef2720f0276a21f12720f02720f1276a21f22720" - "f12720f2276a21f32720f22720f3276a21f42720f32720f4276a21f52720f42720f5276a21f62720f52720f6276a21" - "f72720f62720f7276a21f82720f72720f8276a21f92720f82720f9276a21fa2720f92720fa276a21fb2720fa2720fb" - "276a21fc2720fb2720fc276a21fd2720fc2720fd276a21fe2720fd2720fe276a21ff2720fe2720ff276a21802820ff" - "272080286a2181282080282081286a2182282081282082286a2183282082282083286a2184282083282084286a2185" - "282084282085286a2186282085282086286a2187282086282087286a2188282087282088286a218928208828208928" - "6a218a28208928208a286a218b28208a28208b286a218c28208b28208c286a218d28208c28208d286a218e28208d28" - "208e286a218f28208e28208f286a219028208f282090286a2191282090282091286a2192282091282092286a219328" - "2092282093286a2194282093282094286a2195282094282095286a2196282095282096286a2197282096282097286a" - "2198282097282098286a2199282098282099286a219a28209928209a286a219b28209a28209b286a219c28209b2820" - "9c286a219d28209c28209d286a219e28209d28209e286a219f28209e28209f286a21a028209f2820a0286a21a12820" - "a02820a1286a21a22820a12820a2286a21a32820a22820a3286a21a42820a32820a4286a21a52820a42820a5286a21" - "a62820a52820a6286a21a72820a62820a7286a21a82820a72820a8286a21a92820a82820a9286a21aa2820a92820aa" - "286a21ab2820aa2820ab286a21ac2820ab2820ac286a21ad2820ac2820ad286a21ae2820ad2820ae286a21af2820ae" - "2820af286a21b02820af2820b0286a21b12820b02820b1286a21b22820b12820b2286a21b32820b22820b3286a21b4" - "2820b32820b4286a21b52820b42820b5286a21b62820b52820b6286a21b72820b62820b7286a21b82820b72820b828" - "6a21b92820b82820b9286a21ba2820b92820ba286a21bb2820ba2820bb286a21bc2820bb2820bc286a21bd2820bc28" - "20bd286a21be2820bd2820be286a21bf2820be2820bf286a21c02820bf2820c0286a21c12820c02820c1286a21c228" - "20c12820c2286a21c32820c22820c3286a21c42820c32820c4286a21c52820c42820c5286a21c62820c52820c6286a" - "21c72820c62820c7286a21c82820c72820c8286a21c92820c82820c9286a21ca2820c92820ca286a21cb2820ca2820" - "cb286a21cc2820cb2820cc286a21cd2820cc2820cd286a21ce2820cd2820ce286a21cf2820ce2820cf286a21d02820" - "cf2820d0286a21d12820d02820d1286a21d22820d12820d2286a21d32820d22820d3286a21d42820d32820d4286a21" - "d52820d42820d5286a21d62820d52820d6286a21d72820d62820d7286a21d82820d72820d8286a21d92820d82820d9" - "286a21da2820d92820da286a21db2820da2820db286a21dc2820db2820dc286a21dd2820dc2820dd286a21de2820dd" - "2820de286a21df2820de2820df286a21e02820df2820e0286a21e12820e02820e1286a21e22820e12820e2286a21e3" - "2820e22820e3286a21e42820e32820e4286a21e52820e42820e5286a21e62820e52820e6286a21e72820e62820e728" - "6a21e82820e72820e8286a21e92820e82820e9286a21ea2820e92820ea286a21eb2820ea2820eb286a21ec2820eb28" - "20ec286a21ed2820ec2820ed286a21ee2820ed2820ee286a21ef2820ee2820ef286a21f02820ef2820f0286a21f128" - "20f02820f1286a21f22820f12820f2286a21f32820f22820f3286a21f42820f32820f4286a21f52820f42820f5286a" - "21f62820f52820f6286a21f72820f62820f7286a21f82820f72820f8286a21f92820f82820f9286a21fa2820f92820" - "fa286a21fb2820fa2820fb286a21fc2820fb2820fc286a21fd2820fc2820fd286a21fe2820fd2820fe286a21ff2820" - "fe2820ff286a21802920ff282080296a2181292080292081296a2182292081292082296a2183292082292083296a21" - "84292083292084296a2185292084292085296a2186292085292086296a2187292086292087296a2188292087292088" - "296a2189292088292089296a218a29208929208a296a218b29208a29208b296a218c29208b29208c296a218d29208c" - "29208d296a218e29208d29208e296a218f29208e29208f296a219029208f292090296a2191292090292091296a2192" - "292091292092296a2193292092292093296a2194292093292094296a2195292094292095296a219629209529209629" - "6a2197292096292097296a2198292097292098296a2199292098292099296a219a29209929209a296a219b29209a29" - "209b296a219c29209b29209c296a219d29209c29209d296a219e29209d29209e296a219f29209e29209f296a21a029" - "209f2920a0296a21a12920a02920a1296a21a22920a12920a2296a21a32920a22920a3296a21a42920a32920a4296a" - "21a52920a42920a5296a21a62920a52920a6296a21a72920a62920a7296a21a82920a72920a8296a21a92920a82920" - "a9296a21aa2920a92920aa296a21ab2920aa2920ab296a21ac2920ab2920ac296a21ad2920ac2920ad296a21ae2920" - "ad2920ae296a21af2920ae2920af296a21b02920af2920b0296a21b12920b02920b1296a21b22920b12920b2296a21" - "b32920b22920b3296a21b42920b32920b4296a21b52920b42920b5296a21b62920b52920b6296a21b72920b62920b7" - "296a21b82920b72920b8296a21b92920b82920b9296a21ba2920b92920ba296a21bb2920ba2920bb296a21bc2920bb" - "2920bc296a21bd2920bc2920bd296a21be2920bd2920be296a21bf2920be2920bf296a21c02920bf2920c0296a21c1" - "2920c02920c1296a21c22920c12920c2296a21c32920c22920c3296a21c42920c32920c4296a21c52920c42920c529" - "6a21c62920c52920c6296a21c72920c62920c7296a21c82920c72920c8296a21c92920c82920c9296a21ca2920c929" - "20ca296a21cb2920ca2920cb296a21cc2920cb2920cc296a21cd2920cc2920cd296a21ce2920cd2920ce296a21cf29" - "20ce2920cf296a21d02920cf2920d0296a21d12920d02920d1296a21d22920d12920d2296a21d32920d22920d3296a" - "21d42920d32920d4296a21d52920d42920d5296a21d62920d52920d6296a21d72920d62920d7296a21d82920d72920" - "d8296a21d92920d82920d9296a21da2920d92920da296a21db2920da2920db296a21dc2920db2920dc296a21dd2920" - "dc2920dd296a21de2920dd2920de296a21df2920de2920df296a21e02920df2920e0296a21e12920e02920e1296a21" - "e22920e12920e2296a21e32920e22920e3296a21e42920e32920e4296a21e52920e42920e5296a21e62920e52920e6" - "296a21e72920e62920e7296a21e82920e72920e8296a21e92920e82920e9296a21ea2920e92920ea296a21eb2920ea" - "2920eb296a21ec2920eb2920ec296a21ed2920ec2920ed296a21ee2920ed2920ee296a21ef2920ee2920ef296a21f0" - "2920ef2920f0296a21f12920f02920f1296a21f22920f12920f2296a21f32920f22920f3296a21f42920f32920f429" - "6a21f52920f42920f5296a21f62920f52920f6296a21f72920f62920f7296a21f82920f72920f8296a21f92920f829" - "20f9296a21fa2920f92920fa296a21fb2920fa2920fb296a21fc2920fb2920fc296a21fd2920fc2920fd296a21fe29" - "20fd2920fe296a21ff2920fe2920ff296a21802a20ff2920802a6a21812a20802a20812a6a21822a20812a20822a6a" - "21832a20822a20832a6a21842a20832a20842a6a21852a20842a20852a6a21862a20852a20862a6a21872a20862a20" - "872a6a21882a20872a20882a6a21892a20882a20892a6a218a2a20892a208a2a6a218b2a208a2a208b2a6a218c2a20" - "8b2a208c2a6a218d2a208c2a208d2a6a218e2a208d2a208e2a6a218f2a208e2a208f2a6a21902a208f2a20902a6a21" - "912a20902a20912a6a21922a20912a20922a6a21932a20922a20932a6a21942a20932a20942a6a21952a20942a2095" - "2a6a21962a20952a20962a6a21972a20962a20972a6a21982a20972a20982a6a21992a20982a20992a6a219a2a2099" - "2a209a2a6a219b2a209a2a209b2a6a219c2a209b2a209c2a6a219d2a209c2a209d2a6a219e2a209d2a209e2a6a219f" - "2a209e2a209f2a6a21a02a209f2a20a02a6a21a12a20a02a20a12a6a21a22a20a12a20a22a6a21a32a20a22a20a32a" - "6a21a42a20a32a20a42a6a21a52a20a42a20a52a6a21a62a20a52a20a62a6a21a72a20a62a20a72a6a21a82a20a72a" - "20a82a6a21a92a20a82a20a92a6a21aa2a20a92a20aa2a6a21ab2a20aa2a20ab2a6a21ac2a20ab2a20ac2a6a21ad2a" - "20ac2a20ad2a6a21ae2a20ad2a20ae2a6a21af2a20ae2a20af2a6a21b02a20af2a20b02a6a21b12a20b02a20b12a6a" - "21b22a20b12a20b22a6a21b32a20b22a20b32a6a21b42a20b32a20b42a6a21b52a20b42a20b52a6a21b62a20b52a20" - "b62a6a21b72a20b62a20b72a6a21b82a20b72a20b82a6a21b92a20b82a20b92a6a21ba2a20b92a20ba2a6a21bb2a20" - "ba2a20bb2a6a21bc2a20bb2a20bc2a6a21bd2a20bc2a20bd2a6a21be2a20bd2a20be2a6a21bf2a20be2a20bf2a6a21" - "c02a20bf2a20c02a6a21c12a20c02a20c12a6a21c22a20c12a20c22a6a21c32a20c22a20c32a6a21c42a20c32a20c4" - "2a6a21c52a20c42a20c52a6a21c62a20c52a20c62a6a21c72a20c62a20c72a6a21c82a20c72a20c82a6a21c92a20c8" - "2a20c92a6a21ca2a20c92a20ca2a6a21cb2a20ca2a20cb2a6a21cc2a20cb2a20cc2a6a21cd2a20cc2a20cd2a6a21ce" - "2a20cd2a20ce2a6a21cf2a20ce2a20cf2a6a21d02a20cf2a20d02a6a21d12a20d02a20d12a6a21d22a20d12a20d22a" - "6a21d32a20d22a20d32a6a21d42a20d32a20d42a6a21d52a20d42a20d52a6a21d62a20d52a20d62a6a21d72a20d62a" - "20d72a6a21d82a20d72a20d82a6a21d92a20d82a20d92a6a21da2a20d92a20da2a6a21db2a20da2a20db2a6a21dc2a" - "20db2a20dc2a6a21dd2a20dc2a20dd2a6a21de2a20dd2a20de2a6a21df2a20de2a20df2a6a21e02a20df2a20e02a6a" - "21e12a20e02a20e12a6a21e22a20e12a20e22a6a21e32a20e22a20e32a6a21e42a20e32a20e42a6a21e52a20e42a20" - "e52a6a21e62a20e52a20e62a6a21e72a20e62a20e72a6a21e82a20e72a20e82a6a21e92a20e82a20e92a6a21ea2a20" - "e92a20ea2a6a21eb2a20ea2a20eb2a6a21ec2a20eb2a20ec2a6a21ed2a20ec2a20ed2a6a21ee2a20ed2a20ee2a6a21" - "ef2a20ee2a20ef2a6a21f02a20ef2a20f02a6a21f12a20f02a20f12a6a21f22a20f12a20f22a6a21f32a20f22a20f3" - "2a6a21f42a20f32a20f42a6a21f52a20f42a20f52a6a21f62a20f52a20f62a6a21f72a20f62a20f72a6a21f82a20f7" - "2a20f82a6a21f92a20f82a20f92a6a21fa2a20f92a20fa2a6a21fb2a20fa2a20fb2a6a21fc2a20fb2a20fc2a6a21fd" - "2a20fc2a20fd2a6a21fe2a20fd2a20fe2a6a21ff2a20fe2a20ff2a6a21802b20ff2a20802b6a21812b20802b20812b" - "6a21822b20812b20822b6a21832b20822b20832b6a21842b20832b20842b6a21852b20842b20852b6a21862b20852b" - "20862b6a21872b20862b20872b6a21882b20872b20882b6a21892b20882b20892b6a218a2b20892b208a2b6a218b2b" - "208a2b208b2b6a218c2b208b2b208c2b6a218d2b208c2b208d2b6a218e2b208d2b208e2b6a218f2b208e2b208f2b6a" - "21902b208f2b20902b6a21912b20902b20912b6a21922b20912b20922b6a21932b20922b20932b6a21942b20932b20" - "942b6a21952b20942b20952b6a21962b20952b20962b6a21972b20962b20972b6a21982b20972b20982b6a21992b20" - "982b20992b6a219a2b20992b209a2b6a219b2b209a2b209b2b6a219c2b209b2b209c2b6a219d2b209c2b209d2b6a21" - "9e2b209d2b209e2b6a219f2b209e2b209f2b6a21a02b209f2b20a02b6a21a12b20a02b20a12b6a21a22b20a12b20a2" - "2b6a21a32b20a22b20a32b6a21a42b20a32b20a42b6a21a52b20a42b20a52b6a21a62b20a52b20a62b6a21a72b20a6" - "2b20a72b6a21a82b20a72b20a82b6a21a92b20a82b20a92b6a21aa2b20a92b20aa2b6a21ab2b20aa2b20ab2b6a21ac" - "2b20ab2b20ac2b6a21ad2b20ac2b20ad2b6a21ae2b20ad2b20ae2b6a21af2b20ae2b20af2b6a21b02b20af2b20b02b" - "6a21b12b20b02b20b12b6a21b22b20b12b20b22b6a21b32b20b22b20b32b6a21b42b20b32b20b42b6a21b52b20b42b" - "20b52b6a21b62b20b52b20b62b6a21b72b20b62b20b72b6a21b82b20b72b20b82b6a21b92b20b82b20b92b6a21ba2b" - "20b92b20ba2b6a21bb2b20ba2b20bb2b6a21bc2b20bb2b20bc2b6a21bd2b20bc2b20bd2b6a21be2b20bd2b20be2b6a" - "21bf2b20be2b20bf2b6a21c02b20bf2b20c02b6a21c12b20c02b20c12b6a21c22b20c12b20c22b6a21c32b20c22b20" - "c32b6a21c42b20c32b20c42b6a21c52b20c42b20c52b6a21c62b20c52b20c62b6a21c72b20c62b20c72b6a21c82b20" - "c72b20c82b6a21c92b20c82b20c92b6a21ca2b20c92b20ca2b6a21cb2b20ca2b20cb2b6a21cc2b20cb2b20cc2b6a21" - "cd2b20cc2b20cd2b6a21ce2b20cd2b20ce2b6a21cf2b20ce2b20cf2b6a21d02b20cf2b20d02b6a21d12b20d02b20d1" - "2b6a21d22b20d12b20d22b6a21d32b20d22b20d32b6a21d42b20d32b20d42b6a21d52b20d42b20d52b6a21d62b20d5" - "2b20d62b6a21d72b20d62b20d72b6a21d82b20d72b20d82b6a21d92b20d82b20d92b6a21da2b20d92b20da2b6a21db" - "2b20da2b20db2b6a21dc2b20db2b20dc2b6a21dd2b20dc2b20dd2b6a21de2b20dd2b20de2b6a21df2b20de2b20df2b" - "6a21e02b20df2b20e02b6a21e12b20e02b20e12b6a21e22b20e12b20e22b6a21e32b20e22b20e32b6a21e42b20e32b" - "20e42b6a21e52b20e42b20e52b6a21e62b20e52b20e62b6a21e72b20e62b20e72b6a21e82b20e72b20e82b6a21e92b" - "20e82b20e92b6a21ea2b20e92b20ea2b6a21eb2b20ea2b20eb2b6a21ec2b20eb2b20ec2b6a21ed2b20ec2b20ed2b6a" - "21ee2b20ed2b20ee2b6a21ef2b20ee2b20ef2b6a21f02b20ef2b20f02b6a21f12b20f02b20f12b6a21f22b20f12b20" - "f22b6a21f32b20f22b20f32b6a21f42b20f32b20f42b6a21f52b20f42b20f52b6a21f62b20f52b20f62b6a21f72b20" - "f62b20f72b6a21f82b20f72b20f82b6a21f92b20f82b20f92b6a21fa2b20f92b20fa2b6a21fb2b20fa2b20fb2b6a21" - "fc2b20fb2b20fc2b6a21fd2b20fc2b20fd2b6a21fe2b20fd2b20fe2b6a21ff2b20fe2b20ff2b6a21802c20ff2b2080" - "2c6a21812c20802c20812c6a21822c20812c20822c6a21832c20822c20832c6a21842c20832c20842c6a21852c2084" - "2c20852c6a21862c20852c20862c6a21872c20862c20872c6a21882c20872c20882c6a21892c20882c20892c6a218a" - "2c20892c208a2c6a218b2c208a2c208b2c6a218c2c208b2c208c2c6a218d2c208c2c208d2c6a218e2c208d2c208e2c" - "6a218f2c208e2c208f2c6a21902c208f2c20902c6a21912c20902c20912c6a21922c20912c20922c6a21932c20922c" - "20932c6a21942c20932c20942c6a21952c20942c20952c6a21962c20952c20962c6a21972c20962c20972c6a21982c" - "20972c20982c6a21992c20982c20992c6a219a2c20992c209a2c6a219b2c209a2c209b2c6a219c2c209b2c209c2c6a" - "219d2c209c2c209d2c6a219e2c209d2c209e2c6a219f2c209e2c209f2c6a21a02c209f2c20a02c6a21a12c20a02c20" - "a12c6a21a22c20a12c20a22c6a21a32c20a22c20a32c6a21a42c20a32c20a42c6a21a52c20a42c20a52c6a21a62c20" - "a52c20a62c6a21a72c20a62c20a72c6a21a82c20a72c20a82c6a21a92c20a82c20a92c6a21aa2c20a92c20aa2c6a21" - "ab2c20aa2c20ab2c6a21ac2c20ab2c20ac2c6a21ad2c20ac2c20ad2c6a21ae2c20ad2c20ae2c6a21af2c20ae2c20af" - "2c6a21b02c20af2c20b02c6a21b12c20b02c20b12c6a21b22c20b12c20b22c6a21b32c20b22c20b32c6a21b42c20b3" - "2c20b42c6a21b52c20b42c20b52c6a21b62c20b52c20b62c6a21b72c20b62c20b72c6a21b82c20b72c20b82c6a21b9" - "2c20b82c20b92c6a21ba2c20b92c20ba2c6a21bb2c20ba2c20bb2c6a21bc2c20bb2c20bc2c6a21bd2c20bc2c20bd2c" - "6a21be2c20bd2c20be2c6a21bf2c20be2c20bf2c6a21c02c20bf2c20c02c6a21c12c20c02c20c12c6a21c22c20c12c" - "20c22c6a21c32c20c22c20c32c6a21c42c20c32c20c42c6a21c52c20c42c20c52c6a21c62c20c52c20c62c6a21c72c" - "20c62c20c72c6a21c82c20c72c20c82c6a21c92c20c82c20c92c6a21ca2c20c92c20ca2c6a21cb2c20ca2c20cb2c6a" - "21cc2c20cb2c20cc2c6a21cd2c20cc2c20cd2c6a21ce2c20cd2c20ce2c6a21cf2c20ce2c20cf2c6a21d02c20cf2c20" - "d02c6a21d12c20d02c20d12c6a21d22c20d12c20d22c6a21d32c20d22c20d32c6a21d42c20d32c20d42c6a21d52c20" - "d42c20d52c6a21d62c20d52c20d62c6a21d72c20d62c20d72c6a21d82c20d72c20d82c6a21d92c20d82c20d92c6a21" - "da2c20d92c20da2c6a21db2c20da2c20db2c6a21dc2c20db2c20dc2c6a21dd2c20dc2c20dd2c6a21de2c20dd2c20de" - "2c6a21df2c20de2c20df2c6a21e02c20df2c20e02c6a21e12c20e02c20e12c6a21e22c20e12c20e22c6a21e32c20e2" - "2c20e32c6a21e42c20e32c20e42c6a21e52c20e42c20e52c6a21e62c20e52c20e62c6a21e72c20e62c20e72c6a21e8" - "2c20e72c20e82c6a21e92c20e82c20e92c6a21ea2c20e92c20ea2c6a21eb2c20ea2c20eb2c6a21ec2c20eb2c20ec2c" - "6a21ed2c20ec2c20ed2c6a21ee2c20ed2c20ee2c6a21ef2c20ee2c20ef2c6a21f02c20ef2c20f02c6a21f12c20f02c" - "20f12c6a21f22c20f12c20f22c6a21f32c20f22c20f32c6a21f42c20f32c20f42c6a21f52c20f42c20f52c6a21f62c" - "20f52c20f62c6a21f72c20f62c20f72c6a21f82c20f72c20f82c6a21f92c20f82c20f92c6a21fa2c20f92c20fa2c6a" - "21fb2c20fa2c20fb2c6a21fc2c20fb2c20fc2c6a21fd2c20fc2c20fd2c6a21fe2c20fd2c20fe2c6a21ff2c20fe2c20" - "ff2c6a21802d20ff2c20802d6a21812d20802d20812d6a21822d20812d20822d6a21832d20822d20832d6a21842d20" - "832d20842d6a21852d20842d20852d6a21862d20852d20862d6a21872d20862d20872d6a21882d20872d20882d6a21" - "892d20882d20892d6a218a2d20892d208a2d6a218b2d208a2d208b2d6a218c2d208b2d208c2d6a218d2d208c2d208d" - "2d6a218e2d208d2d208e2d6a218f2d208e2d208f2d6a21902d208f2d20902d6a21912d20902d20912d6a21922d2091" - "2d20922d6a21932d20922d20932d6a21942d20932d20942d6a21952d20942d20952d6a21962d20952d20962d6a2197" - "2d20962d20972d6a21982d20972d20982d6a21992d20982d20992d6a219a2d20992d209a2d6a219b2d209a2d209b2d" - "6a219c2d209b2d209c2d6a219d2d209c2d209d2d6a219e2d209d2d209e2d6a219f2d209e2d209f2d6a21a02d209f2d" - "20a02d6a21a12d20a02d20a12d6a21a22d20a12d20a22d6a21a32d20a22d20a32d6a21a42d20a32d20a42d6a21a52d" - "20a42d20a52d6a21a62d20a52d20a62d6a21a72d20a62d20a72d6a21a82d20a72d20a82d6a21a92d20a82d20a92d6a" - "21aa2d20a92d20aa2d6a21ab2d20aa2d20ab2d6a21ac2d20ab2d20ac2d6a21ad2d20ac2d20ad2d6a21ae2d20ad2d20" - "ae2d6a21af2d20ae2d20af2d6a21b02d20af2d20b02d6a21b12d20b02d20b12d6a21b22d20b12d20b22d6a21b32d20" - "b22d20b32d6a21b42d20b32d20b42d6a21b52d20b42d20b52d6a21b62d20b52d20b62d6a21b72d20b62d20b72d6a21" - "b82d20b72d20b82d6a21b92d20b82d20b92d6a21ba2d20b92d20ba2d6a21bb2d20ba2d20bb2d6a21bc2d20bb2d20bc" - "2d6a21bd2d20bc2d20bd2d6a21be2d20bd2d20be2d6a21bf2d20be2d20bf2d6a21c02d20bf2d20c02d6a21c12d20c0" - "2d20c12d6a21c22d20c12d20c22d6a21c32d20c22d20c32d6a21c42d20c32d20c42d6a21c52d20c42d20c52d6a21c6" - "2d20c52d20c62d6a21c72d20c62d20c72d6a21c82d20c72d20c82d6a21c92d20c82d20c92d6a21ca2d20c92d20ca2d" - "6a21cb2d20ca2d20cb2d6a21cc2d20cb2d20cc2d6a21cd2d20cc2d20cd2d6a21ce2d20cd2d20ce2d6a21cf2d20ce2d" - "20cf2d6a21d02d20cf2d20d02d6a21d12d20d02d20d12d6a21d22d20d12d20d22d6a21d32d20d22d20d32d6a21d42d" - "20d32d20d42d6a21d52d20d42d20d52d6a21d62d20d52d20d62d6a21d72d20d62d20d72d6a21d82d20d72d20d82d6a" - "21d92d20d82d20d92d6a21da2d20d92d20da2d6a21db2d20da2d20db2d6a21dc2d20db2d20dc2d6a21dd2d20dc2d20" - "dd2d6a21de2d20dd2d20de2d6a21df2d20de2d20df2d6a21e02d20df2d20e02d6a21e12d20e02d20e12d6a21e22d20" - "e12d20e22d6a21e32d20e22d20e32d6a21e42d20e32d20e42d6a21e52d20e42d20e52d6a21e62d20e52d20e62d6a21" - "e72d20e62d20e72d6a21e82d20e72d20e82d6a21e92d20e82d20e92d6a21ea2d20e92d20ea2d6a21eb2d20ea2d20eb" - "2d6a21ec2d20eb2d20ec2d6a21ed2d20ec2d20ed2d6a21ee2d20ed2d20ee2d6a21ef2d20ee2d20ef2d6a21f02d20ef" - "2d20f02d6a21f12d20f02d20f12d6a21f22d20f12d20f22d6a21f32d20f22d20f32d6a21f42d20f32d20f42d6a21f5" - "2d20f42d20f52d6a21f62d20f52d20f62d6a21f72d20f62d20f72d6a21f82d20f72d20f82d6a21f92d20f82d20f92d" - "6a21fa2d20f92d20fa2d6a21fb2d20fa2d20fb2d6a21fc2d20fb2d20fc2d6a21fd2d20fc2d20fd2d6a21fe2d20fd2d" - "20fe2d6a21ff2d20fe2d20ff2d6a21802e20ff2d20802e6a21812e20802e20812e6a21822e20812e20822e6a21832e" - "20822e20832e6a21842e20832e20842e6a21852e20842e20852e6a21862e20852e20862e6a21872e20862e20872e6a" - "21882e20872e20882e6a21892e20882e20892e6a218a2e20892e208a2e6a218b2e208a2e208b2e6a218c2e208b2e20" - "8c2e6a218d2e208c2e208d2e6a218e2e208d2e208e2e6a218f2e208e2e208f2e6a21902e208f2e20902e6a21912e20" - "902e20912e6a21922e20912e20922e6a21932e20922e20932e6a21942e20932e20942e6a21952e20942e20952e6a21" - "962e20952e20962e6a21972e20962e20972e6a21982e20972e20982e6a21992e20982e20992e6a219a2e20992e209a" - "2e6a219b2e209a2e209b2e6a219c2e209b2e209c2e6a219d2e209c2e209d2e6a219e2e209d2e209e2e6a219f2e209e" - "2e209f2e6a21a02e209f2e20a02e6a21a12e20a02e20a12e6a21a22e20a12e20a22e6a21a32e20a22e20a32e6a21a4" - "2e20a32e20a42e6a21a52e20a42e20a52e6a21a62e20a52e20a62e6a21a72e20a62e20a72e6a21a82e20a72e20a82e" - "6a21a92e20a82e20a92e6a21aa2e20a92e20aa2e6a21ab2e20aa2e20ab2e6a21ac2e20ab2e20ac2e6a21ad2e20ac2e" - "20ad2e6a21ae2e20ad2e20ae2e6a21af2e20ae2e20af2e6a21b02e20af2e20b02e6a21b12e20b02e20b12e6a21b22e" - "20b12e20b22e6a21b32e20b22e20b32e6a21b42e20b32e20b42e6a21b52e20b42e20b52e6a21b62e20b52e20b62e6a" - "21b72e20b62e20b72e6a21b82e20b72e20b82e6a21b92e20b82e20b92e6a21ba2e20b92e20ba2e6a21bb2e20ba2e20" - "bb2e6a21bc2e20bb2e20bc2e6a21bd2e20bc2e20bd2e6a21be2e20bd2e20be2e6a21bf2e20be2e20bf2e6a21c02e20" - "bf2e20c02e6a21c12e20c02e20c12e6a21c22e20c12e20c22e6a21c32e20c22e20c32e6a21c42e20c32e20c42e6a21" - "c52e20c42e20c52e6a21c62e20c52e20c62e6a21c72e20c62e20c72e6a21c82e20c72e20c82e6a21c92e20c82e20c9" - "2e6a21ca2e20c92e20ca2e6a21cb2e20ca2e20cb2e6a21cc2e20cb2e20cc2e6a21cd2e20cc2e20cd2e6a21ce2e20cd" - "2e20ce2e6a21cf2e20ce2e20cf2e6a21d02e20cf2e20d02e6a21d12e20d02e20d12e6a21d22e20d12e20d22e6a21d3" - "2e20d22e20d32e6a21d42e20d32e20d42e6a21d52e20d42e20d52e6a21d62e20d52e20d62e6a21d72e20d62e20d72e" - "6a21d82e20d72e20d82e6a21d92e20d82e20d92e6a21da2e20d92e20da2e6a21db2e20da2e20db2e6a21dc2e20db2e" - "20dc2e6a21dd2e20dc2e20dd2e6a21de2e20dd2e20de2e6a21df2e20de2e20df2e6a21e02e20df2e20e02e6a21e12e" - "20e02e20e12e6a21e22e20e12e20e22e6a21e32e20e22e20e32e6a21e42e20e32e20e42e6a21e52e20e42e20e52e6a" - "21e62e20e52e20e62e6a21e72e20e62e20e72e6a21e82e20e72e20e82e6a21e92e20e82e20e92e6a21ea2e20e92e20" - "ea2e6a21eb2e20ea2e20eb2e6a21ec2e20eb2e20ec2e6a21ed2e20ec2e20ed2e6a21ee2e20ed2e20ee2e6a21ef2e20" - "ee2e20ef2e6a21f02e20ef2e20f02e6a21f12e20f02e20f12e6a21f22e20f12e20f22e6a21f32e20f22e20f32e6a21" - "f42e20f32e20f42e6a21f52e20f42e20f52e6a21f62e20f52e20f62e6a21f72e20f62e20f72e6a21f82e20f72e20f8" - "2e6a21f92e20f82e20f92e6a21fa2e20f92e20fa2e6a21fb2e20fa2e20fb2e6a21fc2e20fb2e20fc2e6a21fd2e20fc" - "2e20fd2e6a21fe2e20fd2e20fe2e6a21ff2e20fe2e20ff2e6a21802f20ff2e20802f6a21812f20802f20812f6a2182" - "2f20812f20822f6a21832f20822f20832f6a21842f20832f20842f6a21852f20842f20852f6a21862f20852f20862f" - "6a21872f20862f20872f6a21882f20872f20882f6a21892f20882f20892f6a218a2f20892f208a2f6a218b2f208a2f" - "208b2f6a218c2f208b2f208c2f6a218d2f208c2f208d2f6a218e2f208d2f208e2f6a218f2f208e2f208f2f6a21902f" - "208f2f20902f6a21912f20902f20912f6a21922f20912f20922f6a21932f20922f20932f6a21942f20932f20942f6a" - "21952f20942f20952f6a21962f20952f20962f6a21972f20962f20972f6a21982f20972f20982f6a21992f20982f20" - "992f6a219a2f20992f209a2f6a219b2f209a2f209b2f6a219c2f209b2f209c2f6a219d2f209c2f209d2f6a219e2f20" - "9d2f209e2f6a219f2f209e2f209f2f6a21a02f209f2f20a02f6a21a12f20a02f20a12f6a21a22f20a12f20a22f6a21" - "a32f20a22f20a32f6a21a42f20a32f20a42f6a21a52f20a42f20a52f6a21a62f20a52f20a62f6a21a72f20a62f20a7" - "2f6a21a82f20a72f20a82f6a21a92f20a82f20a92f6a21aa2f20a92f20aa2f6a21ab2f20aa2f20ab2f6a21ac2f20ab" - "2f20ac2f6a21ad2f20ac2f20ad2f6a21ae2f20ad2f20ae2f6a21af2f20ae2f20af2f6a21b02f20af2f20b02f6a21b1" - "2f20b02f20b12f6a21b22f20b12f20b22f6a21b32f20b22f20b32f6a21b42f20b32f20b42f6a21b52f20b42f20b52f" - "6a21b62f20b52f20b62f6a21b72f20b62f20b72f6a21b82f20b72f20b82f6a21b92f20b82f20b92f6a21ba2f20b92f" - "20ba2f6a21bb2f20ba2f20bb2f6a21bc2f20bb2f20bc2f6a21bd2f20bc2f20bd2f6a21be2f20bd2f20be2f6a21bf2f" - "20be2f20bf2f6a21c02f20bf2f20c02f6a21c12f20c02f20c12f6a21c22f20c12f20c22f6a21c32f20c22f20c32f6a" - "21c42f20c32f20c42f6a21c52f20c42f20c52f6a21c62f20c52f20c62f6a21c72f20c62f20c72f6a21c82f20c72f20" - "c82f6a21c92f20c82f20c92f6a21ca2f20c92f20ca2f6a21cb2f20ca2f20cb2f6a21cc2f20cb2f20cc2f6a21cd2f20" - "cc2f20cd2f6a21ce2f20cd2f20ce2f6a21cf2f20ce2f20cf2f6a21d02f20cf2f20d02f6a21d12f20d02f20d12f6a21" - "d22f20d12f20d22f6a21d32f20d22f20d32f6a21d42f20d32f20d42f6a21d52f20d42f20d52f6a21d62f20d52f20d6" - "2f6a21d72f20d62f20d72f6a21d82f20d72f20d82f6a21d92f20d82f20d92f6a21da2f20d92f20da2f6a21db2f20da" - "2f20db2f6a21dc2f20db2f20dc2f6a21dd2f20dc2f20dd2f6a21de2f20dd2f20de2f6a21df2f20de2f20df2f6a21e0" - "2f20df2f20e02f6a21e12f20e02f20e12f6a21e22f20e12f20e22f6a21e32f20e22f20e32f6a21e42f20e32f20e42f" - "6a21e52f20e42f20e52f6a21e62f20e52f20e62f6a21e72f20e62f20e72f6a21e82f20e72f20e82f6a21e92f20e82f" - "20e92f6a21ea2f20e92f20ea2f6a21eb2f20ea2f20eb2f6a21ec2f20eb2f20ec2f6a21ed2f20ec2f20ed2f6a21ee2f" - "20ed2f20ee2f6a21ef2f20ee2f20ef2f6a21f02f20ef2f20f02f6a21f12f20f02f20f12f6a21f22f20f12f20f22f6a" - "21f32f20f22f20f32f6a21f42f20f32f20f42f6a21f52f20f42f20f52f6a21f62f20f52f20f62f6a21f72f20f62f20" - "f72f6a21f82f20f72f20f82f6a21f92f20f82f20f92f6a21fa2f20f92f20fa2f6a21fb2f20fa2f20fb2f6a21fc2f20" - "fb2f20fc2f6a21fd2f20fc2f20fd2f6a21fe2f20fd2f20fe2f6a21ff2f20fe2f20ff2f6a21803020ff2f2080306a21" - "81302080302081306a2182302081302082306a2183302082302083306a2184302083302084306a2185302084302085" - "306a2186302085302086306a2187302086302087306a2188302087302088306a2189302088302089306a218a302089" - "30208a306a218b30208a30208b306a218c30208b30208c306a218d30208c30208d306a218e30208d30208e306a218f" - "30208e30208f306a219030208f302090306a2191302090302091306a2192302091302092306a219330209230209330" - "6a2194302093302094306a2195302094302095306a2196302095302096306a2197302096302097306a219830209730" - "2098306a2199302098302099306a219a30209930209a306a219b30209a30209b306a219c30209b30209c306a219d30" - "209c30209d306a219e30209d30209e306a219f30209e30209f306a21a030209f3020a0306a21a13020a03020a1306a" - "21a23020a13020a2306a21a33020a23020a3306a21a43020a33020a4306a21a53020a43020a5306a21a63020a53020" - "a6306a21a73020a63020a7306a21a83020a73020a8306a21a93020a83020a9306a21aa3020a93020aa306a21ab3020" - "aa3020ab306a21ac3020ab3020ac306a21ad3020ac3020ad306a21ae3020ad3020ae306a21af3020ae3020af306a21" - "b03020af3020b0306a21b13020b03020b1306a21b23020b13020b2306a21b33020b23020b3306a21b43020b33020b4" - "306a21b53020b43020b5306a21b63020b53020b6306a21b73020b63020b7306a21b83020b73020b8306a21b93020b8" - "3020b9306a21ba3020b93020ba306a21bb3020ba3020bb306a21bc3020bb3020bc306a21bd3020bc3020bd306a21be" - "3020bd3020be306a21bf3020be3020bf306a21c03020bf3020c0306a21c13020c03020c1306a21c23020c13020c230" - "6a21c33020c23020c3306a21c43020c33020c4306a21c53020c43020c5306a21c63020c53020c6306a21c73020c630" - "20c7306a21c83020c73020c8306a21c93020c83020c9306a21ca3020c93020ca306a21cb3020ca3020cb306a21cc30" - "20cb3020cc306a21cd3020cc3020cd306a21ce3020cd3020ce306a21cf3020ce3020cf306a21d03020cf3020d0306a" - "21d13020d03020d1306a21d23020d13020d2306a21d33020d23020d3306a21d43020d33020d4306a21d53020d43020" - "d5306a21d63020d53020d6306a21d73020d63020d7306a21d83020d73020d8306a21d93020d83020d9306a21da3020" - "d93020da306a21db3020da3020db306a21dc3020db3020dc306a21dd3020dc3020dd306a21de3020dd3020de306a21" - "df3020de3020df306a21e03020df3020e0306a21e13020e03020e1306a21e23020e13020e2306a21e33020e23020e3" - "306a21e43020e33020e4306a21e53020e43020e5306a21e63020e53020e6306a21e73020e63020e7306a21e83020e7" - "3020e8306a21e93020e83020e9306a21ea3020e93020ea306a21eb3020ea3020eb306a21ec3020eb3020ec306a21ed" - "3020ec3020ed306a21ee3020ed3020ee306a21ef3020ee3020ef306a21f03020ef3020f0306a21f13020f03020f130" - "6a21f23020f13020f2306a21f33020f23020f3306a21f43020f33020f4306a21f53020f43020f5306a21f63020f530" - "20f6306a21f73020f63020f7306a21f83020f73020f8306a21f93020f83020f9306a21fa3020f93020fa306a21fb30" - "20fa3020fb306a21fc3020fb3020fc306a21fd3020fc3020fd306a21fe3020fd3020fe306a21ff3020fe3020ff306a" - "21803120ff302080316a2181312080312081316a2182312081312082316a2183312082312083316a21843120833120" - "84316a2185312084312085316a2186312085312086316a2187312086312087316a2188312087312088316a21893120" - "88312089316a218a31208931208a316a218b31208a31208b316a218c31208b31208c316a218d31208c31208d316a21" - "8e31208d31208e316a218f31208e31208f316a219031208f312090316a2191312090312091316a2192312091312092" - "316a2193312092312093316a2194312093312094316a2195312094312095316a2196312095312096316a2197312096" - "312097316a2198312097312098316a2199312098312099316a219a31209931209a316a219b31209a31209b316a219c" - "31209b31209c316a219d31209c31209d316a219e31209d31209e316a219f31209e31209f316a21a031209f3120a031" - "6a21a13120a03120a1316a21a23120a13120a2316a21a33120a23120a3316a21a43120a33120a4316a21a53120a431" - "20a5316a21a63120a53120a6316a21a73120a63120a7316a21a83120a73120a8316a21a93120a83120a9316a21aa31" - "20a93120aa316a21ab3120aa3120ab316a21ac3120ab3120ac316a21ad3120ac3120ad316a21ae3120ad3120ae316a" - "21af3120ae3120af316a21b03120af3120b0316a21b13120b03120b1316a21b23120b13120b2316a21b33120b23120" - "b3316a21b43120b33120b4316a21b53120b43120b5316a21b63120b53120b6316a21b73120b63120b7316a21b83120" - "b73120b8316a21b93120b83120b9316a21ba3120b93120ba316a21bb3120ba3120bb316a21bc3120bb3120bc316a21" - "bd3120bc3120bd316a21be3120bd3120be316a21bf3120be3120bf316a21c03120bf3120c0316a21c13120c03120c1" - "316a21c23120c13120c2316a21c33120c23120c3316a21c43120c33120c4316a21c53120c43120c5316a21c63120c5" - "3120c6316a21c73120c63120c7316a21c83120c73120c8316a21c93120c83120c9316a21ca3120c93120ca316a21cb" - "3120ca3120cb316a21cc3120cb3120cc316a21cd3120cc3120cd316a21ce3120cd3120ce316a21cf3120ce3120cf31" - "6a21d03120cf3120d0316a21d13120d03120d1316a21d23120d13120d2316a21d33120d23120d3316a21d43120d331" - "20d4316a21d53120d43120d5316a21d63120d53120d6316a21d73120d63120d7316a21d83120d73120d8316a21d931" - "20d83120d9316a21da3120d93120da316a21db3120da3120db316a21dc3120db3120dc316a21dd3120dc3120dd316a" - "21de3120dd3120de316a21df3120de3120df316a21e03120df3120e0316a21e13120e03120e1316a21e23120e13120" - "e2316a21e33120e23120e3316a21e43120e33120e4316a21e53120e43120e5316a21e63120e53120e6316a21e73120" - "e63120e7316a21e83120e73120e8316a21e93120e83120e9316a21ea3120e93120ea316a21eb3120ea3120eb316a21" - "ec3120eb3120ec316a21ed3120ec3120ed316a21ee3120ed3120ee316a21ef3120ee3120ef316a21f03120ef3120f0" - "316a21f13120f03120f1316a21f23120f13120f2316a21f33120f23120f3316a21f43120f33120f4316a21f53120f4" - "3120f5316a21f63120f53120f6316a21f73120f63120f7316a21f83120f73120f8316a21f93120f83120f9316a21fa" - "3120f93120fa316a21fb3120fa3120fb316a21fc3120fb3120fc316a21fd3120fc3120fd316a21fe3120fd3120fe31" - "6a21ff3120fe3120ff316a21803220ff312080326a2181322080322081326a2182322081322082326a218332208232" - "2083326a2184322083322084326a2185322084322085326a2186322085322086326a2187322086322087326a218832" - "2087322088326a2189322088322089326a218a32208932208a326a218b32208a32208b326a218c32208b32208c326a" - "218d32208c32208d326a218e32208d32208e326a218f32208e32208f326a219032208f322090326a21913220903220" - "91326a2192322091322092326a2193322092322093326a2194322093322094326a2195322094322095326a21963220" - "95322096326a2197322096322097326a2198322097322098326a2199322098322099326a219a32209932209a326a21" - "9b32209a32209b326a219c32209b32209c326a219d32209c32209d326a219e32209d32209e326a219f32209e32209f" - "326a21a032209f3220a0326a21a13220a03220a1326a21a23220a13220a2326a21a33220a23220a3326a21a43220a3" - "3220a4326a21a53220a43220a5326a21a63220a53220a6326a21a73220a63220a7326a21a83220a73220a8326a21a9" - "3220a83220a9326a21aa3220a93220aa326a21ab3220aa3220ab326a21ac3220ab3220ac326a21ad3220ac3220ad32" - "6a21ae3220ad3220ae326a21af3220ae3220af326a21b03220af3220b0326a21b13220b03220b1326a21b23220b132" - "20b2326a21b33220b23220b3326a21b43220b33220b4326a21b53220b43220b5326a21b63220b53220b6326a21b732" - "20b63220b7326a21b83220b73220b8326a21b93220b83220b9326a21ba3220b93220ba326a21bb3220ba3220bb326a" - "21bc3220bb3220bc326a21bd3220bc3220bd326a21be3220bd3220be326a21bf3220be3220bf326a21c03220bf3220" - "c0326a21c13220c03220c1326a21c23220c13220c2326a21c33220c23220c3326a21c43220c33220c4326a21c53220" - "c43220c5326a21c63220c53220c6326a21c73220c63220c7326a21c83220c73220c8326a21c93220c83220c9326a21" - "ca3220c93220ca326a21cb3220ca3220cb326a21cc3220cb3220cc326a21cd3220cc3220cd326a21ce3220cd3220ce" - "326a21cf3220ce3220cf326a21d03220cf3220d0326a21d13220d03220d1326a21d23220d13220d2326a21d33220d2" - "3220d3326a21d43220d33220d4326a21d53220d43220d5326a21d63220d53220d6326a21d73220d63220d7326a21d8" - "3220d73220d8326a21d93220d83220d9326a21da3220d93220da326a21db3220da3220db326a21dc3220db3220dc32" - "6a21dd3220dc3220dd326a21de3220dd3220de326a21df3220de3220df326a21e03220df3220e0326a21e13220e032" - "20e1326a21e23220e13220e2326a21e33220e23220e3326a21e43220e33220e4326a21e53220e43220e5326a21e632" - "20e53220e6326a21e73220e63220e7326a21e83220e73220e8326a21e93220e83220e9326a21ea3220e93220ea326a" - "21eb3220ea3220eb326a21ec3220eb3220ec326a21ed3220ec3220ed326a21ee3220ed3220ee326a21ef3220ee3220" - "ef326a21f03220ef3220f0326a21f13220f03220f1326a21f23220f13220f2326a21f33220f23220f3326a21f43220" - "f33220f4326a21f53220f43220f5326a21f63220f53220f6326a21f73220f63220f7326a21f83220f73220f8326a21" - "f93220f83220f9326a21fa3220f93220fa326a21fb3220fa3220fb326a21fc3220fb3220fc326a21fd3220fc3220fd" - "326a21fe3220fd3220fe326a21ff3220fe3220ff326a21803320ff322080336a2181332080332081336a2182332081" - "332082336a2183332082332083336a2184332083332084336a2185332084332085336a2186332085332086336a2187" - "332086332087336a2188332087332088336a2189332088332089336a218a33208933208a336a218b33208a33208b33" - "6a218c33208b33208c336a218d33208c33208d336a218e33208d33208e336a218f33208e33208f336a219033208f33" - "2090336a2191332090332091336a2192332091332092336a2193332092332093336a2194332093332094336a219533" - "2094332095336a2196332095332096336a2197332096332097336a2198332097332098336a2199332098332099336a" - "219a33209933209a336a219b33209a33209b336a219c33209b33209c336a219d33209c33209d336a219e33209d3320" - "9e336a219f33209e33209f336a21a033209f3320a0336a21a13320a03320a1336a21a23320a13320a2336a21a33320" - "a23320a3336a21a43320a33320a4336a21a53320a43320a5336a21a63320a53320a6336a21a73320a63320a7336a21" - "a83320a73320a8336a21a93320a83320a9336a21aa3320a93320aa336a21ab3320aa3320ab336a21ac3320ab3320ac" - "336a21ad3320ac3320ad336a21ae3320ad3320ae336a21af3320ae3320af336a21b03320af3320b0336a21b13320b0" - "3320b1336a21b23320b13320b2336a21b33320b23320b3336a21b43320b33320b4336a21b53320b43320b5336a21b6" - "3320b53320b6336a21b73320b63320b7336a21b83320b73320b8336a21b93320b83320b9336a21ba3320b93320ba33" - "6a21bb3320ba3320bb336a21bc3320bb3320bc336a21bd3320bc3320bd336a21be3320bd3320be336a21bf3320be33" - "20bf336a21c03320bf3320c0336a21c13320c03320c1336a21c23320c13320c2336a21c33320c23320c3336a21c433" - "20c33320c4336a21c53320c43320c5336a21c63320c53320c6336a21c73320c63320c7336a21c83320c73320c8336a" - "21c93320c83320c9336a21ca3320c93320ca336a21cb3320ca3320cb336a21cc3320cb3320cc336a21cd3320cc3320" - "cd336a21ce3320cd3320ce336a21cf3320ce3320cf336a21d03320cf3320d0336a21d13320d03320d1336a21d23320" - "d13320d2336a21d33320d23320d3336a21d43320d33320d4336a21d53320d43320d5336a21d63320d53320d6336a21" - "d73320d63320d7336a21d83320d73320d8336a21d93320d83320d9336a21da3320d93320da336a21db3320da3320db" - "336a21dc3320db3320dc336a21dd3320dc3320dd336a21de3320dd3320de336a21df3320de3320df336a21e03320df" - "3320e0336a21e13320e03320e1336a21e23320e13320e2336a21e33320e23320e3336a21e43320e33320e4336a21e5" - "3320e43320e5336a21e63320e53320e6336a21e73320e63320e7336a21e83320e73320e8336a21e93320e83320e933" - "6a21ea3320e93320ea336a21eb3320ea3320eb336a21ec3320eb3320ec336a21ed3320ec3320ed336a21ee3320ed33" - "20ee336a21ef3320ee3320ef336a21f03320ef3320f0336a21f13320f03320f1336a21f23320f13320f2336a21f333" - "20f23320f3336a21f43320f33320f4336a21f53320f43320f5336a21f63320f53320f6336a21f73320f63320f7336a" - "21f83320f73320f8336a21f93320f83320f9336a21fa3320f93320fa336a21fb3320fa3320fb336a21fc3320fb3320" - "fc336a21fd3320fc3320fd336a21fe3320fd3320fe336a21ff3320fe3320ff336a21803420ff332080346a21813420" - "80342081346a2182342081342082346a2183342082342083346a2184342083342084346a2185342084342085346a21" - "86342085342086346a2187342086342087346a2188342087342088346a2189342088342089346a218a34208934208a" - "346a218b34208a34208b346a218c34208b34208c346a218d34208c34208d346a218e34208d34208e346a218f34208e" - "34208f346a219034208f342090346a2191342090342091346a2192342091342092346a2193342092342093346a2194" - "342093342094346a2195342094342095346a2196342095342096346a2197342096342097346a219834209734209834" - "6a2199342098342099346a219a34209934209a346a219b34209a34209b346a219c34209b34209c346a219d34209c34" - "209d346a219e34209d34209e346a219f34209e34209f346a21a034209f3420a0346a21a13420a03420a1346a21a234" - "20a13420a2346a21a33420a23420a3346a21a43420a33420a4346a21a53420a43420a5346a21a63420a53420a6346a" - "21a73420a63420a7346a21a83420a73420a8346a21a93420a83420a9346a21aa3420a93420aa346a21ab3420aa3420" - "ab346a21ac3420ab3420ac346a21ad3420ac3420ad346a21ae3420ad3420ae346a21af3420ae3420af346a21b03420" - "af3420b0346a21b13420b03420b1346a21b23420b13420b2346a21b33420b23420b3346a21b43420b33420b4346a21" - "b53420b43420b5346a21b63420b53420b6346a21b73420b63420b7346a21b83420b73420b8346a21b93420b83420b9" - "346a21ba3420b93420ba346a21bb3420ba3420bb346a21bc3420bb3420bc346a21bd3420bc3420bd346a21be3420bd" - "3420be346a21bf3420be3420bf346a21c03420bf3420c0346a21c13420c03420c1346a21c23420c13420c2346a21c3" - "3420c23420c3346a21c43420c33420c4346a21c53420c43420c5346a21c63420c53420c6346a21c73420c63420c734" - "6a21c83420c73420c8346a21c93420c83420c9346a21ca3420c93420ca346a21cb3420ca3420cb346a21cc3420cb34" - "20cc346a21cd3420cc3420cd346a21ce3420cd3420ce346a21cf3420ce3420cf346a21d03420cf3420d0346a21d134" - "20d03420d1346a21d23420d13420d2346a21d33420d23420d3346a21d43420d33420d4346a21d53420d43420d5346a" - "21d63420d53420d6346a21d73420d63420d7346a21d83420d73420d8346a21d93420d83420d9346a21da3420d93420" - "da346a21db3420da3420db346a21dc3420db3420dc346a21dd3420dc3420dd346a21de3420dd3420de346a21df3420" - "de3420df346a21e03420df3420e0346a21e13420e03420e1346a21e23420e13420e2346a21e33420e23420e3346a21" - "e43420e33420e4346a21e53420e43420e5346a21e63420e53420e6346a21e73420e63420e7346a21e83420e73420e8" - "346a21e93420e83420e9346a21ea3420e93420ea346a21eb3420ea3420eb346a21ec3420eb3420ec346a21ed3420ec" - "3420ed346a21ee3420ed3420ee346a21ef3420ee3420ef346a21f03420ef3420f0346a21f13420f03420f1346a21f2" - "3420f13420f2346a21f33420f23420f3346a21f43420f33420f4346a21f53420f43420f5346a21f63420f53420f634" - "6a21f73420f63420f7346a21f83420f73420f8346a21f93420f83420f9346a21fa3420f93420fa346a21fb3420fa34" - "20fb346a21fc3420fb3420fc346a21fd3420fc3420fd346a21fe3420fd3420fe346a21ff3420fe3420ff346a218035" - "20ff342080356a2181352080352081356a2182352081352082356a2183352082352083356a2184352083352084356a" - "2185352084352085356a2186352085352086356a2187352086352087356a2188352087352088356a21893520883520" - "89356a218a35208935208a356a218b35208a35208b356a218c35208b35208c356a218d35208c35208d356a218e3520" - "8d35208e356a218f35208e35208f356a219035208f352090356a2191352090352091356a2192352091352092356a21" - "93352092352093356a2194352093352094356a2195352094352095356a2196352095352096356a2197352096352097" - "356a2198352097352098356a2199352098352099356a219a35209935209a356a219b35209a35209b356a219c35209b" - "35209c356a219d35209c35209d356a219e35209d35209e356a219f35209e35209f356a21a035209f3520a0356a21a1" - "3520a03520a1356a21a23520a13520a2356a21a33520a23520a3356a21a43520a33520a4356a21a53520a43520a535" - "6a21a63520a53520a6356a21a73520a63520a7356a21a83520a73520a8356a21a93520a83520a9356a21aa3520a935" - "20aa356a21ab3520aa3520ab356a21ac3520ab3520ac356a21ad3520ac3520ad356a21ae3520ad3520ae356a21af35" - "20ae3520af356a21b03520af3520b0356a21b13520b03520b1356a21b23520b13520b2356a21b33520b23520b3356a" - "21b43520b33520b4356a21b53520b43520b5356a21b63520b53520b6356a21b73520b63520b7356a21b83520b73520" - "b8356a21b93520b83520b9356a21ba3520b93520ba356a21bb3520ba3520bb356a21bc3520bb3520bc356a21bd3520" - "bc3520bd356a21be3520bd3520be356a21bf3520be3520bf356a21c03520bf3520c0356a21c13520c03520c1356a21" - "c23520c13520c2356a21c33520c23520c3356a21c43520c33520c4356a21c53520c43520c5356a21c63520c53520c6" - "356a21c73520c63520c7356a21c83520c73520c8356a21c93520c83520c9356a21ca3520c93520ca356a21cb3520ca" - "3520cb356a21cc3520cb3520cc356a21cd3520cc3520cd356a21ce3520cd3520ce356a21cf3520ce3520cf356a21d0" - "3520cf3520d0356a21d13520d03520d1356a21d23520d13520d2356a21d33520d23520d3356a21d43520d33520d435" - "6a21d53520d43520d5356a21d63520d53520d6356a21d73520d63520d7356a21d83520d73520d8356a21d93520d835" - "20d9356a21da3520d93520da356a21db3520da3520db356a21dc3520db3520dc356a21dd3520dc3520dd356a21de35" - "20dd3520de356a21df3520de3520df356a21e03520df3520e0356a21e13520e03520e1356a21e23520e13520e2356a" - "21e33520e23520e3356a21e43520e33520e4356a21e53520e43520e5356a21e63520e53520e6356a21e73520e63520" - "e7356a21e83520e73520e8356a21e93520e83520e9356a21ea3520e93520ea356a21eb3520ea3520eb356a21ec3520" - "eb3520ec356a21ed3520ec3520ed356a21ee3520ed3520ee356a21ef3520ee3520ef356a21f03520ef3520f0356a21" - "f13520f03520f1356a21f23520f13520f2356a21f33520f23520f3356a21f43520f33520f4356a21f53520f43520f5" - "356a21f63520f53520f6356a21f73520f63520f7356a21f83520f73520f8356a21f93520f83520f9356a21fa3520f9" - "3520fa356a21fb3520fa3520fb356a21fc3520fb3520fc356a21fd3520fc3520fd356a21fe3520fd3520fe356a21ff" - "3520fe3520ff356a21803620ff352080366a2181362080362081366a2182362081362082366a218336208236208336" - "6a2184362083362084366a2185362084362085366a2186362085362086366a2187362086362087366a218836208736" - "2088366a2189362088362089366a218a36208936208a366a218b36208a36208b366a218c36208b36208c366a218d36" - "208c36208d366a218e36208d36208e366a218f36208e36208f366a219036208f362090366a2191362090362091366a" - "2192362091362092366a2193362092362093366a2194362093362094366a2195362094362095366a21963620953620" - "96366a2197362096362097366a2198362097362098366a2199362098362099366a219a36209936209a366a219b3620" - "9a36209b366a219c36209b36209c366a219d36209c36209d366a219e36209d36209e366a219f36209e36209f366a21" - "a036209f3620a0366a21a13620a03620a1366a21a23620a13620a2366a21a33620a23620a3366a21a43620a33620a4" - "366a21a53620a43620a5366a21a63620a53620a6366a21a73620a63620a7366a21a83620a73620a8366a21a93620a8" - "3620a9366a21aa3620a93620aa366a21ab3620aa3620ab366a21ac3620ab3620ac366a21ad3620ac3620ad366a21ae" - "3620ad3620ae366a21af3620ae3620af366a21b03620af3620b0366a21b13620b03620b1366a21b23620b13620b236" - "6a21b33620b23620b3366a21b43620b33620b4366a21b53620b43620b5366a21b63620b53620b6366a21b73620b636" - "20b7366a21b83620b73620b8366a21b93620b83620b9366a21ba3620b93620ba366a21bb3620ba3620bb366a21bc36" - "20bb3620bc366a21bd3620bc3620bd366a21be3620bd3620be366a21bf3620be3620bf366a21c03620bf3620c0366a" - "21c13620c03620c1366a21c23620c13620c2366a21c33620c23620c3366a21c43620c33620c4366a21c53620c43620" - "c5366a21c63620c53620c6366a21c73620c63620c7366a21c83620c73620c8366a21c93620c83620c9366a21ca3620" - "c93620ca366a21cb3620ca3620cb366a21cc3620cb3620cc366a21cd3620cc3620cd366a21ce3620cd3620ce366a21" - "cf3620ce3620cf366a21d03620cf3620d0366a21d13620d03620d1366a21d23620d13620d2366a21d33620d23620d3" - "366a21d43620d33620d4366a21d53620d43620d5366a21d63620d53620d6366a21d73620d63620d7366a21d83620d7" - "3620d8366a21d93620d83620d9366a21da3620d93620da366a21db3620da3620db366a21dc3620db3620dc366a21dd" - "3620dc3620dd366a21de3620dd3620de366a21df3620de3620df366a21e03620df3620e0366a21e13620e03620e136" - "6a21e23620e13620e2366a21e33620e23620e3366a21e43620e33620e4366a21e53620e43620e5366a21e63620e536" - "20e6366a21e73620e63620e7366a21e83620e73620e8366a21e93620e83620e9366a21ea3620e93620ea366a21eb36" - "20ea3620eb366a21ec3620eb3620ec366a21ed3620ec3620ed366a21ee3620ed3620ee366a21ef3620ee3620ef366a" - "21f03620ef3620f0366a21f13620f03620f1366a21f23620f13620f2366a21f33620f23620f3366a21f43620f33620" - "f4366a21f53620f43620f5366a21f63620f53620f6366a21f73620f63620f7366a21f83620f73620f8366a21f93620" - "f83620f9366a21fa3620f93620fa366a21fb3620fa3620fb366a21fc3620fb3620fc366a21fd3620fc3620fd366a21" - "fe3620fd3620fe366a21ff3620fe3620ff366a21803720ff362080376a2181372080372081376a2182372081372082" - "376a2183372082372083376a2184372083372084376a2185372084372085376a2186372085372086376a2187372086" - "372087376a2188372087372088376a2189372088372089376a218a37208937208a376a218b37208a37208b376a218c" - "37208b37208c376a218d37208c37208d376a218e37208d37208e376a218f37208e37208f376a219037208f37209037" - "6a2191372090372091376a2192372091372092376a2193372092372093376a2194372093372094376a219537209437" - "2095376a2196372095372096376a2197372096372097376a2198372097372098376a2199372098372099376a219a37" - "209937209a376a219b37209a37209b376a219c37209b37209c376a219d37209c37209d376a219e37209d37209e376a" - "219f37209e37209f376a21a037209f3720a0376a21a13720a03720a1376a21a23720a13720a2376a21a33720a23720" - "a3376a21a43720a33720a4376a21a53720a43720a5376a21a63720a53720a6376a21a73720a63720a7376a21a83720" - "a73720a8376a21a93720a83720a9376a21aa3720a93720aa376a21ab3720aa3720ab376a21ac3720ab3720ac376a21" - "ad3720ac3720ad376a21ae3720ad3720ae376a21af3720ae3720af376a21b03720af3720b0376a21b13720b03720b1" - "376a21b23720b13720b2376a21b33720b23720b3376a21b43720b33720b4376a21b53720b43720b5376a21b63720b5" - "3720b6376a21b73720b63720b7376a21b83720b73720b8376a21b93720b83720b9376a21ba3720b93720ba376a21bb" - "3720ba3720bb376a21bc3720bb3720bc376a21bd3720bc3720bd376a21be3720bd3720be376a21bf3720be3720bf37" - "6a21c03720bf3720c0376a21c13720c03720c1376a21c23720c13720c2376a21c33720c23720c3376a21c43720c337" - "20c4376a21c53720c43720c5376a21c63720c53720c6376a21c73720c63720c7376a21c83720c73720c8376a21c937" - "20c83720c9376a21ca3720c93720ca376a21cb3720ca3720cb376a21cc3720cb3720cc376a21cd3720cc3720cd376a" - "21ce3720cd3720ce376a21cf3720ce3720cf376a21d03720cf3720d0376a21d13720d03720d1376a21d23720d13720" - "d2376a21d33720d23720d3376a21d43720d33720d4376a21d53720d43720d5376a21d63720d53720d6376a21d73720" - "d63720d7376a21d83720d73720d8376a21d93720d83720d9376a21da3720d93720da376a21db3720da3720db376a21" - "dc3720db3720dc376a21dd3720dc3720dd376a21de3720dd3720de376a21df3720de3720df376a21e03720df3720e0" - "376a21e13720e03720e1376a21e23720e13720e2376a21e33720e23720e3376a21e43720e33720e4376a21e53720e4" - "3720e5376a21e63720e53720e6376a21e73720e63720e7376a21e83720e73720e8376a21e93720e83720e9376a21ea" - "3720e93720ea376a21eb3720ea3720eb376a21ec3720eb3720ec376a21ed3720ec3720ed376a21ee3720ed3720ee37" - "6a21ef3720ee3720ef376a21f03720ef3720f0376a21f13720f03720f1376a21f23720f13720f2376a21f33720f237" - "20f3376a21f43720f33720f4376a21f53720f43720f5376a21f63720f53720f6376a21f73720f63720f7376a21f837" - "20f73720f8376a21f93720f83720f9376a21fa3720f93720fa376a21fb3720fa3720fb376a21fc3720fb3720fc376a" - "21fd3720fc3720fd376a21fe3720fd3720fe376a21ff3720fe3720ff376a21803820ff372080386a21813820803820" - "81386a2182382081382082386a2183382082382083386a2184382083382084386a2185382084382085386a21863820" - "85382086386a2187382086382087386a2188382087382088386a2189382088382089386a218a38208938208a386a21" - "8b38208a38208b386a218c38208b38208c386a218d38208c38208d386a218e38208d38208e386a218f38208e38208f" - "386a219038208f382090386a2191382090382091386a2192382091382092386a2193382092382093386a2194382093" - "382094386a2195382094382095386a2196382095382096386a2197382096382097386a2198382097382098386a2199" - "382098382099386a219a38209938209a386a219b38209a38209b386a219c38209b38209c386a219d38209c38209d38" - "6a219e38209d38209e386a219f38209e38209f386a21a038209f3820a0386a21a13820a03820a1386a21a23820a138" - "20a2386a21a33820a23820a3386a21a43820a33820a4386a21a53820a43820a5386a21a63820a53820a6386a21a738" - "20a63820a7386a21a83820a73820a8386a21a93820a83820a9386a21aa3820a93820aa386a21ab3820aa3820ab386a" - "21ac3820ab3820ac386a21ad3820ac3820ad386a21ae3820ad3820ae386a21af3820ae3820af386a21b03820af3820" - "b0386a21b13820b03820b1386a21b23820b13820b2386a21b33820b23820b3386a21b43820b33820b4386a21b53820" - "b43820b5386a21b63820b53820b6386a21b73820b63820b7386a21b83820b73820b8386a21b93820b83820b9386a21" - "ba3820b93820ba386a21bb3820ba3820bb386a21bc3820bb3820bc386a21bd3820bc3820bd386a21be3820bd3820be" - "386a21bf3820be3820bf386a21c03820bf3820c0386a21c13820c03820c1386a21c23820c13820c2386a21c33820c2" - "3820c3386a21c43820c33820c4386a21c53820c43820c5386a21c63820c53820c6386a21c73820c63820c7386a21c8" - "3820c73820c8386a21c93820c83820c9386a21ca3820c93820ca386a21cb3820ca3820cb386a21cc3820cb3820cc38" - "6a21cd3820cc3820cd386a21ce3820cd3820ce386a21cf3820ce3820cf386a21d03820cf3820d0386a21d13820d038" - "20d1386a21d23820d13820d2386a21d33820d23820d3386a21d43820d33820d4386a21d53820d43820d5386a21d638" - "20d53820d6386a21d73820d63820d7386a21d83820d73820d8386a21d93820d83820d9386a21da3820d93820da386a" - "21db3820da3820db386a21dc3820db3820dc386a21dd3820dc3820dd386a21de3820dd3820de386a21df3820de3820" - "df386a21e03820df3820e0386a21e13820e03820e1386a21e23820e13820e2386a21e33820e23820e3386a21e43820" - "e33820e4386a21e53820e43820e5386a21e63820e53820e6386a21e73820e63820e7386a21e83820e73820e8386a21" - "e93820e83820e9386a21ea3820e93820ea386a21eb3820ea3820eb386a21ec3820eb3820ec386a21ed3820ec3820ed" - "386a21ee3820ed3820ee386a21ef3820ee3820ef386a21f03820ef3820f0386a21f13820f03820f1386a21f23820f1" - "3820f2386a21f33820f23820f3386a21f43820f33820f4386a21f53820f43820f5386a21f63820f53820f6386a21f7" - "3820f63820f7386a21f83820f73820f8386a21f93820f83820f9386a21fa3820f93820fa386a21fb3820fa3820fb38" - "6a21fc3820fb3820fc386a21fd3820fc3820fd386a21fe3820fd3820fe386a21ff3820fe3820ff386a21803920ff38" - "2080396a2181392080392081396a2182392081392082396a2183392082392083396a2184392083392084396a218539" - "2084392085396a2186392085392086396a2187392086392087396a2188392087392088396a2189392088392089396a" - "218a39208939208a396a218b39208a39208b396a218c39208b39208c396a218d39208c39208d396a218e39208d3920" - "8e396a218f39208e39208f396a219039208f392090396a2191392090392091396a2192392091392092396a21933920" - "92392093396a2194392093392094396a2195392094392095396a2196392095392096396a2197392096392097396a21" - "98392097392098396a2199392098392099396a219a39209939209a396a219b39209a39209b396a219c39209b39209c" - "396a219d39209c39209d396a219e39209d39209e396a219f39209e39209f396a21a039209f3920a0396a21a13920a0" - "3920a1396a21a23920a13920a2396a21a33920a23920a3396a21a43920a33920a4396a21a53920a43920a5396a21a6" - "3920a53920a6396a21a73920a63920a7396a21a83920a73920a8396a21a93920a83920a9396a21aa3920a93920aa39" - "6a21ab3920aa3920ab396a21ac3920ab3920ac396a21ad3920ac3920ad396a21ae3920ad3920ae396a21af3920ae39" - "20af396a21b03920af3920b0396a21b13920b03920b1396a21b23920b13920b2396a21b33920b23920b3396a21b439" - "20b33920b4396a21b53920b43920b5396a21b63920b53920b6396a21b73920b63920b7396a21b83920b73920b8396a" - "21b93920b83920b9396a21ba3920b93920ba396a21bb3920ba3920bb396a21bc3920bb3920bc396a21bd3920bc3920" - "bd396a21be3920bd3920be396a21bf3920be3920bf396a21c03920bf3920c0396a21c13920c03920c1396a21c23920" - "c13920c2396a21c33920c23920c3396a21c43920c33920c4396a21c53920c43920c5396a21c63920c53920c6396a21" - "c73920c63920c7396a21c83920c73920c8396a21c93920c83920c9396a21ca3920c93920ca396a21cb3920ca3920cb" - "396a21cc3920cb3920cc396a21cd3920cc3920cd396a21ce3920cd3920ce396a21cf3920ce3920cf396a21d03920cf" - "3920d0396a21d13920d03920d1396a21d23920d13920d2396a21d33920d23920d3396a21d43920d33920d4396a21d5" - "3920d43920d5396a21d63920d53920d6396a21d73920d63920d7396a21d83920d73920d8396a21d93920d83920d939" - "6a21da3920d93920da396a21db3920da3920db396a21dc3920db3920dc396a21dd3920dc3920dd396a21de3920dd39" - "20de396a21df3920de3920df396a21e03920df3920e0396a21e13920e03920e1396a21e23920e13920e2396a21e339" - "20e23920e3396a21e43920e33920e4396a21e53920e43920e5396a21e63920e53920e6396a21e73920e63920e7396a" - "21e83920e73920e8396a21e93920e83920e9396a21ea3920e93920ea396a21eb3920ea3920eb396a21ec3920eb3920" - "ec396a21ed3920ec3920ed396a21ee3920ed3920ee396a21ef3920ee3920ef396a21f03920ef3920f0396a21f13920" - "f03920f1396a21f23920f13920f2396a21f33920f23920f3396a21f43920f33920f4396a21f53920f43920f5396a21" - "f63920f53920f6396a21f73920f63920f7396a21f83920f73920f8396a21f93920f83920f9396a21fa3920f93920fa" - "396a21fb3920fa3920fb396a21fc3920fb3920fc396a21fd3920fc3920fd396a21fe3920fd3920fe396a21ff3920fe" - "3920ff396a21803a20ff3920803a6a21813a20803a20813a6a21823a20813a20823a6a21833a20823a20833a6a2184" - "3a20833a20843a6a21853a20843a20853a6a21863a20853a20863a6a21873a20863a20873a6a21883a20873a20883a" - "6a21893a20883a20893a6a218a3a20893a208a3a6a218b3a208a3a208b3a6a218c3a208b3a208c3a6a218d3a208c3a" - "208d3a6a218e3a208d3a208e3a6a218f3a208e3a208f3a6a21903a208f3a20903a6a21913a20903a20913a6a21923a" - "20913a20923a6a21933a20923a20933a6a21943a20933a20943a6a21953a20943a20953a6a21963a20953a20963a6a" - "21973a20963a20973a6a21983a20973a20983a6a21993a20983a20993a6a219a3a20993a209a3a6a219b3a209a3a20" - "9b3a6a219c3a209b3a209c3a6a219d3a209c3a209d3a6a219e3a209d3a209e3a6a219f3a209e3a209f3a6a21a03a20" - "9f3a20a03a6a21a13a20a03a20a13a6a21a23a20a13a20a23a6a21a33a20a23a20a33a6a21a43a20a33a20a43a6a21" - "a53a20a43a20a53a6a21a63a20a53a20a63a6a21a73a20a63a20a73a6a21a83a20a73a20a83a6a21a93a20a83a20a9" - "3a6a21aa3a20a93a20aa3a6a21ab3a20aa3a20ab3a6a21ac3a20ab3a20ac3a6a21ad3a20ac3a20ad3a6a21ae3a20ad" - "3a20ae3a6a21af3a20ae3a20af3a6a21b03a20af3a20b03a6a21b13a20b03a20b13a6a21b23a20b13a20b23a6a21b3" - "3a20b23a20b33a6a21b43a20b33a20b43a6a21b53a20b43a20b53a6a21b63a20b53a20b63a6a21b73a20b63a20b73a" - "6a21b83a20b73a20b83a6a21b93a20b83a20b93a6a21ba3a20b93a20ba3a6a21bb3a20ba3a20bb3a6a21bc3a20bb3a" - "20bc3a6a21bd3a20bc3a20bd3a6a21be3a20bd3a20be3a6a21bf3a20be3a20bf3a6a21c03a20bf3a20c03a6a21c13a" - "20c03a20c13a6a21c23a20c13a20c23a6a21c33a20c23a20c33a6a21c43a20c33a20c43a6a21c53a20c43a20c53a6a" - "21c63a20c53a20c63a6a21c73a20c63a20c73a6a21c83a20c73a20c83a6a21c93a20c83a20c93a6a21ca3a20c93a20" - "ca3a6a21cb3a20ca3a20cb3a6a21cc3a20cb3a20cc3a6a21cd3a20cc3a20cd3a6a21ce3a20cd3a20ce3a6a21cf3a20" - "ce3a20cf3a6a21d03a20cf3a20d03a6a21d13a20d03a20d13a6a21d23a20d13a20d23a6a21d33a20d23a20d33a6a21" - "d43a20d33a20d43a6a21d53a20d43a20d53a6a21d63a20d53a20d63a6a21d73a20d63a20d73a6a21d83a20d73a20d8" - "3a6a21d93a20d83a20d93a6a21da3a20d93a20da3a6a21db3a20da3a20db3a6a21dc3a20db3a20dc3a6a21dd3a20dc" - "3a20dd3a6a21de3a20dd3a20de3a6a21df3a20de3a20df3a6a21e03a20df3a20e03a6a21e13a20e03a20e13a6a21e2" - "3a20e13a20e23a6a21e33a20e23a20e33a6a21e43a20e33a20e43a6a21e53a20e43a20e53a6a21e63a20e53a20e63a" - "6a21e73a20e63a20e73a6a21e83a20e73a20e83a6a21e93a20e83a20e93a6a21ea3a20e93a20ea3a6a21eb3a20ea3a" - "20eb3a6a21ec3a20eb3a20ec3a6a21ed3a20ec3a20ed3a6a21ee3a20ed3a20ee3a6a21ef3a20ee3a20ef3a6a21f03a" - "20ef3a20f03a6a21f13a20f03a20f13a6a21f23a20f13a20f23a6a21f33a20f23a20f33a6a21f43a20f33a20f43a6a" - "21f53a20f43a20f53a6a21f63a20f53a20f63a6a21f73a20f63a20f73a6a21f83a20f73a20f83a6a21f93a20f83a20" - "f93a6a21fa3a20f93a20fa3a6a21fb3a20fa3a20fb3a6a21fc3a20fb3a20fc3a6a21fd3a20fc3a20fd3a6a21fe3a20" - "fd3a20fe3a6a21ff3a20fe3a20ff3a6a21803b20ff3a20803b6a21813b20803b20813b6a21823b20813b20823b6a21" - "833b20823b20833b6a21843b20833b20843b6a21853b20843b20853b6a21863b20853b20863b6a21873b20863b2087" - "3b6a21883b20873b20883b6a21893b20883b20893b6a218a3b20893b208a3b6a218b3b208a3b208b3b6a218c3b208b" - "3b208c3b6a218d3b208c3b208d3b6a218e3b208d3b208e3b6a218f3b208e3b208f3b6a21903b208f3b20903b6a2191" - "3b20903b20913b6a21923b20913b20923b6a21933b20923b20933b6a21943b20933b20943b6a21953b20943b20953b" - "6a21963b20953b20963b6a21973b20963b20973b6a21983b20973b20983b6a21993b20983b20993b6a219a3b20993b" - "209a3b6a219b3b209a3b209b3b6a219c3b209b3b209c3b6a219d3b209c3b209d3b6a219e3b209d3b209e3b6a219f3b" - "209e3b209f3b6a21a03b209f3b20a03b6a21a13b20a03b20a13b6a21a23b20a13b20a23b6a21a33b20a23b20a33b6a" - "21a43b20a33b20a43b6a21a53b20a43b20a53b6a21a63b20a53b20a63b6a21a73b20a63b20a73b6a21a83b20a73b20" - "a83b6a21a93b20a83b20a93b6a21aa3b20a93b20aa3b6a21ab3b20aa3b20ab3b6a21ac3b20ab3b20ac3b6a21ad3b20" - "ac3b20ad3b6a21ae3b20ad3b20ae3b6a21af3b20ae3b20af3b6a21b03b20af3b20b03b6a21b13b20b03b20b13b6a21" - "b23b20b13b20b23b6a21b33b20b23b20b33b6a21b43b20b33b20b43b6a21b53b20b43b20b53b6a21b63b20b53b20b6" - "3b6a21b73b20b63b20b73b6a21b83b20b73b20b83b6a21b93b20b83b20b93b6a21ba3b20b93b20ba3b6a21bb3b20ba" - "3b20bb3b6a21bc3b20bb3b20bc3b6a21bd3b20bc3b20bd3b6a21be3b20bd3b20be3b6a21bf3b20be3b20bf3b6a21c0" - "3b20bf3b20c03b6a21c13b20c03b20c13b6a21c23b20c13b20c23b6a21c33b20c23b20c33b6a21c43b20c33b20c43b" - "6a21c53b20c43b20c53b6a21c63b20c53b20c63b6a21c73b20c63b20c73b6a21c83b20c73b20c83b6a21c93b20c83b" - "20c93b6a21ca3b20c93b20ca3b6a21cb3b20ca3b20cb3b6a21cc3b20cb3b20cc3b6a21cd3b20cc3b20cd3b6a21ce3b" - "20cd3b20ce3b6a21cf3b20ce3b20cf3b6a21d03b20cf3b20d03b6a21d13b20d03b20d13b6a21d23b20d13b20d23b6a" - "21d33b20d23b20d33b6a21d43b20d33b20d43b6a21d53b20d43b20d53b6a21d63b20d53b20d63b6a21d73b20d63b20" - "d73b6a21d83b20d73b20d83b6a21d93b20d83b20d93b6a21da3b20d93b20da3b6a21db3b20da3b20db3b6a21dc3b20" - "db3b20dc3b6a21dd3b20dc3b20dd3b6a21de3b20dd3b20de3b6a21df3b20de3b20df3b6a21e03b20df3b20e03b6a21" - "e13b20e03b20e13b6a21e23b20e13b20e23b6a21e33b20e23b20e33b6a21e43b20e33b20e43b6a21e53b20e43b20e5" - "3b6a21e63b20e53b20e63b6a21e73b20e63b20e73b6a21e83b20e73b20e83b6a21e93b20e83b20e93b6a21ea3b20e9" - "3b20ea3b6a21eb3b20ea3b20eb3b6a21ec3b20eb3b20ec3b6a21ed3b20ec3b20ed3b6a21ee3b20ed3b20ee3b6a21ef" - "3b20ee3b20ef3b6a21f03b20ef3b20f03b6a21f13b20f03b20f13b6a21f23b20f13b20f23b6a21f33b20f23b20f33b" - "6a21f43b20f33b20f43b6a21f53b20f43b20f53b6a21f63b20f53b20f63b6a21f73b20f63b20f73b6a21f83b20f73b" - "20f83b6a21f93b20f83b20f93b6a21fa3b20f93b20fa3b6a21fb3b20fa3b20fb3b6a21fc3b20fb3b20fc3b6a21fd3b" - "20fc3b20fd3b6a21fe3b20fd3b20fe3b6a21ff3b20fe3b20ff3b6a21803c20ff3b20803c6a21813c20803c20813c6a" - "21823c20813c20823c6a21833c20823c20833c6a21843c20833c20843c6a21853c20843c20853c6a21863c20853c20" - "863c6a21873c20863c20873c6a21883c20873c20883c6a21893c20883c20893c6a218a3c20893c208a3c6a218b3c20" - "8a3c208b3c6a218c3c208b3c208c3c6a218d3c208c3c208d3c6a218e3c208d3c208e3c6a218f3c208e3c208f3c6a21" - "903c208f3c20903c6a21913c20903c20913c6a21923c20913c20923c6a21933c20923c20933c6a21943c20933c2094" - "3c6a21953c20943c20953c6a21963c20953c20963c6a21973c20963c20973c6a21983c20973c20983c6a21993c2098" - "3c20993c6a219a3c20993c209a3c6a219b3c209a3c209b3c6a219c3c209b3c209c3c6a219d3c209c3c209d3c6a219e" - "3c209d3c209e3c6a219f3c209e3c209f3c6a21a03c209f3c20a03c6a21a13c20a03c20a13c6a21a23c20a13c20a23c" - "6a21a33c20a23c20a33c6a21a43c20a33c20a43c6a21a53c20a43c20a53c6a21a63c20a53c20a63c6a21a73c20a63c" - "20a73c6a21a83c20a73c20a83c6a21a93c20a83c20a93c6a21aa3c20a93c20aa3c6a21ab3c20aa3c20ab3c6a21ac3c" - "20ab3c20ac3c6a21ad3c20ac3c20ad3c6a21ae3c20ad3c20ae3c6a21af3c20ae3c20af3c6a21b03c20af3c20b03c6a" - "21b13c20b03c20b13c6a21b23c20b13c20b23c6a21b33c20b23c20b33c6a21b43c20b33c20b43c6a21b53c20b43c20" - "b53c6a21b63c20b53c20b63c6a21b73c20b63c20b73c6a21b83c20b73c20b83c6a21b93c20b83c20b93c6a21ba3c20" - "b93c20ba3c6a21bb3c20ba3c20bb3c6a21bc3c20bb3c20bc3c6a21bd3c20bc3c20bd3c6a21be3c20bd3c20be3c6a21" - "bf3c20be3c20bf3c6a21c03c20bf3c20c03c6a21c13c20c03c20c13c6a21c23c20c13c20c23c6a21c33c20c23c20c3" - "3c6a21c43c20c33c20c43c6a21c53c20c43c20c53c6a21c63c20c53c20c63c6a21c73c20c63c20c73c6a21c83c20c7" - "3c20c83c6a21c93c20c83c20c93c6a21ca3c20c93c20ca3c6a21cb3c20ca3c20cb3c6a21cc3c20cb3c20cc3c6a21cd" - "3c20cc3c20cd3c6a21ce3c20cd3c20ce3c6a21cf3c20ce3c20cf3c6a21d03c20cf3c20d03c6a21d13c20d03c20d13c" - "6a21d23c20d13c20d23c6a21d33c20d23c20d33c6a21d43c20d33c20d43c6a21d53c20d43c20d53c6a21d63c20d53c" - "20d63c6a21d73c20d63c20d73c6a21d83c20d73c20d83c6a21d93c20d83c20d93c6a21da3c20d93c20da3c6a21db3c" - "20da3c20db3c6a21dc3c20db3c20dc3c6a21dd3c20dc3c20dd3c6a21de3c20dd3c20de3c6a21df3c20de3c20df3c6a" - "21e03c20df3c20e03c6a21e13c20e03c20e13c6a21e23c20e13c20e23c6a21e33c20e23c20e33c6a21e43c20e33c20" - "e43c6a21e53c20e43c20e53c6a21e63c20e53c20e63c6a21e73c20e63c20e73c6a21e83c20e73c20e83c6a21e93c20" - "e83c20e93c6a21ea3c20e93c20ea3c6a21eb3c20ea3c20eb3c6a21ec3c20eb3c20ec3c6a21ed3c20ec3c20ed3c6a21" - "ee3c20ed3c20ee3c6a21ef3c20ee3c20ef3c6a21f03c20ef3c20f03c6a21f13c20f03c20f13c6a21f23c20f13c20f2" - "3c6a21f33c20f23c20f33c6a21f43c20f33c20f43c6a21f53c20f43c20f53c6a21f63c20f53c20f63c6a21f73c20f6" - "3c20f73c6a21f83c20f73c20f83c6a21f93c20f83c20f93c6a21fa3c20f93c20fa3c6a21fb3c20fa3c20fb3c6a21fc" - "3c20fb3c20fc3c6a21fd3c20fc3c20fd3c6a21fe3c20fd3c20fe3c6a21ff3c20fe3c20ff3c6a21803d20ff3c20803d" - "6a21813d20803d20813d6a21823d20813d20823d6a21833d20823d20833d6a21843d20833d20843d6a21853d20843d" - "20853d6a21863d20853d20863d6a21873d20863d20873d6a21883d20873d20883d6a21893d20883d20893d6a218a3d" - "20893d208a3d6a218b3d208a3d208b3d6a218c3d208b3d208c3d6a218d3d208c3d208d3d6a218e3d208d3d208e3d6a" - "218f3d208e3d208f3d6a21903d208f3d20903d6a21913d20903d20913d6a21923d20913d20923d6a21933d20923d20" - "933d6a21943d20933d20943d6a21953d20943d20953d6a21963d20953d20963d6a21973d20963d20973d6a21983d20" - "973d20983d6a21993d20983d20993d6a219a3d20993d209a3d6a219b3d209a3d209b3d6a219c3d209b3d209c3d6a21" - "9d3d209c3d209d3d6a219e3d209d3d209e3d6a219f3d209e3d209f3d6a21a03d209f3d20a03d6a21a13d20a03d20a1" - "3d6a21a23d20a13d20a23d6a21a33d20a23d20a33d6a21a43d20a33d20a43d6a21a53d20a43d20a53d6a21a63d20a5" - "3d20a63d6a21a73d20a63d20a73d6a21a83d20a73d20a83d6a21a93d20a83d20a93d6a21aa3d20a93d20aa3d6a21ab" - "3d20aa3d20ab3d6a21ac3d20ab3d20ac3d6a21ad3d20ac3d20ad3d6a21ae3d20ad3d20ae3d6a21af3d20ae3d20af3d" - "6a21b03d20af3d20b03d6a21b13d20b03d20b13d6a21b23d20b13d20b23d6a21b33d20b23d20b33d6a21b43d20b33d" - "20b43d6a21b53d20b43d20b53d6a21b63d20b53d20b63d6a21b73d20b63d20b73d6a21b83d20b73d20b83d6a21b93d" - "20b83d20b93d6a21ba3d20b93d20ba3d6a21bb3d20ba3d20bb3d6a21bc3d20bb3d20bc3d6a21bd3d20bc3d20bd3d6a" - "21be3d20bd3d20be3d6a21bf3d20be3d20bf3d6a21c03d20bf3d20c03d6a21c13d20c03d20c13d6a21c23d20c13d20" - "c23d6a21c33d20c23d20c33d6a21c43d20c33d20c43d6a21c53d20c43d20c53d6a21c63d20c53d20c63d6a21c73d20" - "c63d20c73d6a21c83d20c73d20c83d6a21c93d20c83d20c93d6a21ca3d20c93d20ca3d6a21cb3d20ca3d20cb3d6a21" - "cc3d20cb3d20cc3d6a21cd3d20cc3d20cd3d6a21ce3d20cd3d20ce3d6a21cf3d20ce3d20cf3d6a21d03d20cf3d20d0" - "3d6a21d13d20d03d20d13d6a21d23d20d13d20d23d6a21d33d20d23d20d33d6a21d43d20d33d20d43d6a21d53d20d4" - "3d20d53d6a21d63d20d53d20d63d6a21d73d20d63d20d73d6a21d83d20d73d20d83d6a21d93d20d83d20d93d6a21da" - "3d20d93d20da3d6a21db3d20da3d20db3d6a21dc3d20db3d20dc3d6a21dd3d20dc3d20dd3d6a21de3d20dd3d20de3d" - "6a21df3d20de3d20df3d6a21e03d20df3d20e03d6a21e13d20e03d20e13d6a21e23d20e13d20e23d6a21e33d20e23d" - "20e33d6a21e43d20e33d20e43d6a21e53d20e43d20e53d6a21e63d20e53d20e63d6a21e73d20e63d20e73d6a21e83d" - "20e73d20e83d6a21e93d20e83d20e93d6a21ea3d20e93d20ea3d6a21eb3d20ea3d20eb3d6a21ec3d20eb3d20ec3d6a" - "21ed3d20ec3d20ed3d6a21ee3d20ed3d20ee3d6a21ef3d20ee3d20ef3d6a21f03d20ef3d20f03d6a21f13d20f03d20" - "f13d6a21f23d20f13d20f23d6a21f33d20f23d20f33d6a21f43d20f33d20f43d6a21f53d20f43d20f53d6a21f63d20" - "f53d20f63d6a21f73d20f63d20f73d6a21f83d20f73d20f83d6a21f93d20f83d20f93d6a21fa3d20f93d20fa3d6a21" - "fb3d20fa3d20fb3d6a21fc3d20fb3d20fc3d6a21fd3d20fc3d20fd3d6a21fe3d20fd3d20fe3d6a21ff3d20fe3d20ff" - "3d6a21803e20ff3d20803e6a21813e20803e20813e6a21823e20813e20823e6a21833e20823e20833e6a21843e2083" - "3e20843e6a21853e20843e20853e6a21863e20853e20863e6a21873e20863e20873e6a21883e20873e20883e6a2189" - "3e20883e20893e6a218a3e20893e208a3e6a218b3e208a3e208b3e6a218c3e208b3e208c3e6a218d3e208c3e208d3e" - "6a218e3e208d3e208e3e6a218f3e208e3e208f3e6a21903e208f3e20903e6a21913e20903e20913e6a21923e20913e" - "20923e6a21933e20923e20933e6a21943e20933e20943e6a21953e20943e20953e6a21963e20953e20963e6a21973e" - "20963e20973e6a21983e20973e20983e6a21993e20983e20993e6a219a3e20993e209a3e6a219b3e209a3e209b3e6a" - "219c3e209b3e209c3e6a219d3e209c3e209d3e6a219e3e209d3e209e3e6a219f3e209e3e209f3e6a21a03e209f3e20" - "a03e6a21a13e20a03e20a13e6a21a23e20a13e20a23e6a21a33e20a23e20a33e6a21a43e20a33e20a43e6a21a53e20" - "a43e20a53e6a21a63e20a53e20a63e6a21a73e20a63e20a73e6a21a83e20a73e20a83e6a21a93e20a83e20a93e6a21" - "aa3e20a93e20aa3e6a21ab3e20aa3e20ab3e6a21ac3e20ab3e20ac3e6a21ad3e20ac3e20ad3e6a21ae3e20ad3e20ae" - "3e6a21af3e20ae3e20af3e6a21b03e20af3e20b03e6a21b13e20b03e20b13e6a21b23e20b13e20b23e6a21b33e20b2" - "3e20b33e6a21b43e20b33e20b43e6a21b53e20b43e20b53e6a21b63e20b53e20b63e6a21b73e20b63e20b73e6a21b8" - "3e20b73e20b83e6a21b93e20b83e20b93e6a21ba3e20b93e20ba3e6a21bb3e20ba3e20bb3e6a21bc3e20bb3e20bc3e" - "6a21bd3e20bc3e20bd3e6a21be3e20bd3e20be3e6a21bf3e20be3e20bf3e6a21c03e20bf3e20c03e6a21c13e20c03e" - "20c13e6a21c23e20c13e20c23e6a21c33e20c23e20c33e6a21c43e20c33e20c43e6a21c53e20c43e20c53e6a21c63e" - "20c53e20c63e6a21c73e20c63e20c73e6a21c83e20c73e20c83e6a21c93e20c83e20c93e6a21ca3e20c93e20ca3e6a" - "21cb3e20ca3e20cb3e6a21cc3e20cb3e20cc3e6a21cd3e20cc3e20cd3e6a21ce3e20cd3e20ce3e6a21cf3e20ce3e20" - "cf3e6a21d03e20cf3e20d03e6a21d13e20d03e20d13e6a21d23e20d13e20d23e6a21d33e20d23e20d33e6a21d43e20" - "d33e20d43e6a21d53e20d43e20d53e6a21d63e20d53e20d63e6a21d73e20d63e20d73e6a21d83e20d73e20d83e6a21" - "d93e20d83e20d93e6a21da3e20d93e20da3e6a21db3e20da3e20db3e6a21dc3e20db3e20dc3e6a21dd3e20dc3e20dd" - "3e6a21de3e20dd3e20de3e6a21df3e20de3e20df3e6a21e03e20df3e20e03e6a21e13e20e03e20e13e6a21e23e20e1" - "3e20e23e6a21e33e20e23e20e33e6a21e43e20e33e20e43e6a21e53e20e43e20e53e6a21e63e20e53e20e63e6a21e7" - "3e20e63e20e73e6a21e83e20e73e20e83e6a21e93e20e83e20e93e6a21ea3e20e93e20ea3e6a21eb3e20ea3e20eb3e" - "6a21ec3e20eb3e20ec3e6a21ed3e20ec3e20ed3e6a21ee3e20ed3e20ee3e6a21ef3e20ee3e20ef3e6a21f03e20ef3e" - "20f03e6a21f13e20f03e20f13e6a21f23e20f13e20f23e6a21f33e20f23e20f33e6a21f43e20f33e20f43e6a21f53e" - "20f43e20f53e6a21f63e20f53e20f63e6a21f73e20f63e20f73e6a21f83e20f73e20f83e6a21f93e20f83e20f93e6a" - "21fa3e20f93e20fa3e6a21fb3e20fa3e20fb3e6a21fc3e20fb3e20fc3e6a21fd3e20fc3e20fd3e6a21fe3e20fd3e20" - "fe3e6a21ff3e20fe3e20ff3e6a21803f20ff3e20803f6a21813f20803f20813f6a21823f20813f20823f6a21833f20" - "823f20833f6a21843f20833f20843f6a21853f20843f20853f6a21863f20853f20863f6a21873f20863f20873f6a21" - "883f20873f20883f6a21893f20883f20893f6a218a3f20893f208a3f6a218b3f208a3f208b3f6a218c3f208b3f208c" - "3f6a218d3f208c3f208d3f6a218e3f208d3f208e3f6a218f3f208e3f208f3f6a21903f208f3f20903f6a21913f2090" - "3f20913f6a21923f20913f20923f6a21933f20923f20933f6a21943f20933f20943f6a21953f20943f20953f6a2196" - "3f20953f20963f6a21973f20963f20973f6a21983f20973f20983f6a21993f20983f20993f6a219a3f20993f209a3f" - "6a219b3f209a3f209b3f6a219c3f209b3f209c3f6a219d3f209c3f209d3f6a219e3f209d3f209e3f6a219f3f209e3f" - "209f3f6a21a03f209f3f20a03f6a21a13f20a03f20a13f6a21a23f20a13f20a23f6a21a33f20a23f20a33f6a21a43f" - "20a33f20a43f6a21a53f20a43f20a53f6a21a63f20a53f20a63f6a21a73f20a63f20a73f6a21a83f20a73f20a83f6a" - "21a93f20a83f20a93f6a21aa3f20a93f20aa3f6a21ab3f20aa3f20ab3f6a21ac3f20ab3f20ac3f6a21ad3f20ac3f20" - "ad3f6a21ae3f20ad3f20ae3f6a21af3f20ae3f20af3f6a21b03f20af3f20b03f6a21b13f20b03f20b13f6a21b23f20" - "b13f20b23f6a21b33f20b23f20b33f6a21b43f20b33f20b43f6a21b53f20b43f20b53f6a21b63f20b53f20b63f6a21" - "b73f20b63f20b73f6a21b83f20b73f20b83f6a21b93f20b83f20b93f6a21ba3f20b93f20ba3f6a21bb3f20ba3f20bb" - "3f6a21bc3f20bb3f20bc3f6a21bd3f20bc3f20bd3f6a21be3f20bd3f20be3f6a21bf3f20be3f20bf3f6a21c03f20bf" - "3f20c03f6a21c13f20c03f20c13f6a21c23f20c13f20c23f6a21c33f20c23f20c33f6a21c43f20c33f20c43f6a21c5" - "3f20c43f20c53f6a21c63f20c53f20c63f6a21c73f20c63f20c73f6a21c83f20c73f20c83f6a21c93f20c83f20c93f" - "6a21ca3f20c93f20ca3f6a21cb3f20ca3f20cb3f6a21cc3f20cb3f20cc3f6a21cd3f20cc3f20cd3f6a21ce3f20cd3f" - "20ce3f6a21cf3f20ce3f20cf3f6a21d03f20cf3f20d03f6a21d13f20d03f20d13f6a21d23f20d13f20d23f6a21d33f" - "20d23f20d33f6a21d43f20d33f20d43f6a21d53f20d43f20d53f6a21d63f20d53f20d63f6a21d73f20d63f20d73f6a" - "21d83f20d73f20d83f6a21d93f20d83f20d93f6a21da3f20d93f20da3f6a21db3f20da3f20db3f6a21dc3f20db3f20" - "dc3f6a21dd3f20dc3f20dd3f6a21de3f20dd3f20de3f6a21df3f20de3f20df3f6a21e03f20df3f20e03f6a21e13f20" - "e03f20e13f6a21e23f20e13f20e23f6a21e33f20e23f20e33f6a21e43f20e33f20e43f6a21e53f20e43f20e53f6a21" - "e63f20e53f20e63f6a21e73f20e63f20e73f6a21e83f20e73f20e83f6a21e93f20e83f20e93f6a21ea3f20e93f20ea" - "3f6a21eb3f20ea3f20eb3f6a21ec3f20eb3f20ec3f6a21ed3f20ec3f20ed3f6a21ee3f20ed3f20ee3f6a21ef3f20ee" - "3f20ef3f6a21f03f20ef3f20f03f6a21f13f20f03f20f13f6a21f23f20f13f20f23f6a21f33f20f23f20f33f6a21f4" - "3f20f33f20f43f6a21f53f20f43f20f53f6a21f63f20f53f20f63f6a21f73f20f63f20f73f6a21f83f20f73f20f83f" - "6a21f93f20f83f20f93f6a21fa3f20f93f20fa3f6a21fb3f20fa3f20fb3f6a21fc3f20fb3f20fc3f6a21fd3f20fc3f" - "20fd3f6a21fe3f20fd3f20fe3f6a21ff3f20fe3f20ff3f6a21804020ff3f2080406a2181402080402081406a218240" - "2081402082406a2183402082402083406a2184402083402084406a2185402084402085406a2186402085402086406a" - "2187402086402087406a2188402087402088406a2189402088402089406a218a40208940208a406a218b40208a4020" - "8b406a218c40208b40208c406a218d40208c40208d406a218e40208d40208e406a218f40208e40208f406a21904020" - "8f402090406a2191402090402091406a2192402091402092406a2193402092402093406a2194402093402094406a21" - "95402094402095406a2196402095402096406a2197402096402097406a2198402097402098406a2199402098402099" - "406a219a40209940209a406a219b40209a40209b406a219c40209b40209c406a219d40209c40209d406a219e40209d" - "40209e406a219f40209e40209f406a21a040209f4020a0406a21a14020a04020a1406a21a24020a14020a2406a21a3" - "4020a24020a3406a21a44020a34020a4406a21a54020a44020a5406a21a64020a54020a6406a21a74020a64020a740" - "6a21a84020a74020a8406a21a94020a84020a9406a21aa4020a94020aa406a21ab4020aa4020ab406a21ac4020ab40" - "20ac406a21ad4020ac4020ad406a21ae4020ad4020ae406a21af4020ae4020af406a21b04020af4020b0406a21b140" - "20b04020b1406a21b24020b14020b2406a21b34020b24020b3406a21b44020b34020b4406a21b54020b44020b5406a" - "21b64020b54020b6406a21b74020b64020b7406a21b84020b74020b8406a21b94020b84020b9406a21ba4020b94020" - "ba406a21bb4020ba4020bb406a21bc4020bb4020bc406a21bd4020bc4020bd406a21be4020bd4020be406a21bf4020" - "be4020bf406a21c04020bf4020c0406a21c14020c04020c1406a21c24020c14020c2406a21c34020c24020c3406a21" - "c44020c34020c4406a21c54020c44020c5406a21c64020c54020c6406a21c74020c64020c7406a21c84020c74020c8" - "406a21c94020c84020c9406a21ca4020c94020ca406a21cb4020ca4020cb406a21cc4020cb4020cc406a21cd4020cc" - "4020cd406a21ce4020cd4020ce406a21cf4020ce4020cf406a21d04020cf4020d0406a21d14020d04020d1406a21d2" - "4020d14020d2406a21d34020d24020d3406a21d44020d34020d4406a21d54020d44020d5406a21d64020d54020d640" - "6a21d74020d64020d7406a21d84020d74020d8406a21d94020d84020d9406a21da4020d94020da406a21db4020da40" - "20db406a21dc4020db4020dc406a21dd4020dc4020dd406a21de4020dd4020de406a21df4020de4020df406a21e040" - "20df4020e0406a21e14020e04020e1406a21e24020e14020e2406a21e34020e24020e3406a21e44020e34020e4406a" - "21e54020e44020e5406a21e64020e54020e6406a21e74020e64020e7406a21e84020e74020e8406a21e94020e84020" - "e9406a21ea4020e94020ea406a21eb4020ea4020eb406a21ec4020eb4020ec406a21ed4020ec4020ed406a21ee4020" - "ed4020ee406a21ef4020ee4020ef406a21f04020ef4020f0406a21f14020f04020f1406a21f24020f14020f2406a21" - "f34020f24020f3406a21f44020f34020f4406a21f54020f44020f5406a21f64020f54020f6406a21f74020f64020f7" - "406a21f84020f74020f8406a21f94020f84020f9406a21fa4020f94020fa406a21fb4020fa4020fb406a21fc4020fb" - "4020fc406a21fd4020fc4020fd406a21fe4020fd4020fe406a21ff4020fe4020ff406a21804120ff402080416a2181" - "412080412081416a2182412081412082416a2183412082412083416a2184412083412084416a218541208441208541" - "6a2186412085412086416a2187412086412087416a2188412087412088416a2189412088412089416a218a41208941" - "208a416a218b41208a41208b416a218c41208b41208c416a218d41208c41208d416a218e41208d41208e416a218f41" - "208e41208f416a219041208f412090416a2191412090412091416a2192412091412092416a2193412092412093416a" - "2194412093412094416a2195412094412095416a2196412095412096416a2197412096412097416a21984120974120" - "98416a2199412098412099416a219a41209941209a416a219b41209a41209b416a219c41209b41209c416a219d4120" - "9c41209d416a219e41209d41209e416a219f41209e41209f416a21a041209f4120a0416a21a14120a04120a1416a21" - "a24120a14120a2416a21a34120a24120a3416a21a44120a34120a4416a21a54120a44120a5416a21a64120a54120a6" - "416a21a74120a64120a7416a21a84120a74120a8416a21a94120a84120a9416a21aa4120a94120aa416a21ab4120aa" - "4120ab416a21ac4120ab4120ac416a21ad4120ac4120ad416a21ae4120ad4120ae416a21af4120ae4120af416a21b0" - "4120af4120b0416a21b14120b04120b1416a21b24120b14120b2416a21b34120b24120b3416a21b44120b34120b441" - "6a21b54120b44120b5416a21b64120b54120b6416a21b74120b64120b7416a21b84120b74120b8416a21b94120b841" - "20b9416a21ba4120b94120ba416a21bb4120ba4120bb416a21bc4120bb4120bc416a21bd4120bc4120bd416a21be41" - "20bd4120be416a21bf4120be4120bf416a21c04120bf4120c0416a21c14120c04120c1416a21c24120c14120c2416a" - "21c34120c24120c3416a21c44120c34120c4416a21c54120c44120c5416a21c64120c54120c6416a21c74120c64120" - "c7416a21c84120c74120c8416a21c94120c84120c9416a21ca4120c94120ca416a21cb4120ca4120cb416a21cc4120" - "cb4120cc416a21cd4120cc4120cd416a21ce4120cd4120ce416a21cf4120ce4120cf416a21d04120cf4120d0416a21" - "d14120d04120d1416a21d24120d14120d2416a21d34120d24120d3416a21d44120d34120d4416a21d54120d44120d5" - "416a21d64120d54120d6416a21d74120d64120d7416a21d84120d74120d8416a21d94120d84120d9416a21da4120d9" - "4120da416a21db4120da4120db416a21dc4120db4120dc416a21dd4120dc4120dd416a21de4120dd4120de416a21df" - "4120de4120df416a21e04120df4120e0416a21e14120e04120e1416a21e24120e14120e2416a21e34120e24120e341" - "6a21e44120e34120e4416a21e54120e44120e5416a21e64120e54120e6416a21e74120e64120e7416a21e84120e741" - "20e8416a21e94120e84120e9416a21ea4120e94120ea416a21eb4120ea4120eb416a21ec4120eb4120ec416a21ed41" - "20ec4120ed416a21ee4120ed4120ee416a21ef4120ee4120ef416a21f04120ef4120f0416a21f14120f04120f1416a" - "21f24120f14120f2416a21f34120f24120f3416a21f44120f34120f4416a21f54120f44120f5416a21f64120f54120" - "f6416a21f74120f64120f7416a21f84120f74120f8416a21f94120f84120f9416a21fa4120f94120fa416a21fb4120" - "fa4120fb416a21fc4120fb4120fc416a21fd4120fc4120fd416a21fe4120fd4120fe416a21ff4120fe4120ff416a21" - "804220ff412080426a2181422080422081426a2182422081422082426a2183422082422083426a2184422083422084" - "426a2185422084422085426a2186422085422086426a2187422086422087426a2188422087422088426a2189422088" - "422089426a218a42208942208a426a218b42208a42208b426a218c42208b42208c426a218d42208c42208d426a218e" - "42208d42208e426a218f42208e42208f426a219042208f422090426a2191422090422091426a219242209142209242" - "6a2193422092422093426a2194422093422094426a2195422094422095426a2196422095422096426a219742209642" - "2097426a2198422097422098426a2199422098422099426a219a42209942209a426a219b42209a42209b426a219c42" - "209b42209c426a219d42209c42209d426a219e42209d42209e426a219f42209e42209f426a21a042209f4220a0426a" - "21a14220a04220a1426a21a24220a14220a2426a21a34220a24220a3426a21a44220a34220a4426a21a54220a44220" - "a5426a21a64220a54220a6426a21a74220a64220a7426a21a84220a74220a8426a21a94220a84220a9426a21aa4220" - "a94220aa426a21ab4220aa4220ab426a21ac4220ab4220ac426a21ad4220ac4220ad426a21ae4220ad4220ae426a21" - "af4220ae4220af426a21b04220af4220b0426a21b14220b04220b1426a21b24220b14220b2426a21b34220b24220b3" - "426a21b44220b34220b4426a21b54220b44220b5426a21b64220b54220b6426a21b74220b64220b7426a21b84220b7" - "4220b8426a21b94220b84220b9426a21ba4220b94220ba426a21bb4220ba4220bb426a21bc4220bb4220bc426a21bd" - "4220bc4220bd426a21be4220bd4220be426a21bf4220be4220bf426a21c04220bf4220c0426a21c14220c04220c142" - "6a21c24220c14220c2426a21c34220c24220c3426a21c44220c34220c4426a21c54220c44220c5426a21c64220c542" - "20c6426a21c74220c64220c7426a21c84220c74220c8426a21c94220c84220c9426a21ca4220c94220ca426a21cb42" - "20ca4220cb426a21cc4220cb4220cc426a21cd4220cc4220cd426a21ce4220cd4220ce426a21cf4220ce4220cf426a" - "21d04220cf4220d0426a21d14220d04220d1426a21d24220d14220d2426a21d34220d24220d3426a21d44220d34220" - "d4426a21d54220d44220d5426a21d64220d54220d6426a21d74220d64220d7426a21d84220d74220d8426a21d94220" - "d84220d9426a21da4220d94220da426a21db4220da4220db426a21dc4220db4220dc426a21dd4220dc4220dd426a21" - "de4220dd4220de426a21df4220de4220df426a21e04220df4220e0426a21e14220e04220e1426a21e24220e14220e2" - "426a21e34220e24220e3426a21e44220e34220e4426a21e54220e44220e5426a21e64220e54220e6426a21e74220e6" - "4220e7426a21e84220e74220e8426a21e94220e84220e9426a21ea4220e94220ea426a21eb4220ea4220eb426a21ec" - "4220eb4220ec426a21ed4220ec4220ed426a21ee4220ed4220ee426a21ef4220ee4220ef426a21f04220ef4220f042" - "6a21f14220f04220f1426a21f24220f14220f2426a21f34220f24220f3426a21f44220f34220f4426a21f54220f442" - "20f5426a21f64220f54220f6426a21f74220f64220f7426a21f84220f74220f8426a21f94220f84220f9426a21fa42" - "20f94220fa426a21fb4220fa4220fb426a21fc4220fb4220fc426a21fd4220fc4220fd426a21fe4220fd4220fe426a" - "21ff4220fe4220ff426a21804320ff422080436a2181432080432081436a2182432081432082436a21834320824320" - "83436a2184432083432084436a2185432084432085436a2186432085432086436a2187432086432087436a21884320" - "87432088436a2189432088432089436a218a43208943208a436a218b43208a43208b436a218c43208b43208c436a21" - "8d43208c43208d436a218e43208d43208e436a218f43208e43208f436a219043208f432090436a2191432090432091" - "436a2192432091432092436a2193432092432093436a2194432093432094436a2195432094432095436a2196432095" - "432096436a2197432096432097436a2198432097432098436a2199432098432099436a219a43209943209a436a219b" - "43209a43209b436a219c43209b43209c436a219d43209c43209d436a219e43209d43209e436a219f43209e43209f43" - "6a21a043209f4320a0436a21a14320a04320a1436a21a24320a14320a2436a21a34320a24320a3436a21a44320a343" - "20a4436a21a54320a44320a5436a21a64320a54320a6436a21a74320a64320a7436a21a84320a74320a8436a21a943" - "20a84320a9436a21aa4320a94320aa436a21ab4320aa4320ab436a21ac4320ab4320ac436a21ad4320ac4320ad436a" - "21ae4320ad4320ae436a21af4320ae4320af436a21b04320af4320b0436a21b14320b04320b1436a21b24320b14320" - "b2436a21b34320b24320b3436a21b44320b34320b4436a21b54320b44320b5436a21b64320b54320b6436a21b74320" - "b64320b7436a21b84320b74320b8436a21b94320b84320b9436a21ba4320b94320ba436a21bb4320ba4320bb436a21" - "bc4320bb4320bc436a21bd4320bc4320bd436a21be4320bd4320be436a21bf4320be4320bf436a21c04320bf4320c0" - "436a21c14320c04320c1436a21c24320c14320c2436a21c34320c24320c3436a21c44320c34320c4436a21c54320c4" - "4320c5436a21c64320c54320c6436a21c74320c64320c7436a21c84320c74320c8436a21c94320c84320c9436a21ca" - "4320c94320ca436a21cb4320ca4320cb436a21cc4320cb4320cc436a21cd4320cc4320cd436a21ce4320cd4320ce43" - "6a21cf4320ce4320cf436a21d04320cf4320d0436a21d14320d04320d1436a21d24320d14320d2436a21d34320d243" - "20d3436a21d44320d34320d4436a21d54320d44320d5436a21d64320d54320d6436a21d74320d64320d7436a21d843" - "20d74320d8436a21d94320d84320d9436a21da4320d94320da436a21db4320da4320db436a21dc4320db4320dc436a" - "21dd4320dc4320dd436a21de4320dd4320de436a21df4320de4320df436a21e04320df4320e0436a21e14320e04320" - "e1436a21e24320e14320e2436a21e34320e24320e3436a21e44320e34320e4436a21e54320e44320e5436a21e64320" - "e54320e6436a21e74320e64320e7436a21e84320e74320e8436a21e94320e84320e9436a21ea4320e94320ea436a21" - "eb4320ea4320eb436a21ec4320eb4320ec436a21ed4320ec4320ed436a21ee4320ed4320ee436a21ef4320ee4320ef" - "436a21f04320ef4320f0436a21f14320f04320f1436a21f24320f14320f2436a21f34320f24320f3436a21f44320f3" - "4320f4436a21f54320f44320f5436a21f64320f54320f6436a21f74320f64320f7436a21f84320f74320f8436a21f9" - "4320f84320f9436a21fa4320f94320fa436a21fb4320fa4320fb436a21fc4320fb4320fc436a21fd4320fc4320fd43" - "6a21fe4320fd4320fe436a21ff4320fe4320ff436a21804420ff432080446a2181442080442081446a218244208144" - "2082446a2183442082442083446a2184442083442084446a2185442084442085446a2186442085442086446a218744" - "2086442087446a2188442087442088446a2189442088442089446a218a44208944208a446a218b44208a44208b446a" - "218c44208b44208c446a218d44208c44208d446a218e44208d44208e446a218f44208e44208f446a219044208f4420" - "90446a2191442090442091446a2192442091442092446a2193442092442093446a2194442093442094446a21954420" - "94442095446a2196442095442096446a2197442096442097446a2198442097442098446a2199442098442099446a21" - "9a44209944209a446a219b44209a44209b446a219c44209b44209c446a219d44209c44209d446a219e44209d44209e" - "446a219f44209e44209f446a21a044209f4420a0446a21a14420a04420a1446a21a24420a14420a2446a21a34420a2" - "4420a3446a21a44420a34420a4446a21a54420a44420a5446a21a64420a54420a6446a21a74420a64420a7446a21a8" - "4420a74420a8446a21a94420a84420a9446a21aa4420a94420aa446a21ab4420aa4420ab446a21ac4420ab4420ac44" - "6a21ad4420ac4420ad446a21ae4420ad4420ae446a21af4420ae4420af446a21b04420af4420b0446a21b14420b044" - "20b1446a21b24420b14420b2446a21b34420b24420b3446a21b44420b34420b4446a21b54420b44420b5446a21b644" - "20b54420b6446a21b74420b64420b7446a21b84420b74420b8446a21b94420b84420b9446a21ba4420b94420ba446a" - "21bb4420ba4420bb446a21bc4420bb4420bc446a21bd4420bc4420bd446a21be4420bd4420be446a21bf4420be4420" - "bf446a21c04420bf4420c0446a21c14420c04420c1446a21c24420c14420c2446a21c34420c24420c3446a21c44420" - "c34420c4446a21c54420c44420c5446a21c64420c54420c6446a21c74420c64420c7446a21c84420c74420c8446a21" - "c94420c84420c9446a21ca4420c94420ca446a21cb4420ca4420cb446a21cc4420cb4420cc446a21cd4420cc4420cd" - "446a21ce4420cd4420ce446a21cf4420ce4420cf446a21d04420cf4420d0446a21d14420d04420d1446a21d24420d1" - "4420d2446a21d34420d24420d3446a21d44420d34420d4446a21d54420d44420d5446a21d64420d54420d6446a21d7" - "4420d64420d7446a21d84420d74420d8446a21d94420d84420d9446a21da4420d94420da446a21db4420da4420db44" - "6a21dc4420db4420dc446a21dd4420dc4420dd446a21de4420dd4420de446a21df4420de4420df446a21e04420df44" - "20e0446a21e14420e04420e1446a21e24420e14420e2446a21e34420e24420e3446a21e44420e34420e4446a21e544" - "20e44420e5446a21e64420e54420e6446a21e74420e64420e7446a21e84420e74420e8446a21e94420e84420e9446a" - "21ea4420e94420ea446a21eb4420ea4420eb446a21ec4420eb4420ec446a21ed4420ec4420ed446a21ee4420ed4420" - "ee446a21ef4420ee4420ef446a21f04420ef4420f0446a21f14420f04420f1446a21f24420f14420f2446a21f34420" - "f24420f3446a21f44420f34420f4446a21f54420f44420f5446a21f64420f54420f6446a21f74420f64420f7446a21" - "f84420f74420f8446a21f94420f84420f9446a21fa4420f94420fa446a21fb4420fa4420fb446a21fc4420fb4420fc" - "446a21fd4420fc4420fd446a21fe4420fd4420fe446a21ff4420fe4420ff446a21804520ff442080456a2181452080" - "452081456a2182452081452082456a2183452082452083456a2184452083452084456a2185452084452085456a2186" - "452085452086456a2187452086452087456a2188452087452088456a2189452088452089456a218a45208945208a45" - "6a218b45208a45208b456a218c45208b45208c456a218d45208c45208d456a218e45208d45208e456a218f45208e45" - "208f456a219045208f452090456a2191452090452091456a2192452091452092456a2193452092452093456a219445" - "2093452094456a2195452094452095456a2196452095452096456a2197452096452097456a2198452097452098456a" - "2199452098452099456a219a45209945209a456a219b45209a45209b456a219c45209b45209c456a219d45209c4520" - "9d456a219e45209d45209e456a219f45209e45209f456a21a045209f4520a0456a21a14520a04520a1456a21a24520" - "a14520a2456a21a34520a24520a3456a21a44520a34520a4456a21a54520a44520a5456a21a64520a54520a6456a21" - "a74520a64520a7456a21a84520a74520a8456a21a94520a84520a9456a21aa4520a94520aa456a21ab4520aa4520ab" - "456a21ac4520ab4520ac456a21ad4520ac4520ad456a21ae4520ad4520ae456a21af4520ae4520af456a21b04520af" - "4520b0456a21b14520b04520b1456a21b24520b14520b2456a21b34520b24520b3456a21b44520b34520b4456a21b5" - "4520b44520b5456a21b64520b54520b6456a21b74520b64520b7456a21b84520b74520b8456a21b94520b84520b945" - "6a21ba4520b94520ba456a21bb4520ba4520bb456a21bc4520bb4520bc456a21bd4520bc4520bd456a21be4520bd45" - "20be456a21bf4520be4520bf456a21c04520bf4520c0456a21c14520c04520c1456a21c24520c14520c2456a21c345" - "20c24520c3456a21c44520c34520c4456a21c54520c44520c5456a21c64520c54520c6456a21c74520c64520c7456a" - "21c84520c74520c8456a21c94520c84520c9456a21ca4520c94520ca456a21cb4520ca4520cb456a21cc4520cb4520" - "cc456a21cd4520cc4520cd456a21ce4520cd4520ce456a21cf4520ce4520cf456a21d04520cf4520d0456a21d14520" - "d04520d1456a21d24520d14520d2456a21d34520d24520d3456a21d44520d34520d4456a21d54520d44520d5456a21" - "d64520d54520d6456a21d74520d64520d7456a21d84520d74520d8456a21d94520d84520d9456a21da4520d94520da" - "456a21db4520da4520db456a21dc4520db4520dc456a21dd4520dc4520dd456a21de4520dd4520de456a21df4520de" - "4520df456a21e04520df4520e0456a21e14520e04520e1456a21e24520e14520e2456a21e34520e24520e3456a21e4" - "4520e34520e4456a21e54520e44520e5456a21e64520e54520e6456a21e74520e64520e7456a21e84520e74520e845" - "6a21e94520e84520e9456a21ea4520e94520ea456a21eb4520ea4520eb456a21ec4520eb4520ec456a21ed4520ec45" - "20ed456a21ee4520ed4520ee456a21ef4520ee4520ef456a21f04520ef4520f0456a21f14520f04520f1456a21f245" - "20f14520f2456a21f34520f24520f3456a21f44520f34520f4456a21f54520f44520f5456a21f64520f54520f6456a" - "21f74520f64520f7456a21f84520f74520f8456a21f94520f84520f9456a21fa4520f94520fa456a21fb4520fa4520" - "fb456a21fc4520fb4520fc456a21fd4520fc4520fd456a21fe4520fd4520fe456a21ff4520fe4520ff456a21804620" - "ff452080466a2181462080462081466a2182462081462082466a2183462082462083466a2184462083462084466a21" - "85462084462085466a2186462085462086466a2187462086462087466a2188462087462088466a2189462088462089" - "466a218a46208946208a466a218b46208a46208b466a218c46208b46208c466a218d46208c46208d466a218e46208d" - "46208e466a218f46208e46208f466a219046208f462090466a2191462090462091466a2192462091462092466a2193" - "462092462093466a2194462093462094466a2195462094462095466a2196462095462096466a219746209646209746" - "6a2198462097462098466a2199462098462099466a219a46209946209a466a219b46209a46209b466a219c46209b46" - "209c466a219d46209c46209d466a219e46209d46209e466a219f46209e46209f466a21a046209f4620a0466a21a146" - "20a04620a1466a21a24620a14620a2466a21a34620a24620a3466a21a44620a34620a4466a21a54620a44620a5466a" - "21a64620a54620a6466a21a74620a64620a7466a21a84620a74620a8466a21a94620a84620a9466a21aa4620a94620" - "aa466a21ab4620aa4620ab466a21ac4620ab4620ac466a21ad4620ac4620ad466a21ae4620ad4620ae466a21af4620" - "ae4620af466a21b04620af4620b0466a21b14620b04620b1466a21b24620b14620b2466a21b34620b24620b3466a21" - "b44620b34620b4466a21b54620b44620b5466a21b64620b54620b6466a21b74620b64620b7466a21b84620b74620b8" - "466a21b94620b84620b9466a21ba4620b94620ba466a21bb4620ba4620bb466a21bc4620bb4620bc466a21bd4620bc" - "4620bd466a21be4620bd4620be466a21bf4620be4620bf466a21c04620bf4620c0466a21c14620c04620c1466a21c2" - "4620c14620c2466a21c34620c24620c3466a21c44620c34620c4466a21c54620c44620c5466a21c64620c54620c646" - "6a21c74620c64620c7466a21c84620c74620c8466a21c94620c84620c9466a21ca4620c94620ca466a21cb4620ca46" - "20cb466a21cc4620cb4620cc466a21cd4620cc4620cd466a21ce4620cd4620ce466a21cf4620ce4620cf466a21d046" - "20cf4620d0466a21d14620d04620d1466a21d24620d14620d2466a21d34620d24620d3466a21d44620d34620d4466a" - "21d54620d44620d5466a21d64620d54620d6466a21d74620d64620d7466a21d84620d74620d8466a21d94620d84620" - "d9466a21da4620d94620da466a21db4620da4620db466a21dc4620db4620dc466a21dd4620dc4620dd466a21de4620" - "dd4620de466a21df4620de4620df466a21e04620df4620e0466a21e14620e04620e1466a21e24620e14620e2466a21" - "e34620e24620e3466a21e44620e34620e4466a21e54620e44620e5466a21e64620e54620e6466a21e74620e64620e7" - "466a21e84620e74620e8466a21e94620e84620e9466a21ea4620e94620ea466a21eb4620ea4620eb466a21ec4620eb" - "4620ec466a21ed4620ec4620ed466a21ee4620ed4620ee466a21ef4620ee4620ef466a21f04620ef4620f0466a21f1" - "4620f04620f1466a21f24620f14620f2466a21f34620f24620f3466a21f44620f34620f4466a21f54620f44620f546" - "6a21f64620f54620f6466a21f74620f64620f7466a21f84620f74620f8466a21f94620f84620f9466a21fa4620f946" - "20fa466a21fb4620fa4620fb466a21fc4620fb4620fc466a21fd4620fc4620fd466a21fe4620fd4620fe466a21ff46" - "20fe4620ff466a21804720ff462080476a2181472080472081476a2182472081472082476a2183472082472083476a" - "2184472083472084476a2185472084472085476a2186472085472086476a2187472086472087476a21884720874720" - "88476a2189472088472089476a218a47208947208a476a218b47208a47208b476a218c47208b47208c476a218d4720" - "8c47208d476a218e47208d47208e476a218f47208e47208f476a219047208f472090476a2191472090472091476a21" - "92472091472092476a2193472092472093476a2194472093472094476a2195472094472095476a2196472095472096" - "476a2197472096472097476a2198472097472098476a2199472098472099476a219a47209947209a476a219b47209a" - "47209b476a219c47209b47209c476a219d47209c47209d476a219e47209d47209e476a219f47209e47209f476a21a0" - "47209f4720a0476a21a14720a04720a1476a21a24720a14720a2476a21a34720a24720a3476a21a44720a34720a447" - "6a21a54720a44720a5476a21a64720a54720a6476a21a74720a64720a7476a21a84720a74720a8476a21a94720a847" - "20a9476a21aa4720a94720aa476a21ab4720aa4720ab476a21ac4720ab4720ac476a21ad4720ac4720ad476a21ae47" - "20ad4720ae476a21af4720ae4720af476a21b04720af4720b0476a21b14720b04720b1476a21b24720b14720b2476a" - "21b34720b24720b3476a21b44720b34720b4476a21b54720b44720b5476a21b64720b54720b6476a21b74720b64720" - "b7476a21b84720b74720b8476a21b94720b84720b9476a21ba4720b94720ba476a21bb4720ba4720bb476a21bc4720" - "bb4720bc476a21bd4720bc4720bd476a21be4720bd4720be476a21bf4720be4720bf476a21c04720bf4720c0476a21" - "c14720c04720c1476a21c24720c14720c2476a21c34720c24720c3476a21c44720c34720c4476a21c54720c44720c5" - "476a21c64720c54720c6476a21c74720c64720c7476a21c84720c74720c8476a21c94720c84720c9476a21ca4720c9" - "4720ca476a21cb4720ca4720cb476a21cc4720cb4720cc476a21cd4720cc4720cd476a21ce4720cd4720ce476a21cf" - "4720ce4720cf476a21d04720cf4720d0476a21d14720d04720d1476a21d24720d14720d2476a21d34720d24720d347" - "6a21d44720d34720d4476a21d54720d44720d5476a21d64720d54720d6476a21d74720d64720d7476a21d84720d747" - "20d8476a21d94720d84720d9476a21da4720d94720da476a21db4720da4720db476a21dc4720db4720dc476a21dd47" - "20dc4720dd476a21de4720dd4720de476a21df4720de4720df476a21e04720df4720e0476a21e14720e04720e1476a" - "21e24720e14720e2476a21e34720e24720e3476a21e44720e34720e4476a21e54720e44720e5476a21e64720e54720" - "e6476a21e74720e64720e7476a21e84720e74720e8476a21e94720e84720e9476a21ea4720e94720ea476a21eb4720" - "ea4720eb476a21ec4720eb4720ec476a21ed4720ec4720ed476a21ee4720ed4720ee476a21ef4720ee4720ef476a21" - "f04720ef4720f0476a21f14720f04720f1476a21f24720f14720f2476a21f34720f24720f3476a21f44720f34720f4" - "476a21f54720f44720f5476a21f64720f54720f6476a21f74720f64720f7476a21f84720f74720f8476a21f94720f8" - "4720f9476a21fa4720f94720fa476a21fb4720fa4720fb476a21fc4720fb4720fc476a21fd4720fc4720fd476a21fe" - "4720fd4720fe476a21ff4720fe4720ff476a21804820ff472080486a2181482080482081486a218248208148208248" - "6a2183482082482083486a2184482083482084486a2185482084482085486a2186482085482086486a218748208648" - "2087486a2188482087482088486a2189482088482089486a218a48208948208a486a218b48208a48208b486a218c48" - "208b48208c486a218d48208c48208d486a218e48208d48208e486a218f48208e48208f486a219048208f482090486a" - "2191482090482091486a2192482091482092486a2193482092482093486a2194482093482094486a21954820944820" - "95486a2196482095482096486a2197482096482097486a2198482097482098486a2199482098482099486a219a4820" - "9948209a486a219b48209a48209b486a219c48209b48209c486a219d48209c48209d486a219e48209d48209e486a21" - "9f48209e48209f486a21a048209f4820a0486a21a14820a04820a1486a21a24820a14820a2486a21a34820a24820a3" - "486a21a44820a34820a4486a21a54820a44820a5486a21a64820a54820a6486a21a74820a64820a7486a21a84820a7" - "4820a8486a21a94820a84820a9486a21aa4820a94820aa486a21ab4820aa4820ab486a21ac4820ab4820ac486a21ad" - "4820ac4820ad486a21ae4820ad4820ae486a21af4820ae4820af486a21b04820af4820b0486a21b14820b04820b148" - "6a21b24820b14820b2486a21b34820b24820b3486a21b44820b34820b4486a21b54820b44820b5486a21b64820b548" - "20b6486a21b74820b64820b7486a21b84820b74820b8486a21b94820b84820b9486a21ba4820b94820ba486a21bb48" - "20ba4820bb486a21bc4820bb4820bc486a21bd4820bc4820bd486a21be4820bd4820be486a21bf4820be4820bf486a" - "21c04820bf4820c0486a21c14820c04820c1486a21c24820c14820c2486a21c34820c24820c3486a21c44820c34820" - "c4486a21c54820c44820c5486a21c64820c54820c6486a21c74820c64820c7486a21c84820c74820c8486a21c94820" - "c84820c9486a21ca4820c94820ca486a21cb4820ca4820cb486a21cc4820cb4820cc486a21cd4820cc4820cd486a21" - "ce4820cd4820ce486a21cf4820ce4820cf486a21d04820cf4820d0486a21d14820d04820d1486a21d24820d14820d2" - "486a21d34820d24820d3486a21d44820d34820d4486a21d54820d44820d5486a21d64820d54820d6486a21d74820d6" - "4820d7486a21d84820d74820d8486a21d94820d84820d9486a21da4820d94820da486a21db4820da4820db486a21dc" - "4820db4820dc486a21dd4820dc4820dd486a21de4820dd4820de486a21df4820de4820df486a21e04820df4820e048" - "6a21e14820e04820e1486a21e24820e14820e2486a21e34820e24820e3486a21e44820e34820e4486a21e54820e448" - "20e5486a21e64820e54820e6486a21e74820e64820e7486a21e84820e74820e8486a21e94820e84820e9486a21ea48" - "20e94820ea486a21eb4820ea4820eb486a21ec4820eb4820ec486a21ed4820ec4820ed486a21ee4820ed4820ee486a" - "21ef4820ee4820ef486a21f04820ef4820f0486a21f14820f04820f1486a21f24820f14820f2486a21f34820f24820" - "f3486a21f44820f34820f4486a21f54820f44820f5486a21f64820f54820f6486a21f74820f64820f7486a21f84820" - "f74820f8486a21f94820f84820f9486a21fa4820f94820fa486a21fb4820fa4820fb486a21fc4820fb4820fc486a21" - "fd4820fc4820fd486a21fe4820fd4820fe486a21ff4820fe4820ff486a21804920ff482080496a2181492080492081" - "496a2182492081492082496a2183492082492083496a2184492083492084496a2185492084492085496a2186492085" - "492086496a2187492086492087496a2188492087492088496a2189492088492089496a218a49208949208a496a218b" - "49208a49208b496a218c49208b49208c496a218d49208c49208d496a218e49208d49208e496a218f49208e49208f49" - "6a219049208f492090496a2191492090492091496a2192492091492092496a2193492092492093496a219449209349" - "2094496a2195492094492095496a2196492095492096496a2197492096492097496a2198492097492098496a219949" - "2098492099496a219a49209949209a496a219b49209a49209b496a219c49209b49209c496a219d49209c49209d496a" - "219e49209d49209e496a219f49209e49209f496a21a049209f4920a0496a21a14920a04920a1496a21a24920a14920" - "a2496a21a34920a24920a3496a21a44920a34920a4496a21a54920a44920a5496a21a64920a54920a6496a21a74920" - "a64920a7496a21a84920a74920a8496a21a94920a84920a9496a21aa4920a94920aa496a21ab4920aa4920ab496a21" - "ac4920ab4920ac496a21ad4920ac4920ad496a21ae4920ad4920ae496a21af4920ae4920af496a21b04920af4920b0" - "496a21b14920b04920b1496a21b24920b14920b2496a21b34920b24920b3496a21b44920b34920b4496a21b54920b4" - "4920b5496a21b64920b54920b6496a21b74920b64920b7496a21b84920b74920b8496a21b94920b84920b9496a21ba" - "4920b94920ba496a21bb4920ba4920bb496a21bc4920bb4920bc496a21bd4920bc4920bd496a21be4920bd4920be49" - "6a21bf4920be4920bf496a21c04920bf4920c0496a21c14920c04920c1496a21c24920c14920c2496a21c34920c249" - "20c3496a21c44920c34920c4496a21c54920c44920c5496a21c64920c54920c6496a21c74920c64920c7496a21c849" - "20c74920c8496a21c94920c84920c9496a21ca4920c94920ca496a21cb4920ca4920cb496a21cc4920cb4920cc496a" - "21cd4920cc4920cd496a21ce4920cd4920ce496a21cf4920ce4920cf496a21d04920cf4920d0496a21d14920d04920" - "d1496a21d24920d14920d2496a21d34920d24920d3496a21d44920d34920d4496a21d54920d44920d5496a21d64920" - "d54920d6496a21d74920d64920d7496a21d84920d74920d8496a21d94920d84920d9496a21da4920d94920da496a21" - "db4920da4920db496a21dc4920db4920dc496a21dd4920dc4920dd496a21de4920dd4920de496a21df4920de4920df" - "496a21e04920df4920e0496a21e14920e04920e1496a21e24920e14920e2496a21e34920e24920e3496a21e44920e3" - "4920e4496a21e54920e44920e5496a21e64920e54920e6496a21e74920e64920e7496a21e84920e74920e8496a21e9" - "4920e84920e9496a21ea4920e94920ea496a21eb4920ea4920eb496a21ec4920eb4920ec496a21ed4920ec4920ed49" - "6a21ee4920ed4920ee496a21ef4920ee4920ef496a21f04920ef4920f0496a21f14920f04920f1496a21f24920f149" - "20f2496a21f34920f24920f3496a21f44920f34920f4496a21f54920f44920f5496a21f64920f54920f6496a21f749" - "20f64920f7496a21f84920f74920f8496a21f94920f84920f9496a21fa4920f94920fa496a21fb4920fa4920fb496a" - "21fc4920fb4920fc496a21fd4920fc4920fd496a21fe4920fd4920fe496a21ff4920fe4920ff496a21804a20ff4920" - "804a6a21814a20804a20814a6a21824a20814a20824a6a21834a20824a20834a6a21844a20834a20844a6a21854a20" - "844a20854a6a21864a20854a20864a6a21874a20864a20874a6a21884a20874a20884a6a21894a20884a20894a6a21" - "8a4a20894a208a4a6a218b4a208a4a208b4a6a218c4a208b4a208c4a6a218d4a208c4a208d4a6a218e4a208d4a208e" - "4a6a218f4a208e4a208f4a6a21904a208f4a20904a6a21914a20904a20914a6a21924a20914a20924a6a21934a2092" - "4a20934a6a21944a20934a20944a6a21954a20944a20954a6a21964a20954a20964a6a21974a20964a20974a6a2198" - "4a20974a20984a6a21994a20984a20994a6a219a4a20994a209a4a6a219b4a209a4a209b4a6a219c4a209b4a209c4a" - "6a219d4a209c4a209d4a6a219e4a209d4a209e4a6a219f4a209e4a209f4a6a21a04a209f4a20a04a6a21a14a20a04a" - "20a14a6a21a24a20a14a20a24a6a21a34a20a24a20a34a6a21a44a20a34a20a44a6a21a54a20a44a20a54a6a21a64a" - "20a54a20a64a6a21a74a20a64a20a74a6a21a84a20a74a20a84a6a21a94a20a84a20a94a6a21aa4a20a94a20aa4a6a" - "21ab4a20aa4a20ab4a6a21ac4a20ab4a20ac4a6a21ad4a20ac4a20ad4a6a21ae4a20ad4a20ae4a6a21af4a20ae4a20" - "af4a6a21b04a20af4a20b04a6a21b14a20b04a20b14a6a21b24a20b14a20b24a6a21b34a20b24a20b34a6a21b44a20" - "b34a20b44a6a21b54a20b44a20b54a6a21b64a20b54a20b64a6a21b74a20b64a20b74a6a21b84a20b74a20b84a6a21" - "b94a20b84a20b94a6a21ba4a20b94a20ba4a6a21bb4a20ba4a20bb4a6a21bc4a20bb4a20bc4a6a21bd4a20bc4a20bd" - "4a6a21be4a20bd4a20be4a6a21bf4a20be4a20bf4a6a21c04a20bf4a20c04a6a21c14a20c04a20c14a6a21c24a20c1" - "4a20c24a6a21c34a20c24a20c34a6a21c44a20c34a20c44a6a21c54a20c44a20c54a6a21c64a20c54a20c64a6a21c7" - "4a20c64a20c74a6a21c84a20c74a20c84a6a21c94a20c84a20c94a6a21ca4a20c94a20ca4a6a21cb4a20ca4a20cb4a" - "6a21cc4a20cb4a20cc4a6a21cd4a20cc4a20cd4a6a21ce4a20cd4a20ce4a6a21cf4a20ce4a20cf4a6a21d04a20cf4a" - "20d04a6a21d14a20d04a20d14a6a21d24a20d14a20d24a6a21d34a20d24a20d34a6a21d44a20d34a20d44a6a21d54a" - "20d44a20d54a6a21d64a20d54a20d64a6a21d74a20d64a20d74a6a21d84a20d74a20d84a6a21d94a20d84a20d94a6a" - "21da4a20d94a20da4a6a21db4a20da4a20db4a6a21dc4a20db4a20dc4a6a21dd4a20dc4a20dd4a6a21de4a20dd4a20" - "de4a6a21df4a20de4a20df4a6a21e04a20df4a20e04a6a21e14a20e04a20e14a6a21e24a20e14a20e24a6a21e34a20" - "e24a20e34a6a21e44a20e34a20e44a6a21e54a20e44a20e54a6a21e64a20e54a20e64a6a21e74a20e64a20e74a6a21" - "e84a20e74a20e84a6a21e94a20e84a20e94a6a21ea4a20e94a20ea4a6a21eb4a20ea4a20eb4a6a21ec4a20eb4a20ec" - "4a6a21ed4a20ec4a20ed4a6a21ee4a20ed4a20ee4a6a21ef4a20ee4a20ef4a6a21f04a20ef4a20f04a6a21f14a20f0" - "4a20f14a6a21f24a20f14a20f24a6a21f34a20f24a20f34a6a21f44a20f34a20f44a6a21f54a20f44a20f54a6a21f6" - "4a20f54a20f64a6a21f74a20f64a20f74a6a21f84a20f74a20f84a6a21f94a20f84a20f94a6a21fa4a20f94a20fa4a" - "6a21fb4a20fa4a20fb4a6a21fc4a20fb4a20fc4a6a21fd4a20fc4a20fd4a6a21fe4a20fd4a20fe4a6a21ff4a20fe4a" - "20ff4a6a21804b20ff4a20804b6a21814b20804b20814b6a21824b20814b20824b6a21834b20824b20834b6a21844b" - "20834b20844b6a21854b20844b20854b6a21864b20854b20864b6a21874b20864b20874b6a21884b20874b20884b6a" - "21894b20884b20894b6a218a4b20894b208a4b6a218b4b208a4b208b4b6a218c4b208b4b208c4b6a218d4b208c4b20" - "8d4b6a218e4b208d4b208e4b6a218f4b208e4b208f4b6a21904b208f4b20904b6a21914b20904b20914b6a21924b20" - "914b20924b6a21934b20924b20934b6a21944b20934b20944b6a21954b20944b20954b6a21964b20954b20964b6a21" - "974b20964b20974b6a21984b20974b20984b6a21994b20984b20994b6a219a4b20994b209a4b6a219b4b209a4b209b" - "4b6a219c4b209b4b209c4b6a219d4b209c4b209d4b6a219e4b209d4b209e4b6a219f4b209e4b209f4b6a21a04b209f" - "4b20a04b6a21a14b20a04b20a14b6a21a24b20a14b20a24b6a21a34b20a24b20a34b6a21a44b20a34b20a44b6a21a5" - "4b20a44b20a54b6a21a64b20a54b20a64b6a21a74b20a64b20a74b6a21a84b20a74b20a84b6a21a94b20a84b20a94b" - "6a21aa4b20a94b20aa4b6a21ab4b20aa4b20ab4b6a21ac4b20ab4b20ac4b6a21ad4b20ac4b20ad4b6a21ae4b20ad4b" - "20ae4b6a21af4b20ae4b20af4b6a21b04b20af4b20b04b6a21b14b20b04b20b14b6a21b24b20b14b20b24b6a21b34b" - "20b24b20b34b6a21b44b20b34b20b44b6a21b54b20b44b20b54b6a21b64b20b54b20b64b6a21b74b20b64b20b74b6a" - "21b84b20b74b20b84b6a21b94b20b84b20b94b6a21ba4b20b94b20ba4b6a21bb4b20ba4b20bb4b6a21bc4b20bb4b20" - "bc4b6a21bd4b20bc4b20bd4b6a21be4b20bd4b20be4b6a21bf4b20be4b20bf4b6a21c04b20bf4b20c04b6a21c14b20" - "c04b20c14b6a21c24b20c14b20c24b6a21c34b20c24b20c34b6a21c44b20c34b20c44b6a21c54b20c44b20c54b6a21" - "c64b20c54b20c64b6a21c74b20c64b20c74b6a21c84b20c74b20c84b6a21c94b20c84b20c94b6a21ca4b20c94b20ca" - "4b6a21cb4b20ca4b20cb4b6a21cc4b20cb4b20cc4b6a21cd4b20cc4b20cd4b6a21ce4b20cd4b20ce4b6a21cf4b20ce" - "4b20cf4b6a21d04b20cf4b20d04b6a21d14b20d04b20d14b6a21d24b20d14b20d24b6a21d34b20d24b20d34b6a21d4" - "4b20d34b20d44b6a21d54b20d44b20d54b6a21d64b20d54b20d64b6a21d74b20d64b20d74b6a21d84b20d74b20d84b" - "6a21d94b20d84b20d94b6a21da4b20d94b20da4b6a21db4b20da4b20db4b6a21dc4b20db4b20dc4b6a21dd4b20dc4b" - "20dd4b6a21de4b20dd4b20de4b6a21df4b20de4b20df4b6a21e04b20df4b20e04b6a21e14b20e04b20e14b6a21e24b" - "20e14b20e24b6a21e34b20e24b20e34b6a21e44b20e34b20e44b6a21e54b20e44b20e54b6a21e64b20e54b20e64b6a" - "21e74b20e64b20e74b6a21e84b20e74b20e84b6a21e94b20e84b20e94b6a21ea4b20e94b20ea4b6a21eb4b20ea4b20" - "eb4b6a21ec4b20eb4b20ec4b6a21ed4b20ec4b20ed4b6a21ee4b20ed4b20ee4b6a21ef4b20ee4b20ef4b6a21f04b20" - "ef4b20f04b6a21f14b20f04b20f14b6a21f24b20f14b20f24b6a21f34b20f24b20f34b6a21f44b20f34b20f44b6a21" - "f54b20f44b20f54b6a21f64b20f54b20f64b6a21f74b20f64b20f74b6a21f84b20f74b20f84b6a21f94b20f84b20f9" - "4b6a21fa4b20f94b20fa4b6a21fb4b20fa4b20fb4b6a21fc4b20fb4b20fc4b6a21fd4b20fc4b20fd4b6a21fe4b20fd" - "4b20fe4b6a21ff4b20fe4b20ff4b6a21804c20ff4b20804c6a21814c20804c20814c6a21824c20814c20824c6a2183" - "4c20824c20834c6a21844c20834c20844c6a21854c20844c20854c6a21864c20854c20864c6a21874c20864c20874c" - "6a21884c20874c20884c6a21894c20884c20894c6a218a4c20894c208a4c6a218b4c208a4c208b4c6a218c4c208b4c" - "208c4c6a218d4c208c4c208d4c6a218e4c208d4c208e4c6a218f4c208e4c208f4c6a21904c208f4c20904c6a21914c" - "20904c20914c6a21924c20914c20924c6a21934c20924c20934c6a21944c20934c20944c6a21954c20944c20954c6a" - "21964c20954c20964c6a21974c20964c20974c6a21984c20974c20984c6a21994c20984c20994c6a219a4c20994c20" - "9a4c6a219b4c209a4c209b4c6a219c4c209b4c209c4c6a219d4c209c4c209d4c6a219e4c209d4c209e4c6a219f4c20" - "9e4c209f4c6a21a04c209f4c20a04c6a21a14c20a04c20a14c6a21a24c20a14c20a24c6a21a34c20a24c20a34c6a21" - "a44c20a34c20a44c6a21a54c20a44c20a54c6a21a64c20a54c20a64c6a21a74c20a64c20a74c6a21a84c20a74c20a8" - "4c6a21a94c20a84c20a94c6a21aa4c20a94c20aa4c6a21ab4c20aa4c20ab4c6a21ac4c20ab4c20ac4c6a21ad4c20ac" - "4c20ad4c6a21ae4c20ad4c20ae4c6a21af4c20ae4c20af4c6a21b04c20af4c20b04c6a21b14c20b04c20b14c6a21b2" - "4c20b14c20b24c6a21b34c20b24c20b34c6a21b44c20b34c20b44c6a21b54c20b44c20b54c6a21b64c20b54c20b64c" - "6a21b74c20b64c20b74c6a21b84c20b74c20b84c6a21b94c20b84c20b94c6a21ba4c20b94c20ba4c6a21bb4c20ba4c" - "20bb4c6a21bc4c20bb4c20bc4c6a21bd4c20bc4c20bd4c6a21be4c20bd4c20be4c6a21bf4c20be4c20bf4c6a21c04c" - "20bf4c20c04c6a21c14c20c04c20c14c6a21c24c20c14c20c24c6a21c34c20c24c20c34c6a21c44c20c34c20c44c6a" - "21c54c20c44c20c54c6a21c64c20c54c20c64c6a21c74c20c64c20c74c6a21c84c20c74c20c84c6a21c94c20c84c20" - "c94c6a21ca4c20c94c20ca4c6a21cb4c20ca4c20cb4c6a21cc4c20cb4c20cc4c6a21cd4c20cc4c20cd4c6a21ce4c20" - "cd4c20ce4c6a21cf4c20ce4c20cf4c6a21d04c20cf4c20d04c6a21d14c20d04c20d14c6a21d24c20d14c20d24c6a21" - "d34c20d24c20d34c6a21d44c20d34c20d44c6a21d54c20d44c20d54c6a21d64c20d54c20d64c6a21d74c20d64c20d7" - "4c6a21d84c20d74c20d84c6a21d94c20d84c20d94c6a21da4c20d94c20da4c6a21db4c20da4c20db4c6a21dc4c20db" - "4c20dc4c6a21dd4c20dc4c20dd4c6a21de4c20dd4c20de4c6a21df4c20de4c20df4c6a21e04c20df4c20e04c6a21e1" - "4c20e04c20e14c6a21e24c20e14c20e24c6a21e34c20e24c20e34c6a21e44c20e34c20e44c6a21e54c20e44c20e54c" - "6a21e64c20e54c20e64c6a21e74c20e64c20e74c6a21e84c20e74c20e84c6a21e94c20e84c20e94c6a21ea4c20e94c" - "20ea4c6a21eb4c20ea4c20eb4c6a21ec4c20eb4c20ec4c6a21ed4c20ec4c20ed4c6a21ee4c20ed4c20ee4c6a21ef4c" - "20ee4c20ef4c6a21f04c20ef4c20f04c6a21f14c20f04c20f14c6a21f24c20f14c20f24c6a21f34c20f24c20f34c6a" - "21f44c20f34c20f44c6a21f54c20f44c20f54c6a21f64c20f54c20f64c6a21f74c20f64c20f74c6a21f84c20f74c20" - "f84c6a21f94c20f84c20f94c6a21fa4c20f94c20fa4c6a21fb4c20fa4c20fb4c6a21fc4c20fb4c20fc4c6a21fd4c20" - "fc4c20fd4c6a21fe4c20fd4c20fe4c6a21ff4c20fe4c20ff4c6a21804d20ff4c20804d6a21814d20804d20814d6a21" - "824d20814d20824d6a21834d20824d20834d6a21844d20834d20844d6a21854d20844d20854d6a21864d20854d2086" - "4d6a21874d20864d20874d6a21884d20874d20884d6a21894d20884d20894d6a218a4d20894d208a4d6a218b4d208a" - "4d208b4d6a218c4d208b4d208c4d6a218d4d208c4d208d4d6a218e4d208d4d208e4d6a218f4d208e4d208f4d6a2190" - "4d208f4d20904d6a21914d20904d20914d6a21924d20914d20924d6a21934d20924d20934d6a21944d20934d20944d" - "6a21954d20944d20954d6a21964d20954d20964d6a21974d20964d20974d6a21984d20974d20984d6a21994d20984d" - "20994d6a219a4d20994d209a4d6a219b4d209a4d209b4d6a219c4d209b4d209c4d6a219d4d209c4d209d4d6a219e4d" - "209d4d209e4d6a219f4d209e4d209f4d6a21a04d209f4d20a04d6a21a14d20a04d20a14d6a21a24d20a14d20a24d6a" - "21a34d20a24d20a34d6a21a44d20a34d20a44d6a21a54d20a44d20a54d6a21a64d20a54d20a64d6a21a74d20a64d20" - "a74d6a21a84d20a74d20a84d6a21a94d20a84d20a94d6a21aa4d20a94d20aa4d6a21ab4d20aa4d20ab4d6a21ac4d20" - "ab4d20ac4d6a21ad4d20ac4d20ad4d6a21ae4d20ad4d20ae4d6a21af4d20ae4d20af4d6a21b04d20af4d20b04d6a21" - "b14d20b04d20b14d6a21b24d20b14d20b24d6a21b34d20b24d20b34d6a21b44d20b34d20b44d6a21b54d20b44d20b5" - "4d6a21b64d20b54d20b64d6a21b74d20b64d20b74d6a21b84d20b74d20b84d6a21b94d20b84d20b94d6a21ba4d20b9" - "4d20ba4d6a21bb4d20ba4d20bb4d6a21bc4d20bb4d20bc4d6a21bd4d20bc4d20bd4d6a21be4d20bd4d20be4d6a21bf" - "4d20be4d20bf4d6a21c04d20bf4d20c04d6a21c14d20c04d20c14d6a21c24d20c14d20c24d6a21c34d20c24d20c34d" - "6a21c44d20c34d20c44d6a21c54d20c44d20c54d6a21c64d20c54d20c64d6a21c74d20c64d20c74d6a21c84d20c74d" - "20c84d6a21c94d20c84d20c94d6a21ca4d20c94d20ca4d6a21cb4d20ca4d20cb4d6a21cc4d20cb4d20cc4d6a21cd4d" - "20cc4d20cd4d6a21ce4d20cd4d20ce4d6a21cf4d20ce4d20cf4d6a21d04d20cf4d20d04d6a21d14d20d04d20d14d6a" - "21d24d20d14d20d24d6a21d34d20d24d20d34d6a21d44d20d34d20d44d6a21d54d20d44d20d54d6a21d64d20d54d20" - "d64d6a21d74d20d64d20d74d6a21d84d20d74d20d84d6a21d94d20d84d20d94d6a21da4d20d94d20da4d6a21db4d20" - "da4d20db4d6a21dc4d20db4d20dc4d6a21dd4d20dc4d20dd4d6a21de4d20dd4d20de4d6a21df4d20de4d20df4d6a21" - "e04d20df4d20e04d6a21e14d20e04d20e14d6a21e24d20e14d20e24d6a21e34d20e24d20e34d6a21e44d20e34d20e4" - "4d6a21e54d20e44d20e54d6a21e64d20e54d20e64d6a21e74d20e64d20e74d6a21e84d20e74d20e84d6a21e94d20e8" - "4d20e94d6a21ea4d20e94d20ea4d6a21eb4d20ea4d20eb4d6a21ec4d20eb4d20ec4d6a21ed4d20ec4d20ed4d6a21ee" - "4d20ed4d20ee4d6a21ef4d20ee4d20ef4d6a21f04d20ef4d20f04d6a21f14d20f04d20f14d6a21f24d20f14d20f24d" - "6a21f34d20f24d20f34d6a21f44d20f34d20f44d6a21f54d20f44d20f54d6a21f64d20f54d20f64d6a21f74d20f64d" - "20f74d6a21f84d20f74d20f84d6a21f94d20f84d20f94d6a21fa4d20f94d20fa4d6a21fb4d20fa4d20fb4d6a21fc4d" - "20fb4d20fc4d6a21fd4d20fc4d20fd4d6a21fe4d20fd4d20fe4d6a21ff4d20fe4d20ff4d6a21804e20ff4d20804e6a" - "21814e20804e20814e6a21824e20814e20824e6a21834e20824e20834e6a21844e20834e20844e6a21854e20844e20" - "854e6a21864e20854e20864e6a21874e20864e20874e6a21884e20874e20884e6a21894e20884e20894e6a218a4e20" - "894e208a4e6a218b4e208a4e208b4e6a218c4e208b4e208c4e6a218d4e208c4e208d4e6a218e4e208d4e208e4e6a21" - "8f4e208f4e0b"; diff --git a/src/test/app/wasm_fixtures/float_0/Cargo.lock b/src/test/app/wasm_fixtures/float_0/Cargo.lock deleted file mode 100644 index 690b1b51f3..0000000000 --- a/src/test/app/wasm_fixtures/float_0/Cargo.lock +++ /dev/null @@ -1,171 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "block-buffer" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "digest" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", -] - -[[package]] -name = "float_0" -version = "0.0.1" -dependencies = [ - "xrpl-wasm-stdlib", -] - -[[package]] -name = "hybrid-array" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" -dependencies = [ - "typenum", -] - -[[package]] -name = "libc" -version = "0.2.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "sha2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "syn" -version = "2.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tinyvec" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "typenum" -version = "1.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "xrpl-macros" -version = "0.1.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=renames#6b35fe45ac70bad38914e7f319d31d7947e05e25" -dependencies = [ - "bs58", - "proc-macro2", - "quote", - "sha2", - "syn", -] - -[[package]] -name = "xrpl-wasm-stdlib" -version = "0.8.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=renames#6b35fe45ac70bad38914e7f319d31d7947e05e25" -dependencies = [ - "xrpl-macros", -] diff --git a/src/test/app/wasm_fixtures/float_0/Cargo.toml b/src/test/app/wasm_fixtures/float_0/Cargo.toml deleted file mode 100644 index 95254f2e2b..0000000000 --- a/src/test/app/wasm_fixtures/float_0/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "float_0" -version = "0.0.1" -edition = "2024" - -# This empty workspace definition keeps this project independent of the parent workspace -[workspace] - -[lib] -crate-type = ["cdylib"] - -[profile.release] -lto = true -opt-level = 's' -panic = "abort" - -[dependencies] -xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-wasm-stdlib", branch = "renames" } - -[profile.dev] -panic = "abort" diff --git a/src/test/app/wasm_fixtures/float_0/src/lib.rs b/src/test/app/wasm_fixtures/float_0/src/lib.rs deleted file mode 100644 index 5f6c8f0770..0000000000 --- a/src/test/app/wasm_fixtures/float_0/src/lib.rs +++ /dev/null @@ -1,70 +0,0 @@ -#![cfg_attr(target_arch = "wasm32", no_std)] - -use xrpl_std::host::trace::trace; -use xrpl_std::host::{float_cmp, float_from_int, float_sub, FLOAT_ROUNDING_MODES_TO_NEAREST}; - -// Float size constant (8 bytes mantissa + 4 bytes exponent) -const FLOAT_SIZE: usize = 12; - -// FLOAT_ZERO constant -const FLOAT_ZERO: [u8; FLOAT_SIZE] = [ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, -]; - -#[unsafe(no_mangle)] -pub extern "C" fn escrow_finish() -> i32 { - let _ = trace("\n$$$ test_float_0 $$$"); - - // Test: 10 - 10 should equal 0 - let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - let mut f_result: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - - // Create float from 10 - if FLOAT_SIZE as i32 - != unsafe { - float_from_int( - 10, - f10.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - } - { - let _ = trace(" float 10-10: failed"); - return 1; - } - - // Subtract: 10 - 10 = 0 - if FLOAT_SIZE as i32 - != unsafe { - float_sub( - f10.as_ptr(), - FLOAT_SIZE, - f10.as_ptr(), - FLOAT_SIZE, - f_result.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - } - { - let _ = trace(" float 10-10: failed"); - return 1; - } - - // Compare result with FLOAT_ZERO constant - if 0 == unsafe { - float_cmp( - f_result.as_ptr(), - FLOAT_SIZE, - FLOAT_ZERO.as_ptr(), - FLOAT_SIZE, - ) - } { - let _ = trace(" FLOAT_ZERO compare: good"); - } else { - let _ = trace(" FLOAT_ZERO compare: bad"); - } - - 1 -} diff --git a/src/test/app/wasm_fixtures/float_tests/Cargo.lock b/src/test/app/wasm_fixtures/float_tests/Cargo.lock deleted file mode 100644 index 92158d3262..0000000000 --- a/src/test/app/wasm_fixtures/float_tests/Cargo.lock +++ /dev/null @@ -1,171 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "block-buffer" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "digest" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" -dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", -] - -[[package]] -name = "float_tests" -version = "0.0.1" -dependencies = [ - "xrpl-wasm-stdlib", -] - -[[package]] -name = "hybrid-array" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c" -dependencies = [ - "typenum", -] - -[[package]] -name = "libc" -version = "0.2.177" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" - -[[package]] -name = "proc-macro2" -version = "1.0.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "sha2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "syn" -version = "2.0.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "typenum" -version = "1.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" - -[[package]] -name = "unicode-ident" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" - -[[package]] -name = "xrpl-macros" -version = "0.1.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=renames#6b35fe45ac70bad38914e7f319d31d7947e05e25" -dependencies = [ - "bs58", - "proc-macro2", - "quote", - "sha2", - "syn", -] - -[[package]] -name = "xrpl-wasm-stdlib" -version = "0.8.0" -source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git?branch=renames#6b35fe45ac70bad38914e7f319d31d7947e05e25" -dependencies = [ - "xrpl-macros", -] diff --git a/src/test/app/wasm_fixtures/float_tests/Cargo.toml b/src/test/app/wasm_fixtures/float_tests/Cargo.toml deleted file mode 100644 index d4f70f1afc..0000000000 --- a/src/test/app/wasm_fixtures/float_tests/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "float_tests" -version = "0.0.1" -edition = "2024" - -# This empty workspace definition keeps this project independent of the parent workspace -[workspace] - -[lib] -crate-type = ["cdylib"] - -[profile.release] -lto = true -opt-level = 's' -panic = "abort" - -[dependencies] -xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-wasm-stdlib", branch = "renames" } - -[profile.dev] -panic = "abort" diff --git a/src/test/app/wasm_fixtures/float_tests/src/lib.rs b/src/test/app/wasm_fixtures/float_tests/src/lib.rs deleted file mode 100644 index b5e6aa6185..0000000000 --- a/src/test/app/wasm_fixtures/float_tests/src/lib.rs +++ /dev/null @@ -1,1112 +0,0 @@ -#![allow(unused_imports)] -#![allow(unused_variables)] -#![cfg_attr(target_arch = "wasm32", no_std)] - -#[cfg(not(target_arch = "wasm32"))] -extern crate std; - -use xrpl_std::core::locator::Locator; -use xrpl_std::decode_hex_32; -use xrpl_std::host::trace::DataRepr::AsHex; -use xrpl_std::host::trace::{trace, trace_data, trace_num, DataRepr}; -use xrpl_std::host::{ - cache_le, float_add, float_cmp, float_div, float_from_int, float_from_uint, float_mult, - float_pow, float_root, float_sub, le_field, le_inner, le_inner_arr_len, - FLOAT_ROUNDING_MODES_TO_NEAREST, -}; -use xrpl_std::sfield; -use xrpl_std::sfield::{ - Account, AccountTxnID, Balance, Domain, EmailHash, Flags, LedgerEntryType, MessageKey, - OwnerCount, PreviousTxnID, PreviousTxnLgrSeq, RegularKey, Sequence, TicketCount, TransferRate, -}; - -// External host functions not yet in xrpl_std -unsafe extern "C" { - #[link_name = "float_from_stamount"] - fn float_from_stamount( - amount_ptr: *const u8, - amount_len: i32, - out_ptr: *mut u8, - out_len: i32, - rounding: i32, - ) -> i32; - - #[link_name = "float_from_stnumber"] - fn float_from_stnumber( - number_ptr: *const u8, - number_len: i32, - out_ptr: *mut u8, - out_len: i32, - rounding: i32, - ) -> i32; - - #[link_name = "float_to_int"] - fn float_to_int( - float_ptr: *const u8, - float_len: i32, - out_ptr: *mut u8, - out_len: i32, - rounding: i32, - ) -> i32; - - #[link_name = "float_to_mant_exp"] - fn float_to_mant_exp( - float_ptr: *const u8, - float_len: i32, - mantissa_ptr: *mut u8, - mantissa_len: i32, - exponent_ptr: *mut u8, - exponent_len: i32, - ) -> i32; - - #[link_name = "float_from_mant_exp"] - fn float_from_mant_exp( - mantissa: i64, - exponent: i32, - out_ptr: *mut u8, - out_len: i32, - rounding: i32, - ) -> i32; -} - -// Float size constant (8 bytes mantissa + 4 bytes exponent) -const FLOAT_SIZE: usize = 12; - -// Float constants (8 bytes mantissa + 4 bytes exponent, big-endian) -// FLOAT_ONE: mantissa=0x0DE0B6B3A7640000 (10^18), exponent=0xFFFFFFEE (-18) -const FLOAT_ONE: [u8; FLOAT_SIZE] = [ - 0x0D, 0xE0, 0xB6, 0xB3, 0xA7, 0x64, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xEE, -]; -// FLOAT_NEGATIVE_ONE: mantissa=0xF21F494C589C0000 (-10^18), exponent=0xFFFFFFEE (-18) -const FLOAT_NEGATIVE_ONE: [u8; FLOAT_SIZE] = [ - 0xF2, 0x1F, 0x49, 0x4C, 0x58, 0x9C, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xEE, -]; - -// Helper function to trace floats -fn trace_float(msg: &str, f: &[u8; FLOAT_SIZE]) { - let _ = trace(msg); - let _ = trace_data(" ", f, AsHex); -} - -fn test_float_from_wasm() -> bool { - let _ = trace("\n$$$ test_float_from_wasm $$$"); - let mut all_pass = true; - - let mut f: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - if FLOAT_SIZE as i32 - == unsafe { - float_from_int( - 12300, - f.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - } - { - let _ = trace_float(" float from i64 12300:", &f); - let _ = trace_data(" float from i64 12300 as HEX:", &f, AsHex); - } else { - let _ = trace(" float from i64 12300: failed"); - all_pass = false; - } - - let u64_value: u64 = 12300; - if FLOAT_SIZE as i32 - == unsafe { - float_from_uint( - &u64_value as *const u64 as *const u8, - 8, - f.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - } - { - let _ = trace_float(" float from u64 12300:", &f); - } else { - let _ = trace(" float from u64 12300: failed"); - all_pass = false; - } - - if FLOAT_SIZE as i32 - == unsafe { - float_from_mant_exp( - 123, - 2, - f.as_mut_ptr(), - FLOAT_SIZE as i32, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - } - { - let _ = trace_float(" float from exp 2, mantissa 123:", &f); - } else { - let _ = trace(" float from exp 2, mantissa 123: failed"); - all_pass = false; - } - - let _ = trace_float(" float from const 1:", &FLOAT_ONE); - let _ = trace_float(" float from const -1:", &FLOAT_NEGATIVE_ONE); - - all_pass -} - -fn test_float_cmp() -> bool { - let _ = trace("\n$$$ test_float_cmp $$$"); - let mut all_pass = true; - - let mut f1: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - if FLOAT_SIZE as i32 - != unsafe { - float_from_int( - 1, - f1.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - } - { - let _ = trace(" float from 1: failed"); - all_pass = false; - } else { - let _ = trace_float(" float from 1:", &f1); - } - - if 0 == unsafe { float_cmp(f1.as_ptr(), FLOAT_SIZE, FLOAT_ONE.as_ptr(), FLOAT_SIZE) } { - let _ = trace(" float from 1 == FLOAT_ONE"); - } else { - let _ = trace(" float from 1 != FLOAT_ONE, failed"); - all_pass = false; - } - - if 1 == unsafe { - float_cmp( - f1.as_ptr(), - FLOAT_SIZE, - FLOAT_NEGATIVE_ONE.as_ptr(), - FLOAT_SIZE, - ) - } { - let _ = trace(" float from 1 > FLOAT_NEGATIVE_ONE"); - } else { - let _ = trace(" float from 1 !> FLOAT_NEGATIVE_ONE, failed"); - all_pass = false; - } - - if 2 == unsafe { - float_cmp( - FLOAT_NEGATIVE_ONE.as_ptr(), - FLOAT_SIZE, - f1.as_ptr(), - FLOAT_SIZE, - ) - } { - let _ = trace(" FLOAT_NEGATIVE_ONE < float from 1"); - } else { - let _ = trace(" FLOAT_NEGATIVE_ONE !< float from 1, failed"); - all_pass = false; - } - - all_pass -} - -fn test_float_add_subtract() -> bool { - let _ = trace("\n$$$ test_float_add_subtract $$$"); - let mut all_pass = true; - - let mut f_compute: [u8; FLOAT_SIZE] = FLOAT_ONE; - for i in 0..9 { - unsafe { - float_add( - f_compute.as_ptr(), - FLOAT_SIZE, - FLOAT_ONE.as_ptr(), - FLOAT_SIZE, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - // let _ = trace_float(" float:", &f_compute); - } - let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - if FLOAT_SIZE as i32 - != unsafe { - float_from_int( - 10, - f10.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - } - { - let _ = trace(" float from 10: failed"); - all_pass = false; - } - - if 0 == unsafe { float_cmp(f10.as_ptr(), FLOAT_SIZE, f_compute.as_ptr(), FLOAT_SIZE) } { - let _ = trace(" repeated add: good"); - } else { - let _ = trace(" repeated add: failed"); - all_pass = false; - } - - for i in 0..11 { - unsafe { - float_sub( - f_compute.as_ptr(), - FLOAT_SIZE, - FLOAT_ONE.as_ptr(), - FLOAT_SIZE, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - } - if 0 == unsafe { - float_cmp( - f_compute.as_ptr(), - FLOAT_SIZE, - FLOAT_NEGATIVE_ONE.as_ptr(), - FLOAT_SIZE, - ) - } { - let _ = trace(" repeated subtract: good"); - } else { - let _ = trace(" repeated subtract: failed"); - all_pass = false; - } - - all_pass -} - -fn test_float_mult_divide() -> bool { - let _ = trace("\n$$$ test_float_mult_divide $$$"); - let mut all_pass = true; - - let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - 10, - f10.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let mut f_compute: [u8; FLOAT_SIZE] = FLOAT_ONE; - for i in 0..6 { - unsafe { - float_mult( - f_compute.as_ptr(), - FLOAT_SIZE, - f10.as_ptr(), - FLOAT_SIZE, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - // let _ = trace_float(" float:", &f_compute); - } - let mut f1000000: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - 1000000, - f1000000.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - - if 0 == unsafe { - float_cmp( - f1000000.as_ptr(), - FLOAT_SIZE, - f_compute.as_ptr(), - FLOAT_SIZE, - ) - } { - let _ = trace(" repeated multiply: good"); - } else { - let _ = trace(" repeated multiply: failed"); - all_pass = false; - } - - for i in 0..7 { - unsafe { - float_div( - f_compute.as_ptr(), - FLOAT_SIZE, - f10.as_ptr(), - FLOAT_SIZE, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - } - let mut f01: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_mant_exp( - 1, - -1, - f01.as_mut_ptr(), - FLOAT_SIZE as i32, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - - if 0 == unsafe { float_cmp(f_compute.as_ptr(), FLOAT_SIZE, f01.as_ptr(), FLOAT_SIZE) } { - let _ = trace(" repeated divide: good"); - } else { - let _ = trace(" repeated divide: failed"); - all_pass = false; - } - - all_pass -} - -fn test_float_pow() -> bool { - let _ = trace("\n$$$ test_float_pow $$$"); - let mut all_pass = true; - - let mut f_compute: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_pow( - FLOAT_ONE.as_ptr(), - FLOAT_SIZE, - 3, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" float cube of 1:", &f_compute); - - unsafe { - float_pow( - FLOAT_NEGATIVE_ONE.as_ptr(), - FLOAT_SIZE, - 6, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" float 6th power of -1:", &f_compute); - - let mut f9: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - 9, - f9.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - unsafe { - float_pow( - f9.as_ptr(), - FLOAT_SIZE, - 2, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" float square of 9:", &f_compute); - - unsafe { - float_pow( - f9.as_ptr(), - FLOAT_SIZE, - 0, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" float 0th power of 9:", &f_compute); - - let mut f0: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - 0, - f0.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - unsafe { - float_pow( - f0.as_ptr(), - FLOAT_SIZE, - 2, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" float square of 0:", &f_compute); - - let r = unsafe { - float_pow( - f0.as_ptr(), - FLOAT_SIZE, - 0, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_num( - " float 0th power of 0 (expecting INVALID_PARAMS error):", - r as i64, - ); - - all_pass -} - -fn test_float_root() -> bool { - let _ = trace("\n$$$ test_float_root $$$"); - let mut all_pass = true; - - let mut f9: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - 9, - f9.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let mut f_compute: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_root( - f9.as_ptr(), - FLOAT_SIZE, - 2, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" float sqrt of 9:", &f_compute); - unsafe { - float_root( - f9.as_ptr(), - FLOAT_SIZE, - 3, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" float cbrt of 9:", &f_compute); - - let mut f1000000: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - 1000000, - f1000000.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - unsafe { - float_root( - f1000000.as_ptr(), - FLOAT_SIZE, - 3, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" float cbrt of 1000000:", &f_compute); - unsafe { - float_root( - f1000000.as_ptr(), - FLOAT_SIZE, - 6, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" float 6th root of 1000000:", &f_compute); - - all_pass -} - -fn test_float_invert() -> bool { - let _ = trace("\n$$$ test_float_invert $$$"); - let mut all_pass = true; - - let mut f_compute: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - 10, - f10.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - unsafe { - float_div( - FLOAT_ONE.as_ptr(), - FLOAT_SIZE, - f10.as_ptr(), - FLOAT_SIZE, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" invert a float from 10:", &f_compute); - unsafe { - float_div( - FLOAT_ONE.as_ptr(), - FLOAT_SIZE, - f_compute.as_ptr(), - FLOAT_SIZE, - f_compute.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let _ = trace_float(" invert again:", &f_compute); - - // if f10's value is 7, then invert twice won't match the original value - if 0 == unsafe { float_cmp(f10.as_ptr(), FLOAT_SIZE, f_compute.as_ptr(), FLOAT_SIZE) } { - let _ = trace(" invert twice: good"); - } else { - let _ = trace(" invert twice: failed"); - all_pass = false; - } - - all_pass -} - -fn test_float_to_int() -> bool { - let _ = trace("\n$$$ test_float_to_int $$$"); - let mut all_pass = true; - let mut result: [u8; 8] = [0u8; 8]; - - // Test converting FLOAT_ONE (value 1) to int - let ret = unsafe { - float_to_int( - FLOAT_ONE.as_ptr(), - FLOAT_SIZE as i32, - result.as_mut_ptr(), - 8, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - if ret == 8 { - let number = i64::from_le_bytes(result); - if number == 1 { - let _ = trace(" float_to_int(1): good"); - } else { - let _ = trace(" float_to_int(1): failed"); - let _ = trace_num(" got:", number); - all_pass = false; - } - } else { - let _ = trace(" float_to_int(1): failed with error"); - let _ = trace_num(" error code:", ret as i64); - all_pass = false; - } - - // Test converting FLOAT_NEGATIVE_ONE (value -1) to int - let ret = unsafe { - float_to_int( - FLOAT_NEGATIVE_ONE.as_ptr(), - FLOAT_SIZE as i32, - result.as_mut_ptr(), - 8, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - if ret == 8 { - let number = i64::from_le_bytes(result); - if number == -1 { - let _ = trace(" float_to_int(-1): good"); - } else { - let _ = trace(" float_to_int(-1): failed"); - let _ = trace_num(" got:", number); - all_pass = false; - } - } else { - let _ = trace(" float_to_int(-1): failed with error"); - let _ = trace_num(" error code:", ret as i64); - all_pass = false; - } - - // Test converting a larger number (i64::MAX) - let test_val: i64 = i64::MAX; - let mut f_max: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - test_val, - f_max.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let ret = unsafe { - float_to_int( - f_max.as_ptr(), - FLOAT_SIZE as i32, - result.as_mut_ptr(), - 8, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - if ret == 8 { - let number = i64::from_le_bytes(result); - if number == test_val { - let _ = trace(" float_to_int(i64::MAX): good"); - } else { - let _ = trace(" float_to_int(i64::MAX): failed"); - let _ = trace_num(" expected:", test_val); - let _ = trace_num(" got:", number); - all_pass = false; - } - } else { - let _ = trace(" float_to_int(i64::MAX): failed with error"); - let _ = trace_num(" error code:", ret as i64); - all_pass = false; - } - - // Test converting zero - let mut f0: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - 0, - f0.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let ret = unsafe { - float_to_int( - f0.as_ptr(), - FLOAT_SIZE as i32, - result.as_mut_ptr(), - 8, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - if ret == 8 { - let number = i64::from_le_bytes(result); - if number == 0 { - let _ = trace(" float_to_int(0): good"); - } else { - let _ = trace(" float_to_int(0): failed"); - let _ = trace_num(" got:", number); - all_pass = false; - } - } else { - let _ = trace(" float_to_int(0): failed with error"); - let _ = trace_num(" error code:", ret as i64); - all_pass = false; - } - - // Test rounding with fractional value (0.1) - let mut f01: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_mant_exp( - 1, - -1, - f01.as_mut_ptr(), - FLOAT_SIZE as i32, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - let ret = unsafe { - float_to_int( - f01.as_ptr(), - FLOAT_SIZE as i32, - result.as_mut_ptr(), - 8 as i32, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - if ret == 8 as i32 { - let number = i64::from_le_bytes(result); - if number == 0 { - let _ = trace(" float_to_int(0.1, to_nearest): good"); - } else { - let _ = trace(" float_to_int(0.1, to_nearest): failed"); - let _ = trace_num(" got:", number); - all_pass = false; - } - } else { - let _ = trace(" float_to_int(0.1, to_nearest): failed with error"); - let _ = trace_num(" error code:", ret as i64); - all_pass = false; - } - - // Test rounding mode 1 (towards_zero) - let ret = unsafe { - float_to_int( - f01.as_ptr(), - FLOAT_SIZE as i32, - result.as_mut_ptr(), - 8 as i32, - 1, - ) - }; - if ret == 8 as i32 { - let number = i64::from_le_bytes(result); - if number == 0 { - let _ = trace(" float_to_int(0.1, towards_zero): good"); - } else { - let _ = trace(" float_to_int(0.1, towards_zero): failed"); - let _ = trace_num(" got:", number); - all_pass = false; - } - } else { - let _ = trace(" float_to_int(0.1, towards_zero): failed with error"); - let _ = trace_num(" error code:", ret as i64); - all_pass = false; - } - - all_pass -} - -fn test_float_to_mant_exp() -> bool { - let _ = trace("\n$$$ test_float_to_mant_exp $$$"); - let mut all_pass = true; - - // Test with FLOAT_ONE (value 1) - let mut mantissa_bytes: [u8; 8] = [0u8; 8]; - let mut exponent_bytes: [u8; 4] = [0u8; 4]; - let result = unsafe { - float_to_mant_exp( - FLOAT_ONE.as_ptr(), - FLOAT_SIZE as i32, - mantissa_bytes.as_mut_ptr(), - 8, - exponent_bytes.as_mut_ptr(), - 4, - ) - }; - - if result == FLOAT_SIZE as i32 { - let mantissa = i64::from_le_bytes(mantissa_bytes); - let exponent = i32::from_le_bytes(exponent_bytes); - if mantissa == 1000000000000000000 && exponent == -18 { - let _ = trace(" float_to_mant_exp(1): good"); - } else { - let _ = trace(" float_to_mant_exp(1): failed"); - let _ = trace_num(" expected mantissa 1000000000000000000, got:", mantissa); - let _ = trace_num(" expected exponent -18, got:", exponent as i64); - all_pass = false; - } - } else { - let _ = trace(" float_to_mant_exp(1): failed with error"); - let _ = trace_num(" error code:", result as i64); - all_pass = false; - } - - // Test with FLOAT_NEGATIVE_ONE (value -1) - let mut mantissa_bytes: [u8; 8] = [0u8; 8]; - let mut exponent_bytes: [u8; 4] = [0u8; 4]; - let result = unsafe { - float_to_mant_exp( - FLOAT_NEGATIVE_ONE.as_ptr(), - FLOAT_SIZE as i32, - mantissa_bytes.as_mut_ptr(), - 8, - exponent_bytes.as_mut_ptr(), - 4, - ) - }; - - if result == FLOAT_SIZE as i32 { - let mantissa = i64::from_le_bytes(mantissa_bytes); - let exponent = i32::from_le_bytes(exponent_bytes); - if mantissa == -1000000000000000000 && exponent == -18 { - let _ = trace(" float_to_mant_exp(-1): good"); - } else { - let _ = trace(" float_to_mant_exp(-1): failed"); - let _ = trace_num(" expected mantissa -1000000000000000000, got:", mantissa); - let _ = trace_num(" expected exponent -18, got:", exponent as i64); - all_pass = false; - } - } else { - let _ = trace(" float_to_mant_exp(-1): failed with error"); - let _ = trace_num(" error code:", result as i64); - all_pass = false; - } - - // Test with a float created from int (10) - let mut f10: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - 10, - f10.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - - let mut mantissa_bytes: [u8; 8] = [0u8; 8]; - let mut exponent_bytes: [u8; 4] = [0u8; 4]; - let result = unsafe { - float_to_mant_exp( - f10.as_ptr(), - FLOAT_SIZE as i32, - mantissa_bytes.as_mut_ptr(), - 8, - exponent_bytes.as_mut_ptr(), - 4, - ) - }; - - if result == FLOAT_SIZE as i32 { - let mantissa = i64::from_le_bytes(mantissa_bytes); - let exponent = i32::from_le_bytes(exponent_bytes); - if mantissa == 1000000000000000000 && exponent == -17 { - let _ = trace(" float_to_mant_exp(10): good"); - } else { - let _ = trace(" float_to_mant_exp(10): failed"); - let _ = trace_num(" expected mantissa 1000000000000000000, got:", mantissa); - let _ = trace_num(" expected exponent -17, got:", exponent as i64); - all_pass = false; - } - } else { - let _ = trace(" float_to_mant_exp(10): failed with error"); - let _ = trace_num(" error code:", result as i64); - all_pass = false; - } - - // Test with zero - let mut f0: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - unsafe { - float_from_int( - 0, - f0.as_mut_ptr(), - FLOAT_SIZE, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - - let mut mantissa_bytes: [u8; 8] = [0u8; 8]; - let mut exponent_bytes: [u8; 4] = [0u8; 4]; - let result = unsafe { - float_to_mant_exp( - f0.as_ptr(), - FLOAT_SIZE as i32, - mantissa_bytes.as_mut_ptr(), - 8, - exponent_bytes.as_mut_ptr(), - 4, - ) - }; - - if result == FLOAT_SIZE as i32 { - let mantissa = i64::from_le_bytes(mantissa_bytes); - let exponent = i32::from_le_bytes(exponent_bytes); - if mantissa == 0 && exponent == -2147483648 { - let _ = trace(" float_to_mant_exp(0): good"); - } else { - let _ = trace(" float_to_mant_exp(0): failed"); - let _ = trace_num(" expected mantissa 0, got:", mantissa); - let _ = trace_num(" expected exponent -2147483648, got:", exponent as i64); - all_pass = false; - } - } else { - let _ = trace(" float_to_mant_exp(0): failed with error"); - let _ = trace_num(" error code:", result as i64); - all_pass = false; - } - - all_pass -} - -fn test_float_from_stamount() -> bool { - let _ = trace("\n$$$ test_float_from_stamount $$$"); - let mut all_pass = true; - - // STAmount is serialized as: - // - 1 byte: type/flags - // - 8 bytes: amount (for XRP) or mantissa (for IOU) - // - For IOU: additional currency and issuer fields - - // Create an XRP amount: 100 XRP = 100,000,000 drops - // XRP format: bit 62 clear (not IOU), bit 63 clear (not negative) - // Amount in drops: 100,000,000 = 0x05F5E100 - let xrp_amount: [u8; 8] = [0x40, 0x00, 0x00, 0x00, 0x05, 0xF5, 0xE1, 0x00]; - - let mut f_result: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - let result_size = unsafe { - float_from_stamount( - xrp_amount.as_ptr(), - 8, - f_result.as_mut_ptr(), - FLOAT_SIZE as i32, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - - if result_size == FLOAT_SIZE as i32 { - let _ = trace_float(" float from XRP amount (100 XRP):", &f_result); - - // Convert back to int to verify - let mut int_bytes: [u8; 8] = [0u8; 8]; - let ret = unsafe { - float_to_int( - f_result.as_ptr(), - FLOAT_SIZE as i32, - int_bytes.as_mut_ptr(), - 8, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - if ret == 8 { - let int_val = i64::from_le_bytes(int_bytes); - if int_val == 100000000 { - let _ = trace(" XRP amount conversion: good"); - } else { - let _ = trace(" XRP amount conversion: failed"); - let _ = trace_num(" expected 100000000, got:", int_val); - all_pass = false; - } - } else { - let _ = trace(" XRP amount conversion: failed - float_to_int error"); - let _ = trace_num(" error code:", ret as i64); - all_pass = false; - } - } else { - let _ = trace(" float from XRP amount: failed"); - let _ = trace_num(" result_size:", result_size as i64); - all_pass = false; - } - - all_pass -} - -fn test_float_from_stnumber() -> bool { - let _ = trace("\n$$$ test_float_from_stnumber $$$"); - let mut all_pass = true; - - // STNumber is serialized as: - // - 8 bytes: mantissa (big-endian signed int64) - // - 4 bytes: exponent (big-endian signed int32) - - // Create STNumber for value 123 (mantissa=123*10^18, exponent=-18) - // mantissa = 123000000000000000000 = 0x6ADF37F675EF6B28000 - // But we need to fit in int64, so use mantissa=123*10^15, exponent=-15 - // 123*10^15 = 123000000000000000 = 0x01B69B4BA630F34000 - let stnumber_123: [u8; 12] = [ - 0x01, 0xB6, 0x9B, 0x4B, 0xA6, 0x30, 0xF3, 0x40, // mantissa - 0xFF, 0xFF, 0xFF, 0xF1, // exponent = -15 - ]; - - let mut f_result: [u8; FLOAT_SIZE] = [0u8; FLOAT_SIZE]; - let result_size = unsafe { - float_from_stnumber( - stnumber_123.as_ptr(), - 12, - f_result.as_mut_ptr(), - FLOAT_SIZE as i32, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - - if result_size == FLOAT_SIZE as i32 { - let _ = trace_float(" float from STNumber (123):", &f_result); - - // Convert back to int to verify - let mut int_bytes: [u8; 8] = [0u8; 8]; - let ret = unsafe { - float_to_int( - f_result.as_ptr(), - FLOAT_SIZE as i32, - int_bytes.as_mut_ptr(), - 8, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - if ret == 8 { - let int_val = i64::from_le_bytes(int_bytes); - if int_val == 123 { - let _ = trace(" STNumber conversion: good"); - } else { - let _ = trace(" STNumber conversion: failed"); - let _ = trace_num(" expected 123, got:", int_val); - all_pass = false; - } - } else { - let _ = trace(" STNumber conversion: failed - float_to_int error"); - let _ = trace_num(" error code:", ret as i64); - all_pass = false; - } - } else { - let _ = trace(" float from STNumber: failed"); - let _ = trace_num(" result_size:", result_size as i64); - all_pass = false; - } - - // Test with FLOAT_ONE constant (which is already in STNumber format) - let result_size = unsafe { - float_from_stnumber( - FLOAT_ONE.as_ptr(), - FLOAT_SIZE as i32, - f_result.as_mut_ptr(), - FLOAT_SIZE as i32, - FLOAT_ROUNDING_MODES_TO_NEAREST, - ) - }; - - if result_size == FLOAT_SIZE as i32 { - let _ = trace_float(" float from STNumber (1):", &f_result); - - // Should match FLOAT_ONE - if 0 == unsafe { - float_cmp( - f_result.as_ptr(), - FLOAT_SIZE, - FLOAT_ONE.as_ptr(), - FLOAT_SIZE, - ) - } { - let _ = trace(" STNumber(1) == FLOAT_ONE: good"); - } else { - let _ = trace(" STNumber(1) == FLOAT_ONE: failed"); - all_pass = false; - } - } else { - let _ = trace(" float from STNumber(1): failed"); - all_pass = false; - } - - all_pass -} - -#[unsafe(no_mangle)] -pub extern "C" fn escrow_finish() -> i32 { - let mut all_pass = true; - all_pass &= test_float_from_wasm(); - all_pass &= test_float_cmp(); - all_pass &= test_float_add_subtract(); - all_pass &= test_float_mult_divide(); - all_pass &= test_float_pow(); - all_pass &= test_float_root(); - all_pass &= test_float_invert(); - all_pass &= test_float_to_int(); - all_pass &= test_float_to_mant_exp(); - all_pass &= test_float_from_stamount(); - all_pass &= test_float_from_stnumber(); - - if all_pass { - 1 - } else { - 0 - } -} diff --git a/src/test/app/wasm_fixtures/infiniteLoop.c b/src/test/app/wasm_fixtures/infiniteLoop.c deleted file mode 100644 index ba84a92ac1..0000000000 --- a/src/test/app/wasm_fixtures/infiniteLoop.c +++ /dev/null @@ -1,7 +0,0 @@ -int loop() -{ - int volatile x = 0; - while (1) - x++; - return x; -} diff --git a/src/test/app/wasm_fixtures/ledgerSqn.c b/src/test/app/wasm_fixtures/ledgerSqn.c deleted file mode 100644 index 0f4c27af7d..0000000000 --- a/src/test/app/wasm_fixtures/ledgerSqn.c +++ /dev/null @@ -1,14 +0,0 @@ -#include - -int32_t ldgr_index(uint8_t *, int32_t); - -int escrow_finish() -{ - uint32_t sqn; - int32_t result = ldgr_index((uint8_t *)&sqn, sizeof(sqn)); - - if (result < 0) - return result; - - return sqn >= 5 ? 5 : 0; -} diff --git a/src/test/app/wasm_fixtures/thousand1_params.c b/src/test/app/wasm_fixtures/thousand1_params.c deleted file mode 100644 index 1a281461c4..0000000000 --- a/src/test/app/wasm_fixtures/thousand1_params.c +++ /dev/null @@ -1,264 +0,0 @@ -// clang-format off - -#include - -int32_t test( - int32_t p0, int32_t p1, int32_t p2, int32_t p3, int32_t p4, int32_t p5, int32_t p6, int32_t p7 -, int32_t p8, int32_t p9, int32_t p10, int32_t p11, int32_t p12, int32_t p13, int32_t p14, int32_t p15 -, int32_t p16, int32_t p17, int32_t p18, int32_t p19, int32_t p20, int32_t p21, int32_t p22, int32_t p23 -, int32_t p24, int32_t p25, int32_t p26, int32_t p27, int32_t p28, int32_t p29, int32_t p30, int32_t p31 -, int32_t p32, int32_t p33, int32_t p34, int32_t p35, int32_t p36, int32_t p37, int32_t p38, int32_t p39 -, int32_t p40, int32_t p41, int32_t p42, int32_t p43, int32_t p44, int32_t p45, int32_t p46, int32_t p47 -, int32_t p48, int32_t p49, int32_t p50, int32_t p51, int32_t p52, int32_t p53, int32_t p54, int32_t p55 -, int32_t p56, int32_t p57, int32_t p58, int32_t p59, int32_t p60, int32_t p61, int32_t p62, int32_t p63 -, int32_t p64, int32_t p65, int32_t p66, int32_t p67, int32_t p68, int32_t p69, int32_t p70, int32_t p71 -, int32_t p72, int32_t p73, int32_t p74, int32_t p75, int32_t p76, int32_t p77, int32_t p78, int32_t p79 -, int32_t p80, int32_t p81, int32_t p82, int32_t p83, int32_t p84, int32_t p85, int32_t p86, int32_t p87 -, int32_t p88, int32_t p89, int32_t p90, int32_t p91, int32_t p92, int32_t p93, int32_t p94, int32_t p95 -, int32_t p96, int32_t p97, int32_t p98, int32_t p99, int32_t p100, int32_t p101, int32_t p102, int32_t p103 -, int32_t p104, int32_t p105, int32_t p106, int32_t p107, int32_t p108, int32_t p109, int32_t p110, int32_t p111 -, int32_t p112, int32_t p113, int32_t p114, int32_t p115, int32_t p116, int32_t p117, int32_t p118, int32_t p119 -, int32_t p120, int32_t p121, int32_t p122, int32_t p123, int32_t p124, int32_t p125, int32_t p126, int32_t p127 -, int32_t p128, int32_t p129, int32_t p130, int32_t p131, int32_t p132, int32_t p133, int32_t p134, int32_t p135 -, int32_t p136, int32_t p137, int32_t p138, int32_t p139, int32_t p140, int32_t p141, int32_t p142, int32_t p143 -, int32_t p144, int32_t p145, int32_t p146, int32_t p147, int32_t p148, int32_t p149, int32_t p150, int32_t p151 -, int32_t p152, int32_t p153, int32_t p154, int32_t p155, int32_t p156, int32_t p157, int32_t p158, int32_t p159 -, int32_t p160, int32_t p161, int32_t p162, int32_t p163, int32_t p164, int32_t p165, int32_t p166, int32_t p167 -, int32_t p168, int32_t p169, int32_t p170, int32_t p171, int32_t p172, int32_t p173, int32_t p174, int32_t p175 -, int32_t p176, int32_t p177, int32_t p178, int32_t p179, int32_t p180, int32_t p181, int32_t p182, int32_t p183 -, int32_t p184, int32_t p185, int32_t p186, int32_t p187, int32_t p188, int32_t p189, int32_t p190, int32_t p191 -, int32_t p192, int32_t p193, int32_t p194, int32_t p195, int32_t p196, int32_t p197, int32_t p198, int32_t p199 -, int32_t p200, int32_t p201, int32_t p202, int32_t p203, int32_t p204, int32_t p205, int32_t p206, int32_t p207 -, int32_t p208, int32_t p209, int32_t p210, int32_t p211, int32_t p212, int32_t p213, int32_t p214, int32_t p215 -, int32_t p216, int32_t p217, int32_t p218, int32_t p219, int32_t p220, int32_t p221, int32_t p222, int32_t p223 -, int32_t p224, int32_t p225, int32_t p226, int32_t p227, int32_t p228, int32_t p229, int32_t p230, int32_t p231 -, int32_t p232, int32_t p233, int32_t p234, int32_t p235, int32_t p236, int32_t p237, int32_t p238, int32_t p239 -, int32_t p240, int32_t p241, int32_t p242, int32_t p243, int32_t p244, int32_t p245, int32_t p246, int32_t p247 -, int32_t p248, int32_t p249, int32_t p250, int32_t p251, int32_t p252, int32_t p253, int32_t p254, int32_t p255 -, int32_t p256, int32_t p257, int32_t p258, int32_t p259, int32_t p260, int32_t p261, int32_t p262, int32_t p263 -, int32_t p264, int32_t p265, int32_t p266, int32_t p267, int32_t p268, int32_t p269, int32_t p270, int32_t p271 -, int32_t p272, int32_t p273, int32_t p274, int32_t p275, int32_t p276, int32_t p277, int32_t p278, int32_t p279 -, int32_t p280, int32_t p281, int32_t p282, int32_t p283, int32_t p284, int32_t p285, int32_t p286, int32_t p287 -, int32_t p288, int32_t p289, int32_t p290, int32_t p291, int32_t p292, int32_t p293, int32_t p294, int32_t p295 -, int32_t p296, int32_t p297, int32_t p298, int32_t p299, int32_t p300, int32_t p301, int32_t p302, int32_t p303 -, int32_t p304, int32_t p305, int32_t p306, int32_t p307, int32_t p308, int32_t p309, int32_t p310, int32_t p311 -, int32_t p312, int32_t p313, int32_t p314, int32_t p315, int32_t p316, int32_t p317, int32_t p318, int32_t p319 -, int32_t p320, int32_t p321, int32_t p322, int32_t p323, int32_t p324, int32_t p325, int32_t p326, int32_t p327 -, int32_t p328, int32_t p329, int32_t p330, int32_t p331, int32_t p332, int32_t p333, int32_t p334, int32_t p335 -, int32_t p336, int32_t p337, int32_t p338, int32_t p339, int32_t p340, int32_t p341, int32_t p342, int32_t p343 -, int32_t p344, int32_t p345, int32_t p346, int32_t p347, int32_t p348, int32_t p349, int32_t p350, int32_t p351 -, int32_t p352, int32_t p353, int32_t p354, int32_t p355, int32_t p356, int32_t p357, int32_t p358, int32_t p359 -, int32_t p360, int32_t p361, int32_t p362, int32_t p363, int32_t p364, int32_t p365, int32_t p366, int32_t p367 -, int32_t p368, int32_t p369, int32_t p370, int32_t p371, int32_t p372, int32_t p373, int32_t p374, int32_t p375 -, int32_t p376, int32_t p377, int32_t p378, int32_t p379, int32_t p380, int32_t p381, int32_t p382, int32_t p383 -, int32_t p384, int32_t p385, int32_t p386, int32_t p387, int32_t p388, int32_t p389, int32_t p390, int32_t p391 -, int32_t p392, int32_t p393, int32_t p394, int32_t p395, int32_t p396, int32_t p397, int32_t p398, int32_t p399 -, int32_t p400, int32_t p401, int32_t p402, int32_t p403, int32_t p404, int32_t p405, int32_t p406, int32_t p407 -, int32_t p408, int32_t p409, int32_t p410, int32_t p411, int32_t p412, int32_t p413, int32_t p414, int32_t p415 -, int32_t p416, int32_t p417, int32_t p418, int32_t p419, int32_t p420, int32_t p421, int32_t p422, int32_t p423 -, int32_t p424, int32_t p425, int32_t p426, int32_t p427, int32_t p428, int32_t p429, int32_t p430, int32_t p431 -, int32_t p432, int32_t p433, int32_t p434, int32_t p435, int32_t p436, int32_t p437, int32_t p438, int32_t p439 -, int32_t p440, int32_t p441, int32_t p442, int32_t p443, int32_t p444, int32_t p445, int32_t p446, int32_t p447 -, int32_t p448, int32_t p449, int32_t p450, int32_t p451, int32_t p452, int32_t p453, int32_t p454, int32_t p455 -, int32_t p456, int32_t p457, int32_t p458, int32_t p459, int32_t p460, int32_t p461, int32_t p462, int32_t p463 -, int32_t p464, int32_t p465, int32_t p466, int32_t p467, int32_t p468, int32_t p469, int32_t p470, int32_t p471 -, int32_t p472, int32_t p473, int32_t p474, int32_t p475, int32_t p476, int32_t p477, int32_t p478, int32_t p479 -, int32_t p480, int32_t p481, int32_t p482, int32_t p483, int32_t p484, int32_t p485, int32_t p486, int32_t p487 -, int32_t p488, int32_t p489, int32_t p490, int32_t p491, int32_t p492, int32_t p493, int32_t p494, int32_t p495 -, int32_t p496, int32_t p497, int32_t p498, int32_t p499, int32_t p500, int32_t p501, int32_t p502, int32_t p503 -, int32_t p504, int32_t p505, int32_t p506, int32_t p507, int32_t p508, int32_t p509, int32_t p510, int32_t p511 -, int32_t p512, int32_t p513, int32_t p514, int32_t p515, int32_t p516, int32_t p517, int32_t p518, int32_t p519 -, int32_t p520, int32_t p521, int32_t p522, int32_t p523, int32_t p524, int32_t p525, int32_t p526, int32_t p527 -, int32_t p528, int32_t p529, int32_t p530, int32_t p531, int32_t p532, int32_t p533, int32_t p534, int32_t p535 -, int32_t p536, int32_t p537, int32_t p538, int32_t p539, int32_t p540, int32_t p541, int32_t p542, int32_t p543 -, int32_t p544, int32_t p545, int32_t p546, int32_t p547, int32_t p548, int32_t p549, int32_t p550, int32_t p551 -, int32_t p552, int32_t p553, int32_t p554, int32_t p555, int32_t p556, int32_t p557, int32_t p558, int32_t p559 -, int32_t p560, int32_t p561, int32_t p562, int32_t p563, int32_t p564, int32_t p565, int32_t p566, int32_t p567 -, int32_t p568, int32_t p569, int32_t p570, int32_t p571, int32_t p572, int32_t p573, int32_t p574, int32_t p575 -, int32_t p576, int32_t p577, int32_t p578, int32_t p579, int32_t p580, int32_t p581, int32_t p582, int32_t p583 -, int32_t p584, int32_t p585, int32_t p586, int32_t p587, int32_t p588, int32_t p589, int32_t p590, int32_t p591 -, int32_t p592, int32_t p593, int32_t p594, int32_t p595, int32_t p596, int32_t p597, int32_t p598, int32_t p599 -, int32_t p600, int32_t p601, int32_t p602, int32_t p603, int32_t p604, int32_t p605, int32_t p606, int32_t p607 -, int32_t p608, int32_t p609, int32_t p610, int32_t p611, int32_t p612, int32_t p613, int32_t p614, int32_t p615 -, int32_t p616, int32_t p617, int32_t p618, int32_t p619, int32_t p620, int32_t p621, int32_t p622, int32_t p623 -, int32_t p624, int32_t p625, int32_t p626, int32_t p627, int32_t p628, int32_t p629, int32_t p630, int32_t p631 -, int32_t p632, int32_t p633, int32_t p634, int32_t p635, int32_t p636, int32_t p637, int32_t p638, int32_t p639 -, int32_t p640, int32_t p641, int32_t p642, int32_t p643, int32_t p644, int32_t p645, int32_t p646, int32_t p647 -, int32_t p648, int32_t p649, int32_t p650, int32_t p651, int32_t p652, int32_t p653, int32_t p654, int32_t p655 -, int32_t p656, int32_t p657, int32_t p658, int32_t p659, int32_t p660, int32_t p661, int32_t p662, int32_t p663 -, int32_t p664, int32_t p665, int32_t p666, int32_t p667, int32_t p668, int32_t p669, int32_t p670, int32_t p671 -, int32_t p672, int32_t p673, int32_t p674, int32_t p675, int32_t p676, int32_t p677, int32_t p678, int32_t p679 -, int32_t p680, int32_t p681, int32_t p682, int32_t p683, int32_t p684, int32_t p685, int32_t p686, int32_t p687 -, int32_t p688, int32_t p689, int32_t p690, int32_t p691, int32_t p692, int32_t p693, int32_t p694, int32_t p695 -, int32_t p696, int32_t p697, int32_t p698, int32_t p699, int32_t p700, int32_t p701, int32_t p702, int32_t p703 -, int32_t p704, int32_t p705, int32_t p706, int32_t p707, int32_t p708, int32_t p709, int32_t p710, int32_t p711 -, int32_t p712, int32_t p713, int32_t p714, int32_t p715, int32_t p716, int32_t p717, int32_t p718, int32_t p719 -, int32_t p720, int32_t p721, int32_t p722, int32_t p723, int32_t p724, int32_t p725, int32_t p726, int32_t p727 -, int32_t p728, int32_t p729, int32_t p730, int32_t p731, int32_t p732, int32_t p733, int32_t p734, int32_t p735 -, int32_t p736, int32_t p737, int32_t p738, int32_t p739, int32_t p740, int32_t p741, int32_t p742, int32_t p743 -, int32_t p744, int32_t p745, int32_t p746, int32_t p747, int32_t p748, int32_t p749, int32_t p750, int32_t p751 -, int32_t p752, int32_t p753, int32_t p754, int32_t p755, int32_t p756, int32_t p757, int32_t p758, int32_t p759 -, int32_t p760, int32_t p761, int32_t p762, int32_t p763, int32_t p764, int32_t p765, int32_t p766, int32_t p767 -, int32_t p768, int32_t p769, int32_t p770, int32_t p771, int32_t p772, int32_t p773, int32_t p774, int32_t p775 -, int32_t p776, int32_t p777, int32_t p778, int32_t p779, int32_t p780, int32_t p781, int32_t p782, int32_t p783 -, int32_t p784, int32_t p785, int32_t p786, int32_t p787, int32_t p788, int32_t p789, int32_t p790, int32_t p791 -, int32_t p792, int32_t p793, int32_t p794, int32_t p795, int32_t p796, int32_t p797, int32_t p798, int32_t p799 -, int32_t p800, int32_t p801, int32_t p802, int32_t p803, int32_t p804, int32_t p805, int32_t p806, int32_t p807 -, int32_t p808, int32_t p809, int32_t p810, int32_t p811, int32_t p812, int32_t p813, int32_t p814, int32_t p815 -, int32_t p816, int32_t p817, int32_t p818, int32_t p819, int32_t p820, int32_t p821, int32_t p822, int32_t p823 -, int32_t p824, int32_t p825, int32_t p826, int32_t p827, int32_t p828, int32_t p829, int32_t p830, int32_t p831 -, int32_t p832, int32_t p833, int32_t p834, int32_t p835, int32_t p836, int32_t p837, int32_t p838, int32_t p839 -, int32_t p840, int32_t p841, int32_t p842, int32_t p843, int32_t p844, int32_t p845, int32_t p846, int32_t p847 -, int32_t p848, int32_t p849, int32_t p850, int32_t p851, int32_t p852, int32_t p853, int32_t p854, int32_t p855 -, int32_t p856, int32_t p857, int32_t p858, int32_t p859, int32_t p860, int32_t p861, int32_t p862, int32_t p863 -, int32_t p864, int32_t p865, int32_t p866, int32_t p867, int32_t p868, int32_t p869, int32_t p870, int32_t p871 -, int32_t p872, int32_t p873, int32_t p874, int32_t p875, int32_t p876, int32_t p877, int32_t p878, int32_t p879 -, int32_t p880, int32_t p881, int32_t p882, int32_t p883, int32_t p884, int32_t p885, int32_t p886, int32_t p887 -, int32_t p888, int32_t p889, int32_t p890, int32_t p891, int32_t p892, int32_t p893, int32_t p894, int32_t p895 -, int32_t p896, int32_t p897, int32_t p898, int32_t p899, int32_t p900, int32_t p901, int32_t p902, int32_t p903 -, int32_t p904, int32_t p905, int32_t p906, int32_t p907, int32_t p908, int32_t p909, int32_t p910, int32_t p911 -, int32_t p912, int32_t p913, int32_t p914, int32_t p915, int32_t p916, int32_t p917, int32_t p918, int32_t p919 -, int32_t p920, int32_t p921, int32_t p922, int32_t p923, int32_t p924, int32_t p925, int32_t p926, int32_t p927 -, int32_t p928, int32_t p929, int32_t p930, int32_t p931, int32_t p932, int32_t p933, int32_t p934, int32_t p935 -, int32_t p936, int32_t p937, int32_t p938, int32_t p939, int32_t p940, int32_t p941, int32_t p942, int32_t p943 -, int32_t p944, int32_t p945, int32_t p946, int32_t p947, int32_t p948, int32_t p949, int32_t p950, int32_t p951 -, int32_t p952, int32_t p953, int32_t p954, int32_t p955, int32_t p956, int32_t p957, int32_t p958, int32_t p959 -, int32_t p960, int32_t p961, int32_t p962, int32_t p963, int32_t p964, int32_t p965, int32_t p966, int32_t p967 -, int32_t p968, int32_t p969, int32_t p970, int32_t p971, int32_t p972, int32_t p973, int32_t p974, int32_t p975 -, int32_t p976, int32_t p977, int32_t p978, int32_t p979, int32_t p980, int32_t p981, int32_t p982, int32_t p983 -, int32_t p984, int32_t p985, int32_t p986, int32_t p987, int32_t p988, int32_t p989, int32_t p990, int32_t p991 -, int32_t p992, int32_t p993, int32_t p994, int32_t p995, int32_t p996, int32_t p997, int32_t p998, int32_t p999 -, int32_t p1000 -) -{ - int32_t x; - x = p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 - + p8 + p9 + p10 + p11 + p12 + p13 + p14 + p15 - + p16 + p17 + p18 + p19 + p20 + p21 + p22 + p23 - + p24 + p25 + p26 + p27 + p28 + p29 + p30 + p31 - + p32 + p33 + p34 + p35 + p36 + p37 + p38 + p39 - + p40 + p41 + p42 + p43 + p44 + p45 + p46 + p47 - + p48 + p49 + p50 + p51 + p52 + p53 + p54 + p55 - + p56 + p57 + p58 + p59 + p60 + p61 + p62 + p63 - + p64 + p65 + p66 + p67 + p68 + p69 + p70 + p71 - + p72 + p73 + p74 + p75 + p76 + p77 + p78 + p79 - + p80 + p81 + p82 + p83 + p84 + p85 + p86 + p87 - + p88 + p89 + p90 + p91 + p92 + p93 + p94 + p95 - + p96 + p97 + p98 + p99 + p100 + p101 + p102 + p103 - + p104 + p105 + p106 + p107 + p108 + p109 + p110 + p111 - + p112 + p113 + p114 + p115 + p116 + p117 + p118 + p119 - + p120 + p121 + p122 + p123 + p124 + p125 + p126 + p127 - + p128 + p129 + p130 + p131 + p132 + p133 + p134 + p135 - + p136 + p137 + p138 + p139 + p140 + p141 + p142 + p143 - + p144 + p145 + p146 + p147 + p148 + p149 + p150 + p151 - + p152 + p153 + p154 + p155 + p156 + p157 + p158 + p159 - + p160 + p161 + p162 + p163 + p164 + p165 + p166 + p167 - + p168 + p169 + p170 + p171 + p172 + p173 + p174 + p175 - + p176 + p177 + p178 + p179 + p180 + p181 + p182 + p183 - + p184 + p185 + p186 + p187 + p188 + p189 + p190 + p191 - + p192 + p193 + p194 + p195 + p196 + p197 + p198 + p199 - + p200 + p201 + p202 + p203 + p204 + p205 + p206 + p207 - + p208 + p209 + p210 + p211 + p212 + p213 + p214 + p215 - + p216 + p217 + p218 + p219 + p220 + p221 + p222 + p223 - + p224 + p225 + p226 + p227 + p228 + p229 + p230 + p231 - + p232 + p233 + p234 + p235 + p236 + p237 + p238 + p239 - + p240 + p241 + p242 + p243 + p244 + p245 + p246 + p247 - + p248 + p249 + p250 + p251 + p252 + p253 + p254 + p255 - + p256 + p257 + p258 + p259 + p260 + p261 + p262 + p263 - + p264 + p265 + p266 + p267 + p268 + p269 + p270 + p271 - + p272 + p273 + p274 + p275 + p276 + p277 + p278 + p279 - + p280 + p281 + p282 + p283 + p284 + p285 + p286 + p287 - + p288 + p289 + p290 + p291 + p292 + p293 + p294 + p295 - + p296 + p297 + p298 + p299 + p300 + p301 + p302 + p303 - + p304 + p305 + p306 + p307 + p308 + p309 + p310 + p311 - + p312 + p313 + p314 + p315 + p316 + p317 + p318 + p319 - + p320 + p321 + p322 + p323 + p324 + p325 + p326 + p327 - + p328 + p329 + p330 + p331 + p332 + p333 + p334 + p335 - + p336 + p337 + p338 + p339 + p340 + p341 + p342 + p343 - + p344 + p345 + p346 + p347 + p348 + p349 + p350 + p351 - + p352 + p353 + p354 + p355 + p356 + p357 + p358 + p359 - + p360 + p361 + p362 + p363 + p364 + p365 + p366 + p367 - + p368 + p369 + p370 + p371 + p372 + p373 + p374 + p375 - + p376 + p377 + p378 + p379 + p380 + p381 + p382 + p383 - + p384 + p385 + p386 + p387 + p388 + p389 + p390 + p391 - + p392 + p393 + p394 + p395 + p396 + p397 + p398 + p399 - + p400 + p401 + p402 + p403 + p404 + p405 + p406 + p407 - + p408 + p409 + p410 + p411 + p412 + p413 + p414 + p415 - + p416 + p417 + p418 + p419 + p420 + p421 + p422 + p423 - + p424 + p425 + p426 + p427 + p428 + p429 + p430 + p431 - + p432 + p433 + p434 + p435 + p436 + p437 + p438 + p439 - + p440 + p441 + p442 + p443 + p444 + p445 + p446 + p447 - + p448 + p449 + p450 + p451 + p452 + p453 + p454 + p455 - + p456 + p457 + p458 + p459 + p460 + p461 + p462 + p463 - + p464 + p465 + p466 + p467 + p468 + p469 + p470 + p471 - + p472 + p473 + p474 + p475 + p476 + p477 + p478 + p479 - + p480 + p481 + p482 + p483 + p484 + p485 + p486 + p487 - + p488 + p489 + p490 + p491 + p492 + p493 + p494 + p495 - + p496 + p497 + p498 + p499 + p500 + p501 + p502 + p503 - + p504 + p505 + p506 + p507 + p508 + p509 + p510 + p511 - + p512 + p513 + p514 + p515 + p516 + p517 + p518 + p519 - + p520 + p521 + p522 + p523 + p524 + p525 + p526 + p527 - + p528 + p529 + p530 + p531 + p532 + p533 + p534 + p535 - + p536 + p537 + p538 + p539 + p540 + p541 + p542 + p543 - + p544 + p545 + p546 + p547 + p548 + p549 + p550 + p551 - + p552 + p553 + p554 + p555 + p556 + p557 + p558 + p559 - + p560 + p561 + p562 + p563 + p564 + p565 + p566 + p567 - + p568 + p569 + p570 + p571 + p572 + p573 + p574 + p575 - + p576 + p577 + p578 + p579 + p580 + p581 + p582 + p583 - + p584 + p585 + p586 + p587 + p588 + p589 + p590 + p591 - + p592 + p593 + p594 + p595 + p596 + p597 + p598 + p599 - + p600 + p601 + p602 + p603 + p604 + p605 + p606 + p607 - + p608 + p609 + p610 + p611 + p612 + p613 + p614 + p615 - + p616 + p617 + p618 + p619 + p620 + p621 + p622 + p623 - + p624 + p625 + p626 + p627 + p628 + p629 + p630 + p631 - + p632 + p633 + p634 + p635 + p636 + p637 + p638 + p639 - + p640 + p641 + p642 + p643 + p644 + p645 + p646 + p647 - + p648 + p649 + p650 + p651 + p652 + p653 + p654 + p655 - + p656 + p657 + p658 + p659 + p660 + p661 + p662 + p663 - + p664 + p665 + p666 + p667 + p668 + p669 + p670 + p671 - + p672 + p673 + p674 + p675 + p676 + p677 + p678 + p679 - + p680 + p681 + p682 + p683 + p684 + p685 + p686 + p687 - + p688 + p689 + p690 + p691 + p692 + p693 + p694 + p695 - + p696 + p697 + p698 + p699 + p700 + p701 + p702 + p703 - + p704 + p705 + p706 + p707 + p708 + p709 + p710 + p711 - + p712 + p713 + p714 + p715 + p716 + p717 + p718 + p719 - + p720 + p721 + p722 + p723 + p724 + p725 + p726 + p727 - + p728 + p729 + p730 + p731 + p732 + p733 + p734 + p735 - + p736 + p737 + p738 + p739 + p740 + p741 + p742 + p743 - + p744 + p745 + p746 + p747 + p748 + p749 + p750 + p751 - + p752 + p753 + p754 + p755 + p756 + p757 + p758 + p759 - + p760 + p761 + p762 + p763 + p764 + p765 + p766 + p767 - + p768 + p769 + p770 + p771 + p772 + p773 + p774 + p775 - + p776 + p777 + p778 + p779 + p780 + p781 + p782 + p783 - + p784 + p785 + p786 + p787 + p788 + p789 + p790 + p791 - + p792 + p793 + p794 + p795 + p796 + p797 + p798 + p799 - + p800 + p801 + p802 + p803 + p804 + p805 + p806 + p807 - + p808 + p809 + p810 + p811 + p812 + p813 + p814 + p815 - + p816 + p817 + p818 + p819 + p820 + p821 + p822 + p823 - + p824 + p825 + p826 + p827 + p828 + p829 + p830 + p831 - + p832 + p833 + p834 + p835 + p836 + p837 + p838 + p839 - + p840 + p841 + p842 + p843 + p844 + p845 + p846 + p847 - + p848 + p849 + p850 + p851 + p852 + p853 + p854 + p855 - + p856 + p857 + p858 + p859 + p860 + p861 + p862 + p863 - + p864 + p865 + p866 + p867 + p868 + p869 + p870 + p871 - + p872 + p873 + p874 + p875 + p876 + p877 + p878 + p879 - + p880 + p881 + p882 + p883 + p884 + p885 + p886 + p887 - + p888 + p889 + p890 + p891 + p892 + p893 + p894 + p895 - + p896 + p897 + p898 + p899 + p900 + p901 + p902 + p903 - + p904 + p905 + p906 + p907 + p908 + p909 + p910 + p911 - + p912 + p913 + p914 + p915 + p916 + p917 + p918 + p919 - + p920 + p921 + p922 + p923 + p924 + p925 + p926 + p927 - + p928 + p929 + p930 + p931 + p932 + p933 + p934 + p935 - + p936 + p937 + p938 + p939 + p940 + p941 + p942 + p943 - + p944 + p945 + p946 + p947 + p948 + p949 + p950 + p951 - + p952 + p953 + p954 + p955 + p956 + p957 + p958 + p959 - + p960 + p961 + p962 + p963 + p964 + p965 + p966 + p967 - + p968 + p969 + p970 + p971 + p972 + p973 + p974 + p975 - + p976 + p977 + p978 + p979 + p980 + p981 + p982 + p983 - + p984 + p985 + p986 + p987 + p988 + p989 + p990 + p991 - + p992 + p993 + p994 + p995 + p996 + p997 + p998 + p999 - + p1000; - return x; -} - -// clang-format on diff --git a/src/test/app/wasm_fixtures/thousand_params.c b/src/test/app/wasm_fixtures/thousand_params.c deleted file mode 100644 index d934ca38c8..0000000000 --- a/src/test/app/wasm_fixtures/thousand_params.c +++ /dev/null @@ -1,262 +0,0 @@ -// clang-format off - -#include - -int32_t test( - int32_t p0, int32_t p1, int32_t p2, int32_t p3, int32_t p4, int32_t p5, int32_t p6, int32_t p7 -, int32_t p8, int32_t p9, int32_t p10, int32_t p11, int32_t p12, int32_t p13, int32_t p14, int32_t p15 -, int32_t p16, int32_t p17, int32_t p18, int32_t p19, int32_t p20, int32_t p21, int32_t p22, int32_t p23 -, int32_t p24, int32_t p25, int32_t p26, int32_t p27, int32_t p28, int32_t p29, int32_t p30, int32_t p31 -, int32_t p32, int32_t p33, int32_t p34, int32_t p35, int32_t p36, int32_t p37, int32_t p38, int32_t p39 -, int32_t p40, int32_t p41, int32_t p42, int32_t p43, int32_t p44, int32_t p45, int32_t p46, int32_t p47 -, int32_t p48, int32_t p49, int32_t p50, int32_t p51, int32_t p52, int32_t p53, int32_t p54, int32_t p55 -, int32_t p56, int32_t p57, int32_t p58, int32_t p59, int32_t p60, int32_t p61, int32_t p62, int32_t p63 -, int32_t p64, int32_t p65, int32_t p66, int32_t p67, int32_t p68, int32_t p69, int32_t p70, int32_t p71 -, int32_t p72, int32_t p73, int32_t p74, int32_t p75, int32_t p76, int32_t p77, int32_t p78, int32_t p79 -, int32_t p80, int32_t p81, int32_t p82, int32_t p83, int32_t p84, int32_t p85, int32_t p86, int32_t p87 -, int32_t p88, int32_t p89, int32_t p90, int32_t p91, int32_t p92, int32_t p93, int32_t p94, int32_t p95 -, int32_t p96, int32_t p97, int32_t p98, int32_t p99, int32_t p100, int32_t p101, int32_t p102, int32_t p103 -, int32_t p104, int32_t p105, int32_t p106, int32_t p107, int32_t p108, int32_t p109, int32_t p110, int32_t p111 -, int32_t p112, int32_t p113, int32_t p114, int32_t p115, int32_t p116, int32_t p117, int32_t p118, int32_t p119 -, int32_t p120, int32_t p121, int32_t p122, int32_t p123, int32_t p124, int32_t p125, int32_t p126, int32_t p127 -, int32_t p128, int32_t p129, int32_t p130, int32_t p131, int32_t p132, int32_t p133, int32_t p134, int32_t p135 -, int32_t p136, int32_t p137, int32_t p138, int32_t p139, int32_t p140, int32_t p141, int32_t p142, int32_t p143 -, int32_t p144, int32_t p145, int32_t p146, int32_t p147, int32_t p148, int32_t p149, int32_t p150, int32_t p151 -, int32_t p152, int32_t p153, int32_t p154, int32_t p155, int32_t p156, int32_t p157, int32_t p158, int32_t p159 -, int32_t p160, int32_t p161, int32_t p162, int32_t p163, int32_t p164, int32_t p165, int32_t p166, int32_t p167 -, int32_t p168, int32_t p169, int32_t p170, int32_t p171, int32_t p172, int32_t p173, int32_t p174, int32_t p175 -, int32_t p176, int32_t p177, int32_t p178, int32_t p179, int32_t p180, int32_t p181, int32_t p182, int32_t p183 -, int32_t p184, int32_t p185, int32_t p186, int32_t p187, int32_t p188, int32_t p189, int32_t p190, int32_t p191 -, int32_t p192, int32_t p193, int32_t p194, int32_t p195, int32_t p196, int32_t p197, int32_t p198, int32_t p199 -, int32_t p200, int32_t p201, int32_t p202, int32_t p203, int32_t p204, int32_t p205, int32_t p206, int32_t p207 -, int32_t p208, int32_t p209, int32_t p210, int32_t p211, int32_t p212, int32_t p213, int32_t p214, int32_t p215 -, int32_t p216, int32_t p217, int32_t p218, int32_t p219, int32_t p220, int32_t p221, int32_t p222, int32_t p223 -, int32_t p224, int32_t p225, int32_t p226, int32_t p227, int32_t p228, int32_t p229, int32_t p230, int32_t p231 -, int32_t p232, int32_t p233, int32_t p234, int32_t p235, int32_t p236, int32_t p237, int32_t p238, int32_t p239 -, int32_t p240, int32_t p241, int32_t p242, int32_t p243, int32_t p244, int32_t p245, int32_t p246, int32_t p247 -, int32_t p248, int32_t p249, int32_t p250, int32_t p251, int32_t p252, int32_t p253, int32_t p254, int32_t p255 -, int32_t p256, int32_t p257, int32_t p258, int32_t p259, int32_t p260, int32_t p261, int32_t p262, int32_t p263 -, int32_t p264, int32_t p265, int32_t p266, int32_t p267, int32_t p268, int32_t p269, int32_t p270, int32_t p271 -, int32_t p272, int32_t p273, int32_t p274, int32_t p275, int32_t p276, int32_t p277, int32_t p278, int32_t p279 -, int32_t p280, int32_t p281, int32_t p282, int32_t p283, int32_t p284, int32_t p285, int32_t p286, int32_t p287 -, int32_t p288, int32_t p289, int32_t p290, int32_t p291, int32_t p292, int32_t p293, int32_t p294, int32_t p295 -, int32_t p296, int32_t p297, int32_t p298, int32_t p299, int32_t p300, int32_t p301, int32_t p302, int32_t p303 -, int32_t p304, int32_t p305, int32_t p306, int32_t p307, int32_t p308, int32_t p309, int32_t p310, int32_t p311 -, int32_t p312, int32_t p313, int32_t p314, int32_t p315, int32_t p316, int32_t p317, int32_t p318, int32_t p319 -, int32_t p320, int32_t p321, int32_t p322, int32_t p323, int32_t p324, int32_t p325, int32_t p326, int32_t p327 -, int32_t p328, int32_t p329, int32_t p330, int32_t p331, int32_t p332, int32_t p333, int32_t p334, int32_t p335 -, int32_t p336, int32_t p337, int32_t p338, int32_t p339, int32_t p340, int32_t p341, int32_t p342, int32_t p343 -, int32_t p344, int32_t p345, int32_t p346, int32_t p347, int32_t p348, int32_t p349, int32_t p350, int32_t p351 -, int32_t p352, int32_t p353, int32_t p354, int32_t p355, int32_t p356, int32_t p357, int32_t p358, int32_t p359 -, int32_t p360, int32_t p361, int32_t p362, int32_t p363, int32_t p364, int32_t p365, int32_t p366, int32_t p367 -, int32_t p368, int32_t p369, int32_t p370, int32_t p371, int32_t p372, int32_t p373, int32_t p374, int32_t p375 -, int32_t p376, int32_t p377, int32_t p378, int32_t p379, int32_t p380, int32_t p381, int32_t p382, int32_t p383 -, int32_t p384, int32_t p385, int32_t p386, int32_t p387, int32_t p388, int32_t p389, int32_t p390, int32_t p391 -, int32_t p392, int32_t p393, int32_t p394, int32_t p395, int32_t p396, int32_t p397, int32_t p398, int32_t p399 -, int32_t p400, int32_t p401, int32_t p402, int32_t p403, int32_t p404, int32_t p405, int32_t p406, int32_t p407 -, int32_t p408, int32_t p409, int32_t p410, int32_t p411, int32_t p412, int32_t p413, int32_t p414, int32_t p415 -, int32_t p416, int32_t p417, int32_t p418, int32_t p419, int32_t p420, int32_t p421, int32_t p422, int32_t p423 -, int32_t p424, int32_t p425, int32_t p426, int32_t p427, int32_t p428, int32_t p429, int32_t p430, int32_t p431 -, int32_t p432, int32_t p433, int32_t p434, int32_t p435, int32_t p436, int32_t p437, int32_t p438, int32_t p439 -, int32_t p440, int32_t p441, int32_t p442, int32_t p443, int32_t p444, int32_t p445, int32_t p446, int32_t p447 -, int32_t p448, int32_t p449, int32_t p450, int32_t p451, int32_t p452, int32_t p453, int32_t p454, int32_t p455 -, int32_t p456, int32_t p457, int32_t p458, int32_t p459, int32_t p460, int32_t p461, int32_t p462, int32_t p463 -, int32_t p464, int32_t p465, int32_t p466, int32_t p467, int32_t p468, int32_t p469, int32_t p470, int32_t p471 -, int32_t p472, int32_t p473, int32_t p474, int32_t p475, int32_t p476, int32_t p477, int32_t p478, int32_t p479 -, int32_t p480, int32_t p481, int32_t p482, int32_t p483, int32_t p484, int32_t p485, int32_t p486, int32_t p487 -, int32_t p488, int32_t p489, int32_t p490, int32_t p491, int32_t p492, int32_t p493, int32_t p494, int32_t p495 -, int32_t p496, int32_t p497, int32_t p498, int32_t p499, int32_t p500, int32_t p501, int32_t p502, int32_t p503 -, int32_t p504, int32_t p505, int32_t p506, int32_t p507, int32_t p508, int32_t p509, int32_t p510, int32_t p511 -, int32_t p512, int32_t p513, int32_t p514, int32_t p515, int32_t p516, int32_t p517, int32_t p518, int32_t p519 -, int32_t p520, int32_t p521, int32_t p522, int32_t p523, int32_t p524, int32_t p525, int32_t p526, int32_t p527 -, int32_t p528, int32_t p529, int32_t p530, int32_t p531, int32_t p532, int32_t p533, int32_t p534, int32_t p535 -, int32_t p536, int32_t p537, int32_t p538, int32_t p539, int32_t p540, int32_t p541, int32_t p542, int32_t p543 -, int32_t p544, int32_t p545, int32_t p546, int32_t p547, int32_t p548, int32_t p549, int32_t p550, int32_t p551 -, int32_t p552, int32_t p553, int32_t p554, int32_t p555, int32_t p556, int32_t p557, int32_t p558, int32_t p559 -, int32_t p560, int32_t p561, int32_t p562, int32_t p563, int32_t p564, int32_t p565, int32_t p566, int32_t p567 -, int32_t p568, int32_t p569, int32_t p570, int32_t p571, int32_t p572, int32_t p573, int32_t p574, int32_t p575 -, int32_t p576, int32_t p577, int32_t p578, int32_t p579, int32_t p580, int32_t p581, int32_t p582, int32_t p583 -, int32_t p584, int32_t p585, int32_t p586, int32_t p587, int32_t p588, int32_t p589, int32_t p590, int32_t p591 -, int32_t p592, int32_t p593, int32_t p594, int32_t p595, int32_t p596, int32_t p597, int32_t p598, int32_t p599 -, int32_t p600, int32_t p601, int32_t p602, int32_t p603, int32_t p604, int32_t p605, int32_t p606, int32_t p607 -, int32_t p608, int32_t p609, int32_t p610, int32_t p611, int32_t p612, int32_t p613, int32_t p614, int32_t p615 -, int32_t p616, int32_t p617, int32_t p618, int32_t p619, int32_t p620, int32_t p621, int32_t p622, int32_t p623 -, int32_t p624, int32_t p625, int32_t p626, int32_t p627, int32_t p628, int32_t p629, int32_t p630, int32_t p631 -, int32_t p632, int32_t p633, int32_t p634, int32_t p635, int32_t p636, int32_t p637, int32_t p638, int32_t p639 -, int32_t p640, int32_t p641, int32_t p642, int32_t p643, int32_t p644, int32_t p645, int32_t p646, int32_t p647 -, int32_t p648, int32_t p649, int32_t p650, int32_t p651, int32_t p652, int32_t p653, int32_t p654, int32_t p655 -, int32_t p656, int32_t p657, int32_t p658, int32_t p659, int32_t p660, int32_t p661, int32_t p662, int32_t p663 -, int32_t p664, int32_t p665, int32_t p666, int32_t p667, int32_t p668, int32_t p669, int32_t p670, int32_t p671 -, int32_t p672, int32_t p673, int32_t p674, int32_t p675, int32_t p676, int32_t p677, int32_t p678, int32_t p679 -, int32_t p680, int32_t p681, int32_t p682, int32_t p683, int32_t p684, int32_t p685, int32_t p686, int32_t p687 -, int32_t p688, int32_t p689, int32_t p690, int32_t p691, int32_t p692, int32_t p693, int32_t p694, int32_t p695 -, int32_t p696, int32_t p697, int32_t p698, int32_t p699, int32_t p700, int32_t p701, int32_t p702, int32_t p703 -, int32_t p704, int32_t p705, int32_t p706, int32_t p707, int32_t p708, int32_t p709, int32_t p710, int32_t p711 -, int32_t p712, int32_t p713, int32_t p714, int32_t p715, int32_t p716, int32_t p717, int32_t p718, int32_t p719 -, int32_t p720, int32_t p721, int32_t p722, int32_t p723, int32_t p724, int32_t p725, int32_t p726, int32_t p727 -, int32_t p728, int32_t p729, int32_t p730, int32_t p731, int32_t p732, int32_t p733, int32_t p734, int32_t p735 -, int32_t p736, int32_t p737, int32_t p738, int32_t p739, int32_t p740, int32_t p741, int32_t p742, int32_t p743 -, int32_t p744, int32_t p745, int32_t p746, int32_t p747, int32_t p748, int32_t p749, int32_t p750, int32_t p751 -, int32_t p752, int32_t p753, int32_t p754, int32_t p755, int32_t p756, int32_t p757, int32_t p758, int32_t p759 -, int32_t p760, int32_t p761, int32_t p762, int32_t p763, int32_t p764, int32_t p765, int32_t p766, int32_t p767 -, int32_t p768, int32_t p769, int32_t p770, int32_t p771, int32_t p772, int32_t p773, int32_t p774, int32_t p775 -, int32_t p776, int32_t p777, int32_t p778, int32_t p779, int32_t p780, int32_t p781, int32_t p782, int32_t p783 -, int32_t p784, int32_t p785, int32_t p786, int32_t p787, int32_t p788, int32_t p789, int32_t p790, int32_t p791 -, int32_t p792, int32_t p793, int32_t p794, int32_t p795, int32_t p796, int32_t p797, int32_t p798, int32_t p799 -, int32_t p800, int32_t p801, int32_t p802, int32_t p803, int32_t p804, int32_t p805, int32_t p806, int32_t p807 -, int32_t p808, int32_t p809, int32_t p810, int32_t p811, int32_t p812, int32_t p813, int32_t p814, int32_t p815 -, int32_t p816, int32_t p817, int32_t p818, int32_t p819, int32_t p820, int32_t p821, int32_t p822, int32_t p823 -, int32_t p824, int32_t p825, int32_t p826, int32_t p827, int32_t p828, int32_t p829, int32_t p830, int32_t p831 -, int32_t p832, int32_t p833, int32_t p834, int32_t p835, int32_t p836, int32_t p837, int32_t p838, int32_t p839 -, int32_t p840, int32_t p841, int32_t p842, int32_t p843, int32_t p844, int32_t p845, int32_t p846, int32_t p847 -, int32_t p848, int32_t p849, int32_t p850, int32_t p851, int32_t p852, int32_t p853, int32_t p854, int32_t p855 -, int32_t p856, int32_t p857, int32_t p858, int32_t p859, int32_t p860, int32_t p861, int32_t p862, int32_t p863 -, int32_t p864, int32_t p865, int32_t p866, int32_t p867, int32_t p868, int32_t p869, int32_t p870, int32_t p871 -, int32_t p872, int32_t p873, int32_t p874, int32_t p875, int32_t p876, int32_t p877, int32_t p878, int32_t p879 -, int32_t p880, int32_t p881, int32_t p882, int32_t p883, int32_t p884, int32_t p885, int32_t p886, int32_t p887 -, int32_t p888, int32_t p889, int32_t p890, int32_t p891, int32_t p892, int32_t p893, int32_t p894, int32_t p895 -, int32_t p896, int32_t p897, int32_t p898, int32_t p899, int32_t p900, int32_t p901, int32_t p902, int32_t p903 -, int32_t p904, int32_t p905, int32_t p906, int32_t p907, int32_t p908, int32_t p909, int32_t p910, int32_t p911 -, int32_t p912, int32_t p913, int32_t p914, int32_t p915, int32_t p916, int32_t p917, int32_t p918, int32_t p919 -, int32_t p920, int32_t p921, int32_t p922, int32_t p923, int32_t p924, int32_t p925, int32_t p926, int32_t p927 -, int32_t p928, int32_t p929, int32_t p930, int32_t p931, int32_t p932, int32_t p933, int32_t p934, int32_t p935 -, int32_t p936, int32_t p937, int32_t p938, int32_t p939, int32_t p940, int32_t p941, int32_t p942, int32_t p943 -, int32_t p944, int32_t p945, int32_t p946, int32_t p947, int32_t p948, int32_t p949, int32_t p950, int32_t p951 -, int32_t p952, int32_t p953, int32_t p954, int32_t p955, int32_t p956, int32_t p957, int32_t p958, int32_t p959 -, int32_t p960, int32_t p961, int32_t p962, int32_t p963, int32_t p964, int32_t p965, int32_t p966, int32_t p967 -, int32_t p968, int32_t p969, int32_t p970, int32_t p971, int32_t p972, int32_t p973, int32_t p974, int32_t p975 -, int32_t p976, int32_t p977, int32_t p978, int32_t p979, int32_t p980, int32_t p981, int32_t p982, int32_t p983 -, int32_t p984, int32_t p985, int32_t p986, int32_t p987, int32_t p988, int32_t p989, int32_t p990, int32_t p991 -, int32_t p992, int32_t p993, int32_t p994, int32_t p995, int32_t p996, int32_t p997, int32_t p998, int32_t p999 -) -{ - int32_t x; - x = p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 - + p8 + p9 + p10 + p11 + p12 + p13 + p14 + p15 - + p16 + p17 + p18 + p19 + p20 + p21 + p22 + p23 - + p24 + p25 + p26 + p27 + p28 + p29 + p30 + p31 - + p32 + p33 + p34 + p35 + p36 + p37 + p38 + p39 - + p40 + p41 + p42 + p43 + p44 + p45 + p46 + p47 - + p48 + p49 + p50 + p51 + p52 + p53 + p54 + p55 - + p56 + p57 + p58 + p59 + p60 + p61 + p62 + p63 - + p64 + p65 + p66 + p67 + p68 + p69 + p70 + p71 - + p72 + p73 + p74 + p75 + p76 + p77 + p78 + p79 - + p80 + p81 + p82 + p83 + p84 + p85 + p86 + p87 - + p88 + p89 + p90 + p91 + p92 + p93 + p94 + p95 - + p96 + p97 + p98 + p99 + p100 + p101 + p102 + p103 - + p104 + p105 + p106 + p107 + p108 + p109 + p110 + p111 - + p112 + p113 + p114 + p115 + p116 + p117 + p118 + p119 - + p120 + p121 + p122 + p123 + p124 + p125 + p126 + p127 - + p128 + p129 + p130 + p131 + p132 + p133 + p134 + p135 - + p136 + p137 + p138 + p139 + p140 + p141 + p142 + p143 - + p144 + p145 + p146 + p147 + p148 + p149 + p150 + p151 - + p152 + p153 + p154 + p155 + p156 + p157 + p158 + p159 - + p160 + p161 + p162 + p163 + p164 + p165 + p166 + p167 - + p168 + p169 + p170 + p171 + p172 + p173 + p174 + p175 - + p176 + p177 + p178 + p179 + p180 + p181 + p182 + p183 - + p184 + p185 + p186 + p187 + p188 + p189 + p190 + p191 - + p192 + p193 + p194 + p195 + p196 + p197 + p198 + p199 - + p200 + p201 + p202 + p203 + p204 + p205 + p206 + p207 - + p208 + p209 + p210 + p211 + p212 + p213 + p214 + p215 - + p216 + p217 + p218 + p219 + p220 + p221 + p222 + p223 - + p224 + p225 + p226 + p227 + p228 + p229 + p230 + p231 - + p232 + p233 + p234 + p235 + p236 + p237 + p238 + p239 - + p240 + p241 + p242 + p243 + p244 + p245 + p246 + p247 - + p248 + p249 + p250 + p251 + p252 + p253 + p254 + p255 - + p256 + p257 + p258 + p259 + p260 + p261 + p262 + p263 - + p264 + p265 + p266 + p267 + p268 + p269 + p270 + p271 - + p272 + p273 + p274 + p275 + p276 + p277 + p278 + p279 - + p280 + p281 + p282 + p283 + p284 + p285 + p286 + p287 - + p288 + p289 + p290 + p291 + p292 + p293 + p294 + p295 - + p296 + p297 + p298 + p299 + p300 + p301 + p302 + p303 - + p304 + p305 + p306 + p307 + p308 + p309 + p310 + p311 - + p312 + p313 + p314 + p315 + p316 + p317 + p318 + p319 - + p320 + p321 + p322 + p323 + p324 + p325 + p326 + p327 - + p328 + p329 + p330 + p331 + p332 + p333 + p334 + p335 - + p336 + p337 + p338 + p339 + p340 + p341 + p342 + p343 - + p344 + p345 + p346 + p347 + p348 + p349 + p350 + p351 - + p352 + p353 + p354 + p355 + p356 + p357 + p358 + p359 - + p360 + p361 + p362 + p363 + p364 + p365 + p366 + p367 - + p368 + p369 + p370 + p371 + p372 + p373 + p374 + p375 - + p376 + p377 + p378 + p379 + p380 + p381 + p382 + p383 - + p384 + p385 + p386 + p387 + p388 + p389 + p390 + p391 - + p392 + p393 + p394 + p395 + p396 + p397 + p398 + p399 - + p400 + p401 + p402 + p403 + p404 + p405 + p406 + p407 - + p408 + p409 + p410 + p411 + p412 + p413 + p414 + p415 - + p416 + p417 + p418 + p419 + p420 + p421 + p422 + p423 - + p424 + p425 + p426 + p427 + p428 + p429 + p430 + p431 - + p432 + p433 + p434 + p435 + p436 + p437 + p438 + p439 - + p440 + p441 + p442 + p443 + p444 + p445 + p446 + p447 - + p448 + p449 + p450 + p451 + p452 + p453 + p454 + p455 - + p456 + p457 + p458 + p459 + p460 + p461 + p462 + p463 - + p464 + p465 + p466 + p467 + p468 + p469 + p470 + p471 - + p472 + p473 + p474 + p475 + p476 + p477 + p478 + p479 - + p480 + p481 + p482 + p483 + p484 + p485 + p486 + p487 - + p488 + p489 + p490 + p491 + p492 + p493 + p494 + p495 - + p496 + p497 + p498 + p499 + p500 + p501 + p502 + p503 - + p504 + p505 + p506 + p507 + p508 + p509 + p510 + p511 - + p512 + p513 + p514 + p515 + p516 + p517 + p518 + p519 - + p520 + p521 + p522 + p523 + p524 + p525 + p526 + p527 - + p528 + p529 + p530 + p531 + p532 + p533 + p534 + p535 - + p536 + p537 + p538 + p539 + p540 + p541 + p542 + p543 - + p544 + p545 + p546 + p547 + p548 + p549 + p550 + p551 - + p552 + p553 + p554 + p555 + p556 + p557 + p558 + p559 - + p560 + p561 + p562 + p563 + p564 + p565 + p566 + p567 - + p568 + p569 + p570 + p571 + p572 + p573 + p574 + p575 - + p576 + p577 + p578 + p579 + p580 + p581 + p582 + p583 - + p584 + p585 + p586 + p587 + p588 + p589 + p590 + p591 - + p592 + p593 + p594 + p595 + p596 + p597 + p598 + p599 - + p600 + p601 + p602 + p603 + p604 + p605 + p606 + p607 - + p608 + p609 + p610 + p611 + p612 + p613 + p614 + p615 - + p616 + p617 + p618 + p619 + p620 + p621 + p622 + p623 - + p624 + p625 + p626 + p627 + p628 + p629 + p630 + p631 - + p632 + p633 + p634 + p635 + p636 + p637 + p638 + p639 - + p640 + p641 + p642 + p643 + p644 + p645 + p646 + p647 - + p648 + p649 + p650 + p651 + p652 + p653 + p654 + p655 - + p656 + p657 + p658 + p659 + p660 + p661 + p662 + p663 - + p664 + p665 + p666 + p667 + p668 + p669 + p670 + p671 - + p672 + p673 + p674 + p675 + p676 + p677 + p678 + p679 - + p680 + p681 + p682 + p683 + p684 + p685 + p686 + p687 - + p688 + p689 + p690 + p691 + p692 + p693 + p694 + p695 - + p696 + p697 + p698 + p699 + p700 + p701 + p702 + p703 - + p704 + p705 + p706 + p707 + p708 + p709 + p710 + p711 - + p712 + p713 + p714 + p715 + p716 + p717 + p718 + p719 - + p720 + p721 + p722 + p723 + p724 + p725 + p726 + p727 - + p728 + p729 + p730 + p731 + p732 + p733 + p734 + p735 - + p736 + p737 + p738 + p739 + p740 + p741 + p742 + p743 - + p744 + p745 + p746 + p747 + p748 + p749 + p750 + p751 - + p752 + p753 + p754 + p755 + p756 + p757 + p758 + p759 - + p760 + p761 + p762 + p763 + p764 + p765 + p766 + p767 - + p768 + p769 + p770 + p771 + p772 + p773 + p774 + p775 - + p776 + p777 + p778 + p779 + p780 + p781 + p782 + p783 - + p784 + p785 + p786 + p787 + p788 + p789 + p790 + p791 - + p792 + p793 + p794 + p795 + p796 + p797 + p798 + p799 - + p800 + p801 + p802 + p803 + p804 + p805 + p806 + p807 - + p808 + p809 + p810 + p811 + p812 + p813 + p814 + p815 - + p816 + p817 + p818 + p819 + p820 + p821 + p822 + p823 - + p824 + p825 + p826 + p827 + p828 + p829 + p830 + p831 - + p832 + p833 + p834 + p835 + p836 + p837 + p838 + p839 - + p840 + p841 + p842 + p843 + p844 + p845 + p846 + p847 - + p848 + p849 + p850 + p851 + p852 + p853 + p854 + p855 - + p856 + p857 + p858 + p859 + p860 + p861 + p862 + p863 - + p864 + p865 + p866 + p867 + p868 + p869 + p870 + p871 - + p872 + p873 + p874 + p875 + p876 + p877 + p878 + p879 - + p880 + p881 + p882 + p883 + p884 + p885 + p886 + p887 - + p888 + p889 + p890 + p891 + p892 + p893 + p894 + p895 - + p896 + p897 + p898 + p899 + p900 + p901 + p902 + p903 - + p904 + p905 + p906 + p907 + p908 + p909 + p910 + p911 - + p912 + p913 + p914 + p915 + p916 + p917 + p918 + p919 - + p920 + p921 + p922 + p923 + p924 + p925 + p926 + p927 - + p928 + p929 + p930 + p931 + p932 + p933 + p934 + p935 - + p936 + p937 + p938 + p939 + p940 + p941 + p942 + p943 - + p944 + p945 + p946 + p947 + p948 + p949 + p950 + p951 - + p952 + p953 + p954 + p955 + p956 + p957 + p958 + p959 - + p960 + p961 + p962 + p963 + p964 + p965 + p966 + p967 - + p968 + p969 + p970 + p971 + p972 + p973 + p974 + p975 - + p976 + p977 + p978 + p979 + p980 + p981 + p982 + p983 - + p984 + p985 + p986 + p987 + p988 + p989 + p990 + p991 - + p992 + p993 + p994 + p995 + p996 + p997 + p998 + p999; - return x; -} - -// clang-format on diff --git a/src/test/app/wasm_fixtures/wat/custom_page_sizes.wat b/src/test/app/wasm_fixtures/wat/custom_page_sizes.wat deleted file mode 100644 index c0bf1c3a11..0000000000 --- a/src/test/app/wasm_fixtures/wat/custom_page_sizes.wat +++ /dev/null @@ -1,13 +0,0 @@ -(module - ;; Define a memory with 1 initial page. - ;; CRITICAL: We explicitly set the page size to 1 byte. - ;; Standard Wasm implies (pagesize 65536). - (memory 1 (pagesize 1)) - - (func $escrow_finish (result i32) - ;; If this module instantiates, the runtime accepted the custom page size. - i32.const 1 - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/deep_recursion.wat b/src/test/app/wasm_fixtures/wat/deep_recursion.wat deleted file mode 100644 index efe20cf53d..0000000000 --- a/src/test/app/wasm_fixtures/wat/deep_recursion.wat +++ /dev/null @@ -1,29 +0,0 @@ -(module - ;; Define a Mutable Global Variable to act as our counter. - ;; We initialize it to 1,000,000. - (global $counter (mut i32) (i32.const 1000000)) - - (func $escrow_finish (result i32) - ;; 1. Check if counter == 0 (Base Case) - global.get $counter - i32.eqz - if - ;; If counter is 0, we are done. Return 1. - i32.const 1 - return - end - - ;; 2. Decrement the Global Counter - global.get $counter - i32.const 1 - i32.sub - global.set $counter - - ;; 3. Recursive Step: Call SELF - ;; This puts an i32 (1) on the stack when it returns. - call $escrow_finish - ) - - ;; Export the only function we have - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/functions_5k.zip b/src/test/app/wasm_fixtures/wat/functions_5k.zip deleted file mode 100644 index e261760545..0000000000 Binary files a/src/test/app/wasm_fixtures/wat/functions_5k.zip and /dev/null differ diff --git a/src/test/app/wasm_fixtures/wat/locals_10k.zip b/src/test/app/wasm_fixtures/wat/locals_10k.zip deleted file mode 100644 index 22aad2db51..0000000000 Binary files a/src/test/app/wasm_fixtures/wat/locals_10k.zip and /dev/null differ diff --git a/src/test/app/wasm_fixtures/wat/memory64.wat b/src/test/app/wasm_fixtures/wat/memory64.wat deleted file mode 100644 index 3273af1e40..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory64.wat +++ /dev/null @@ -1,21 +0,0 @@ -(module - ;; Define a 64-bit memory (index type i64) - ;; Start with 1 page. - (memory i64 1) - - (func $escrow_finish (result i32) - ;; 1. Perform a store using a 64-bit address. - ;; Even if the value is small (0), the type MUST be i64. - i64.const 0 ;; Address (64-bit) - i32.const 42 ;; Value (32-bit) - i32.store8 ;; Opcode doesn't change, but validation rules do. - - ;; 2. check memory size - ;; memory.size now returns an i64. - memory.size - i64.const 1 - i64.eq ;; Returns i32 (1 if true) - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_end_of_word_over_limit.wat b/src/test/app/wasm_fixtures/wat/memory_end_of_word_over_limit.wat deleted file mode 100644 index 855307ddf4..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_end_of_word_over_limit.wat +++ /dev/null @@ -1,28 +0,0 @@ -(module - ;; 1. Define Memory: 1 Page = 64KB = 65,536 bytes - (memory 1) - - ;; Export memory so the host can inspect it if needed - (export "memory" (memory 0)) - - (func $test_straddle (result i32) - ;; Push the address onto the stack. - ;; 65534 is valid, but it is only 2 bytes away from the end. - i32.const 65534 - - ;; Attempt to load an i32 (4 bytes) from that address. - ;; This requires bytes 65534, 65535, 65536, and 65537. - ;; Since 65536 is the first invalid byte, this MUST trap. - i32.load - - ;; Clean up the stack. - ;; The load pushed a value, but we don't care what it is. - drop - - ;; Return 1 to signal "I survived the memory access" - i32.const 1 - ) - - ;; Export the function so you can call it from your host (JS, Python, etc.) - (export "escrow_finish" (func $test_straddle)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_grow_0_page_more_than_8MB.wat b/src/test/app/wasm_fixtures/wat/memory_grow_0_page_more_than_8MB.wat deleted file mode 100644 index 777f3062bf..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_grow_0_page_more_than_8MB.wat +++ /dev/null @@ -1,29 +0,0 @@ -(module - ;; Start at your limit: 128 pages (8MB) - (memory 128) - (export "memory" (memory 0)) - - (func $try_grow_beyond_limit (result i32) - ;; Attempt to grow by 0 page - i32.const 0 - memory.grow - - ;; memory.grow returns: - ;; -1 if the growth failed (Correct behavior for your limit) - ;; 128 (old size) if growth succeeded (Means limit was bypassed) - - ;; Check if result == -1 - i32.const -1 - i32.eq - if - ;; Growth FAILED (Host blocked it). Return -1. - i32.const -1 - return - end - - ;; Growth SUCCEEDED (Host allowed it). Return 1. - i32.const 1 - ) - - (export "escrow_finish" (func $try_grow_beyond_limit)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_grow_0_to_1.wat b/src/test/app/wasm_fixtures/wat/memory_grow_0_to_1.wat deleted file mode 100644 index 54a4193927..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_grow_0_to_1.wat +++ /dev/null @@ -1,26 +0,0 @@ -(module - ;; 1. Define Memory: Start with 0 pages - (memory 0) - - ;; Export memory to host - (export "memory" (memory 0)) - - (func $grow_from_zero (result i32) - ;; We have 0 pages. We want to add 1 page. - ;; Push delta (1) onto stack. - i32.const 1 - - ;; Grow the memory. - ;; If successful: memory becomes 64KB, returns old size (0). - ;; If failed: memory stays 0, returns -1. - memory.grow - - ;; Drop the return value of memory.grow - drop - - ;; Return 1 (as requested) - i32.const 1 - ) - - (export "escrow_finish" (func $grow_from_zero)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_grow_1_page_more_than_8MB.wat b/src/test/app/wasm_fixtures/wat/memory_grow_1_page_more_than_8MB.wat deleted file mode 100644 index 540b112178..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_grow_1_page_more_than_8MB.wat +++ /dev/null @@ -1,29 +0,0 @@ -(module - ;; Start at your limit: 128 pages (8MB) - (memory 128) - (export "memory" (memory 0)) - - (func $try_grow_beyond_limit (result i32) - ;; Attempt to grow by 1 page - i32.const 1 - memory.grow - - ;; memory.grow returns: - ;; -1 if the growth failed (Correct behavior for your limit) - ;; 128 (old size) if growth succeeded (Means limit was bypassed) - - ;; Check if result == -1 - i32.const -1 - i32.eq - if - ;; Growth FAILED (Host blocked it). Return -1. - i32.const -1 - return - end - - ;; Growth SUCCEEDED (Host allowed it). Return 1. - i32.const 1 - ) - - (export "escrow_finish" (func $try_grow_beyond_limit)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_grow_1_to_0.wat b/src/test/app/wasm_fixtures/wat/memory_grow_1_to_0.wat deleted file mode 100644 index cc4d161153..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_grow_1_to_0.wat +++ /dev/null @@ -1,33 +0,0 @@ -(module - ;; 1. Define Memory: Start with 1 page (64KB) - (memory 1) - - ;; Export memory to host - (export "memory" (memory 0)) - - (func $grow_negative (result i32) - ;; The user pushed -1. In Wasm, this is interpreted as unsigned MAX_UINT32. - ;; This is requesting to add 4,294,967,295 pages (approx 256 TB). - ;; A secure runtime MUST fail this request (return -1) without crashing. - i32.const -1 - - ;; Grow the memory. - ;; Returns: old_size if success, -1 if failure. - memory.grow - - ;; Check if result == -1 (Failure) - i32.const -1 - i32.eq - if - ;; If memory.grow returned -1, we return -1 to signal "Correctly failed". - i32.const -1 - return - end - - ;; If we are here, memory.grow somehow SUCCEEDED (Vulnerability). - ;; We return 1 to signal "Unexpected Success". - i32.const 1 - ) - - (export "escrow_finish" (func $grow_negative)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_init_1_page_more_than_8MB.wat b/src/test/app/wasm_fixtures/wat/memory_init_1_page_more_than_8MB.wat deleted file mode 100644 index f1bbee6c61..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_init_1_page_more_than_8MB.wat +++ /dev/null @@ -1,27 +0,0 @@ -(module - ;; Define memory: 129 pages (> 8MB limit) min, 129 pages max - (memory 129 129) - - ;; Export memory so host can verify size - (export "memory" (memory 0)) - - ;; access last byte of 8MB limit - (func $access_last_byte (result i32) - ;; Math: 128 pages * 64,536 bytes/page = 8,388,608 bytes - ;; Valid indices: 0 to 8,388,607 - - ;; Push the address of the LAST valid byte - i32.const 8388607 - - ;; Load byte from that address - i32.load8_u - - ;; Drop the value (we don't care what it is, just that we could read it) - drop - - ;; Return 1 to indicate success - i32.const 1 - ) - - (export "escrow_finish" (func $access_last_byte)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_last_byte_of_8MB.wat b/src/test/app/wasm_fixtures/wat/memory_last_byte_of_8MB.wat deleted file mode 100644 index e00f5e1239..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_last_byte_of_8MB.wat +++ /dev/null @@ -1,26 +0,0 @@ -(module - ;; Define memory: 128 pages (8MB) min, 128 pages max - (memory 128 128) - - ;; Export memory so host can verify size - (export "memory" (memory 0)) - - (func $access_last_byte (result i32) - ;; Math: 128 pages * 64,536 bytes/page = 8,388,608 bytes - ;; Valid indices: 0 to 8,388,607 - - ;; Push the address of the LAST valid byte - i32.const 8388607 - - ;; Load byte from that address - i32.load8_u - - ;; Drop the value (we don't care what it is, just that we could read it) - drop - - ;; Return 1 to indicate success - i32.const 1 - ) - - (export "escrow_finish" (func $access_last_byte)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_negative_address.wat b/src/test/app/wasm_fixtures/wat/memory_negative_address.wat deleted file mode 100644 index 6e26a07108..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_negative_address.wat +++ /dev/null @@ -1,23 +0,0 @@ -(module - ;; Define memory: 128 pages (8MB) min, 128 pages max - (memory 128 128) - - ;; Export memory so host can verify size - (export "memory" (memory 0)) - - (func $access_last_byte (result i32) - ;; Push a negative address - i32.const -1 - - ;; Load byte from that address - i32.load8_u - - ;; Drop the value - drop - - ;; Return 1 to indicate success - i32.const 1 - ) - - (export "escrow_finish" (func $access_last_byte)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_offset_over_limit.wat b/src/test/app/wasm_fixtures/wat/memory_offset_over_limit.wat deleted file mode 100644 index 20a401e3d2..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_offset_over_limit.wat +++ /dev/null @@ -1,27 +0,0 @@ -(module - ;; 1. Define Memory: 1 Page = 64KB - (memory 1) - - (export "memory" (memory 0)) - - (func $test_offset_overflow (result i32) - ;; 1. Push the base address onto the stack. - ;; We use '0', which is the safest, most valid address possible. - i32.const 0 - - ;; 2. Attempt to load using a static offset. - ;; syntax: i32.load offset=N align=N - ;; We set the offset to 65536 (the size of the memory). - ;; The effective address becomes 0 + 65536 = 65536. - i32.load offset=65536 - - ;; Clean up the stack. - ;; The load pushed a value, but we don't care what it is. - drop - - ;; Return 1 to signal "I survived the memory access" - i32.const 1 - ) - - (export "escrow_finish" (func $test_offset_overflow)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_pointer_at_limit.wat b/src/test/app/wasm_fixtures/wat/memory_pointer_at_limit.wat deleted file mode 100644 index e4432e6fdd..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_pointer_at_limit.wat +++ /dev/null @@ -1,22 +0,0 @@ -(module - ;; Define 1 page of memory (64KB = 65,536 bytes) - (memory 1) - - (func $read_edge (result i32) - ;; Push the index of the LAST valid byte - i32.const 65535 - - ;; Load 1 byte (unsigned) - i32.load8_u - - ;; Clean up the stack. - ;; The load pushed a value, but we don't care what it is. - drop - - ;; Return 1 to signal "I survived the memory access" - i32.const 1 - ) - - ;; Export as "escrow_finish" as requested - (export "escrow_finish" (func $read_edge)) -) diff --git a/src/test/app/wasm_fixtures/wat/memory_pointer_over_limit.wat b/src/test/app/wasm_fixtures/wat/memory_pointer_over_limit.wat deleted file mode 100644 index 906468f308..0000000000 --- a/src/test/app/wasm_fixtures/wat/memory_pointer_over_limit.wat +++ /dev/null @@ -1,23 +0,0 @@ -(module - ;; Define 1 page of memory (64KB = 65,536 bytes) - (memory 1) - - (func $read_overflow (result i32) - ;; Push the index of the FIRST invalid byte - ;; Memory is 0..65535, so 65536 is out of bounds. - i32.const 65536 - - ;; Load 1 byte (unsigned) - i32.load8_u - - ;; Clean up the stack. - ;; The load pushed a value, but we don't care what it is. - drop - - ;; Return 1 to signal "I survived the memory access" - i32.const 1 - ) - - ;; Export as "escrow_finish" as requested - (export "escrow_finish" (func $read_overflow)) - ) diff --git a/src/test/app/wasm_fixtures/wat/multi_memory.wat b/src/test/app/wasm_fixtures/wat/multi_memory.wat deleted file mode 100644 index 67fc5e76aa..0000000000 --- a/src/test/app/wasm_fixtures/wat/multi_memory.wat +++ /dev/null @@ -1,16 +0,0 @@ -(module - ;; Memory 0: Index 0 (Empty) - (memory 0) - - ;; Memory 1: Index 1 (Size 1 page) - ;; If multi-memory is disabled, this line causes a validation error (max 1 memory). - (memory 1) - - (func $escrow_finish (result i32) - ;; Query size of Memory Index 1. - ;; Should return 1 (success). - memory.size 1 - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/opc_reserved.wat b/src/test/app/wasm_fixtures/wat/opc_reserved.wat deleted file mode 100644 index 0bc61b52c3..0000000000 --- a/src/test/app/wasm_fixtures/wat/opc_reserved.wat +++ /dev/null @@ -1,98 +0,0 @@ -(module - - ;; Type for call_indirect - (type (func (result i32))) - - ;; Memory and table declarations - (memory 1) - (table 1 funcref) - (data (i32.const 0) "test") - (elem (i32.const 0) $test_func) - - ;; Global declarations - (global $g0 (mut i32) (i32.const 0)) - (global $g1 (mut i64) (i64.const 0)) - - ;; Test function for call/call_indirect - (func $test_func (result i32) - i32.const 42 - ) - - - ;; Main function with all instructions in hex order - (func $all_instructions (export "all_instructions") (result i32) - (local $l0 i32) - (local $l1 i64) - - ;; 0x01: nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - i32.const 11 - ) -) diff --git a/src/test/app/wasm_fixtures/wat/proposal_bulk_memory.wat b/src/test/app/wasm_fixtures/wat/proposal_bulk_memory.wat deleted file mode 100644 index ce59868ce6..0000000000 --- a/src/test/app/wasm_fixtures/wat/proposal_bulk_memory.wat +++ /dev/null @@ -1,25 +0,0 @@ -(module - ;; Define 1 page of memory - (memory 1) - (export "memory" (memory 0)) - - (func $test_bulk_ops (result i32) - ;; Setup: Write value 42 at index 0 so we have something to copy - (i32.store8 (i32.const 0) (i32.const 42)) - - ;; Test memory.copy (Opcode 0xFC 0x0A) - ;; Copy 1 byte from offset 0 to offset 100 - (memory.copy - (i32.const 100) ;; Destination Offset - (i32.const 0) ;; Source Offset - (i32.const 1) ;; Size (bytes) - ) - - ;; Verify: Read byte at offset 100. Should be 42. - (i32.load8_u (i32.const 100)) - (i32.const 42) - i32.eq - ) - - (export "escrow_finish" (func $test_bulk_ops)) -) diff --git a/src/test/app/wasm_fixtures/wat/proposal_extended_const.wat b/src/test/app/wasm_fixtures/wat/proposal_extended_const.wat deleted file mode 100644 index e296a468f0..0000000000 --- a/src/test/app/wasm_fixtures/wat/proposal_extended_const.wat +++ /dev/null @@ -1,15 +0,0 @@ -(module - ;; 1. Define a global using an EXTENDED constant expression. - ;; MVP only allows (i32.const X). - ;; This proposal allows (i32.add (i32.const X) (i32.const Y)). - (global $g i32 (i32.add (i32.const 10) (i32.const 32))) - - (func $escrow_finish (result i32) - ;; 2. verify the global equals 42 - global.get $g - i32.const 42 - i32.eq - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/proposal_float_to_int.wat b/src/test/app/wasm_fixtures/wat/proposal_float_to_int.wat deleted file mode 100644 index 367735f5e7..0000000000 --- a/src/test/app/wasm_fixtures/wat/proposal_float_to_int.wat +++ /dev/null @@ -1,18 +0,0 @@ -(module - (func $test_saturation (result i32) - ;; 1. Push a float that is too big for a 32-bit integer - ;; 1e10 (10 billion) > 2.14 billion (Max i32) - f32.const 1.0e10 - - ;; 2. Attempt saturating conversion (Opcode 0xFC 0x00) - ;; If supported: Clamps to MAX_I32. - ;; If disabled: Validation error (unknown instruction). - i32.trunc_sat_f32_s - - ;; 3. Check if result is MAX_I32 (2147483647) - i32.const 2147483647 - i32.eq - ) - - (export "escrow_finish" (func $test_saturation)) -) diff --git a/src/test/app/wasm_fixtures/wat/proposal_gc_struct_new.wat b/src/test/app/wasm_fixtures/wat/proposal_gc_struct_new.wat deleted file mode 100644 index bc33b7fada..0000000000 --- a/src/test/app/wasm_fixtures/wat/proposal_gc_struct_new.wat +++ /dev/null @@ -1,12 +0,0 @@ -;; generated by wasm-tools print gc_test.wasm that has the following hex -;; 0061736d01000000010b026000017f5f027f017f0103020100070a010666696e69736800000a0a010800fb01011a41010b -(module - (type (;0;) (func (result i32))) - (type (;1;) (struct (field (mut i32)) (field (mut i32)))) - (export "escrow_finish" (func 0)) - (func (;0;) (type 0) (result i32) - struct.new_default 1 - drop - i32.const 1 - ) -) diff --git a/src/test/app/wasm_fixtures/wat/proposal_multi_value.wat b/src/test/app/wasm_fixtures/wat/proposal_multi_value.wat deleted file mode 100644 index 23f1691872..0000000000 --- a/src/test/app/wasm_fixtures/wat/proposal_multi_value.wat +++ /dev/null @@ -1,22 +0,0 @@ -(module - ;; 1. Function returning TWO values (Multi-Value feature) - (func $get_numbers (result i32 i32) - i32.const 10 - i32.const 20 - ) - - (func $escrow_finish (result i32) - ;; Call pushes [10, 20] onto the stack - call $get_numbers - - ;; 2. Block taking TWO parameters (Multi-Value feature) - ;; It consumes the [10, 20] from the stack. - block (param i32 i32) (result i32) - i32.add ;; 10 + 20 = 30 - i32.const 30 ;; Expected result - i32.eq ;; Compare: returns 1 if equal - end - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/proposal_mutable_global.wat b/src/test/app/wasm_fixtures/wat/proposal_mutable_global.wat deleted file mode 100644 index 82a5d35203..0000000000 --- a/src/test/app/wasm_fixtures/wat/proposal_mutable_global.wat +++ /dev/null @@ -1,25 +0,0 @@ -(module - ;; Define a mutable global initialized to 0 - (global $counter (mut i32) (i32.const 0)) - - ;; EXPORTING a mutable global is the key feature of this proposal. - ;; In strict MVP, exported globals had to be immutable (const). - (export "counter" (global $counter)) - - (func $escrow_finish (result i32) - ;; 1. Get current value - global.get $counter - - ;; 2. Add 1 - i32.const 1 - i32.add - - ;; 3. Set new value (Mutation) - global.set $counter - - ;; 4. Return 1 for success - i32.const 1 - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/proposal_ref_types.wat b/src/test/app/wasm_fixtures/wat/proposal_ref_types.wat deleted file mode 100644 index 8cba4edf29..0000000000 --- a/src/test/app/wasm_fixtures/wat/proposal_ref_types.wat +++ /dev/null @@ -1,18 +0,0 @@ -(module - ;; Import a table from the host that holds externrefs - (import "env" "table" (table 1 externref)) - - (func $test_ref_types (result i32) - ;; Store a null externref into the table at index 0 - ;; If reference_types is disabled, 'externref' and 'ref.null' will fail parsing. - (table.set - (i32.const 0) ;; Index - (ref.null extern) ;; Value (Null External Reference) - ) - - ;; Return 1 (Success) - i32.const 1 - ) - - (export "escrow_finish" (func $test_ref_types)) -) diff --git a/src/test/app/wasm_fixtures/wat/proposal_sign_ext.wat b/src/test/app/wasm_fixtures/wat/proposal_sign_ext.wat deleted file mode 100644 index 9c8fdd1980..0000000000 --- a/src/test/app/wasm_fixtures/wat/proposal_sign_ext.wat +++ /dev/null @@ -1,18 +0,0 @@ -(module - (func $test_sign_ext (result i32) - ;; Push 255 (0x000000FF) onto the stack - i32.const 255 - - ;; Sign-extend from 8-bit to 32-bit - ;; If 255 is treated as an i8, it is -1. - ;; Result should be -1 (0xFFFFFFFF). - ;; Without this proposal, this opcode (0xC0) causes a validation error. - i32.extend8_s - - ;; Check if result is -1 - i32.const -1 - i32.eq - ) - - (export "escrow_finish" (func $test_sign_ext)) -) diff --git a/src/test/app/wasm_fixtures/wat/proposal_stringref.wat b/src/test/app/wasm_fixtures/wat/proposal_stringref.wat deleted file mode 100644 index c9f8030faf..0000000000 --- a/src/test/app/wasm_fixtures/wat/proposal_stringref.wat +++ /dev/null @@ -1 +0,0 @@ -;;hard to generate diff --git a/src/test/app/wasm_fixtures/wat/proposal_tail_call.wat b/src/test/app/wasm_fixtures/wat/proposal_tail_call.wat deleted file mode 100644 index 193fb0aeb2..0000000000 --- a/src/test/app/wasm_fixtures/wat/proposal_tail_call.wat +++ /dev/null @@ -1,15 +0,0 @@ -(module - ;; Define a simple function we can tail-call - (func $target (result i32) - i32.const 1 - ) - - (func $escrow_finish (result i32) - ;; Try to use the 'return_call' instruction (Opcode 0x12) - ;; If Tail Call proposal is disabled, this fails to Compile/Validate. - ;; If enabled, it jumps to $target, which returns 1. - return_call $target - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/start_loop.wat b/src/test/app/wasm_fixtures/wat/start_loop.wat deleted file mode 100644 index 241774e53e..0000000000 --- a/src/test/app/wasm_fixtures/wat/start_loop.wat +++ /dev/null @@ -1,22 +0,0 @@ -(module - ;; Function 1: The Infinite Loop - (func $run_forever - (loop $infinite - br $infinite - ) - ) - - ;; Function 2: Finish - (func $escrow_finish (result i32) - i32.const 1 - ) - - ;; 1. EXPORT the functions (optional, if you want to call them later) - (export "start" (func $run_forever)) - (export "escrow_finish" (func $escrow_finish)) - - ;; 2. The special start section - ;; This tells the VM: "Run function $run_forever immediately - ;; when this module is instantiated." - (start $run_forever) -) diff --git a/src/test/app/wasm_fixtures/wat/table_0_elements.wat b/src/test/app/wasm_fixtures/wat/table_0_elements.wat deleted file mode 100644 index 9b8a5408d2..0000000000 --- a/src/test/app/wasm_fixtures/wat/table_0_elements.wat +++ /dev/null @@ -1,10 +0,0 @@ -(module - ;; Define a table with exactly 0 entries - (table 0 funcref) - - ;; Standard finish function - (func $escrow_finish (result i32) - i32.const 1 - ) - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/table_2_tables.wat b/src/test/app/wasm_fixtures/wat/table_2_tables.wat deleted file mode 100644 index 4e4e013ce3..0000000000 --- a/src/test/app/wasm_fixtures/wat/table_2_tables.wat +++ /dev/null @@ -1,24 +0,0 @@ -(module - ;; Define a dummy function to put in the tables - (func $dummy) - - ;; TABLE 0: The default table (allowed in MVP) - ;; Size: 1 initial, 1 max - (table $t0 1 1 funcref) - - ;; Initialize Table 0 at index 0 - (elem (table $t0) (i32.const 0) $dummy) - - ;; TABLE 1: The second table (Requires Reference Types proposal) - ;; If strict MVP is enforced, the parser should error here. - (table $t1 1 1 funcref) - - ;; Initialize Table 1 at index 0 - (elem (table $t1) (i32.const 0) $dummy) - - (func $escrow_finish (result i32) - ;; If we successfully loaded a module with 2 tables, return 1. - i32.const 1 - ) - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/table_64_elements.wat b/src/test/app/wasm_fixtures/wat/table_64_elements.wat deleted file mode 100644 index 3221571fe9..0000000000 --- a/src/test/app/wasm_fixtures/wat/table_64_elements.wat +++ /dev/null @@ -1,25 +0,0 @@ -(module - ;; Define a table with exactly 64 entries - (table 64 funcref) - - ;; A dummy function to reference - (func $dummy) - - ;; Initialize the table at offset 0 with 64 references to $dummy - (elem (i32.const 0) - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 8 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 16 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 24 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 32 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 40 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 48 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 56 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 64 - ) - - ;; Standard finish function - (func $escrow_finish (result i32) - i32.const 1 - ) - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/table_65_elements.wat b/src/test/app/wasm_fixtures/wat/table_65_elements.wat deleted file mode 100644 index aa0688c56f..0000000000 --- a/src/test/app/wasm_fixtures/wat/table_65_elements.wat +++ /dev/null @@ -1,25 +0,0 @@ -(module - ;; Define a table with exactly 65 entries - (table 65 funcref) - - ;; A dummy function to reference - (func $dummy) - - ;; Initialize the table at offset 0 with 65 references to $dummy - (elem (i32.const 0) - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 8 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 16 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 24 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 32 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 40 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 48 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 56 - $dummy $dummy $dummy $dummy $dummy $dummy $dummy $dummy ;; 64 - $dummy ;; 65 (The one that breaks the camel's back) - ) - - (func $escrow_finish (result i32) - i32.const 1 - ) - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/table_uint_max.wat b/src/test/app/wasm_fixtures/wat/table_uint_max.wat deleted file mode 100644 index 23908611c8..0000000000 --- a/src/test/app/wasm_fixtures/wat/table_uint_max.wat +++ /dev/null @@ -1,15 +0,0 @@ -(module - ;; Definition: (table ) - ;; We use 0xFFFFFFFF (4,294,967,295), which is the unsigned equivalent of -1. - ;; This tests if the runtime handles the maximum possible u32 value - ;; without integer overflows or attempting a massive allocation. - ;; - ;; Note that using -1 as the table size cannot be parsed by wasm-tools or wat2wasm - (table 0xFFFFFFFF funcref) - - (func $escrow_finish (result i32) - ;; If the module loads despite the massive table, return 1. - i32.const 1 - ) - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/trap_divide_by_0.wat b/src/test/app/wasm_fixtures/wat/trap_divide_by_0.wat deleted file mode 100644 index 6f8754ec8f..0000000000 --- a/src/test/app/wasm_fixtures/wat/trap_divide_by_0.wat +++ /dev/null @@ -1,15 +0,0 @@ -(module - (func $escrow_finish (export "escrow_finish") (result i32) - ;; Setup for Requirement 2: Divide an i32 by 0 - i32.const 42 ;; Push numerator - i32.const 0 ;; Push denominator (0) - i32.div_s ;; Perform signed division (42 / 0) - - ;; --- NOTE: Execution usually traps (crashes) at the line above --- - - ;; Logic to satisfy Requirement 1: Return i32 = 1 - ;; If execution continued, we would drop the division result and return 1 - drop ;; Clear the stack - i32.const 1 ;; Push the return value - ) -) diff --git a/src/test/app/wasm_fixtures/wat/trap_func_signature_mismatch.wat b/src/test/app/wasm_fixtures/wat/trap_func_signature_mismatch.wat deleted file mode 100644 index fd20f6176a..0000000000 --- a/src/test/app/wasm_fixtures/wat/trap_func_signature_mismatch.wat +++ /dev/null @@ -1,33 +0,0 @@ -(module - ;; Define a table with 1 slot - (table 1 funcref) - - ;; Define Type A: Takes nothing, returns nothing - (type $type_void (func)) - - ;; Define Type B: Takes nothing, returns i32 - (type $type_i32 (func (result i32))) - - ;; Define a function of Type A - (func $void_func (type $type_void) - nop - ) - - ;; Put Type A function into Table[0] - (elem (i32.const 0) $void_func) - - (func $escrow_finish (result i32) - ;; Attempt to call Index 0, but CLAIM we expect Type B (result i32). - ;; The function at Index 0 matches Type A. - ;; TRAP: "indirect call type mismatch" - - ;; 1. Push the table index (0) onto the stack - i32.const 0 - - ;; 2. Call indirect using Type B signature. - ;; This pops the index (0) from the stack. - call_indirect (type $type_i32) - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/trap_int_overflow.wat b/src/test/app/wasm_fixtures/wat/trap_int_overflow.wat deleted file mode 100644 index 208e5bd211..0000000000 --- a/src/test/app/wasm_fixtures/wat/trap_int_overflow.wat +++ /dev/null @@ -1,18 +0,0 @@ -(module - (func $test_int_overflow (result i32) - ;; 1. Push INT_MIN (-2147483648) - ;; In Hex: 0x80000000 - i32.const -2147483648 - - ;; 2. Push -1 - i32.const -1 - - ;; 3. Signed Division - ;; This specific case is the ONLY integer arithmetic operation - ;; (besides divide by zero) that traps in the spec. - ;; Result would be +2147483648, which is too big for signed i32. - i32.div_s - ) - - (export "escrow_finish" (func $test_int_overflow)) -) diff --git a/src/test/app/wasm_fixtures/wat/trap_null_call.wat b/src/test/app/wasm_fixtures/wat/trap_null_call.wat deleted file mode 100644 index 63173303c5..0000000000 --- a/src/test/app/wasm_fixtures/wat/trap_null_call.wat +++ /dev/null @@ -1,22 +0,0 @@ -(module - ;; Table size is 1, so Index 0 is VALID bounds. - ;; However, we do NOT initialize it, so it contains 'ref.null'. - (table 1 funcref) - - (type $t (func (result i32))) - - (func $escrow_finish (result i32) - ;; Call Index 0. - ;; Bounds check passes (0 < 1). - ;; Null check fails. - ;; TRAP: "uninitialized element" or "undefined element" - - ;; 1. Push the index (0) onto the stack first - i32.const 0 - - ;; 2. Perform the call. This pops the index. - call_indirect (type $t) - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/trap_unreachable.wat b/src/test/app/wasm_fixtures/wat/trap_unreachable.wat deleted file mode 100644 index 3d8fe89f5b..0000000000 --- a/src/test/app/wasm_fixtures/wat/trap_unreachable.wat +++ /dev/null @@ -1,12 +0,0 @@ -(module - (func $escrow_finish (result i32) - ;; This instruction explicitly causes a trap. - ;; It consumes no fuel (beyond the instruction itself) and stops execution. - unreachable - - ;; This code is dead and never reached - i32.const 1 - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/wasi_get_time.wat b/src/test/app/wasm_fixtures/wat/wasi_get_time.wat deleted file mode 100644 index 6b525067a8..0000000000 --- a/src/test/app/wasm_fixtures/wat/wasi_get_time.wat +++ /dev/null @@ -1,38 +0,0 @@ -(module - ;; Import clock_time_get from WASI - ;; Signature: (param clock_id precision return_ptr) (result errno) - (import "wasi_snapshot_preview1" "clock_time_get" - (func $clock_time_get (param i32 i64 i32) (result i32)) - ) - - (memory 1) - (export "memory" (memory 0)) - - (func $escrow_finish (result i32) - ;; We will store the timestamp (a 64-bit integer) at address 0. - ;; No setup required in memory beforehand! - - ;; Call the function - (call $clock_time_get - (i32.const 0) ;; clock_id: 0 = Realtime (Wallclock) - (i64.const 1000) ;; precision: 1000ns (hint to OS) - (i32.const 0) ;; result_ptr: Write the time to address 0 - ) - - ;; The function returns an 'errno' (error code). - ;; 0 = Success. Anything else = Error. - - ;; Check if errno (top of stack) is 0 - i32.eqz - if (result i32) - ;; Success! The time is now stored in heap[0..8]. - ;; We return 1 as requested. - i32.const 1 - else - ;; Failed (maybe WASI is disabled or clock is missing) - i32.const -1 - end - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/wasi_print.wat b/src/test/app/wasm_fixtures/wat/wasi_print.wat deleted file mode 100644 index 511c5ba724..0000000000 --- a/src/test/app/wasm_fixtures/wat/wasi_print.wat +++ /dev/null @@ -1,59 +0,0 @@ -(module - ;; Import WASI fd_write - ;; Signature: (fd, iovs_ptr, iovs_len, nwritten_ptr) -> errno - (import "wasi_snapshot_preview1" "fd_write" - (func $fd_write (param i32 i32 i32 i32) (result i32)) - ) - - (memory 1) - (export "memory" (memory 0)) - - ;; --- DATA SEGMENTS --- - - ;; 1. The String Data "Hello\n" placed at offset 16 - ;; We assume offset 0-16 is reserved for the IOVec struct - (data (i32.const 16) "Hello\n") - - ;; 2. The IO Vector (struct iovec) placed at offset 0 - ;; Structure: { buf_ptr: u32, buf_len: u32 } - - ;; Field 1: buf_ptr = 16 (Location of "Hello\n") - ;; Encoded in little-endian: 10 00 00 00 - (data (i32.const 0) "\10\00\00\00") - - ;; Field 2: buf_len = 6 (Length of "Hello\n") - ;; Encoded in little-endian: 06 00 00 00 - (data (i32.const 4) "\06\00\00\00") - - (func $escrow_finish (result i32) - (local $nwritten_ptr i32) - - ;; We will ask WASI to write the "number of bytes written" to address 24 - ;; (safely after our string data) - i32.const 24 - local.set $nwritten_ptr - - ;; Call fd_write - (call $fd_write - (i32.const 1) ;; fd: 1 = STDOUT - (i32.const 0) ;; iovs_ptr: Address 0 (where we defined the struct) - (i32.const 1) ;; iovs_len: We are passing 1 vector - (local.get $nwritten_ptr) ;; nwritten_ptr: Address 24 - ) - - ;; The function returns an 'errno' (i32). - ;; 0 means Success. - - ;; Check if errno == 0 - i32.eqz - if (result i32) - ;; Success: Return 1 - i32.const 1 - else - ;; Failure: Return -1 - i32.const -1 - end - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/test/app/wasm_fixtures/wat/wide_arithmetic.wat b/src/test/app/wasm_fixtures/wat/wide_arithmetic.wat deleted file mode 100644 index 13b1ab4836..0000000000 --- a/src/test/app/wasm_fixtures/wat/wide_arithmetic.wat +++ /dev/null @@ -1,22 +0,0 @@ -(module - (func $escrow_finish (result i32) - ;; 1. Push operands - i64.const 1 - i64.const 2 - - ;; 2. Execute Wide Multiplication - ;; If the feature is DISABLED, the parser/validator will trap here - ;; with "unknown instruction" or "invalid opcode". - ;; Input: [i64, i64] -> Output: [i64, i64] - i64.mul_wide_u - - ;; 3. Clean up the stack (drop the two i64 results) - drop - drop - - ;; 4. Return 1 to signal that validation passed - i32.const 1 - ) - - (export "escrow_finish" (func $escrow_finish)) -) diff --git a/src/tests/libxrpl/CMakeLists.txt b/src/tests/libxrpl/CMakeLists.txt index 44f7b4bdc4..f8c53e02bd 100644 --- a/src/tests/libxrpl/CMakeLists.txt +++ b/src/tests/libxrpl/CMakeLists.txt @@ -5,15 +5,24 @@ include(verify_headers) # Test requirements. find_package(GTest REQUIRED) -# Single combined gtest binary built from the shared test helpers and all test -# modules below. -add_executable( - xrpl_tests - main.cpp +add_library( + xrpl.testkit.wasm + STATIC helpers/Account.cpp helpers/TestSink.cpp helpers/TxTest.cpp + tx/wasm/fixtures/NftSetup.cpp + tx/wasm/fixtures/WasmLedger.cpp + tx/wasm/fixtures/WasmRun.cpp ) +target_include_directories(xrpl.testkit.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries( + xrpl.testkit.wasm + PUBLIC xrpl.libxrpl xrpl_wasm_testkit_cxxbridge +) +add_dependencies(xrpl.testkit.wasm xrpl_crates) + +add_executable(xrpl_tests main.cpp) patch_nix_binary(xrpl_tests) set_target_properties( xrpl_tests @@ -21,10 +30,10 @@ set_target_properties( ) # Lets test sources include the shared helpers as . target_include_directories(xrpl_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(xrpl_tests PRIVATE GTest::gtest GTest::gmock xrpl.libxrpl) - -target_link_libraries(xrpl_tests PRIVATE xrpl_wasm_testkit_cxxbridge) -add_dependencies(xrpl_tests xrpl_crates) +target_link_libraries( + xrpl_tests + PRIVATE GTest::gtest GTest::gmock xrpl.libxrpl xrpl.testkit.wasm +) # One source subdirectory per module. Network unit tests are currently not # supported on Windows. @@ -55,6 +64,13 @@ foreach(module IN LISTS test_modules) "${CMAKE_CURRENT_SOURCE_DIR}/${module}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/${module}.cpp" ) + # The framework-free half of tx/wasm/fixtures/ is compiled into xrpl.testkit.wasm, + # which this binary links; the rest of that folder belongs here. + list( + FILTER sources + EXCLUDE + REGEX "/fixtures/(NftSetup|WasmLedger|WasmRun)\\.cpp$" + ) target_sources(xrpl_tests PRIVATE ${sources}) # Expose the module's private headers under their canonical include path. diff --git a/src/tests/libxrpl/tx/wasm/NFTFixture.h b/src/tests/libxrpl/tx/wasm/NFTFixture.h deleted file mode 100644 index 559787ada4..0000000000 --- a/src/tests/libxrpl/tx/wasm/NFTFixture.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include - -#include -#include -#include - -namespace xrpl::test { - -struct NFTTest : RealHostFixture -{ - static constexpr std::uint16_t kFlags = nft::kFlagTransferable | nft::kFlagBurnable; - static constexpr std::uint16_t kFee = 314; - static constexpr std::uint32_t kTaxon = 12345; - static constexpr std::uint32_t kSequence = 7; - - static uint256 - makeNftId(AccountID const& issuer); - - // Mint a real NFToken owned by `issuer` (taxon 0) and return its id, read back from the - // owner's NFTokenPage. TxTest applies to the open ledger, which produces no metadata, so - // the id is recovered from ledger state rather than from the mint's metadata. - uint256 - mintNFT(Account const& issuer, std::optional uri = std::nullopt); -}; - -} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/Preflight.cpp b/src/tests/libxrpl/tx/wasm/Preflight.cpp index 2309fafd46..095ef4ced8 100644 --- a/src/tests/libxrpl/tx/wasm/Preflight.cpp +++ b/src/tests/libxrpl/tx/wasm/Preflight.cpp @@ -6,8 +6,8 @@ #include #include #include -#include -#include +#include +#include #include #include @@ -29,7 +29,7 @@ constexpr std::string_view kRunnableWat = R"wat( } // namespace // `preflightEscrowWasm` takes no host, so this fixture holds none - which is the point of -// the signature, and what deriving from `WasmTest` would hide. Only a journal, to read the +// the signature, and what deriving from `MockVmTest` would hide. Only a journal, to read the // refusal out of. struct PreflightTest : testing::Test { diff --git a/src/tests/libxrpl/tx/wasm/README.md b/src/tests/libxrpl/tx/wasm/README.md new file mode 100644 index 0000000000..ed1621c8aa --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/README.md @@ -0,0 +1,90 @@ +# WASM host-function tests — layering + +These tests are deliberately **layered**: each layer isolates one thing, so a failure points at +one place instead of "somewhere in the stack." If a folder looks thin, the breadth it seems to be +missing lives in a sibling layer. + +## The layers + +| Layer | Location | host | VM | ledger | Answers | +| ------------------------------------- | --------------------------------------------------- | ---- | --- | ------ | ----------------------------------------------------------------------------------- | +| Engine / gas / limits / ABI | `crates/xrpl-wasm-vm`, `crates/xrpl-host-functions` | mock | ✓ | ✗ | gas, transfer budget, memory/field limits, preflight, VM limits, generated ABI | +| `host_context/` (`HostContextTest`) | `.../host_context` | mock | ✗ | ✗ | the `HostContext` marshalling shim alone (byte order, buffer sizing, `SField` xlat) | +| `host_calls/` (`HostCallTest`) | `.../host_calls` | mock | ✓ | ✗ | per-function **wire contract** — what the host was asked, what came back | +| `host_functions/` (`RealHostFixture`) | `.../host_functions` | real | ✗ | real | each function's **actual answer** vs. a real `TxTest` ledger | +| `e2e/` (`RealVmTest`) | `.../e2e` | real | ✓ | real | **full-stack integration** — VM + `HostContext` + real impl + real ledger | + +Run the C++ side with: + +```bash +./build/xrpl_tests --gtest_filter='*Impl.*:*Call.*:*E2e.*:WasmVMTest.*:WasmVMDeathTest.*:PreflightTest.*' +``` + +(707 tests, 136 suites.) The engine-level coverage is Rust: `cd crates && cargo test`. + +## `fixtures/` — split by whether it needs a test framework + +| | | +| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **No GTest** — the `xrpl.testkit.wasm` library | `WasmLedger` (real genesis ledger + the real host over it), `WasmRun` (WAT assembler), `NftSetup`, `FloatConstants` | +| **GTest** → `xrpl_tests` | `RealHostFixture` (`: testing::Test, WasmLedger` + `expectValue`/`expectError`/`expectKeyletMatches`), `FloatFixture`, `NFTFixture`, `MockHostFunctions`, `WasmFixture`, `RealVmTest`, `HostContextFixture` | + +A benchmark wants a ledger and a host, not GTest's lifecycle. Both binaries link the library; +`xrpl.bench.wasm` links no GTest and no GMock at all. + +Setup steps in `WasmLedger` and `NftSetup` **throw** (`fixtureFailed`) rather than using `EXPECT_`. +Not stylistic: an `EXPECT_` outside a running test is recorded and discarded, so a benchmark whose +escrow was never created would still run its host call, take the not-found path, and report a +cheap, plausible, completely wrong price. **If you add a setup step that can fail, throw.** + +## Gas calibration + +The benchmarks that price these host functions live in `src/benchmarks/libxrpl/wasm/`, mirroring +this tree one file per function, and have their own README. They link `xrpl.testkit.wasm` (above) +for the ledger and host, and no test framework. + +## What `e2e/` covers — the rule + +**`e2e/` covers every marshalling shape and cross-call convention exactly once. It does not cover +every function.** That is a completeness claim on the axis e2e uniquely tests, not a sample. + +`host_calls` pins what the bridge _asks_ with a _canned_ answer; `host_functions` pins what the +real impl _answers_. The type system guarantees they agree on signatures. Nothing guarantees they +agree on **conventions** — units, endianness, buffer layout — because in neither test does a real +guest write bytes a real host reads. That is exactly the `seq`-as-little-endian-region bug: every +internal test passed, and it was caught by cross-checking the guest SDK. + +Convention mismatch is a property of a call's **shape**, not of the function. All 19 keylets share +one shape, so a 19th keylet e2e proves nothing the 1st did. The inventory is meant to be exhaustive: + +| Shape / convention | Covered by | Why it is its own row | +| ----------------------------------------- | -------------------------- | -------------------------------------------------------- | +| no-input scalar getter | `LedgerSqnE2e` | header read; the minimal call | +| field code in, bytes out (ledger object) | `CurrentLedgerObjFieldE2e` | `SField` translation over a real object | +| field code in, bytes out (transaction) | `TxFieldE2e` | a different source than a ledger object | +| region in, bytes out + `u32` region | `CacheLedgerObjE2e` | the 4-byte little-endian region convention | +| slot in, bytes out — **cross-call state** | `CacheLedgerObjE2e` | the slot table is the only host state outliving one call | +| locator (path of i32 steps) | `TxNestedFieldE2e` | a wire format the guest writes and the host walks | +| **two** output regions | `FloatToMantExpE2e` | two bounds checks, two writes, an ordering between them | +| write / mutation | `SetDataE2e` | the one thing a contract changes | +| **error** path from a real impl | `HostErrorE2e` | a soft code from a real failure, not a staged one | +| realistic multi-call contract | `HostFunctionTourE2e` | the old `all_host_functions` tour shape, as one test | + +Adding a function needs no new e2e case unless it introduces a shape not in that table. Per-function +breadth lives in `host_functions/` and `host_calls/`, one case each. + +## Out of scope + +**The guest SDK** (`xrpl-std` / `xrpl-escrow`, external `xrpl-wasm-stdlib` repo) is not exercised +here — that is the SDK repo's own suite. These tests hand-write the ABI in WAT (raw imports, +literal field codes, hand-built byte layouts), deliberately bypassing all SDK code. Agreement is +verified _transitively_: the SDK repo tests the SDK against the ABI spec, this repo tests the host +against the same spec. That would not catch a drift where both diverge on an ambiguous point; +closing it needs a **cross-repo integration test** (compiled guests against a real host) in CI +where the Rust→wasm toolchain exists. + +**Transactor-level (L5) tests** are deferred: the redesign does not yet wire `runEscrowWasm` into +the `EscrowFinish` transactor, so there is no caller under `src/xrpld`. When it is wired, these +need a home as C++ transactor tests over a real `Env` — `set_data` persistence (including on +`tecBYTECODE_REJECTED`), `sfGasUsed` / `sfVMReturnCode` in transaction metadata, and owner-reserve +accounting for a bytecode-bearing escrow. The layers here deliberately stop at the VM boundary. diff --git a/src/tests/libxrpl/tx/wasm/WasmVM.cpp b/src/tests/libxrpl/tx/wasm/WasmVM.cpp index f4c771872a..59d1c9a2f2 100644 --- a/src/tests/libxrpl/tx/wasm/WasmVM.cpp +++ b/src/tests/libxrpl/tx/wasm/WasmVM.cpp @@ -6,7 +6,8 @@ #include #include -#include +#include +#include #include #include @@ -52,7 +53,7 @@ constexpr std::string_view kNoMemoryWat = R"wat( } // namespace -class WasmVMTest : public WasmTest +class WasmVMTest : public MockVmTest { }; diff --git a/src/tests/libxrpl/tx/wasm/e2e/CacheLedgerObj.cpp b/src/tests/libxrpl/tx/wasm/e2e/CacheLedgerObj.cpp new file mode 100644 index 0000000000..80635fee76 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/e2e/CacheLedgerObj.cpp @@ -0,0 +1,63 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test { + +// The keylet -> cache -> read round trip: the only place a contract's host calls depend on +// each other. Every other e2e case here is one call in isolation. This one is three, and each +// consumes what the last produced: `accountroot_id` computes a key into guest memory, `cache_le` +// hands those same bytes back to the host and answers with a slot number, and `le_field` +// uses that slot to read the object. The slot table is the one piece of host state that +// outlives a single call, so this is the only test at any layer that can catch the two ends +// of that state disagreeing — `host_calls` mocks the host, so its slot numbers are whatever +// the mock was told to return, and `host_functions` calls the impl directly, so its slots +// never cross the guest boundary at all. +struct CacheLedgerObjE2e : RealVmTest +{ +}; + +TEST_F(CacheLedgerObjE2e, ContractComputesAKeyCachesTheObjectAndReadsItsField) +{ + auto const owner = fund("owner"); + auto const wat = std::format( + R"wat( +(module + (import "host_lib" "accountroot_id" (func $accountroot_id (param i32 i32 i32 i32) (result i32))) + (import "host_lib" "cache_le" (func $cache_le (param i32 i32 i32) (result i32))) + (import "host_lib" "le_field" (func $le_field (param i32 i32 i32 i32) (result i32))) + (memory (export "memory") 1) + (data (i32.const 0) "{}") + (func (export "escrow_finish") (result i32) + (local $slot i32) + (local $r i32) + ;; The account's AccountRoot keylet, computed by the host into offset 64. + (local.set $r (call $accountroot_id (i32.const 0) (i32.const 20) (i32.const 64) (i32.const 32))) + (if (i32.lt_s (local.get $r) (i32.const 0)) (then (return (local.get $r)))) + ;; Those same 32 bytes handed straight back: cache the object they name. + (local.set $slot (call $cache_le (i32.const 64) (i32.const 32) (i32.const 0))) + (if (i32.lt_s (local.get $slot) (i32.const 0)) (then (return (local.get $slot)))) + ;; And read a field of it through the slot the host just assigned. + (call $le_field (local.get $slot) (i32.const {}) (i32.const 128) (i32.const 32)))) +)wat", + watEscaped(RealHostFixture::toBytes(owner.id())), + sfAccount.getCode()); + + auto const outcome = run(wat); + ASSERT_TRUE(outcome.has_value()) << transToken(outcome.error().ter); + // 20 bytes: the `sfAccount` the contract read back is the account it started from, so + // the key it computed found the right object. + EXPECT_EQ( + outcome->result, static_cast(RealHostFixture::toBytes(owner.id()).size())); +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/e2e/CurrentLedgerObjField.cpp b/src/tests/libxrpl/tx/wasm/e2e/CurrentLedgerObjField.cpp new file mode 100644 index 0000000000..839aaedd1d --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/e2e/CurrentLedgerObjField.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test { + +// A contract reads a field of its current ledger object (a real escrow) end to end: the real +// VM runs the guest, `HostContext` marshals the field code into an `SField`, the real impl +// reads the real ledger, and the byte count comes back to the guest. `host_calls/` proves the +// marshalling with a mock and `host_functions/` proves the impl's answer without a VM; this +// proves the two agree over a real ledger. +struct CurrentLedgerObjFieldE2e : RealVmTest +{ + // Create a real escrow owned by `owner` and return its keylet — the object the contract + // runs against. + Keylet + makeEscrow(Account const& owner, Account const& dest) + { + ledger.createAccount(owner, XRP(1000)); + ledger.createAccount(dest, XRP(1000)); + auto const ownerSeq = ledger.getAccountRoot(owner.id()).getSequence(); + auto const r = ledger.submit( + transactions::EscrowCreateBuilder{owner.id(), dest.id(), XRP(100)}.setFinishAfter( + 900'000'000), + owner); + EXPECT_EQ(r.ter, tesSUCCESS) << transToken(r.ter); + ledger.close(); + return keylet::escrow(owner.id(), SeqProxy::rawSequence(ownerSeq)); + } +}; + +TEST_F(CurrentLedgerObjFieldE2e, ContractReadsAFieldOfItsRealEscrow) +{ + auto const owner = Account{"owner"}; + auto const escrow = makeEscrow(owner, Account{"dest"}); + + // Ask the current object for `sfAccount` and return the byte count the host wrote — 20 for + // an account id — proving the read reached the real ledger and came back through the VM. + auto const wat = std::format( + R"wat( +(module + (import "host_lib" "home_le_field" (func $home_le_field (param i32 i32 i32) (result i32))) + (memory (export "memory") 1) + (func (export "escrow_finish") (result i32) + (call $home_le_field (i32.const {}) (i32.const 0) (i32.const 32)))) +)wat", + sfAccount.getCode()); + + auto const outcome = run(wat, escrow); + ASSERT_TRUE(outcome.has_value()) << transToken(outcome.error().ter); + EXPECT_EQ(outcome->result, static_cast(toBytes(owner.id()).size())); +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/e2e/FloatToMantExp.cpp b/src/tests/libxrpl/tx/wasm/e2e/FloatToMantExp.cpp new file mode 100644 index 0000000000..a70fdb07ce --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/e2e/FloatToMantExp.cpp @@ -0,0 +1,66 @@ +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test { + +// The only host function that writes to *two* output regions, and so the only place the +// "one call, one answer" assumption in every other marshalling path is not what happens. +// `float_to_mant_exp` splits a float into an eight-byte mantissa and a four-byte exponent, +// each into its own guest buffer, and answers with a status rather than a byte count. Two +// regions means two independent bounds checks, two writes, and an ordering between them — +// none of which the single-output shapes exercise. `host_calls` pins that wiring against a +// mock; this proves the real impl drives it the same way, with the guest reading both +// halves back out of its own memory. +struct FloatToMantExpE2e : RealVmTest +{ +}; + +TEST_F(FloatToMantExpE2e, ContractReadsBothHalvesOfASplitFloat) +{ + // Pi's canonical encoding in, mantissa to offset 64, exponent to offset 128. The + // contract returns the low half of the mantissa so the assertion checks that real bytes + // landed in the guest's buffer, not merely that the call reported success. + auto const wat = std::format( + R"wat( +(module + (import "host_lib" "float_to_mant_exp" (func $split (param i32 i32 i32 i32 i32 i32) (result i32))) + (memory (export "memory") 1) + (data (i32.const 0) "{}") + (func (export "escrow_finish") (result i32) + (local $r i32) + (local.set $r (call $split + (i32.const 0) (i32.const 12) + (i32.const 64) (i32.const 8) + (i32.const 128) (i32.const 4))) + (if (i32.lt_s (local.get $r) (i32.const 0)) (then (return (local.get $r)))) + (i32.load (i32.const 64)))) +)wat", + watEscaped(FloatTest::kPi)); + + auto const outcome = run(wat); + ASSERT_TRUE(outcome.has_value()) << transToken(outcome.error().ter); + + // The expected value is derived from the input rather than written out as a literal, + // because the derivation is the interesting part: a float stores its mantissa in the + // first eight bytes **big-endian**, while `float_to_mant_exp` writes it to the guest + // **little-endian**. So the guest's `i32.load` at the start of the mantissa buffer sees + // the *low* 32 bits of a number whose bytes arrived in the opposite order. Getting that + // flip wrong is exactly the convention mismatch this layer exists to catch, and a + // hard-coded constant would hide it. + auto mantissa = std::int64_t{0}; + for (auto i = 0U; i < 8; ++i) + { + mantissa = (mantissa << 8) | FloatTest::kPi[i]; + } + EXPECT_EQ(outcome->result, static_cast(mantissa & 0xFFFFFFFF)); +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/e2e/HostError.cpp b/src/tests/libxrpl/tx/wasm/e2e/HostError.cpp new file mode 100644 index 0000000000..3b7203b415 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/e2e/HostError.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test { + +// The error channel, driven by a real failure rather than a mock's canned one. +// Every other e2e case here proves a success path. But a contract spends most of its life +// reacting to codes, and the path a *real* error takes is different from the one a mock +// error takes: the impl returns a `HostFunctionError`, `HostContext` turns it into a wire +// code, and the engine hands that back to the guest as a negative i32 without disturbing the +// run. `host_calls` proves the middle step against a mock that was *told* to fail; nothing +// until now has proved that a real impl's real failure comes out the far end intact. +struct HostErrorE2e : RealVmTest +{ +}; + +TEST_F(HostErrorE2e, ARealHostErrorReachesTheGuestAsItsWireCode) +{ + // The contract runs against an account root, then asks it for `sfMemoData` — a field + // that object does not carry. The impl genuinely fails to find it, so the code the + // guest reads was produced by the real lookup rather than staged. + auto const owner = fund("owner"); + + auto const wat = std::format( + R"wat( +(module + (import "host_lib" "home_le_field" (func $home_le_field (param i32 i32 i32) (result i32))) + (memory (export "memory") 1) + (func (export "escrow_finish") (result i32) + (call $home_le_field (i32.const {}) (i32.const 0) (i32.const 32)))) +)wat", + sfMemoData.getCode()); + + auto const outcome = run(wat, keylet::account(owner.id())); + + // The run itself succeeds: a soft host error is an answer to the contract, not a fault + // in it. Reporting it as a failed run would be the interesting bug here. + ASSERT_TRUE(outcome.has_value()) << transToken(outcome.error().ter); + EXPECT_EQ(outcome->result, static_cast(HostFunctionError::FieldNotFound)); +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/e2e/HostFunctionTour.cpp b/src/tests/libxrpl/tx/wasm/e2e/HostFunctionTour.cpp new file mode 100644 index 0000000000..ed3570aab5 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/e2e/HostFunctionTour.cpp @@ -0,0 +1,49 @@ +#include + +#include +#include + +#include + +namespace xrpl::test { + +// A single contract that tours several host functions end to end — a ledger-header read, the +// base fee, a hash, a keylet, and a data write — returning 1 only if every call succeeds. +struct HostFunctionTourE2e : RealVmTest +{ +}; + +TEST_F(HostFunctionTourE2e, AContractTouringManyHostFunctionsSucceeds) +{ + // Each call must return >= 0 (a byte count, i.e. success); the guest returns the first + // negative error code, or 1 if the whole tour succeeds. Output regions are disjoint so no + // call clobbers another, and buffers are generous so exact value sizes don't matter. + static constexpr auto kWat = std::string_view{R"wat( +(module + (import "host_lib" "ldgr_index" (func $ldgr_index (param i32 i32) (result i32))) + (import "host_lib" "base_fee" (func $base_fee (param i32 i32) (result i32))) + (import "host_lib" "sha512_half" (func $sha512_half (param i32 i32 i32 i32) (result i32))) + (import "host_lib" "accountroot_id" (func $accountroot_id (param i32 i32 i32 i32) (result i32))) + (import "host_lib" "set_data" (func $set_data (param i32 i32) (result i32))) + (memory (export "memory") 1) + (func (export "escrow_finish") (result i32) + (local $r i32) + (local.set $r (call $ldgr_index (i32.const 0) (i32.const 32))) + (if (i32.lt_s (local.get $r) (i32.const 0)) (then (return (local.get $r)))) + (local.set $r (call $base_fee (i32.const 32) (i32.const 32))) + (if (i32.lt_s (local.get $r) (i32.const 0)) (then (return (local.get $r)))) + (local.set $r (call $sha512_half (i32.const 0) (i32.const 4) (i32.const 64) (i32.const 32))) + (if (i32.lt_s (local.get $r) (i32.const 0)) (then (return (local.get $r)))) + (local.set $r (call $accountroot_id (i32.const 0) (i32.const 20) (i32.const 128) (i32.const 32))) + (if (i32.lt_s (local.get $r) (i32.const 0)) (then (return (local.get $r)))) + (local.set $r (call $set_data (i32.const 0) (i32.const 8))) + (if (i32.lt_s (local.get $r) (i32.const 0)) (then (return (local.get $r)))) + (i32.const 1))) +)wat"}; + + auto const outcome = run(kWat); + ASSERT_TRUE(outcome.has_value()) << transToken(outcome.error().ter); + EXPECT_EQ(outcome->result, 1) << "every host call in the tour should have succeeded"; +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/e2e/LedgerSqn.cpp b/src/tests/libxrpl/tx/wasm/e2e/LedgerSqn.cpp new file mode 100644 index 0000000000..824cd19f45 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/e2e/LedgerSqn.cpp @@ -0,0 +1,33 @@ +#include + +#include +#include + +#include +#include + +namespace xrpl::test { + +// The real ledger's sequence. +struct LedgerSqnE2e : RealVmTest +{ +}; + +TEST_F(LedgerSqnE2e, ContractReadsTheRealLedgerSequence) +{ + // Ask the host for the ledger sequence into offset 0, then return the i32 stored there. + static constexpr auto kWat = std::string_view{R"wat( +(module + (import "host_lib" "ldgr_index" (func $ldgr_index (param i32 i32) (result i32))) + (memory (export "memory") 1) + (func (export "escrow_finish") (result i32) + (drop (call $ldgr_index (i32.const 0) (i32.const 4))) + (i32.load (i32.const 0)))) +)wat"}; + + auto const outcome = run(kWat); + ASSERT_TRUE(outcome.has_value()) << transToken(outcome.error().ter); + EXPECT_EQ(outcome->result, static_cast(ledger.getOpenLedger().header().seq)); +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/e2e/SetData.cpp b/src/tests/libxrpl/tx/wasm/e2e/SetData.cpp new file mode 100644 index 0000000000..130c812dc8 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/e2e/SetData.cpp @@ -0,0 +1,31 @@ +#include + +#include +#include + +#include + +namespace xrpl::test { + +// A contract writes its data field end to end. +struct SetDataE2e : RealVmTest +{ +}; + +TEST_F(SetDataE2e, ContractWritesItsData) +{ + // `set_data` over 8 bytes of (zero-initialized) memory returns the byte count it stored. + static constexpr auto kWat = std::string_view{R"wat( +(module + (import "host_lib" "set_data" (func $set_data (param i32 i32) (result i32))) + (memory (export "memory") 1) + (func (export "escrow_finish") (result i32) + (call $set_data (i32.const 0) (i32.const 8)))) +)wat"}; + + auto const outcome = run(kWat); + ASSERT_TRUE(outcome.has_value()) << transToken(outcome.error().ter); + EXPECT_EQ(outcome->result, 8); +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/e2e/TxField.cpp b/src/tests/libxrpl/tx/wasm/e2e/TxField.cpp new file mode 100644 index 0000000000..54c66c1e9e --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/e2e/TxField.cpp @@ -0,0 +1,47 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test { + +// A contract reads a field of its transaction end to end. +struct TxFieldE2e : RealVmTest +{ +}; + +TEST_F(TxFieldE2e, ContractReadsAFieldOfItsTransaction) +{ + auto const owner = Account{"owner"}; + ledger.createAccount(owner, XRP(1000)); + static constexpr auto kScale = std::uint8_t{8}; + auto const tx = mptIssuanceCreateTx(owner, kScale); + + // Ask the tx for `sfAssetScale` (a single byte) and return the i32 the guest loads — the + // scale, zero-extended — so the assertion checks the value flowed through, not just a count. + auto const wat = std::format( + R"wat( +(module + (import "host_lib" "tx_field" (func $tx_field (param i32 i32 i32) (result i32))) + (memory (export "memory") 1) + (func (export "escrow_finish") (result i32) + (drop (call $tx_field (i32.const {}) (i32.const 0) (i32.const 4))) + (i32.load (i32.const 0)))) +)wat", + sfAssetScale.getCode()); + + auto const outcome = run(wat, keylet::account(owner.id()), tx.type, tx.build); + ASSERT_TRUE(outcome.has_value()) << transToken(outcome.error().ter); + EXPECT_EQ(outcome->result, kScale); +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/e2e/TxNestedField.cpp b/src/tests/libxrpl/tx/wasm/e2e/TxNestedField.cpp new file mode 100644 index 0000000000..224e3bb525 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/e2e/TxNestedField.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace xrpl::test { + +// The locator convention, end to end. +struct TxNestedFieldE2e : RealVmTest +{ + // An EscrowFinish carrying a memo, so the locator has a real leaf to reach. + TxAssembler + withMemo(Account const& acct) + { + auto assembler = escrowFinishTx(ledger, acct); + assembler.build = [inner = std::move(assembler.build)](STObject& obj) { + inner(obj); + auto memos = STArray{}; + auto memo = STObject::makeInnerObject(sfMemo); + memo.setFieldVL(sfMemoData, Slice{"hello", 5}); + memos.push_back(std::move(memo)); + obj.setFieldArray(sfMemos, memos); + }; + return assembler; + } +}; + +TEST_F(TxNestedFieldE2e, ContractWalksALocatorToANestedTransactionField) +{ + auto const owner = fund("owner"); + auto assembler = withMemo(owner); + + auto const wat = std::format( + R"wat( +(module + (import "host_lib" "tx_inner" (func $tx_inner (param i32 i32 i32 i32) (result i32))) + (memory (export "memory") 1) + (func (export "escrow_finish") (result i32) + (i32.store (i32.const 0) (i32.const {})) + (i32.store (i32.const 4) (i32.const 0)) + (i32.store (i32.const 8) (i32.const {})) + (call $tx_inner (i32.const 0) (i32.const 12) (i32.const 64) (i32.const 32)))) +)wat", + sfMemos.getCode(), + sfMemoData.getCode()); + + auto const outcome = run(wat, keylet::account(owner.id()), assembler.type, assembler.build); + ASSERT_TRUE(outcome.has_value()) << transToken(outcome.error().ter); + // Five bytes: "hello", the memo's data, reached through the locator. + EXPECT_EQ(outcome->result, 5); +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/FloatFixture.h b/src/tests/libxrpl/tx/wasm/fixtures/FloatConstants.h similarity index 91% rename from src/tests/libxrpl/tx/wasm/FloatFixture.h rename to src/tests/libxrpl/tx/wasm/fixtures/FloatConstants.h index d643f7f39a..fe7be63c8d 100644 --- a/src/tests/libxrpl/tx/wasm/FloatFixture.h +++ b/src/tests/libxrpl/tx/wasm/fixtures/FloatConstants.h @@ -3,15 +3,17 @@ #include #include -#include - #include #include #include +// Canonical float encodings, with no ledger and no test framework behind them — just the byte +// patterns the float host functions take and return. Benchmarks include this directly; +// `FloatFixture.h` mixes it into the GTest fixture the `host_functions/` tests use. + namespace xrpl::test { -struct FloatTest : RealHostFixture +struct FloatConstants { static constexpr std::int64_t kMin64 = std::numeric_limits::min(); static constexpr std::int64_t kMax64 = std::numeric_limits::max(); diff --git a/src/tests/libxrpl/tx/wasm/fixtures/FloatFixture.h b/src/tests/libxrpl/tx/wasm/fixtures/FloatFixture.h new file mode 100644 index 0000000000..926a6f5943 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/fixtures/FloatFixture.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +// The float constants with a real ledger and GTest attached, for the `host_functions/Float*` +// tests. The constants alone are in FloatConstants.h, which links no test framework. + +namespace xrpl::test { + +struct FloatTest : RealHostFixture, FloatConstants +{ +}; + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/HostContextFixture.cpp b/src/tests/libxrpl/tx/wasm/fixtures/HostContextFixture.cpp similarity index 96% rename from src/tests/libxrpl/tx/wasm/HostContextFixture.cpp rename to src/tests/libxrpl/tx/wasm/fixtures/HostContextFixture.cpp index cf5efc0453..fd0fd5d4bc 100644 --- a/src/tests/libxrpl/tx/wasm/HostContextFixture.cpp +++ b/src/tests/libxrpl/tx/wasm/fixtures/HostContextFixture.cpp @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/HostContextFixture.h b/src/tests/libxrpl/tx/wasm/fixtures/HostContextFixture.h similarity index 98% rename from src/tests/libxrpl/tx/wasm/HostContextFixture.h rename to src/tests/libxrpl/tx/wasm/fixtures/HostContextFixture.h index 1677014b8a..3789b3b7fa 100644 --- a/src/tests/libxrpl/tx/wasm/HostContextFixture.h +++ b/src/tests/libxrpl/tx/wasm/fixtures/HostContextFixture.h @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/MockHostFunctions.h b/src/tests/libxrpl/tx/wasm/fixtures/MockHostFunctions.h similarity index 100% rename from src/tests/libxrpl/tx/wasm/MockHostFunctions.h rename to src/tests/libxrpl/tx/wasm/fixtures/MockHostFunctions.h diff --git a/src/tests/libxrpl/tx/wasm/fixtures/NFTFixture.h b/src/tests/libxrpl/tx/wasm/fixtures/NFTFixture.h new file mode 100644 index 0000000000..9a163b2ca0 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/fixtures/NFTFixture.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include +#include +#include + +#include +#include + +// The NFToken helpers with a real ledger and GTest attached, for the `host_functions/NFT*` tests. +// The ledger-only versions are in NftSetup.h, which links no test framework. + +namespace xrpl::test { + +struct NFTTest : RealHostFixture, NftIds +{ + uint256 + mintNFT(Account const& issuer, std::optional uri = std::nullopt) + { + return mintNft(*this, issuer, uri); + } +}; + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/NFTFixture.cpp b/src/tests/libxrpl/tx/wasm/fixtures/NftSetup.cpp similarity index 59% rename from src/tests/libxrpl/tx/wasm/NFTFixture.cpp rename to src/tests/libxrpl/tx/wasm/fixtures/NftSetup.cpp index 0bf1ea023c..bdaf29c8f9 100644 --- a/src/tests/libxrpl/tx/wasm/NFTFixture.cpp +++ b/src/tests/libxrpl/tx/wasm/fixtures/NftSetup.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -10,28 +10,33 @@ #include // IWYU pragma: keep #include -#include #include +#include #include +#include #include namespace xrpl::test { uint256 -NFTTest::makeNftId(AccountID const& issuer) +NftIds::makeNftId(AccountID const& issuer) { return NFTokenMint::createNFTokenID(kFlags, kFee, issuer, nft::toTaxon(kTaxon), kSequence); } uint256 -NFTTest::mintNFT(Account const& issuer, std::optional uri) +mintNft(WasmLedger& fixture, Account const& issuer, std::optional uri) { + auto& ledger = fixture.ledger; auto builder = transactions::NFTokenMintBuilder{issuer.id(), 0u}; if (uri) builder.setURI(Slice{uri->data(), uri->size()}); auto const r = ledger.submit(builder, issuer); - EXPECT_EQ(r.ter, tesSUCCESS) << transToken(r.ter); + if (r.ter != tesSUCCESS) + { + fixtureFailed(std::string{"minting the NFToken: "} + transToken(r.ter)); + } ledger.close(); // The single minted token lives in the owner's first NFTokenPage. @@ -39,14 +44,21 @@ NFTTest::mintNFT(Account const& issuer, std::optional uri) auto const first = keylet::nftokenPageMin(issuer.id()).key; auto const last = keylet::nftokenPageMax(issuer.id()).key; auto const pageKey = view.succ(first, last.next()); - EXPECT_TRUE(pageKey.has_value()); - auto const page = pageKey ? view.read(Keylet{ltNFTOKEN_PAGE, *pageKey}) : nullptr; - EXPECT_NE(page, nullptr); - if (!page) - return uint256{}; + if (!pageKey.has_value()) + { + fixtureFailed("finding the minted token's NFTokenPage"); + } + auto const page = view.read(Keylet{ltNFTOKEN_PAGE, *pageKey}); + if (page == nullptr) + { + fixtureFailed("reading the minted token's NFTokenPage"); + } auto const& tokens = page->getFieldArray(sfNFTokens); - EXPECT_FALSE(tokens.empty()); - return tokens.empty() ? uint256{} : tokens[0].getFieldH256(sfNFTokenID); + if (tokens.empty()) + { + fixtureFailed("the NFTokenPage holds no tokens"); + } + return tokens[0].getFieldH256(sfNFTokenID); } } // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/fixtures/NftSetup.h b/src/tests/libxrpl/tx/wasm/fixtures/NftSetup.h new file mode 100644 index 0000000000..93e3f798f1 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/fixtures/NftSetup.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include + +#include +#include + +#include +#include +#include + +// NFToken setup, built on `WasmLedger` rather than on a GTest fixture so a benchmark can mint a +// token without linking a test framework. Tests reach the same helpers through +// `RealHostFixture`, which derives from `WasmLedger`. + +namespace xrpl::test { + +// The fields baked into `makeNftId`, so a caller can assert an extractor returned the right one. +struct NftIds +{ + static constexpr std::uint16_t kFlags = nft::kFlagTransferable | nft::kFlagBurnable; + static constexpr std::uint16_t kFee = 314; + static constexpr std::uint32_t kTaxon = 12345; + static constexpr std::uint32_t kSequence = 7; + + // A well-formed id carrying the constants above. Computed, not minted: the id-extractor host + // functions read the id itself and never touch the ledger. + static uint256 + makeNftId(AccountID const& issuer); +}; + +// Mint a real NFToken owned by `issuer` (taxon 0) and return its id, read back from the owner's +// NFTokenPage. `TxTest` applies to the open ledger, which produces no metadata, so the id comes +// from ledger state rather than from the mint's metadata. +// +// Throws via `fixtureFailed` if the mint or the page lookup fails; see WasmLedger.h for why that +// is a throw and not an `EXPECT_`. +uint256 +mintNft( + WasmLedger& fixture, + Account const& issuer, + std::optional uri = std::nullopt); + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/fixtures/RealHostFixture.cpp b/src/tests/libxrpl/tx/wasm/fixtures/RealHostFixture.cpp new file mode 100644 index 0000000000..6380f301f6 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/fixtures/RealHostFixture.cpp @@ -0,0 +1,16 @@ +#include + +#include +#include + +#include + +namespace xrpl::test { + +void +expectKeyletMatches(std::expected const& result, Keylet const& expected) +{ + expectValue(result, RealHostFixture::toBytes(expected.key)); +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/fixtures/RealHostFixture.h b/src/tests/libxrpl/tx/wasm/fixtures/RealHostFixture.h new file mode 100644 index 0000000000..f9bdb6b049 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/fixtures/RealHostFixture.h @@ -0,0 +1,54 @@ +#pragma once + +#include +#include + +#include +#include + +#include +#include + +// The GTest layer over `WasmLedger`: the assertion helpers, and the fixture base the +// `host_functions/` tests derive from. +// +// Everything that touches a ledger or builds a host lives in `WasmLedger.h`, which knows nothing +// about GTest so the benchmarks can share it. Only what genuinely needs the framework is here. + +namespace xrpl::test { + +template +void +expectValue( + std::expected const& result, + U const& expected, + std::source_location loc = std::source_location::current()) +{ + auto trace = testing::ScopedTrace{loc.file_name(), static_cast(loc.line()), ""}; + ASSERT_TRUE(result.has_value()) + << "expected a value, got error " << static_cast(result.error()); + EXPECT_EQ(*result, expected); +} + +template +void +expectError( + std::expected const& result, + HostFunctionError expected, + std::source_location loc = std::source_location::current()) +{ + auto trace = testing::ScopedTrace{loc.file_name(), static_cast(loc.line()), ""}; + ASSERT_FALSE(result.has_value()) << "expected error, got a value"; + EXPECT_EQ(result.error(), expected); +} + +void +expectKeyletMatches(std::expected const& result, Keylet const& expected); + +// A `WasmLedger` with GTest's lifecycle attached. Tests derive from this; benchmarks use +// `WasmLedger` directly. +struct RealHostFixture : testing::Test, WasmLedger +{ +}; + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/fixtures/RealVmTest.h b/src/tests/libxrpl/tx/wasm/fixtures/RealVmTest.h new file mode 100644 index 0000000000..a2bed7bc4d --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/fixtures/RealVmTest.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace xrpl::test { + +// End-to-end: a WAT contract run through the REAL VM against the REAL host +// over a REAL `TxTest` ledger. +struct RealVmTest : RealHostFixture +{ + // Assemble `wat` and run its `entryPoint` through the real VM against a real host built + // over the current open ledger. `leKey`/`txType`/`assembler` configure the ledger object + // the contract runs against and the transaction it reads. + std::expected + run( + std::string_view wat, + Keylet const& leKey = keylet::account(AccountID{}), + TxType txType = ttESCROW_FINISH, + std::function assembler = [](STObject&) {}, + std::int64_t gas = kAmpleGas, + std::string_view entryPoint = escrowFunctionName) + { + auto host = makeHost(leKey, txType, std::move(assembler)); + return runWat(*host, wat, gas, entryPoint); + } +}; + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/WasmFixture.h b/src/tests/libxrpl/tx/wasm/fixtures/WasmFixture.h similarity index 77% rename from src/tests/libxrpl/tx/wasm/WasmFixture.h rename to src/tests/libxrpl/tx/wasm/fixtures/WasmFixture.h index 662752806e..28099f0a97 100644 --- a/src/tests/libxrpl/tx/wasm/WasmFixture.h +++ b/src/tests/libxrpl/tx/wasm/fixtures/WasmFixture.h @@ -8,8 +8,8 @@ #include #include #include -#include -#include +#include +#include #include #include @@ -18,30 +18,16 @@ namespace xrpl::test { -// Assemble `wat`. Throws `rust::Error` on a typo, which gtest reports against the test that -// holds it. -// -// A free function because not every wasm test needs a host: `preflightEscrowWasm` takes none, -// so its fixture derives from `testing::Test` rather than from `WasmTest`. -inline Bytes -assembleWat(std::string_view wat) -{ - auto const wasm = rs::wasm_testkit::compile_wat(rust::Str{wat.data(), wat.size()}); - return Bytes{wasm.begin(), wasm.end()}; -} - -// Base for every wasm test that runs a contract: a mocked host whose log is captured, and one -// way into the engine. +// Base for every wasm test that runs a contract against a MOCKED host whose log is captured. +// Its real-host counterpart is `RealVmTest`; both run a WAT guest through the real VM and +// forward to the shared `runWat` harness (`WasmRun.h`), differing only in the host. // // Modules are written as WebAssembly text and assembled by `assembleWat`. The assembler is in // a test-only crate: the engine itself refuses text // (`the_vm_refuses_a_text_format_module`), because a text assembler on the consensus path // would make a transaction's validity a build flag. -struct WasmTest : testing::Test +struct MockVmTest : testing::Test { - // Enough for every module here to run to completion; a test about budgets passes its own. - static constexpr std::int64_t kAmpleGas = 100'000; - // Keeps what a run logged. The host's default journal is a null sink, which would let a // swallowed condition pass a test that only checks the TER. CaptureSink sink{beast::Severity::Warning}; @@ -51,7 +37,7 @@ struct WasmTest : testing::Test // something on its own — which is the kind of surprise a test suite exists to catch. testing::StrictMock host{beast::Journal{sink}}; - WasmTest() + MockVmTest() { // `runEscrowWasm` asks every run whether the host is clean, so under a strict mock // every test would have to say so. Declared once here, and any number of times @@ -71,7 +57,7 @@ struct WasmTest : testing::Test std::int64_t gas = kAmpleGas, std::string_view entryPoint = escrowFunctionName) { - return runEscrowWasm(assemble(wat), host, gas, entryPoint); + return runWat(host, wat, gas, entryPoint); } std::expected @@ -93,7 +79,7 @@ struct WasmTest : testing::Test // Base for the per-host-function fixtures. Each derives, supplies the module that exercises // its own import, and runs it through `callHost()` — so a test says only what the host was // asked and what came back. -struct HostCallTest : WasmTest +struct HostCallTest : MockVmTest { // The module under test. One import, one `escrow_finish` that calls it. [[nodiscard]] virtual std::string diff --git a/src/tests/libxrpl/tx/wasm/RealHostFixture.cpp b/src/tests/libxrpl/tx/wasm/fixtures/WasmLedger.cpp similarity index 82% rename from src/tests/libxrpl/tx/wasm/RealHostFixture.cpp rename to src/tests/libxrpl/tx/wasm/fixtures/WasmLedger.cpp index 4e97566845..887bf4fbab 100644 --- a/src/tests/libxrpl/tx/wasm/RealHostFixture.cpp +++ b/src/tests/libxrpl/tx/wasm/fixtures/WasmLedger.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -24,36 +24,42 @@ #include #include -#include #include #include #include -#include #include #include #include #include +#include +#include #include #include #include namespace xrpl::test { +void +fixtureFailed(std::string_view what) +{ + throw std::runtime_error("test fixture setup failed: " + std::string{what}); +} + Bytes -RealHostFixture::toBytes(std::uint8_t value) +WasmLedger::toBytes(std::uint8_t value) { return {value}; } Bytes -RealHostFixture::toBytes(std::uint16_t value) +WasmLedger::toBytes(std::uint16_t value) { return {static_cast(value), static_cast(value >> 8)}; } Bytes -RealHostFixture::toBytes(std::uint32_t value) +WasmLedger::toBytes(std::uint32_t value) { return { static_cast(value), @@ -63,31 +69,31 @@ RealHostFixture::toBytes(std::uint32_t value) } Bytes -RealHostFixture::toBytes(uint256 const& value) +WasmLedger::toBytes(uint256 const& value) { return Bytes{std::begin(value), std::end(value)}; } Bytes -RealHostFixture::toBytes(std::string_view value) +WasmLedger::toBytes(std::string_view value) { return Bytes{std::begin(value), std::end(value)}; } Bytes -RealHostFixture::toBytes(std::span value) +WasmLedger::toBytes(std::span value) { return Bytes{std::begin(value), std::end(value)}; } Bytes -RealHostFixture::toBytes(AccountID const& account) +WasmLedger::toBytes(AccountID const& account) { return Bytes{std::begin(account), std::end(account)}; } Bytes -RealHostFixture::toBytes(Issue const& issue) +WasmLedger::toBytes(Issue const& issue) { auto s = Serializer{}; s.addBitString(issue.currency); @@ -97,7 +103,7 @@ RealHostFixture::toBytes(Issue const& issue) } Bytes -RealHostFixture::toBytes(Asset const& asset) +WasmLedger::toBytes(Asset const& asset) { if (asset.holds()) return toBytes(asset.get()); @@ -108,7 +114,7 @@ RealHostFixture::toBytes(Asset const& asset) } Bytes -RealHostFixture::toBytes(STAmount const& amount) +WasmLedger::toBytes(STAmount const& amount) { auto msg = Serializer{}; amount.add(msg); @@ -116,19 +122,13 @@ RealHostFixture::toBytes(STAmount const& amount) } Bytes -RealHostFixture::toBytes(STNumber const& number) +WasmLedger::toBytes(STNumber const& number) { auto msg = Serializer{}; number.add(msg); return msg.getData(); } -void -expectKeyletMatches(std::expected const& result, Keylet const& expected) -{ - expectValue(result, RealHostFixture::toBytes(expected.key)); -} - SignedMessage signMessage(std::string_view message, KeyType keyType) { @@ -145,7 +145,10 @@ uint256 credentialId(std::string_view hex) { auto id = uint256{}; - EXPECT_TRUE(id.parseHex(std::string{hex})); + if (!id.parseHex(std::string{hex})) + { + fixtureFailed("parsing the credential id hex"); + } return id; } @@ -168,8 +171,11 @@ escrowFinishTx(TxTest& ledger, Account const& acct) { return {.type = ttESCROW_FINISH, .build = [&ledger, acct](STObject& obj) { auto credId = uint256{}; - EXPECT_TRUE(credId.parseHex( - "0011223344556677889900112233445566778899001122334455667788990011")); + if (!credId.parseHex( + "0011223344556677889900112233445566778899001122334455667788990011")) + { + fixtureFailed("parsing the credential id hex"); + } obj.setAccountID(sfAccount, acct.id()); obj.setAccountID(sfOwner, acct.id()); @@ -221,7 +227,7 @@ WasmHost::operator*() const } Account -RealHostFixture::fund(char const* name, XRPAmount amount) +WasmLedger::fund(char const* name, XRPAmount amount) { auto const account = Account{name}; ledger.createAccount(account, amount); @@ -229,7 +235,7 @@ RealHostFixture::fund(char const* name, XRPAmount amount) } WasmHost -RealHostFixture::makeHost( +WasmLedger::makeHost( beast::Journal journal, Keylet const& leKey, TxType txType, @@ -250,17 +256,14 @@ RealHostFixture::makeHost( } WasmHost -RealHostFixture::makeHost( - Keylet const& leKey, - TxType txType, - std::function assembler) +WasmLedger::makeHost(Keylet const& leKey, TxType txType, std::function assembler) { return makeHost( beast::Journal{beast::Journal::getNullSink()}, leKey, txType, std::move(assembler)); } WasmHost -RealHostFixture::makeTracingHost( +WasmLedger::makeTracingHost( Keylet const& leKey, TxType txType, std::function assembler) @@ -269,13 +272,13 @@ RealHostFixture::makeTracingHost( } std::string -RealHostFixture::logged() const +WasmLedger::logged() const { return traceSink_.messages(); } void -RealHostFixture::makeSignerList( +WasmLedger::makeSignerList( Account const& owner, std::uint32_t quorum, std::vector> const& signers) @@ -290,7 +293,10 @@ RealHostFixture::makeSignerList( } auto const r = ledger.submit( transactions::SignerListSetBuilder{owner.id(), quorum}.setSignerEntries(entries), owner); - EXPECT_EQ(r.ter, tesSUCCESS) << transToken(r.ter); + if (r.ter != tesSUCCESS) + { + fixtureFailed(std::string{"submitting the signer list: "} + transToken(r.ter)); + } ledger.close(); } diff --git a/src/tests/libxrpl/tx/wasm/RealHostFixture.h b/src/tests/libxrpl/tx/wasm/fixtures/WasmLedger.h similarity index 79% rename from src/tests/libxrpl/tx/wasm/RealHostFixture.h rename to src/tests/libxrpl/tx/wasm/fixtures/WasmLedger.h index 9e149c1f3b..abe6aa8e26 100644 --- a/src/tests/libxrpl/tx/wasm/RealHostFixture.h +++ b/src/tests/libxrpl/tx/wasm/fixtures/WasmLedger.h @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -19,51 +18,36 @@ #include #include -#include #include #include #include #include -#include #include #include -#include #include #include #include #include #include +// A real genesis ledger and the real host built over it, with **no test framework**. +// +// This is the piece both `xrpl_tests` and `xrpl.bench.wasm` need, and the reason it is its own +// type: a benchmark wants a ledger and a host, not GTest's lifecycle. `RealHostFixture` adds the +// framework on top (`: testing::Test, WasmLedger`) plus the assertion helpers; a benchmark uses +// `WasmLedger` directly and links no GTest at all. +// +// Setup steps here **throw** rather than `EXPECT_`. That is the point of the separation, not a +// detail: an `EXPECT_` outside a running test is recorded and discarded, so a benchmark whose +// escrow was never created would still run its host call, take the not-found path, and report a +// cheap, plausible, completely wrong price. Throwing turns that into a stopped run. + namespace xrpl::test { -template -void -expectValue( - std::expected const& result, - U const& expected, - std::source_location loc = std::source_location::current()) -{ - auto trace = testing::ScopedTrace{loc.file_name(), static_cast(loc.line()), ""}; - ASSERT_TRUE(result.has_value()) - << "expected a value, got error " << static_cast(result.error()); - EXPECT_EQ(*result, expected); -} - -template -void -expectError( - std::expected const& result, - HostFunctionError expected, - std::source_location loc = std::source_location::current()) -{ - auto trace = testing::ScopedTrace{loc.file_name(), static_cast(loc.line()), ""}; - ASSERT_FALSE(result.has_value()) << "expected error, got a value"; - EXPECT_EQ(result.error(), expected); -} - -void -expectKeyletMatches(std::expected const& result, Keylet const& expected); +// Fail a setup step loudly. See the note above on why this is not an `EXPECT_`. +[[noreturn]] void +fixtureFailed(std::string_view what); struct SignedMessage { @@ -116,7 +100,7 @@ private: std::unique_ptr host_; }; -class RealHostFixture : public testing::Test +class WasmLedger { public: TxTest ledger; diff --git a/src/tests/libxrpl/tx/wasm/fixtures/WasmRun.cpp b/src/tests/libxrpl/tx/wasm/fixtures/WasmRun.cpp new file mode 100644 index 0000000000..278bd8fabe --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/fixtures/WasmRun.cpp @@ -0,0 +1,52 @@ +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace xrpl::test { + +Bytes +assembleWat(std::string_view wat) +{ + auto const wasm = rs::wasm_testkit::compile_wat(rust::Str{wat.data(), wat.size()}); + return Bytes{wasm.begin(), wasm.end()}; +} + +std::string +watEscaped(std::span bytes) +{ + static constexpr char kHex[] = "0123456789abcdef"; + auto out = std::string{}; + out.reserve(bytes.size() * 3); + for (auto const byte : bytes) + { + out += '\\'; + out += kHex[byte >> 4]; + out += kHex[byte & 0x0F]; + } + return out; +} + +std::string +watEscaped(Bytes const& bytes) +{ + return watEscaped(std::span{bytes.data(), bytes.size()}); +} + +std::expected +runWat(HostFunctions& host, std::string_view wat, std::int64_t gas, std::string_view entryPoint) +{ + return runEscrowWasm(assembleWat(wat), host, gas, entryPoint); +} + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/fixtures/WasmRun.h b/src/tests/libxrpl/tx/wasm/fixtures/WasmRun.h new file mode 100644 index 0000000000..a67d784bb6 --- /dev/null +++ b/src/tests/libxrpl/tx/wasm/fixtures/WasmRun.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace xrpl::test { + +// Enough gas for a small module to run to completion; a test about budgets passes its own. +inline constexpr std::int64_t kAmpleGas = 100'000; + +// Assemble WebAssembly text to bytes via the test-only `wasm_testkit` crate. The engine +// itself refuses text (a text assembler on the consensus path would make a transaction's +// validity a build flag), so this is where a WAT string becomes something runnable. Throws +// `rust::Error` on a typo, which gtest reports against the test that holds it. +Bytes +assembleWat(std::string_view wat); + +// `bytes` as the escape sequence a WAT string literal wants (`\aa\bb...`), for seeding a +// contract's memory through a `(data ...)` segment. +// +// Guest memory starts zeroed, and zeros are not a usable input to most host functions: an +// all-zero account id is `InvalidAccount`, an all-zero float is non-canonical. A contract +// that needs real bytes to work on gets them here, once at instantiation, rather than +// building them out of `i32.store` instructions. +std::string +watEscaped(std::span bytes); + +std::string +watEscaped(Bytes const& bytes); + +// Assemble and run `wat`'s `entryPoint` through the real VM, servicing host calls through +// `host` — a mock (`MockVmTest`) or the real impl over a ledger (`RealVmTest`). The one +// host-agnostic harness both fixtures inject their host into. +std::expected +runWat( + HostFunctions& host, + std::string_view wat, + std::int64_t gas = kAmpleGas, + std::string_view entryPoint = escrowFunctionName); + +} // namespace xrpl::test diff --git a/src/tests/libxrpl/tx/wasm/host_calls/CurrentLedgerObjField.cpp b/src/tests/libxrpl/tx/wasm/host_calls/CurrentLedgerObjField.cpp index 143c20fa96..e6030d7886 100644 --- a/src/tests/libxrpl/tx/wasm/host_calls/CurrentLedgerObjField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_calls/CurrentLedgerObjField.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_calls/LedgerSqn.cpp b/src/tests/libxrpl/tx/wasm/host_calls/LedgerSqn.cpp index d4cec43616..32f383f5c6 100644 --- a/src/tests/libxrpl/tx/wasm/host_calls/LedgerSqn.cpp +++ b/src/tests/libxrpl/tx/wasm/host_calls/LedgerSqn.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_calls/Sha512Half.cpp b/src/tests/libxrpl/tx/wasm/host_calls/Sha512Half.cpp index 3653a6e931..9aef5d5966 100644 --- a/src/tests/libxrpl/tx/wasm/host_calls/Sha512Half.cpp +++ b/src/tests/libxrpl/tx/wasm/host_calls/Sha512Half.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_calls/Trace.cpp b/src/tests/libxrpl/tx/wasm/host_calls/Trace.cpp index e7dd854d22..fd7b871749 100644 --- a/src/tests/libxrpl/tx/wasm/host_calls/Trace.cpp +++ b/src/tests/libxrpl/tx/wasm/host_calls/Trace.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include // For `TraceDataType`: declared in the cxx bridge, defined in the header it generates. #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/AccountKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/AccountKeylet.cpp index e64ef2c073..f53d625216 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/AccountKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/AccountKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/AmmKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/AmmKeylet.cpp index e734bdc464..5ef7108fda 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/AmmKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/AmmKeylet.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/BaseFee.cpp b/src/tests/libxrpl/tx/wasm/host_context/BaseFee.cpp index 373a47f483..ee8557ce3a 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/BaseFee.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/BaseFee.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/CacheLedgerObj.cpp b/src/tests/libxrpl/tx/wasm/host_context/CacheLedgerObj.cpp index 8c3d015362..a9376fa890 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/CacheLedgerObj.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/CacheLedgerObj.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/CheckKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/CheckKeylet.cpp index 60191ec484..f2af938101 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/CheckKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/CheckKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/CheckSignature.cpp b/src/tests/libxrpl/tx/wasm/host_context/CheckSignature.cpp index 796c56665c..751e4f17aa 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/CheckSignature.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/CheckSignature.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/CredentialKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/CredentialKeylet.cpp index 09d4c7b2fc..462babad6c 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/CredentialKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/CredentialKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjArrayLen.cpp index 5ef9dbe7c3..8c3aab2d8b 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjArrayLen.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjField.cpp b/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjField.cpp index ad00450c35..43f139bfc4 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjField.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjNestedArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjNestedArrayLen.cpp index 6a3f9f2263..5b68a4c510 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjNestedArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjNestedArrayLen.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjNestedField.cpp b/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjNestedField.cpp index f9b03f0623..7279438209 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjNestedField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/CurrentLedgerObjNestedField.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/DelegateKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/DelegateKeylet.cpp index ecbbf2abab..d1ef893d00 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/DelegateKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/DelegateKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/DepositPreauthKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/DepositPreauthKeylet.cpp index a6f2cc151c..81e524baf2 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/DepositPreauthKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/DepositPreauthKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/DidKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/DidKeylet.cpp index 872c6e9120..220cce677f 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/DidKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/DidKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/EscrowKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/EscrowKeylet.cpp index fbb4d2dbce..8983cfae8b 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/EscrowKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/EscrowKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatAdd.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatAdd.cpp index a6dadf0219..5408e80738 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatAdd.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatAdd.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatCompare.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatCompare.cpp index dbd2fbcb65..381dc58e6f 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatCompare.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatCompare.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatDivide.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatDivide.cpp index 552d172e34..b224e353e8 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatDivide.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatDivide.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatFromInt.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatFromInt.cpp index 78e78d7aa1..51736589a8 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatFromInt.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatFromInt.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatFromMantExp.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatFromMantExp.cpp index 0f3b5d8acd..f825f43f49 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatFromMantExp.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatFromMantExp.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatFromSTAmount.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatFromSTAmount.cpp index 9a9c22e390..ce2b9f070e 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatFromSTAmount.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatFromSTAmount.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatFromSTNumber.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatFromSTNumber.cpp index c18e849026..58497bd914 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatFromSTNumber.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatFromSTNumber.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatFromUint.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatFromUint.cpp index 35370dfb9b..2c8c101863 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatFromUint.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatFromUint.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatMultiply.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatMultiply.cpp index 939ecb6885..74f20430e4 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatMultiply.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatMultiply.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatPower.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatPower.cpp index 6b2c8087f4..3ec0c3b8be 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatPower.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatPower.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatSubtract.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatSubtract.cpp index 7f2a08ee1b..1821acc392 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatSubtract.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatSubtract.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatToInt.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatToInt.cpp index 05626d5c60..7f9f3f0ae2 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatToInt.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatToInt.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/FloatToMantExp.cpp b/src/tests/libxrpl/tx/wasm/host_context/FloatToMantExp.cpp index 709c6198c0..fb6a82cdc4 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/FloatToMantExp.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/FloatToMantExp.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/IsAmendmentEnabled.cpp b/src/tests/libxrpl/tx/wasm/host_context/IsAmendmentEnabled.cpp index b0cbb6362c..f8fe9c7010 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/IsAmendmentEnabled.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/IsAmendmentEnabled.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/LedgerObjArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_context/LedgerObjArrayLen.cpp index 80df1bd313..e7c9c62b0e 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/LedgerObjArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/LedgerObjArrayLen.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/LedgerObjField.cpp b/src/tests/libxrpl/tx/wasm/host_context/LedgerObjField.cpp index 8ee616b75a..bd33245258 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/LedgerObjField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/LedgerObjField.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/LedgerObjNestedArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_context/LedgerObjNestedArrayLen.cpp index 8f2d0d59a0..f4048f93fc 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/LedgerObjNestedArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/LedgerObjNestedArrayLen.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/LedgerObjNestedField.cpp b/src/tests/libxrpl/tx/wasm/host_context/LedgerObjNestedField.cpp index f0336cf39c..a4df4ec6da 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/LedgerObjNestedField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/LedgerObjNestedField.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/LedgerSqn.cpp b/src/tests/libxrpl/tx/wasm/host_context/LedgerSqn.cpp index 442248b47a..4471a0e2b0 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/LedgerSqn.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/LedgerSqn.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/MptokenIssuanceKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/MptokenIssuanceKeylet.cpp index 5a53b05eb5..b8c4c7701b 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/MptokenIssuanceKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/MptokenIssuanceKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/MptokenKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/MptokenKeylet.cpp index 7f4fd2b8f3..c26f0cd5cf 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/MptokenKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/MptokenKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/NFT.cpp b/src/tests/libxrpl/tx/wasm/host_context/NFT.cpp index ba34fff6b0..67ee63ab7b 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/NFT.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/NFT.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/NFTFlags.cpp b/src/tests/libxrpl/tx/wasm/host_context/NFTFlags.cpp index 3c18d53f1f..7c785de074 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/NFTFlags.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/NFTFlags.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/NFTIssuer.cpp b/src/tests/libxrpl/tx/wasm/host_context/NFTIssuer.cpp index 7d0401bccb..cf0c222cf2 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/NFTIssuer.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/NFTIssuer.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/NFTSequence.cpp b/src/tests/libxrpl/tx/wasm/host_context/NFTSequence.cpp index 01bdf0e19a..d3fcc9be87 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/NFTSequence.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/NFTSequence.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/NFTTaxon.cpp b/src/tests/libxrpl/tx/wasm/host_context/NFTTaxon.cpp index 4ddff82c78..1e2909845e 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/NFTTaxon.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/NFTTaxon.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/NFTTransferFee.cpp b/src/tests/libxrpl/tx/wasm/host_context/NFTTransferFee.cpp index d67c5fc5db..2ccd30f517 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/NFTTransferFee.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/NFTTransferFee.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/NftokenOfferKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/NftokenOfferKeylet.cpp index c009321ad2..81e547039e 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/NftokenOfferKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/NftokenOfferKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/OfferKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/OfferKeylet.cpp index de1f36809d..7068ee846d 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/OfferKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/OfferKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/OracleKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/OracleKeylet.cpp index 0355d05b8c..85c58d2c1d 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/OracleKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/OracleKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/ParentLedgerHash.cpp b/src/tests/libxrpl/tx/wasm/host_context/ParentLedgerHash.cpp index 2c9d3f219b..9d11271ae6 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/ParentLedgerHash.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/ParentLedgerHash.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/ParentLedgerTime.cpp b/src/tests/libxrpl/tx/wasm/host_context/ParentLedgerTime.cpp index 71a02e995c..c31d20a690 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/ParentLedgerTime.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/ParentLedgerTime.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/PaychannelKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/PaychannelKeylet.cpp index a184882a1a..096a3996b9 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/PaychannelKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/PaychannelKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/PermissionedDomainKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/PermissionedDomainKeylet.cpp index 5b490954b5..b2484379d3 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/PermissionedDomainKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/PermissionedDomainKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/Sha512Half.cpp b/src/tests/libxrpl/tx/wasm/host_context/Sha512Half.cpp index 6745be70d3..a7bd781335 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/Sha512Half.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/Sha512Half.cpp @@ -4,8 +4,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/SignerListKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/SignerListKeylet.cpp index 29c179863c..fd48a2d18b 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/SignerListKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/SignerListKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/TicketKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/TicketKeylet.cpp index 03dadd4079..c18963993d 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/TicketKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/TicketKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/Trace.cpp b/src/tests/libxrpl/tx/wasm/host_context/Trace.cpp index 857b068cdd..2ac0ebacf3 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/Trace.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/Trace.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/TrustLineKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/TrustLineKeylet.cpp index c4e4bccb01..18a4d8d34a 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/TrustLineKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/TrustLineKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/TxArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_context/TxArrayLen.cpp index 120a8069d7..887842ef7a 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/TxArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/TxArrayLen.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/TxField.cpp b/src/tests/libxrpl/tx/wasm/host_context/TxField.cpp index 24b73bb63c..84a3d694a4 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/TxField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/TxField.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/TxNestedArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_context/TxNestedArrayLen.cpp index 0269f6fbbe..5d550cc623 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/TxNestedArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/TxNestedArrayLen.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/TxNestedField.cpp b/src/tests/libxrpl/tx/wasm/host_context/TxNestedField.cpp index 0cc1cb5a77..43351b6884 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/TxNestedField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/TxNestedField.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/UpdateData.cpp b/src/tests/libxrpl/tx/wasm/host_context/UpdateData.cpp index 7d724205d5..11ee5760ed 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/UpdateData.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/UpdateData.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_context/VaultKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_context/VaultKeylet.cpp index a480b21ba2..febf81f0e0 100644 --- a/src/tests/libxrpl/tx/wasm/host_context/VaultKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_context/VaultKeylet.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/AccountKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/AccountKeylet.cpp index c36eea1d13..a846f8807e 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/AccountKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/AccountKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/AmmKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/AmmKeylet.cpp index 9414ecd6dc..cf393f7b89 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/AmmKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/AmmKeylet.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/BaseFee.cpp b/src/tests/libxrpl/tx/wasm/host_functions/BaseFee.cpp index b1f40233ca..0bba608633 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/BaseFee.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/BaseFee.cpp @@ -1,5 +1,5 @@ #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/CacheLedgerObj.cpp b/src/tests/libxrpl/tx/wasm/host_functions/CacheLedgerObj.cpp index 2625238e2e..649bd6e5ba 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/CacheLedgerObj.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/CacheLedgerObj.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/CheckKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/CheckKeylet.cpp index 0abcbdc3db..7e2571fac5 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/CheckKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/CheckKeylet.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/CheckSignature.cpp b/src/tests/libxrpl/tx/wasm/host_functions/CheckSignature.cpp index c1bfd722e4..7bfd7be73a 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/CheckSignature.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/CheckSignature.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/CredentialKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/CredentialKeylet.cpp index 0eaeeb5d6a..d3521ad256 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/CredentialKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/CredentialKeylet.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjArrayLen.cpp index 6ef7b686c3..72c3491e85 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjArrayLen.cpp @@ -4,7 +4,8 @@ #include #include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjField.cpp b/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjField.cpp index 08816ee4fa..c3c249396f 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjField.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjNestedArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjNestedArrayLen.cpp index b94d6f1329..40ce10c841 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjNestedArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjNestedArrayLen.cpp @@ -4,7 +4,8 @@ #include #include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjNestedField.cpp b/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjNestedField.cpp index c59ab5ed47..c1a9cab3da 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjNestedField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/CurrentLedgerObjNestedField.cpp @@ -6,7 +6,8 @@ #include #include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/DelegateKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/DelegateKeylet.cpp index 8b936652d3..afe148ed53 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/DelegateKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/DelegateKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/DepositPreauthKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/DepositPreauthKeylet.cpp index 8846c8d1f0..a7a3fec8c4 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/DepositPreauthKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/DepositPreauthKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/DidKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/DidKeylet.cpp index 933b3583e0..5ba5a9585c 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/DidKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/DidKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/EscrowKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/EscrowKeylet.cpp index ce6bfa73a0..e8bbaa1145 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/EscrowKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/EscrowKeylet.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatAdd.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatAdd.cpp index 6864794411..c594950cad 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatAdd.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatAdd.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatCompare.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatCompare.cpp index e66a3beebe..21acd3f915 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatCompare.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatCompare.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatDivide.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatDivide.cpp index 518ab79a82..8e48cfcafe 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatDivide.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatDivide.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatFromInt.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatFromInt.cpp index 9b5cc70b1f..cc972cbde3 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatFromInt.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatFromInt.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatFromMantExp.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatFromMantExp.cpp index 518db9e411..705c6b3fa1 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatFromMantExp.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatFromMantExp.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatFromStAmount.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatFromStAmount.cpp index 66136d78c4..36666ba2d3 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatFromStAmount.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatFromStAmount.cpp @@ -7,8 +7,8 @@ #include #include #include -#include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatFromStNumber.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatFromStNumber.cpp index 17b350fb9c..40c9f30fa5 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatFromStNumber.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatFromStNumber.cpp @@ -4,8 +4,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatFromUint.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatFromUint.cpp index bac8d19b6e..c407831448 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatFromUint.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatFromUint.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatMultiply.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatMultiply.cpp index d49693dc31..cb91211dd4 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatMultiply.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatMultiply.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatPower.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatPower.cpp index dcb99ca9b3..44e01add62 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatPower.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatPower.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatSubtract.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatSubtract.cpp index fc0d5eaa53..4e2a1d9d95 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatSubtract.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatSubtract.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatToInt.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatToInt.cpp index 119ab42b00..c8fbe6c54b 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatToInt.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatToInt.cpp @@ -2,8 +2,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/FloatToMantExp.cpp b/src/tests/libxrpl/tx/wasm/host_functions/FloatToMantExp.cpp index 877db427d5..5c8a89e5d0 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/FloatToMantExp.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/FloatToMantExp.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/GetNFT.cpp b/src/tests/libxrpl/tx/wasm/host_functions/GetNFT.cpp index e51b65e1e6..e6d152a06b 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/GetNFT.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/GetNFT.cpp @@ -4,8 +4,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/IsAmendmentEnabled.cpp b/src/tests/libxrpl/tx/wasm/host_functions/IsAmendmentEnabled.cpp index f31954c54c..8c9c34a0df 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/IsAmendmentEnabled.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/IsAmendmentEnabled.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjArrayLen.cpp index c9969d9f86..b63dfa2657 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjArrayLen.cpp @@ -5,7 +5,8 @@ #include #include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjField.cpp b/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjField.cpp index 91efc2738b..8deed246f5 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjField.cpp @@ -5,7 +5,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjNestedArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjNestedArrayLen.cpp index bd340883e6..d7e2fa8939 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjNestedArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjNestedArrayLen.cpp @@ -5,7 +5,8 @@ #include #include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjNestedField.cpp b/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjNestedField.cpp index 95c4da4e69..c8e5d844e7 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjNestedField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/LedgerObjNestedField.cpp @@ -7,7 +7,8 @@ #include #include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/LedgerSqn.cpp b/src/tests/libxrpl/tx/wasm/host_functions/LedgerSqn.cpp index cf21a259f1..a88c81a586 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/LedgerSqn.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/LedgerSqn.cpp @@ -1,5 +1,5 @@ #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/MptokenIssuanceKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/MptokenIssuanceKeylet.cpp index 91637c6e3e..d2960a0747 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/MptokenIssuanceKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/MptokenIssuanceKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/MptokenKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/MptokenKeylet.cpp index 1e9a67fe90..eb3544c2a5 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/MptokenKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/MptokenKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/NFTFlags.cpp b/src/tests/libxrpl/tx/wasm/host_functions/NFTFlags.cpp index d06ad23a17..c69871dc0d 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/NFTFlags.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/NFTFlags.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/NFTIssuer.cpp b/src/tests/libxrpl/tx/wasm/host_functions/NFTIssuer.cpp index 12fcf76c48..ef65a4fa4a 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/NFTIssuer.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/NFTIssuer.cpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/NFTSequence.cpp b/src/tests/libxrpl/tx/wasm/host_functions/NFTSequence.cpp index af8f2227a4..28cba45a68 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/NFTSequence.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/NFTSequence.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/NFTTaxon.cpp b/src/tests/libxrpl/tx/wasm/host_functions/NFTTaxon.cpp index da2942e6cd..3b7641d9e1 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/NFTTaxon.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/NFTTaxon.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/NFTTransferFee.cpp b/src/tests/libxrpl/tx/wasm/host_functions/NFTTransferFee.cpp index c9181b872c..e69eee0192 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/NFTTransferFee.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/NFTTransferFee.cpp @@ -1,8 +1,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/NftokenOfferKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/NftokenOfferKeylet.cpp index 97d8b3f699..18e669e949 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/NftokenOfferKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/NftokenOfferKeylet.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/OfferKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/OfferKeylet.cpp index cf4eac49e6..82737c9a11 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/OfferKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/OfferKeylet.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/OracleKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/OracleKeylet.cpp index 0d6df50f13..69b0792fe4 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/OracleKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/OracleKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/ParentLedgerHash.cpp b/src/tests/libxrpl/tx/wasm/host_functions/ParentLedgerHash.cpp index 4f0142731a..d5b39bde46 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/ParentLedgerHash.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/ParentLedgerHash.cpp @@ -1,5 +1,5 @@ #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/ParentLedgerTime.cpp b/src/tests/libxrpl/tx/wasm/host_functions/ParentLedgerTime.cpp index f76e47fda1..3abdef7916 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/ParentLedgerTime.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/ParentLedgerTime.cpp @@ -1,5 +1,5 @@ #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/PaychannelKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/PaychannelKeylet.cpp index 77b51254dd..8695f51605 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/PaychannelKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/PaychannelKeylet.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/PermissionedDomainedKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/PermissionedDomainedKeylet.cpp index 1c9a2ae3ce..fd659f24a7 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/PermissionedDomainedKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/PermissionedDomainedKeylet.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/Sha512Half.cpp b/src/tests/libxrpl/tx/wasm/host_functions/Sha512Half.cpp index b02c720503..7cf56f4550 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/Sha512Half.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/Sha512Half.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/SignerListKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/SignerListKeylet.cpp index b35afd493b..4d640a7a25 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/SignerListKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/SignerListKeylet.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/TicketKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/TicketKeylet.cpp index e7669bc354..93be84aff7 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/TicketKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/TicketKeylet.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/Trace.cpp b/src/tests/libxrpl/tx/wasm/host_functions/Trace.cpp index 8bb94acd13..0db8539c1d 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/Trace.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/Trace.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/TrustLineKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/TrustLineKeylet.cpp index 26017ade9e..c8c428eadf 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/TrustLineKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/TrustLineKeylet.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/TxArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_functions/TxArrayLen.cpp index 12aa3b6760..97e5d1d8b9 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/TxArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/TxArrayLen.cpp @@ -6,7 +6,8 @@ #include #include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/TxField.cpp b/src/tests/libxrpl/tx/wasm/host_functions/TxField.cpp index 6d83977c09..c0dd8efdc7 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/TxField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/TxField.cpp @@ -9,7 +9,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/TxNestedArrayLen.cpp b/src/tests/libxrpl/tx/wasm/host_functions/TxNestedArrayLen.cpp index c2d8354805..f697ceeed3 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/TxNestedArrayLen.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/TxNestedArrayLen.cpp @@ -6,7 +6,8 @@ #include #include -#include +#include +#include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/TxNestedField.cpp b/src/tests/libxrpl/tx/wasm/host_functions/TxNestedField.cpp index 4a229478db..d801d46f44 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/TxNestedField.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/TxNestedField.cpp @@ -7,7 +7,8 @@ #include #include -#include +#include +#include #include #include diff --git a/src/tests/libxrpl/tx/wasm/host_functions/UpdateData.cpp b/src/tests/libxrpl/tx/wasm/host_functions/UpdateData.cpp index 46bbee69d8..295956d6fb 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/UpdateData.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/UpdateData.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include namespace xrpl::test { diff --git a/src/tests/libxrpl/tx/wasm/host_functions/VaultKeylet.cpp b/src/tests/libxrpl/tx/wasm/host_functions/VaultKeylet.cpp index dfc968fa04..1026ed448e 100644 --- a/src/tests/libxrpl/tx/wasm/host_functions/VaultKeylet.cpp +++ b/src/tests/libxrpl/tx/wasm/host_functions/VaultKeylet.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include namespace xrpl::test {