@aztec/end-to-end 0.0.1-commit.c80b6263 → 0.0.1-commit.cd76b27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/dest/bench/client_flows/client_flows_benchmark.d.ts +2 -2
  2. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  3. package/dest/bench/client_flows/client_flows_benchmark.js +3 -3
  4. package/dest/bench/client_flows/config.d.ts +2 -2
  5. package/dest/bench/client_flows/config.d.ts.map +1 -1
  6. package/dest/bench/client_flows/config.js +18 -0
  7. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +4 -2
  8. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  9. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +10 -0
  10. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +2 -2
  11. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  12. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +3 -2
  13. package/dest/e2e_deploy_contract/deploy_test.d.ts +2 -2
  14. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  15. package/dest/e2e_epochs/epochs_test.d.ts +9 -7
  16. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  17. package/dest/e2e_epochs/epochs_test.js +58 -33
  18. package/dest/e2e_fees/fees_test.d.ts +2 -2
  19. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  20. package/dest/e2e_fees/fees_test.js +5 -5
  21. package/dest/e2e_l1_publisher/write_json.d.ts +3 -2
  22. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -1
  23. package/dest/e2e_l1_publisher/write_json.js +1 -7
  24. package/dest/e2e_p2p/p2p_network.d.ts +2 -2
  25. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  26. package/dest/e2e_p2p/p2p_network.js +16 -2
  27. package/dest/e2e_p2p/reqresp/utils.d.ts +22 -0
  28. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -0
  29. package/dest/e2e_p2p/reqresp/utils.js +177 -0
  30. package/dest/e2e_p2p/shared.d.ts +2 -2
  31. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  32. package/dest/e2e_p2p/shared.js +5 -1
  33. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +2 -0
  34. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +1 -0
  35. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.js +184 -0
  36. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts +18 -0
  37. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +1 -0
  38. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.js +120 -0
  39. package/dest/e2e_token_contract/token_contract_test.d.ts +4 -2
  40. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  41. package/dest/e2e_token_contract/token_contract_test.js +10 -0
  42. package/dest/fixtures/authwit_proxy.d.ts +15 -0
  43. package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
  44. package/dest/fixtures/authwit_proxy.js +30 -0
  45. package/dest/fixtures/e2e_prover_test.d.ts +4 -4
  46. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  47. package/dest/fixtures/e2e_prover_test.js +27 -34
  48. package/dest/fixtures/fixtures.d.ts +5 -1
  49. package/dest/fixtures/fixtures.d.ts.map +1 -1
  50. package/dest/fixtures/fixtures.js +6 -0
  51. package/dest/fixtures/ha_setup.d.ts +71 -0
  52. package/dest/fixtures/ha_setup.d.ts.map +1 -0
  53. package/dest/fixtures/ha_setup.js +116 -0
  54. package/dest/fixtures/index.d.ts +2 -1
  55. package/dest/fixtures/index.d.ts.map +1 -1
  56. package/dest/fixtures/index.js +1 -0
  57. package/dest/fixtures/setup.d.ts +39 -22
  58. package/dest/fixtures/setup.d.ts.map +1 -1
  59. package/dest/fixtures/setup.js +59 -149
  60. package/dest/fixtures/setup_p2p_test.d.ts +15 -7
  61. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  62. package/dest/fixtures/setup_p2p_test.js +18 -12
  63. package/dest/shared/index.d.ts +2 -1
  64. package/dest/shared/index.d.ts.map +1 -1
  65. package/dest/shared/index.js +1 -0
  66. package/dest/shared/mock_state_view.d.ts +86 -0
  67. package/dest/shared/mock_state_view.d.ts.map +1 -0
  68. package/dest/shared/mock_state_view.js +186 -0
  69. package/dest/shared/submit-transactions.d.ts +2 -2
  70. package/dest/shared/submit-transactions.d.ts.map +1 -1
  71. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  72. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  73. package/dest/shared/uniswap_l1_l2.js +8 -6
  74. package/dest/simulators/token_simulator.d.ts +1 -1
  75. package/dest/simulators/token_simulator.d.ts.map +1 -1
  76. package/dest/simulators/token_simulator.js +2 -23
  77. package/dest/spartan/setup_test_wallets.d.ts +9 -2
  78. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  79. package/dest/spartan/setup_test_wallets.js +31 -1
  80. package/dest/spartan/utils/bot.d.ts +3 -2
  81. package/dest/spartan/utils/bot.d.ts.map +1 -1
  82. package/dest/spartan/utils/bot.js +2 -1
  83. package/dest/spartan/utils/config.d.ts +4 -1
  84. package/dest/spartan/utils/config.d.ts.map +1 -1
  85. package/dest/spartan/utils/config.js +2 -1
  86. package/dest/spartan/utils/index.d.ts +4 -4
  87. package/dest/spartan/utils/index.d.ts.map +1 -1
  88. package/dest/spartan/utils/index.js +2 -2
  89. package/dest/spartan/utils/k8s.d.ts +31 -1
  90. package/dest/spartan/utils/k8s.d.ts.map +1 -1
  91. package/dest/spartan/utils/k8s.js +124 -0
  92. package/dest/spartan/utils/nodes.d.ts +11 -1
  93. package/dest/spartan/utils/nodes.d.ts.map +1 -1
  94. package/dest/spartan/utils/nodes.js +198 -27
  95. package/dest/spartan/utils/scripts.d.ts +18 -4
  96. package/dest/spartan/utils/scripts.d.ts.map +1 -1
  97. package/dest/spartan/utils/scripts.js +19 -4
  98. package/dest/test-wallet/test_wallet.d.ts +83 -0
  99. package/dest/test-wallet/test_wallet.d.ts.map +1 -0
  100. package/dest/test-wallet/test_wallet.js +214 -0
  101. package/dest/test-wallet/utils.d.ts +41 -0
  102. package/dest/test-wallet/utils.d.ts.map +1 -0
  103. package/dest/test-wallet/utils.js +71 -0
  104. package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
  105. package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
  106. package/dest/test-wallet/wallet_worker_script.js +40 -0
  107. package/dest/test-wallet/worker_wallet.d.ts +52 -0
  108. package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
  109. package/dest/test-wallet/worker_wallet.js +103 -0
  110. package/dest/test-wallet/worker_wallet_schema.d.ts +271 -0
  111. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
  112. package/dest/test-wallet/worker_wallet_schema.js +10 -0
  113. package/package.json +43 -39
  114. package/src/bench/client_flows/client_flows_benchmark.ts +8 -12
  115. package/src/bench/client_flows/config.ts +9 -1
  116. package/src/bench/utils.ts +1 -1
  117. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +11 -2
  118. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +7 -8
  119. package/src/e2e_deploy_contract/deploy_test.ts +3 -3
  120. package/src/e2e_epochs/epochs_test.ts +73 -63
  121. package/src/e2e_fees/bridging_race.notest.ts +1 -1
  122. package/src/e2e_fees/fees_test.ts +11 -26
  123. package/src/e2e_l1_publisher/write_json.ts +1 -6
  124. package/src/e2e_nested_contract/nested_contract_test.ts +1 -1
  125. package/src/e2e_p2p/inactivity_slash_test.ts +4 -4
  126. package/src/e2e_p2p/p2p_network.ts +29 -7
  127. package/src/e2e_p2p/reqresp/utils.ts +235 -0
  128. package/src/e2e_p2p/shared.ts +3 -1
  129. package/src/e2e_storage_proof/fixtures/storage_proof.json +915 -0
  130. package/src/e2e_storage_proof/fixtures/storage_proof_fetcher.ts +190 -0
  131. package/src/e2e_storage_proof/fixtures/storage_proof_fixture.ts +173 -0
  132. package/src/e2e_token_contract/token_contract_test.ts +11 -2
  133. package/src/fixtures/authwit_proxy.ts +50 -0
  134. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  135. package/src/fixtures/e2e_prover_test.ts +28 -38
  136. package/src/fixtures/fixtures.ts +10 -0
  137. package/src/fixtures/ha_setup.ts +186 -0
  138. package/src/fixtures/index.ts +1 -0
  139. package/src/fixtures/setup.ts +89 -210
  140. package/src/fixtures/setup_p2p_test.ts +25 -24
  141. package/src/guides/up_quick_start.sh +3 -3
  142. package/src/shared/index.ts +1 -0
  143. package/src/shared/mock_state_view.ts +188 -0
  144. package/src/shared/submit-transactions.ts +2 -1
  145. package/src/shared/uniswap_l1_l2.ts +9 -11
  146. package/src/simulators/token_simulator.ts +1 -29
  147. package/src/spartan/setup_test_wallets.ts +43 -1
  148. package/src/spartan/utils/bot.ts +4 -1
  149. package/src/spartan/utils/config.ts +1 -0
  150. package/src/spartan/utils/index.ts +4 -1
  151. package/src/spartan/utils/k8s.ts +160 -0
  152. package/src/spartan/utils/nodes.ts +239 -24
  153. package/src/spartan/utils/scripts.ts +43 -7
  154. package/src/test-wallet/test_wallet.ts +306 -0
  155. package/src/test-wallet/utils.ts +112 -0
  156. package/src/test-wallet/wallet_worker_script.ts +43 -0
  157. package/src/test-wallet/worker_wallet.ts +165 -0
  158. package/src/test-wallet/worker_wallet_schema.ts +13 -0
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Fetches a ERC20 balance storage proof from the Ethereum mainnet and saves it to a Prover.toml compatible JSON.
3
+ * The JSON can be converted to toml for use with nargo, or used directly as a JSON file when used in
4
+ * Aztec contracts. This script is not using any Aztec library code, so it's easily portable.
5
+ */
6
+ import fs from 'fs';
7
+ import { dirname, join } from 'path';
8
+ import { fileURLToPath } from 'url';
9
+ import { createPublicClient, encodeAbiParameters, fromRlp, hexToBytes, http, keccak256 } from 'viem';
10
+ import { mainnet } from 'viem/chains';
11
+
12
+ const __dirname = dirname(fileURLToPath(import.meta.url));
13
+
14
+ const RPC_URL = process.env.RPC_URL;
15
+ const ERC20_CONTRACT = (process.env.ERC20_CONTRACT || '0xdAC17F958D2ee523a2206206994597C13D831ec7') as `0x${string}`;
16
+ const HOLDER = (process.env.HOLDER || '0x23878914EFE38d27C4D67Ab83ed1b93A74D4086a') as `0x${string}`;
17
+ const SLOT = BigInt(process.env.SLOT || '2');
18
+ const BLOCK_TAG = process.env.BLOCK_NUMBER ? BigInt(process.env.BLOCK_NUMBER) : 'latest';
19
+ const MAX_ACCOUNT_PATH = 15;
20
+ const MAX_STORAGE_PATH = 10;
21
+
22
+ function padTo(arr: number[], len: number) {
23
+ return [...arr, ...Array(len - arr.length).fill(0)].slice(0, len);
24
+ }
25
+
26
+ function toBytes(hex: `0x${string}`) {
27
+ return Array.from(hexToBytes(hex));
28
+ }
29
+
30
+ function bytesToU64s(bytes: number[]) {
31
+ const paddedBytes = padTo(bytes, 32);
32
+ return Array.from({ length: 4 }, (_, i) => {
33
+ let val = 0n;
34
+ for (let j = 0; j < 8; j++) {
35
+ val += BigInt(paddedBytes[i * 8 + j]) << BigInt(j * 8);
36
+ }
37
+ return val.toString();
38
+ });
39
+ }
40
+
41
+ function toBytesAndLen(val: bigint | number) {
42
+ if (val === 0n || val === 0) {
43
+ return { bytes: [0], length: 0 };
44
+ }
45
+ let hex = val.toString(16);
46
+ if (hex.length % 2) {
47
+ hex = '0' + hex;
48
+ }
49
+ const bytes = toBytes(`0x${hex}`);
50
+ return { bytes, length: bytes.length };
51
+ }
52
+
53
+ function parseNode(rlp: `0x${string}`) {
54
+ // Should be safe when working with branches and extensions without embedded children.
55
+ const decoded = fromRlp(rlp) as `0x${string}`[];
56
+ const node = {
57
+ rows: Array(16)
58
+ .fill(0)
59
+ .map(() => Array(32).fill(0)),
60
+ row_exist: Array(16).fill(false),
61
+ node_type: 0,
62
+ };
63
+
64
+ if (decoded.length === 17) {
65
+ for (let i = 0; i < 16; i++) {
66
+ if (decoded[i] !== '0x') {
67
+ node.row_exist[i] = true;
68
+ node.rows[i] = padTo(toBytes(decoded[i]), 32);
69
+ }
70
+ }
71
+ } else if (decoded.length === 2) {
72
+ const keyBytes = toBytes(decoded[0]);
73
+ const prefix = keyBytes[0];
74
+ if (prefix >> 4 >= 2) {
75
+ throw new Error('Unsupported: leaf node in proof path');
76
+ }
77
+ node.node_type = 1;
78
+ // Extension header format expected by the noir code: check out storage_proof types.nr.
79
+ node.rows[0][0] = prefix >> 4;
80
+ node.rows[0][8] = prefix & 0x0f;
81
+ node.rows[0][16] = keyBytes.length - 1;
82
+
83
+ for (let i = 1; i < keyBytes.length && i < 32; i++) {
84
+ node.rows[1][i - 1] = keyBytes[i];
85
+ }
86
+ node.rows[2] = padTo(toBytes(decoded[1]), 32);
87
+ node.row_exist[0] = node.row_exist[1] = node.row_exist[2] = true;
88
+ }
89
+ return node;
90
+ }
91
+
92
+ function parseProof(proof: `0x${string}`[], maxLen: number) {
93
+ const nodes = proof.slice(0, -1).slice(0, maxLen).map(parseNode);
94
+ while (nodes.length < maxLen) {
95
+ nodes.push({
96
+ rows: Array(16)
97
+ .fill(0)
98
+ .map(() => Array(32).fill(0)),
99
+ row_exist: Array(16).fill(false),
100
+ node_type: 0,
101
+ });
102
+ }
103
+ return nodes;
104
+ }
105
+
106
+ function nodeToLibFormat(node: { rows: number[][]; row_exist: boolean[]; node_type: number }) {
107
+ return {
108
+ rows: node.rows.map(bytesToU64s),
109
+ row_exist: node.row_exist,
110
+ node_type: String(node.node_type),
111
+ };
112
+ }
113
+
114
+ async function main() {
115
+ if (!RPC_URL) {
116
+ throw new Error('RPC_URL is not set');
117
+ }
118
+ const storageKey = keccak256(encodeAbiParameters([{ type: 'address' }, { type: 'uint256' }], [HOLDER, SLOT]));
119
+ console.log(`Fetching storage proof for ${ERC20_CONTRACT}, holder ${HOLDER}, slot ${SLOT}`);
120
+ console.log(`Storage key: ${storageKey}`);
121
+
122
+ const client = createPublicClient({
123
+ chain: mainnet,
124
+ transport: http(RPC_URL),
125
+ });
126
+
127
+ const [blockNumber, proof, block] = await Promise.all([
128
+ client.getBlockNumber(),
129
+ client.getProof({
130
+ address: ERC20_CONTRACT,
131
+ storageKeys: [storageKey],
132
+ blockNumber: BLOCK_TAG === 'latest' ? undefined : BLOCK_TAG,
133
+ }),
134
+ client.getBlock({
135
+ blockNumber: BLOCK_TAG === 'latest' ? undefined : BLOCK_TAG,
136
+ }),
137
+ ]);
138
+
139
+ const storageProof = proof.storageProof[0];
140
+ console.log(
141
+ `Block: ${blockNumber}, Account nodes: ${proof.accountProof.length}, Storage nodes: ${storageProof.proof.length}`,
142
+ );
143
+ console.log(`Value: ${storageProof.value}`);
144
+
145
+ // The -1 is because the last node in the proof is the leaf, which is excluded from path verification.
146
+ const accountPathLen = proof.accountProof.length - 1;
147
+ const storagePathLen = storageProof.proof.length - 1;
148
+ if (accountPathLen > MAX_ACCOUNT_PATH) {
149
+ throw new Error(
150
+ `Account proof path length ${accountPathLen} exceeds MAX_ACCOUNT_PATH ${MAX_ACCOUNT_PATH}. Increase the limit.`,
151
+ );
152
+ }
153
+ if (storagePathLen > MAX_STORAGE_PATH) {
154
+ throw new Error(
155
+ `Storage proof path length ${storagePathLen} exceeds MAX_STORAGE_PATH ${MAX_STORAGE_PATH}. Increase the limit.`,
156
+ );
157
+ }
158
+
159
+ const nonce = toBytesAndLen(proof.nonce);
160
+ const balance = toBytesAndLen(proof.balance);
161
+ const slotValue = toBytesAndLen(storageProof.value);
162
+
163
+ const data = {
164
+ account_nodes: parseProof(proof.accountProof, MAX_ACCOUNT_PATH).map(nodeToLibFormat),
165
+ account_node_length: String(accountPathLen),
166
+ storage_nodes: parseProof(storageProof.proof, MAX_STORAGE_PATH).map(nodeToLibFormat),
167
+ storage_node_length: String(storagePathLen),
168
+ account: {
169
+ nonce: padTo(nonce.bytes, 8).map(String),
170
+ nonce_length: String(nonce.length),
171
+ balance: padTo(balance.bytes, 32).map(String),
172
+ balance_length: String(balance.length),
173
+ address: toBytes(ERC20_CONTRACT).map(String),
174
+ storage_hash: bytesToU64s(toBytes(proof.storageHash)),
175
+ code_hash: bytesToU64s(toBytes(proof.codeHash)),
176
+ },
177
+ slot: {
178
+ value: padTo(slotValue.bytes, 32).map(String),
179
+ value_length: String(slotValue.length),
180
+ },
181
+ slot_key: toBytes(storageKey).map(String),
182
+ root: bytesToU64s(toBytes(block.stateRoot)),
183
+ block_number: String(blockNumber),
184
+ };
185
+
186
+ fs.writeFileSync(join(__dirname, 'storage_proof.json'), JSON.stringify(data, null, 2));
187
+ console.log('storage_proof.json generated');
188
+ }
189
+
190
+ main().catch(console.error);
@@ -0,0 +1,173 @@
1
+ import type { AztecAddress } from '@aztec/aztec.js/addresses';
2
+ import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
+ import { EthAddress } from '@aztec/foundation/eth-address';
5
+ import { Capsule } from '@aztec/stdlib/tx';
6
+
7
+ import { readFileSync } from 'fs';
8
+ import { dirname, join } from 'path';
9
+ import { fileURLToPath } from 'url';
10
+
11
+ const __dirname = dirname(fileURLToPath(import.meta.url));
12
+ const FIXTURE_PATH = join(__dirname, './storage_proof.json');
13
+
14
+ // Constants matching the Noir contract
15
+ const ACCOUNT_CAPSULE_KEY_SEPARATOR = 100;
16
+ const ACCOUNT_PROOF_CAPSULE_KEY_SEPARATOR = 101;
17
+ const STORAGE_PROOF_CAPSULE_KEY_SEPARATOR = 102;
18
+ const STORAGE_PROOF_NODE_CAPSULE_KEY_SEPARATOR = 103;
19
+ const MAX_ACCOUNT_PROOF_LENGTH = 15;
20
+ /** Node: rows [[u64;4];16] (64) + row_exist [bool;16] (16) + node_type u8 (1) = 81 fields */
21
+ const NODE_FIELD_COUNT = 81;
22
+
23
+ // --- JSON fixture types ---
24
+
25
+ type JsonNode = { rows: string[][]; row_exist: boolean[]; node_type: string };
26
+
27
+ type JsonAccount = {
28
+ nonce: string[];
29
+ balance: string[];
30
+ address: string[];
31
+ nonce_length: string;
32
+ balance_length: string;
33
+ storage_hash: string[];
34
+ code_hash: string[];
35
+ };
36
+
37
+ type StorageProofJSON = {
38
+ root: string[];
39
+ slot_key: string[];
40
+ account_node_length: string;
41
+ storage_node_length: string;
42
+ account_nodes: JsonNode[];
43
+ storage_nodes: JsonNode[];
44
+ account: JsonAccount;
45
+ slot: { value: string[]; value_length: string };
46
+ };
47
+
48
+ // --- Serialization helpers (Noir struct Serialize layout) ---
49
+
50
+ function serializeNode(node: JsonNode): Fr[] {
51
+ const fields: Fr[] = [];
52
+ for (const row of node.rows) {
53
+ for (const val of row) {
54
+ fields.push(new Fr(BigInt(val)));
55
+ }
56
+ }
57
+ for (const exists of node.row_exist) {
58
+ fields.push(new Fr(exists ? 1n : 0n));
59
+ }
60
+ fields.push(new Fr(BigInt(node.node_type)));
61
+ return fields;
62
+ }
63
+
64
+ /** Account: nonce [u8;8] + balance [u8;32] + address [u8;20] + nonce_length u8 + balance_length u8 + storage_hash [u64;4] + code_hash [u64;4] = 70 fields */
65
+ function serializeAccount(account: JsonAccount): Fr[] {
66
+ const fields: Fr[] = [];
67
+ for (const v of account.nonce) {
68
+ fields.push(new Fr(BigInt(v)));
69
+ }
70
+ for (const v of account.balance) {
71
+ fields.push(new Fr(BigInt(v)));
72
+ }
73
+ for (const v of account.address) {
74
+ fields.push(new Fr(BigInt(v)));
75
+ }
76
+ fields.push(new Fr(BigInt(account.nonce_length)));
77
+ fields.push(new Fr(BigInt(account.balance_length)));
78
+ for (const v of account.storage_hash) {
79
+ fields.push(new Fr(BigInt(v)));
80
+ }
81
+ for (const v of account.code_hash) {
82
+ fields.push(new Fr(BigInt(v)));
83
+ }
84
+ return fields;
85
+ }
86
+
87
+ function zeroNode(): Fr[] {
88
+ return Array(NODE_FIELD_COUNT).fill(Fr.ZERO);
89
+ }
90
+
91
+ // --- Public API ---
92
+
93
+ /** Parsed + typed fixture data ready for use as contract function arguments. */
94
+ export type StorageProofArgs = {
95
+ ethAddress: EthAddress;
96
+ slotKey: number[];
97
+ slotContents: { value: number[]; value_length: number };
98
+ root: bigint[];
99
+ };
100
+
101
+ /** Loads the storage proof fixture from disk and returns the contract args. */
102
+ export function loadStorageProofArgs(): StorageProofArgs {
103
+ const fixture: StorageProofJSON = JSON.parse(readFileSync(FIXTURE_PATH, 'utf8'));
104
+ const addressBytes = Buffer.from(fixture.account.address.map(v => Number(v)));
105
+ return {
106
+ ethAddress: EthAddress.fromString('0x' + addressBytes.toString('hex')),
107
+ slotKey: fixture.slot_key.map(v => Number(v)),
108
+ slotContents: {
109
+ value: fixture.slot.value.map(v => Number(v)),
110
+ // eslint-disable-next-line camelcase
111
+ value_length: Number(fixture.slot.value_length),
112
+ },
113
+ root: fixture.root.map(v => BigInt(v)),
114
+ };
115
+ }
116
+
117
+ /** Builds all the capsules the StorageProofTest contract expects during private execution. */
118
+ export async function buildStorageProofCapsules(contractAddress: AztecAddress): Promise<Capsule[]> {
119
+ const fixture: StorageProofJSON = JSON.parse(readFileSync(FIXTURE_PATH, 'utf8'));
120
+
121
+ const root = fixture.root.map(v => BigInt(v));
122
+ const slotKey = fixture.slot_key.map(v => Number(v));
123
+ const accountNodeLength = Number(fixture.account_node_length);
124
+ const storageNodeLength = Number(fixture.storage_node_length);
125
+ const ethAddress = EthAddress.fromBuffer(Buffer.from(fixture.account.address.map(v => Number(v))));
126
+
127
+ // Compute capsule keys (must match the Noir contract's poseidon2_hash computations)
128
+ const addressCapsuleKey = await poseidon2Hash([
129
+ new Fr(ACCOUNT_CAPSULE_KEY_SEPARATOR),
130
+ ...root.map(v => new Fr(v)),
131
+ ethAddress.toField(),
132
+ ]);
133
+
134
+ const accountProofCapsuleKey = await poseidon2Hash([new Fr(ACCOUNT_PROOF_CAPSULE_KEY_SEPARATOR), addressCapsuleKey]);
135
+
136
+ const storageProofCapsuleKey = await poseidon2Hash([
137
+ new Fr(STORAGE_PROOF_CAPSULE_KEY_SEPARATOR),
138
+ addressCapsuleKey,
139
+ ...slotKey.map(v => new Fr(v)),
140
+ ]);
141
+
142
+ // Build capsule data
143
+
144
+ // 1. Account data
145
+ const accountData = serializeAccount(fixture.account);
146
+
147
+ // 2. Account proof nodes padded to MAX_ACCOUNT_PROOF_LENGTH
148
+ const accountProofData: Fr[] = [new Fr(accountNodeLength)];
149
+ for (let i = 0; i < MAX_ACCOUNT_PROOF_LENGTH; i++) {
150
+ accountProofData.push(...(i < fixture.account_nodes.length ? serializeNode(fixture.account_nodes[i]) : zeroNode()));
151
+ }
152
+
153
+ // 3. Storage proof length (u32)
154
+ const storageProofLengthData = [new Fr(storageNodeLength)];
155
+
156
+ const capsules: Capsule[] = [
157
+ new Capsule(contractAddress, addressCapsuleKey, accountData),
158
+ new Capsule(contractAddress, accountProofCapsuleKey, accountProofData),
159
+ new Capsule(contractAddress, storageProofCapsuleKey, storageProofLengthData),
160
+ ];
161
+
162
+ // 4. Individual storage node capsules for private recursion.
163
+ for (let i = 0; i < storageNodeLength; i++) {
164
+ const nodeCapsuleKey = await poseidon2Hash([
165
+ new Fr(STORAGE_PROOF_NODE_CAPSULE_KEY_SEPARATOR),
166
+ storageProofCapsuleKey,
167
+ new Fr(i),
168
+ ]);
169
+ capsules.push(new Capsule(contractAddress, nodeCapsuleKey, serializeNode(fixture.storage_nodes[i])));
170
+ }
171
+
172
+ return capsules;
173
+ }
@@ -2,14 +2,15 @@ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
2
  import { type Logger, createLogger } from '@aztec/aztec.js/log';
