diff --git a/docs/generated/changelog.html b/docs/generated/changelog.html
index 1edf0a1cb..8d8cf012b 100644
--- a/docs/generated/changelog.html
+++ b/docs/generated/changelog.html
@@ -11,7 +11,13 @@
Agent-JS Changelog
Version x.x.x
-
+
+ -
+ feat!: adds certificate logic to decode subnet and node key paths from the hashtree.
+ Changes the interface for `lookup_path` to allow returning a HashTree, but also constrains
+ `lookup` response to an ArrayBuffer using a new `lookupResultToBuffer` export
+
+
Version 0.19.3
- fix: Principal JSON is compatible with @dfinity/utils jsonReviver helper
diff --git a/packages/agent/src/agent/http/__certificates__/goldenCertificates.test.ts b/packages/agent/src/agent/http/__certificates__/goldenCertificates.test.ts
new file mode 100644
index 000000000..a5f89bae5
--- /dev/null
+++ b/packages/agent/src/agent/http/__certificates__/goldenCertificates.test.ts
@@ -0,0 +1,10 @@
+test.skip('goldenCertificates', () => {
+ // file needs to include at least one test
+});
+
+export const goldenCertificates = {
+ mainnetSystem: `d9d9f7a2647472656583018204582064abbe468e0569dc74af0a631fd9205141a6bf956036e09fd193428a6543eaa083018302467375626e65748301830183018301830183018302581d033a778c6c9eac039fdda83dc90d2c12eb846de85c475e36ead6715c02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000100000001014a00000000010fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100aa544423a45fb0388c43703a159a96208cafd17f01f1e7c400676d2c69f62195f6a5bb564d564f7967047def10b48c22003f38c5d56961d0c47879f9212b93cd206620114bd9e1d4db22d04e294d37e1ff42cedf2322ebf60702c88325c606808302581d0f033c5125db4f6b32e426268df663a5ce98fe3b531d962e1a7a87fa02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001c0000001014a0000000001cfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100913f6a84f05736c2dd0b2dc3ec838e95419ae0ef426d556f50152a445b9c232495bc051cdabbd46a7bd8879b09720cbb13b3bcd265ff75567dcbf04e9ae1c3a2141229a6757605625b093c5ca34336393e5a88b78df7b0a3a7e5b9841716d0a483018302581d10b647334a5406987796b2f8b6b14cd32f0876d3fd4fc8452105832502830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000180000001014a00000000018fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084cbe7a009258947dc30983fede3b98b34cfee5e5d1ae4e1e72891590738ca9a58f9f6364b359a5448b6c5e20ee5310300e4c0c9cca29b07e2d73208f8ec6cd1fb6ca46c168c43393f9e050a05448836b0a6f5c75d2a398c999c42d7c981cb898302581d12790e7661fccd3d4fc83138dcaffd9f188e867b45ae10c8836dd0b802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000150000001014a00000000015fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610086d88ebbd2f1663e65d3a3ff07e8ee9fa420d08b9a6822919f224b8b802d5d9be150dc493f84c23e73a0cc1d2c2ee28709ff140000128fcd5dfbd7b457ef3af344766d7ff0924fe7a7f456ded77ca6de3b1b406b710c4eaed7287ab9a3527669830183018302581d17f67590355e7123aeffabce4c1bddf3a0efd53a2c2e3f6228fc3adf02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000d0000001014a0000000000dfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100850e5edfb0685d36757643be011f5d3378fef0bfb9b0ef67429912ebb9237f5028979eb33779df7c63acf59b78eba4d904c6b4abad529b9e8e2195321e287f8c51900f5b440872719c7ac56e381c8063bc6176f8e4b74d06de669493e49055678302581d1cc5ad563f1bce937c305be3d12bef627f73b727808672dc2432aef902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001f0000001014a0000000001ffffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610093907710f0f89af4b5bd35a28e0162171e2f411d11e152152e88e3da4c2079799e4eac7a3a9f3923fb63b33b68928ae91652fae5c2ccce872173632648ef4dd79ae7e8c15b9e97f132ea34a4349506d281bd66bbd0c3afdd78cbe026927a8c1683018302581d2c55b347ecf2686c83781d6c59d1b43e7b4cba8deb6c1b376107f2cd02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000060000001014a00000000006000ae0101824a00000000006000b001014a00000000006fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610090075120778eb21a530a02bcc763e7f4a192933506966af7b54c10a4d2b24de6a86b200e3440bae6267bf4c488d9a11d0472c38c1b6221198f98e4e6882ba38a5a4e3aa5afce899b7f825ed95adfa12629688073556f2747527213e8d73e40ce8302581d2d030caf397e446c03cece4fd072acce432c75b6a700592e73f5d13302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000090000001014a00000000009fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100805230c2da9687218fdfa49bddab093578c2e8a10b27d69fdda097f286abccdae2541c711e3ca771202bfc9b366bf61b17e9f1173d7c9a6eaaa907ccdba3bc86764bc1d552437c4948038e1018a9c49e444189cd55358e37a6f879d88c0a26938301830183018302581d2ecc29447b0eef6c241dcfdf7dab077093ccd6a1266be0fe9c9b127602830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000e0000001014a0000000000efffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610091541cdc7b65c4828286c911602d9438de5649d698b60fc06aec73589395d0bca71746524ed2ff17b2c8da9fbc897f0f07a40b204871b6fe96d45ef10b51d1f1d530d0679a5db82de96929805fa17c737994ebcc2312d2a25bd94747ecf8f34b8302581d2f1a9548062f52ca0e90e72a4a97cb324fa1dfb62b564ef1b29f38aa02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000160000001014a00000000016fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084698ba18ea46f2041353c98fdf6980235fab99a6f5b83c5de3bb32a7ad190ef26fd2afad2dd2e4fb5eaebc4fd177e3c11ed29fb7dab26a6909d366c185cb9d964d3ff3a8e71c0c28adfca715698f679cef6b6346106a78c9f8d3f8e9a66e88083018302581d30580a1a7643049513f8f7d6ffe6f51000570345a63160cab7784c5902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000a0000001014a0000000000afffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610085c8811b0caf15f9ad2e34f1841a7820dd1a70642e21362748bf0927c6fd67ddc0c1329fdd840e06a16d383023c4c00f062f173e628528eb801c15258e2e417d511fe4ba3c175469570cc8e1338e5457ed6b31b72b139b537554f00b14fd69158302581d33c2f9ea0f8e2c53e6e54766dbc6cec8da6787b0154260a99925f7a802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000f0000001014a0000000000ffffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100b31b406c9f6648695a88154ae2e4f5fe87883d4ad81c2844c5571b2d91d401cdd40836e763a7c18dccb84629b0d808f7142c3175bc8231dc09bd53637efd6f2568801385ec973d34e6eef9c8c8280a9f4a114163a43a8540941ba367f0c7cb28830183018302581d4164d0b890d702b3cf4f1121e504f24b0f0d94da0e935221220f3a3702830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000040000001014a00000000004fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008ac081401431767be18972543b3ee45c6769c447fb727a1abd72bc1c12487d5c1169522857cbb8d89273847f669563af05833ecee73afa853a16de4aa5549ffea02f3280167129fe026d8aeadc959d73b44570dd18eb9c6ba313edd0a45282748302581d43dcaf1180db82fda708ce3ac7a03a6060abde13e9546c60e8cce65d02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000701014a00000000000000070101824a000000000210000001014a00000000021fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008675b634a43e39726238cfe39c9518bc3e3225cb6f5a8479bfcf2b608fba6f8524dcb80f35a8ae44b47f262f0a6620d41279f06fe0c53a739fcca01a48926fe651a3519b5b329ffbecc9f0cb908b098dd3e8845cfb99c56379e049ac465ec80683018302581d45178b66a407a4d59c0a4d6733bda2ce3f37c111b4257ec41908f4f802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000070000001014a00000000007fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100955f52f73c2dec59a637b294e50b934db5d6de29e73bbcf84e7d86a4ac41bad7b539f9817ade8916961d9dd6bf9257010d5857156e8fe6aafcf6fd068795e70bd3399b3411300c9ccc8eba0d068c10e4cfb6f4e27d195b1ead785d618eb393b98302581d4f82b62edffa3fa4e6a5c48327ce8cfb3f850db2e5abc90e955d77f002830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000230000001014a00000000023fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a32153e6271817b87d91d1cd0b727119a2eda7355ee7ef64ee9f10bf6396aed6899a5475d37d6cc51c6a741397d3685318e8e0dabec1b1994112e2c4da3262033ea18fc667dd0ead6e0a151f4d884ee644b799c05e56f502d42f22ffabbca09783018301830183018302581d581b5aa2f10c5f221e45de74a2cecafd3da076be39db0907cbf554bb02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000170000001014a00000000017fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100ad28a2bfaae6c9248ef1ea3e4f4bc6ea29101ce533b0075349bb86a88535c216ce434c9aa018b87465441dd997ed23270e2b21e126c74f16293bdba29033e858ecd50bda7be1b692a401e154eb87b65dcf0983635e578e3ea2f6d9b02c7c79dc8302581d5c76b3988ed788abc32d2ea13331bc29debc4f24d19a8f41417eaeb102830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000120000001014a00000000012fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100ae04b0b53b4f62ce4a789a6b0f0c9e66dfa5868cb2f3e0e7f628ca6fb93e4f33879a8fe47a23485f30f5a68472c4fd460bc29923b851023792437af3cc690891740a676ffbeb8d836e6ed5b2409dcb32104dde956743e51d3b0e23222ac9487b83018302581d601575e11b35c86fad26229748379d1d9693312bff16e2bca1c1cdd902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000220000001014a00000000022fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100987ce1744dba1052580903a85d6ac697f1619a9ce3119cfa8b06697013a9e2a799b2078763c3119023981410523c52030e00b5d3fd6663e85c59473366ac9846fee6fe9b415c69a96ee9f0f7768673839211f52b19fab495978f100f982d0f618302581d61b718d0b8c31db1ef09451eadd068887c1df5f37e7de0a3afc5a56a02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000010000001014a00000000001fffff0101824a00000000006000af01014a00000000006000af010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084ec5e445306312c9d94e1d1a37cb7d3a6a5a6f86bc85f30ba9bc5a261ab8a37f814786b8e1bae8aa004afb1bba510a411bde94c2a494fb2caa9155abfe0dfc19046854929f7d67726c83e572faa4b812c96196221ed549ef27fb9fb78c2e06d830183018302581d6a8f67d86ecc8307048038ad71599458c131b531dc9bb0b691940db902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000080000001014a00000000008fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008c4e7e55222f134fc3a633620701f6d25a2a5eecd71a3d49c36846ff5d5cd98d382764e81c5869e95e0feb61d132a9f20d4822f7c5bc4c8ed7cb59d52884736864478f1b0e81b1892cfa01ccc7b2fa5fff31586096217c599ff2652368b2f1948302581d806b712f189b5651e7349743820c5f45a81592464c25048e79f25cd602830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000b0000001014a0000000000bfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100af4f78ab97b3cdc76075f552e83842d5b07c4e35f9f83614b4976e70751f94ea1bc5ebec45892086f4344ea8fb3f7e3a053da28155c0ac501ab6a26ccfc60e729d0bbe91bf0772837cf2911fb4e952d066daf14ea45c08c2104cc69bf221a4f883018302581d9365a8c9f27f413060850835d1859a415c67575cd30c04a183fd096302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001e0000001014a0000000001efffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008a91b23b098aeb7dd5e525717f0c29d3967c5f4e61d0b5c7c697172e6f5682aa5e423d42077695c517aba7e3b636da940938d7d5caeee26c3c71cc6888f542c5966e60ea4d91ddb95ad0994283171097e325026bef003128b44641056c86d04a8302581d9c7d405764f197f3611b7a6d3f7756f0c5f7a7dbb02504da09d21f2902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000140000001014a00000000014fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a5d492126a99c65b09c53fe75b5ad8e24d1556a9db2bfe74dffae1816165405923e6fa2b4c58e5adbddf99575fb83b1a06736dc6e4ce20eabf54ca6ca574d3af0d14ef8ae143f9339cf16e62e72b5dfd47d1d642e731c5ee853a00fef69d70db8301830183018302581d9dfdc32362ee85e05f3f36ad947cc62cd276d7b8687d239637de118c02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000200000001014a00000000020fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a0e2dffe693d3c75cabacb68760466611df84ddd06e42954cfdf85c665841801319dcaff52cbad03bc37b64061c562920b77389679afb7f888bfc4a36b4772e6cf41374ff8714101f390056e26de88611c93c22eb90e96fe6370ac246ea6faa28302581da22bac610f4e17278d2a0f2cf83a2e2556f6594371615940334d31d302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000190000001014a00000000019fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100afd62f0314d4f866c512d95a649db5c3241d6624b15c62b2fdd3d29af2dee832e3f1af39c60c2389cc4826c181b82d01133dc9f10f727b315c5bf18de580b70a8d8800c570b99b89514922a6476fbf76591e022ca68cdb4b3610e7f642d9bfa083018302581dacc260d8fc5e1421c9aacc9bb5e1a1147aa15bf15304831ba734b9f802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000050000001014a00000000005fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100aaeeda397b35cf5473ebc1792d7aadf102d085aca490551906f73c4108df12b8478b13b73c8953c148235d0efe99427017451ce8cdd0bd9ee81ede26221c4c3ff0f49af21c6402e6d35fc4c3c61352ff3d8767a3cc8d7ee58a2b50abbbdf2dbe8302581dba488d13a5dd7649d8093fe4897df1cc7c728ab64c856a78c4b97d6a02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000110000001014a00000000011fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610088dc7b350da56b6ff41f08332636ab9d162bf3a293a65f795089ef8b8fe9a5af91c51f67e34729408bfdf21b110b7ca405c98af5c1a9ca2ff2995e27ed4e9d0325bd8fa92623e31879247ea508729cf46e0dd2804bea34f3acabe4aa4ef0b973830183018302581dba58b21125381b0567e61f3f2ecd65f37710316084ee791cdfdb4a1a02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001d0000001014a0000000001dfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100852c9ff8de8c5964d4b6209feaa6f7675a3afab47ab8ec9b67b111ddc158983fd7b034ffcce4958c60ec37040938eb1e18633d7e9a086153e53755008642bf9f87db91d6709a65f242b9e4e31dbeba64a684745a76dee8cfe6729c5ab3c52f148302581dbd26ec81a3360bc8050673531b92b27988bf2a893b506f80e40c11cf02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001a0000001014a0000000001afffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008e41463b1893989f425af308744b916d9034e83d9382b03b1e30b117fee21a4e1ff03fc59d54f4bc710a51ba04a1e21d0fd863b5329bf68ee67c6d15f82d4a673775604a1c719cb6ce200b2710e425663c7060e5e98e032beda6835c9010158d83018302581dbfca29efbb1f48b67849f2c9bab8a7856fd57882fb99c8ad497cf55202830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001b0000001014a0000000001bfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100846c395853586d94a2e546485537d4f81bb7820d5e82c274b507d592d59353a165dd8ed432e8b7c0792d90d52cf968c20c5ae06d69817d814a7ee2d54130baf49b192186890621abc70046ea9939978df172fc1cd16aded5f227cd8c27bcdb658302581dc3b96ea47e04c8977cb703f15aaf5aaaaf73d596c7be19a43a718d8b02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000030000001014a00000000003fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610087bcc7281aa5620454d5621da57502fd0ac9f10031cecc9df6715994c30ac76f212788d23dba8aa05c8ec109090561ce07c5ce7aef9f248eecd1d0a97bcab22977fb9856f4bfb5ced1fc5693320b7b6ef5fe28c69688b92a8dae61cae762eb47830183018302581dcff280e32d7f5ccd2246882f94afb20f54ca61a21765e712d43d2789028301830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000001014a00000000000000060101824a000000000000000801014a00000000000fffff01018302446e6f64658301830183018301830183018302581d24c56af1a646bdee74ba2c8cad88ba6e4f2ee098f99055bd0e9640c60283024a7075626c69635f6b65798203582c302a300506032b6570032100526742592f1e331aa13db7d1ebf224ff0b8231e0626eeefad0b629413a93e7988302581d2995ce7aeea59467fb3a634b434dcc965ba147ba2f9804ea2e8f1b5c0283024a7075626c69635f6b65798203582c302a300506032b657003210099c734e5f28c50741b04b63e87c77533d47dc2347524ed1ec8c266e429cef63683018302581d32442407acaa5ea43e62b1dac1ac20119c64cfd5c23cc0ae1508ee250283024a7075626c69635f6b65798203582c302a300506032b657003210054432c37b495e9206b46b5ce85da87a7eb2d853cd3f02feec4acf39efe9828508302581d325c033f6f1fd07e7bcb57b7ab8a24b1abf73beffd1ca17ed88cf3ab0283024a7075626c69635f6b65798203582c302a300506032b657003210059ef19e6aec7336d0912a80fe269ed4f0e8360cff9dc6fbe7a941643142bb4ff830183018302581d3c4d78ddee38b0eb2910a004c3a7362017a5c14a9346007a65829ebb0283024a7075626c69635f6b65798203582c302a300506032b657003210076f7f52d74955cc045838a6ef71b882dd5339ba058bdcf1085f893b3545d44bf8302581d3eda90ac6d378ae7c7917f94fd61c0e685b22f5ced5ad0735af250230283024a7075626c69635f6b65798203582c302a300506032b65700321000b4ca05b18b5dff4efc88badc802bccc4bae5ce2f16febe6a893904a240af36083018302581d46e3cfcd286afe6a1f4572d2350facd38f0f8647d58c499e5bc5039d0283024a7075626c69635f6b65798203582c302a300506032b65700321003f29994149099aa1b1d2dcdaabe5eda73aea6866d067e2c45b97e216532bcd338302581d53e39463ea45264875d00c508e4bb1325722a96a00053dbc2662fc5e0283024a7075626c69635f6b65798203582c302a300506032b65700321004323320684d4e1edb89bdcdee00844830a0f7de3e3cc7346e5a3868d1aef02b58301830183018302581d607eb9a00ad3b4411f5911276879c618a6895fd57fe6c9b0a879f9b00283024a7075626c69635f6b65798203582c302a300506032b6570032100a8fa77ad6c1da6d50d04fbc96bf33d0e30a67c1e8ba97fa3ce7c3d9c868a7b998302581d6ad96c153126046203336a5174a04b30f0adea457c2298b976ab674e0283024a7075626c69635f6b65798203582c302a300506032b65700321005e12ef0eae2809a5468471ee2d9745d23f20b1c0da7129fa447d96a67336be5b83018302581d8156c471c227bb551da5ff7603b22e4a1c87f711292502aef5cdae320283024a7075626c69635f6b65798203582c302a300506032b6570032100995e3dcf4b0fe927bee5172cef595b53bace86185890f052939a63d24eabf0da8302581d8465e6cc28f5be102098a7ae96264f6ec72f1c4a858b491cd60e55a50283024a7075626c69635f6b65798203582c302a300506032b6570032100dc624cca12ec1daebedd007ec838e77990a6da3f8dff968ceebf3a0e8390562f830183018302581d8cf60ae159aabf4207328d2a5524675d5c157a8aa1f80a52ec44221b0283024a7075626c69635f6b65798203582c302a300506032b6570032100d1955dd0b79c84d036422763c3a29154f31ab907ecdcfc9870db91db3e9dba7b8302581d904ebdc04493093d1f6f7d37a6a91c5fa6616ddf19771fd346cd5aeb0283024a7075626c69635f6b65798203582c302a300506032b6570032100767f31d2bb762bc9fa9b2cbe9f86504f16422f206fe4e61ec57b73a97fea242683018302581d9f00ea7b0826aa145abd4348c3656133ed84e188780f63c5151009bf0283024a7075626c69635f6b65798203582c302a300506032b65700321003dac46790dd80a38b0238ac3e1c1766fb3049a3b46d406c4ad85ccff42317a1e8302581da7835a01f618d7b552d0eae3310aebd0cac6ea2bf02865472f4546fc0283024a7075626c69635f6b65798203582c302a300506032b6570032100b80f4705b1420119acf881fb01e90f50044df72b1893cca44b4e81129e7a3e6e83018301830183018302581da7bad7420d9671f6992d64ca541ce75fe04a7c51c2561dd9aad945880283024a7075626c69635f6b65798203582c302a300506032b65700321008aa5bb79948b296c12c14131b35f9009ce331981b08c7ec57a595c6eda59d6938302581db1dee04210dded1afbc7e5d31492d7f0b1379b8fea5b203d30b3c03e0283024a7075626c69635f6b65798203582c302a300506032b6570032100031739d3139245f101349d4d2fb8cdc2e2707084d3fef1d033042d64ebd452bb83018302581db858dfb622c91c481e81e9cdbfb7ab78da5dbb7a09d2e321787a0c1a0283024a7075626c69635f6b65798203582c302a300506032b6570032100cd59f18eea954c1fc8e315099657d929b6bfb7fefadb7bb214448809f4a9d19f8302581db8e453c069995d67a5253c43ec43b4b39038d272f4c67fa9155e6e490283024a7075626c69635f6b65798203582c302a300506032b657003210079d79503838b2b01791f66c18bc7614e19d3a6aba73bae00b92bb99edeea5287830183018302581dc0588b3d010691102a6dc738ab5517afaa4f27882a3554b006d2b3920283024a7075626c69635f6b65798203582c302a300506032b6570032100879ee566edf8a11717120cca3e4b1521f07a781c6d79ddda637b3a4c770f6fc68302581dc6f9bfce466cc84184b6c0993a1bf50dabc45f0f5a591c8bcd0326bd0283024a7075626c69635f6b65798203582c302a300506032b6570032100d8e091572c325ee4edf561c8f0c85f59203f4b79e955f2adcaf39dc9037b59cb83018302581dc749a1b9b5c123bdc745883bd4901e311ae90a586a6825d52d99739e0283024a7075626c69635f6b65798203582c302a300506032b6570032100bfa1b1575803d5fb21032a69ff50a04a3394dba63c509e9a1ae9edf781b3f1748302581dcec168cc1c818e1bcbf8622c2bf05ead8f63ad21d04e0498fd64fce80283024a7075626c69635f6b65798203582c302a300506032b6570032100dc1a8cd77897793bb5b6bbbbbab2ac828f212c31ef7d8cd1a5e9da71d4368a1a8301830183018302581dcff1f1e404582ce832e51ef54dd196540af764448da6720f443d28860283024a7075626c69635f6b65798203582c302a300506032b6570032100b9f3c99d054c571483371cabababeba71a95af2f1db75a9eff5362a00168bab38302581dd0d9bd9de8bde02b0179227caefdb94de48a74231c4aa88c6bba74780283024a7075626c69635f6b65798203582c302a300506032b6570032100cd8d2ec2ff21561e2772d9e68ea249dbe874c214899c33c5503444b34786be3283018302581dd52a16f3dc32065f858393468f14585efb701a4cad05c445ba75a1dd0283024a7075626c69635f6b65798203582c302a300506032b6570032100013eb950162c07d85df53e01759052f239e953b592d13121ca5c038e28b6ea288302581dd5607c139fbf027070f48977431c08c47c96199ed4f75642774408930283024a7075626c69635f6b65798203582c302a300506032b65700321004558f956c1197f57de5eda61e88f6feb2bcd97cb69992edf3ed77326376447cc830183018302581dd7d81b675fb361616868d4f31793e064c6619a7a3fb4715d340fc2e00283024a7075626c69635f6b65798203582c302a300506032b6570032100455044dd9eaf7a0dd463d8e194f4c10bd4943cfc9beaf0e7ae4074373d1548938302581ddbcb3c89c77e2a4bb43c2244752161f5c08d759f97acdca282af8f9d0283024a7075626c69635f6b65798203582c302a300506032b6570032100b1c163e31457e5af99033c20a313371c3a00237a3bedf2ce8cdfef475db5b87583018302581ddce94d09354a1751d180df5fe0a8f352c7396bd63c338f8f91fdf5340283024a7075626c69635f6b65798203582c302a300506032b65700321000391e646f29f87929474489743d2958abd973ded1826d146b1d5cd67ae05b55d8302581ddeba05a0e095a26bf12507f792863507d32fc012be8e4f4d705dbb7e0283024a7075626c69635f6b65798203582c302a300506032b657003210004623b4767a979d854f118eaad12777b5ffa0ab0d9640708f68579cb4f6700358301830183018302581de058cf7bdd01bc75227405ebfab94752a4d2f43ff113b5ca68e4df4f0283024a7075626c69635f6b65798203582c302a300506032b657003210072de1b160077674e745a9d03e75a9432622aada8229d36d12b48ce567882e0d38302581de8373870d8066d971c415cbdaf1611bcf84cd3644d22b389de95d9e40283024a7075626c69635f6b65798203582c302a300506032b6570032100c8cf4e899a7227b656028521ba6d7c305528e120498db2e145b5448b96f824cd83018302581de85c5ec8051f35f9e3c915e3dbb3c32af6506b2a668b74c0bd003c850283024a7075626c69635f6b65798203582c302a300506032b65700321002f2e7160e775b899b3921b3a9676373a542c7ee4965d3b43952781820b880b938302581ded8915a3c359b8e16da92f2c42d6fbcd34fcc23a011770fba5734c990283024a7075626c69635f6b65798203582c302a300506032b65700321003db88746a7def775447aebeab07f35a7ab325a1e156c1d076da2ef988cf4cf8d830183018302581df032935f1185096317778e4206e8de237a7e090ba0b3289582c0fff50283024a7075626c69635f6b65798203582c302a300506032b657003210088eccdb0ceab1a41a33496dbfc7abac145d1674363c527f36707b53b354f7d238302581df2be1c26024bc9e103d662dfd167cbfe861400e7748b7778e01adc790283024a7075626c69635f6b65798203582c302a300506032b65700321006fed5c19bfcdf67f1e8d9a866f826d89cb05bdcd40cb633a5d7645f82394665c83018302581df92bb6e3332495ffd40fcf37af5fe9482b0667f3d4063d598fe8e8fa0283024a7075626c69635f6b65798203582c302a300506032b657003210038e87a8fcc24cdaad8541ad88a0d1f521a8c9bbc29379382055602ca59d226ff8302581dfd8e4151c4762d9b4b6b36e08d36a49b83e9458a5040a1dc26d63b530283024a7075626c69635f6b65798203582c302a300506032b65700321001909d5eefbb0075b3176069b7ac4a6e99934342a8fe5b3ec301d20b6cf453e5383024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100814c0e6ec71fab583b08bd81373c255c3c371b2e84863c98a4f1e08b74235d14fb5d9c0cd546d9685f913a0c0b2cc5341583bf4b4392e467db96d65b9bb4cb717112f8472e0d5a4d14505ffd7484b01291091c5f87b98883463f98091a0baaae8302581dd77b2a2f7199b9a8aec93fe6fb588661358cf12223e9a3af7b4ebac402830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000020000001014a00000000002fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361009933e1f89e8a3c4d7fdcccdbd518089e2bd4d8180a261f18d9c247a52768ebce98dc7328a39814a8f911086a1dd50cbe015e2a53b7bf78b55288893daa15c346640e8831d72a12bdedd979d28470c34823b8d1c3f4795d9c3984a247132e94fe83018302581dfc7d15b27df96b3e98731463a2af13d6e43cf426d0cb487a7120091502830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000c0000001014a0000000000cfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361009053b542dc8d758237ada280dc505846c327b0c43b7e26c0ee6f7729cdebd43639d959c10fe1aa058622437d7ec34a920035dfd55de4f40937b4c419e02b517eb2b7a6aa7f42644352202f8f4c67e726ca8f168ab588764261dbcc3a5c8113938302581dfe320f2fbbb9d49c8e6edbcc9d85ec096bf645351d95bbddf556f7db02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000130000001014a00000000013fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100b2a6741083996223f83384666740a3eacf8ce78c6d39fecdee582a5b243c158706bb215f396ba0429d2188df9ef176721306d048aaa58f6b413457dd63ef1a56de2378e71ca444201e29e490e3790098e92ee85e0142a33ef806c8388aec6baf83024474696d65820349e497bab5ceb8b6c417697369676e61747572655830aad9a5bb55b042aecbddb8ead3ac4bba7f7383ee6c46162fea9f80cac8b46516dbe901dc7e7e886ae7f4c2c8b380b5b9`,
+ mainnetApplication: `d9d9f7a364747265658301820458201974c7c7bcddc5fb14fc025206a4b146f372fc1b4fb33e6b62d1b11ff980afff83018302467375626e65748301830183018301830183018302581d033a778c6c9eac039fdda83dc90d2c12eb846de85c475e36ead6715c02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000100000001014a00000000010fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100aa544423a45fb0388c43703a159a96208cafd17f01f1e7c400676d2c69f62195f6a5bb564d564f7967047def10b48c22003f38c5d56961d0c47879f9212b93cd206620114bd9e1d4db22d04e294d37e1ff42cedf2322ebf60702c88325c606808302581d0f033c5125db4f6b32e426268df663a5ce98fe3b531d962e1a7a87fa02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001c0000001014a0000000001cfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100913f6a84f05736c2dd0b2dc3ec838e95419ae0ef426d556f50152a445b9c232495bc051cdabbd46a7bd8879b09720cbb13b3bcd265ff75567dcbf04e9ae1c3a2141229a6757605625b093c5ca34336393e5a88b78df7b0a3a7e5b9841716d0a483018302581d10b647334a5406987796b2f8b6b14cd32f0876d3fd4fc8452105832502830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000180000001014a00000000018fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084cbe7a009258947dc30983fede3b98b34cfee5e5d1ae4e1e72891590738ca9a58f9f6364b359a5448b6c5e20ee5310300e4c0c9cca29b07e2d73208f8ec6cd1fb6ca46c168c43393f9e050a05448836b0a6f5c75d2a398c999c42d7c981cb898302581d12790e7661fccd3d4fc83138dcaffd9f188e867b45ae10c8836dd0b802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000150000001014a00000000015fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610086d88ebbd2f1663e65d3a3ff07e8ee9fa420d08b9a6822919f224b8b802d5d9be150dc493f84c23e73a0cc1d2c2ee28709ff140000128fcd5dfbd7b457ef3af344766d7ff0924fe7a7f456ded77ca6de3b1b406b710c4eaed7287ab9a3527669830183018302581d17f67590355e7123aeffabce4c1bddf3a0efd53a2c2e3f6228fc3adf02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000d0000001014a0000000000dfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100850e5edfb0685d36757643be011f5d3378fef0bfb9b0ef67429912ebb9237f5028979eb33779df7c63acf59b78eba4d904c6b4abad529b9e8e2195321e287f8c51900f5b440872719c7ac56e381c8063bc6176f8e4b74d06de669493e49055678302581d1cc5ad563f1bce937c305be3d12bef627f73b727808672dc2432aef902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001f0000001014a0000000001ffffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610093907710f0f89af4b5bd35a28e0162171e2f411d11e152152e88e3da4c2079799e4eac7a3a9f3923fb63b33b68928ae91652fae5c2ccce872173632648ef4dd79ae7e8c15b9e97f132ea34a4349506d281bd66bbd0c3afdd78cbe026927a8c1683018302581d2c55b347ecf2686c83781d6c59d1b43e7b4cba8deb6c1b376107f2cd02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000060000001014a00000000006000ae0101824a00000000006000b001014a00000000006fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610090075120778eb21a530a02bcc763e7f4a192933506966af7b54c10a4d2b24de6a86b200e3440bae6267bf4c488d9a11d0472c38c1b6221198f98e4e6882ba38a5a4e3aa5afce899b7f825ed95adfa12629688073556f2747527213e8d73e40ce8302581d2d030caf397e446c03cece4fd072acce432c75b6a700592e73f5d13302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000090000001014a00000000009fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100805230c2da9687218fdfa49bddab093578c2e8a10b27d69fdda097f286abccdae2541c711e3ca771202bfc9b366bf61b17e9f1173d7c9a6eaaa907ccdba3bc86764bc1d552437c4948038e1018a9c49e444189cd55358e37a6f879d88c0a26938301830183018302581d2ecc29447b0eef6c241dcfdf7dab077093ccd6a1266be0fe9c9b127602830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000e0000001014a0000000000efffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610091541cdc7b65c4828286c911602d9438de5649d698b60fc06aec73589395d0bca71746524ed2ff17b2c8da9fbc897f0f07a40b204871b6fe96d45ef10b51d1f1d530d0679a5db82de96929805fa17c737994ebcc2312d2a25bd94747ecf8f34b8302581d2f1a9548062f52ca0e90e72a4a97cb324fa1dfb62b564ef1b29f38aa02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000160000001014a00000000016fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084698ba18ea46f2041353c98fdf6980235fab99a6f5b83c5de3bb32a7ad190ef26fd2afad2dd2e4fb5eaebc4fd177e3c11ed29fb7dab26a6909d366c185cb9d964d3ff3a8e71c0c28adfca715698f679cef6b6346106a78c9f8d3f8e9a66e88083018302581d30580a1a7643049513f8f7d6ffe6f51000570345a63160cab7784c5902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000a0000001014a0000000000afffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610085c8811b0caf15f9ad2e34f1841a7820dd1a70642e21362748bf0927c6fd67ddc0c1329fdd840e06a16d383023c4c00f062f173e628528eb801c15258e2e417d511fe4ba3c175469570cc8e1338e5457ed6b31b72b139b537554f00b14fd69158302581d33c2f9ea0f8e2c53e6e54766dbc6cec8da6787b0154260a99925f7a802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000f0000001014a0000000000ffffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100b31b406c9f6648695a88154ae2e4f5fe87883d4ad81c2844c5571b2d91d401cdd40836e763a7c18dccb84629b0d808f7142c3175bc8231dc09bd53637efd6f2568801385ec973d34e6eef9c8c8280a9f4a114163a43a8540941ba367f0c7cb28830183018302581d4164d0b890d702b3cf4f1121e504f24b0f0d94da0e935221220f3a3702830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000040000001014a00000000004fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008ac081401431767be18972543b3ee45c6769c447fb727a1abd72bc1c12487d5c1169522857cbb8d89273847f669563af05833ecee73afa853a16de4aa5549ffea02f3280167129fe026d8aeadc959d73b44570dd18eb9c6ba313edd0a45282748302581d43dcaf1180db82fda708ce3ac7a03a6060abde13e9546c60e8cce65d02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000701014a00000000000000070101824a000000000210000001014a00000000021fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008675b634a43e39726238cfe39c9518bc3e3225cb6f5a8479bfcf2b608fba6f8524dcb80f35a8ae44b47f262f0a6620d41279f06fe0c53a739fcca01a48926fe651a3519b5b329ffbecc9f0cb908b098dd3e8845cfb99c56379e049ac465ec80683018302581d45178b66a407a4d59c0a4d6733bda2ce3f37c111b4257ec41908f4f802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000070000001014a00000000007fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100955f52f73c2dec59a637b294e50b934db5d6de29e73bbcf84e7d86a4ac41bad7b539f9817ade8916961d9dd6bf9257010d5857156e8fe6aafcf6fd068795e70bd3399b3411300c9ccc8eba0d068c10e4cfb6f4e27d195b1ead785d618eb393b98302581d4f82b62edffa3fa4e6a5c48327ce8cfb3f850db2e5abc90e955d77f002830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000230000001014a00000000023fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a32153e6271817b87d91d1cd0b727119a2eda7355ee7ef64ee9f10bf6396aed6899a5475d37d6cc51c6a741397d3685318e8e0dabec1b1994112e2c4da3262033ea18fc667dd0ead6e0a151f4d884ee644b799c05e56f502d42f22ffabbca09783018301830183018302581d581b5aa2f10c5f221e45de74a2cecafd3da076be39db0907cbf554bb02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000170000001014a00000000017fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100ad28a2bfaae6c9248ef1ea3e4f4bc6ea29101ce533b0075349bb86a88535c216ce434c9aa018b87465441dd997ed23270e2b21e126c74f16293bdba29033e858ecd50bda7be1b692a401e154eb87b65dcf0983635e578e3ea2f6d9b02c7c79dc8302581d5c76b3988ed788abc32d2ea13331bc29debc4f24d19a8f41417eaeb102830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000120000001014a00000000012fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100ae04b0b53b4f62ce4a789a6b0f0c9e66dfa5868cb2f3e0e7f628ca6fb93e4f33879a8fe47a23485f30f5a68472c4fd460bc29923b851023792437af3cc690891740a676ffbeb8d836e6ed5b2409dcb32104dde956743e51d3b0e23222ac9487b83018302581d601575e11b35c86fad26229748379d1d9693312bff16e2bca1c1cdd902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000220000001014a00000000022fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100987ce1744dba1052580903a85d6ac697f1619a9ce3119cfa8b06697013a9e2a799b2078763c3119023981410523c52030e00b5d3fd6663e85c59473366ac9846fee6fe9b415c69a96ee9f0f7768673839211f52b19fab495978f100f982d0f618302581d61b718d0b8c31db1ef09451eadd068887c1df5f37e7de0a3afc5a56a02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000010000001014a00000000001fffff0101824a00000000006000af01014a00000000006000af010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084ec5e445306312c9d94e1d1a37cb7d3a6a5a6f86bc85f30ba9bc5a261ab8a37f814786b8e1bae8aa004afb1bba510a411bde94c2a494fb2caa9155abfe0dfc19046854929f7d67726c83e572faa4b812c96196221ed549ef27fb9fb78c2e06d830183018302581d6a8f67d86ecc8307048038ad71599458c131b531dc9bb0b691940db902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000080000001014a00000000008fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008c4e7e55222f134fc3a633620701f6d25a2a5eecd71a3d49c36846ff5d5cd98d382764e81c5869e95e0feb61d132a9f20d4822f7c5bc4c8ed7cb59d52884736864478f1b0e81b1892cfa01ccc7b2fa5fff31586096217c599ff2652368b2f1948302581d806b712f189b5651e7349743820c5f45a81592464c25048e79f25cd602830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000b0000001014a0000000000bfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100af4f78ab97b3cdc76075f552e83842d5b07c4e35f9f83614b4976e70751f94ea1bc5ebec45892086f4344ea8fb3f7e3a053da28155c0ac501ab6a26ccfc60e729d0bbe91bf0772837cf2911fb4e952d066daf14ea45c08c2104cc69bf221a4f883018302581d9365a8c9f27f413060850835d1859a415c67575cd30c04a183fd096302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001e0000001014a0000000001efffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008a91b23b098aeb7dd5e525717f0c29d3967c5f4e61d0b5c7c697172e6f5682aa5e423d42077695c517aba7e3b636da940938d7d5caeee26c3c71cc6888f542c5966e60ea4d91ddb95ad0994283171097e325026bef003128b44641056c86d04a8302581d9c7d405764f197f3611b7a6d3f7756f0c5f7a7dbb02504da09d21f2902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000140000001014a00000000014fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a5d492126a99c65b09c53fe75b5ad8e24d1556a9db2bfe74dffae1816165405923e6fa2b4c58e5adbddf99575fb83b1a06736dc6e4ce20eabf54ca6ca574d3af0d14ef8ae143f9339cf16e62e72b5dfd47d1d642e731c5ee853a00fef69d70db8301830183018302581d9dfdc32362ee85e05f3f36ad947cc62cd276d7b8687d239637de118c02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000200000001014a00000000020fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a0e2dffe693d3c75cabacb68760466611df84ddd06e42954cfdf85c665841801319dcaff52cbad03bc37b64061c562920b77389679afb7f888bfc4a36b4772e6cf41374ff8714101f390056e26de88611c93c22eb90e96fe6370ac246ea6faa28302581da22bac610f4e17278d2a0f2cf83a2e2556f6594371615940334d31d302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000190000001014a00000000019fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100afd62f0314d4f866c512d95a649db5c3241d6624b15c62b2fdd3d29af2dee832e3f1af39c60c2389cc4826c181b82d01133dc9f10f727b315c5bf18de580b70a8d8800c570b99b89514922a6476fbf76591e022ca68cdb4b3610e7f642d9bfa083018302581dacc260d8fc5e1421c9aacc9bb5e1a1147aa15bf15304831ba734b9f802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000050000001014a00000000005fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100aaeeda397b35cf5473ebc1792d7aadf102d085aca490551906f73c4108df12b8478b13b73c8953c148235d0efe99427017451ce8cdd0bd9ee81ede26221c4c3ff0f49af21c6402e6d35fc4c3c61352ff3d8767a3cc8d7ee58a2b50abbbdf2dbe8302581dba488d13a5dd7649d8093fe4897df1cc7c728ab64c856a78c4b97d6a02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000110000001014a00000000011fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610088dc7b350da56b6ff41f08332636ab9d162bf3a293a65f795089ef8b8fe9a5af91c51f67e34729408bfdf21b110b7ca405c98af5c1a9ca2ff2995e27ed4e9d0325bd8fa92623e31879247ea508729cf46e0dd2804bea34f3acabe4aa4ef0b973830183018302581dba58b21125381b0567e61f3f2ecd65f37710316084ee791cdfdb4a1a02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001d0000001014a0000000001dfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100852c9ff8de8c5964d4b6209feaa6f7675a3afab47ab8ec9b67b111ddc158983fd7b034ffcce4958c60ec37040938eb1e18633d7e9a086153e53755008642bf9f87db91d6709a65f242b9e4e31dbeba64a684745a76dee8cfe6729c5ab3c52f148302581dbd26ec81a3360bc8050673531b92b27988bf2a893b506f80e40c11cf02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001a0000001014a0000000001afffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008e41463b1893989f425af308744b916d9034e83d9382b03b1e30b117fee21a4e1ff03fc59d54f4bc710a51ba04a1e21d0fd863b5329bf68ee67c6d15f82d4a673775604a1c719cb6ce200b2710e425663c7060e5e98e032beda6835c9010158d83018302581dbfca29efbb1f48b67849f2c9bab8a7856fd57882fb99c8ad497cf55202830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001b0000001014a0000000001bfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100846c395853586d94a2e546485537d4f81bb7820d5e82c274b507d592d59353a165dd8ed432e8b7c0792d90d52cf968c20c5ae06d69817d814a7ee2d54130baf49b192186890621abc70046ea9939978df172fc1cd16aded5f227cd8c27bcdb658302581dc3b96ea47e04c8977cb703f15aaf5aaaaf73d596c7be19a43a718d8b028301830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000030000001014a00000000003fffff01018302476d65747269637382035823a4001901c3011b00000002547ccc1702a2001b00000dc43d2206f80100031a0003649883018302446e6f646583018301830183018302581d8554fbd9569af03e79ccabb8e0df5376da7d9c52c6116d477dc8e7a80283024a7075626c69635f6b65798203582c302a300506032b65700321005b0bdf0329932ab0a78fa7192ad76cf37d67eb2024739774d3b67da7799ebc9c8302581d88729cd45ca059e2af291c1521462cad7d479445170c68b050e4c3ba0283024a7075626c69635f6b65798203582c302a300506032b65700321009776d25542873dafb8099303d1fca8e4aa344e73cf5a3d7df5b40f9c8ed5a08583018302581d8e64078481caf73482c8b734e37523c8e6a0767882bd3a21b7a93c250283024a7075626c69635f6b65798203582c302a300506032b6570032100e5a9296571826cc3be977490296405ae9da1da7d59cce1642421bc19804cc3108302581d9717b99c1bf40cb84611aee69e92e7715eb0a90221aac29be62d7e3d0283024a7075626c69635f6b65798203582c302a300506032b6570032100b761a93e418ab326d2d106d9137268d407f7c8a743127e2833899933337eb09b830183018302581d9b5c9ed769f8dbd6210f4680cadb73beb3852e76ac43e9ea2dd35a280283024a7075626c69635f6b65798203582c302a300506032b6570032100afd56377478dc711cbfe043022423d9f7f7decb709de7501545923274186883f8302581da142f96f269cac297b0d7d651c5a43470d78322e5b5369cd5d04a9ce0283024a7075626c69635f6b65798203582c302a300506032b6570032100ce76939540cac8de3475329517c684e0562fb6cbad1db67fb60362808bdaf46283018302581da870dc773b62cae3c31ca1905ff7c7242a4460bf18594dcc12641c170283024a7075626c69635f6b65798203582c302a300506032b65700321001645a7cb7f3980dd6f9ca6ca0966a4d4bde9d57d90df0f10fc31eac960a8ab418302581db506e1548dbaa9a0d840282a3c5a608a7d90a9435a8d391cfb028c660283024a7075626c69635f6b65798203582c302a300506032b65700321000c441fada59fea1cf21ebc157392338ca56775011c4c5630782823e2a7938c8f8301830183018302581dbe9c9341fcf1ce0cb07e809686431958cf497725f37868f3ef990e020283024a7075626c69635f6b65798203582c302a300506032b6570032100f408b362fc92255a4776666179eba4b9dfbd6d3b9f6b87b3abb80f726878e0a98302581dcc84fb1d9f904589c629c10b052a1214318029e46af6b682c70d52530283024a7075626c69635f6b65798203582c302a300506032b6570032100cab5efd3205fa4b3409b6f5e421ebd776dd36ea6108820c624478016df9c6a2083018302581dd972b647954b754c516162ef7eb651cb3d8d6e264d1c289a76f46fa80283024a7075626c69635f6b65798203582c302a300506032b6570032100e650a1cc4bf264cdc80442d33d7bd00e3de1f15ddd48c7ac0f2fe582f599d9548302581de7d8693d4f6322560cc8b0cab4280f40c1a1957de51576893a11ea9d0283024a7075626c69635f6b65798203582c302a300506032b6570032100be0759d30172a9dfdcc2e11b92e8daf1753c45f126b8413c8e57e621b5626d378302581dfe9763f6e077ef3d42f2225c16bc1ec040f97be6add75cff99b24e020283024a7075626c69635f6b65798203582c302a300506032b65700321006b8ef72b0efb4ef38dc957097cb26dfcf24b083dd6b2b5fcd5269657cd8e59a783024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610087bcc7281aa5620454d5621da57502fd0ac9f10031cecc9df6715994c30ac76f212788d23dba8aa05c8ec109090561ce07c5ce7aef9f248eecd1d0a97bcab22977fb9856f4bfb5ced1fc5693320b7b6ef5fe28c69688b92a8dae61cae762eb47830183018302581dcff280e32d7f5ccd2246882f94afb20f54ca61a21765e712d43d278902830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000001014a00000000000000060101824a000000000000000801014a00000000000fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100814c0e6ec71fab583b08bd81373c255c3c371b2e84863c98a4f1e08b74235d14fb5d9c0cd546d9685f913a0c0b2cc5341583bf4b4392e467db96d65b9bb4cb717112f8472e0d5a4d14505ffd7484b01291091c5f87b98883463f98091a0baaae8302581dd77b2a2f7199b9a8aec93fe6fb588661358cf12223e9a3af7b4ebac402830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000020000001014a00000000002fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361009933e1f89e8a3c4d7fdcccdbd518089e2bd4d8180a261f18d9c247a52768ebce98dc7328a39814a8f911086a1dd50cbe015e2a53b7bf78b55288893daa15c346640e8831d72a12bdedd979d28470c34823b8d1c3f4795d9c3984a247132e94fe83018302581dfc7d15b27df96b3e98731463a2af13d6e43cf426d0cb487a7120091502830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000c0000001014a0000000000cfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361009053b542dc8d758237ada280dc505846c327b0c43b7e26c0ee6f7729cdebd43639d959c10fe1aa058622437d7ec34a920035dfd55de4f40937b4c419e02b517eb2b7a6aa7f42644352202f8f4c67e726ca8f168ab588764261dbcc3a5c8113938302581dfe320f2fbbb9d49c8e6edbcc9d85ec096bf645351d95bbddf556f7db02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000130000001014a00000000013fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100b2a6741083996223f83384666740a3eacf8ce78c6d39fecdee582a5b243c158706bb215f396ba0429d2188df9ef176721306d048aaa58f6b413457dd63ef1a56de2378e71ca444201e29e490e3790098e92ee85e0142a33ef806c8388aec6baf83024474696d65820349d6b2cda6e896b6c417697369676e61747572655830ab3f413732a43a06f1fb9b4b33ca93000f82694ce8939d2f09752d32bee0c48059bcfefb1a78a0c70c6000498b90fbb36a64656c65676174696f6ea2697375626e65745f6964581dc3b96ea47e04c8977cb703f15aaf5aaaaf73d596c7be19a43a718d8b026b6365727469666963617465590257d9d9f7a264747265658301820458201e757e29e560315f8b01e8fd15ec9d0018612d65cc1d7ecddc3c4219e4fcb71083018302467375626e657483018301820458205363d9921c468ac1a0c0475124a1703b0eeab44f12afe4bb721a059eabfbccde8301820458201715cf8e070b9844e1cc2d88b020cddf01463fbdb1a63351c7a2f134b4d22c7883018204582056de5b2239f855d965786fa8fc032c85f07dcd595e7fe19259eadd0808967fbc830182045820ad16bbe070678ae81807dc5a10506cd58ec328abae4a43b3ee93ca27a4062d4b8301820458204d4e6ae2db005b61fa587835203df74b00b2a34626fa1b1d895eb20a899599a08302581dc3b96ea47e04c8977cb703f15aaf5aaaaf73d596c7be19a43a718d8b02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000030000001014a00000000003fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610087bcc7281aa5620454d5621da57502fd0ac9f10031cecc9df6715994c30ac76f212788d23dba8aa05c8ec109090561ce07c5ce7aef9f248eecd1d0a97bcab22977fb9856f4bfb5ced1fc5693320b7b6ef5fe28c69688b92a8dae61cae762eb478204582053500b9323caa4e30ecfb70fba000e908670ef4dbb1d8cae818051be76656ccb83024474696d65820349bfbfabb4f6eaadc417697369676e617475726558308be7643a5542a0eb4c031c2945bc71fa46aaf4c5d02151dad26b53f42433e4ef8150ea7bcd2bb8c86db4a53d49e58c3d`,
+ localSystem: `d9d9f7a264747265658301820458201d7d7679b4b9276bc98296be92a3e0af4b294ec8642a00b6e930a83b4bc65bc083018302467375626e65748301830183018301830183018302581d033a778c6c9eac039fdda83dc90d2c12eb846de85c475e36ead6715c02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000100000001014a00000000010fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100aa544423a45fb0388c43703a159a96208cafd17f01f1e7c400676d2c69f62195f6a5bb564d564f7967047def10b48c22003f38c5d56961d0c47879f9212b93cd206620114bd9e1d4db22d04e294d37e1ff42cedf2322ebf60702c88325c606808302581d0f033c5125db4f6b32e426268df663a5ce98fe3b531d962e1a7a87fa02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001c0000001014a0000000001cfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100913f6a84f05736c2dd0b2dc3ec838e95419ae0ef426d556f50152a445b9c232495bc051cdabbd46a7bd8879b09720cbb13b3bcd265ff75567dcbf04e9ae1c3a2141229a6757605625b093c5ca34336393e5a88b78df7b0a3a7e5b9841716d0a483018302581d10b647334a5406987796b2f8b6b14cd32f0876d3fd4fc8452105832502830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000180000001014a00000000018fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084cbe7a009258947dc30983fede3b98b34cfee5e5d1ae4e1e72891590738ca9a58f9f6364b359a5448b6c5e20ee5310300e4c0c9cca29b07e2d73208f8ec6cd1fb6ca46c168c43393f9e050a05448836b0a6f5c75d2a398c999c42d7c981cb898302581d12790e7661fccd3d4fc83138dcaffd9f188e867b45ae10c8836dd0b802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000150000001014a00000000015fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610086d88ebbd2f1663e65d3a3ff07e8ee9fa420d08b9a6822919f224b8b802d5d9be150dc493f84c23e73a0cc1d2c2ee28709ff140000128fcd5dfbd7b457ef3af344766d7ff0924fe7a7f456ded77ca6de3b1b406b710c4eaed7287ab9a3527669830183018302581d17f67590355e7123aeffabce4c1bddf3a0efd53a2c2e3f6228fc3adf02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000d0000001014a0000000000dfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100850e5edfb0685d36757643be011f5d3378fef0bfb9b0ef67429912ebb9237f5028979eb33779df7c63acf59b78eba4d904c6b4abad529b9e8e2195321e287f8c51900f5b440872719c7ac56e381c8063bc6176f8e4b74d06de669493e49055678302581d1cc5ad563f1bce937c305be3d12bef627f73b727808672dc2432aef902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001f0000001014a0000000001ffffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610093907710f0f89af4b5bd35a28e0162171e2f411d11e152152e88e3da4c2079799e4eac7a3a9f3923fb63b33b68928ae91652fae5c2ccce872173632648ef4dd79ae7e8c15b9e97f132ea34a4349506d281bd66bbd0c3afdd78cbe026927a8c1683018302581d2c55b347ecf2686c83781d6c59d1b43e7b4cba8deb6c1b376107f2cd02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000060000001014a00000000006000ae0101824a00000000006000b001014a00000000006fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610090075120778eb21a530a02bcc763e7f4a192933506966af7b54c10a4d2b24de6a86b200e3440bae6267bf4c488d9a11d0472c38c1b6221198f98e4e6882ba38a5a4e3aa5afce899b7f825ed95adfa12629688073556f2747527213e8d73e40ce8302581d2d030caf397e446c03cece4fd072acce432c75b6a700592e73f5d13302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000090000001014a00000000009fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100805230c2da9687218fdfa49bddab093578c2e8a10b27d69fdda097f286abccdae2541c711e3ca771202bfc9b366bf61b17e9f1173d7c9a6eaaa907ccdba3bc86764bc1d552437c4948038e1018a9c49e444189cd55358e37a6f879d88c0a26938301830183018302581d2ecc29447b0eef6c241dcfdf7dab077093ccd6a1266be0fe9c9b127602830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000e0000001014a0000000000efffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610091541cdc7b65c4828286c911602d9438de5649d698b60fc06aec73589395d0bca71746524ed2ff17b2c8da9fbc897f0f07a40b204871b6fe96d45ef10b51d1f1d530d0679a5db82de96929805fa17c737994ebcc2312d2a25bd94747ecf8f34b8302581d2f1a9548062f52ca0e90e72a4a97cb324fa1dfb62b564ef1b29f38aa02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000160000001014a00000000016fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084698ba18ea46f2041353c98fdf6980235fab99a6f5b83c5de3bb32a7ad190ef26fd2afad2dd2e4fb5eaebc4fd177e3c11ed29fb7dab26a6909d366c185cb9d964d3ff3a8e71c0c28adfca715698f679cef6b6346106a78c9f8d3f8e9a66e88083018302581d30580a1a7643049513f8f7d6ffe6f51000570345a63160cab7784c5902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000a0000001014a0000000000afffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610085c8811b0caf15f9ad2e34f1841a7820dd1a70642e21362748bf0927c6fd67ddc0c1329fdd840e06a16d383023c4c00f062f173e628528eb801c15258e2e417d511fe4ba3c175469570cc8e1338e5457ed6b31b72b139b537554f00b14fd69158302581d33c2f9ea0f8e2c53e6e54766dbc6cec8da6787b0154260a99925f7a802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000f0000001014a0000000000ffffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100b31b406c9f6648695a88154ae2e4f5fe87883d4ad81c2844c5571b2d91d401cdd40836e763a7c18dccb84629b0d808f7142c3175bc8231dc09bd53637efd6f2568801385ec973d34e6eef9c8c8280a9f4a114163a43a8540941ba367f0c7cb28830183018302581d4164d0b890d702b3cf4f1121e504f24b0f0d94da0e935221220f3a3702830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000040000001014a00000000004fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008ac081401431767be18972543b3ee45c6769c447fb727a1abd72bc1c12487d5c1169522857cbb8d89273847f669563af05833ecee73afa853a16de4aa5549ffea02f3280167129fe026d8aeadc959d73b44570dd18eb9c6ba313edd0a45282748302581d43dcaf1180db82fda708ce3ac7a03a6060abde13e9546c60e8cce65d02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000701014a00000000000000070101824a000000000210000001014a00000000021fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008675b634a43e39726238cfe39c9518bc3e3225cb6f5a8479bfcf2b608fba6f8524dcb80f35a8ae44b47f262f0a6620d41279f06fe0c53a739fcca01a48926fe651a3519b5b329ffbecc9f0cb908b098dd3e8845cfb99c56379e049ac465ec80683018302581d45178b66a407a4d59c0a4d6733bda2ce3f37c111b4257ec41908f4f802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000070000001014a00000000007fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100955f52f73c2dec59a637b294e50b934db5d6de29e73bbcf84e7d86a4ac41bad7b539f9817ade8916961d9dd6bf9257010d5857156e8fe6aafcf6fd068795e70bd3399b3411300c9ccc8eba0d068c10e4cfb6f4e27d195b1ead785d618eb393b98302581d4f82b62edffa3fa4e6a5c48327ce8cfb3f850db2e5abc90e955d77f002830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000230000001014a00000000023fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a32153e6271817b87d91d1cd0b727119a2eda7355ee7ef64ee9f10bf6396aed6899a5475d37d6cc51c6a741397d3685318e8e0dabec1b1994112e2c4da3262033ea18fc667dd0ead6e0a151f4d884ee644b799c05e56f502d42f22ffabbca09783018301830183018302581d581b5aa2f10c5f221e45de74a2cecafd3da076be39db0907cbf554bb02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000170000001014a00000000017fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100ad28a2bfaae6c9248ef1ea3e4f4bc6ea29101ce533b0075349bb86a88535c216ce434c9aa018b87465441dd997ed23270e2b21e126c74f16293bdba29033e858ecd50bda7be1b692a401e154eb87b65dcf0983635e578e3ea2f6d9b02c7c79dc8302581d5c76b3988ed788abc32d2ea13331bc29debc4f24d19a8f41417eaeb102830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000120000001014a00000000012fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100ae04b0b53b4f62ce4a789a6b0f0c9e66dfa5868cb2f3e0e7f628ca6fb93e4f33879a8fe47a23485f30f5a68472c4fd460bc29923b851023792437af3cc690891740a676ffbeb8d836e6ed5b2409dcb32104dde956743e51d3b0e23222ac9487b83018302581d601575e11b35c86fad26229748379d1d9693312bff16e2bca1c1cdd902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000220000001014a00000000022fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100987ce1744dba1052580903a85d6ac697f1619a9ce3119cfa8b06697013a9e2a799b2078763c3119023981410523c52030e00b5d3fd6663e85c59473366ac9846fee6fe9b415c69a96ee9f0f7768673839211f52b19fab495978f100f982d0f618302581d61b718d0b8c31db1ef09451eadd068887c1df5f37e7de0a3afc5a56a02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000010000001014a00000000001fffff0101824a00000000006000af01014a00000000006000af010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084ec5e445306312c9d94e1d1a37cb7d3a6a5a6f86bc85f30ba9bc5a261ab8a37f814786b8e1bae8aa004afb1bba510a411bde94c2a494fb2caa9155abfe0dfc19046854929f7d67726c83e572faa4b812c96196221ed549ef27fb9fb78c2e06d830183018302581d6a8f67d86ecc8307048038ad71599458c131b531dc9bb0b691940db902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000080000001014a00000000008fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008c4e7e55222f134fc3a633620701f6d25a2a5eecd71a3d49c36846ff5d5cd98d382764e81c5869e95e0feb61d132a9f20d4822f7c5bc4c8ed7cb59d52884736864478f1b0e81b1892cfa01ccc7b2fa5fff31586096217c599ff2652368b2f1948302581d806b712f189b5651e7349743820c5f45a81592464c25048e79f25cd602830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000b0000001014a0000000000bfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100af4f78ab97b3cdc76075f552e83842d5b07c4e35f9f83614b4976e70751f94ea1bc5ebec45892086f4344ea8fb3f7e3a053da28155c0ac501ab6a26ccfc60e729d0bbe91bf0772837cf2911fb4e952d066daf14ea45c08c2104cc69bf221a4f883018302581d9365a8c9f27f413060850835d1859a415c67575cd30c04a183fd096302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001e0000001014a0000000001efffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008a91b23b098aeb7dd5e525717f0c29d3967c5f4e61d0b5c7c697172e6f5682aa5e423d42077695c517aba7e3b636da940938d7d5caeee26c3c71cc6888f542c5966e60ea4d91ddb95ad0994283171097e325026bef003128b44641056c86d04a8302581d9c7d405764f197f3611b7a6d3f7756f0c5f7a7dbb02504da09d21f2902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000140000001014a00000000014fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a5d492126a99c65b09c53fe75b5ad8e24d1556a9db2bfe74dffae1816165405923e6fa2b4c58e5adbddf99575fb83b1a06736dc6e4ce20eabf54ca6ca574d3af0d14ef8ae143f9339cf16e62e72b5dfd47d1d642e731c5ee853a00fef69d70db8301830183018302581d9dfdc32362ee85e05f3f36ad947cc62cd276d7b8687d239637de118c02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000200000001014a00000000020fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a0e2dffe693d3c75cabacb68760466611df84ddd06e42954cfdf85c665841801319dcaff52cbad03bc37b64061c562920b77389679afb7f888bfc4a36b4772e6cf41374ff8714101f390056e26de88611c93c22eb90e96fe6370ac246ea6faa28302581da22bac610f4e17278d2a0f2cf83a2e2556f6594371615940334d31d302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000190000001014a00000000019fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100afd62f0314d4f866c512d95a649db5c3241d6624b15c62b2fdd3d29af2dee832e3f1af39c60c2389cc4826c181b82d01133dc9f10f727b315c5bf18de580b70a8d8800c570b99b89514922a6476fbf76591e022ca68cdb4b3610e7f642d9bfa083018302581dacc260d8fc5e1421c9aacc9bb5e1a1147aa15bf15304831ba734b9f802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000050000001014a00000000005fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100aaeeda397b35cf5473ebc1792d7aadf102d085aca490551906f73c4108df12b8478b13b73c8953c148235d0efe99427017451ce8cdd0bd9ee81ede26221c4c3ff0f49af21c6402e6d35fc4c3c61352ff3d8767a3cc8d7ee58a2b50abbbdf2dbe8302581dba488d13a5dd7649d8093fe4897df1cc7c728ab64c856a78c4b97d6a02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000110000001014a00000000011fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610088dc7b350da56b6ff41f08332636ab9d162bf3a293a65f795089ef8b8fe9a5af91c51f67e34729408bfdf21b110b7ca405c98af5c1a9ca2ff2995e27ed4e9d0325bd8fa92623e31879247ea508729cf46e0dd2804bea34f3acabe4aa4ef0b973830183018302581dba58b21125381b0567e61f3f2ecd65f37710316084ee791cdfdb4a1a02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001d0000001014a0000000001dfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100852c9ff8de8c5964d4b6209feaa6f7675a3afab47ab8ec9b67b111ddc158983fd7b034ffcce4958c60ec37040938eb1e18633d7e9a086153e53755008642bf9f87db91d6709a65f242b9e4e31dbeba64a684745a76dee8cfe6729c5ab3c52f148302581dbd26ec81a3360bc8050673531b92b27988bf2a893b506f80e40c11cf02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001a0000001014a0000000001afffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008e41463b1893989f425af308744b916d9034e83d9382b03b1e30b117fee21a4e1ff03fc59d54f4bc710a51ba04a1e21d0fd863b5329bf68ee67c6d15f82d4a673775604a1c719cb6ce200b2710e425663c7060e5e98e032beda6835c9010158d83018302581dbfca29efbb1f48b67849f2c9bab8a7856fd57882fb99c8ad497cf55202830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001b0000001014a0000000001bfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100846c395853586d94a2e546485537d4f81bb7820d5e82c274b507d592d59353a165dd8ed432e8b7c0792d90d52cf968c20c5ae06d69817d814a7ee2d54130baf49b192186890621abc70046ea9939978df172fc1cd16aded5f227cd8c27bcdb658302581dc3b96ea47e04c8977cb703f15aaf5aaaaf73d596c7be19a43a718d8b02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000030000001014a00000000003fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610087bcc7281aa5620454d5621da57502fd0ac9f10031cecc9df6715994c30ac76f212788d23dba8aa05c8ec109090561ce07c5ce7aef9f248eecd1d0a97bcab22977fb9856f4bfb5ced1fc5693320b7b6ef5fe28c69688b92a8dae61cae762eb47830183018302581dcff280e32d7f5ccd2246882f94afb20f54ca61a21765e712d43d2789028301830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000001014a00000000000000060101824a000000000000000801014a00000000000fffff01018302446e6f64658301830183018301830183018302581d24c56af1a646bdee74ba2c8cad88ba6e4f2ee098f99055bd0e9640c60283024a7075626c69635f6b65798203582c302a300506032b6570032100526742592f1e331aa13db7d1ebf224ff0b8231e0626eeefad0b629413a93e7988302581d2995ce7aeea59467fb3a634b434dcc965ba147ba2f9804ea2e8f1b5c0283024a7075626c69635f6b65798203582c302a300506032b657003210099c734e5f28c50741b04b63e87c77533d47dc2347524ed1ec8c266e429cef63683018302581d32442407acaa5ea43e62b1dac1ac20119c64cfd5c23cc0ae1508ee250283024a7075626c69635f6b65798203582c302a300506032b657003210054432c37b495e9206b46b5ce85da87a7eb2d853cd3f02feec4acf39efe9828508302581d325c033f6f1fd07e7bcb57b7ab8a24b1abf73beffd1ca17ed88cf3ab0283024a7075626c69635f6b65798203582c302a300506032b657003210059ef19e6aec7336d0912a80fe269ed4f0e8360cff9dc6fbe7a941643142bb4ff830183018302581d3c4d78ddee38b0eb2910a004c3a7362017a5c14a9346007a65829ebb0283024a7075626c69635f6b65798203582c302a300506032b657003210076f7f52d74955cc045838a6ef71b882dd5339ba058bdcf1085f893b3545d44bf8302581d3eda90ac6d378ae7c7917f94fd61c0e685b22f5ced5ad0735af250230283024a7075626c69635f6b65798203582c302a300506032b65700321000b4ca05b18b5dff4efc88badc802bccc4bae5ce2f16febe6a893904a240af36083018302581d46e3cfcd286afe6a1f4572d2350facd38f0f8647d58c499e5bc5039d0283024a7075626c69635f6b65798203582c302a300506032b65700321003f29994149099aa1b1d2dcdaabe5eda73aea6866d067e2c45b97e216532bcd338302581d53e39463ea45264875d00c508e4bb1325722a96a00053dbc2662fc5e0283024a7075626c69635f6b65798203582c302a300506032b65700321004323320684d4e1edb89bdcdee00844830a0f7de3e3cc7346e5a3868d1aef02b58301830183018302581d607eb9a00ad3b4411f5911276879c618a6895fd57fe6c9b0a879f9b00283024a7075626c69635f6b65798203582c302a300506032b6570032100a8fa77ad6c1da6d50d04fbc96bf33d0e30a67c1e8ba97fa3ce7c3d9c868a7b998302581d6ad96c153126046203336a5174a04b30f0adea457c2298b976ab674e0283024a7075626c69635f6b65798203582c302a300506032b65700321005e12ef0eae2809a5468471ee2d9745d23f20b1c0da7129fa447d96a67336be5b83018302581d8156c471c227bb551da5ff7603b22e4a1c87f711292502aef5cdae320283024a7075626c69635f6b65798203582c302a300506032b6570032100995e3dcf4b0fe927bee5172cef595b53bace86185890f052939a63d24eabf0da8302581d8465e6cc28f5be102098a7ae96264f6ec72f1c4a858b491cd60e55a50283024a7075626c69635f6b65798203582c302a300506032b6570032100dc624cca12ec1daebedd007ec838e77990a6da3f8dff968ceebf3a0e8390562f830183018302581d8cf60ae159aabf4207328d2a5524675d5c157a8aa1f80a52ec44221b0283024a7075626c69635f6b65798203582c302a300506032b6570032100d1955dd0b79c84d036422763c3a29154f31ab907ecdcfc9870db91db3e9dba7b8302581d904ebdc04493093d1f6f7d37a6a91c5fa6616ddf19771fd346cd5aeb0283024a7075626c69635f6b65798203582c302a300506032b6570032100767f31d2bb762bc9fa9b2cbe9f86504f16422f206fe4e61ec57b73a97fea242683018302581d9f00ea7b0826aa145abd4348c3656133ed84e188780f63c5151009bf0283024a7075626c69635f6b65798203582c302a300506032b65700321003dac46790dd80a38b0238ac3e1c1766fb3049a3b46d406c4ad85ccff42317a1e8302581da7835a01f618d7b552d0eae3310aebd0cac6ea2bf02865472f4546fc0283024a7075626c69635f6b65798203582c302a300506032b6570032100b80f4705b1420119acf881fb01e90f50044df72b1893cca44b4e81129e7a3e6e83018301830183018302581da7bad7420d9671f6992d64ca541ce75fe04a7c51c2561dd9aad945880283024a7075626c69635f6b65798203582c302a300506032b65700321008aa5bb79948b296c12c14131b35f9009ce331981b08c7ec57a595c6eda59d6938302581db1dee04210dded1afbc7e5d31492d7f0b1379b8fea5b203d30b3c03e0283024a7075626c69635f6b65798203582c302a300506032b6570032100031739d3139245f101349d4d2fb8cdc2e2707084d3fef1d033042d64ebd452bb83018302581db858dfb622c91c481e81e9cdbfb7ab78da5dbb7a09d2e321787a0c1a0283024a7075626c69635f6b65798203582c302a300506032b6570032100cd59f18eea954c1fc8e315099657d929b6bfb7fefadb7bb214448809f4a9d19f8302581db8e453c069995d67a5253c43ec43b4b39038d272f4c67fa9155e6e490283024a7075626c69635f6b65798203582c302a300506032b657003210079d79503838b2b01791f66c18bc7614e19d3a6aba73bae00b92bb99edeea5287830183018302581dc0588b3d010691102a6dc738ab5517afaa4f27882a3554b006d2b3920283024a7075626c69635f6b65798203582c302a300506032b6570032100879ee566edf8a11717120cca3e4b1521f07a781c6d79ddda637b3a4c770f6fc68302581dc6f9bfce466cc84184b6c0993a1bf50dabc45f0f5a591c8bcd0326bd0283024a7075626c69635f6b65798203582c302a300506032b6570032100d8e091572c325ee4edf561c8f0c85f59203f4b79e955f2adcaf39dc9037b59cb83018302581dc749a1b9b5c123bdc745883bd4901e311ae90a586a6825d52d99739e0283024a7075626c69635f6b65798203582c302a300506032b6570032100bfa1b1575803d5fb21032a69ff50a04a3394dba63c509e9a1ae9edf781b3f1748302581dcec168cc1c818e1bcbf8622c2bf05ead8f63ad21d04e0498fd64fce80283024a7075626c69635f6b65798203582c302a300506032b6570032100dc1a8cd77897793bb5b6bbbbbab2ac828f212c31ef7d8cd1a5e9da71d4368a1a8301830183018302581dcff1f1e404582ce832e51ef54dd196540af764448da6720f443d28860283024a7075626c69635f6b65798203582c302a300506032b6570032100b9f3c99d054c571483371cabababeba71a95af2f1db75a9eff5362a00168bab38302581dd0d9bd9de8bde02b0179227caefdb94de48a74231c4aa88c6bba74780283024a7075626c69635f6b65798203582c302a300506032b6570032100cd8d2ec2ff21561e2772d9e68ea249dbe874c214899c33c5503444b34786be3283018302581dd52a16f3dc32065f858393468f14585efb701a4cad05c445ba75a1dd0283024a7075626c69635f6b65798203582c302a300506032b6570032100013eb950162c07d85df53e01759052f239e953b592d13121ca5c038e28b6ea288302581dd5607c139fbf027070f48977431c08c47c96199ed4f75642774408930283024a7075626c69635f6b65798203582c302a300506032b65700321004558f956c1197f57de5eda61e88f6feb2bcd97cb69992edf3ed77326376447cc830183018302581dd7d81b675fb361616868d4f31793e064c6619a7a3fb4715d340fc2e00283024a7075626c69635f6b65798203582c302a300506032b6570032100455044dd9eaf7a0dd463d8e194f4c10bd4943cfc9beaf0e7ae4074373d1548938302581ddbcb3c89c77e2a4bb43c2244752161f5c08d759f97acdca282af8f9d0283024a7075626c69635f6b65798203582c302a300506032b6570032100b1c163e31457e5af99033c20a313371c3a00237a3bedf2ce8cdfef475db5b87583018302581ddce94d09354a1751d180df5fe0a8f352c7396bd63c338f8f91fdf5340283024a7075626c69635f6b65798203582c302a300506032b65700321000391e646f29f87929474489743d2958abd973ded1826d146b1d5cd67ae05b55d8302581ddeba05a0e095a26bf12507f792863507d32fc012be8e4f4d705dbb7e0283024a7075626c69635f6b65798203582c302a300506032b657003210004623b4767a979d854f118eaad12777b5ffa0ab0d9640708f68579cb4f6700358301830183018302581de058cf7bdd01bc75227405ebfab94752a4d2f43ff113b5ca68e4df4f0283024a7075626c69635f6b65798203582c302a300506032b657003210072de1b160077674e745a9d03e75a9432622aada8229d36d12b48ce567882e0d38302581de8373870d8066d971c415cbdaf1611bcf84cd3644d22b389de95d9e40283024a7075626c69635f6b65798203582c302a300506032b6570032100c8cf4e899a7227b656028521ba6d7c305528e120498db2e145b5448b96f824cd83018302581de85c5ec8051f35f9e3c915e3dbb3c32af6506b2a668b74c0bd003c850283024a7075626c69635f6b65798203582c302a300506032b65700321002f2e7160e775b899b3921b3a9676373a542c7ee4965d3b43952781820b880b938302581ded8915a3c359b8e16da92f2c42d6fbcd34fcc23a011770fba5734c990283024a7075626c69635f6b65798203582c302a300506032b65700321003db88746a7def775447aebeab07f35a7ab325a1e156c1d076da2ef988cf4cf8d830183018302581df032935f1185096317778e4206e8de237a7e090ba0b3289582c0fff50283024a7075626c69635f6b65798203582c302a300506032b657003210088eccdb0ceab1a41a33496dbfc7abac145d1674363c527f36707b53b354f7d238302581df2be1c26024bc9e103d662dfd167cbfe861400e7748b7778e01adc790283024a7075626c69635f6b65798203582c302a300506032b65700321006fed5c19bfcdf67f1e8d9a866f826d89cb05bdcd40cb633a5d7645f82394665c83018302581df92bb6e3332495ffd40fcf37af5fe9482b0667f3d4063d598fe8e8fa0283024a7075626c69635f6b65798203582c302a300506032b657003210038e87a8fcc24cdaad8541ad88a0d1f521a8c9bbc29379382055602ca59d226ff8302581dfd8e4151c4762d9b4b6b36e08d36a49b83e9458a5040a1dc26d63b530283024a7075626c69635f6b65798203582c302a300506032b65700321001909d5eefbb0075b3176069b7ac4a6e99934342a8fe5b3ec301d20b6cf453e5383024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100814c0e6ec71fab583b08bd81373c255c3c371b2e84863c98a4f1e08b74235d14fb5d9c0cd546d9685f913a0c0b2cc5341583bf4b4392e467db96d65b9bb4cb717112f8472e0d5a4d14505ffd7484b01291091c5f87b98883463f98091a0baaae8302581dd77b2a2f7199b9a8aec93fe6fb588661358cf12223e9a3af7b4ebac402830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000020000001014a00000000002fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361009933e1f89e8a3c4d7fdcccdbd518089e2bd4d8180a261f18d9c247a52768ebce98dc7328a39814a8f911086a1dd50cbe015e2a53b7bf78b55288893daa15c346640e8831d72a12bdedd979d28470c34823b8d1c3f4795d9c3984a247132e94fe83018302581dfc7d15b27df96b3e98731463a2af13d6e43cf426d0cb487a7120091502830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000c0000001014a0000000000cfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361009053b542dc8d758237ada280dc505846c327b0c43b7e26c0ee6f7729cdebd43639d959c10fe1aa058622437d7ec34a920035dfd55de4f40937b4c419e02b517eb2b7a6aa7f42644352202f8f4c67e726ca8f168ab588764261dbcc3a5c8113938302581dfe320f2fbbb9d49c8e6edbcc9d85ec096bf645351d95bbddf556f7db02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000130000001014a00000000013fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100b2a6741083996223f83384666740a3eacf8ce78c6d39fecdee582a5b243c158706bb215f396ba0429d2188df9ef176721306d048aaa58f6b413457dd63ef1a56de2378e71ca444201e29e490e3790098e92ee85e0142a33ef806c8388aec6baf83024474696d6582034998e98fdac4dbb6c417697369676e61747572655830957863c11a54909e3ade079efa35c27ce5a350cf483f889c6297112f36d70170e114d305fe720dbc84c70c93eb64c221`,
+ localApplication: `d9d9f7a26474726565830182045820b06c8a8b1f5eb2cf3c0ecb21e8f4384057ca8a6f9c3c615e819c1a53d5c89e1f83018302467375626e65748301830183018301830183018302581d033a778c6c9eac039fdda83dc90d2c12eb846de85c475e36ead6715c02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000100000001014a00000000010fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100aa544423a45fb0388c43703a159a96208cafd17f01f1e7c400676d2c69f62195f6a5bb564d564f7967047def10b48c22003f38c5d56961d0c47879f9212b93cd206620114bd9e1d4db22d04e294d37e1ff42cedf2322ebf60702c88325c606808302581d0f033c5125db4f6b32e426268df663a5ce98fe3b531d962e1a7a87fa02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001c0000001014a0000000001cfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100913f6a84f05736c2dd0b2dc3ec838e95419ae0ef426d556f50152a445b9c232495bc051cdabbd46a7bd8879b09720cbb13b3bcd265ff75567dcbf04e9ae1c3a2141229a6757605625b093c5ca34336393e5a88b78df7b0a3a7e5b9841716d0a483018302581d10b647334a5406987796b2f8b6b14cd32f0876d3fd4fc8452105832502830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000180000001014a00000000018fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084cbe7a009258947dc30983fede3b98b34cfee5e5d1ae4e1e72891590738ca9a58f9f6364b359a5448b6c5e20ee5310300e4c0c9cca29b07e2d73208f8ec6cd1fb6ca46c168c43393f9e050a05448836b0a6f5c75d2a398c999c42d7c981cb898302581d12790e7661fccd3d4fc83138dcaffd9f188e867b45ae10c8836dd0b802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000150000001014a00000000015fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610086d88ebbd2f1663e65d3a3ff07e8ee9fa420d08b9a6822919f224b8b802d5d9be150dc493f84c23e73a0cc1d2c2ee28709ff140000128fcd5dfbd7b457ef3af344766d7ff0924fe7a7f456ded77ca6de3b1b406b710c4eaed7287ab9a3527669830183018302581d17f67590355e7123aeffabce4c1bddf3a0efd53a2c2e3f6228fc3adf02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000d0000001014a0000000000dfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100850e5edfb0685d36757643be011f5d3378fef0bfb9b0ef67429912ebb9237f5028979eb33779df7c63acf59b78eba4d904c6b4abad529b9e8e2195321e287f8c51900f5b440872719c7ac56e381c8063bc6176f8e4b74d06de669493e49055678302581d1cc5ad563f1bce937c305be3d12bef627f73b727808672dc2432aef902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001f0000001014a0000000001ffffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610093907710f0f89af4b5bd35a28e0162171e2f411d11e152152e88e3da4c2079799e4eac7a3a9f3923fb63b33b68928ae91652fae5c2ccce872173632648ef4dd79ae7e8c15b9e97f132ea34a4349506d281bd66bbd0c3afdd78cbe026927a8c1683018302581d2c55b347ecf2686c83781d6c59d1b43e7b4cba8deb6c1b376107f2cd02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000060000001014a00000000006000ae0101824a00000000006000b001014a00000000006fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610090075120778eb21a530a02bcc763e7f4a192933506966af7b54c10a4d2b24de6a86b200e3440bae6267bf4c488d9a11d0472c38c1b6221198f98e4e6882ba38a5a4e3aa5afce899b7f825ed95adfa12629688073556f2747527213e8d73e40ce8302581d2d030caf397e446c03cece4fd072acce432c75b6a700592e73f5d13302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000090000001014a00000000009fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100805230c2da9687218fdfa49bddab093578c2e8a10b27d69fdda097f286abccdae2541c711e3ca771202bfc9b366bf61b17e9f1173d7c9a6eaaa907ccdba3bc86764bc1d552437c4948038e1018a9c49e444189cd55358e37a6f879d88c0a26938301830183018302581d2ecc29447b0eef6c241dcfdf7dab077093ccd6a1266be0fe9c9b127602830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000e0000001014a0000000000efffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610091541cdc7b65c4828286c911602d9438de5649d698b60fc06aec73589395d0bca71746524ed2ff17b2c8da9fbc897f0f07a40b204871b6fe96d45ef10b51d1f1d530d0679a5db82de96929805fa17c737994ebcc2312d2a25bd94747ecf8f34b8302581d2f1a9548062f52ca0e90e72a4a97cb324fa1dfb62b564ef1b29f38aa02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000160000001014a00000000016fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084698ba18ea46f2041353c98fdf6980235fab99a6f5b83c5de3bb32a7ad190ef26fd2afad2dd2e4fb5eaebc4fd177e3c11ed29fb7dab26a6909d366c185cb9d964d3ff3a8e71c0c28adfca715698f679cef6b6346106a78c9f8d3f8e9a66e88083018302581d30580a1a7643049513f8f7d6ffe6f51000570345a63160cab7784c5902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000a0000001014a0000000000afffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610085c8811b0caf15f9ad2e34f1841a7820dd1a70642e21362748bf0927c6fd67ddc0c1329fdd840e06a16d383023c4c00f062f173e628528eb801c15258e2e417d511fe4ba3c175469570cc8e1338e5457ed6b31b72b139b537554f00b14fd69158302581d33c2f9ea0f8e2c53e6e54766dbc6cec8da6787b0154260a99925f7a802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000f0000001014a0000000000ffffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100b31b406c9f6648695a88154ae2e4f5fe87883d4ad81c2844c5571b2d91d401cdd40836e763a7c18dccb84629b0d808f7142c3175bc8231dc09bd53637efd6f2568801385ec973d34e6eef9c8c8280a9f4a114163a43a8540941ba367f0c7cb28830183018302581d4164d0b890d702b3cf4f1121e504f24b0f0d94da0e935221220f3a3702830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000040000001014a00000000004fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008ac081401431767be18972543b3ee45c6769c447fb727a1abd72bc1c12487d5c1169522857cbb8d89273847f669563af05833ecee73afa853a16de4aa5549ffea02f3280167129fe026d8aeadc959d73b44570dd18eb9c6ba313edd0a45282748302581d43dcaf1180db82fda708ce3ac7a03a6060abde13e9546c60e8cce65d02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000701014a00000000000000070101824a000000000210000001014a00000000021fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008675b634a43e39726238cfe39c9518bc3e3225cb6f5a8479bfcf2b608fba6f8524dcb80f35a8ae44b47f262f0a6620d41279f06fe0c53a739fcca01a48926fe651a3519b5b329ffbecc9f0cb908b098dd3e8845cfb99c56379e049ac465ec80683018302581d45178b66a407a4d59c0a4d6733bda2ce3f37c111b4257ec41908f4f802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000070000001014a00000000007fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100955f52f73c2dec59a637b294e50b934db5d6de29e73bbcf84e7d86a4ac41bad7b539f9817ade8916961d9dd6bf9257010d5857156e8fe6aafcf6fd068795e70bd3399b3411300c9ccc8eba0d068c10e4cfb6f4e27d195b1ead785d618eb393b98302581d4f82b62edffa3fa4e6a5c48327ce8cfb3f850db2e5abc90e955d77f002830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000230000001014a00000000023fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a32153e6271817b87d91d1cd0b727119a2eda7355ee7ef64ee9f10bf6396aed6899a5475d37d6cc51c6a741397d3685318e8e0dabec1b1994112e2c4da3262033ea18fc667dd0ead6e0a151f4d884ee644b799c05e56f502d42f22ffabbca09783018301830183018302581d581b5aa2f10c5f221e45de74a2cecafd3da076be39db0907cbf554bb02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000170000001014a00000000017fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100ad28a2bfaae6c9248ef1ea3e4f4bc6ea29101ce533b0075349bb86a88535c216ce434c9aa018b87465441dd997ed23270e2b21e126c74f16293bdba29033e858ecd50bda7be1b692a401e154eb87b65dcf0983635e578e3ea2f6d9b02c7c79dc8302581d5c76b3988ed788abc32d2ea13331bc29debc4f24d19a8f41417eaeb102830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000120000001014a00000000012fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100ae04b0b53b4f62ce4a789a6b0f0c9e66dfa5868cb2f3e0e7f628ca6fb93e4f33879a8fe47a23485f30f5a68472c4fd460bc29923b851023792437af3cc690891740a676ffbeb8d836e6ed5b2409dcb32104dde956743e51d3b0e23222ac9487b83018302581d601575e11b35c86fad26229748379d1d9693312bff16e2bca1c1cdd902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000220000001014a00000000022fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100987ce1744dba1052580903a85d6ac697f1619a9ce3119cfa8b06697013a9e2a799b2078763c3119023981410523c52030e00b5d3fd6663e85c59473366ac9846fee6fe9b415c69a96ee9f0f7768673839211f52b19fab495978f100f982d0f618302581d61b718d0b8c31db1ef09451eadd068887c1df5f37e7de0a3afc5a56a02830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000010000001014a00000000001fffff0101824a00000000006000af01014a00000000006000af010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610084ec5e445306312c9d94e1d1a37cb7d3a6a5a6f86bc85f30ba9bc5a261ab8a37f814786b8e1bae8aa004afb1bba510a411bde94c2a494fb2caa9155abfe0dfc19046854929f7d67726c83e572faa4b812c96196221ed549ef27fb9fb78c2e06d830183018302581d6a8f67d86ecc8307048038ad71599458c131b531dc9bb0b691940db902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000080000001014a00000000008fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008c4e7e55222f134fc3a633620701f6d25a2a5eecd71a3d49c36846ff5d5cd98d382764e81c5869e95e0feb61d132a9f20d4822f7c5bc4c8ed7cb59d52884736864478f1b0e81b1892cfa01ccc7b2fa5fff31586096217c599ff2652368b2f1948302581d806b712f189b5651e7349743820c5f45a81592464c25048e79f25cd602830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000b0000001014a0000000000bfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100af4f78ab97b3cdc76075f552e83842d5b07c4e35f9f83614b4976e70751f94ea1bc5ebec45892086f4344ea8fb3f7e3a053da28155c0ac501ab6a26ccfc60e729d0bbe91bf0772837cf2911fb4e952d066daf14ea45c08c2104cc69bf221a4f883018302581d9365a8c9f27f413060850835d1859a415c67575cd30c04a183fd096302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001e0000001014a0000000001efffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008a91b23b098aeb7dd5e525717f0c29d3967c5f4e61d0b5c7c697172e6f5682aa5e423d42077695c517aba7e3b636da940938d7d5caeee26c3c71cc6888f542c5966e60ea4d91ddb95ad0994283171097e325026bef003128b44641056c86d04a8302581d9c7d405764f197f3611b7a6d3f7756f0c5f7a7dbb02504da09d21f2902830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000140000001014a00000000014fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a5d492126a99c65b09c53fe75b5ad8e24d1556a9db2bfe74dffae1816165405923e6fa2b4c58e5adbddf99575fb83b1a06736dc6e4ce20eabf54ca6ca574d3af0d14ef8ae143f9339cf16e62e72b5dfd47d1d642e731c5ee853a00fef69d70db8301830183018302581d9dfdc32362ee85e05f3f36ad947cc62cd276d7b8687d239637de118c02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000200000001014a00000000020fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100a0e2dffe693d3c75cabacb68760466611df84ddd06e42954cfdf85c665841801319dcaff52cbad03bc37b64061c562920b77389679afb7f888bfc4a36b4772e6cf41374ff8714101f390056e26de88611c93c22eb90e96fe6370ac246ea6faa28302581da22bac610f4e17278d2a0f2cf83a2e2556f6594371615940334d31d302830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000190000001014a00000000019fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100afd62f0314d4f866c512d95a649db5c3241d6624b15c62b2fdd3d29af2dee832e3f1af39c60c2389cc4826c181b82d01133dc9f10f727b315c5bf18de580b70a8d8800c570b99b89514922a6476fbf76591e022ca68cdb4b3610e7f642d9bfa083018302581dacc260d8fc5e1421c9aacc9bb5e1a1147aa15bf15304831ba734b9f802830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000050000001014a00000000005fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100aaeeda397b35cf5473ebc1792d7aadf102d085aca490551906f73c4108df12b8478b13b73c8953c148235d0efe99427017451ce8cdd0bd9ee81ede26221c4c3ff0f49af21c6402e6d35fc4c3c61352ff3d8767a3cc8d7ee58a2b50abbbdf2dbe8302581dba488d13a5dd7649d8093fe4897df1cc7c728ab64c856a78c4b97d6a02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000110000001014a00000000011fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610088dc7b350da56b6ff41f08332636ab9d162bf3a293a65f795089ef8b8fe9a5af91c51f67e34729408bfdf21b110b7ca405c98af5c1a9ca2ff2995e27ed4e9d0325bd8fa92623e31879247ea508729cf46e0dd2804bea34f3acabe4aa4ef0b973830183018302581dba58b21125381b0567e61f3f2ecd65f37710316084ee791cdfdb4a1a02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001d0000001014a0000000001dfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100852c9ff8de8c5964d4b6209feaa6f7675a3afab47ab8ec9b67b111ddc158983fd7b034ffcce4958c60ec37040938eb1e18633d7e9a086153e53755008642bf9f87db91d6709a65f242b9e4e31dbeba64a684745a76dee8cfe6729c5ab3c52f148302581dbd26ec81a3360bc8050673531b92b27988bf2a893b506f80e40c11cf02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001a0000001014a0000000001afffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361008e41463b1893989f425af308744b916d9034e83d9382b03b1e30b117fee21a4e1ff03fc59d54f4bc710a51ba04a1e21d0fd863b5329bf68ee67c6d15f82d4a673775604a1c719cb6ce200b2710e425663c7060e5e98e032beda6835c9010158d83018302581dbfca29efbb1f48b67849f2c9bab8a7856fd57882fb99c8ad497cf55202830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000001b0000001014a0000000001bfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100846c395853586d94a2e546485537d4f81bb7820d5e82c274b507d592d59353a165dd8ed432e8b7c0792d90d52cf968c20c5ae06d69817d814a7ee2d54130baf49b192186890621abc70046ea9939978df172fc1cd16aded5f227cd8c27bcdb658302581dc3b96ea47e04c8977cb703f15aaf5aaaaf73d596c7be19a43a718d8b02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000030000001014a00000000003fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c0503020103610087bcc7281aa5620454d5621da57502fd0ac9f10031cecc9df6715994c30ac76f212788d23dba8aa05c8ec109090561ce07c5ce7aef9f248eecd1d0a97bcab22977fb9856f4bfb5ced1fc5693320b7b6ef5fe28c69688b92a8dae61cae762eb47830183018302581dcff280e32d7f5ccd2246882f94afb20f54ca61a21765e712d43d2789028301830183024f63616e69737465725f72616e67657382035832d9d9f782824a000000000000000001014a00000000000000060101824a000000000000000801014a00000000000fffff01018302446e6f64658301830183018301830183018302581d24c56af1a646bdee74ba2c8cad88ba6e4f2ee098f99055bd0e9640c60283024a7075626c69635f6b65798203582c302a300506032b6570032100526742592f1e331aa13db7d1ebf224ff0b8231e0626eeefad0b629413a93e7988302581d2995ce7aeea59467fb3a634b434dcc965ba147ba2f9804ea2e8f1b5c0283024a7075626c69635f6b65798203582c302a300506032b657003210099c734e5f28c50741b04b63e87c77533d47dc2347524ed1ec8c266e429cef63683018302581d32442407acaa5ea43e62b1dac1ac20119c64cfd5c23cc0ae1508ee250283024a7075626c69635f6b65798203582c302a300506032b657003210054432c37b495e9206b46b5ce85da87a7eb2d853cd3f02feec4acf39efe9828508302581d325c033f6f1fd07e7bcb57b7ab8a24b1abf73beffd1ca17ed88cf3ab0283024a7075626c69635f6b65798203582c302a300506032b657003210059ef19e6aec7336d0912a80fe269ed4f0e8360cff9dc6fbe7a941643142bb4ff830183018302581d3c4d78ddee38b0eb2910a004c3a7362017a5c14a9346007a65829ebb0283024a7075626c69635f6b65798203582c302a300506032b657003210076f7f52d74955cc045838a6ef71b882dd5339ba058bdcf1085f893b3545d44bf8302581d3eda90ac6d378ae7c7917f94fd61c0e685b22f5ced5ad0735af250230283024a7075626c69635f6b65798203582c302a300506032b65700321000b4ca05b18b5dff4efc88badc802bccc4bae5ce2f16febe6a893904a240af36083018302581d46e3cfcd286afe6a1f4572d2350facd38f0f8647d58c499e5bc5039d0283024a7075626c69635f6b65798203582c302a300506032b65700321003f29994149099aa1b1d2dcdaabe5eda73aea6866d067e2c45b97e216532bcd338302581d53e39463ea45264875d00c508e4bb1325722a96a00053dbc2662fc5e0283024a7075626c69635f6b65798203582c302a300506032b65700321004323320684d4e1edb89bdcdee00844830a0f7de3e3cc7346e5a3868d1aef02b58301830183018302581d607eb9a00ad3b4411f5911276879c618a6895fd57fe6c9b0a879f9b00283024a7075626c69635f6b65798203582c302a300506032b6570032100a8fa77ad6c1da6d50d04fbc96bf33d0e30a67c1e8ba97fa3ce7c3d9c868a7b998302581d6ad96c153126046203336a5174a04b30f0adea457c2298b976ab674e0283024a7075626c69635f6b65798203582c302a300506032b65700321005e12ef0eae2809a5468471ee2d9745d23f20b1c0da7129fa447d96a67336be5b83018302581d8156c471c227bb551da5ff7603b22e4a1c87f711292502aef5cdae320283024a7075626c69635f6b65798203582c302a300506032b6570032100995e3dcf4b0fe927bee5172cef595b53bace86185890f052939a63d24eabf0da8302581d8465e6cc28f5be102098a7ae96264f6ec72f1c4a858b491cd60e55a50283024a7075626c69635f6b65798203582c302a300506032b6570032100dc624cca12ec1daebedd007ec838e77990a6da3f8dff968ceebf3a0e8390562f830183018302581d8cf60ae159aabf4207328d2a5524675d5c157a8aa1f80a52ec44221b0283024a7075626c69635f6b65798203582c302a300506032b6570032100d1955dd0b79c84d036422763c3a29154f31ab907ecdcfc9870db91db3e9dba7b8302581d904ebdc04493093d1f6f7d37a6a91c5fa6616ddf19771fd346cd5aeb0283024a7075626c69635f6b65798203582c302a300506032b6570032100767f31d2bb762bc9fa9b2cbe9f86504f16422f206fe4e61ec57b73a97fea242683018302581d9f00ea7b0826aa145abd4348c3656133ed84e188780f63c5151009bf0283024a7075626c69635f6b65798203582c302a300506032b65700321003dac46790dd80a38b0238ac3e1c1766fb3049a3b46d406c4ad85ccff42317a1e8302581da7835a01f618d7b552d0eae3310aebd0cac6ea2bf02865472f4546fc0283024a7075626c69635f6b65798203582c302a300506032b6570032100b80f4705b1420119acf881fb01e90f50044df72b1893cca44b4e81129e7a3e6e83018301830183018302581da7bad7420d9671f6992d64ca541ce75fe04a7c51c2561dd9aad945880283024a7075626c69635f6b65798203582c302a300506032b65700321008aa5bb79948b296c12c14131b35f9009ce331981b08c7ec57a595c6eda59d6938302581db1dee04210dded1afbc7e5d31492d7f0b1379b8fea5b203d30b3c03e0283024a7075626c69635f6b65798203582c302a300506032b6570032100031739d3139245f101349d4d2fb8cdc2e2707084d3fef1d033042d64ebd452bb83018302581db858dfb622c91c481e81e9cdbfb7ab78da5dbb7a09d2e321787a0c1a0283024a7075626c69635f6b65798203582c302a300506032b6570032100cd59f18eea954c1fc8e315099657d929b6bfb7fefadb7bb214448809f4a9d19f8302581db8e453c069995d67a5253c43ec43b4b39038d272f4c67fa9155e6e490283024a7075626c69635f6b65798203582c302a300506032b657003210079d79503838b2b01791f66c18bc7614e19d3a6aba73bae00b92bb99edeea5287830183018302581dc0588b3d010691102a6dc738ab5517afaa4f27882a3554b006d2b3920283024a7075626c69635f6b65798203582c302a300506032b6570032100879ee566edf8a11717120cca3e4b1521f07a781c6d79ddda637b3a4c770f6fc68302581dc6f9bfce466cc84184b6c0993a1bf50dabc45f0f5a591c8bcd0326bd0283024a7075626c69635f6b65798203582c302a300506032b6570032100d8e091572c325ee4edf561c8f0c85f59203f4b79e955f2adcaf39dc9037b59cb83018302581dc749a1b9b5c123bdc745883bd4901e311ae90a586a6825d52d99739e0283024a7075626c69635f6b65798203582c302a300506032b6570032100bfa1b1575803d5fb21032a69ff50a04a3394dba63c509e9a1ae9edf781b3f1748302581dcec168cc1c818e1bcbf8622c2bf05ead8f63ad21d04e0498fd64fce80283024a7075626c69635f6b65798203582c302a300506032b6570032100dc1a8cd77897793bb5b6bbbbbab2ac828f212c31ef7d8cd1a5e9da71d4368a1a8301830183018302581dcff1f1e404582ce832e51ef54dd196540af764448da6720f443d28860283024a7075626c69635f6b65798203582c302a300506032b6570032100b9f3c99d054c571483371cabababeba71a95af2f1db75a9eff5362a00168bab38302581dd0d9bd9de8bde02b0179227caefdb94de48a74231c4aa88c6bba74780283024a7075626c69635f6b65798203582c302a300506032b6570032100cd8d2ec2ff21561e2772d9e68ea249dbe874c214899c33c5503444b34786be3283018302581dd52a16f3dc32065f858393468f14585efb701a4cad05c445ba75a1dd0283024a7075626c69635f6b65798203582c302a300506032b6570032100013eb950162c07d85df53e01759052f239e953b592d13121ca5c038e28b6ea288302581dd5607c139fbf027070f48977431c08c47c96199ed4f75642774408930283024a7075626c69635f6b65798203582c302a300506032b65700321004558f956c1197f57de5eda61e88f6feb2bcd97cb69992edf3ed77326376447cc830183018302581dd7d81b675fb361616868d4f31793e064c6619a7a3fb4715d340fc2e00283024a7075626c69635f6b65798203582c302a300506032b6570032100455044dd9eaf7a0dd463d8e194f4c10bd4943cfc9beaf0e7ae4074373d1548938302581ddbcb3c89c77e2a4bb43c2244752161f5c08d759f97acdca282af8f9d0283024a7075626c69635f6b65798203582c302a300506032b6570032100b1c163e31457e5af99033c20a313371c3a00237a3bedf2ce8cdfef475db5b87583018302581ddce94d09354a1751d180df5fe0a8f352c7396bd63c338f8f91fdf5340283024a7075626c69635f6b65798203582c302a300506032b65700321000391e646f29f87929474489743d2958abd973ded1826d146b1d5cd67ae05b55d8302581ddeba05a0e095a26bf12507f792863507d32fc012be8e4f4d705dbb7e0283024a7075626c69635f6b65798203582c302a300506032b657003210004623b4767a979d854f118eaad12777b5ffa0ab0d9640708f68579cb4f6700358301830183018302581de058cf7bdd01bc75227405ebfab94752a4d2f43ff113b5ca68e4df4f0283024a7075626c69635f6b65798203582c302a300506032b657003210072de1b160077674e745a9d03e75a9432622aada8229d36d12b48ce567882e0d38302581de8373870d8066d971c415cbdaf1611bcf84cd3644d22b389de95d9e40283024a7075626c69635f6b65798203582c302a300506032b6570032100c8cf4e899a7227b656028521ba6d7c305528e120498db2e145b5448b96f824cd83018302581de85c5ec8051f35f9e3c915e3dbb3c32af6506b2a668b74c0bd003c850283024a7075626c69635f6b65798203582c302a300506032b65700321002f2e7160e775b899b3921b3a9676373a542c7ee4965d3b43952781820b880b938302581ded8915a3c359b8e16da92f2c42d6fbcd34fcc23a011770fba5734c990283024a7075626c69635f6b65798203582c302a300506032b65700321003db88746a7def775447aebeab07f35a7ab325a1e156c1d076da2ef988cf4cf8d830183018302581df032935f1185096317778e4206e8de237a7e090ba0b3289582c0fff50283024a7075626c69635f6b65798203582c302a300506032b657003210088eccdb0ceab1a41a33496dbfc7abac145d1674363c527f36707b53b354f7d238302581df2be1c26024bc9e103d662dfd167cbfe861400e7748b7778e01adc790283024a7075626c69635f6b65798203582c302a300506032b65700321006fed5c19bfcdf67f1e8d9a866f826d89cb05bdcd40cb633a5d7645f82394665c83018302581df92bb6e3332495ffd40fcf37af5fe9482b0667f3d4063d598fe8e8fa0283024a7075626c69635f6b65798203582c302a300506032b657003210038e87a8fcc24cdaad8541ad88a0d1f521a8c9bbc29379382055602ca59d226ff8302581dfd8e4151c4762d9b4b6b36e08d36a49b83e9458a5040a1dc26d63b530283024a7075626c69635f6b65798203582c302a300506032b65700321001909d5eefbb0075b3176069b7ac4a6e99934342a8fe5b3ec301d20b6cf453e5383024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100814c0e6ec71fab583b08bd81373c255c3c371b2e84863c98a4f1e08b74235d14fb5d9c0cd546d9685f913a0c0b2cc5341583bf4b4392e467db96d65b9bb4cb717112f8472e0d5a4d14505ffd7484b01291091c5f87b98883463f98091a0baaae8302581dd77b2a2f7199b9a8aec93fe6fb588661358cf12223e9a3af7b4ebac402830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000020000001014a00000000002fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361009933e1f89e8a3c4d7fdcccdbd518089e2bd4d8180a261f18d9c247a52768ebce98dc7328a39814a8f911086a1dd50cbe015e2a53b7bf78b55288893daa15c346640e8831d72a12bdedd979d28470c34823b8d1c3f4795d9c3984a247132e94fe83018302581dfc7d15b27df96b3e98731463a2af13d6e43cf426d0cb487a7120091502830183024f63616e69737465725f72616e6765738203581bd9d9f781824a0000000000c0000001014a0000000000cfffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c050302010361009053b542dc8d758237ada280dc505846c327b0c43b7e26c0ee6f7729cdebd43639d959c10fe1aa058622437d7ec34a920035dfd55de4f40937b4c419e02b517eb2b7a6aa7f42644352202f8f4c67e726ca8f168ab588764261dbcc3a5c8113938302581dfe320f2fbbb9d49c8e6edbcc9d85ec096bf645351d95bbddf556f7db02830183024f63616e69737465725f72616e6765738203581bd9d9f781824a000000000130000001014a00000000013fffff010183024a7075626c69635f6b657982035885308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100b2a6741083996223f83384666740a3eacf8ce78c6d39fecdee582a5b243c158706bb215f396ba0429d2188df9ef176721306d048aaa58f6b413457dd63ef1a56de2378e71ca444201e29e490e3790098e92ee85e0142a33ef806c8388aec6baf83024474696d65820349d6d2f0d7dbd5b6c417697369676e61747572655830ae1324ba253591ef6c5e58053d0c266ad2914c63a730e9f0dbac7763be24a1fc20fa2fde4847a07d0089c8984774129b`,
+};
diff --git a/packages/agent/src/agent/http/index.ts b/packages/agent/src/agent/http/index.ts
index e4b5d1e30..48fef4935 100644
--- a/packages/agent/src/agent/http/index.ts
+++ b/packages/agent/src/agent/http/index.ts
@@ -27,6 +27,8 @@ import {
SubmitRequestType,
} from './types';
import { AgentHTTPResponseError } from './errors';
+import { request } from '../../canisterStatus';
+import { SubnetStatus } from '../../certificate';
export * from './transforms';
export { Nonce, makeNonce } from './types';
@@ -178,6 +180,8 @@ export class HttpAgent implements Agent {
private readonly _retryTimes; // Retry requests N times before erroring by default
public readonly _isAgent = true;
+ #subnetKeys: Map = new Map();
+
constructor(options: HttpAgentOptions = {}) {
if (options.source) {
if (!(options.source instanceof HttpAgent)) {
@@ -575,6 +579,21 @@ export class HttpAgent implements Agent {
this._identity = Promise.resolve(identity);
}
+ public async fetchSubnetKeys(canisterId: Principal | string): Promise {
+ const effectiveCanisterId: Principal = Principal.from(canisterId);
+ const response = await request({
+ canisterId: effectiveCanisterId,
+ paths: ['subnet'],
+ agent: this,
+ });
+
+ const subnetResponse = response.get('subnet');
+ if (subnetResponse && typeof subnetResponse === 'object' && 'nodeKeys' in subnetResponse) {
+ this.#subnetKeys.set(effectiveCanisterId.toText(), subnetResponse as SubnetStatus);
+ }
+ return subnetResponse;
+ }
+
protected _transform(request: HttpAgentRequest): Promise {
let p = Promise.resolve(request);
diff --git a/packages/agent/src/canisterStatus/index.test.ts b/packages/agent/src/canisterStatus/index.test.ts
index 15b4943f3..5691d8fd1 100644
--- a/packages/agent/src/canisterStatus/index.test.ts
+++ b/packages/agent/src/canisterStatus/index.test.ts
@@ -188,6 +188,6 @@ describe('Canister Status utility', () => {
expect(status.get('asdf' as unknown as Path)).toBe(null);
// Expect undefined for unset value
expect(status.get('test123')).toBe(undefined);
- expect(consoleSpy).toBeCalledTimes(2);
+ expect(consoleSpy).toBeCalledTimes(3);
});
});
diff --git a/packages/agent/src/canisterStatus/index.ts b/packages/agent/src/canisterStatus/index.ts
index 6ff87eab9..7c92b1da0 100644
--- a/packages/agent/src/canisterStatus/index.ts
+++ b/packages/agent/src/canisterStatus/index.ts
@@ -1,9 +1,13 @@
/** @module CanisterStatus */
-
import { Principal } from '@dfinity/principal';
import { AgentError } from '../errors';
import { HttpAgent } from '../agent/http';
-import { Certificate, CreateCertificateOptions } from '../certificate';
+import {
+ Certificate,
+ CreateCertificateOptions,
+ SubnetStatus,
+ lookupResultToBuffer,
+} from '../certificate';
import { toHex } from '../utils/buffer';
import * as Cbor from '../cbor';
import { decodeLeb128, decodeTime } from '../utils/leb';
@@ -12,7 +16,15 @@ import { decodeLeb128, decodeTime } from '../utils/leb';
* Types of an entry on the canisterStatus map.
* An entry of null indicates that the request failed, due to lack of permissions or the result being missing.
*/
-export type Status = string | ArrayBuffer | Date | ArrayBuffer[] | Principal[] | bigint | null;
+export type Status =
+ | string
+ | ArrayBuffer
+ | Date
+ | ArrayBuffer[]
+ | Principal[]
+ | SubnetStatus
+ | bigint
+ | null;
/**
* Interface to define a custom path. Nested paths will be represented as individual buffers, and can be created from text using {@link TextEncoder}
@@ -98,7 +110,24 @@ export const request = async (options: {
canisterId: canisterId,
});
- const data = cert.lookup(encodePath(uniquePaths[index], canisterId));
+ response.certificate;
+ const lookup = (cert: Certificate, path: Path) => {
+ if (path === 'subnet') {
+ const data = cert.cache_node_keys();
+ return {
+ path: path,
+ data,
+ };
+ } else {
+ return {
+ path: path,
+ data: lookupResultToBuffer(cert.lookup(encodePath(path, canisterId))),
+ };
+ }
+ };
+
+ // must pass in the rootKey if we have no delegation
+ const { path, data } = lookup(cert, uniquePaths[index]);
if (!data) {
// Typically, the cert lookup will throw
console.warn(`Expected to find result for path ${path}, but instead found nothing.`);
@@ -121,6 +150,10 @@ export const request = async (options: {
status.set(path, decodeHex(data));
break;
}
+ case 'subnet': {
+ status.set(path, data);
+ break;
+ }
case 'candid': {
status.set(path, new TextDecoder().decode(data));
break;
diff --git a/packages/agent/src/certificate.test.ts b/packages/agent/src/certificate.test.ts
index 29c7b2db2..44bd5e0a0 100644
--- a/packages/agent/src/certificate.test.ts
+++ b/packages/agent/src/certificate.test.ts
@@ -8,7 +8,8 @@ import * as Cert from './certificate';
import { fromHex, toHex } from './utils/buffer';
import { Principal } from '@dfinity/principal';
import { decodeTime } from './utils/leb';
-import { lookup_path } from './certificate';
+import { lookupResultToBuffer, lookup_path } from './certificate';
+import { goldenCertificates } from './agent/http/__certificates__/goldenCertificates.test';
function label(str: string): ArrayBuffer {
return new TextEncoder().encode(str);
@@ -126,12 +127,14 @@ test('lookup', () => {
return new TextEncoder().encode(str);
}
expect(Cert.lookup_path([fromText('a'), fromText('a')], tree)).toEqual(undefined);
- expect(toText(Cert.lookup_path([fromText('a'), fromText('y')], tree))).toEqual('world');
+ expect(
+ toText(lookupResultToBuffer(Cert.lookup_path([fromText('a'), fromText('y')], tree))!),
+ ).toEqual('world');
expect(Cert.lookup_path([fromText('aa')], tree)).toEqual(undefined);
expect(Cert.lookup_path([fromText('ax')], tree)).toEqual(undefined);
expect(Cert.lookup_path([fromText('b')], tree)).toEqual(undefined);
expect(Cert.lookup_path([fromText('bb')], tree)).toEqual(undefined);
- expect(toText(Cert.lookup_path([fromText('d')], tree))).toEqual('morning');
+ expect(toText(lookupResultToBuffer(Cert.lookup_path([fromText('d')], tree))!)).toEqual('morning');
expect(Cert.lookup_path([fromText('e')], tree)).toEqual(undefined);
});
@@ -143,7 +146,7 @@ const SAMPLE_CERT: string =
const parseTimeFromCert = (cert: ArrayBuffer): Date => {
const certObj = cbor.decode(new Uint8Array(cert)) as any;
if (!certObj.tree) throw new Error('Invalid certificate');
- const lookup = lookup_path(['time'], certObj.tree);
+ const lookup = lookupResultToBuffer(lookup_path(['time'], certObj.tree));
if (!lookup) throw new Error('Invalid certificate');
return decodeTime(lookup);
@@ -256,3 +259,218 @@ test('certificate verification fails if the time of the certificate is > 5 minut
}),
).rejects.toThrow('Invalid certificate: Certificate is signed more than 5 minutes in the future');
});
+
+describe('node keys', () => {
+ it('should return the node keys from a mainnet application subnet certificate', async () => {
+ const { mainnetApplication } = goldenCertificates;
+ jest.useFakeTimers();
+ jest.setSystemTime(new Date(Date.parse('2023-09-27T19:38:58.129Z')));
+ const cert = await Cert.Certificate.create({
+ certificate: fromHex(mainnetApplication),
+ canisterId: Principal.fromText('erxue-5aaaa-aaaab-qaagq-cai'),
+ rootKey: fromHex(IC_ROOT_KEY),
+ });
+
+ const nodeKeys = cert.cache_node_keys();
+ expect(nodeKeys).toMatchInlineSnapshot(`
+ Object {
+ "nodeKeys": Array [
+ "302a300506032b65700321005b0bdf0329932ab0a78fa7192ad76cf37d67eb2024739774d3b67da7799ebc9c",
+ "302a300506032b65700321009776d25542873dafb8099303d1fca8e4aa344e73cf5a3d7df5b40f9c8ed5a085",
+ "302a300506032b6570032100e5a9296571826cc3be977490296405ae9da1da7d59cce1642421bc19804cc310",
+ "302a300506032b6570032100b761a93e418ab326d2d106d9137268d407f7c8a743127e2833899933337eb09b",
+ "302a300506032b6570032100afd56377478dc711cbfe043022423d9f7f7decb709de7501545923274186883f",
+ "302a300506032b6570032100ce76939540cac8de3475329517c684e0562fb6cbad1db67fb60362808bdaf462",
+ "302a300506032b65700321001645a7cb7f3980dd6f9ca6ca0966a4d4bde9d57d90df0f10fc31eac960a8ab41",
+ "302a300506032b65700321000c441fada59fea1cf21ebc157392338ca56775011c4c5630782823e2a7938c8f",
+ "302a300506032b6570032100f408b362fc92255a4776666179eba4b9dfbd6d3b9f6b87b3abb80f726878e0a9",
+ "302a300506032b6570032100cab5efd3205fa4b3409b6f5e421ebd776dd36ea6108820c624478016df9c6a20",
+ "302a300506032b6570032100e650a1cc4bf264cdc80442d33d7bd00e3de1f15ddd48c7ac0f2fe582f599d954",
+ "302a300506032b6570032100be0759d30172a9dfdcc2e11b92e8daf1753c45f126b8413c8e57e621b5626d37",
+ "302a300506032b65700321006b8ef72b0efb4ef38dc957097cb26dfcf24b083dd6b2b5fcd5269657cd8e59a7",
+ ],
+ "subnetId": "pae4o-o6dxf-xki7q-ezclx-znyd6-fnk6w-vkv5z-5lfwh-xym2i-otrrw-fqe",
+ }
+ `);
+ });
+
+ it('should return the node keys from a mainnet system subnet certificate', async () => {
+ const { mainnetSystem } = goldenCertificates;
+ jest.useFakeTimers();
+ jest.setSystemTime(new Date(Date.parse('2023-09-27T19:58:19.412Z')));
+ const cert = await Cert.Certificate.create({
+ certificate: fromHex(mainnetSystem),
+ canisterId: Principal.fromText('ryjl3-tyaaa-aaaaa-aaaba-cai'),
+ rootKey: fromHex(IC_ROOT_KEY),
+ });
+
+ const nodeKeys = cert.cache_node_keys();
+ expect(nodeKeys).toMatchInlineSnapshot(`
+ Object {
+ "nodeKeys": Array [
+ "302a300506032b6570032100526742592f1e331aa13db7d1ebf224ff0b8231e0626eeefad0b629413a93e798",
+ "302a300506032b657003210099c734e5f28c50741b04b63e87c77533d47dc2347524ed1ec8c266e429cef636",
+ "302a300506032b657003210054432c37b495e9206b46b5ce85da87a7eb2d853cd3f02feec4acf39efe982850",
+ "302a300506032b657003210059ef19e6aec7336d0912a80fe269ed4f0e8360cff9dc6fbe7a941643142bb4ff",
+ "302a300506032b657003210076f7f52d74955cc045838a6ef71b882dd5339ba058bdcf1085f893b3545d44bf",
+ "302a300506032b65700321000b4ca05b18b5dff4efc88badc802bccc4bae5ce2f16febe6a893904a240af360",
+ "302a300506032b65700321003f29994149099aa1b1d2dcdaabe5eda73aea6866d067e2c45b97e216532bcd33",
+ "302a300506032b65700321004323320684d4e1edb89bdcdee00844830a0f7de3e3cc7346e5a3868d1aef02b5",
+ "302a300506032b6570032100a8fa77ad6c1da6d50d04fbc96bf33d0e30a67c1e8ba97fa3ce7c3d9c868a7b99",
+ "302a300506032b65700321005e12ef0eae2809a5468471ee2d9745d23f20b1c0da7129fa447d96a67336be5b",
+ "302a300506032b6570032100995e3dcf4b0fe927bee5172cef595b53bace86185890f052939a63d24eabf0da",
+ "302a300506032b6570032100dc624cca12ec1daebedd007ec838e77990a6da3f8dff968ceebf3a0e8390562f",
+ "302a300506032b6570032100d1955dd0b79c84d036422763c3a29154f31ab907ecdcfc9870db91db3e9dba7b",
+ "302a300506032b6570032100767f31d2bb762bc9fa9b2cbe9f86504f16422f206fe4e61ec57b73a97fea2426",
+ "302a300506032b65700321003dac46790dd80a38b0238ac3e1c1766fb3049a3b46d406c4ad85ccff42317a1e",
+ "302a300506032b6570032100b80f4705b1420119acf881fb01e90f50044df72b1893cca44b4e81129e7a3e6e",
+ "302a300506032b65700321008aa5bb79948b296c12c14131b35f9009ce331981b08c7ec57a595c6eda59d693",
+ "302a300506032b6570032100031739d3139245f101349d4d2fb8cdc2e2707084d3fef1d033042d64ebd452bb",
+ "302a300506032b6570032100cd59f18eea954c1fc8e315099657d929b6bfb7fefadb7bb214448809f4a9d19f",
+ "302a300506032b657003210079d79503838b2b01791f66c18bc7614e19d3a6aba73bae00b92bb99edeea5287",
+ "302a300506032b6570032100879ee566edf8a11717120cca3e4b1521f07a781c6d79ddda637b3a4c770f6fc6",
+ "302a300506032b6570032100d8e091572c325ee4edf561c8f0c85f59203f4b79e955f2adcaf39dc9037b59cb",
+ "302a300506032b6570032100bfa1b1575803d5fb21032a69ff50a04a3394dba63c509e9a1ae9edf781b3f174",
+ "302a300506032b6570032100dc1a8cd77897793bb5b6bbbbbab2ac828f212c31ef7d8cd1a5e9da71d4368a1a",
+ "302a300506032b6570032100b9f3c99d054c571483371cabababeba71a95af2f1db75a9eff5362a00168bab3",
+ "302a300506032b6570032100cd8d2ec2ff21561e2772d9e68ea249dbe874c214899c33c5503444b34786be32",
+ "302a300506032b6570032100013eb950162c07d85df53e01759052f239e953b592d13121ca5c038e28b6ea28",
+ "302a300506032b65700321004558f956c1197f57de5eda61e88f6feb2bcd97cb69992edf3ed77326376447cc",
+ "302a300506032b6570032100455044dd9eaf7a0dd463d8e194f4c10bd4943cfc9beaf0e7ae4074373d154893",
+ "302a300506032b6570032100b1c163e31457e5af99033c20a313371c3a00237a3bedf2ce8cdfef475db5b875",
+ "302a300506032b65700321000391e646f29f87929474489743d2958abd973ded1826d146b1d5cd67ae05b55d",
+ "302a300506032b657003210004623b4767a979d854f118eaad12777b5ffa0ab0d9640708f68579cb4f670035",
+ "302a300506032b657003210072de1b160077674e745a9d03e75a9432622aada8229d36d12b48ce567882e0d3",
+ "302a300506032b6570032100c8cf4e899a7227b656028521ba6d7c305528e120498db2e145b5448b96f824cd",
+ "302a300506032b65700321002f2e7160e775b899b3921b3a9676373a542c7ee4965d3b43952781820b880b93",
+ "302a300506032b65700321003db88746a7def775447aebeab07f35a7ab325a1e156c1d076da2ef988cf4cf8d",
+ "302a300506032b657003210088eccdb0ceab1a41a33496dbfc7abac145d1674363c527f36707b53b354f7d23",
+ "302a300506032b65700321006fed5c19bfcdf67f1e8d9a866f826d89cb05bdcd40cb633a5d7645f82394665c",
+ "302a300506032b657003210038e87a8fcc24cdaad8541ad88a0d1f521a8c9bbc29379382055602ca59d226ff",
+ "302a300506032b65700321001909d5eefbb0075b3176069b7ac4a6e99934342a8fe5b3ec301d20b6cf453e53",
+ ],
+ "subnetId": "tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe",
+ }
+ `);
+ });
+
+ it('should return the node keys from a local application subnet certificate', async () => {
+ const { localApplication } = goldenCertificates;
+ jest.useFakeTimers();
+ jest.setSystemTime(new Date(Date.parse('2023-09-27T20:14:59.406Z')));
+ const cert = await Cert.Certificate.create({
+ certificate: fromHex(localApplication),
+ canisterId: Principal.fromText('ryjl3-tyaaa-aaaaa-aaaba-cai'),
+ rootKey: fromHex(IC_ROOT_KEY),
+ });
+
+ const nodeKeys = cert.cache_node_keys();
+ expect(nodeKeys).toMatchInlineSnapshot(`
+ Object {
+ "nodeKeys": Array [
+ "302a300506032b6570032100526742592f1e331aa13db7d1ebf224ff0b8231e0626eeefad0b629413a93e798",
+ "302a300506032b657003210099c734e5f28c50741b04b63e87c77533d47dc2347524ed1ec8c266e429cef636",
+ "302a300506032b657003210054432c37b495e9206b46b5ce85da87a7eb2d853cd3f02feec4acf39efe982850",
+ "302a300506032b657003210059ef19e6aec7336d0912a80fe269ed4f0e8360cff9dc6fbe7a941643142bb4ff",
+ "302a300506032b657003210076f7f52d74955cc045838a6ef71b882dd5339ba058bdcf1085f893b3545d44bf",
+ "302a300506032b65700321000b4ca05b18b5dff4efc88badc802bccc4bae5ce2f16febe6a893904a240af360",
+ "302a300506032b65700321003f29994149099aa1b1d2dcdaabe5eda73aea6866d067e2c45b97e216532bcd33",
+ "302a300506032b65700321004323320684d4e1edb89bdcdee00844830a0f7de3e3cc7346e5a3868d1aef02b5",
+ "302a300506032b6570032100a8fa77ad6c1da6d50d04fbc96bf33d0e30a67c1e8ba97fa3ce7c3d9c868a7b99",
+ "302a300506032b65700321005e12ef0eae2809a5468471ee2d9745d23f20b1c0da7129fa447d96a67336be5b",
+ "302a300506032b6570032100995e3dcf4b0fe927bee5172cef595b53bace86185890f052939a63d24eabf0da",
+ "302a300506032b6570032100dc624cca12ec1daebedd007ec838e77990a6da3f8dff968ceebf3a0e8390562f",
+ "302a300506032b6570032100d1955dd0b79c84d036422763c3a29154f31ab907ecdcfc9870db91db3e9dba7b",
+ "302a300506032b6570032100767f31d2bb762bc9fa9b2cbe9f86504f16422f206fe4e61ec57b73a97fea2426",
+ "302a300506032b65700321003dac46790dd80a38b0238ac3e1c1766fb3049a3b46d406c4ad85ccff42317a1e",
+ "302a300506032b6570032100b80f4705b1420119acf881fb01e90f50044df72b1893cca44b4e81129e7a3e6e",
+ "302a300506032b65700321008aa5bb79948b296c12c14131b35f9009ce331981b08c7ec57a595c6eda59d693",
+ "302a300506032b6570032100031739d3139245f101349d4d2fb8cdc2e2707084d3fef1d033042d64ebd452bb",
+ "302a300506032b6570032100cd59f18eea954c1fc8e315099657d929b6bfb7fefadb7bb214448809f4a9d19f",
+ "302a300506032b657003210079d79503838b2b01791f66c18bc7614e19d3a6aba73bae00b92bb99edeea5287",
+ "302a300506032b6570032100879ee566edf8a11717120cca3e4b1521f07a781c6d79ddda637b3a4c770f6fc6",
+ "302a300506032b6570032100d8e091572c325ee4edf561c8f0c85f59203f4b79e955f2adcaf39dc9037b59cb",
+ "302a300506032b6570032100bfa1b1575803d5fb21032a69ff50a04a3394dba63c509e9a1ae9edf781b3f174",
+ "302a300506032b6570032100dc1a8cd77897793bb5b6bbbbbab2ac828f212c31ef7d8cd1a5e9da71d4368a1a",
+ "302a300506032b6570032100b9f3c99d054c571483371cabababeba71a95af2f1db75a9eff5362a00168bab3",
+ "302a300506032b6570032100cd8d2ec2ff21561e2772d9e68ea249dbe874c214899c33c5503444b34786be32",
+ "302a300506032b6570032100013eb950162c07d85df53e01759052f239e953b592d13121ca5c038e28b6ea28",
+ "302a300506032b65700321004558f956c1197f57de5eda61e88f6feb2bcd97cb69992edf3ed77326376447cc",
+ "302a300506032b6570032100455044dd9eaf7a0dd463d8e194f4c10bd4943cfc9beaf0e7ae4074373d154893",
+ "302a300506032b6570032100b1c163e31457e5af99033c20a313371c3a00237a3bedf2ce8cdfef475db5b875",
+ "302a300506032b65700321000391e646f29f87929474489743d2958abd973ded1826d146b1d5cd67ae05b55d",
+ "302a300506032b657003210004623b4767a979d854f118eaad12777b5ffa0ab0d9640708f68579cb4f670035",
+ "302a300506032b657003210072de1b160077674e745a9d03e75a9432622aada8229d36d12b48ce567882e0d3",
+ "302a300506032b6570032100c8cf4e899a7227b656028521ba6d7c305528e120498db2e145b5448b96f824cd",
+ "302a300506032b65700321002f2e7160e775b899b3921b3a9676373a542c7ee4965d3b43952781820b880b93",
+ "302a300506032b65700321003db88746a7def775447aebeab07f35a7ab325a1e156c1d076da2ef988cf4cf8d",
+ "302a300506032b657003210088eccdb0ceab1a41a33496dbfc7abac145d1674363c527f36707b53b354f7d23",
+ "302a300506032b65700321006fed5c19bfcdf67f1e8d9a866f826d89cb05bdcd40cb633a5d7645f82394665c",
+ "302a300506032b657003210038e87a8fcc24cdaad8541ad88a0d1f521a8c9bbc29379382055602ca59d226ff",
+ "302a300506032b65700321001909d5eefbb0075b3176069b7ac4a6e99934342a8fe5b3ec301d20b6cf453e53",
+ ],
+ "subnetId": "tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe",
+ }
+ `);
+ });
+
+ it('should return the node keys from a local system subnet certificate', async () => {
+ const { localSystem } = goldenCertificates;
+ jest.useFakeTimers();
+ jest.setSystemTime(new Date(Date.parse('2023-09-27T20:15:03.406Z')));
+ const cert = await Cert.Certificate.create({
+ certificate: fromHex(localSystem),
+ canisterId: Principal.fromText('ryjl3-tyaaa-aaaaa-aaaba-cai'),
+ rootKey: fromHex(IC_ROOT_KEY),
+ });
+
+ const nodeKeys = cert.cache_node_keys();
+ expect(nodeKeys).toMatchInlineSnapshot(`
+ Object {
+ "nodeKeys": Array [
+ "302a300506032b6570032100526742592f1e331aa13db7d1ebf224ff0b8231e0626eeefad0b629413a93e798",
+ "302a300506032b657003210099c734e5f28c50741b04b63e87c77533d47dc2347524ed1ec8c266e429cef636",
+ "302a300506032b657003210054432c37b495e9206b46b5ce85da87a7eb2d853cd3f02feec4acf39efe982850",
+ "302a300506032b657003210059ef19e6aec7336d0912a80fe269ed4f0e8360cff9dc6fbe7a941643142bb4ff",
+ "302a300506032b657003210076f7f52d74955cc045838a6ef71b882dd5339ba058bdcf1085f893b3545d44bf",
+ "302a300506032b65700321000b4ca05b18b5dff4efc88badc802bccc4bae5ce2f16febe6a893904a240af360",
+ "302a300506032b65700321003f29994149099aa1b1d2dcdaabe5eda73aea6866d067e2c45b97e216532bcd33",
+ "302a300506032b65700321004323320684d4e1edb89bdcdee00844830a0f7de3e3cc7346e5a3868d1aef02b5",
+ "302a300506032b6570032100a8fa77ad6c1da6d50d04fbc96bf33d0e30a67c1e8ba97fa3ce7c3d9c868a7b99",
+ "302a300506032b65700321005e12ef0eae2809a5468471ee2d9745d23f20b1c0da7129fa447d96a67336be5b",
+ "302a300506032b6570032100995e3dcf4b0fe927bee5172cef595b53bace86185890f052939a63d24eabf0da",
+ "302a300506032b6570032100dc624cca12ec1daebedd007ec838e77990a6da3f8dff968ceebf3a0e8390562f",
+ "302a300506032b6570032100d1955dd0b79c84d036422763c3a29154f31ab907ecdcfc9870db91db3e9dba7b",
+ "302a300506032b6570032100767f31d2bb762bc9fa9b2cbe9f86504f16422f206fe4e61ec57b73a97fea2426",
+ "302a300506032b65700321003dac46790dd80a38b0238ac3e1c1766fb3049a3b46d406c4ad85ccff42317a1e",
+ "302a300506032b6570032100b80f4705b1420119acf881fb01e90f50044df72b1893cca44b4e81129e7a3e6e",
+ "302a300506032b65700321008aa5bb79948b296c12c14131b35f9009ce331981b08c7ec57a595c6eda59d693",
+ "302a300506032b6570032100031739d3139245f101349d4d2fb8cdc2e2707084d3fef1d033042d64ebd452bb",
+ "302a300506032b6570032100cd59f18eea954c1fc8e315099657d929b6bfb7fefadb7bb214448809f4a9d19f",
+ "302a300506032b657003210079d79503838b2b01791f66c18bc7614e19d3a6aba73bae00b92bb99edeea5287",
+ "302a300506032b6570032100879ee566edf8a11717120cca3e4b1521f07a781c6d79ddda637b3a4c770f6fc6",
+ "302a300506032b6570032100d8e091572c325ee4edf561c8f0c85f59203f4b79e955f2adcaf39dc9037b59cb",
+ "302a300506032b6570032100bfa1b1575803d5fb21032a69ff50a04a3394dba63c509e9a1ae9edf781b3f174",
+ "302a300506032b6570032100dc1a8cd77897793bb5b6bbbbbab2ac828f212c31ef7d8cd1a5e9da71d4368a1a",
+ "302a300506032b6570032100b9f3c99d054c571483371cabababeba71a95af2f1db75a9eff5362a00168bab3",
+ "302a300506032b6570032100cd8d2ec2ff21561e2772d9e68ea249dbe874c214899c33c5503444b34786be32",
+ "302a300506032b6570032100013eb950162c07d85df53e01759052f239e953b592d13121ca5c038e28b6ea28",
+ "302a300506032b65700321004558f956c1197f57de5eda61e88f6feb2bcd97cb69992edf3ed77326376447cc",
+ "302a300506032b6570032100455044dd9eaf7a0dd463d8e194f4c10bd4943cfc9beaf0e7ae4074373d154893",
+ "302a300506032b6570032100b1c163e31457e5af99033c20a313371c3a00237a3bedf2ce8cdfef475db5b875",
+ "302a300506032b65700321000391e646f29f87929474489743d2958abd973ded1826d146b1d5cd67ae05b55d",
+ "302a300506032b657003210004623b4767a979d854f118eaad12777b5ffa0ab0d9640708f68579cb4f670035",
+ "302a300506032b657003210072de1b160077674e745a9d03e75a9432622aada8229d36d12b48ce567882e0d3",
+ "302a300506032b6570032100c8cf4e899a7227b656028521ba6d7c305528e120498db2e145b5448b96f824cd",
+ "302a300506032b65700321002f2e7160e775b899b3921b3a9676373a542c7ee4965d3b43952781820b880b93",
+ "302a300506032b65700321003db88746a7def775447aebeab07f35a7ab325a1e156c1d076da2ef988cf4cf8d",
+ "302a300506032b657003210088eccdb0ceab1a41a33496dbfc7abac145d1674363c527f36707b53b354f7d23",
+ "302a300506032b65700321006fed5c19bfcdf67f1e8d9a866f826d89cb05bdcd40cb633a5d7645f82394665c",
+ "302a300506032b657003210038e87a8fcc24cdaad8541ad88a0d1f521a8c9bbc29379382055602ca59d226ff",
+ "302a300506032b65700321001909d5eefbb0075b3176069b7ac4a6e99934342a8fe5b3ec301d20b6cf453e53",
+ ],
+ "subnetId": "tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe",
+ }
+ `);
+ });
+});
diff --git a/packages/agent/src/certificate.ts b/packages/agent/src/certificate.ts
index 1e8576413..3682c9b9b 100644
--- a/packages/agent/src/certificate.ts
+++ b/packages/agent/src/certificate.ts
@@ -21,20 +21,35 @@ interface Cert {
delegation?: Delegation;
}
-const enum NodeId {
- Empty = 0,
- Fork = 1,
- Labeled = 2,
- Leaf = 3,
- Pruned = 4,
-}
+const NodeId = {
+ Empty: 0,
+ Fork: 1,
+ Labeled: 2,
+ Leaf: 3,
+ Pruned: 4,
+};
+
+export type NodeIdType = typeof NodeId[keyof typeof NodeId];
+
+export { NodeId };
export type HashTree =
- | [NodeId.Empty]
- | [NodeId.Fork, HashTree, HashTree]
- | [NodeId.Labeled, ArrayBuffer, HashTree]
- | [NodeId.Leaf, ArrayBuffer]
- | [NodeId.Pruned, ArrayBuffer];
+ | [typeof NodeId.Empty]
+ | [typeof NodeId.Fork, HashTree, HashTree]
+ | [typeof NodeId.Labeled, ArrayBuffer, HashTree]
+ | [typeof NodeId.Leaf, ArrayBuffer]
+ | [typeof NodeId.Pruned, ArrayBuffer];
+
+/**
+ * Represents the useful information about a subnet
+ * @param {string} subnetId the principal id of the canister's subnet
+ * @param {string[]} nodeKeys the keys of the individual nodes in the subnet
+ */
+export type SubnetStatus = {
+ // Principal as a string
+ subnetId: string;
+ nodeKeys: string[];
+};
/**
* Make a human readable string out of a hash tree.
@@ -59,19 +74,38 @@ export function hashTreeToString(tree: HashTree): string {
case NodeId.Empty:
return '()';
case NodeId.Fork: {
- const left = hashTreeToString(tree[1]);
- const right = hashTreeToString(tree[2]);
- return `sub(\n left:\n${indent(left)}\n---\n right:\n${indent(right)}\n)`;
+ if (tree[1] instanceof Array && tree[2] instanceof ArrayBuffer) {
+ const left = hashTreeToString(tree[1]);
+ const right = hashTreeToString(tree[2]);
+ return `sub(\n left:\n${indent(left)}\n---\n right:\n${indent(right)}\n)`;
+ } else {
+ throw new Error('Invalid tree structure for fork');
+ }
}
case NodeId.Labeled: {
- const label = labelToString(tree[1]);
- const sub = hashTreeToString(tree[2]);
- return `label(\n label:\n${indent(label)}\n sub:\n${indent(sub)}\n)`;
+ if (tree[1] instanceof ArrayBuffer && tree[2] instanceof ArrayBuffer) {
+ const label = labelToString(tree[1]);
+ const sub = hashTreeToString(tree[2]);
+ return `label(\n label:\n${indent(label)}\n sub:\n${indent(sub)}\n)`;
+ } else {
+ throw new Error('Invalid tree structure for labeled');
+ }
}
case NodeId.Leaf: {
+ if (!tree[1]) {
+ throw new Error('Invalid tree structure for leaf');
+ } else if (Array.isArray(tree[1])) {
+ return JSON.stringify(tree[1]);
+ }
return `leaf(...${tree[1].byteLength} bytes)`;
}
case NodeId.Pruned: {
+ if (!tree[1]) {
+ throw new Error('Invalid tree structure for pruned');
+ } else if (Array.isArray(tree[1])) {
+ return JSON.stringify(tree[1]);
+ }
+
return `pruned(${toHex(new Uint8Array(tree[1]))}`;
}
default: {
@@ -132,6 +166,7 @@ export interface CreateCertificateOptions {
export class Certificate {
private readonly cert: Cert;
+ #nodeKeys: string[] = [];
/**
* Create a new instance of a certificate, automatically verifying it. Throws a
@@ -156,6 +191,7 @@ export class Certificate {
blsVerify,
options.maxAgeInMinutes,
);
+
await cert.verify();
return cert;
}
@@ -172,7 +208,50 @@ export class Certificate {
}
public lookup(path: Array): ArrayBuffer | undefined {
- return lookup_path(path, this.cert.tree);
+ // constrain the type of the result, so that empty HashTree is undefined
+ return lookupResultToBuffer(lookup_path(path, this.cert.tree));
+ }
+
+ public lookup_label(label: ArrayBuffer): ArrayBuffer | HashTree | undefined {
+ return this.lookup([label]);
+ }
+
+ public cache_node_keys(root_key?: Uint8Array): SubnetStatus {
+ const tree = this.cert.tree;
+ let delegation = this.cert.delegation;
+ // On local replica, with System type subnet, there is no delegation
+ if (!delegation && typeof root_key !== 'undefined') {
+ delegation = {
+ subnet_id: Principal.selfAuthenticating(root_key).toUint8Array(),
+ certificate: new ArrayBuffer(0),
+ };
+ }
+ // otherwise use default NNS subnet id
+ else if (!delegation) {
+ delegation = {
+ subnet_id: Principal.fromText(
+ 'tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe',
+ ).toUint8Array(),
+ certificate: new ArrayBuffer(0),
+ };
+ }
+ const nodeTree = lookup_path(['subnet', delegation?.subnet_id as ArrayBuffer, 'node'], tree);
+ const nodeForks = flatten_forks(nodeTree as HashTree) as HashTree[];
+ nodeForks.length;
+
+ this.#nodeKeys = nodeForks.map(fork => {
+ const derEncodedPublicKey = lookup_path(['public_key'], fork[2] as HashTree) as ArrayBuffer;
+ if (derEncodedPublicKey.byteLength !== 44) {
+ throw new Error('Invalid public key length');
+ } else {
+ return toHex(derEncodedPublicKey);
+ }
+ });
+
+ return {
+ subnetId: Principal.fromUint8Array(new Uint8Array(delegation.subnet_id)).toText(),
+ nodeKeys: this.#nodeKeys,
+ };
}
private async verify(): Promise {
@@ -287,6 +366,22 @@ function extractDER(buf: ArrayBuffer): ArrayBuffer {
return buf.slice(DER_PREFIX.byteLength);
}
+/**
+ * utility function to constrain the type of a path
+ * @param {ArrayBuffer | HashTree | undefined} result - the result of a lookup
+ * @returns ArrayBuffer or Undefined
+ */
+export function lookupResultToBuffer(
+ result: ArrayBuffer | HashTree | undefined,
+): ArrayBuffer | undefined {
+ if (result instanceof ArrayBuffer) {
+ return result;
+ } else if (result instanceof Uint8Array) {
+ return result.buffer;
+ }
+ return undefined;
+}
+
/**
* @param t
*/
@@ -332,11 +427,20 @@ function domain_sep(s: string): ArrayBuffer {
export function lookup_path(
path: Array,
tree: HashTree,
-): ArrayBuffer | undefined {
+): ArrayBuffer | HashTree | undefined {
if (path.length === 0) {
switch (tree[0]) {
case NodeId.Leaf: {
- return new Uint8Array(tree[1]).buffer;
+ // should not be undefined
+ if (!tree[1]) throw new Error('Invalid tree structure for leaf');
+ if (tree[1] instanceof ArrayBuffer) {
+ return tree[1];
+ } else if (tree[1] instanceof Uint8Array) {
+ return tree[1].buffer;
+ } else return tree[1];
+ }
+ case NodeId.Fork: {
+ return tree;
}
default: {
return undefined;
diff --git a/packages/assets/src/index.ts b/packages/assets/src/index.ts
index 626ebb78f..9c4e91618 100644
--- a/packages/assets/src/index.ts
+++ b/packages/assets/src/index.ts
@@ -8,6 +8,7 @@ import {
getDefaultAgent,
HashTree,
lookup_path,
+ lookupResultToBuffer,
reconstruct,
uint8ToBuf,
} from '@dfinity/agent';
@@ -563,7 +564,7 @@ class Asset {
}
// Lookup hash of asset in tree
- const treeSha = lookup_path(['http_assets', this._key], hashTree);
+ const treeSha = lookupResultToBuffer(lookup_path(['http_assets', this._key], hashTree));
return !!treeSha && !!this.sha256 && compare(this.sha256.buffer, treeSha) === 0;
}