3
3
  import type { AztecNode } from '@aztec/aztec.js/node';
4
4
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
5
+ import { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
5
6
  import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAccount';
6
- import type { TestWallet } from '@aztec/test-wallet/server';
7
7
 
8
8
  import { jest } from '@jest/globals';
9
9
 
10
10
  import { type EndToEndContext, deployAccounts, publicDeployAccounts, setup, teardown } from '../fixtures/setup.js';
11
11
  import { mintTokensToPrivate } from '../fixtures/token_utils.js';
12
12
  import { TokenSimulator } from '../simulators/token_simulator.js';
13
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
13
14
 
14
15
  const { METRICS_PORT: metricsPort } = process.env;
15
16
 
@@ -25,6 +26,7 @@ export class TokenContractTest {
25
26
  node!: AztecNode;
26
27
 
27
28
  badAccount!: InvalidAccountContract;
29
+ authwitProxy!: GenericProxyContract;
28
30
  wallet!: TestWallet;
29
31
  adminAddress!: AztecAddress;
30
32
  account1Address!: AztecAddress;
@@ -70,7 +72,7 @@ export class TokenContractTest {
70
72
  initialFundedAccounts: this.context.initialFundedAccounts,
71
73
  });
72
74
 
73
- this.node = this.context.aztecNodeService!;
75
+ this.node = this.context.aztecNodeService;
74
76
  this.wallet = this.context.wallet;
75
77
  [this.adminAddress, this.account1Address, this.account2Address] = deployedAccounts.map(acc => acc.address);
76
78
 
@@ -92,6 +94,13 @@ export class TokenContractTest {
92
94
  this.badAccount = await InvalidAccountContract.deploy(this.wallet).send({ from: this.adminAddress });
93
95
  this.logger.verbose(`Deployed to ${this.badAccount.address}.`);
94
96
 
97
+ // Deploy a proxy contract for "on behalf of other" tests. The note owner must be the tx sender
98
+ // (so their notes are in scope), but msg_sender in the target must differ from the note owner
99
+ // to trigger authwit validation. The proxy forwards calls so that msg_sender != tx sender.
100
+ this.logger.verbose(`Deploying generic proxy...`);
101
+ this.authwitProxy = await GenericProxyContract.deploy(this.wallet).send({ from: this.adminAddress });
102
+ this.logger.verbose(`Deployed to ${this.authwitProxy.address}.`);
103
+
95
104
  this.tokenSim = new TokenSimulator(this.asset, this.wallet, this.adminAddress, this.logger, [
96
105
  this.adminAddress,
97
106
  this.account1Address,
@@ -0,0 +1,50 @@
1
+ import type {
2
+ ContractFunctionInteraction,
3
+ SendInteractionOptions,
4
+ SimulateInteractionOptions,
5
+ } from '@aztec/aztec.js/contracts';
6
+ import type { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
7
+
8
+ /**
9
+ * Builds a proxy forwarding call from an action, selecting the right forward_private_N method.
10
+ */
11
+ async function buildProxyCall(proxy: GenericProxyContract, action: ContractFunctionInteraction) {
12
+ const call = await action.getFunctionCall();
13
+ const argCount = call.args.length;
14
+ if (argCount === 2) {
15
+ return proxy.methods.forward_private_2(call.to, call.selector, call.args);
16
+ } else if (argCount === 3) {
17
+ return proxy.methods.forward_private_3(call.to, call.selector, call.args);
18
+ } else if (argCount === 4) {
19
+ return proxy.methods.forward_private_4(call.to, call.selector, call.args);
20
+ }
21
+ throw new Error(`No forward_private_${argCount} method on proxy`);
22
+ }
23
+
24
+ /**
25
+ * Sends a contract call through the authwit proxy.
26
+ * The proxy becomes msg_sender in the target (triggering authwit validation),
27
+ * while the actual tx sender retains their keys in scope.
28
+ */
29
+ export async function sendThroughAuthwitProxy(
30
+ proxy: GenericProxyContract,
31
+ action: ContractFunctionInteraction,
32
+ options: SendInteractionOptions,
33
+ ) {
34
+ const proxyCall = await buildProxyCall(proxy, action);
35
+ return proxyCall.send(options);
36
+ }
37
+
38
+ /**
39
+ * Simulates a contract call through the authwit proxy.
40
+ * The proxy becomes msg_sender in the target (triggering authwit validation),
41
+ * while the actual tx sender retains their keys in scope.
42
+ */
43
+ export async function simulateThroughAuthwitProxy(
44
+ proxy: GenericProxyContract,
45
+ action: ContractFunctionInteraction,
46
+ options: SimulateInteractionOptions,
47
+ ) {
48
+ const proxyCall = await buildProxyCall(proxy, action);
49
+ return proxyCall.simulate(options);
50
+ }
@@ -1 +1 @@
1
- {"proof":"0x00004d6006f32a63ab1a10c44b40a14c94fd4e693830a91920a63778c91df75b67c3a2590000000000000000000000000000000000000000000000000000000000000001221894f21cae5e98d0c7a1a2658eaf169b0688cf8348dc7be4d5a944d568bd4600000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb00087e2b1632207a64d2be3430a622118411f15477dcf399a057660b8e566041001c2aa1e8a9c646939d1d0d3a1b789e2eb024aa538a4c7864db736646faf6cc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e586311f1581539435ce58c90ec4a9d291746a8b33999d1654faffb07f382db2efd3fd6b542f09e9f76c84337f46370f67729ce54c815d35866b4cb2a2672030000000000000000000000000000000000000000000000000000000000000000003f1c36600e57c2c3556b97fe6d9919a7c418380b539dcf74182dacf5baea2e16743433c1b3d551429cfbc09ab7899d4e14d2b5786a3243e29bc9c6c0d76bf100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf1e314549c5109330000000000000000000000000000000000000000000000078ab65cae0766dac4000000000000000000000000000000000000000000000006d9729dd2114d251600000000000000000000000000000000000000000000000000025bb48088e2d6000000000000000000000000000000000000000000000004112c333273480d9d00000000000000000000000000000000000000000000000e79ddc992614451e3000000000000000000000000000000000000000000000005d880c4e49e3909410000000000000000000000000000000000000000000000000001adc707a50e7500000000000000000000000000000000000000000000000591960a3c52d5a331000000000000000000000000000000000000000000000005d69c43aaa65acc860000000000000000000000000000000000000000000000011ce4d0df71d9b0da00000000000000000000000000000000000000000000000000007c4b84e96f1200000000000000000000000000000000000000000000000e796d0a9ec64b048d00000000000000000000000000000000000000000000000a9f1811bacc20b1ef0000000000000000000000000000000000000000000000081959aa974bf5661900000000000000000000000000000000000000000000000000014ac071abce30000000000000000000000000000000ca9d55b6e986c398073827360972cbdd6900000000000000000000000000000000001099819f900ee75e8a6ab54c59fa4000000000000000000000000000000081180a8b96072c3f4246e9a036d07f3507000000000000000000000000000000000027d2cbe77a3e0edefc570e90c90b9f000000000000000000000000000000d6ee6d7b1ba024766d6f835521249b7ae4000000000000000000000000000000000016a0da7d14c7230116a9948f6550ca00000000000000000000000000000019227c5f9b9bc32f21583696973ff92ffe00000000000000000000000000000000002e72b67d18384e0ea627c38592ab76000000000000000000000000000000f4ec1a574da16cc52af9cfe52a0a88ac0800000000000000000000000000000000002dd342a68d2d19b030ec0b82734484000000000000000000000000000000f24ff72c85a62ed5b9cdb3ab52878e5d6600000000000000000000000000000000000f7afb370a128f12d63e3649ae47790000000000000000000000000000004b35876712ed72f6999ccf4346aea9dc8800000000000000000000000000000000000b9c4ede9e05409f4df0b886e12a1e000000000000000000000000000000f4338b85257350c3bbafb99d2c1464cb8100000000000000000000000000000000002efbe244cd2cfd9aa0c8f71e50c96200000000000000000000000000000054f2bc452d87e94668fa54fdb54790c9b0000000000000000000000000000000000025980f026372c596860eda2a791d9b00000000000000000000000000000047dd57b3275e8f09905f26b7bc44e48bba0000000000000000000000000000000000010988e60c8f065cf95a1c9a292364000000000000000000000000000000c9119a149e8374416e40f7586311a3861f00000000000000000000000000000000002ad3d93fb74b1be165a915ad72a3380000000000000000000000000000000148b87898085b1b8b915c1878b2a188d000000000000000000000000000000000002a91ee00ef56a5964ff759ca2990ec00000000000000000000000000000091163f22963ea9894fdc40b2516296029f00000000000000000000000000000000001db9fdde7620ad93d46e0fad2cdd1f0000000000000000000000000000005ce65ed82881f4f78356cbe6d94699849c000000000000000000000000000000000014250c7cd0c960952568293d732d20000000000000000000000000000000cde964c7dbc45d7bea0e22c409d3f4bf960000000000000000000000000000000000016cfaf8940e476cdc1852d5a9172d000000000000000000000000000000ca8d4a2f2ec921c4b8f591c2c27dbdd8ae000000000000000000000000000000000027d9c460264941701fcd49bca2b2f61db5f435f1c9b1b0f491d38cf071b8cc67cb453563b2b60c99daaf55a85360d412ae5a3cef67ee78c3be7229910f9f90c068a3131606ba84aa07463e47ac9f2d2fa7f383cb9bda2055d025ba59925a45d09bbc3abf2a607ca649a641fbf19225033120e4db3ca51d56e3ac61527718a0a5f9d106973575780d8803c89bd9e7be0fa40d87661532cbf29108288ae6a1ceae9eb3fea4d2c7a767f4196a8d4117c52bd771c13a22a6986d53dc0734cc775e2b47c6538d0dd5f82ca62ea90010607802774fe2ae0ded6cc0fb00f591b98a8a17e9a1b0592973bcef46339b184bf1660220da8db31103b2f88257f3a6a49c41ed8895a8c759621d5994e7b71b3959c72c4290a83a957c5d7ec3305efc4137c921bc019382bb97aa434a5b206e60258a2c6283d5e2fa72db956e03a261af9807fb352d8394e8a3f8f497604c586cc43808ba9508f19dcd2c88ebdf68f7faf36d5a4ec4b5355c318734e8273a864d923c0d122ead90fb432d9beda2e8ba40fd5132ba52aa3def71f2893378e49b0c65eb0b88e36f6e25b4d27c975fa867555b51cbfd9412744819e753db95c7fa1087dd0965cf48bc50a9e96cbc1b1ce8b2ca27132029dc01101c7e1a13cac34ce8fe0128c1d28e4d69f5057c8eb4de3cd1406dbdb46f45881b41481faf3942ad75aa5612ce5af105c235ef077fae32c577a820333addc7d22ee9917dfe1823b8ff645023a789b1287e074fc0d44e1ddf5c64dd272a6ab61cdab64b9c22e95a0beeaee52b960f0eb444467e546c409a7def039a1ffe2323c7609b807d184b0207cecef406f5e7a413f18d01a6c9cd20fddcee991b2e66c646d2133bb4f296ba1465fb042e3308b159399371602a4600934b56b48c93e145ef89b8ce32e0c4319420852a260fc934bb5b2ddc0e0487fe59a88b074f579df8bc93218b7a750e7656885a450e7e8e3acc01c991025dfa5c3a0c733c02b51b4596ed1b6cca3da27a5aab6f81059fca6c74e504744b8e4f4fcf34be13c1c641e0fa69cec87fe2e61d3828f5ca2c3dd4e23ab8365dff18bf503ff9298b0f7cc5f79640672faa67f6c15a82dd6019b949fb94e03235adfec37cddf6e0c2db7803662f70f700a4134f05db1b7f331aabb24920355a935d257979d043b6f419fb652bb0ac3354a5cad5c22ce0b029083005d775aec13fe5215f2998092ce9d9c6b59e876900ba4a218b02112eabdc30339b7d9b74c357275ee52c2e92e9f840fee659f063205ee913b8771108cd7205061a27fa68b0a5d11ee01390ecf9db47180fd044e5b8e68f20876cb59d884a0634bce681ce910d3839decccbb99548e4b2c48ab58008138387a88edbd3bf541217acce5c99b311743f0a885ab4fc5be60dbd12e3691c9fcded433f2f23cfb02b5baaade2dc7bea9687c53ae5cf93f89ddac6bd8a898b1933a87ad4bb9a16ce069c746023a2d0aa491466b442061961118dcd93432104a203dd855a6a75268d06ef585e2f552d811ca934b2a17e7ce192d56bccdd8262e621a8cc0be364cbd4119113909bcef03f3d310d79c12987f7e2b9a5dd5e76438542e66c6ffb48a32f0baca42f56b4d0387f8ae9548347a56c0b7fed358db3e8a6b2267f0f4186b6a305bab73106ea0559c0c38c8b8f91b56ff8826107e411a14512aa75d9dfea89e51233560d096fb5ede83cb4925de73194869a980b0e3e4f362125d5ff962c13e60b7b5445901eb8aad7c273af9ad2154914b6d87791dee5348803b5f07b63cacc0fe976fd85339a6192505b8b1bf27e0a3947b87e57b803e091afe80a04b88f370722c07c87b4163022c8a45916f0232d73770f3186094533fa2cef9cd818384c0ddd0c4b7802230ae60738f44ac6dfaa3389a3fbbb103c5948ee0262c45f1c4619b30f1fe28037be4f630cc577705107bf585c8183c4b74fe16b9ab6f8c6dba016585ba8ce2bf3e24c49f75fedfc588b10b3d46d4b400c49335b6cee47ca48ed1aeb8bdfd317556091d058b2d82713ddfc91adae10e46be3d90c02bd11c8761e10118eace939f78fb4b27a698ec4e0660bcc540a7c6f921152185a748d5932ea10622bbbc32f885edec3a69cee3773be88a2d58199243b961efb6d4f85468f5d1d3b7315511da9a1138808b18e684baffb1ca91f77901e9928b5e31492e037600e15f1818fcf0970b973bbf36363a463c156abb1d417f1b9e674720beb55647c1bc7e1ef4a8fed5d330baef509cace450e5a5284728d158b39729aa5c09017f21ae28c00e7d7c53ff73e934226723e2f54ff4d20335249473988d3c769e0866720b787e351441001b269c93c71a16a4308f079e8506fbffb3e8fcdbd279dc03003b0e7b77b29093846aeb08ac57b63e9e6ca5da9ff9a92da45ad62a2851dce1617d2a88bb172e575a8fa2ea2b2a73947d8e0bd1e5258fe80b1f23427df5bfd1d0c22f8ca454458f49c05d75a7e015a7adaac6b6a680f2a1f847b8f163a64714b156ee53bd2b5bc153cbac4b9b180b5eda314f86176b9c3f848aff8967e1be2460e45a56ef2c2e5d2a6a432d6b68f99ee6d5bb23934cee0752286dc5e3bebf0b51fd1057ecbe5cdb0777521739a2327d621a2dbb14cf95d64fe5781595e63dead24cf5131c82145bd4d92ed504e9a60893596cdf437fa87481fbe335d33320fe42a330d852b76c0aa33dcb22045d4124e63869a825b672655be11f1539e7fd7ec1d925673b23327ac733382033d7526b09e7816787b77f4025dd8ff9560cd39b607474d881e61d07160c81c07df3d19c9ef9279ed9b9a87fd1b302f2785e6d030135a68128b627337aae616fb0c44ac0904a728e56f32b48a05c43fbca7193b3c0cbaee34a10be73cb5efb067e0a6f639fea08c4cfd9054de1dbcf775f97690502d6c3802b5407c5bb25ef4c51c82dd15622eff5c0dc883975d210126340293c608be656b21422672140c9e218cd85d7a06d0a212266afda817112a23263c790319fdfc82e8ddc9bba8ac8fc18ebb4b74655ce6a87e4fba40888f391e4483a22f17cb0e241ad558f67f921a28be36647e025291b8c3563c0d4195eec985b4b7f31cebd69fd1277c3b71f6a95c2a95745799bac4bfc84d2d8180a3352d6e7c5ec11e9470e104ed350bf8adabf8a5fb98e720f31d8d43b89260c2edb61fd9200a002b069ac3f27375d0a7a99c30137298490a133441e1659a869a6a1738969f55650ae5e20015818c4abd45165534290130c85af0656687023c6771d9b8e96507c02b0afa988c0a3329876aa1cfadbb760660dea99f70828bfe29c5272b7b128f220708fedb4747e814da49a8223d67d398335cd60746db92f3bc2fb4dee71aeb362bc028e3a57b7c3b084aa1a3d7d091fc348d7e6c66ad39307b7bb150b023d76a017cbd7259a19175f3d12a4049dbb68cd9bcc1d90e247fe3e7575b9be5548ecb1303e4899b05ed3fe96c6daa0159a41e5caf66600d0fe9776113d4ec10e32a4a1f17c4577e3e940b49c068b65f30d171a3ed813ec34c3c6a891f76c3aada0b851003e6d72ee3374d19ddd79b82631d45934204c3707e2c53f6249252b1efb95e1b944e13ea3442a2b425c64caa62e80d5a8770526dff7473d4f980773b3087040fb1e72eca5d56620add7fb2772dc91481d845d7e69c2cac5d11bfe8476cddaa119a19be2f7d19a0d6cf00dde3cc7727b829497629abc11ca4c2e173169b12bc284478c0b48994489cb12d0313b8bb5fbc3f397e6433fd13e6f20a9945a128441a52d9e2b37bdb97aefff765a8757deec39f6da1e2c5221d6e3eebfafd98f1471356c5e502404156f8ffca15d9020bc4c34a9f37b35a8759ee0dd42cc5f01eeb00fd87fc66bfc33b91e0f1462a6df820f8d06e5286d8f2b6a8f2f28cdf3b869e2347e75edb5dade6a2341fd6119ce9b236e2f8b103c95112de486515b7ef021625dd028a3009bcb2001879d0656d3f538b2181096e10afaa8741f69ae7149a9620e4005c11c98c438e7d9a9d13eda86a81031e59d5297df58ab48c33a22fc0e00e44373fb8eb35fb90540370844e2368e67f5f51f296af41afb124c5790c307f19a15d5e07a6d8615b623e0e0938b71797048cd0124124983b6ee83f476917c80aa5d7e6ff05d2e6a0871beaddb9e6cedcf9c291fe353896accd666121822ea2184f582f6ac8ec7dd9219b915ec779ee54f5d3cd398680fc81412943f8a9285f09eed8558d9a143946f77d90e49643e4088cd905eafbc32c117491ac81bd7d8703789147fc529acf0d61b7a43545a58a776d881fd9b88b39424b5ffb2c29bd6003bef49bdf90fd9119c2d3b1dbfa1f21464f9429a7977716873c9f4ce112777b1a9dc0f03761819893c52014c0e734b1bb58eb4e8c4817b727fa3766e6b5da8f0e45d6ef3bbed7662348782f6a74fe492711a610751aac932e014c32a3da7c312c73dbe8d0e04868315b24722c96b397eb20f4f071c40c58db960ff6acad6a552673df936d8d40e23a027a917fa2779fc7edb284a155773c725cd73955ea7abc2cc4889333eaa6809996e123959a3a3f8d83c96759ce9e3f7c6c09730bbdd98c1aa07c0680a3d9e6dd843d24e7fe49ec9d21a62d54bff6f64a9ee5e08fb11c3a2f8ad777f36bf832803321bc86f1f4a4f72a2eb1fb41913a6cc6dccdbdc340760ffdaff52d1f1245c0d8334d72f5cf99bdac2be88f755d6c37a8214f12bf49e7153b7e75165d3d6920173724eb228e37c3d3e869772d7e982b350e29c07bfa6311e701c78009064faa24e89582b68e68440c660c810f11d316d670f4aa66e05314c04145895b8d875b1b4dccbe89457ebd946fe0523dbe7ddf5fae64aaea32bb0a84ad33f4b8005c00eb2535d0a9ccb8af87ca7f42a78503ab8a07acd630363f2e1a87cb164e41fcf1be838f39a66288ea938fe72275a6db9cfd23b5a51ffd0a1d8ab5b1ceade4fed78376d97a2ae58b1c68c4a53350511df91ff5710ee2fa4e1649055bb19084952ada33df6ea0c8e0f1e549a2f1e6fbf1988fdf00184c98be1431b48ee04df9088e873dd33ef27eb0256512d25f8c0435cf698d52271f82872ec03f71561862b3435535f6e71f1b075d9d544d45ecc11695b695deb45d750026c294d56366e281ab66f2dd3994a5ac3a14ce157aa5d566db035b00aebc0f801e232803cca81f368079508e3a55a9e8c0914d719f7dcab5c4540d050097c61f2e0137a33b9d4e9c67c0b93a22a3b77bed25dac563925b1077627300712f42751b034ec5b3d57085922c3e7e7359bf4694070e43519adb125ea0fa5b964b20a512d95dd6694bd85101318c90fe2e1267efa53c6496c9e076368292c53c4ee56b19c683ea9f5b1fc87532eccdb8fad939f3687f42694b6af100fa1cbc6c27c8102ae94ca0d7c16c9e8ac6ccb18453be033acbf503e4811e59513b058c4ee7defe1b405e22adf7095fc5c8d4eefbb0f50989d6888e6fc9feeea9cf4e198f320a0b0812e27e24b7d3da6e853fdab5c92f85cfd8dd411c6d6c89fb3edb60e4fc3c670c8fc09cedbf16e9c156ef9bdf4f3af22f9901aa20dda1848c8aac42e59984b4031093542cecf7d2c3a039af76683801b33641e348ed611ac1013d83185c118926cd7af617c3ff1f9fdd3837eed0139bfe0d0432bea5f34a65a36a0a873846b028aa1680748beeffe1a802c1659cc25c9acf2f91fe6bb8dadd4436a80b9370e914d13105c4dbeb1bd584ce3987ae2ff62b245d26b2529874d1f49fd9449e6ad61a8993ef077f2bd170851e3eb51ba4639d81ff2fd9196e8d062227d1c1c344e412d030082a057b6dfd0d5036fd87155a2d759bfdc47245d2e55c553ee876dbc509aeaef065e60c37b09b8989af2f54c604047063bc040e07fad0677c2517f56b1b703eec763782336c9a5863ca6e1f2f52346b4586d2447d552f4f8a68cee8d4257b0fe89f35d6b5cf9d1aecfd13e5295f726f06b75a2ed43a0db405b3f1529f2beb899ac04e4b50cf45a7b68765ef92ab03785519983349f9d884ff92583e0120d9a298acd1dd9ee8234b9c35d6978ff9a282f826c41be47e647e48235ba2ee300fa16102f76dde521ddc19d186b73c27ff9b3b341d1d8ccb71664c02b74a4421d22b2ae4d624350dc2cfadb8202659a381c7d458ed1926d8cde3f3bafdc4022dcba972fbff1cbd43002e205287081e346aa39eb981df15dd01008bffe8375a0f7f302db96bbc960c5f1b44186a28c22f3efd2464fb058313bcd623d68cf3ee1424dbf0dd7f14784dc6874ce573e88dec8bf168a30d724f389436c4a1bbf2141a6307ee84eb712e53b73a93361b7ed19949e68884fb50f7782a172716c134e2030140bf394b092573ecfcc9771fe2320b4b4f1e7462af1a510ec78d9317fd51281ab64c26c0b69ff6dda6ec0528186ad0faea1e1f835a8a03d55265c99647d21dc60b01daa3c3a826a71e7a81d424ed4ef70548004185d1c394a6a4c91c75e520a1665d716cc07e8db3490df6f48695e59fd24df7936adf11fd6c76f3b93fc61af47d4f13c560bcd9f66e0be39f31fe9e01f103bda296ca7a24a1369197a2ad04e2eac8c21f92e029ac27cb43e84940b5c07e9612329c5fd30fbb79dbddd0a226da1b0cddcb5ebe352dfef7e8214a5340477d4b63f597bb991de61ace715c7503c9c99ae748d77219ef2c7afcaf2db0a0ce84f0888f8f92834caf45fa72acf81bd0a24d39f36eddbe02a9ff88b0ab7252df0c39b70805c199bc2d72855b069f13f9e8f0990780814ff0852b103ccd7bea5e80e118bbf517223edf1058498f070ffd27cf08f39ba10af54803457db4066b029146c7399e1ef16e54ff7e494e1b02d84c168f6c2a12450279dbc4544c0dbeb745c86fc87632dfe85ca8fc439d7a3053a9b1c63c64bb32940ae3a3cdba614ddd6ff98b102f6fb680684257b655452b3082fc1456ddb5eb551a5652fc46bb553ca9bfe5fd72c710a0413c4b7e5b200b37ee615524093473b99318f268a2ccef91d09ca66aa77bfa32bbc9149076dd272834a4848f29eb304a652567b5f6ee9a2d42a6c431669f71ba6bf58a2a982c1e28c5cd23179ce6f559c5f5132bd2b698b3161724d96335077f67dd22fee9951b852b6f5169f1194c61a9c526f2fbf8f59e3f9d58ccf91a655ab60edaccfa32042fea7b8a4c37f7afa5dad12747f6de96fc9327c4cf0abb75ac2322aa90d87b13816f3db7113c9114f403bc0fe5573ae876d9930e8ea7af5e48125cd50b371d2565e4cdfb5923b279a6dd8230e58e3b5afa585fee6674d6e5716db5a2464abf23163d7a16ca25c7ebbd95f03498337faf402c703b4c0867a3d39cc707d4dece2281551441763c2b90e0cd7fd734a34bccce474462352281c5830502f5e247050b1d1c46d7897740af413cb9c46018f2eeec615c65ab5a7965ec4b35391daacf0413d252d650f28c2efbbe4aac18145370a218b8a1d79e24ae8906fcabcbc530207e7de442ddd569c4763e77a97d200ae2be108367ac43d3d366bc0c36982e38228b2be51f841a9cfdb98c9f42cab2e34ee55afb8ed45b9430eb848967ae9cb2049aba7b95ae916910b49ccc9787901a2ec6f851f8a0ab7021fa43fbeffc93cc06facafaefd92b11704a252d5ad6e16f17ae8a9b1998a561789934b901b4159e03b0fbb480bdfb6f663959c4b29562d01e8a775b9c44b9e1a62d2ba4a2d85685066b847dcb0f8dcc4496b10041d5bc6234e0ecf76497a0193e7e7aa2609b300616b10c3692f12f4b265f2639d408d25dac1acee6c59600a0f01b98fbd5dc463b040214f30d7b358346351c2825f8104f1546f13387059c8b39f07a9c1863194d2b73c577664b978c19b6bcd65e64afd4927e78ec1d8626ecef2116052ace280816fc1b1cc186d0f276153d9038b7b2b3bc077f9c8a3ce84fba4484b000a8d47d19f9e5328cb52ddab8b88ef9abf4e9f84e7fd97df6740733a16d85a98cd4569624b3f2e5ff7f8d254e5ef53286e60c710b446acac2704137a72f156720f855cc0255a3365ce594033b07eef0c3033ce98118f564819ef65801f53bc1e0a34a0e21abc7411fc71c396e42edae13f5f807f7a2f79b8c85f804be41070f664a2c571c164582c928f7991d0b22e25d1f3319f1b60a61f7515b50b5889d9f4bb860b5145a3e6522506fa7aa34c7f87ee7656ee848185591f8f5f483af0ad1485186d31d613ef216c8789674a42073931c81ccabd884b77ba1479cbfa6aa3f3ed1b9a420f7ce535d19d4da400fe4c32c981e2087aa0c29d1f0142ff5a9c153ddca84062e79406b8426c4f97924950b9ef82f6a097abce445a09f7f869030148c9f7a72195870a9eeea8aa29aa93ec2921103c5bd3432207786381afb0ee572f2ceccf0021d5a2ce58679660f61d0d2619a3449489dcdc282f178223ed4f4636cbdfcc2118d31fba11378eb82c9ff5bc03bd69f198fbf63a5f6befb633be1a9e8e2bbdb133751ac604cce3cec313b48633719e9dd0b8a7916771a4b945c48996d13909c2fb952d39ac4adb75ecc2a4cf5db2178ad83ac95355ed862621304fb3d86fac62c61cca81abb5b628bd37472ba4bf4dbb3b2667eaf3b476ad980d87561512d9a10317c74dd2157b5e6181f1ef7c73438b3a4d394c401ce9215d3d03e4d3fe9e8105e648c5c684be8cc1c57c6e7bc70e29a47dd1bb5663d9b49b0b8ff3e7456be1113c8c8eb409d034d5688d6d148d416a0fa3945dc3860f23ff1ee6f4d8ac219118a28944db7061c51457c09bf97c8871a6ba6fc71849ec5baa7420709bc53b21aedfedc384f01d9c01e0091ff2736074143cb080baafff845ddefff7700808e274a56bf03d38c256536603878e346d0f47ed7002e7da6347b63a996f4fff76b2e000b11d6acde02c82d54c02c6093f099b481dce32022d817f21968a9dfd4a623822000dc618333f1929e149b18176c476ae4962042cb735a78a9b38eb30dc629a45947e5259217eec6266b3245b6589abff779e7b07d875fa903304ee96a1c16f5ccb122445362c13a16d2396e55666509342b9a9007337c0f22ab153a07920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001402f7659df3ce4b0bfa819b34f29c0f800d94162e03d2a4be37a2198f936ed70db4e58202eab407bdba483e989c8111922c71128e041a66da0d33f4835259d402d89783ff57170ab96b3aff910be4d2b64533b63d1c40433ed765c8a94cc6332e5f83b76282da1f46f08356349ad2582f792eb17a2673e895da46e01c2c8f350aab4e3cb5da218e9e596ba882ef9d62d950553b7f4f7ec360802011f5e85ff91bf63aafcdd53c44fe2db368a87455f21216924ef69539245eedfe6c6d32fb261564f88acfb671f82dec451fc8d19fa8a83ceb159999bd06396dba6a273bd093099f70a592e3cd931487dc21b8579419924a55b1eb48acd718d81d2188f854a22d2382f46605ffa664d0bbd3db337760273af98b957ad443d4304a08548aecaa1a4d6ed4e7169cd76a91b9fc30a006c4d32de3b2191fd868422affb2b6425a0e1d408d02105c088eec9cafab13a5c8581e09c0d7b46230ac8ce3eb78a18e0a9e300e2e5755002c308852d2d7a63bb4fcbb44b465bdedbfa618948505cc4b7ba23038d231dc8a11bfd7c078c21684edcb89b585bbe94ff795bbf76ad19642ab2d04c59ae6995141156908b56567f1aa2ff9fde626abda743706f3732c97460da423232162662b2d1ada17aa317cc8eaa705a07664c549b68f68837509f545c4f21f89a1cf2e9bf58f4c3826abd7e36442159374b0b9fbf1f068455ee46d5fab89217b00e1d5b92e9eb8e080ebde50fb3b142f2c7ad82359e56e7cfc08ecd802ab089aa2a8f458d4c5d20d5b4af86d7e93679d733ba41771d2c600b9841c012732215d655092a96f71ea81cf619fdbad73841d58444ee320316dc33a9a6247cc7f00636ddb0f5195c8cf49d66df0d2fa81e71bd0697589d7d16e9d66736e4ab21a1862ca3242544f5944ecfae168e77553b865263a1b5c4015284476549d4341ff0f0a9ff123dc5981de4646f53305305acddbf6879e0cb5e1913a2db655b2c3fb0e471d707375a93f30c500c1e6d84c2482e67f8781e2e7a970a7a5b819c179602dd80ef283ff3b9c6ecc7644d3995492acd0c6b34ce7a042b67ce44de924a5cf2895daf8f1953387d27048afad60b6625707aedfa2280a4dcf7800605534119f0a403b2e983004fdfc563ea25be5a8fbeec9a7977866e39376defe79a02c600816a39dd8f7151193c9acaf5ff453f9fb0f1287a54b886b3a73d22e7a8f350a7423abe64976b74963111ac5d96927dcd77d9c42e226815ef093e7aee71910f2410a4871f6f2f3fbc119cd73de82053a670e2d8271532c74dfc10b6f21e27f6d1623029782b7b3325589642a9b62b5646228f7761dddbfecdbe601dfe68dfdb4b100c68140a2e0c1f8547a8907d10c97228ef4ed84d836ec90895a8041c3b2f18323202006853989462ddd65da3e0fc9f341af8c027f49dfc3b6f450401c3bc61f05651b24f3cbfcb90076d8b52a653d214e5defa2a91106a01dd8b97701e7dad4166e196a20a4d78ee1d4fd6b759ebe21dc4749546367c3c8cc5ede0d04684b6101c3691c0bbaff670529eeccda5bd603065f4badb3b420f7ac3cd6df3cae9ce81427a4594869cc7ef87a05bd16d9fec0755be22d8379ec4455e3673e5e6e296110b58c1fbf16379a111301021f14f72bdb1d6823cfe3c3b0845ef2ecb4e14d1010af6857f22c5a75427ce225894454333b6cc21cbb530b73b62577773d55dd3d110f67b79bff7bf6bc29e6ea7d626e555374bc721c310bb584b06b0489ccc6f50060dcca1e966da7b611ee59a6aab337543b38f5523da01b751fabfcfcfde70a0000000000000000000000000000006e99400a2e669210b323b13e4a559562340000000000000000000000000000000000113587ff735be1bd07037d32afa6c20000000000000000000000000000006d61fb1ba9632b8cbc76132b5b2a4f5dbf0000000000000000000000000000000000264a56b9aaebc291ff766c2368d7b20000000000000000000000000000007fb5b38f675b9dd9adf1119e77bf6d1b2500000000000000000000000000000000001b5f6eecfd877030f4b801591720c400000000000000000000000000000044a28ec206f26f99a7fe98bdfb82bd225d000000000000000000000000000000000002dff7548595122ed0e4f353f5ad32000000000000000000000000000000bbc30b9415db001f70fdd8987beb1c3e9c00000000000000000000000000000000002d8652e9ad4e0a4c2ca8eda205c27c00000000000000000000000000000087b1b7f5e9abe2f8dc781bdac7fff1aa1100000000000000000000000000000000000d95630725a26fe91e15b78056b1500000000000000000000000000000009350c0aecfa2f72e376bf403ec8721f86d00000000000000000000000000000000000c6d69390ac401c6fc8096c173b49f000000000000000000000000000000b9a4dea2978f80a7fd5c8e51be6532ad97000000000000000000000000000000000015ac99e0063363eba179d9bddf370500000000000000000000000000000029692467d705f2920dcf22b32f79fd3be80000000000000000000000000000000000079354a1a7faf934f32b3869c64d6b000000000000000000000000000000f2617d01e89a14e588bd8f6a599b8f9e8f00000000000000000000000000000000002026b9dc6c9c2ea6c9b6d97ad5e7cf00000000000000000000000000000073167a42c43fb98d38ff8f48623b8027d400000000000000000000000000000000000d68131afcb0dd20f4972cf543772b000000000000000000000000000000afaf580c7bf00931cd0c4102f8aaa7fcbb00000000000000000000000000000000000c7217eaf7d8bb18f8748c77bdb31e0000000000000000000000000000000ed9d41f73191606c11301a7b542dcfea400000000000000000000000000000000001fd2713b9e5b9e5117fe3732873c9400000000000000000000000000000091750a4e48f1feefffe3c4cc8dfa11b384000000000000000000000000000000000020c1023a70b1d27bca3d24b06d5579000000000000000000000000000000d74a7d51338e01a28b236c60ff8fbbf394000000000000000000000000000000000004e1232c30bfcce815402234f0713f0000000000000000000000000000006bde145ebdd90ca2a689e65943777fd80600000000000000000000000000000000002df07a18ed3fe8b2c070a57c944bbc000000000000000000000000000000d5b24ca3dc8e1f9d29e2a17ade852f1b7b000000000000000000000000000000000026360c3bda49bc3f5f5093c2a1c5d5000000000000000000000000000000dba886e62edf0787e22c73d9fa6ade05830000000000000000000000000000000000178848e705cb1df7f400459540a5e700000000000000000000000000000025170aa9b693320182c04029c5e7e4121900000000000000000000000000000000000bd42d893c4e1c614c357437d6bc74000000000000000000000000000000c4ecd919483c1a2ab845f12dc62077900b000000000000000000000000000000000022f1c6248535576a0717d01d4bf1ea000000000000000000000000000000965739e421592c66c4afb6565d07df6a5900000000000000000000000000000000000c66b846cea6387827a86b53f06a69000000000000000000000000000000460c41dff84a6bce3104c5f6c492c66f7c0000000000000000000000000000000000064f261a0890bd5ef9598cf92611d7000000000000000000000000000000de718a32a28cfaa98d7295000e72c06fc6000000000000000000000000000000000009015a08cdef623230553bbef5b9ac000000000000000000000000000000b7858366c56a0c3da72210cb7b47ebd3ad000000000000000000000000000000000012c80e071fb1aff3b4afc0d80c0902000000000000000000000000000000b32fcd0ca6d0c4e2a35634876ae6b4bcfc00000000000000000000000000000000002295aec998986d3260001b2652da8500000000000000000000000000000073ea51d2509a870718aa82b7f00e974ad2000000000000000000000000000000000023324c74a3b371c2f5e5b31ccfbce80000000000000000000000000000000e2b8a28a33389a4c09c8af5d4e7422ea700000000000000000000000000000000000041d2e62390a06022c514c42745300000000000000000000000000000002b5f6ed66337998236038a6fff1fc69502000000000000000000000000000000000023d1351f04cd9ef7abe1048ddf6c3e000000000000000000000000000000ce251683e0567843df829e63031f4350df00000000000000000000000000000000002ec340753bd9e99424e8910d75ab02000000000000000000000000000000d35ee5cb042d4aec737803c5dea2630c1b00000000000000000000000000000000000daac357d6549124e57d6eedc0b98c000000000000000000000000000000b0309944ea7e471a09fd971bfb9c36c7e7000000000000000000000000000000000007a368b4c1f6e35c0a480af8414da900000000000000000000000000000021f1225266bea5ab62e97d6c3e2fd7048000000000000000000000000000000000000a9599125c1c84e9f03acd8fcf7a1f0000000000000000000000000000004f93b5557f54eeb37238973013387e6efc00000000000000000000000000000000002a543ca44d941e21b40b2aeaffd067000000000000000000000000000000a3ffd818a85aff4e9590b851012624dcd200000000000000000000000000000000000db87fb229661e5b4f3c1491b7036a00000000000000000000000000000087c95c65ed8c8c03b7ff4c8b83dab94254000000000000000000000000000000000004670b0675c3aa38c1e2fd7d32b6ea000000000000000000000000000000a602a4b43bf305b4c888b9a3ba01964ac3000000000000000000000000000000000012ab08c2a76a1a8f30626d315d20da0000000000000000000000000000005fb41fc6841b45666f000ec89dc579a2e800000000000000000000000000000000002d975efc23a624beb991500f03d4da0000000000000000000000000000004b7702c931ece3321f98d33e85c557ef13000000000000000000000000000000000007bac1ea635e4f038b3a994679d54d0000000000000000000000000000000d079e5da08c9dcb4de83eb932d9c9903c00000000000000000000000000000000000682058115f71bc5f523d1d22e30a600000000000000000000000000000054fd9150dcee9f00d909983a171c0a599500000000000000000000000000000000002d48075b83ac71ac534ae7d2aa536f000000000000000000000000000000ed5a96f25e597e90a24fb0c975b83a94a80000000000000000000000000000000000286dd35274d7ceddfadc89056807f8000000000000000000000000000000c00e574323056ecdbb5d95b5a47edd2aba00000000000000000000000000000000001608e6ba98f975d660532fe37b3a4e000000000000000000000000000000544f7a22b7c1d9abbde125f75aefd6aaa5000000000000000000000000000000000020ea76d9fa9beca8380bb22786eb610000000000000000000000000000007ccab9b2d3cf3fde1b40b5f4b8f805b8a10000000000000000000000000000000000209c01f19dc726d266498735ce39ff0000000000000000000000000000006623a5a32ef26f9cba849c2a3b5d83f4d0000000000000000000000000000000000008b8b0ca5a59ef76e1cf60c225e528000000000000000000000000000000b56ec3076bdb7efb74026f41615800a0d600000000000000000000000000000000001423b8dea35a8c0a50385d1b3fd90a0000000000000000000000000000002d1e81446b8c8b2f0ffc3e938cb93b9abc0000000000000000000000000000000000128e448ffc3b1d09bb6783e8058d6d0000000000000000000000000000007dd79fa7035ce3f454326310495ee858a7000000000000000000000000000000000000efb75639b2a3995e71dd437a87fe0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002f6e89e0c65369b14dcc2c500f1653e2ba0053cde393ff12a24aa7de7199043904f6e693ca4adb84f584bba58973a656fea999d21d2efed64d68ef99bdce42e8224cb7be17d12a3223468b5ad8b342779c65f128f23a4a871ff9ea0dac5f94ac19511f9f9e02b4e6cad2370327ba5cfd9f56a1eb61ecf26002ceaec5956a3e0c07cf7141c8ab2e596ab54faebe21f755ba27fd7827a62aa79077e68dffc9a5db202e77fc3a7b1ee01c71e10b4364e1d2f60b3914f243ce8cd2f618fc654680af1d043d652ea6e0f94a1ff8184d1801b34e194007dbcae2e2cc17bc7a07112d2c24cae6f901fd2ac5aa4b4d5f57a80f4ca19132fdb8394094abb6b644bc1eeaf60623ffd184eb42d69422fe3c8e7e0a5484104237c6d958ceeedf99115ebb23560a4ee4d99bd2cc2d9849764fb6559e84ab8c1d0e7b95035151f352b79276cf9e0b5c1b63ce6c1617492d76d8e142dda684bcb496c4cdde8690daddb45be1dbd127bb04a18858b34bacc49be594a39529f480c2aff0b8b67833e7953543f9a4a0057a24f76635c33bebfbc2781a62109d5210a5b13481ad512ddf9c36489be1c00d8989acb1cf7a2e02d624709d64b4aaecb354be0042c31be8c1a0711005482f27a30debe3a61beec341ea0be8357862e8eef1611d25a3aa5ef24d10e086e55d20781cb4cc82d176856102ed95e23228a3fcc1018c82af19eaff112f49ff2781177c7fab42b6ce9d966bc00cd97599627593135e2303cc474f901e61b9b89027069fc33f61a60b3e3bf3ae214db2fe8b94eccde58ffa6439c880bdd8d36f88d2241abbfe0d66f0d9293cd917e89d821159777eaaf33b161f1a486086ff4731dc16ea174843bc9db2c00b4d44221a51d99201bc6f9bbea6cc0c76750f9ea7adb117f445ef3bdbaeec5f74bdcc560dfb38070d574c5a36868d7e259599d32b44a015d26a96cf4ecf6b87753b90cfde8f7126bf21a2644bd8f4ef3c0496eb9b2fdc200267b60b708a173e0d9cf60d568bb809f330e66d07fcee343a558487037afb041f2f05543014ce39617d817df11c8bc033dca9b7879ff2e94653c5f4b979081c1ad70b66e6e75726d2a35d17bd4f1c63a0da3cf0ce7868061f4a6f0071dda90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006433fe684a939fe75a79663e5496d1680000000000000000000000000000000000000ba38b32961bbbd1dfb4742ae9ed5e000000000000000000000000000000638380b39c287b4e608ce046004a50e60600000000000000000000000000000000002b3900dc5cf28d0d8c086719f213ed0000000000000000000000000000005a49a0137d2c4bb49fb4aa0728b8989e97000000000000000000000000000000000027ebfae78d513cdef72f79f46392d3000000000000000000000000000000ca4f7981894ec601389fbb86e8c0941d7f00000000000000000000000000000000000604b2124e61269498e2e20f005a19000000b3","publicInputs":"0x06f32a63ab1a10c44b40a14c94fd4e693830a91920a63778c91df75b67c3a25900000001221894f21cae5e98d0c7a1a2658eaf169b0688cf8348dc7be4d5a944d568bd46000000030000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb00087e2b1632207a64d2be3430a622118411f15477dcf399a057660b8e566041001c2aa1e8a9c646939d1d0d3a1b789e2eb024aa538a4c7864db736646faf6cc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e586311f1581539435ce58c90ec4a9d291746a8b33999d1654faffb07f382db2efd3fd6b542f09e9f76c84337f46370f67729ce54c815d35866b4cb2a2672030000000000000000000000000000000000000000000000000000000000000000003f1c36600e57c2c3556b97fe6d9919a7c418380b539dcf74182dacf5baea2e16743433c1b3d551429cfbc09ab7899d4e14d2b5786a3243e29bc9c6c0d76bf10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
1
+ {"proof":"0x0000374024c73b726f6de9946fc77ee612a1e477439bb81cb8b2c6de62020d690a57de6e181ae5996cd0a8f7d1320121acdf5fa0ce0ded260334259e4579dc12da0cbcd300c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af09300b2670115a9834079b6ecf908fe5d3fd0668954a583e95fe4ac21fd5fc1c5950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000279957fa7f30a5180d14fa065ce2bfbed38e94b985f10b5d1fce4a95a36e59f914e8f9c951ad8f46a095c4f22714f5a2736cff40a950b3437e234331a756dccd000000000000000000000000000000000000000000000000000000000000000000e941ac2af91d7ea3e7b789a78258b8053812398befd8a0733610c3cc2c1c682df8aa820bd774c75ddc4b1e29f3b456f7848bba10a44773ec2745205bdf30a80000000000000000000000000000000000638f6bfae659e3b180dde13f7d41d40000000000000000000000000000000000124a260c41ccf0b34d81c5ecff279b00000000000000000000000000000000000000000000000000000000000073e700b352d50cf0ddebdd509f7e1542f13e39e5ba43f10b037e09a0c4a33df430b4000000000000000000000000000000a4a605cd1e2402ae9e1c1be817815e7675000000000000000000000000000000b4f17712dffb27daedda1599d714b82f77000000000000000000000000000000000028606bc16d10c402be38920df228fd0000000000000000000000000000004545a23d67d11d81e3eddff757701eb55e00000000000000000000000000000000001e7c338bdf8ab7cf63beb379e37c380000000000000000000000000000000b8ea432f8085b38a5c665b8a92e6604a0000000000000000000000000000000000005798e83a88c1416f580bcce5f4cbd000000000000000000000000000000269d2efe7f41c9fde13588412228ebea1f00000000000000000000000000000000000556c1b6526cf56282059a5a8259380b582f4ff44659b2eb32295a662bb9a8810b82cbf2ba699075051227aa8a29a808ee7ad865de7de4016a59eaf6bcaafe2edeeade3a60fe5caff1cb10ec576c0c27210ed98117926c6b59184049199fa3afd4bdee7cb86144909acf56a32dad060072f982040c59889c028132b2f4e6b8b33b169c7cbbee52d1da56a39043d7ce19766d6c767b883e7b2b6b4612f5702fc578d0203b144f0a4c58dd235d03869d25a8fc84e0eed62e84846ba30ba604ff385e23215b55325ba40ed55309ae762a193782db7b347fe2cd790ec1909d637cd360611d4ac4098134b48c576ba9d68115282242fa373432e29e5434049fcf9a19e6f6d19713297e90ac2ea20c3248852274438d5e01f4cc60bfcfd214d48dc18f59bdb6a7ed3f5f4ad6ef326dfd1db51e997e94591c00c715af82249a35d5420f1aaa2bb1372e6eba18c7a6224d8b5b261a45b90aa4afe7001992d4d1c763a251eb82f2180746ebf648c18e67543c2d241035ee2f2c4bc714c01e3f673232b644a7851a5772a2407c655da788b24ce206f08c6d4b5e6b3b30d60f99a7f423b539c4d3bb7c660ff1101040d83032159d0fbeb4cd23e0a9645b83c9b59302659f68293ae294f8c24cf3191870023dd9501165619de58350fefd4d1623178c420d5213138d7ac3d2a8d18d20d1580f316a204bdfbd9a87b25d543a38cca240e2a7b552a3d40421236118b87e61033a083a03d25e6e83b32d423bfd886e02d27a1811084f6694efecba9c53071eed74ebbd2c91f0045d7e72e77c52bd487eaede45172b98e1e4c983d6a78eee75028b144408447e9b89b448513b6c105c947cb0e784d7348e2104a3daf4a61a61787555d52701fa12d06842fbba66e9e591cf6e99d863ede2b4ca632c04c826380a1eab861ac1b405d9281ea923a665bb1ec65f7ff7c30bee57ccff7a0d89b58d0671a8671e1a510ecdf8be64fe5a51ea485767006775cdfdf07cec018c679ce8530f496c0e1c93c0d00a6d21ca8e2e5564d1a6f2e1eb534c68957a03e99b77ad0863a0350bc86358d20e34b9e795a5848c6b893329cf9bb822c59b0f119f4ff491b8a1ff2afdeadf940b47c0c1112387e29fb08628821b1ea02389f1d2271a314544635f132c7ab23be7a0ccaf1f15d6478dbcc8a2f434ccfdb4c761d7569288357d2a421feafb963686409a99ee9bd1d601fb17afdb7e8e5899db2c8ebf43993133a56227c6012d585c197c6fbd2a8d60e3528453178fb7e4e3885f6cbba3e7e6ae72cb1157a42b508d4de8eb6b007cc82a3f8cffd7f28236db5b94ca621dda36000cb506a1f1fce1fc240befd031207f127278de901b0df94e2bf1a49b65403cbf07082a0a732d567fe45d9ff33d3d21f4d5d1557454a6b59bfcaa059346f0ef02c50e1964fe8ac61ddf6338b6f7a53de09d6bf245d359d7d0b37e1bad6d71cd967b5928d4c74951a2485f643750663c56562d24e5e302bf76bcfed8cb2640d629444125b56ca5b679559f71d4a7fa644e63998011196a1015ed9af3ebc8ec9b8a97df192de00cae7adf155828519aa0bdc4f9f25e748793fc0968a2d048a1270889fb089c11c277e3cb8395d4c13448a3d2e63091d335f1eccfffada1a932a0418a1b0a4bc266b08a8510f87bf50a90a25806ac09593a757a7841c46c0e2f95289f6a06f7ceb03b51b6c25cfa109483900a1c2b49419751401419cc85e118ac4b519d1e4ee1f0be5ea51559cabde38a0e540fbaf353b4bd94060b534394111ed7368209ac8b1c9bcb0d357a96b7d997167c464641730f5dc62716e2289d1969c226b306d7cd821830318778fa0ef247a53837ebbe36503d42175fc58dd63b5d0673ce158af84948fd51fab8306d5ca6aa3cc66431fe19ed01c9d8dfe89310b5401f5f200906101aa357108f2b8a02f281555131a6e60d6c1d769ba24da1d08f80f73516f15c539992245c3f91e7d44402df966ab704236b1d560644854a0ab5d779a91cb92d0ee3cd9af7c2d98384af4a6fd06770a470c5964d1268c419e1f77e9be01e5c54a982e5ce1bb71e8b854e0d11217d561ffd6b5da4af7fd6a48c468e952326d29ecdc0c55fdafff21d97cd7223333459fb29803c403768fec657c5b56376166ae84a7a0c642c4056c56afe25dd4b527ec5baa60bc7a45a8fa47efbd9711500593dd8111e28984dc6ed99f4461a25b18ef1be130db3de50e9c26cd3faaee0246952137193b4546816443636d583e0a4ac93bdca1dfea71c2385013e75289e036dcd2bb880a5ba64f83cdade779dd4d3e1e22b3e8bfb2101b16351272eaea520e08c07031139adf078dd6048209e09f6f005ca89af419ee80e04fe1d842b40155dce9a1d5e73be5d35a3a137b76bf03c97c71f5f503f538bd2dea5d414ef311aa90623b7f9bb659f312150596eb55aa2bb0475ef1ab8aafd6a5a826ef1861b1c8e63d60728fc45650cd60638719893f7cd7d25604c3025d2ff5f8b5c7f7c6c01262d8df523daa88e8976fbab0db01ff5be218616ea4926eaa4f8f330a14b021a21cb8e61de2a7f6e27fc1c547ce396e35b10007926950f7ff766fd40922aa9167d97baa4f9d1c63cd25eb35458473698a2ffbb82481a6ec924cd2ee5fa0ef20cef74bc34a2034edc10eebb82cdb2f5a4a392bede70f42f0ba83921d6493fdd0dc4d66547c5356c23ea91249781c911c2d4b46d709adce6fff57ca18f5e1d481695a6964bee82165f10d8575d6b297a34ad0fe6db02f88d1913bf2aed68006b00061714750289588091fa49a5a60bba72a12d40652fb8870836db6d771f66111d84a756238702f94b1dbb47edc85c9170ff5f970f8d6d5a8561ed838aa15e072ade281f9c5f055698950fc1dac87fa6c062af30962fc7419606a372554732161ba34128b38aa95697eb4ef6085b38eaeed1c946ed5319fc2ecdc930399d9470241b2a831c13e19d6ea17bbe364a462b0b1708c9f9e609ece2cdd522a7d4185a26b4d9682232ef43619608abeee702606bccf9e063a28bd93ad828bbd5d2abc40045beae5d8a866ba6e0c81eff9639ecc2350a594f06061f7cd2249d3ce2f0702a31a11e69d51bbb8ebcabf677f32871000ca22322758b6fd7d360a6c344c738007fa843cc66c8787203ff79a06d23dc1c0bd8a73b7496861a76efb63980557f016216fd71b2a2b0ca8c41237b1faef627913adace1f1a0cb735628ecface3ce122f3bc8057682162b700c4a521f6cda6c713b863de8d727d0d82584fdb23be02d09adbf32fa028d6ce5063b46de2cd17ac2b92ca50a2746e9125c95085f0800179d78862e215061980d7d8d8cb281e783b8f5c48314bdda9c778a8a86edf5270ba2a65f32f47bcd28832d829cddb5b00de69776870d4164f469fede36ceede2119a74a477ff69358b03bea84b6c5f09ef629ea66aa7f6fc533d1628bd09869c07dde72e1dca93a72fbbb5cbdb141abe017e8fccbad8049060d6a0ce613cc5a12ab70421ae49e4bb9c73c68de6624e6ba9794f6c4f8b58be27d41fd5bf8481fe0633efa5549d2baca52e3686a5c2a4c2cfe581b11f2d267160a4386f121b381214d39e676cb7b46e896c433b20bdcde7536357952c0ca36f0e76557e3d757e982249e8c24f1f58406229b78e2f544f73e10f703c6a18a737986ffb90b8db17dc179cf1c09a8b517d37eab629d083d380c2a784713af5000061385f0052ddac0606fad9907bae335bc8f89bd2afe446c952c8129e8e108e843bc5909d3d7f72e90964e51e934779ebb5692fd00722a4b43d0e3bf7def5130f389dc57598fe00021ca41cdb77a667566126399f0722f011210fac75df845df079388f491af02f0d25fc2446ffcbdaa1709f753cd6225d61b279e70b55153b0a52fac37973727f1b1adc65fb3c6e09479a3cd2cf511f8712958743d004f7d0129fc44a86aea0f50d18ccb3743cd7f7af24b45a5ceaf1e38baa59d8cc2148d56ff532971d39d87a8c140ffabea5b4cc60f3b6f73beac2ecc16af03ab918bd07507b8a2a48be7a817c18e9fe02e2a9248d8d0d4c4701d9cf2192e07d18a5a10682112676ac06eacc0b0b7f161cd106bbd6c240d2759a934ae0ecacee6cd81d3d4c2ab9e1b7550abe560d1858a3c4e3973c3f55fe7f60c4a117a1796ad68536fdab080720c7a1a362592cbf0ce79014944bdce97dd98e7c57f6bf13f76a0c1f09dc70a3067bdfc558e71556aaa7aa38851c290f7f32cdfacb6b0bd331c5b40dc8b6db154fd09fee0e42296088d9e9d5efaa907c7cefa2b5e94f021feee27881ae022d23ee82b2b23ce004228398d4941fd27ce75f3f73442e64f8356c5ff71a79f0c6133533b972d2fa1158df34cb980f2d98d261ae284b05a088fe046ba5d440692fedf56f81b1510113d9f482d1d363a1fa5865a5080dc9a694b449359e090b65065ed1f64e4dc55e219f6977c792602cff3c7105654b5f72ce2e6b79f29ba6eaa0df48b8e5425c6d223d4a8413586b00ab8ad9c45add3b6395a3e03b799abed7bf7e3ed09a44cffe1f285925828080466c055a37e36bd31d98c8c1c5b3a7f4ffca8d0728b752870a2c713cf117b862ae90fb7a52477c1444377ff0a6cc5e358e726d9e6cd743c69420686f7d497838c7060324a2e50068dca9a3f4b1a2d1f6421c60936e2738d8c30986ca441275993ee08564128e8b4741c9bf6f8a09e97d0e697e2b04c0ef85631b5ea3dd92cb3a40298a8246c4d623ac0cb3df0e8cc0350ff6053df4747ce14d15d1b29212ef05b3dac93adddffb55744b26fd5d444ffd99253f1bb735827d2023e7c38ded4986550f5fb3592332ad3dfd7eb1b74622525ecc9b92390585df060a419fa6dca1a965fc4d8897498920066d0d606f0d0682b725848c62612e3b2f0b80250e8ea018752130192e4b09615cffb2d22f4ad680c833e5ce77c1dd4ee51d660de96cc28a0b41f0676545a0330331a2369410c6ca5b8fa7efe7c6e406fa25b46865b095e5ecfa206b8c478054ba25acf2c0d97bd9e6a5b367357229c5661dec9fee59e8d30eb7d96947dc6c9f76f3ba717bc35b64a61e6777189c362432201f1183c270a53de3160131113a4f88622739fe859ba01795f17571fff5c9241f23490e3aebec3b6c647ac3934d83690636084be65bbbfd272865dd6f2db492293dd46beb15ab4c4f1411034581202bd6609cb9d022837ef225f54dc3f440a720f0eade7579ca6646441c2f4624045d155f0a006de0a2c341abae74431f62922bf1cf062041a5f0c611ed9db9dbaaa557e93ea957faec000faade81ed8d112c1736070e5a051f510dee52aa27e2aa712e8ded0063ae87fd7ca0b776664c3f1021b60c3bff883eaae9b874d4895a6ed133dc5e1052bccbed6d70944d0bd6672b03f2e215178460f57919a38a44e412bacac1faecf3ed39ebcdc4d8f36a7f5d990fc417f2e84feb07a2d17b225f92573b401ae36fe10a594b060c16bf50b075b00d52f4206017ebbe54e262c9f9511a292eec211fa12e5dbbd247ec9189d6086b157efd4c12055537118c60ba78d19a10bfa73e73ba093facd809f29800acee8d17e4e618b02b912891a1de15ff594a3751761ca813cc60392879079a522c7856189084d3102048873f267f08b647ca43cc580906242976aabb032ee3fc24d9c22a568abbaae4d3b90cf011b4478359c01f17857531cc5352202c1a8e1a8662442d3656a165f5658be69c19f1a137b1329f13307a7b4563236e206dce50d2a4961ce2b1f3cf3e230c5c574cbb7adc3cbfb8949cd4a13642c176e0141bab528e400d2ff96d5b4a4d6cd6d01de123324c044108c0f3c3cca9bee6f9b02260910a270a7db9047f43179cffed6c50f567ee8164298188708360214a08c4cb887aee7506eeea95763166b4d37dc34a25def1aa9e53510004404a16827e991effda68950dd2cf34edcfe805e719b70b20abc4cec648adef329a1136245a9b5cf0381f912a350008ab5b5bd47d1c83bfc1546e9a2024fa8a1dbd14ebcd3b5a4b869d9ce32604b84eb1d9024ccd524a301f292613316b1be92787fefe9bbb9950d75f56f101868b2a8175010d5975b8e2d136b2c9df21e0248b26f103372375d5f445112f21ae2aeb3dd304bcb6d665c5b7aa5774530d4e2d712d7642336ad13c8d91eb8805751549b17e3cc00f15b4866ff7f938cdc81e8f426a5742e75a4c2b05b0051d297bdea7b7eb0ee67b284093cde821cb8310ce35a5a0c444ef565309e884a8462c1307c2b4a88297cdaf5f15b56f09e121e1a3c7959e760736b04b7d7e9a51481f4b257e2a8ae5f94a5180ff8e4fddf1c380cd011d5ec5e0810aa3c84e2fa29d103cd609cb27836962318f5246b38cdadbc4eda603a7bba0cc45285389b2820b136c9c2392b96ae13ca72eff4a7731f01831fc3b50d9817606df28df9106ca4302a57cd29870a238c3aef468d364a74b086e010314ccf3737114bbd3a0b04ab5111e8638d50f61e657df06e8a2fd2c5c31a39a10e1baec13a432b89d1ea42ee121c8906a8d401ca9d7044c55ca426a34952fe15d162b55090fd644039b8b66932df9adf2a6d123c86c58aa3d311adc1e8616b3726bc923e9ab1830a88fb57dae11282d1c1d9bfa96ddef19d1a5eb95ff81e30ffbd9295ccf37a37ec151c8a1aa2ce1142a627aa173016d575a3efcf06bf4dde3b6c49647b6e0cdeee094928f4a19e2f48967c7564e01ce9d4d3e873b3da01807ceb45b1dbf283fa4ed68e0cb871a7b68c821844b9d820a495081d67635b823b2e4af8d8cd2f46fca3854a143ba19915e480e138c02993a67356c741c7c9028e98c59583c64174e2c64fd6c8e8d2f0a04a9e6efc4fc7e11b8a562c1585805fc14e062f70276bcdaf83b16f8063f1718f1d998792b2b04a5914fc52d780080b11c5f0de3c355aeb53e50c0375be20396a73cae34d7a04c533e1fc6f8e385b550ceed389d656e48e8f74c4b90ebc617cfa5e2c225f6d5909f406ae5e2a3ea751ec3bec6eda3ddb369f1b33b4b6fb71d6846b226cb365d8e04a4604f2f2b623edc2e41d0a513bd7c24308860d540c9006e71bd43a3b1b0a17e375fdd32fe6b596cc06680dd825b65b7ae8ff409974419b82f159f0858784da5ab6c5c46e752f20795a39b447cfa428dd0db6b1ae29105f0a26cbd43ecac4332e1ee841ae04bcd28a8e86054a939f23eb99c5e6c4c7b27ba24f79d73e0500e6a6710aa134cc1e8fb125d2073d19d457185235fecff9d07fb54f1c8786fe15d0b94525c57df49bae434e831de959bbc278878a0b60400018f67e52e03da3a2a6d8284c2cf6b24cad13b7cf2c846083771f42d0c056ad715d8fc1b8765207a7aa58cdbaac92a48f2f9d82ab748dfa62af4152e667c99a715077aeb0651d17e0985da94102d66365401c84dac5cd2f46666d4f2dad3b25411195948204836afffb5640a17a69a5284f974fb0a3464009813ca0cd6843d4f16cbca83ec497bd89f3ce1b6398bbedc19bc506ae67408389c4bda87e1361f830b96e849d6c08d0951ddbc3d5462a3fe1f7a3f584d2ebf20071b1a28b38be6e02ce7f5c325247a28d825c2d977cad1e8584c7ce747b700c3591e3c1de5ca231224e8c61a1df3277b2ee8695914f1d3df29bb8794dd59cdc592843f11d806cd9728983525f54a7ac029e85439efade8a73baaac5197266103594c1ee1abc14c850328ed4cf1ef8a18fb877f8e01504163ed46dee37a8da091f361b356fcc455b02e48c2ba58176b05da0329b7e87f35278ed716aa64789bf60b7c5a85fa05ee80097f2fbc157e78028844e8574f9d36d43bf4c1d9484187417516f9e67828f64a2a20bc5c5c0d6ca591a17db3d92c235a9c2a7b5a746f56b456ce46d654f4352927a555cf335f67921664b389055ce3f4a7b82c4ed99cdc5fd3e3b67a127bb5570a49d8390b51356b42083940afa211357c779033cdaefe82942cb2958ed3166a2a0b3e7b47a4943bb44f83e21de5c2d52c18c7f71d70153a9fb0fc92301ee7a025cf3ad27e484d82be7ffa5e09437e19990ffd3c1a7f050a6d1d31c2194f4b8016c124cac082c8603b212b383ff50a6f5f68f04d20507e476053dc33d2ef249319174ea26ab899c707205790e515f466005ec5134ebecc4ff7b708d316813e771f910fce8d4a51dcf07e78fca57129668dfec1025dadbb7d1091dc79d58972351922ebffb60659b0ea920b8ed54d5b2adbc63122388b95dcc7016e72cf96a9790e5384235107011a9ec2dc21859038d0872416b581fceb060adf002e206eaf0f23c1503131210994c36f5b26ffb53a758de01c002a51c694bbc8b023d7c560af00ac1ba1a265d0cf31798d304897d12847bf2d1f3a89ff0831da9254e0758e1a13b555584c850b01985067fdbdc84ac0593bac2842cd61c5477aef2ed6fa06f8020a15480627e646dc6c947f65a6e7922804b0d8c6db1ce611d81153b5ff481c25ce0572905ec14c7d4897a1b376583f504e88e2a2f36197e51094fcd83bd5c21f19a730184dd723c1b421b5760b94803c44fae3d385da7933d817af97a8146e0f41c896c01c50dcd67f47ca898255b1f6e1348765bff661655f00800f77b31505f94a74d0758b6f91d53e9e93a43ca3ddbde19b0177ce254fb536ff4235acf425896cf69a5b5c01bacbe5aba78ab7161c3a6a83c7baffc895d21becb03844451cd6c63f5f63cf8cee7d02db380343e1a9d6775af58e8ccc9e8796a8d37ffc8e296b7647fe816011c0aeeefec2c3df76752368a6ffbd10da8e796957541516462dece24d2cc06e50fd90f27d526e88aa4a895a68886226d975af1c59b17ed6472e5ed6c592b225f24cb1e2fc961aeb296bbbfdf0a473e4d04d318a97b0d0991026d3b5101382af12e5ad25fdf61ddbbb9c275c0dc2fbde33ee180fc30ba31e07259ae93fbc44b6d6d23481868670293a1527d475c77baae96a84135176f2bdfb295369f4fce7612dfa1ceeb788b359d232ec668091d400f2441f794f9258925b2f888b5a4ff17e6e384c9360fe7298404cba352c53c8e7f63546813c62be0b581ad5b93b98c6971746071578d2e9f1e2f9d6f1cfd0572c1604570b4b9bae41391f172e9f937f86c558a16a77ae34e43208b1d147d2802d3cefbf35b024fd04e72acc3aaf616487c2b44bae15beaebf34fc9692363390e8e7906d769c0d9a8cdc0492d4a4250f59ad9ebaca89f38a89581eeba2a528bfe18f57d453a01d7725b600014d39b4ed425e8bf7a1347859d7e3c3e2260556aef50deb3b6603590ecfca11944c2b378e1cd48e49be0236ec63d958203fe5b0a70889982dc68661f9ba702d7ea05e151c0d5af415167983e874e03ad9a3f04fe6ba1154a09d33b26cdbc62d985cf73a4bd7f0383d3ba07fe6c48743c2e755df260a882149e015352e2db813ef249a74ab3e221084df8883148da363ddb002e8ed1253618b1d35969d61f31651ff530ad10f6479fdf402848821245f313ff8e1e6f440b9e139267d7659a32cc78412f1a34af408ed3414b68dffb38621a60f1e0cbb7dbaabf4932a927f2d1907fa04d4e761f8c8d570f3deefaefb7835778bea9807aad32e1db0eb74771e18bf1c8c22200af9bf3896fa9764c72c12455117c57ca20d461c72bd5f25601618cdba9fd5969c264d371eb76f4cd8a363fd9fdebc1d56447acc40cc4feadb2c190b2359ac8a8f74b7b6b3deaa1018cf6bbf37c4b1a784d437a3777825a387d01b916ee66048bbbb9195f25f5e3e5406529e32b7853ff2bebfb561be99eb89db1cc1786604be7460bd3663b34fd9f309b6ed25af7a6c7998dafdedaa40a45b0105418d649f9e0ec14953ce98b4732f4df4006e018367e226ba74722881567357285579b7d794ec262e5823d623d4d118cc43651389d6bf032f5dc2520c2edae21e963fe599d3ecfc4ce70a7ff358d7bb28c12d5fbc88430d78425d548e675f1e0250373e8e940fad93c1adf69c344b4a8b1f14c8f43036342bc18f0184dd270c0eeb952f89d6adcc09aba616986c3bdc6bc806e1e03f972d276aa85c234e150506ca166e3bf46518c75ff841b1e1c307f2d99f1a8e7530e319cf56ad5b7aaee111eaac15ca18d83bf522723174edc7ba1389b23a984cbff64f30f7b659dac1890f09b8de5584fd230e10747dcfffb3ff9c2704752de828972443fe523376a8200b25f81f8a2c745a633074163cbfd5d3ed16ef79d5703f0fc0f151e5585c7c65302752afcdb25e0c125db09bb73bd1e420e52ad747f295e84e954784c71b376c1101eba81304e6cd26afdc86ebe5804624381e2f1261451660bb50c4c45bfb5e1600b2a9cd851b3512522791a1711b46d514ea262199c9e0cd8845f938d1607109356f4ddddf1815913ac3364c43565ec96c973b33178b88160242a8ca45287e02a19fdadce2c63fd510d42b48641385c2afa44d1046bfcc8a8b3fe67a8e3119029c7fcd15082942b4e91e2b060a9de824d821951a3e3724014c91efe1ff4bba2c1983dda112c6f4a8d14a0c374b168d30579745f4a9aeba1fdd14d2d5d09aa509a2b6d7b07c0d90a8f20e06e31d88dfd895c60a3c65cb11792609aec48bc31b01f580ad8977c303f24cd82796cdd6e6f2e4d63da4b1441e860a86d7767de7d80171e32c41b51050447bdacd54e7074f8afcac3023fbea479f193bc1e4ab45d21e3f1048b1b95b35c4e9049110360acfd836d7fe23738179566884a16924f0cd27c9d1cf61646917fcaea3b20f605d530b45b9dcdb6954dfdf68105973c70d01041ba2ff3eea60ac493c56d0ca410467d05e89b3266ef354ddbc0504afa7ee1426001161e5f95acf80886931d4e0b90159560e958e372b4451ef05f009814b402ee4ca7af55a3fb838a0da163072b5d3bc5cdc1c82e9b2f5ec92162ab9c7870e172c1094812d91df6aaee3988c42d042d94631a7becb52b955c514d9e2e4c8ad01eced7327a26db95441708e33a8a968a0395dbbb2f508deba7f184fb6cf79b12a7b392fe2f501d3435e55a659f2a629fcd9ed0d99e968f5e636f285ccd7da522ac500f0284c9f247058083293d70dbc2fca6729a27bf1ef09e34be4ec49a8c3105e8f5a6a796d7c5a1648340aaf79f792e3d51527b42cba9ba9443d660a359c287b0bbc6f55d2f65ff5c5bb552e25091a13f2bc7d5beab63c0731d9588b611e2c95c8d450016cd0b1890e8df3ddc41844dc87dc65ada2732448335098e17cee00894310d74b07cc0afa9e399aa3f5c292d3efa5a2b7dc4d1ee58a714725d075044733c134c2608dfdfecf300596326fe217422373fde79cdfd756951372bc401c0ef7ffb913dfbb2bd48836bd71aa4ec4fbd96d3d8fe1720b820959d0e587d301bcb50c287eedd2f9e03b2971de6ea98bdeaa62f4f293f371ffb37bcf01a9010582a84dc47e461617b37fa486a5899ae43f4b671fba5926cf924d9a9cc1dea923780ed6b9936015ad8fefaf233f1ccd2450d4cfbf85fe6b0d28dd34f6117a5c064b6359682460cabccdfeec2e4cd8f48f81b9dad8ab686791f75f261791d31e1108fee4bb11b952b15b8ba31eca87ca7392510eba80f8a46d3d80dfbd7bce2c0e4c51771bb232828e065c10c7372e8588a4d7d1b1543c57c44b655220d9308606ceb49094d1aba143a5f5b08d29bd52e9ab13a59de37b6466503eb1d616eeb424f7639f106ce9d5e80cf9fcdca7e0d02cc958492ce4cab974734d46dfce7329161a1b4e3165895dd3137bb8d7ce21bce5901557e6a4d19ca838c79f9cf7bac12ea5a937e7f52554dbaf508efb1263cfb0b233a7350c076299f00e2ad9c2058707883c81a64bc5368ca2f64a7e44db24d98100c18c226c535e11ecbc0438ac6a0bf6184dea429e39214485905696fa76df29d8a0f102f0c1a319880e91f86cd50d1c6576b1b6b0510ef6ed84d5f7b49d759818270a12a8e44da17ba8fdf587680f39e243c4b130a4a82586569464e4fa625c39771395f034356bfa9f106598d90e70376482a2c6d114457f36d1e10ff0afdd9adeab3d0c222a96c13cda7a257521ef28f409669760e262f6dfbd727a74b831a12335ebe3c408add5136aab309a02e3cf3fbb362c9f566a539452b21724c2b909a827959f507fed7ee5d8dc3e53030a373d9e806e7a2ac9fb2bca656d5f4d84f30a550c46708ce506c22ba282200367823d58ce295925350915529d0e5f61848b0afd1fec77fe37568b201f391812b8cac270e06283ec97ccc078d20f0bd80101567c700a667a299af45bb332dd2dd7c7c6a5f456ddebb79e41f805192aaff2faa7e693b0dae73532238199459b04d692b52837c3f70f4912fa65e43e865da3ce123fff5d75d06a9490bf841afd0a13dc2ee06d800403d431f7dc574137f9627eee323908ff18e75df8f0e17a2a21341c8b3d228cc85c756e5008a8a650be402489039994dd3d69edbb9fd236f9043494e54bb5721952d8ec0bef09ff996b2cbb25cd4a35925ba11e6d275d9b4216a4aff940c8feb891de4cee98457e39d6c9c83a107f8e8ded131c1c5cb04d7504f31e7a9346407d84af9e579a9fabfd79766365f835d4480bbca9ea513f5df22dacf078f24430adebe4551698090f4336bf9aa3a95a1d9d15cc96fc1da0846c186793bc464cb53b83e31aa4f14612e2598aa4564ff7033247f6c3312e7bc0b5288a708dadffe1128446cb6c3442eb2086e75a0f21d16ea7b6248326b601e61318872bc2e02f9c6e45d24443d0b17bd7771b2556b39f985b70e9740e5ee63dd50e36dff036e604d055822ddecb7fb4f3722575f0a631e0add358da7d9675a2dd1d5f6bca28a211ad9bf97d42a012781b8a285c7138c5a234e88e1429a303e53e01f8d2c40bd85d0eb2b86c9ca26c20fd96846e17ea56c698f1bd9d6e43e1b4610cedd35e4ceca27a1e846776083290143c64e8f75e35f095fd1dca2f818b60652ec6d0804bdd0fe74ba56fbf2dd9c5a56602bf59482df4925f82318d2d4fede02f7a21860c14ab0a88f4a75a4d9107bd9e80ae050d8f0ad16ced682f261687b30a9417de6b1be04dc76391a9bf3a96c2543feda257cd8f8c42d4e093e1bed0380f0f63205dbc777a93098a42d1f02f5d2c50f4e9ab2327b08f1ac668d92cde2024ddf8a714ab6597ff34f6af94688b22977cd2c985e267fef21dcea041fe75ac1467af307aa6d853daeac22fe3c034b4bec288b72eea8f86399b771c5407d30217913bac43fd3824ab03a3fc8f7ec4b61483524d22e1ac23da98c54216be116b287f15eae4cfdec799c131ca2cc6e0299435045c773629fefc781caad9c052bd0c320d719771984f0f4d38a87f42bcee6336838db163c4f3b2b25a8f4617ed0c2f34b94c4183bfffa99f0ad67c4c46786870a7345ec223ba214a176716c381af198e486fb4b9becd805b8d43cc4706a33cc8453ce78fecbe924df95973499a432a9bc33f8e44330dc66db844b406d142f7d52611dd4f1e82dc99a522a982d4f92ac5776d9ed398eaef4d657393fc7869736a9ecf2276b7c94ec3e42d30375edc0ad76ac7d9e2a359474c55d46581e088d18d8428cabd1d1a096f7b26b191b93e143b1f0b7c7451037fbb1f5ad68dbb8056217d28a57fd42a1322ce7794c439961cecc6dd81097a2609cd4c7d0a30a27c38a099381a26adc42cb32b2d42008d6125779281b7f84ecb37bb6cea4027cff83f3aecb3cb76f8f230fdd884109b51742759873d94fcdcb4816aba0da294b568edab5d845ec17d01821bfb8b1a4c8c3603fe700181d6e5a87585766eebea662aebe97917196ec375fefd37dad95736fc2caff8eb84263d07ad19efc312ba46c042c6c3950bbd912a1a34aa2e62c97d97274686c34058378bf8f4aa45af9b6ce04678b21fa9b1ac4c782712abb1098eb101095122be10ff24c28dcd1e13ee0ea82aaaeb47f96827849a3a05f256904ceb2eaf049863bc0e49ba6fed03d0a36b03292b66591a2cf0dbce5cea86ac87b0bf01981b862a3ea8962ec92185cbc223bfc99adc4898e56f3db6fb56192a67e7f803f79e34c5b84fedbebd805e6f74f145126d43459877a3c1736dda40fa49116a0c8d117dd640bf37b374ed31b36ffa7efa18de64de8601163c4b2a87ba88acbc270dbfb81ca1b1993b0e4da9db2892fcf941819bba14dbeed41ebb2b3340fa310a44e8f1953b8a110d6e9fdea1c7cbb7894c6b8a9f6e4dd9000d5d057114cff5075d4425d471909bfc5b28c51440a0cc9e87376003504471617c1892a66c58040fbfcd0e4c3550b3f75f8acf37179073204e69342e77310362128367d519007c2ef42b20ff9cd13ce768c3bc474ccdb6eb3053aab7a635f1b3165178f515cc6a26cf9c7bbbdd777d7dba6f3134dd9604ae4717d9e8bd429cb153c848e67a3d0014b72cf48549f11aee178fffea2a9bdf515ad96e37a0cab7a19123b5412f0a051947e4e74eda847e3bc25a9e61533283692c7f19341de9e03d5f10b1e972345026374ce4651715c9c60906a2ed0fbe1690a3a08b7f34bd6d676bd7fe50a09b1c04f85ae240a691c7a16fb08268738f18ece452d1ae1a127e58e6fb3f2d21e82c062f50497296f510a35a710e75d9325136a5b6bdb1a7fe9a49d081c0a1a77bdd00000077","publicInputs":"0x24c73b726f6de9946fc77ee612a1e477439bb81cb8b2c6de62020d690a57de6e181ae5996cd0a8f7d1320121acdf5fa0ce0ded260334259e4579dc12da0cbcd300c95e0ceb41951039e1592745ec2faea9866f6eaf01bf189a4463b4143af09300b2670115a9834079b6ecf908fe5d3fd0668954a583e95fe4ac21fd5fc1c5950000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000279957fa7f30a5180d14fa065ce2bfbed38e94b985f10b5d1fce4a95a36e59f914e8f9c951ad8f46a095c4f22714f5a2736cff40a950b3437e234331a756dccd000000000000000000000000000000000000000000000000000000000000000000e941ac2af91d7ea3e7b789a78258b8053812398befd8a0733610c3cc2c1c682df8aa820bd774c75ddc4b1e29f3b456f7848bba10a44773ec2745205bdf30a873e7124a260c41ccf0b34d81c5ecff279b638f6bfae659e3b180dde13f7d41d41352d50cf0ddebdd509f7e1542f13e39e5ba43f10b037e09a0c4a33df430b4a4a605cd1e2402ae9e1c1be817815e7675128508202fc4d93cc3bceb9ad073766efe80196dc0d29d2bed1413f5a8226cb788c86ffa17dccd213f6bc054bdafbc1c"}