diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3cb3bd4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +input.txt diff --git a/README.md b/README.md index 9917858..e0daf26 100644 --- a/README.md +++ b/README.md @@ -3,32 +3,61 @@ [![](https://img.shields.io/badge/stars%20⭐-12-yellow)](#2024-results) [![](https://img.shields.io/badge/days%20completed-6-red)](#2024-results) - [Advent of Code 2024](https://adventofcode.com/2024) using(/learning) Deno and Zed. -## Usage +## Setup + +Create an `.env` file with the following content: + +```sh +AOC_SESSION=your_session_cookie +INPUT_KEY=encryption_key +``` + +Per AoC guidelines, the inputs should not be stored in your repo so that people cannot reverse their generation strategies. +In order to preserve replayability, the input data is encrypted using the `INPUT_KEY` and stored that way instead. +After pulling a fresh copy of the repo, you can decrypt the input data by running the following command (assuming you have the correct key): + +```sh +deno run decrypt +``` + +This was quite the rabbit hole to go down for this small payoff but whatever. 🤷‍♀️ -Duplicate the `src/00` directory and rename it to the two-digit, one-indexed number of the day's challenge. -Paste the sample and input data into their respective files. +## Daily Workflow -Use the `dev` task to run the tests in watch mode against the sample data: +1. Duplicate the `src/00` directory and name the copy `src/XX` using the two-digit, one-indexed number of the day's challenge. +2. Copy-pasta the sample data into `sample.txt`. +3. Use the `dev` task to run the tests in watch mode against the sample data: ```sh DAY=XX deno run dev ``` -Use the `solve` task to output a solution based on the input data: +4. Use the `solve` task to output a solution based on the input data: ```sh DAY=XX deno run solve ``` +5. Add the solution and timing to the top of that day's `main.ts` for posterity. +6. Duplicate `test.ts` and name the copy `input.test.ts`. Change the target to `input` and update the expected values. +7. Commit with message `day XX` and push, triggering an update of the star/day progress tracking in this README. + +## Other Tasks + Use the `test` task to run all tests against the sample data (mostly for CI): ```sh deno run test ``` +Use the `test:input` task to run all tests against the input data (mostly for validating changes to the repo structure): + +```sh +deno run test:input +``` + ## 2024 Results diff --git a/deno.json b/deno.json index e2db94a..4087a51 100644 --- a/deno.json +++ b/deno.json @@ -1,10 +1,17 @@ { "tasks": { + "decrypt": "deno run -ERW src/encrypt.ts --decrypt", "dev": "deno test --watch -R src/$DAY/test.ts", + "input": "deno run -NEWR src/encrypt.ts --get=$DAY", "solve": "deno run -R src/$DAY/main.ts", - "test": "deno test -R src" + "test": "deno test -R src/**/test.ts", + "test:input": "deno test -R src/**/input.test.ts" }, "imports": { - "@std/assert": "jsr:@std/assert@^1.0.8" + "@std/assert": "jsr:@std/assert@^1.0.8", + "@std/cli": "jsr:@std/cli@^1.0.8", + "@std/crypto": "jsr:@std/crypto@^1.0.3", + "@std/dotenv": "jsr:@std/dotenv@^0.225.3", + "@std/encoding": "jsr:@std/encoding@^1.0.5" } } diff --git a/deno.lock b/deno.lock index 26c4ceb..4e75873 100644 --- a/deno.lock +++ b/deno.lock @@ -2,6 +2,10 @@ "version": "4", "specifiers": { "jsr:@std/assert@^1.0.8": "1.0.8", + "jsr:@std/cli@^1.0.8": "1.0.8", + "jsr:@std/crypto@^1.0.3": "1.0.3", + "jsr:@std/dotenv@~0.225.3": "0.225.3", + "jsr:@std/encoding@^1.0.5": "1.0.5", "jsr:@std/internal@^1.0.5": "1.0.5" }, "jsr": { @@ -11,13 +15,29 @@ "jsr:@std/internal" ] }, + "@std/cli@1.0.8": { + "integrity": "3762d8dc9a373715c08d871c38d45e637b25266f013a1d0bbe560bca409de94e" + }, + "@std/crypto@1.0.3": { + "integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f" + }, + "@std/dotenv@0.225.3": { + "integrity": "a95e5b812c27b0854c52acbae215856d9cce9d4bbf774d938c51d212711e8d4a" + }, + "@std/encoding@1.0.5": { + "integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04" + }, "@std/internal@1.0.5": { "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" } }, "workspace": { "dependencies": [ - "jsr:@std/assert@^1.0.8" + "jsr:@std/assert@^1.0.8", + "jsr:@std/cli@^1.0.8", + "jsr:@std/crypto@^1.0.3", + "jsr:@std/dotenv@~0.225.3", + "jsr:@std/encoding@^1.0.5" ] } } diff --git a/src/00/input.txt b/src/00/input.txt deleted file mode 100644 index e69de29..0000000 diff --git a/src/00/test.ts b/src/00/test.ts index dbc6332..d1a46fd 100644 --- a/src/00/test.ts +++ b/src/00/test.ts @@ -1,7 +1,14 @@ import { assertEquals } from "@std/assert"; import { main } from "./main.ts"; -Deno.test("correct placeholder for sample", async () => { - const result = await main("sample"); +const target = "sample"; + +Deno.test(`correct placeholder1 for ${target}`, async () => { + const result = await main(target); + assertEquals(result.text, ""); +}); + +Deno.test(`correct placeholder2 for ${target}`, async () => { + const result = await main(target); assertEquals(result.text, ""); }); diff --git a/src/01/enput.txt b/src/01/enput.txt new file mode 100644 index 0000000..ebe8eaa --- /dev/null +++ b/src/01/enput.txt @@ -0,0 +1,2 @@ +251,110,61,205,195,124,57,248,160,76,204,81 +183a0003553c69911bdc92230ff1d9d3cf7156244935504b10d73c7e72a43c124db6e6b11298939f537f04e3c50df756b0818f3c7f4b7c03759237052a8b86470f4eacb24a34e965b4176f3b1ebecea3d74792e5d07dac7e8b5f733d93a41c15b9ff73d2be56acc6f90d7306fd71b74006f57decf974c917d053e95477bc962cd5789a18f3666e9539b3f509c0500beb5b74b1ac47f594d00d3485185539bc2c1520e982d49492f3b25ef5c5880e8bf206ade5d92f7cc36c04dbbd09fa14195de3b9321f982ae52cecee69e6998c8df7b6762769a25eb4f3df09920ff7f58925222491e4efa51c3dde3d36bc8187ad5e086073396fd1aa300f1a9c0dd0b67ecb04dcddd159008a27ec966a7decf0edbb6d81de46f59eb7330b6237c9ff6f6d7e1813666729cf50ae3cb6bf814deaddc1810cad6aaf1d741d8fc7ccc2e09a9cc3a262668f90f365d215718a24c561da0509a1839d29d0c10a3e276b0ac7126c6491ede055be2e37cebc1ce6719feec498cc47a4db9614c0d2ec44294e3ab822edef5507b935e76bbbaaa6eb66a816f422131ed1cb64f603d969fca272a2a1362d4acae974d50002a10229eb55b0fa40551a1ac7432cf3ff71623462354cd7a1f63069285e6147af8a472bc8658c716fded3dcecdfafa51a9b66ea7f101347a375f1ad399006e1ee8c45d35972a6352113dff61c87f9c3ae44ae0c86bf93185ad4d5341660b7663cdea54fe7200bad9c2a323eb3199332824d5d5582df24ebd39ad801129fdf3ffc0cf18e5cad55041583db0f8996845258bc07d75c7eae7c6958553542be5ac983259d314670738da46046b0155860a28249153c2ef76ec800e66954e6f15fa862c61b32cd93fb4a712eefa8b0f8b4b065744fa6963345efbfa6bc3305212aef6b1484482ffc9992ce12970177de9c745545856bf07a35ae4ed8ee02e88e2e85b4a879d790783332f4e2a075b5fbf7b4d0cfc2889458616fb0fbdb280b48ef8f69c50be67feaf80a9eccd969e9f9b82e0f143d2c4e878b3fd30a15b00ca7adf98d095b212b56c03cd993986d9935268b4bae3d3cad6676bc18c100aa7dd263ddef8218b03295d71b9201d9246431df45d0cc2b3fb4fb8804b763c9db9c3c44053a6ada8c6a7359b0d9011ddf2635850c2bf970afb79a86fadb70a2017d3cc55ce5c128c410a878543a851d115970e9a23f7825c52021ae6aa36f2a5bfaee45fa9d66403520f84302a42cea5312cac0d3f1e868f6c853bc112bb950accf6493948aa5f0b2ec9b323dbfdc6b65eef844701ca57d1903206bb5d2359e893beb0c58474b95967ede13edd05d56cdced829e57aa0e14ce4f2da7d508f2c3c5190de42a7e55ea379d802cad29f5e576b3aac0e8c07341f290f90d5e40f72ef06d7456e1042a3eba02fcb27ad7f42bb3df86a8d892b874f24845a187245110829cebd3b846c4d41617c488835123179197123a7428dd1a193ab23e876c48512120902a3dccfd6fc51531626fc4654e530dc06f68cad88f07bcfd4cca83de0ab760799bd069cb9df3590ed44aa465bd914fc185d6b07af3ef006e7d15a51d1b33ca7161c0804f1eec57761c9b75e811dce056d29becd00a6ec8e5707ca9b0f345d464c8a3327757a44f670fffc4d936bbfb3cd8c4a86d7cfde397c28008c19a2a624c090b8e993f800c52bb99ade8ca792a810dd76baa9af6d485d6a132e6dd22406d3f38985b2109654f733276766c4248bec0051b2ad33bd929b65b38c44c82a385866ecbe3084984dce16722c3e1d0102dbbce8068dfecce2ac4d6e7f5efdb2b1e8e5d2a8e6ae5dba5d320a28c3068351a03e6cf5fac7a366f143623d65e9e7f5ac4a315c41072560869cffa61346f4a83fbca78bfe8c01bffff99b1e85a7266f71bebc8eb02bf66a46ebdc445282d88e905301c2fe2a77e4e3a6f7c49c2bedf2e55bf4518ce1911424fc2c80151c80f54c16b85b0828852767d6de03c416832451630a066f33c33b26b662a9577c2c2c4f3abe9abeada7a7779a4a9b08aa8464be066e1ea5cc22b1cb1948ad756ca1203da440cd7d4cc16ca2aee16969eceb78988aac9f25d706e391c5fef3dcd13f11c78fcb67fe6b8e9e195ea906252d2956ce0471b212af00d35edc62d106d0bd3d053562e31db737a46b9d788f9379f59ecd542718652040e462da2bb03c99e328b2067d5c9e227bd238d3eb1ba586bc5d2059810bf5e81c73cc2fee678a789dc2f2db60e515f7a869adeee48481990da69cbe5f6c902d76b1e5007da9a787df0eb80db2de650a7c8da4746a12412f929ca7e1f4d6b9ee1ee110163854f6408409f67d67acc894d7f4916a483a34bb9be18fb07305594f54857b2359227406575d55f00f2e50feb8f002d6624bc401a79da5bf9f5b9ceab007c64c769ac670c9f1af3e7e2e15b9fda19c7e9eaaac040bc17f24398bd82dfa1c54f3fd70cc0117b83f46eedb43165b6f345a126d417a9a3aa23727f75fcf3806322cf4427c4f358d6f00007b2c637ba4048ee18627cb040ad572381ac81afb63265ef5d829096c9c3fd6910646053bd4647e2bb34ed8c332c85a8190cfaeacb9e66b453886b4f41b94bc35d2347255136a440b4705ff775938714d7bf5dd5a2026ced02054e99c6f1f2f4da0f5c36dc356cc1787ef0e5dd449ab187e2edfeee77e4e75ce05175d36ea6d7cbd28be6359422034e8df9533f8c43bbea529221626e056247dcccc916e5bb4894bf1d6e1f97eab3385c47794e04c182ac630cad1d8f9171831795ac4a063ab399daffa59bd120cde2deaaefaf400ad477b38627c92f9239221ae768df7a90170654ff90eb9b61fa8edaa2e9ed3703c0de7ddb20e8a1c58b1bbecb86a4273725a6cb961099b460893acd30389b17b5cfda483718fc14c999ceec0084438ce8c2a2b477e7b9aa09f7f7726299c62a3b35162b2166cdd3b91fa443abb24908814084f830607c9fd7bc2bc8818b8a11aa9c55e61a7484ac098fab7140637a6b333a9c2871a338c2ed27e6e8f50c636fe0c2c3b8bcde45594cc904b19dae549b7fd8659fb9834bdc8d0b94df8cd29485053a5f088dfd113dbeb1351a8271012b7df61955197a4b891560d2c8388fc56bba3e02d5854ac53346d8f11c821ad3047036bf8f9e441a55ddbf49f4587d9268e9e5a2d428b3fc62838d211a410ce0c666153824aaeebbe161ef1442af91f3c31e12253ac3dc646f6e50f9838a7cc1b7cfe4f936c4f611d8e53d3a0d04b12f23a06b3e141bf15f402ba8351ad937c37d3313240a1ac66d82b5c78b3ee78f799be9c2d9c5d63c928503b1ffea25cc493e616610f9a275e39553f1370348179408d4cb8f00e7602729e8fee9de985138890380936eede6289723e964873a8e3809500a6b061401a1cf152de15ceb13403bbfd05daa590d3bcfd8d674441118abbfea83b2aa5a8d3c09aed087a9b6e4ea8629a851199c956450ccc37ec7df62cc7cd9cf9614ed7158fff66ae25640700ed88edc2c0ebffd69302d695709733386e7cd32027e4c7bfb69518d388d5349ef3efec9944e84d9c3090a028d36f3eb6fafa836b2b1a0f05ea6b29d78d0d3ed619f8f56bf50431f11d19264c3f0843af41474a915cf9793ec8d778044263b30a53970d2a364157e053cd84a24f6e531f203fa51bb402cb269449cb6749c205f4820e1f10cd5cf48403d3ef5921f7d54bee114d7fb665cedd747403c084bf070c1e58e7340c928d3fbf00565a57e8aec7a91e645e402f23bd4bf978692df4f29ae1a8f9c108c025a26d171d4e5fd68a0d3512df5d919589affa1f1e6cafb92daf5c46cd81ab12c3ea5fce79c49bfabb6022848fba14890149a63cba5e9446b0cbc36c2d26111c13149ebb754dfccd534ecc01131a1b77ff588d4933babce36045712ffd101a9dff72e4537c6b34bc11fdf2371c44c2163b128b0ff36822697623615b8f425b999a9365ba28930feedcf2cf0eb978113d6dc6a785a860a336055133c2aca44cae657653ed7a985d4416731d8f5b09cd00de6f2a9570c72f9188cb128d9b142ccc926f84c8f6d5dca443fd3433f9bbfbb820a3c535d773865db447e7b9aea872fb4840c7e500363acfb76ab6bdfa7e9983d6f6e5678f5b7cc8576b31276dc8bdf305e44a41c5b775d8f4c6b4cbe60dccf8bd7a0d0e3d100f5a4a0f3c65827e68ed26204b1cdf15f702dc3549cdd7c40fe018c66b5c7f9d30bb5ae9c535a867a2e443ad8940c4c030de85a9c6270625e636ea1fca015806a7ea8d1b49d301352d49b92c67b8bc30965c224c48bc75627cbc649c998b1bd18ad5039724ab8d09de1c8aca58a7ff1ab24ba14739532bebfb7bf12d14799291eb95a5600255c3c6452cefd013f3c4de12d8bf385f1af67750492f6ed8f178332b4c35dbaea382676abf6458baeffee2ef0da72d4769ef3659a7042ca01e025764225d6cd8b448d9735bb60c0b60315cf0011843ded4831b0ff6abacc6b9071009c2747cc1868025187ec2a603ad5bb3f19efc12d45f803f15c59421cf37eb0802eeede71cd5be8c5abdadec03dde3da220f7aad7929a631b23a5abcd3842a2e614e54f4463a7f207c7bb9697a8a2a93fb40150ec76851f11a395d2c55f834fd6bca7898b5b11ea8e3a6d211217df031d3bc4a8f2be7c41ccacea89574729538ce088c83075ef0bdaa2579ea6e3aa15afd0da09f79fddd034b358096f3ea7547fd26b85ab33956bbd144e7d5781cbd3fd04188d5b80881e98e41e1afd5c8947f14e77a866f858af360b8db5be2a72c629f4ef7a36e9249aa35728d4d576e83bbc4ae608269d8f6dbac5a991c6abf5df7982c2cd4c58bb7dc40b51d0951fdc4f0fafc0aea4bbdbbd4603f8d4ff5a13d6ca131e6cce14dc4caca7e9ad4bfcd521c5b79abfc497bec5fed9deed8537e01188582f2a3efb4486997437c184c68b6689c6e54c8e223089e720b7df37b22c79f29a5ca55ca31c271ffd87ee76a67905695b5839e84c4ebb53016cc411aaa38716a387df34fb6f0183cd6dd4c3039d626194fff9fb39afca05ecdfc60fb58cbe4655af87eecc11836bc7f202da98a9af4be31e99d07f62f0681949f350f8a6c659ce4ef990d01c0b7c3388198395c8bf0fb0fd9140ce00a81bad2f5da3e57693742a1078d7e122cd3788e18b703bb665006d1237c692d9d79d67975b00632c5a2085c1fd98094281381021b03440e87bc666dcdd44fc9d1a5b6a3a2fab2be9981901aa5c6a868f1dff60ddde9396f476f89a51a2ecde45974fa45f7e0c8109ca857bb9756a6f37e7ece2792dbfeb2575e02ed0e513e7d70a2e700ce83fd46c1976f02873150783797b720d815396aedb2c9a0e46100a498a759f4b7574ec6f5687765ec67a95d4a6c6602da91c68f4a9444fbc590c3b2a58eb93ef518b01d8ea174ffdddfdcc0ca0cb035326ea08cc40b3274516148c116f8fc707d6f264ed6301ac98c07f21efa2f8863c9e865b141f3cb6c93caa596f24c95c4bc6b81de536db629ed5371691578719ff93e49eabeeae68047846e95fb9feb9fb48339b9098c8937108f6dd5b92a66d4f85cf37e825b837265dead56601b84b16462a5bf1beef5b004d2044e79ccbb61935100f90b940c9fb9b15f3e1711590cb4405d5a055cfb091abb232a4d6524c3938e7af83040066f03ec8e0a435230b00dbe4761bc0175a1e8afaab0a8081a07e3ad07186b8932cfd364df1563e855f7a3877a91f63f122bbcaaa6e5081aaf1ce7df5f157ef60d5b60334e43f8c938eb73e136985e9463e3555edbdbfa99aaf32156b3d0eae3634ee3730922797cfb7ad323f960037b100de04f43531507def1edaebc20c22f08c38e7e2d739340883daaec737dd566380845af72842a2c72fb56c56324b832bcf7fe35a1095ff3da63acc40734f4d9130694e1fa614645ea973ca3cda2073f10df26b327e7c496cbdcc0c080ef0f3850a3d36504459eca3bc5c57b330aba0b8db3408a14d7a29b2adb94f6f64dcee7ff6c912ce70cd141fcc116af5d2ea9e8ac83fa19aa376b95b0ef73950c73357e90b348d0fb1cac34cdc11158cbbabba6f29bb29105850497ae14b29dc1118a15975f74aa0b951d3c6ae9a8f40d3aa23b64037fa801e2fdaa16f207df8e0549bf760c42961a961e84fa856657ed3948e07e3c4b0efa437f6270422fec2e7c4edcd1feb2d7fcf6a49b99efbc214ac7443fc3d93e7718548de12966cb3c9838561b6a60db9a64ec593cb9db15b354f00b7850b38b2ab924f6afb83de432331e9e99872831cfb98256e44d90f13145e9ecc396ba39bdab940bf460955f9fc87b9dff48a305ab5917296c449f6ea7da80e37e1be4232df65f37ab25ca7780af2f2baa65fe75ce742da6ac75e457eb6bc696ea745a55964aa87346fb009e5d4181a6ee2a4a22931e0c90070277b4271769103f2bfeb554a844b257771661b846992f8164238f95b8042c7f0e74adc3c478e9a72dd695b500017cdab9e4923ff22e5ff35d9ebdb171f6954464d04b7319a9f89e21ba9e2ecf3191c8850b7d28e3df8d36c5f1f8ae105f31cc5a96be5dc732d6f69ff6327783f15081d482cfda6287f9908dca72fa928594f477bf88f56542ca2209354a0db67ee96dfdde923aed8dc4a62a5ed6e4f10f8c34c3cf487304a10a9c3ed674d958a6bd741d478006f3d8af9d5237a5e2ad82e146cb303eeb2e0dc540944cd213a361267ff5eba105efa6915e9e05f48ff55804a1807076267db46328758f822fd28e0c67e51f7ae6424ec070f033028914148b3ff2cfafe616ec7a9757ac85d27f7bda46f173bf0ae80d8cc2a3a0c8ccaa258ee780fb8a62bc7c80a81ce3879f83ed613411b4b1a614f70d9a2ecf50354a350abcc0693358825affc8924d98341cb756efc0c123642ee8773b910a42edfc8984d9eec9e3d11372c866ea3884144e73127f3c09a2fdcb06db9552647f42f7c4cc422173d5be38329ede8b9b95efa0d3bcec0dc3c40d8427d4a3a762bf452a281f595a969830a09f6dd43b0ecacf11bdb9f5ddc16ed41d180ee3824ce3a64c9ef4901ea57a46e8de99134c63f26d95475b16fc8940e1a1792cb0aec1c98f5d9fb2f284cab28bdff69f1b9c66af993c4c92b57f8b151b8296707f482cdf57a070f679107556c81060099daeade1b66618e9b96b60fba81c752b3d5a5f379f97ec6fe974930481236b7ce864ac100fb6e5098b67a1a1456d502283db62a56ed127f034e9da3e5fdf073538fbdf203d2e717adfb72276430f772a9d0e80cc7656a0cdf518252ad7056e39f544114b915d341fe3fa3013d2bfb74207f5b7754d96169b5917978d08b6aaadb7edf13d65e267b9c9bac3a3faea59c64463a79d00041c69232d328d809d059dda1ad966f9697bc5ef55d21fcad3458921f5834c143917d1c171454968a96021862763e909e385f36ddc99ea83a01a01a006500f3ec82caf13f6d545f22689ebad110e9eef5a631ad6640176ff63665ac570522819529d3f60b1abf2f707c30ea8d30c23d375ea2b8c7629f4240101165ce4d24bdac3908f095e03ee1d84a39fd8d0eaa55958feefb5f9ae4bc132c4bfc836195f59554d6e4bc113d09db7375953d82d0ff26595973a735a8975ec033de23bdcc078341e1b7088299d2a4a68276026a7db4ac9930b9458f6403037fba2dd64615a6dcd5c6ebb93088a557bde6779d42415a0e6e069bb875bff390465779d2b0023af691decc1908a9ade323a9a708aaed6282f261ecd2b0f6e8f98a8f5f6bc74463d80657bd0830d27ddb89ac1c23090106496b797e973275e490401d1c505567050e47028b8d5c8a156e35982705e0e00534a8ec91fff07712cf99e35dee3b2f9cdaabc9b7b62de28b4aab7b4bff3126614cbbac56be199326006560b5f4aef5f3f4e817f19d6a45df2b1b7de79452226a1ae35f9746f0ab567b9bd3fd8ff8a9b5dc38a81169e0000beeca21a836e80db080bd69c520c1c1f7adaae77ddcbe358961ac2c6f9dd0b599d3db245bbfcde2a4cb9d84bd215909c7241944420aab96a06c4004c97b8b095fd4b7b1f2d5721533a6b96c0d6cd0cd5686db33610a88e972d398b1ff2562cbf4095c1df1e7726e26b774ad2d7fd792595c36d9e44b8ccc4f6f9263f19e390172ee119de1e391b1450a1b6443b1d1961072682fbca2e6adb9076572a42221c9d019bb8f2677c636e1b090c3f45d024ae12d62067c28155c1f58d56905f1d286427de39006182d643d698497d80b64cab2b3629bbe5fec94a5a6559d8f891c492d67113cde06eedef6b18d6b03fca5fef773c27448dcc14ff5c46640089e342db6394455aabd14028c9342eeb40bf80962eacde17e4d8e78782112a7e246589bbe9950885b5edaa992f401aef002ba597fcbe9ebc6c4f8dc18202f32c93e37eb64acf9de6a931cf2a970a7c04388d76a591975253c5502e6954c9b8aaf685e08b3cf35f6ff250404bba8784ae9bd2bb18a7df1573bc9837a4cb377f8dd6e109b87956a6883dcb72742b2c5aef554dbac8a91501f031ffe2e70a315d048dd4ac4168a6eecbc6eded306f2453b7057d95e6e7225d59310464df736f7b00ce2c49b77fa84c23fb101959d18c35b97e136f6f6f6f3e892f654a5a28ead122a63cfd5d0abf4cd7dcb5ddc6fdd12b175709bdf98a41d24b42610a9cecf965331d6b92584366b6192d23bab43a28b72676bd07ebeb84ee310c489ff29ead58d1d96ae44258bcf9b756a94f776cb4f2b558b72018405d70f51be2c817b07c48e162957738e6918e7f4a9d8156d7f3c83acfa2544e475b888f19c6171a0c56f8071c953a97ed55a2a034bb37ffb6d9d8dc2a26cfffdc20910abd1cfc7c4f6cd3a747f08695bb4ff33885407637cf87196c9d6b0f9d62fcd851bbbe04fb120560c32c1385e04460aaa9fdd0213f1612ef8047d44659d0efe605d8d9c4cde8a5c24f6c426383bd8da2e8a7ffb397246eb0d28bef9628dbd7aa41b8713cb5aae7ddd6281fc61345a2b5df424a10d265fcfc9feb835220b9bfa5655e482359fbfbf6bbadd7557595a52d90ec46c883f3160182ed836a6624b80ed45d8cd1fb074cbd593d90576b1559c33ed756545964918f1c6b82c39bf9fef5866730db2d4cdc499cbbdaa461200fc2ed2fbed6ed5d0dc47373483f1a47574d1af60356ccf67aac3c9317e1500f49fb00e6de54d79764554c7905a3f86ce4310a98f91d75778e01e8f52e84e7f76f1dc18c28c46ac82c0a1797b249e5e683696af178109d08944cbb761542d03889f88771c7145af62abd08273ffca95f1c3f4db213961aa75ea78305dca7f0b3e9951eb2df3f2a28628561fb2492425d66ceeb20e73fb7d08a83f379a9c422d84314033948fc3209cf4b50e9d6c8c2686d6fb70a1a9f79262c5d069583f4be016d171241fa91d2817f4ca769fb7411d1c6a0d86721aca8b993f0ef4afbc3a83f3620cf35ead83fde8d37fcb58d7c2136980f32472626b3e73c3628700b4a89a0d54ac41cbc0f098118ee75c4f70070d221eda4d6b822523e81c13a9a3401e6595322fe24745ce538efb599773e9dbd669f9506c0f9dba830ebdddc191d02263d86713274c4a48a36cd951bb350c3cfc47712f090059d687c0149b0a5c0e273b3ad601523206af2fb2a1c6dca666a5e6fb6538b38a1c4977f405b787d60a7048593293765103e337076f9763b8a7ac3541bdb6c709a3138a87abf0d471a9259710afa3e8664b5a4039c3ffecfd9cc7eb75793179c62f11d24c9f194f267397c5cf5067df023b4f152932bd8b5d4519fc1dc58868e12f049a1447278e95dad28bbd73332e643fd345cf0d111691ec8ad3ac3226ca480ec9b7b9b2df09f8856782b0555024bbe0c1cf44fc0650721e65c8a49fa1dd8ceb5fedfd2e7677f2d0ba53f476a7ff532aeb3a3ba48b84a6cc9db2a2a96c232e735bb14441c32113a6ebdcae98235daef5555f95097c09f7b9e49cda58090789f01a3ae15b5d9e370c76526e9802238b2741ff3cbd6ac0f616981c8c31ae3cd40447bfc5fbcee7befde06e374d213aa74a79fc894bd5419e5e82a9f5237ddcd0c6b4284d89bad0b217126c16af21dd92c31cb7a42c94d612fa98f272064605e3b06a9c7223f3ffa84d81c86de76cae665bf22c4fd06ebcf9973db1d69734b2da16df700d2974308cd0d61aadc2ae512c00eb997c8c6a7e7eb3fa5ca17861bc541df2b0f01a314a4725f572c0edc9c63d89283e969a54ff15ca76054f33a5f775b40a4a16adebc5fa088731cdcdb9b8004b454d4db81b30465b9a90688a49ac5ecf9dd19e8b63957a45d56f65d213d7fa8f177e40ea0d642c77e0197f1d53cf9323426207ae00ab92bbb6d01fd1b4117b88fa5a4011818a7abb0b15ba5f681e15bd7a3a50e908f454ba5c4d5f11e35f45cbdd4bea849eb4c06ea3325af153c34954deed60519f9ca0c220f4842894060f14dcc41d2fb16aa15a47bdf2f9a06bf6980007699349e013c8224f363b7f9cc24b4e9a72e21d40655ede3ba8e2f0a127779418421c86b8a429147fbc85d7e4d0773744cbc452239e2c6bbda46d84c69aaeb7f72e1064e2ded6941c8977a8fe3dac3e4dd54de6b44f108fc8d2c75e4bf9086e60c4bc0ca84dad72e9514c3d5abfc5012dcff18ca4baa1ace525cb9de42fb92df981c046bfae182866d8ad32c7f45f418d9becc0c509c383b76999eb23e41dfaad5c159993e122f735827b28b54700530f1375ba2315a96e988dc86b7d6c1fce4050f422f24d38a534d13ee58adddad340c82a6b7a95461a132a6c358994e172dffc8d5ced7f843b0e04031f9f4a883e8a9a5103de9226c96de27cbdf19c86c415e46bc6e8135b63f93233c6101fa3f43a9bdeaf416d5907f959e022561cd37e5f4d8f20feb95d6b4cdc0109fa1136c076f044acc5977a4606cd1a137a167d7bdfcd5c40182b56187bd9ffe52a0aaf5339518b36cff98767397ad78b7080ec08947c8375ae48aecabcf9f5c03579e125e9d151ccbe43be13f9121116d13fdcd588b2f4ae30ea3d3f82cde4c33abcd126feaca015849eab1c5b90ef6d4aa0571029c737fc79e54ac1e53bf0e50ade5e1bde04e73a0cf4d6ee0f7d828ab681f5fbe44c13f9f577dabe1c1d3a685de8725679fed45ab14b2ea4edb35a2693c5243a131f7b0a8cd6267c0fc717a5879ec2570442a5256b33fb0ef85bc485c743b99172a3e7d53fe41a322e3ea47e67f88d1bf6066de5584e56a83a7cfdba2c0dbe43255e666fb7a59c7c6916d78640f432de90e9d9b2e592f6ff287975953d4bd3f2f680a21cea33acca3f88564eda5255c681b61c3d8dc37154d6b7dfc77f6767d43dcd6b01e635aaf8c6dfc02afc4f5af5ddfbe987b7591600ad3887fd6a525c81662c5d645d42070a0cce4f6d67c9baa0e0eeff178db89905adda82e6575e4453873be663b7b86840c46082ba4e26ed91558110a9e4521a4db5d8ff3eadad4c09d4ad5f84b478365ca099a9b9d40985d8e31b9b35e9d769a5cb8c316a1c57ccbc41935b88ce1a299e4b2872f5243d0cf30e7a7d725a75f93e4ba7160dd8de46890bc629994de23eba08ef3d6a2b4bec0cf3930e58b34aa55649d020a28c46286c076231e7e8d419337d1a0b95437d9d11cba17036829570f0c77c760d84970348f4fdb1e785a8ce9596566fdb6368f5c4c42629e5b1306bdc96c20f0cc0100a9d275bdb9d35d0069ec1d1b0dfecdc4a18d9a471d5408bc7d0d302118bfaee78bceef82e8c96e9b2b8ee97e26b40046e6775c25399e505061156f3187ea33c55674a989b4b34668dfae3cbe5f350653de0c6d5a835dd8a34b35f0a57be6957a3186201a6b57b8019252e433e68dc38609eed2e30bc02ad8f219254f612df24e8a7d95bf4a81a58afb2a211f4af19745d76b5255c4678ff819a13d8e74eb0e0eafc50e26feb16d9c38b9d8be4a9893fbe7ad17dbc9557d9d8c9359f37e103cd8e6eb4c768ef34b3ef32d37ce8c1853585d54969a43c8d41a7ab9257216e6775e3b00e4696b49023a734e0150459875246d844080e0ad0e44c768266dfb15331928988dad3e708e727318b5a4ca60deab2fa734b526d3d4d14db6f2d9c9833d05263636f557b09e998858094ca6f2b2239028492f0852068c4c3123858c6d487edee0294482c2548e09fe6107d01adeaebf5dfea475c2613b18dba2719e2cbbee740dab6c18712c1c9bba59f0a7367725d982a85b98a57185772d04a9e09c1a00e52824aa6bc71ff02f022849b8b41ea50d988acab29efc964d5c998296f96b838ce29977016c00b9b3e0e9e9aeecde321d4e5fed049be68d6053c91e908a7fc8637a31fd2484994bb34f04e0a1c419c0da743dff38e0c253f85d5d44cedf98b3d8aac58789327cb1b17cf05c0e47c3f6d8a78932d53be03cd8467f57c824d5f027c63eb70166a6b7d7a4b49cda41a35f7468647e5b89ef66429a9ec6d8e1bc4663aae24e7989e100c7451759662a7d131721fd370b6f4718bbc0f9e4d214375c7bfb185dd1602920a4e9d67e26f72ed566c64e59d23237e4d70eed57e97e49d9ae3905e815ec60b03b90f43371a0bf2a131551ea0be636e00fc910c17a7b837dbd094b462a9fb91e1e18c42bbb09175ef296d8aae2c75340d1012c56555262a35622685b91c3cbe74bd0b15f16cdbca383e9ef3a230a7766baaf7431d46d8f4a5345e20fe9b5ba103e6866d2472bae9c641a6d83a72972c4f20e402a440a6815fdbdcb0616e9c195d1b7c0bb3c712d86289e8229cad12f9509488054341c8421e166b6af24610484f25729f0ddef4e8fb6321e1e47269a6b9cd50e74bcc53ae48fd19fb07fc07f85dc51cce1af75f1d233052b4a125939ffc45d24208b073f24385bb26ebe5051e75413ff78334f4de6a9205ab207ed6a7bf68d38ce40f7cbbf477747f28f5be57e264ca9fd242a3b9b941d9b8bdd1a27790af64fadfc29089db7302693ecb2591450855acd39109fc0618499448bb58cbf0468dca4ad59a29ea8b9534de78da14f84ccebabbae6f2903c54c9aa75a766e2e66776870d8beadfbf3416fe19787f52d3a223efedcf06c43e1efb5163c1e1c5b21b539ae9e66771b2b1745b24b6de979cff4f63e7797c988596ee796c4dfd2b0256f5d9bcde5c196060100ffb28bdd19dc1a2fe855cb7d26832ce3163a7f7707500a4d5691f8971f337040b4303daa96a0f89c82d924c23d2cc6fa74dde63f6a39b014b90fe4ce7abb887de6be6850b4e90e6868fe110ecac3b89cce691befc150fa3fdba6c22a60b28e3b632bfd29349dcdcc825c5e99e2714bd9d7cdbbbcbd07e7081a05e722ce30443145d24ee1efd915ff5d720b597adf27ba4a89a93f4aec6e87cbbe223365afba56bd232f6e1806b1fda6093fc571b072adad854676e05852c4eb87fe59b69db0046aa03bc0a4f71c4ebc3f27b12f9d791fa174f9dbcccc2944ea60f251e5eb7cce7131da3c060ddae9da45ba316665e99a310cda97024f8a11b91fc588b9c8065128dbfb34786fa6749e1b521afaae771ca5843126e7646cd88b68732ed570a9191754326074622cae6a8c2c32524ea7957bde0126941beb35dee40e5bc6297a22b8b49881ab18bc267a601508debec1d72323fa80f008ce9f6a56b8205fa40a6bdbf487b8eb295c2ccc58c15900b8caf3575370841da90056693e7cb503e1c3dd852cce38e4a386ce8bfc1bbeb81d8eea0f65f700960176d1aafa80030a775404daaaeff097158aab091f0d45a0320c4b931e7a5c5797eb82eb4d01aeb341ccfcc890682df1cdc89108f85ffef7df8e42d465dce72e78dbabd1b00a9d06b078e1a23fa086a94d0b7abeaa210a9e08fbfd474abf9795694910e6b87d8fe3ea1f7b4974f0d2a9de35d5dc7deb9cdbe8a3e233beb6ca893ba2caf19658bad4d7582b372da225896aaa5115891fe506645d91870e2350a5b1e3b6e317124f882c977977a26c5a3a03ec1ae11413af9c413488921cfe6891a353ad759a156140131b37b0faa309eb637133477f334fa878051cc41a810458a9678ae4dfaef8da65314edd24ba520c59f7e90ab7e9e4ff4a86ef4829f8121d2dc5653a292d3da5880827baeb2e429f02f75de416c81f22457767f87094568bddb7e24990db279a720e1535f0c51aa790a440f59fefbf8e3168fa16e13fe9859de0b59b51acb645c8961e31b0b3bc212994c118b11fe57e830e94abb4de7f9b7717b4c677be94acc769514a49b64fdc63b1cf1491b5c786567b5c42ce3cf404b1ff9c794159371d9675571017c2ec95688b6b965a63635ef8a58dcda5a6e84c0cf2a79c2e2fe61c4095a514059503046d77057fb39269f48395ac966593dcd2fbbd3c7bbf6eabe6992dcd8e32f35660ba7e00cedb07c1e27c78cb3b2d2506e9f909b4bab6103704d85ad853c3a40f0f8adb9b363d6c5f98f22daaa2fdae675d72ff12c5bafa5508b3fff4b3f85660b62c462e7d19f642643b362e1af8942aee46e238889fd16be2fe574b03bc26ac23c9e4bf0061e14613cc303252219cab61595aaf11782e63ba218ff505648b465a2cc9473dc4a1f3bed57de5af9a4c3ffa5b965f03dc82bba2286441435d79ce47e8d1931828fb199578d5dad206e4ad05de08eabe0e5e4c516315601c1662606d7e7044d6bf4455a73f6cdde97fe73795f97f4ef58fb90dc0cdb25f58b8b4e051b434e270fb6121417dba0cf2bb8069060ab8396549e796226a7b30bc0a352e5501b22d119adf07f1bd0361a9012af141ab306ba75107b4378237c746da6a7491a3b812924b777fcf89cbb3de49881c5ae5d204ddd83363f8de0f6eb124f64f23cb6a99fc8ba941d1f5f7dd870bc00364f154910eda8b50641128fb272ae29cf9f15c9168dcb2f81231fa3dd4666c2c69fe3aad3aea1507d4d5fa4d391e328b7bc9f28c7d45aeb93c4f4bc503a0342e3601d91d3ca54228de75658c130c315e1f8346796d50c578f60bb2567dd408685d6aa611a2575f2e448c0a2fc2b6e3795135663da11f3d2acbb4eade3533cfbf0197fcf3343675a9b3dcae03296ad5f5d55af6d3821f576c88e306e5a698f4c1ea859b2f6b47815170d6e8a5404bb7a6f6c1238aabe4fc66076c952b55c689a16c4567b7a27a036b2c1701e9ff0c9b18d9711b4da4f99bbc899eff8e347362bdd56629d04b1aa740b90bc2120cfb48150caad6ba41473f902f109d23dbe7a512f7be28298d9647167674d5666e95302538c6dc67de24ac5227efe34dcd8dc808b01bd1ea60841054ee23cb253ef29c26c32325c60a3425542d0326c4f6dcfbbe7efa021a3256036fce18b0d04dc2c434671c5f8ad93039d56a5d7e1b380bb3722de43f7ff0dd5a7e4403eb25893a76664a49e2b242a3e1f2d38d98118a0f8537a228a99be7b2d542521a6e860f4f7988e8aa10ee96141ee0c679ba4fbb286a60943b26932463ec88d9028b0fff7c7c36ae8fa3362c343f619c6c8d81fe7f9867628bc34fae0033aa5df7d248449574d7da3a9817414a350323c6096933bbdd6b43ed60ebc834b79b0f8893d7c7840c1235969a251753d6019b96540aa3a6c45db0c3932183bf4f7cb7b75b8f53ad0fbe46a2084c104438eb2f8e886f525b11f4039a2923f79d8c907240ca84291a249f119925ae3e3adecb1aa023810a5787391cbe036e2769ca2bf545a018a9c07eb55d8cd00087bb98a5d3f4510178e651d48cfa41e0be63209e5b463bc1dbed4e32f3626dbc1a783e5a581f2532031a67a05aa7a91c66e274cbf33e8579f987e22ebed82e5acd531ac48f38ebf3478da5f1ade701a0f8c279aa7be7ef69052930acc97865cd6ca755e7a2945d2a92df492992112b9c91d5e6379952ce4d36148299fad1256c439c2425b9221841f815e7e137fb7f2b59e7bc7c50c45f794ebf9d2b579e3c616d43428eb99cd2aef124c5c194f9cdf4b15f1233a18f5eeb6d328ba1c251494505ea6ff81049bb7c11a94bb92483936c1b24edee70d93f1b12cc6756bfd781c829ebab49b884ca04fee7521c5775f7f26348a868e1603058d2be5815947045cf50e9350d54e36295643a4562a4f47c1e3bc80099acd0a550dd4c2ca4e527dcd8f29a0cf8edf8a95822c382c3ff6d7ad74658be720b3ba4e6d89a9156d3afc3007f5835b78e2a9cb26079220b1396188e32e70ba561e99aab2fa469727ffec6ac0971ab047a744d574eca603934342f887dc841069a80601e895f4a01778ecb762af86dd6ba5826cb7e1ba036d8ca0ebba05577ce54956fa10ffd3c02998a7f356d7012e38d5ed2f6879feb935e74f229e0a0b768fbaaf56adaf110975cc4f6c2ce8a3d807b1990d66de00683a29200b4aa3141ebd5b49fb2a643adba189ee37707cc79a1d4fe4ecce54f438a93ed464d3609ca50fd920519c32a1aa965077f8426148bc6dae5684e3efc69861c00c3717bc70bf15704343c7fad05e3cfbdfc6858b5f1906b2124bcb0464a733b4df9d45ae7f8578a4b12724eb432e6baba0abbc05871c51adb4f12fa97a29ca1a455dddb8a82859ebf81def9dfd470bd69069702354d9b635f4411c97ae1a1f13913e2809f01f054d37b4133bffefd3e367186a098b02874dab01bda424d0748369c2af4b8d0a7b34da8fcfc5c5272f7d11a35c9808bae9271aadbe994a37acc6af40b1c7f46cc6315e065911940ad9010a405d8472cf6e4025b92594f6e82c1885547726d1b253010272692ddaa2819c87ab14239bf3a33ac3d266b6d790d079523ac2c9fd2f94c19d8f3e1b9cdea0304d61412cf9f117f3033c9e86653fc9886b2b3ff02f233708b5f3c16f6a0f786bbd27450874c0afdb09a8c07ed632d0714fc451baebe95215c5199719187aca49b5c5e71a7950fd8e4a2f753c6511592d0808776226ac622b960ebd83d445b47ca08c0051833894652cd2f44733e67c15add53f0bae1f5b79bd5de555f07a5353e634421b2688d87a2ec2059df5bedd037a7e155f2e5abded1b566dc03b1fa5493157e1837c4a76446d883e5c31a822bfee84aa962a778fbcb83b4e7700da07f88563c168af4962063b5d699dc03908fa5a69e51f4d19e7e8b738acf3fbc8e5b5cd1fa9613cf928c69ac8192193387c9d6fcbeb3476d0d9df2a331c0b39c1832d15f60f17d588099da88eb1365e092eae6c4a29ced8a4c561ec5ed0450f22e523e0a0f98d9f5330d028d39cb1866e07a1a820c8380f9a70b26bedcd17f959b5f89263b45130be706e0c979ff95b502ea1ce04025df2713098e6e92f6443fa976b39992edff9db8539493bea86b4d3ffee1453b8d6d1b5cc03c0aed0201d5a966414714a144249b8e54043b1a71fad24c65ba799e0c4de3e3f5e2a013f785d4b87350ce4d72e5009deb5c890b6794bc5cebd30c19a1aebe450674f7d792618736e1a6152e77ea69a2bfdf9e2289f6520389a57e205997f8757fe8203068c14985925ab14e31e0769fdcaa771384a0825226ad44d3d022f0f4542024a71767cb828911c2aa5af112a9e443091384587622bc78f37a64102a925c57c9b758f3cd64f51028ae2694198064d617afa9f329c29e382dfe1c1a272512ebb2bf987e5ba6af1f155915261c143e355b46f9d289cb7d7e68ab8923e0e82c10e731312c91e3e4d8f84b3023eaff6695741ef9fa95ab4cf24b47f588f8cf9dfb6bdfd62fa65023b1550e04ab322bddf706c92fd78d8ea07fae97564f7a385ba67c249a1b54861d159d3e9a92436580b8f16ade1b05bb960dd0ca2915b224964a7dedebc4c0dc00781a6b838fcf2276c2ea79511530d97dce9fcd13d4ea9d06fdc4d47e13befad12bf0b4074be5a1f4b94c30f0dbe75aacdd95efe99013edf89b03ee3152d87737400b205adfe1938985dbd60ce1fd57e06edbcbc17f223d8766d98bf266247cfec6480d42d2a9a6a2068746139a091e4aabff07e0300eaec3ae499c5fc5a86dd0c155190c3b6c09c697b46255e364c91752c364a30b36dd1659edbf956ff4746a9d060c8088f6c80f3a189fba56d4105add498a2a2bb65a005ebe4d3aff1d429642f339c20ea5e94c35965fe38480cdf19a19a04265e318e609d97dd9f9003acd7d5a92e79ce9a046e9453843a474dcb8f4323f9c686a9d6ee5e5f0c1ba786d226941dbfd024ca02df3a653b7c76a3e22a50effb2b4540211c84522478fed0ef0819d91d0fd20c98e1fc66aef2adb6293dff447c7611abf2346ac3ac953c98818c8307cc8a7b1fa82a7ddb81fe0d90d917ee1a5db8f93114494d80d873c0f8e61e966733045e90580e948c3d32b112132cddbf7cd1493669aa75638615529620fda975ba257562762abc69568645a1c970df47cd20ddeb61d149250ddafa182741ecd0804cd594fd0df5c8853cfd2bde49e1df430f5da05e0a5a9b054a98dd3a7b875772697b0fab856918b98dbf341ef5dff56c1c748151dd2ac11f147625791ec4278b4b7b863e15493b8d4b8d8d295ddc27aad3e5fae62def95eff74a260430ee0f08f3962848ed67e7d2801ec7ef5b50016871308d3125e9464eb98b67787485f2a6ed5679d955694d96272bd3f95f998872335370055f973eb864e51856548b7347fd5f021509ca68bcedef99be5c75b28ce5b8e9a39fdac925b402d8b23154ec87bb89f26e71d1320eaad984edc8cc9d9a20573445d0f6393acd4eb983aa5b061980933b4226ab8125496475576ff5a0c3e7cf1e735a165a9ae880d393b9468bf713aec5064622ebd2210c416ac94d3222f39c16cf163404f8f477229fd25704e11fa11ed765b93b86a562bc44d2e38b1092856b2d8f9d9172547a64b7516b6f6455b722ad70e4637e3374b74edd18069ba27290956ef0961125ae88dfa85a13ce2ec941bcceb35f3cbead5e1806b290d67a867d0c58685c055841e3c6b34c924a86ee0b007ad6b215a5c64639e92026c13168280a95f1e18cc084d55c02f425dd05f249a3a381142522da3aba2e4fa65a170415c1ddbdf2c4f9ad2095fb2c7b8df37af148f7b2410cb7093419d70454054247adae487d0e23c7b22a4886b45c4eb86c7f83bb6b474aeecdb22e3c90eb00bdeaa70849e5c2c1d0c492e805bdd458785cce390f31659b007766ca078e27af56dcdaa9c470efe55e4aae186984aaf63edf0ec0b59c2aca68d6a5e9f018b34b85d10d0917d144287af307a2bc62bd59f68369862df45f5571f46ff2dfca603c617e98f1bcf6990b69a3171a85895f9c9a2eab9b56a2d7d0f12988a86301eecb074b74caf30b6fdb6dc551dd834fcd367a41ae7213d68e15e9c8f3f2d6d37ac68bc77a409474004091b88e242322bb5365b8bf0d5c01920abc8c123c39631ff276fdec1265a3f3e955a4a9ca8366edc148be66d21fe871d56960cbc3ed6fabc0c75a740d78ae57966011e5bd3080a9f5bdf6d47c092c6e76a5923f9b972c3706882db4a92e5e92544de0e5eee9f622df2ccddad11470b32762034d3d990e0a129c70b532417351564300fdc0d617652732120b87c4e1861beede355b08cc2e7a74f73dd2830ad2afc5c34c52dfc926a232ec108d96541b8c0e84d127a6edcd33072a81992ef7dced61d6df1b67a5c2f46ec5ad1f99ca2979745d2c44491ec9718e08450fe64c5cefba7b18125924663492500ed735a1e7cd1200980a99ab4543cf6319a3c501ffc7b5d523da5e942ffd4b4481bc148e9aa44c6136648591410a0735a258d88425bd7b7140b0d7e2bbf6112914a17e814a82a78fa2fae47d6f9f1bf8750e6bfb1107b59e8856e865297dd1b603b02f8727f570a68c49b4597710f4d603 \ No newline at end of file diff --git a/src/01/input.test.ts b/src/01/input.test.ts new file mode 100644 index 0000000..514514b --- /dev/null +++ b/src/01/input.test.ts @@ -0,0 +1,14 @@ +import { assertEquals } from "@std/assert"; +import { main } from "./main.ts"; + +const target = "input"; + +Deno.test(`correct distance for ${target}`, async () => { + const result = await main(target); + assertEquals(result.distance, 3246517); +}); + +Deno.test(`correct similarity for ${target}`, async () => { + const result = await main(target); + assertEquals(result.similiarity, 29379307); +}); diff --git a/src/01/main.ts b/src/01/main.ts index 7aca018..56742ac 100644 --- a/src/01/main.ts +++ b/src/01/main.ts @@ -3,7 +3,7 @@ export async function main(target = "input") { const dirpath = new URL(".", import.meta.url).pathname; - const text = await Deno.readTextFile(`${dirpath}/${target}.txt`); + const text = await Deno.readTextFile(`${dirpath}${target}.txt`); const data = text.split("\n").reduce((agg, line) => { const match = line.match(/^(\d+)\s+(\d+)$/); diff --git a/src/01/test.ts b/src/01/test.ts index 3821686..40cd366 100644 --- a/src/01/test.ts +++ b/src/01/test.ts @@ -1,12 +1,14 @@ import { assertEquals } from "@std/assert"; import { main } from "./main.ts"; -Deno.test("correct distance for sample", async () => { - const result = await main("sample"); +const target = "sample"; + +Deno.test(`correct distance for ${target}`, async () => { + const result = await main(target); assertEquals(result.distance, 11); }); -Deno.test("correct similarity for sample", async () => { - const result = await main("sample"); +Deno.test(`correct similarity for ${target}`, async () => { + const result = await main(target); assertEquals(result.similiarity, 31); }); diff --git a/src/02/enput.txt b/src/02/enput.txt new file mode 100644 index 0000000..5522542 --- /dev/null +++ b/src/02/enput.txt @@ -0,0 +1,2 @@ +173,22,78,137,211,76,251,150,156,72,46,144 +5e31bb5a1884755f8d8a368d8a295a367dc94b65ffdb2ffcd5d0250081c1fcaf4a613bbef8afa6f8d656aec8d0f90bef30332c7e8ce85eb13be1cb82d512544e328db2fdbafb2969425b2bc399aab0dc1451d7c3304098a213e7b36fd0d376fbbc871e70690c3311e6982d572fe3ae1c61713064a7edfcb6039b555b9d96747702353e514a4316fb28f80ad04f65ca6c4a2ed069e0b16beb0023c83aa292e04ac6189e0d674aa2237d5b6ce1083c3a95d10d0b8e0a1840afd41ff11ec011d2c519b80e63b0ee8893fe77347df761fd5474b4c8aacbaddccb27e426ce8d02f3060417cf8fa43ef745bf8fad6339a017cb35ef6d16cfef6fbe54a6223e561b2cc2b8540de625064ac929e068d06632bd6c2a7d57db3de03680df752800f9e17cb1224f3aafe2422d5576dda8d58968564681dfb9d174c0f4ac84b21d698b1fa2f159a7e865f04ae4702030d7b2beac20de75b637afb27d30c5fe65da923e7c385df25bdef3c0a76c1ee50e8223519fa92c6977ee5e40dd7362ab6932705e59c9001cb2c77507956c8d64de14db4b934746ec58787a80f447f4b917a70ea5b6197dd0a9bc8ad60895cd52c3704c85029fb5058513188b560aa2f2f6bee1129b8d6509d45b830acfa8e108c345f8f6f80322fdf0effd3e08f8540cbb811c729d79903ac391f1c7dff243205f6e1c1fdf31ea22a4de0958804166e7546f7051aec6146c7b191ea2906d14a043603e35445ec0bdc47a9dcb3c42df956a19f2d5c189c7d4f8c35be3166bb163d2da3a49c21971029a698622ceba1c095d9abc1297a7ee935b2ffa4a7fa8c9fc0eb7751eb89b675e448d6ccaa8294002b4d591f5531608015fa28f45dd1b4251b4c37490c0e290723a371c373a05ad5fe47041b2a7ea9b04c843c096fe0397f613cdd2ceedcb6ce7cce0452cfb1f6c884c3c9d9f4c4dff745029c031516d910ef615d940501eb35209f65fa6ab0d23a0d7917e348b5bc0023e7b5cd6b95ff433ab570b76d7f680a291b502769ad8ef173e9233e08a74cc3149ff22e07ba1aedec2f31d96dab2d5752396613cba6793479b0f5a75fdd2a301c44fd26cb6f19f1b0cb4654b80759a56b3a97e1dc9e547e7220215a0b4d27982ada263abaceb03b7b6562624803039e7922c702dc109f431498a4dc7c7768fcfd37d9c082020161ed7c423916243762280f8191c96e5fcf287911fdaeab8fb785b810a27324b0d5ee152f9c2ab7d24e2d43f1535609814ede31b1926a9943a3eadd62e9dfd843d1ab5a68ee6d7c6aad1aec9b1a00c14e8a354b929413eed138ca99b19ccc0c3ebcfbcb96d626142e9efd55f0aeeed6bd119a323805e4fdc3c89a038591dd1f72d929750cda0eb520b5c2fea90d81629205e3914c35588dcf94a8827224785b89d06f022b931f244911f63b61f123dedd7507382bf0cf2e0d9ba81bf7b77bb5e2006560f2d19aa82b302ec0c9776759af892d90bd64819ebd453931e5885b52811d87578a2d812e78925227c425db64d9acb3c5105f77a820b07d7bf5024b72f5b4bb117bf2eec38d7cb1d82e23ec486a1d1585616d4806c5a0c32fb9fcf981a2b2d4690be6690d59eb3bd2def183a18b5bcc84238975fe736b192135ca8894def10167c5ab030b059ee9ffbd221347dc44bfcb95e986003ed4586fdd09e4c67c15616f807e03d240e6048834e6627a37360380494ae0b5dcfaa29d5cb50ad24f894d9527cc2350311fd44ec1bdd6c757d9ca8cb2163cdb93ff40c39cdcd69a784473f7da212a18fb62e9c2bc5a6db8ca036a0908b2a1c91397cfb3bf6a7729a2603c08e13f906403bc96cce1c32e775be168c2317d20bf2eeeb9deb7340f6200afa683dd97db4463e48d149a9ec70e71d1f50106b16577bb03d6f1aa2f40ba768646c68b362bf79cfae382b3a74265894c52a950a9c19b8c548cd156e3e8747f78b19f3513476c921d3ec7f86f9c01faf6e20e631eebb0de9282847aafa166319a8796d5372e9bc1282afbb85cc68825cdb8d9ccc4b336ed696a43f4ab91d9b522b7dd9e3149259e7b998b02477a0eda90dff1a861c7a45fca72845f7680b880500c3630bacf0dd871d2c82246eb86530801d2bec5144a0d078c7898f1bb4a69eda402501c1b1d1a58b210ea55c2608ad4389896d641e565157ddaadc1d82d63b4751f8032ffdba9f93e4199f7e100488ea2d7115b93d0cce2ffbc382cadbd929eb885e04ababdc7aac9fb618a2568602c7b330fc203d3f19bf579fcd691573046966315e733d805538bd631576986b2e39738ca0a47a9522aeb8765f64c28a58deab5c7bc6fe6560138d32b8c13389963f4e3d2cffa33c880032c829fcf85726252ee7e5c5104cb512282c1d63183c4219cb6cd90aecfbcb9e3f0dae1fc386e8d9b730a5b2ee54536e1bbcc111682f1cc15c1f737e8c7a2476016f24a796478ebdb65c44d37db7ee4b48aaecf4dbbb35a5cbdc35dbe898b86fdb4f9d6b6d6ca32231b63d9d1f1c83934aa566abee05174b60286ea4350c82df467971297280bac739ea6a00ec05c7df9f767a1918066b3287f1e5f3672c865ccd6f115449e0645314d9febc4193883ec53d1db758e9763f876e1cd520fa9077f3429aae91be0fb8752ea764032c2592a449333398106a119c5c4043d660ef546c9703902cbb9126c722f1028f0cda6deba6a81a6a811812e48bbf69a8c63c67df052fbb4d83156f420eadfa45eeb6a5174399adbf4428020ffced686636bdfb0a7c4a570b78a975751a821cecd80a8f3f16316818c1dcb2a0f26059188e286d2b3ec7ee815d9b92adc8c2a4c6967c3682dd144cfb08ef22ddb1c087f2207f59aa2fb710c9dfc6cdee9623ca45b86b2249f0e338c5941ea14d9bf317c37cda7d1a1f22e5ac2378d3f86c56825dda954aeb8e7454a5536b7d791bf86bd73964322cc80ea0e6148f63800ffb6be0adaebd11f965d34453ead29bccfeae286ea4ced6e573156447d50f1d690299e0c6b6ab0be5e489d932904cdee773738c815275cf4693be2eaa40853248c2a3e7e29d1fa8606bca721c632a16c438b0b48c4bc4fe280092591b5391a29a51bf80d77457f90dc2b7ebb64e0d55aef0875dd55f0a29d0679fb2fba78470453a7edfad3928048ace988462001be2b49e028f7c77c393a9a7c859199f46836810e8ac0bb8b889f579c7cb66f988c974e494c656ea4eed4cab0f9d52df30c8bd40c03afc823a06945fc5a9cb0ddcd81ec89045a7fd56d5111836d37c9429266cb49225dbb8059e4ceb448a5f5d5a3d91f75887c25046b687bc7cf32d49f760cacca35a0b2e59c8a81dfe861b051e308933da1fadfa9d754916706224b1a03e51ae842e6bd929768b0c0c68e8e0b7af1fb25e334a3679a2963faea407acd0ca956c5950627b19bf11393a98cc6228865575fc2d10d437f935e2d510e93973ea15decedeb2f7f27b9babf6fed53811ece304f76635d078cd8793fb11ae219e9a678233228b9aa59cd12b29c92a4c5142e9c61e0ddcde47af25e033bddc24c61b18b3b048b39dff0ea1dac45656346620a5c927554241c83f2487efaf804be157181468372ec7b058383e3ac0ba27673afaa9639550bcf1bb5b5de5e97eaae27a3d7a9cd43a1a4e4acb49b79e3f342a1959b8034073109d57e6e98c807c61982a5de480c4d1e00a83023ad356256479d411df6fef4a209b4d4b78f08e461895a1eb56d0b897278918967b8dfbea8a18087aeb61a3f84f2b86f60cd3f024eec59c1baacdc022421d37e240b83f7819d9c55243a8cd9b01c605700b3b3c7e090af5ab268a34b763977e9bed505087dac5a8a56d34be6f92deab357d0d032c49b9c64080b217e72f7812e46f5c6356f2d15ee3f8c4cef548845a054b633346d5391008691b179a238ecce358c9d29049a75ac19d6afdf73d5dd8d3f468e7d10c0fe175b57bbaf8e8566b9d5ca9471f72d4f3d43b43529c34cd73394a4f3bebb5f601890f164913979114bd49785ea21ddd333866d6e39b2773624eff8e96c8d26f53c38ea3deebc5e943b6965bf5bf9518395575823f383715c4076be0db61b5b5c5dcba842a02b6c846cbe309672d492c128c06fb8864a93ef5661fc536c768d98e6c5fd391aa16355bf62a7fe6fbdf38c8c377795c201dc6234e7870445f7ab7a5b4531f4148d2a1a8c945400e6842944b7d49c7b679e0cc486ec1f31c46da4e469b4b8018840ddcc175475defacfe278ed99148ce2832c524bab6a25ab9dc1f3d7afd22d6670e1770979392960c41dc4d71fe6adfcccbbc66a3ad01a4c3c94fa62edff3811231f452154f3e6849f66e996926b5901033b8b8127675467fa79ce42291945e1aed022309708004913fc8aa3f67861ea4975b8108aae8358f8783daaeb58cd9b7678284581dbd38c003747fca556c0dd2b60895981b9ddddb328c96466cb1d1e72f7aeef5778a8e46a841c4732abeb7bc85706097275892d46b1991b76835df81d9a81f9d3bf214948c4c91a82332d6942ef4824a38dd6ac8feb36231cc4ca6f23d3f1bb4c4bf9bb6cf607deb4c02212479a6c206b192f69564e791658d16d3dbac0f31a0e9d2222889d063ea0359c6f8e74dd5bfb0f69d8d02f812049dd31766eed89e665053ba30d60c926482862e363f71725b2ea44f9df44f68bcf91050113e2be3f291bdead0cccb5db81578a70e64dcdcf76bba2b08e53e077ebc8426f2966b0cb29f707c2a76021f58c9aa5927f080792a40273a29794499056a03315ecf559872b8a8428cb7f67853f125835e2f158799bdb0a0e014270efafce9acf4720b4e5f754aceed261bf4d760fc0c64b442e5faccf7c3aa665d31c0eff8b8c57f3bae874da374a123bf544ccbdff0a0f5fddc1d130d20fc86f9eb3b23d794f1beab851e8b554dbde90e5cf05be900925733b5f8885f4ea350e564fa4bac2fe56e590aa506cf6ca49ad85c8d52cd4442b948a34d05c50a493ef948eb151fa46b5677ae24160b9309416d5bb110b644803cd12f25d8d51be142af747fbc6df48646461915ec8489acb055f0c0ade188a6b2b7bb1fbf63088526086745fe30b2c8ff6b51c1ed49a6b0b7e3a8c70ec76a2791f02192ed299420a65cbac03a146382a8ce32aa9bf66a4fbeaa66d9da374cee2058bd0ab94c27753d1909e5ce6cb030b0d73998059087a123f60591a3174f62210e0f2b33f6ca19436489a78f944a022ac339653bc8c6fdb34f66ed914338c338a4ee5c165eadb7cf24105618e801fdcb18657e34c07f1764fe673bbe4d4a5d7d4d83a05c8d8a2a7f0852f2ba3e02a95763ce6e04e483a3378033fd1047cce16a4ffb6a85b148daa4c2a58e64780552675a5cd4fcd08217dac8d7052b9119d57405024e3466378436364a8d690913f95b4974d8f70238ee21e660269a56302aa6efb9f3098d4d986d59ede03770aba20dbb3c1e6d83aa4325e3b4bbf39860fe09180709f73588eae19849810f2714ec1e7d6ae8518f20acf5e79b276603fc0c6ba26dd33b7bffe72db5cc48ce718c28ef1266b9dbe1eef5c4415f50ca4c0d2821be672ffc7c125061445a3f96df026e1d4d21add1fe943ddefe936c72c52d095917a8ead598bb6bf087139cd32cb631ce6fc768f5d6b0a20c4088bcae7a7c777dde976845751cb2c37d086e1afbc53663b813cbe34d51560bbb733fb163a370898b006c2f486a5cc7aea96acac9e1dd614ac1f5fc9fa9b12bb5d6511e45c3986b928729d2d80cf803c63211875e32077e48d7bef8c19cc9cd220d4fc4ac19045e97f2bad789ed9e427b46322d51ed87463d5e2432373f9118e52a42f003c59d9d180a46e7ec9a3e6c87af415476f6394da3d4e36aa5afb04bfade597575f6d32002b84dbb7ebd03e3ce5627ac449a36f47201ea0de9beff2258bdc69776cbd3b943bd43e9a4ed6fa2ad6652d0b91b3cdc12ffb4c17f3f0d6c42ad5deb8a830c3f04c584da5c20669979cef70da951d8cf9cb0a3b25555770a8ddd7a64fa1a2e9b497302fa7c60b34e2779a02e3ff21d9b04845d25119dd9c394ee2472581df7decdba7343aeaa1964257a8bf3878de5255082359c8105d19643d7b10c1473656e63b3efcfa780dab345874a4b096b55428f84472abdd57f9dde3eee07d4e390c3aa4ae83f3b9ede1414fef4b1d19c237cd4169afe05528bf83323d88576454cffcd69491a9c4d6d631622dc7b24c92d681609fe568a5ffcdae845f10ed9e3e0a16efb7c8f73f53e89cbcaaaf847db65c28d24fd9707ae5b54ad9d14a83d65bc6d2bb316f1693a44afde4baa332d97c0b579569c97a6ae3afe0721d9905a57b6ada82ffc83386479caeddc91cb0b15d8fd881f0ce6c3d70f2f6dcc7f23410f549fa0bca52d24693c53457860d4979028684c25b6a71a7241922b904f85a269983803bf250fffab766aa09caead1cd0af89c818830e7460449c8c79f7b1645920445dce6f5739d6bbc869ae67eb2377426c6c948774e9189b4115164eaca56381d5404f3e36b9f04f2b7a7e3e2b279fe38c9b9a492ebd91b7dad3907a26a52d9c2a28b5e68008f59901db426131ceb8188449637377b51d8af4b89f49f493e3fc723647804e01ebb2ee30ba8d738bfebcd0f6c0651f61da0bd0b57abbd22bcbf4493b1282830d449a087e1b123f55b6fe0b401b69ddc5a49e648dd15eb42b60f485a9269adf586afb8e82134e575dddfb828d7cddc9951e9b25b5fa43ac6a91cfd79cd27797b94a2b95a2c35459a5aa6de3a179b1ad94c1ca89e6605fc8b62b1db9a1bcb190398f59c134c45204549602eba38ffac542c9309cc95022b56d1c1182176c0b0b0d228bdf656fa4feb096ec9d466b8f9a207b3c6065e6bcc5b163fe3f66432a2d0a310281c17c51181a552e01822288a53cba14a5b726d7607827f7ff3cff59ec8a9aac68212f3476dd5de97f5b4c0392d9313e1459d2a62d8a0ee9cec5491fb6b0be2e2f114bf6bc03d35a3b2872a4f90b5154bd69447973a6d13ca2d7bf9a39e30ba7999528c86f0e51c1f25b962a7d244d278742bb8dccf70ff7d561618df5918ac50a1619457c418aa208c24db4d9504a4ce5fc7d530d03992ae10defca2e56f39978608bc349eeaeb81d89088349bb29899da60917b1ef7588737816abb30a76f7a9272464343efa12affb7687ff58ea5dd4629847e12999f0bb7a14e54e6ff10bce10bf38976aa9a61f8d03685b2e88d232c7957775617dec70dd839537fe9c704ef420adcd8a029dd87dd7bc836938afb02c71c39cef4546b7cabc11218f0191385c00aa4f37c7e339424336fa458d93a9478cc12be098a61bce680a1450194e75724e51f4605855e57f76cb31c6c74962b309e906a73525c3fc766b285620c1679344aad145bd685b7727b883cd2039c65cf07117ce164c8db032d10255250747926ef9026ad60783d9edecc64d818ae7382e69b070ce092130194b743d7d94e4cd9e63f4010b1037c7aec3df384280effb5d27f38e87f111526ce8b351bc41275141b2a39d407d63231cb7abfec596750c219fbcfd6b248b392a4cb4fc739b435729186d2ccc806cbb5b114fdc6c88c5b86e4aebc83eb47e50f51f50f6523f7d7975c488432ddb86d58e38d478d28d66a2acef81846da8fc3a2d25b39820ff977418a7971a10180dd26c85c263182d8a54ac227a8d468d5ea601fe3a43cc8524174874de91d0e9c47b28be30ca93189562e8465e5f8a62f393e09229bd3449cbcf295b1d7f71376b78648e30b67970e28603bca77f28e09119a60255bcc07acdd51337b1334b2acd8669b990ac5b6c88647d8abf1d6d3b1ab965fe3ebf1b9df88b3f3c6126971fe7c0cb9fbe4e50df4401a88b9a82de574fd48cbeb549c04bac6a32d21af0d4343b2d266187e2c28bd81292459064cc6799dcf1b57115d39cd9f8b232903b81c77d810721840d0a76df8be3b0d0fd06bf362ec6cd22e9d373b6c112baec07a2995e04512275b961d6980693b0608c5428ecc9d391a679bb9cd0f059a0718d368f04b502700034ba642691a0b8f03c499b49277536a0c8366356c65126041127d10abc25e4af85ee6d4ca40c861b9f7e0fa6a71a16cf3a4f081298075f56ce015170e2f684a10090b31db89ab8137c311412686bdc517edde17f80cc168f847031ef0a0eeec8c2b8dc0e935362bbece1a352d763e8832a0a627cb7d6955d3d89479111b9ed246c0313aae0e9e388ad25021f547ae127fde2bb1122e10207074d3d81153a2f57dd3fb4764ce5d3f5f2934b84a45a56bca1cee98903c1cc2af9f1be4c924c646214fc3b76485b813d640c2e045cf43b58850702a4d9a50ff20d8bfd8eee8b8f6733731e9f9548cde90a90ec5b94bd2af47271977402fffcbcd146e526e049494f98900f074883f31c6131a8a83f181f2e3657a8ed28633a64669c1991e38eba08046cde1fa4f91478c003c8675d9622e6aac1fa1920170efda86c8f5786806af4c75ca3d547e13db2796d211eb1eb135c529ff892291715bfcae197f0aa3239545f0c691f01d9bfe943c63442cc8eaf122fb2aab6a5300679ac3a9435d582a4fcdd71da40ec75df7902cdfeedfba3c9c2a4b0c951ba4988140fecf58855ea98963fbddf45727abcfe2794142c8b85e30cc432902c376eea965836760bd34ab443ec9dd0430131ff780ad2cade1a8282d8778b158a66457c6da18f60c8075d99735ae95031ba4f2d53ff3df6b73985cf2ecfcbe256d9afd580109d215aa49b6fa6b34e7c7a215a60ff727006fcceba364617adafa5f27a6390f43b926de51fc6734f492b34242f0b2abaae94e210087943b702831d2b6dc268268024b332931d040e0b84da12b3e41b79f1a94e1fa49c42ff938de81f1496fb3b53ce2f205f3af8e6886d26f979153f97311bb025aff88cbd869d904462cb75a87c418a489b749d33125c37462d6f3c1f548e73c0a9e4f6049de4f1296e716fbdb54dec539ccc2299706d68224a0a4c2731392352f27ff1e2437d290bf32d8a8a6618aedb10a24090a101dbdb9839323b58bd8bc1cf3647953dcba1d93de86071777fad507bef6cf7086b3318ffaf81d75e39526e104464e78c80fdaf7a1e4b3c52a9a73255404c517135231ac01adaab593d012ad1d00e335cb389d262ec66dbf664aa6e8ef3a38ffa65d83dc53871a044405957f415798ea58e20abc24bebb48dcb923c02b8b08bcd57b5538d33e482bb7eac8570066894c88f46025b7d9e465c2e384c146b6e2a6dc8b29c16a453b6d2eab6116a1159585857c42c8649206786b23cbd1cc5d598f71a7d1652680b178f58f3ab62dae74d1779c0c8db28aee16a55262775edfd30ce01e7032d4fe5dc8c2ced18ebfd3a910914f5d19d63ce322dcbbe94aefdf100145586faefffaa4321d045c5e6121f2d078d1e89602e93407d649c4913991b2779e7c93581c84a269871b5b03c7b4ae8b3358cba210e7f949416e74108ce68f8f998e6dddcdc524b96775f2ba5631a97c2e2a12bd382910eccd56e29f76b463d98ae091eddf81b4490aeb59e14df960e1d80c0f5ecf6782167d5d914c4a5d760ef4af42bef1a2c9916ad2ac23f01433ff8085e2afce0b681dbd1a0cd7d1266d38acb6f13d94f0999ec19fdc71cb9bed72e857d6d90a4c60cfb15ee4610fc04f86c50d22b932ab136540665fa7bbba714bfdedbbfe5b15b41b2ee454b3de86eb897a3acacf22fcba1efc22191543e7094a82b3dbffa0402ce69f78e89d5977b1fe3efb70aded937d599855038ef22810e157c0c7126e9ec8a3b8f60e7e2480f4434d1297f65b11dca05feb68b51002e733335e67c36ea63a96dc0487de609c88302f0bd073d19941d7d83dac33afc284ebec17ee2ff18376e2e8140a26010fdc1d4eb0d376c174f31c3eb2a0282ef0ea15a9343cca20089c0df0fe4179cf4ab771254bd65f238a827a12ca48a4f40955971b87ffefd31c4c82bd7e367fbb1529ec61cb28ba1a119329ca2280d59b9a20b391799997aa4d4e1acd5a98d7983f310ef1a764b8849703e4ac121538267a7390d54c84b693e51c040977329d4fa81709a49358f15795c24f2b13db33fecc4a921395ecedbf9530fc95d716636652db16d0df1ea9f1537061e3b71e9ffe38cfedefa12c8b70eb9ef10d89d890a136c94e3eec87eea43a98e4c644848d3378af3236c9b6f85573b95d77df9656b8e6c565d388b37faee5505d48b7fa7e4319a94ba0ad0d1d88b8b5bf325cf19f32cdf2d949bdb10084a276b9301ccfe18b48c4cba7c475c10d86d98163e6fec7e5a3996655637235f6f483a057b45b0762e17248b81a584da8afd1c4e7d285ede6bff3a3fe2b106f19e3caee7fe9ba02a0de1966249fe2b6c89285317efa55112f36afbb8af8afe19a5bb4d875aa3b4f1cdb460e17b55d50d1457bcd3179de76ade28a3397fdbe4874ae6ed258842ed1c31e2041cab342cc8440dcd6a0ab3447cd0c337485bdca1e0c559bc808cc809d6187fd4289580c1da0d762a67058605c878447891846fc833ff09992b427db4f83c3ce5d9de8b0c73e614962deb5ded07506535ae31e4608e5c68903ce495b90d48130bea4a2bc1e727c87db2374e3693dc658bc16b74a43a7968bd71672109640b281c44aa38734b107d73033bf9b9b5383e5798a6e6132729f9bb96559944b086487ff5e81fe97adba21f13163fba6fc3ca843e8ad75a4d3a945c401fff6cca934a1db1be7d14d3fcff8e7203a28db40fcad79f9674c71ab375c71adb6c4ca840c65e4021456a5d48e0e0e5291e421484d4e9b3648c32ed1b0957a08658ea910987b9b67bfb525a20cb256eb8e15c66811c8b3d9bc134707df7fc505d24ca8a01e8e7b1f36ed72a2052ad877f5aeaa2ee93ad1791261509ca0be2434f65d7381a5e17928fbdfaada817931f17e33fc18fca927a566d345a871b68544b643155b92eddbf5a89b2fb5c2281da933cac94622cddfc55dbd3ab40cff7ad6d6ab17052fee3dfc5bc47c4cb4579120f664de4004d9afade93e7ddc1edc3724d91e88323ed1b3b0956c3e8cd1ab53608be6f8cec0eb8e7dd3bc40b7b257e4676435c91ed63da9d285809109f0bb56ad4296e6e936fe1b1514186a2451206af18eb2d25c9cb1898b6486d1d8c94cd684024df237fda2da60baf65ab00c51b5d90a45364f16d94dc85c51c28882edad46529d0742df11076ea9da7e1030bacc9cf4154a59b2903773b42c662c1257b8ee79beb4980d00802a1b57ca863b699382d2c625c6beb475320bbf987a2c5ac1849d120114a8c269bca24c5dd4a9dc0710359cd8b8e6a749d8e24978031a7b842b1d8474534240c7b0015e1edfb06607cfa284b5a86cf8c9adbf142e697f7203a2d386f11f6d9a046b1a8931316c3fdad883b30347b96cbefde6074ba4fd082ea623341f10a8f099309a0c06b94931b7a5f1d9f3a4ee899b49f055880912a028834bc628f895f61712ad3f8c29d66aea938c02c7cd3a6da39e59a693267caf004e93ba30183b8121aee73948ec397e715d27bfe8f9bf53b78e0c9ca70b96e8b92d5e3766130f006079959e3ea8fa16b63d3226a012752af94af33251600b9257e306c292afd191a23cfd72b5ca483a8f6265df2cfcecc5bdbcd0d70932c0ba28629d6ea63160d956f353d454a24993b9ae6e034a742efc85ba93b9fba9c4db0940875ebe12f79fc266cddcb44765f5469d6bf722fe6ed05547ef4bce1e89173d7a42f2727cfb2e46a8ce10f3cf8c396008ef4731b1283c1fc26202f6d11c6a20a5a785079ce62c1d54cdc620303b87d422c38a8bafe24c2929bbefc0911a036efb67f96ae4d51f07ffe584396ea00db0fcca18283538275dcdb890257be90c7a126844c12b64e977a19a755c8ef195928cfeee28934a75eff18f1f540f607fffaff85ac08139b3c257ff06d02d6886c952c7b5ffced53b8d480787e9a7dcb5d170d3dded5a0e2935b454036926fbf9a84d848c05912e7877c40487816fbdf18f3f473de7e8a524bb474ba436589ef953efc7a78e55c0a3b101c89e5ea8e9ed133eacd7c4bf0dd4ff52609d98d4a2ea20b629d8545b0d3653d50d2a1fa2beda3a00a0575a04fe83583c5a1c98a9d5555d5a0cc867729054c1da179383d1ce95645b60f2a9ab0abd8708d91789355cef0028a91f1dfeea48b515d3b06e6f66d3537b56fcc2a704e06ea8ce82e910c9752c5405afe4d906c9d05b0de62b55d1acea66c5c7b1764bdfdcb4453bb0baf9f24bd3a6dafff817222a24da69691b2b27959e7448f2fc64a216f510176dfd4fd11c8b963e506fe254651ce13d1d5828a0f9d19d3c48bd9fe5ab032df39f5cb258ddd5468083d5095f3d6a0c98a38ed04384b3e191e3066832221fb5dab5829ae060ec7c228b2d5bdcfee97068920daa1fccaf4d7cb9af059bcbbd9bb7e3dbc292e035ab774020673dc350175960fa33f6c1c711978b9aee10082ab791e843319f05e5284dc5302cb337923e2c4c9cade85a71c38eef9ebdc0a0e8bf3e3ab7ea8ea11f4f31acdc89e36041599139fd72aa6e9acca01bfcaada3d942caa2466e54261ff12cb39a1de7b6e372bf7f81fe0374eb9d1fa508202633cdcf5e751c5b6c8ff7beb82480d4a895cedffcd388b71ec21c3ff4d456ab6aeb4cbee563eadb2abc93a7c95d58ff10beab65945e3d1a9a3bb43471098c92b1359567bfd90217b7b30e2bcd1de8208829c8a54605c39b7742d34953eddd78fb61974146d206f53e116f1a66779f754eb4fb8fb1242e25757158206132e871b0384e1010e77e39ecd805e31e3ee34c37267b8381ff50bcbd6825b83664ffc8f63238a261cda1ae25d5491104b1c805fc132f5067700c6b3ad77b75490bd0e66fd410a18edc5083cb548a0b23c09a7072a074341f53f165a7ed1f2960fd333383f5373dc4889e43d66fc371d882fc5b2b43af06992c0fae2f2d85c858d2950eb6a75d78baadf8f729b58e7ae54f7ee324c84fd379ed054cf02f4672b16dfeb2ce2db2f731208a460d1c3e91bfe685b7a96a306aff39deb2ecc66b7096ef35b22cd1a2b8f3a9596fc7b912a13868517f8cb42a23fb9eb4f974a3784657ec3fbc9574ab6cae042bcfb1b5ce1d8c694fe8bd8727ae9ed5234a6a5fb39a8b3221f9f3d740ccbbb8da92a4be35fdaa06050dd1392f5a8d10465223bd0feacd055790bbd8fad5f3e3a457564fc6f8873c7a64d32177bfd4136cd64d1ab5af008d2543ad5c7bc4e8ed5e93f9c224deaff1fa5c9d8849955e021373adedc873e8a3f031b846c49db936f41da27953b31eac4b29cab3eab06c1b742dca7329ffa56c75310d144e3cfc218033f15ca0c80e12da1f21bd2cac74627dc15458d6513de181a5e8cf8d1a202ee7220b0e889f58881550a4234843f12a9768285abf6196b85a552ee3ea05535510b52284916e92ede2c321b68138c08bcf0f9f8ffe3ee22551d18a0681cf327cfb4d1e65d1e9d4e929b7cbb0f02d4adb970388f8bb969444cf5068ed7489241077eadd7a9252ae848963f54d6635cc4b6ffc993882d1329d2ad83b8b7f30abf2039b062db181b2f33613a1043321e0ba95ea2d22472b0852efd548f2e752126bd8352e43a2a4db0ef78d0931bff26d5638390dd538ea1ec6cef93218478bae521c93f9ed927e297098309f66084403d01572d93ffa1d23123876f468539321270aeec360e29840dd03e5f7f6bed4e55d3f72fb473f215a494b700a0442ba0c51dd8c782a4727d40947d3bc33b3e0ca413bba70e9241deb956ae01afde884e32cd30cf77bf02ce3a46ff4b46a8ddd437860760f2bdf77bab359039fbf5f15b5ceed5c281f556b2ecf241228feac85f507911fb92163fcd2cc2d3501d95db2551a4263be9ef8d058fdd45bfdcc94ed7e59fa62da16d213590ce495a4b7a206456e0d7240907dafa16e625d98180fea3da5586906c77c51dadd6b3629132c83bca0555f8c0394373ed8cdd55d257f4a75a475b041596d9193f20117bca80c9e5fba68b9a744660936996ef5489afc72956b41de6b81e8c63a6126b45a3b72fc64efbb2ace1bc77a4b940eb11fb0ef37818d7447b289d3255682a778880fdea8d4599182da93070bef710f5e66c793dc5bd055e59f8f56d74b9e3ee0f455724ef0b562b30e744a09b9f74ad9507a014acf1bbf911d85d3313fcaeac83cf7ae9732fec6875b8a4ff3c85f1534d5368c77c02c07253fff1c95cd5f37cee46103abb10a43c2c675545d72c3ce13aecf9f977c7fc5cc84a2f3caa2009e253832e4554f860c9813e54d36ef26856fa46035f4e1dbfb48552ae658f7182d45a077e9119319d5d4f99540c7217c2c0107ebeeb706a3b4043f7bae67661a27a2a9beebfcf04e95607356f1bd06017249ceaebb8810e99e8d36bf0ffbb5c12fc3f9c7ab61cb0b3a16a085647abb9f6bb0b8fa23df061719ae7f65e63bf17bf938ee3d1e3947e1073d8911bef61789f4d425dafb487aaf0817d4c5d6b4ac8395d79315822fc08fac876a72b0be8a868fde1e295f08eb0b09f36d786d79d2130fe94bf74b46bb5d75dda0f23a1ea2dcaa6d29583a2ec5d691e9467be19fa47b8e8702755abaadd77b8adf73e76db0862aa2c2378aa3e90cdc944dc2a3908dac1fddefa47d7e41a27b8c42fef0f8a71973e32d8556e67e508195f3e61f9f696acfb03194b6389de11bc7778b3c8bfc469aacd49442421126c58dded0052dd90ba13fcad1ed92938b7e1f13af56acd960bb1fe2e27f1894cce690eb23c8d6c9df066b96e0bd0692ac9be821fb26288e14f482df40e2e7a5c01fef90f8bd2978abfac2b346509b4d816875354be52ceb067a6d2175e4c576d7cea0749162befe89d30b393bcbd448adb2ec22d8251a6894acf915dbb2a2f757f3e2e7299647b87ebc9758e434ca31de20f4ac18fbdf05cef7db13f16ce78b81dcbaf669091ffebd665630023afece4daf99665243962539fceac50872d5b17dcaf4fb9f7204e0b778a059bd6cddef9240e654cc204df1d29407b1cefa53097a472c02d4ab6271c7a8233c5c6663b9f50b8d270ae8d4d8bdc90e0bbbff1d51ecf4643ff2285ef4ecc5d2632f2c7008f3bf37357f34fb777167e10fb35cee0d19a7dfeed20c1bc07f7135ff7482cddf44bd49d81d42b788a35ee4745aa85cd68e245d80e507ac03ecaee5dc98dbf2a10ac3e3169b486122ddbfffaad0e4c89b3d31177b076c3584007dc72c8bcfe47061976367dea019f689fefe57dfb2a71d3f6d176e02d8349703a813198642a2ebeeac4368f3e40e5e76cce8c1e71183e896989ee2c634b679a12bf145149d268af39c100149bf38f78ae9933a9e9933a83cd45eff70efedd09cdd60bd1b84b9b64d20b8cab27dba98c761ec0a9782e7bf64172d28b9de9ce9c73c67b08f8924d7535f3941a478b5f223a88718da5d22069b72bee41437c058079a3e63fe4991c0222e6108f5537a9e8ba2d56cd9934fe2f4d896b3116526f4d5e8278b21a02918cfa969c1c8e43decf8012559efccffb4e52c075284ffa2fa7b1d12767c3ba081c2a9783326fa7c67c23eafa2d32af7ae620fa2ac80bca1363de49dbb4cee341fbf0b8d67e10bb987697538b9c470e44f739ef959d377c70675f84b0432627a0c686ba0056b21fb6aed0e2e6501ba08479bbc6318b7b54d8f5c82059834cdaba14e50e79c95550e131e8daa8cfe0219a8f8b9ac95b9f09940e5718548cbc26f09541bc7f9cf90efab2c5ab322a40023fa9f2fb2a3f5c097bbc5d72794f15def5f39a97bbb042b7f9feb626adafe799434d8008c44b3aa93d8cc2725ddbef921954301528414d77bccf78f2d27edf2772847ce10d0e8818b504e39b1bf9b0c63b96524cda6037b40bdbdbe9479ca0e5b1990cc69631d6ee7503c6187a1d8eb639abded5846a4b14f02c6777f74b14d7de2c3d807122609a3b3e261f1f5d99d34261074f1bc1e3f0dbb73e14e5f73913a3409c689953b2d989edd16b389c5d6a6e9a40c002c094e0025b830377c87323b66109ed477ff360fb3486f819efb5ca34b91964f35c66b7b987f4dfb0c6dec2fd1d19864d133bcc61b275ee06bbde945cb6aebf8e9a0da421134b86905c3f31264caa1989a4521fa66ae11737b7a123765212e78ab56580b94b9eb4eb6a06bb108b3795a176bfe06355039d1e159186a4344c5c4dd6f1f723b5c00519e26f5ebff54ed02560943995162512246e95ab6a410f12fc51d795560a761c69034b44928aeb3b3ff371b88975041883d02c519a205a2b0a1aaeb0012b3bbeab8f1169f087064ec42889b2ae71b3900de1b96b699288aef3c8dbd010dab43fb1f5cda8b175360f8415cd11ccaa24ab47edbeb027b2125c5502cf28df690698a85c21b1467b970ef06b2dad54ce2b4af0b37bb94b20fba9fcd1aa14d2950f6eacb51c3c854f3c219c5f2e813df9a51d637db067b533511da8f762bfe4af20060235d17165cf606733462622fb815bd157c7de58a5cbfbdab09ca840561c0d4f1c20ebe1c7ca418ea14a5d37ed298dc3e4f4dab399cca44323c522acdbaa115c2d09965ea1b9deec6547b83b51b35cdad7c8037cd91b8df37ec631ea0e3e35bd8ad0158a56bb2f2cc3f2771e48154669f69a1384be60167ef75e9aeea2b6413cfb0b6d32b49887e2300eea749c6c444cbb4ad009ac4971b09c96a7a24c385c63313d73cf5b3603984a10891a7f2a0bad5a6d453b8775b1367b4829fe02d981e2e5e6ee114a562c496b7cd2073a3755f08c3011e1e1aecef3905db04528145d2e51ff04825a467ec04f6cd880aed97fc6e376e65c6bbaa4987365ebe3d25c75d0c0f0f5e58abed577463a239528276b2f5a5eee692fcbe6f848a269ce1482177f3f7eef95847f872ac8a51dbb0eaa3844a35099905e38798b8b2975bbcd40c8954328f919435fb707b5d759457ae3e9f396edfbc3602ae5ede2dd0428d60bd0e82cdeb2c39b4940a436824e86477ccb6a1408641803172bebac66ea920bc0a4393263bad9ff35d9e262ac4f64f5e152f30c3c39fdf9ada51b72d98b77cebf6cab7198102a0c86ffe9be0d99b04789626d2d0c75e790acae4adc87e13b799d7398094d859e539204360ed6102a79c006f263ec9b1950058748e97a597dbf1e39e91160a395c98e22542c836d9ef5dc796447f32cb26ce280b5458dd638c421d149fa2e299462ca986621b7a0bf36f35b9fd4322824e4ecfb0c93ce1c84481bc917fada534dfb82b76f8963a7834819318f715ccc7495e9e7f30bc28b88063b2e9fc84d27acd1e1c84f981343dfd8bd9d1a6babbbfc531b502435ab3023661dc9ec7f5faa2b1b18a2a816073dadced552c016d85a2eb23ee1f0aa9ad4c61dbb511aef3a4062c5763453f821b52b7fe579b02388bf974a115674292956d8b2cb21e485f9dd2061e33425d14d7fdebfa727105beeac4d5e06b68910cf4e029fd5894526de818ab69c5c69431216883864c0a1253a65a7f4216a35917467d95c56e96dca355cc91cb96c14a7cde7bedf7d343fb363104c488d96182bb5a8f53f3f52acf58e3f1a5dcc29020e27d501d3500eb116189d7a8e4fa97897fadadc63f1fb643fa79b8037789875d1e983e4f595e77d54aee5c7828ac2b07d7c66ff385193e0ef8d9e624f7eb49892a1d62c7d3943cd811e2334f52bbd28da5c4d448b62be746b961c53096d0fc266aa844bded356c7da4520ac6031d5839860bc964c51a87483f4acb47b247f7e06bffb2309a4d6a95fda45294d5926806f1b8d7950210c61d75ea214e1d5fc49269abeadb3fbbf692a3b8b007ef969dfb72ebfaf739fda6e40441100ca6a69c270f5c2944a7131b169767c8a7d7013cfd55c012ea750a60ef7d508a7b1d420b566fd4f39f97d2d74c8c521fea121bbfb1512078d931487e42a2a344bb6397c1077d730a861b037e04a8f788bcc3a48461ef5886c453254466d1d0dfba55bc19689c06452008ac3ff3f952c76fd15b3ccadb0ec54bf7804b94b08821fd7cc5903448e4c7042d7e3e05ae5412daf42f209974422c4e6ba1fd489a0f93851456b78c077c9f864c1fa38ef0a9e90811cc80c50b5c15d6fb92e4fb42eda25422f97f97f15dce9bba909795d8aebe49818e7fc15fd6a9fc1477a4dd95390ffb5278cf04e4e5dc5051b91b8e547eee648fa1e25bfe09765d32c9154045e0a9b1b81607f0761294fb96ae8921ccdf68eac1e8a853c89a61b65730d0e4f173922a85bc24de457c8d944fff490f6ddea2a3a522d73906139186f5f4ce7cb4342985a1f676c144e06b6849fa618330b2371b1384d442a237f4fcbb6b556a1b3dc39a9712ef2c01540d528bb3e089b74733bb9618bd450b1596e69505ec19536e26db6570b97275ab85a6e19d2efad18c650c879de53630bfaff9f2b149f75eda6a357563ee97123eb46cdc220630f715fa8b260f3b86c2a18f079baba74436433fbc4b9686abcefbea16742982a82ef99fdb0053e43ecb82c4ded960cc9133cc34b2530615178efc58874d5b810faf05a52807b886ace3549a829ba202d9c396079090193b3e63414ff8093368fbf2ed01d334bebb2769aa5538aeda29a118515f50a85c308376194244a68b527934aabfba5be7f08234406009ceff0163c62d498f72c8bd795de04400c2178a4e0a9aa016f92cda4780c67ad85f9922c5bf1f1a853bf1388f6838aa3014f3e53ad1d1ac1eeb1fb05008b309c7c60b2161dca31e1d6383f9f1659e2ee2fd6a8fc68661aea387941f6b73516aedcd955262985c407f5323c130d8d1ac945cea9b34475bc64d764b392221ff27d560deebeef9596a358d6e435114532f7cb44ece047c4da9619b15f83eb30959f529400d27f88eaa7091b24c08e9e9e5e9a4135824bd3030e249c81d3c93912e945ef53f01fbe15e3d5b00b67de946c23dcddb25a8d7c364e9de2b429c4d514021d8b4a5ef23f3885251cfde5cf5c6693d9db1a491aecad3a0b733b59862045d831084eac13f3f901dea84bf81c53f59cd059bf5ecb7ab30c17bda82710f569ce48bd889d5147af412b53acb2c421df7364db22a4b5e6bf4a65167fe743d52bad41be5c2fd835fddd58f7ee097a5e074d90da9ba84a03f0b177f61c86e9bfddd5841517eeadb09b6989f3f763d127a0accd04c94aa97091873c828b17b1e57b70a307345ddb57ffbfa502f75b4c687699bba21be94bf648cd6b4139a2325d9a9d3ae2be5c30a12a64fcbd3b4386028cbdd837aca588fb5f8b1f990682d472353e8ff43ebbbbc1af3fd381a73a7e5eb074debe98cc8bec3b41d7a68d78b9b8178d598bef585ea3b93d091841440dbd922b7407c056641a02ab28f97bb2b6390f8c52cbc8a04681a68656e5835198805ef738a49f846e69c3a25f13b5085d92a61f60b53c08088bdb24e30b005ba43c84dee6e8085fa5442e499f7d324efa13f36827702e02e7c997355e0d843648a9b911e547b353c0f0cc8f79eb0c6b17afc14a1f9382f79cb23cba71f4ae111f37de4e12543c756079f32f69056e1e53812b04ec5590a035d296b322319ff518eb7944d13f0d576f34df76583fb77df06214064cdbf2631419497cffa6f3bfd90394ef9ffe31887088acaf05260f7f79917173d9bb39b26111bffff175a0d3b5f4fc271a11bcd576d1e305bf3beee161489f7e3e4abc03d39a1516bce003d34393485fbd9e225c71fd092d3cf03619fa61e81313ea7a61a2422490e236c7b658eac5bbaae21d40c7348d5333a08d77897146524b2474aeed078054c1beeb83f45144102c05ea0294a7349627d1b1e449354b4a3c4e7f5bf6f696f6a7382adfa03ad154e49a1e884049eddc8cd10e303aad4699da5f081bcbf11d01b119275bbe1dc62eb9846b28f13424444e636e64410a2754f055440be348ebb603c646a79d626840ac54ddc96804fb3ba4bb4a967e54ba76db7674c7245248c6ddf3087804035250ebdbdb02e6429113657c8702b068b8c2cb5dd32b8d211a8f33cb4184fd28518f9ab4c53b4d8ddce26e900c0ecfbb87743a93ce594f35388aef7038b01642ee90663f523fe72c96a67b200dd2bd216500927978e99f3962508a465a4567cd092a3de54bf183e7fab2a03c335fa89d6f6a4908f4699cf7caa91826ee7b62a903c1f0a3ef42b73bec3cf2e4271189aa3c7343c792b76d4686ecb940d9a0d5055fc9512be680902892b8806e2344b551765312e72dfb765468256429b1aef4ae2c38543f4add0d358ea7732c0ad351ff2c33008cd14382c0f731b360e1cb7ee52713d8efdaff83fe58935d46593ba31b41720ad08bd07f3b3b08f5e0118e942813cc6b14c93b1a9833fc8e6fbd2c87151ab59705f0d507720d182cfba098475a20c300a3d0fed0735a8bae6ee2dcbc333a0822de1eb51e078ba940d35385ed00f9fa494ac9bd2c542196e0d28c4e329b2f76927053596835b53b15f99d565e133fead840d23688beabcb9c0fbab5bf72ebd85289c8a8afeffa9659dc0018f0618d6211eab2af4069ffa382852ea8e67cbdbbcaa406b3249b08688f2b5c0bb1c263c5e89dca527a66aca5e43c246071682a7e066ac356c08273adfa93d7d7668ec7a4a09c1e5cd7e57af2389c736d5fd272df5ea37c6ec2bec492401430c0506210be1a91d52b0791dfa73ecd9d16f12251b9709df04c668cbca39175e477d7d10cdc76eae8670944bb760078a7f420661b64a9266da6d178d37fa22a0ae28d730c6ad20da9f03b386aa5aa99874c0cc9f3368fb10a28cf0c4edf254cc185ffb43bdd6d319aa6d8a97ebc2c07b965304ef2a33f50e8289674efbc817aa4722e956c3eb6a7fae7bc18aefc1866a23f67294f6e823abc4691ecef62c5bb9290d6acfca3601d8d104441502ee031ae60d56960628e82c60e48ba42e2dcf4192da6989dff1d21ba86f6308fb61dbc5aaa090ebde96503e063654882dd548b52e1b208cce9b20ac90c7a4e0e085ca121e7e603bc0110335e9c73c50cf5bae9f8096bb0862f2fd472c3694d4cf5540446b150916143004f8e05066e65db05f3d97d2055dc186d54557e8bde0b469ae93e01afbd6905bdbfccd8eb9db9d4d687ef7667355521a77123fcbe489f32fc38c24f30d590a1e7b41a6d62a016757d4d3a0834baed304a452c9e6ab399c7da7a8c5704a147a3df17fbd716fafed9da3e1b0c10e85116e1ea573d9efc5fdcc11b79568f03e00e53c837f87735afd588165071a83480e5a359f78e5e98b8a92e233979bb95addee407a8732421998317330a423181d03cd43f37ca268709c5ab274f0f8aa421a5ab94627d6a6d496dddec53d71a98e000e35d09bc747ef07900c915815289be8d66a1e2d8825aacac40e37d6b1803179e67a9c2686d19c2069478ebe65c5e36c85b6e3d897ed352ec037119509a8b5c274c4375da21fb21d41f6c2fe2a3bc81e9769180b78e971d129e8ff8d61c496989b54d7bcbcd08f598ab986a957b20bbe1f899ef10bf4cd6fa854b68a6785b8d51e5ab64dd00ab244a7d544b4c12245faf834765e8014c0831caf402522b98a368023a997c38777db1de7f2e08ef834bf2a54f1a1700a84d0c40a86ee7f5ee21e00964c456ecb51ec66870abdde4f8e8d8344ad8befe4b0b25e597a4386ab4f959960f4e47abffdf7b73b653093aef7638aee69a3cedcebf126462abda5b5cc1bfbf042290fb510b1567cb09371c373b72a795cf12892b535e6e24eb611b3fe25190303ea097b0a991d9a05e70407c7eddecca53e3e07a883e5e378d6d126db1ed826918ffd370e102b33fa44c5d4da864790ad8160482794b677080aaedab39f0396ae5008d6ae5069df35cfc1bc3087cfec3cf493a48fc188e4f648ae79374913a8dfe93a34878379e6c98c7a61e33b6f3d09512a52a55cc1881393c7c1a3b15b06ebaa12ffb9a2ca67bbc3ffcda72db3e4e4a596aeca7b69849ae76529ef4edf58a28270fc3b5a95b46f47e6566d09bb7c11cabf2eda0ce732fa5113c53bfaae2a23d3e328929dcea1d20ddb42f4f64bb3eb65b7f61e3b04eeb2bd8f11bd85739af6f964ca5374b40533b38f576e4b8280386a47ea0c3071c62ddf28490c64100fd37490d04ed32a97e7d97fdad90bdb44faa215f572787356c6eedfe30e1cfbd9f7766b4db5e30ae4cf702cbff978460d1a482fffec571d97704169271a5a8d2c757b4babc09495f0ca70cb50a05d160f4f14d9cfc147d8fecb3b58b636ccfe9971614ef666d3a445cc46eb221b5e1da96d0caa0d65e72fcaab5c91942321aa03eeb659e438b2069d6cf4beca368cc0ae7f65d080ec3fdee6430893a12669e34395cbff3acb8802e62f189195c556b8d945753112d5eb71e6ff3162cad70c41a73b5e2fbaf7593b851d035d4d29cb17c50ff894d8ac464f4377a3df5f1cdbf34c7be0eaa97615b19ac56e4e4b09a5cf9ea3e16566d4f2d37714ab3dcedf1ca70e391316a32b653b6bd04b39a469cbe7422947515295f800815b684a14397bfa284e8165fd7e85147700261de8d446053962e3fa4dfde0b595c542d4d9243f04980092eea14d60f0973da7d97343426565216a61f2b748b90001114c9e3342ea486bc85694fb165d7caad5c8c007ab677728fdd67d76fe6a9f2e2be1ee7cf0a7460267250264110460660cdc24101cc26ba786c9182eb1af30cfa7574997bd4b927dc9174a4a995f6b1d9727d73a3824cb15ec28a91e74db7ef4046f9e5ce4150671b7f9f0ec125ea369d956af4810c7734992d012f7dfe0345e8d4a0717aa6fca15d9125ff875a058e7881b1101c9ef91ae3ceb40ce501691da07fc5c6895a695158f0bcbe910860365ff1a65fda48043e8519b221245a197a7c652a2a05519be39ad6f32f48f40aebcc3cdd0dd9a92cdf7e154638fd5d89afeb3864a29d27165ce1b478d576f762c5fb3084970c3f5630266fbbee91bb2c3c9c55c51ea24d36fb5b2ebaaac65096f99780dad26c3cb54f6018c08939e5e2124067ac987a3fd07482d56a2d8f1744679b3b721984e9dbc559e080a2c98c113555a9dfd439847dfbdacc8b408af372012d570d6b57f1239cbdc72546f84d708fe554db422ee813f6c968c0c9db350949d7f4b7c40173a9c7a6c347934bbbdb9a1ba431a87c7c35bb083be9bd9fc4b8b3ba1e7341ae9f5f65e77aff0092a55b7f51d24bfd862e1f957f6cf2e76fcad9e61c68f0f225ee88461fe622f4baa8a62588e491dd27345e8ad5bb5cd14567ec744f955d76f9de42dc936aef34421c7253b965d3b3836f3392aa0b691097d9705372be47b403b9ae8408f207407a3b0a61b387c282fcd3df27cb88a6abee8bee71c28eca9b4afc8435245fa609d010f69061e7674d1d46f1d1cf9f59be1ad0c5b73094a8824a0c3777bab8017180ff95f7d7e73360d5c4259e15934f152a9dab3affeaac88ed928d50f12a2094b8ddf031b750da0cd068a41ab3b037a0a864a608b5b89c9dff2ea2ce0194a213a4c7a470000ea9ccd1036890543e60a27f27422848a16768f46e350839b928f036bb1484537bb57f5712b4fcf1196b5c13a483b7b718b1b301fa0ff743b2ad057e6e793016045aa1a29444738a9892224563e15da844b248c9739f4e494d403e7ebcfc430744cf9f5a8a47686827323c48151a25af1108ddf2b9a54ddbbbbc38c77e1aef65d640b4204d342f04ba20bce50259b3e95e5dffa51b10946177e00aab7a06fb65407c58beace09eac7cbff05d21e4849ee2093546a7453bfa172f1496c6cf948ea46e7afec2e8fca08a3e24cb1b20857c5e326b6ea61c861d4663fbebc4aea902f89bce0b761c5ce669a022bf4f7188216a5834279b33c568fd339d69f68c3ee250249b4d2d2f03bbf6efb3f92abdb9d9300bd7b841b80f18bdede0b5d95320cb9269a0a59930505a264ec0719dca99a11c4da9dfe886f2d8a0efece1a78e3b1a10933b8abc9904ca2ce14dd00e4889db5c8f12dc50898a1f5266ca4b01306e6a560ffbf33eee82ea2a4c802587302aee7759f600bf415760c64962028908c61e4e1982e90bd806322e8561df2c36da35a272d3fe17d06bdfe5ef024fcfc40726f19619b3c133c560c3876d2689b16edd221e2b3f136bae259ea9edda234cc3bce6775e014b79e58eef9ab8a0ba0db0e0a1417a7799f3da126ff688c26a9d063d43cdbe51876847a43a42d56acb204e1c741460a47d5e2f163e72308640af8d876e0aded53934fa16e6258bcf37ba16d2f4154deb92c022e9ba4287b173eeeb7d14e2fd3feee23744760e1c7b9fac6a5c81120e80694c0e1101abc50a886a41973eecb832e35502dbad5f5025cb99b4b83b193250a2ef91c2a4186cd283aa7c96711762770d7a05bd3d670c678adefbe7c173b7548f9bf7fd9cc68b79f5208b4bbc9cfe94d110d3f5cc4d33c6a3b68ee9dab451f70f013a94e7e6ad0c5290184bbbf63186f431830048cbe4a4f26c31c1f5d6e172a8843d845b40c54afeb37a8d184e1b1fc7211aeccb7057733fc089e69b35b45e2b5318c81e37ac866621049c4b278681d515260616eab9a6df6285a0e716bbbf89863254e797f63d5f7407b82384a14fb0427275eedc36460eb77c6a89b91e8f01c86a7d3f300d77a69b0e33b5dd33290c5a55097a1322c72c39ce13741a3885238c0a0025af15fcc05ba7e781c84207c651a51d8b29b654659381a3a634d8c44cee0ee74cfd7a5bf1ae50c35ffa2684f6e1facccb7b4b5fc7d7a18c55404a75005bd1d806a647474419375493d198d733b8191a881556715d240e3afd928b512b67b4580d68bb37855c4c692d4eafa3090308fab35d674d745150c43a9430b7e7bae16ad73230e0662959dd7e9142d14528ed67ce299fd6bfdd03502fe7a638ac34c61e4f55d5a54faedd31a93d38343cf09cac0bcc7ec8e63f99613295ddaf9550930f5997fac149fae4fef3bd26ac5b4b01a80f68f24be03925dab33f216bcd2b1e6dc3d20de9a690c3c9584657a23e60ff8dbd746374209524e8c4e5f41d411be4f86d310ab1e687a6c5decfdb384e486aa506c3983dcaa8092f487719263b437d4446b12b51feef3447a0819ea9d89d84ec28a415aa32227a146970dae2872fd6b1d2a06319c1a37a432fa52957909b4e6230134be99e0a7979d9a4ae87e8ac63da52385b331f6dbd75cc65d037256392a21c45740dc9c7f395cda4b0775b2235bba353c3175b7cc3c76ecaf180302d6ceb8bd89c537500b7f6651eedf9ad86c09bde8c90e0aa6ca651256a2a5f1b27f323d525aab8402624daa5fcbf9b22e3ebc68309875aa63f450cc104b8b331a2aa06d485606b41f3dffeb58996b17f9bebe3929e67f389cd0ce95c00ca4e7ce594787978bce55f8d8590f1277f23880a2ce78ee96585b602de34e653095e22861d3782ba84afeece17444931074f1f9a6cdfa8137461daa30edb6f42368743257bfb0d83fdfee4a4595139292d8c29f1d22d675276426b5332898d81ebf3344c6751f2ddb2467672e1902db43618250069f022645e86dbf79d94ea966039373519065b5f8c7d1e053a76b20f1fb9fd3d8373dfddebd5bb50480d2ee9c79da3b5b7db972f5df956f6105ebe64a96db1f6761621356164776763d84e83f454fc17a49da67fbd12f551644a813bc33982c26b9c67e90a6c1617c4a5d43a6be095394e60ea4f40ccaf377f553fc047ec7c034a54260da71035ba590ff15dca26e45463f7aa043531f93978ffa659de53d7f849730cb309df7886acf15ed52f55ed214df47f46f6a227b9af77f8da54d4fa5ce4969a176d72efa57fa9928c651d149492332a0486b90d9fe85035843a14e0ada2645ab86f2a8dda0c5e3069a8a739acd320e9a3a80841f90b9df0e7d1109cc45d6980bbccfa283b38a11be7e5f241bee6d40db58ef65c88fabb0d474a387a958894572f66e3fcf8402f6f691f3c813cfd7a60dcf0368eefccecd88b3d2717b0471cbcf324f00b3e693cdd2eb03c2bc2a362c9c7d68ecd4b37d5a1fc42889259c9a1bc85c810c7166b07c0516938570c1c5b664e57707bba9bc5e340030974e927b348bcc36ce2bd91f0afedf6fc6f805b7051d814254c33076eb4fadd47d7e4baacc5eeacac9d04c24cff1563ebf1c027d4a8e4f6d28a4540ec85d387c77de9191f945fd8e2db672d0061bc7b87f12c10b142bffbc3cf7fbbec6594259848a71e37b699ecd51eb472f628ce4683e39c179afe2afe868301bbc0e3e445437f5377b03e3337900cddca89cb3db74d34e190d23c1b568ed469d2972b06686f6298a1e80e233502c122374b3d0d43f36753abf1542497b76b7737e3a362e9c404bd209f08176686a063959ed807dcc73d46e9c3105000552aa6581077287a89e36dc7deba94610caecfbd622495da0bb438e6d3c2b3bb507cb89996358cd5e8742d57566d0eb1dddfebd24d52f2bd730736672acedd6a0ccf60481a19b81a728e8b10993acb2aa0fae6b2cd069a36ec1d56c325e004af788a2840f5fc7fc77e61677faf0bbb945f912f05bcfe8d4521ba9aee5e6db0e8054ccd8132a05f44fdc27aa18acc1ea5d80872d6c3543d79991e15ac8cf0b7ee6debbb6c20c8fd5b279001cc7ea101852bcb3d970f16d5bf4b7a1a2214853a77933bd0c269122ac9e6973edd2d4917daacd2c2fce7ea1ab564dbfbbbfd25d76fff4c1046453b16be21ca7057814c12ab0320854007c22b7cf89fd78f0a509b63e8f1fc1baf46432745fd1bf718ea9738e134d52df15872a087c1f6a878342913ed4109b8929e04bc8dc3422892af4503e13f444099faa2bc4636d4870e596ea7d379ac51b182c1cb0ef0d596a830721ff87fc6be302c9086dab808a886775e638a2e98ab64ea1430685fed0bb936790e98df0abef45d5c3fb28b0c8c10b07c3b9fe4736f06066d279dddb3e157558f08157ea152e8ca040e5fe996f63719eb8a1356f8f941165eb73de2fca1e6dba92d5ef8d380a1e4cf11b9e7c344c0c6ee86999a926d25b6921a7f573f5b41d397e6f587fa7e40a0dec9bd780b69469000155ae251135ad1718d584f9 \ No newline at end of file diff --git a/src/02/input.test.ts b/src/02/input.test.ts new file mode 100644 index 0000000..8bfc0e2 --- /dev/null +++ b/src/02/input.test.ts @@ -0,0 +1,14 @@ +import { assertEquals } from "@std/assert"; +import { main } from "./main.ts"; + +const target = "input"; + +Deno.test(`correct safe count for ${target}`, async () => { + const result = await main(target); + assertEquals(result.safeLines, 660); +}); + +Deno.test(`correct dampended safe count for ${target}`, async () => { + const result = await main(target); + assertEquals(result.dampenedSafeLines, 689); +}); diff --git a/src/02/test.ts b/src/02/test.ts index de404d3..cc1e92a 100644 --- a/src/02/test.ts +++ b/src/02/test.ts @@ -1,12 +1,14 @@ import { assertEquals } from "@std/assert"; import { main } from "./main.ts"; -Deno.test("correct safe count for sample", async () => { - const result = await main("sample"); +const target = "sample"; + +Deno.test(`correct safe count for ${target}`, async () => { + const result = await main(target); assertEquals(result.safeLines, 2); }); -Deno.test("correct dampended safe count for sample", async () => { - const result = await main("sample"); +Deno.test(`correct dampended safe count for ${target}`, async () => { + const result = await main(target); assertEquals(result.dampenedSafeLines, 4); }); diff --git a/src/03/enput.txt b/src/03/enput.txt new file mode 100644 index 0000000..c036098 --- /dev/null +++ b/src/03/enput.txt @@ -0,0 +1,2 @@ +179,91,128,236,163,214,238,154,57,63,241,210 +4961171c23a86eb53743159063653477e24ad39b2be1f248dd8a1338de0ea272ca494eae5b66c985a70dcf09f24f97ecf8db0161dedbc84472fb04e85cb94644f82a97b8ad03336a803daa8f0a0e837b1b2636a243c629724ece0d2978b839044696981a6a8d5bafd6ec902981953ace30a7aec135bf47b5708ccc2869365714acde9e10c73ddb7103460328b4830f0445bd716a3254554ff29a2f50d7bdeb2e07ebacf9f6057afb6afac4aba14428eab3f1ce5e40e94a0848abafa4247b866208cade2bd1bb332f25cc07cfb86f4c0384e31eda67cc04e7bd32fc0ff79eccc3d1508121a430ec20e36528e535435e0d9b26b76ca4dc101a1ffee49e48d00b194c3dfd537b28142187849f99c8698fee7308a6da9c964bde7ea79b05080f1dea0b3e0b3b95a7070dc913ca07a7714ff8b92d133c0f295b0cda53e5ce48c0e0f76f8d74d65b4041d53b8c0115f92287832447ea2ca768a9d33543df9da469482eb40b6b7d35b74101bd8660afa8a27cc24b06b44b43b1bba3fd5d9f29a1bf48027738a3e8cfe53589b568a067233b8465febc6a270ad7344f1b1d5b677c7f1f4755477072b69222a292547f351a969be1110c7015efa05e8e153acff51d93fcc00e549e5c162c59f693cd3b44c1d66fd3bb6e4c370eba3335c1fa5702c80a65113038fc668bc5027f67512d7a5af5989953b8b50047807685323334ab547672d04dabc5a783085b4fc8a062f67df883131cfd5e89c7b23b81837c4e19ea223d77b72d6707f194fb71df902761e669a28a663cb44b412e66a192111c72b8e9ff60b5548c90ab648cd328f575076f08e7160f37afda6fa9f143920a71220958ba60bc7a006bfab169af6a7abf8b647de91d98fc94a544ed85f0e9e03ea292daa9cf5cec6ca0ec109c7e26c05f321602aeb84b2d1cbec1ff26b2138b611e63b9ac5f4e9db5a0e0764e1b797e1e3e4518410e930615e547c58df8b41d078bd75ada95b053210b2ec15a365e37b68f9ee10b687c2cde0a20fe5dd4ef928d22c580df911aaefd479d463d4dd262b5f39770f51e6f18c7117532627f9654b57b9ec32f02018fd26efddcb10e3a0dc369d1adb0753c22532b3ea9f857ef5a16170c951dcda31d6c34c2b3afb0fdf699b5c36cc3e2b5e1bbe8a781a5a84593ab1474e42876292e182be4d54d091878340dede9469d4e8667ce1ca00b838c55cb6c543ec5e21f2c81bb5016b58ff8f62788d2b9caec3b904215aa254524970fddc6ae1fb8a377ec4a7b50e6e8f4e552f90add10e5ff1628ef811ec85956fb221f4f9e6062ff5b8e5784a06b65a5df2626064baf87d8563685b9ecf24620316206de75ef98920d0bdca4470be676347ed7ebabfe4af33f5299141039a981a0a432345dc548ef6e6cd68eb13a016dffd2dcb2b6ae1e4a4e2dd64110e8fc082ddad04253b831b468430c348fccc68d840ac9f9a9006e7564e36775febd1ce4843062f4f028949484e57edde646fb7c734b0d5a61439a3d6e04832fe724e7674b28a48b1b4eb11fb9f792c57fecbdf0551fcb8106eef4552eb27b7e4f9f64c833704f7f7ad1b12efbf98f5d09c7b58dee4b467e6fa131410168a22e68326b1850c1e436f82bbbd98ccec55164a4a640dc8e463232436662a356b6de4c0eb1a164d222d1b6b00906de8ed60f80f5f75abffaa9cdf07c2d06b61887b4d263b1d32ee7c8c9fb297647a3896cfa2f0cf616da244c4fbda27bc91f74fe371447daf646d3aad94f0f4cf45d733181e0eccc1a80c5590da1eade7d1f0c06863e43157c9ae8ead7c7ea338d2011ec6acaa5e8720ad0e8b5da0e573569f94b1c3b3d300405b1e83bdf8e445aca13be400288504ad79a7f61c01380653a0865231c26f82902f842dab828f92dc895cbe0f3a45997f9fa76b19003f538eea51d469cb86f4173cea236508525369ec64c28a06266291b844611058d550d6b8ae2a48e487f13386ca685bf6ee36c57924e53a2a19e7e96c174d16539c6f0a8da09f23dd2a8b71f091f354095eefdaa1af1b50481c665758d56f39a5a517c4404c148d9c2e34d39c0deb00e77eb2ac61461c8e985fc0b47e11a4047e4e767ac6fc03dd7a15309cd731eade8b87ed369c1575af75c26db4a6166d6a94bde8aeeac3a4c8f986f47867f64bc2dfab679c9105db74d57b6646410e013c5950a06fb9d4905d90f68c6264f2cde97cc3a210bfbef3ffc4567c576fa9a15ae7f24e9ca7f549c60c8ce2f990a2e2b7448b9c14a02d011cf48edf3ad9384ae87ceb32feae3acbe3b4f3a3fa23e3c95727d1be0d19391a2181b76c1b50ad18ed0e930f90acd991883213765a16f304a12aaf945f2313efbbfe4c98a43918094ef658063c2203b6ad965d0c2deeb739c7df9509ac9e00c96f3cfeec79d21fccdf4bc9e65bae154e838a56fd7daf8eec0fee52c92300199f8c36465446281a19169c88e8dedc65608ecfb9459b7743373c3a01e12651eac6df854048067c9556ee8ebc357a6ae1a93ea3773e3fc54d2dac7b9605041a7f45edba04f999b769416b0c6a01c2f8164f959276721743ea82298725c1f7990e362b71f9301668d05adfaac38940b63d200ec392e63173a59c1c4e0b94848f1063499d8aff73a2667fb155f640e9281d10f0f56b47b224439d7c3effac417f38218eebfb4ad1a7764bfb62e0924b9f02f4a0dec75e14012230881e23962308197fb20c98734e594f265342f3502e24580d0744dc603633dd4d13e7dc5c70a97a34e7708dcab5dd209d7a3360e7fde523f9478e10eff6ac99699e6ea04c7db38c1c2e8040124c9ce0157173d0f7e9b97b0c1ac7c9e0f7c38ca04ab55dd1b32a59d7e6099a22a30e4629699392d1d63c95fe4ec1fde6bea718451dea85b8ae4f444a4994fdd8915af2e2ce37ca992cd9e654b56b6cc2918f16f61e55817a8e8e5e085a1c110000824259f2a50ef56f1f18bbf8be0822d88515c0909e8d0ab90f85e177c48f07b693891f3f9e845faebfed29e6b533fbe4ac94ff1d64abf6eaaf19d7d5073f61178ebbe8a541a6612193dbc6cffbf6899fd0995b1d2a594ddeab79868cb4aa08033ebc06cf6a260a4abb7f87c07d192647a6d69473fe721b84a91fb2926654a6946c6b71eb8a0d520c23c070f3a7ef19c1b89004e71b3cd971b852537cdb4f581f107f084dcfdedc0fba79de9ef9edc79742d514d2f575b9b70834af23e90d0fd480c1afe734cc45b93026cfb5647ced3870563c25e5cadff72344d11035f80ce3c557411c07225a5ee6b95463607e945c576173e0fee45b80954096b4461b5ed3a900784413b158355428782c469ea536bce9af8dda76511d37883598b2424b805d808ebb83b5df61ac71b02d4ca83398f24ef74d0add62e7d82b143d4cf7c0add681cc9bd306ed8d1077fbac1b87e64623a39c6f0a4f66005c3d088e131ea5b1afaf0db5373612cac536efab0e70ced194c61529e69b44c4d6de8296f02aae914e198f7cdbec0cbf3368a86108bd798f01d63b18dd44808944002799135a1c662b13ba8acb8ba22ea31421678d21354ccdb05f1e5e8a4e869e2f75adb06c816bdd7de7998f98a26197482ee4b501256bb11da54e956009b655c38dea134d76ddc54edad1bc2fef53555a00ff932a18c6e28ee429d49eb3d57de655dc0315238059f94e2a26eb0b7f785b78f9066c31f741015d6dfe2a0794519732b56c85254ad28dee5197710f76840e9b4ad37cc6cf8a054cd274ffa115be9844a11d9d04bfd5a07154037379a28571b50ea4e6f3baf2e2e66320b7b311a1995cf2daedeb33c11792a3ce430c0b5da7998bf4cf8a6db3ae68b070a41e5d5efb784cd1ea75c1ec13be44553aa09e7155859405ba18f3fbbbfababaf10c461825b9c6f2cdb207222a170fc6dacd81e7cb534b677420b688bfbbd5ca211828f00c752161f665dc4b5845313ea3049a2a642002ad9c0ee9e1eae47e76423f339ba4fd722c8b7ade6cced0778608ab5eee7eeee5733f25c1d15125cc92f5391297a180c91bd5e25392dccdcae61d096e0f46b71f5717c3adb495154b4b1989189b83a83789c339ade6be631f5391150bee2e562365c632de08af1862a197cbc2ddf553c8584dba99296acf27fbe2892b3cd84fd3952059893fe9a0f3df86a3426afd718d6162b1b0d04219e2869a89a3298475ddf84e5e84488da90de716ec9c81ec69b304a1cc76100f7476f01a2a46450ecb71c7ddd1b6761e7e91a6fcc198ecec58abc1936b738f1c2003bca236e89cdd29645e167abd51a193347187f0e6364b35e68de39843701940ab66071e4030f2bdf142a6df389bfa5d62c398e4be4faafd8c41dfbf9c4e6ecb349deb331302f7e2768039e360f5f01bf066fd59e84135318a74b2ada89fae3eb912855ad56e4db4a7ee416b751c17fa9db639b3fee6ab983e6d91d56db4a83dadc6e0a4849b6bd268c1bc21c2b8024e96d35ac798dbddf123630c035fc20a69214c69381056a641b43f9d2bbd723e8e09ae25eda26c78de1a345c6577aedf353f835be57f545fbb7e353a75c4f52569ed8987259bdd4bb1569602336a90704c01ceaee21eac061020d45e145b596b6df003562af278ca702e236f56a96792403a3d55217508154f720eedc07c15b187c0cd1b2ca5a287ed7020b95057af27ccacf84b2fcce5de271829cba3ffe287310ae0e8a5ea03776f440488f50b218f0ab5078e6e1db6b3522d1cc33a81028fc372e616e7582416a802db0104db1835403d6ebbf4f3a3614fd0815942178b959168a018696a5afc993e7484c52c0104b43c6cf9909becb830f59328f8c7be3c2f405532d810d9f5762377ea0bbb4873bed25daa4484b1ec3ae9df765c7f2d251f68df0f6f3ce1af4bd2ed78994621cab2999de142cb513c86ed842f66ff4380a641fc5eb5e402124aaf19f58035ac476a6832a99a502725edd5b699af182062dba200916fd16c4484ec592d43a7f7792c4c989fa18bfe6b3e46550d67d4111c2874160f85d308dbfaf63943970c66388551b06da87da13f99aa2200b4d63abcdf6f4640c3ae0861f40fbe7a20dafcf495ea3babff1941d65f1729753bf807459b157f8c5834eaf160f9afe9901d7aab770ce9024695472591cea3af2965ebe1e2b80f7f185a5909a11656df71a80351ae0251fdf6fc0b2159132ce2d2adb2a227db399c1e38246c5301028f7eeec9117696a9ee7abf20de62c1dc69de37c0b0089791708ae92a9510d7394077cf16f7e9e22b5cf608d7bba4ecb4eed727ffb43bad1dc4f8d71b658c10b4938edc07a0235dea5bd36b9dfeb6d5f4ad315ddaeccb937cec7901f15e98c1f10b75e0ab4cc47780e0893d640f16ee10411d4949004d9c7edf8717835ad886eb6d127293b77564e955c15431a12680daafb26de86bb890c47d5394a8c7cd0da876f9d06adf06bcbd6d6d3a6d40e3f762c803df526a2e69089025438e490f66414d79faf56c1edcf3d43e11c0b5be0a5caabf0fc7e55770255394e36c53943b58091951831222213beeac16822e9ae648f2ac6ed06072d66e825106c4c9ce8f91a283b0ee6fc6c58db6ab29dfbef34cbd15706b6b5fcb5b48600a69528f19886dcc8164b0cc244f54d5bd1d35511a3bf2f0da28b476480c54eebe394d6343cf231c6abcbec3588a80e979e7b6a5d89c66fc85d9a63fe6ac61eb1b125984759c04d8e0ecd94fabd51c5e9192a1a636ba69271cf6d6aa0b70e0e7e2025efee74aeb9c2228b52975b2d4ea073c7a8c716da319f9fa57ea633c916bc6051791e21dd76b147b3b330883c8757f26ed1276ae17b56fe8cb41a14e55ee96583e290699702cd453d186edb32b48c0a12c80072c9e9fe1f1d96a6128cb10809380f9baa9ff32bcc68dde6c33144674492a08d1d675fa4ada4b2d28bb56e0b7618f70486126f5fe97a7699b6f604ba99a96032a53b0677c990530fe77db0fb9e77f35b50653aef5ec9e5c31c28aaa670d32e5c420448080dbae3ca152979067ceddd38a9c38ba4360b7062c5a8a24ce6ef43deb6cb0720115a1567c6f84338eed9f2e33d26b035ff84f52475b572ebb0f650301ac20c4a10ebc940e011fd0be7fc9100fce8cdc020b5bb958555400524f9ef3cdc1bfdb0a45201b6e4a7b30c88d77a4ba97a4bc040bdf431ad82f54354aba1b59c1be036aa52fee4ef567f7e073770055318c808af92f619943e983fb8ee51c791947913926985c96450d1255de5dbcc5e7697aa61746ab8be779996bc1d094581d7d77d55b3cc137c6200b1e6cf4d85873d45b3f205e99dfbd1d92dc7d37c50f0d62b244fedbd135a5e2874328f6f198ec61677bbc6ac89dc48733525b178d92b56713a3d2730b745e4a479f68bf2493e48b8e8dd86b2956aacc1905d6b1b8d12e92cb29df71e32fbf478227da3f8e4c9e5d783c2d5ccbe410fd71a5801a2a10594cac71f582debde5190e10357bed3219b7f3ee3545912aac904e510d39b1108da67f7a9456e17c1c884c7cf3cc1edb227d77a83daa576c841b61d49267b714f4ed49d75bf2f1d2bac37985fb68901ab1893841b609732e360cb7ee329db75181acad2f4cddd2123c053789e71b50b273dc59bc3f9e6932283ca68753f7303bbefb9b5e30a2748c44d15c8810cc7b994fff8f8879e5e7209a444a24220fc829162597368c1d6799a5799ce4229fdb30777a9d39e742627584203ab0bd94ae7fb7b050e10716748abef25ddd2368cee4029846fb8dbbc2f4abfe128e7a151e08b9bd6c442b2e175b3c3871f41ecdf2dcc174d5d86d4ec948956de13c13332103f77e0998a1f3c57522e20b802a365688b4f5db7cc3bbf283be96d996c5dcd2ee3ecca939fcc8e5e238c78ee5c1c29a20551b7a079ce6f3c5f6063d53d4e06f4bb21f591c99d8fd2ceeb16d27c1cad918e378f5e22baf1f6d13a8ab6f702c08ca3093bc0b50b9a482db77a309f102645d581e121bff53f35fd1c2c0907de12d0f6af7da77034e09a2894cf1d9db24e8d04c4f79470e393e5a6a0ea9c8ff8ad7afb9e38a8585aaaabbd9ef4a4923200ed0dc38c77b0841baca8171411a8a9f97c797852a6e59718b7e14b461a501183d83b15756b84e9de0adcdb8b3d8d6d419a5da4c9c4a4f15fe105e4033f4b88a77018c9dfc8bd45f38ba124eb90bcf7fe0c01d79f821923ba9608443140e2781eb1453ac159aaac13f97857d078d7bc6852ebcc56ea4af934fa08dc45872c4fd023ea15138e96f50a3ce6a6fce300a377c2387e43ad2d90015ecc73145cbdca4c6cbd1302fda991e7e46fe230021adadf1167dccbaf433145a012899a6d576fe86e4296bc2e484e83ce03fed5991fff9406a086b6d6b8e346b7cae23b96e8b73001f544adaa197ba09bf4e2c6301f16ed2d5a53c21b5b8966deed83fac318f9900ec704967c42cd23a85d8c7eedfab574008656395f4ecb7329ecde1c1e0edb6af1f48399501fd8eb5d880205d8497267c755e67311e6ce044c6bd5c9b029bb55406d5ba96e8d6b4ff38da1a7ed5afd987c6bbc1f8825c7cd8ce7c213084b729546c926317dbd1006aca441339970bd4ccfd7034b1f1721969d581aa8b42cdf358c31938bf7b14333110a0d7a2fd07e14977c27c07b4337780250294145a0de3076c95b7ce903e4f87bf3ad94dd900338f3ec601fc7ca4ab4350cb770b2b63bfd39e136998106f83c896a3f71b84a3f3d8fdf44b34e5d8302d5027aebb18d4eebfc2efeeda6fabc1307fc71890fdb7f2454daa01c3a6fa522a5e632e5dc5cfe426c1a1f6ceedd6adac6efd4660fff73ce89e144b9972872b05fbcc4774b989518ddf5ebefb54a111baf95a30c74a75a8e063559d97607395aa123d5ddaedb185a235cb89569274bc373b4cfd33cb790a6a2883b3bc2776e74ccf57aa8c79c4e4de8210d73436a38ff27e7533051408f58da1d8979ca6ec94d4c00bc668cd3a4d6ea748689545e7ceea4350d6dacbfa83c0ba58317490a2686d85b00ffe52ae0cb4686ff298b2cf0ca2beb5d53fe6ad61d562e0ac5767b8988a289d111cfdd46defdc44fcd0c9e4dc53f8eee1942ea561bf2a139de15d234ac1703f2493a04991ef2471987ce032542b09f801463894dff7f4ed769f2816f455ca28813149c78074880182c6ca4ce6a6611a1913ff36f8284ed1067ed40796ed7ff62c25a2b0965fda80289366ae0a738130b80c94e2a02ac4e216e20c80be44621a15c11a3b2311d35d1fe345e2b359ac43df632fb4770c762eed5a4112cbf8448c90f0637432d11b6f45cadd6a452a07af4bd6a5c94329a459247f1a8385177ab3313fe35d103561d88cfe6d91df85f01384a7262b24dfa47584771d88cdb4c3854d17be7f8c0412dbfa5fc4d91745d61d49c79dd94846a81384ad8e34125b1899b98e6da730fb4da9a355c9ff6da612aa2ca7eb65efe338d87e1cade1d63287822da18f654e34055aca86509dc96d1ff77b4aac16cfb81d0796e065ef372d50c6cee28c989fa882529efc6095a8f78ccb0872f51ad1bac320af691a86d809c28f739b09ed8fbf71aaf4e97fb2cab480ef11caa7f8e01f63b8eb9595df426b3f00243af349ec4ccbb75a6b528de6aa35af5c8c30fc4b83ee9d6cdd5d5791ef806eb5b6eb25d680ecdc5e17be5bbfc114aedffa1bf66fbd7ab4c473878540dbb63fff4f811f185b206429535cdf6c335f7b26207e95c0bf7c91567b47f8b5ebccb9306d10a896e1298351a59e37a7d4379fd500a1bb4fcbbf1f135d51a80965686125d6c99ad08036dc0b8e2f7316cb5f0ff99658f7ba1655f514830adb6ba8d66bf4c746167e6e2686daf7e1a041ca6c085d4791e2e2891047d60a8aeb5af303a3556bfc6e564f085cab747475400f15e8d1b220d7002150a6bd6bff3cafd038206aab3f6fcaa57d2324d6e5a90b242fe173b06e548e39ab8a062e37ebefa89addc24916482264961acd4db71c70a165bd0537e07b360974c44d93be8509ddbd4ebb3bc4fa727990114afe01d7bee50e26acebd000eb4fcea33c4b330f0cfc067f3fcdd91399151abac9f298fa530bdc38e02f634776c5ebfc15d7487e92e2877c5db71a2bb8f1d40adcfda678abd5c4a777fed16cc1e937134e68d07bec63647bb2a88da8d2e0d7afdeeeb077cfcc06fc0f3e07984cfdc903fcbc7a16f6267006af9a1ecd4786b2304ef8e39afe95794854186ee88798c9774b5cfbdd524c877ce3a363e389e91b4837bb5907e971cbf41af4b28bc2e2c51f4c826e5ab257df10624cbe4d3ee9b4c9edf8dbef569dc36d994f4f68cb5a5cf9757ea5ec965d6ffab7d28e55a70129ef3d3f1cf34ee6a1a070e06df015a22f4369ac7bf83e60497459da087a6f2028c25116c67954b5573eacd578066b291e3b955a3d655173188916efd116d6ffbc0112015b3c60411ed961b56f353f7d8b3cde4d24fb69cebb50f2260324d9b5704e372e2edf236368a68ca5dbd860b281f516e1679e66eb90d33fbdcd72332a782fc9e3fc8e060b53c2b753a0917f21f7476356252ef83b0c70a6e7fd7f40c95414b8c583e0b44a166a874f4ffec756d5cf132ff8e5c131da42b40a4e95768bc2e1be52c8a3c0014e0efe11934c88722802c7f1b6bdab8032afbb3cd5cee9a3c5e08d1675e7a58bb3e21c8181f2395b024c905ab4aadde4f1169922dac18f4d882ec295869392b589184e907232550897895758d81708f548485df5150d233ec38e68e396d96fd7a9187c7118ba7d3ed7a39ea1cfccefed152859523134910c109c21294a0686d96cade4ccd7957d7d38a26934a8d30bf5f7b26bc28589d8c02a65d82959e21baaffaeb4f1f450ec325a299e675792c9c9464e2ee5aee0fb3564e2889ebcc5b87cf466eff6700b7f1df55e4de91d1b5e6c4cddea9ea2d6682f75d829c0cb752df50dbc8a76b35a08b600f82d5a63038bfe4754a201caee7707a6d8c924fab2de52e6b8b50e6eb5f5e64a531566c5dd2b8de4b955400ebb81fbfa5f2b628cd536b603de7ac352ac209d1de461f42b54bea0a40c088f339260ffd64a9c1208a0ac59eefe3e7c05cfeb29a25b635fdd530b23cadee1a4055e93d0dc564271a5bc11c5fad86f9cc51b49037349948dfb8185963f3eace1a3faa56b7c871822efb3101096028ecb1e9aaf61af3efffe55d164e4cf25d969fb7ab165d707009ade1c75a101e494b3f22a0eb2920c231cfbeab7df557191dfb84aca675cdfa1fe391a77b4ba0e6bb14da6b008b25ae9489f3e56c33ece60513f29c706f8fd674395547d7e19dcd2ff1c3cdc7be13b41c972aff84ddee70699fd08240edf6a1bd8cc04818ae8ae9e2f7768b36c819e233a9ad50c958d884b542ec5daad56e508ceeca25c12e15c5c339e4a6af65a6d997b55921a8cf71cf840590e173c08e1e522f158d82390adfe35341403fc1a851aac7c49a370d54a94cd94a119781b5f04dce7c90966fd659700bff99cd75416b066eeb11d01230158d235bdc5c8218c4003a0fe26ac3cffab1ac417c82ac2ce8460bca44645a4bbb372932721c95e56474f76000aae04c1fddf309441df485357ecd24a6e1f6bb709213973a8c43f491b79fb8491ba5ce02c1caf564f9dd585aefe22f3332fc3015709b26dc6853a35b0fce18382d98388d75b5c278e6816779c6bcef1ebab244a49d95d864a35ad86faab47b46df841b26e76c66ae121ccb977a57b61c20f38fa7cafd1a01ed667a0f15b90bbeab8be8cf50978a9b79c9281e92bdaff785fabe350282818b6b6b80ad8dbaa22a95dc810fdf6c4e360a791372820e807710a0230b605cde90210cd223bc4d225d2a9e97acfaf72fecc35558f3df5ef105b1f968c2120ad4a7f331e173b32998e372f90a4c34ead3cf3fd67fb00841415cda70a563d74efbb736fd541db498e8e90ef9fe28dae7352371a86a5fffea5fa43930e4b302109a4061e8055a8b48d4143fd13c82f32a0d7ee3564ef05317c34f82845035ad6a690cda2f7c768577cf2d7d5588106fbd867a0208e15b9ec4ebefeb8df3d1ade0293ebee37ed6b00f788e84e13edadf2bc4f90224bff1e25c13f126504e6b12a9aeea0364c4ea6b77570a5d25246d03d27e1ddffb7032ed69c1e793833e71a7efee60dd3993c08b82d56a729b9bf6a4e7f71c6b81cb68cc0e4cd5eb47f82751c00a14d3a83d8e21186fa147aec78c4e0d15a2339e0bc57f964f961448dafdae472b09d54bce87408b4f570af269e1f5c6b34dbef9153c7b3869fc8b2589fd11b2b2b0a3fbd685bb1861c98868478619fdf40b1f0226190e5f6cd276ac3abab056a06b9e1623c60682eee952ed4d6c4e7037df4ad21675b1abb504345fb7820a4657b20055d7c9032850062f11017e2eb6d83ac2ee4cccde9755922f04c410ae263b68494c170d5f14623300cf3f4f45c6b4340866c9eee61d1787d547a291e764d8356acbc1f857dc8ed199bfefdb33b43d2240dd1f678841134290d052dafac64817f0d642938e1e0abff9a7bbf1b4101c154972b503e019adf486df16313f092a18649f0b9cc5352269c13a7739d885d7ce68ff14c1872a9f034919ebf434fac6686814f749052a678229e2e80af50aa7601b7ed9c212f1676a50bc6acb3e6f95c410ff84524e5d8399a84f8e629e3cf6c6ebfedf8c32feec70a8ad7cc96c893beb4307697301e0ede929328fde4c88478b20db156f69e661a4e20a845c7ddc04f636e9783dfe9d6c262bb1974305596e31ecbf2430108cb243177089cf951cdcf7f500d1e510eab2556d1472e903de637e08e69c71ffed387b133fba061e532c7e438a3e5e9da6fd118d5b2ff0903a6f58ee81c9014ba5e04bcebe61a9d1fcf1a3490847a2a58cf2b32886fcbbc876ca47e95d25e897c7e817d34324c9e8005fd183a60d08f600bf32a32ccf9320de5f47fbf298b4b14f564e486b48021f90bfa0bd6790c5a93cf6f5437bf2fccb2748b2ecc36ba59fc76cd15f2bb1aea1a04a545a52dc5ba9203dd1ef91a0dca0a73206e681fe8812acd1f20c1bf628309ecab199661804da07365832e003a963457b351f61c8e1f5cff37b5f5694be246c4b8fd97d8f980af3480573315e7abb9656e0456f69594ca965e30e0e4d3c6b6356eb5d3292fa3a955333a559d03d0bf3b3fa5a33f1c5c19b931cdeeac842c8aecae5660f0f05185d3386867a958d6352e2a0762894bebc4967a5d931dfe450fc9299cfdf4dca5205c611b7d4b6b68249aca77f77dbf57b9ac6f38bb54ee8c04ffdc9772e7306b720a4496bcbbef3fd9eefb4d93640ca1f8e992701f3ec3ff13363d418203f8a84c257103f5a0ab0814c6b3bc4701571c38619fce92a18c691b78007bee9f4d1a46f3823eac78d6e2a7686974caec0d55cdfd0717945aae6c9dcd0051090922498413ee0223a8c4597a7f2bb4b993e999751b4835fd67e617805a276749a2538b2adfbfcadf21b466844ceb4a6b36f61b66bed416d97589894cdac75cd686723aea104ebc9b0c05a0a0e5a88b1646ad6ec66414f3ad75ba2423b33d1b0dc9871073bdf9098bb132f0196310de6aed8378283211cccaaa7a9391c3f9ec2a51f19594c04668719297a19d6e5df53ad2988a71a6dc8bd903d924f305a323227b4ae3d0a971ca4b7009bf63891af3c72a94405868bf987540075eeeb69f29f1b63b0652f04f31c8311c2d6d1ec428fa9f3a90511dfbb510467b1a85e05fe62590f28f2e5d84a8fdab4b6b03f66aba3499315763ba2e05805c8bcdb8410fc7efee7e0d286de3afb7f9cef6e908a11f15cf16933086e77e5729627ff8bf1971fd0adc9d795f7b7a06e306825cbe8b2acff36561c72a08a7441f849fb631211503d09a23dab6619bf630f2e246f8e3ddca6b13e5019e43ecd465b5ad7df49e1467e9b9663239c1fc42582bd361d7fe4af4995cfa75ee461b1be3ddf0fc6f990f3c8a16e1b0932fb06c3ae53c9823ff88fa81ffc3e293f6d4db16bf159e09b3a5ec3053acb2ab3918c16ea5ae37e70d4baaf7f8138493684299f4734252e414c011fc64d811d45dcb4a2ae6feb6ef36fbed38994d562ec0a534397e9e1628a0cf3de7a2ef26a31be46fab9f370940db7c72c4ca551f22194fc870711d7016c928133016fcaa3c4f30f40b4610b6526365728740b29d486b04ae88909ff9e668d73db922308e2a451656b48b8cfef98dbf6520f696a1fafb81e7fe545fdf77a1da2889b89bc4ccdfd6e40947a712f95620aa11f81a10189b0b07a33d3ab06db971aa760f177ab8b534615f0b9d16e2f3f82e97925e882eba5ddd28d815d684e072dc4bb948a6d1c3b922e445e282a243e58b9cb792736a81665d0c0070858325eae72469822304c5bb6c2ae500e5a22438684b80aac7e99b331098f4070c317481489ed44fc20ed9572c8bc12b07e47077e64d19a892ddb6107ac6545c0b264b48391f7670811eb254b753d9a17fdd6b5d2695dc2df7414da88916d8db71259e3a9aeeb39cd962cbd4acfdf52e1be9e64269b8b483ae1fab778a9aa3f4fe758b37ef629044f060cea0c07c0f59e40251c149b5292ffcc4feb277fa90643dba8717f8826c0202725829705d60770dcee07cf3c9d59964d3e3d453f1c9bda97373423ebe5ff72a532b064b4670674a1dade82ed3c5e411f060f41645a5595204861e1f3d78d29df9f3210057bca2d6dd53c24e2c4c84b36ef577f52a72921006793df854ceffd164f834d2f11487aa51d8266ee2ce9b0e19061258db86772fe9e9abd4ec53a4e04874271fdc38496a755bc2b794d7af1a2d4a8d306ad3e4223f06a74c2c55ae6234fd302ab04cedad1b868c5faa31394f7aa55ddb14dd2d31f2d7020cfb799561c85f3dc6b5e9f6edfeb7588021722a9dc4a1cbb40d204ced63cfd6c5ab338687a3db146d8dcb3799953e85ceaf1800c0942f2c1f49fba89cd93fc172f89f845c33edb892f1376bbfa5b5b6941d98e73f9e28387f402dffec08d4a5b44c4da0443c2bfed19c0109ec8f3026aa3384436f67c4f1cff762592a2241c738b215c4824a3f438f709560374c663c1f5220760653eeaf847a5fa38100b6a16b355d932664b6238ff5fdf3eae64699a815c489d1fc92730c8d1cd8c0f5db511ea9f91d2f0a3d7fcb76d6a1b352e3f37d2edb1082ae7d07f859baed90de1af58dd09ab79ebec576559a79adec3710092b2d031518328f0282ab85d15261d467653e0a49d91b012753f0a7934bc940b141a1a0ced3dd47864a3f143344f4565733dd48e0e30136f5a34021008af5bf45951a453f1aadf8b3b7ba42d875dde79672c4d33519f86d256d89d0bb094245fc1e7f68c3a1634e60331fead81ee5b72c37659d11f3ef609bf43276b43f3729edfb7d079e032faae4a1c9c11e122222f23523a60e5dbd84e531f39969e6c325d0331abf11f772a48c5431c5b0bd586d522ec358427e9aa0c79ffc8a027002cd87c9c1d2a2e46e3cc3f9f9507c48ffd8c215dee2bfc155185a9d3dfb72f0615750357f2c6857402fb05fafbed65f34f2bc16be3da743a3288e17fa12cde1208994c608cca8eabbd434eaa6aa91ac3599d77826de7087433a6e1b580fad447fef58f4c192db9d04c50b1a78ceea0749f1d0d1b38e15550c452beda07766edc5fdc83a4bb07954013d98ad168ece601395ee39acfc60a52c1fc70f2a0b074b92b7e635fba0111a991e86731253935997e704dc1c0dd95030be10a78324162b81f10c3b71e43051c7fa0aab1f67e99f69518898699afb1267ef7cdf62fb8d8e9c264f544ece52f1251e6afd72ce107c7e7797dbd546e4d7fa545d7c0301f16a5051f4e219dfae20107f1eb42e9ee480216a4909b1031362f63ac0752c845b23b115df84d9faca59c1e6766dea4aaa922dd1126280d9a2060d7b9fc5dc7c4685985ceb74939becbdf14105c09b422812bd091272a92850f6d676ff47912ed719eb829871fd2c1118ad14d9301d561d22b918fe1d11ca51f28b91ebf2f08f3a4c17782e043b6c0ab14bbdaf68a586b3de3f3f522803093ca781ce69ecb9e72e6c09a7fc240d2c0912dd2d927cf6b43a5cab233e53e2de69e251b3f9b5b1e2d6357f1d93e5793aeeed5729c4b758115b763860edc65d547b5fd6af7bb66c0003957afd1866c7ba5dbc2c4f2fcca3e2146f450df71374254e4a952a85cfb30e11401011ad008ee1aaba6a24498623020f5e62433de17f00ee277208209ed3188c0b1012a7bcefd423fe17297a88d51e3285f2e30ed8cd21721f6d275039107ce5154d69f0826ee22f88d3270e1f9a7b3c7b11872322fab3be218ec6d01156cc8416cec0e5ddb4685f086b563aa7653644a3a38349f901e79b02dfa958cfb6e8129eb3be62ce2438d4cf29d744db0faabc41ac7e1a87c0e99b698266ff46168ca77da799c1adc7bc8b71145aa517598bd65a0039124616206570cb45a445ad6bc39b2a1e37d8d104fa85529ddee7d786d9f8376000279899caf75ccac2cf4966fe0e81e726fc30a156d8c6a824b324406d8841b2ae9a154aa3653f8ad9b7d7da82b1a551c9d0e5fb1365a0766503c92c2214bd9e587128df901b39f5c0f5b6b86f386b87b7a50df90f9955e7717e1609c682310c7d951cb2b9531f3312db5c32a1546176b8250fd6d3526124d21f62d1663946337a965c694ad44b33e213378cbddefcaca56fa6719bdf009b2c0f2a8e689fd497f41224cfce257c07dd62d8a4cbcb237ee1f8d9309d847813996b771942699312962632b87548e060310bd0a33ac53c125cb47e8361dd1f38c3ed3d4a0d7b0e50d33e1512e99b75291ae468dce7657c2321d18eded4646a326fa27cd03b8b2d57e6a1e859b4d9cfb1750a97f6e93e23b2f1e5ccfc9cf33029109f1b3deb9d3af0460f912a4f0ba39f1cec1c2c817fd352d2ca3040fb20158daae040255702aeeedc05d1f4ada8195e5df45e35542b34b8cffed6cb731e5155b6bb878941bd611abc9c43cc17b9d3721508471277edcc657daac9d3d0d7042f2199f6219356373fd96e0ad55e22d36358cc75e860deb257a00e27bd54b4fe2ff2b3e617d78ae3461d44e556c529080fa1d74e4731837037e191cebd6e9456feb557965946f010cfe6e1c621f14fecae7ac9f0dfbd5e155a3c603b6399fbcd06a69f462b8eae7309fde7c204952ed5885b8cc17decd07811cda100fe3869e42e9b2da73da3b00543fa43e96c49b58269a86cc56f42388317d5365b96f2af23d9a45a5b4701bca30adf04d484136c857bf321f31ea514857f338852f703b4a978a912519b881f57c2446617de89378f8a948827b5be1c9915a15cb2402a860ac134e91246ea7e33a94248289b2c9bec677f2fc41520233d9330c26ca14ccf4d71639190198494a64fad717a7d8ab5a8d541257589763238d90b502fd3682e256e9509a4b7380e5cba13451c4802801e08b451845b106ac8d61cde4c4bf5cce1b1682d420b66b74a4c60dceebd05802785be5db5c58510da28d386e0a2257a08a5a11e047d08b471051653a2ef6486527d595f4db9fabbf8500f17c347a20c15d7836be30c7cbebf0b4d4af21f277211eceab76e704d97197ef6e918593212159e17abb2c22bb72abe8978273e71d2e744c9c7592eaa385e11e9c4ad627c56097631abfee2612f658bcd6c0d59fc3e08db54e517a37fa8422c5a34bc6381f7cd105d53eaaf7555ff712947783f6cd3045fa05af8410cbc757b41177cdd1535bcb18a167670c6e541a1ea99dce43a55af4011be1bb2ac9036b9e57b35403d6a7643d6128371ae20eab86598eb8bfe1cf8039ec7d5d7ee30ce7dbaba67e81b7a43c59a9e18f522862887d6f3b62170a1ed80df78be4e63db909ece857a6b0da7a734074bf71a068f27948a6270793ecafbb358385351e668b0d3fab327025cfc49c9903c6906f9440c74991e06625d29d51ae4a3298dd882768a505fdcccf3c4f56ea7878a36cd1d95df3fd6a6b8e3d7486642ef379e9ee54138b23ba83ba2622e50f6b51f29df9d4b256124fb4289941a55468c654e967925bce449b8d4524a4327391064d1115f48e962d95944b67c5fec7665a0ebd2b9712b4def1802b91b648a66e74b0096b11d9cf263fb494a8923842f0b05f48ca9ed88921af988c14e2433409e39fe315e715e3456e5f36a44ef3366883ad2aeb78da7bb3b626f3d7f95709edb0a9a6fbea20d5dd3c339b2925a1844606265eb75c3903943e6d74ec74e18f7a79df04fdc599a2df2a908a4b3ac949c48520bfa1724166c259787bc3774976f4c8c38d1339364fadbfbc8a0fb4affce663b673a4d832126ec3a78fdfc3edab54fc8462dcc3e7bc18a14703486841848787aa86914acdbb0b06d8167cbd3ef4b67023e31cc7c8ff87ff4a717371c0daa4a684bcd9a9b18edaf9d376c7cabc97bfc531c28b73f3f86f7ef2d0fb71ba07238009eb733b02b4f116e7cf1384985b4ca8ee42f733f7e8650660cbaf2b781d2925768c0497e40e9e44b2042461ed678967bc9da6f828ac408aa37dfc43b5ff9149b704f1ab8903856fdd21c23aa29a2534b1783b51590462c25b2100cbc68af9d85a674e78dfad3e9b73fca06fa794c8a70fdcf3962a2baa4541ba57c83a22ca75030ee8873d5d93260ef1d59c517d787b437937d6b11b366df8c94c55946f99ae045fe0f14a716d790faa8bd40696905139cb0d05871d069fd7e37f054b560125dbe4a07210803d0d33eb596530cc32b07d14dc98030908ce3378213cd1c5c42781f3d20855edc1fa8bd725f3fc764d738701eb099f27ae14133b1eb948ef712fbbdcc24eb6ead0725b6532169766ad7db9bdef8a92fa8ac25f8e49a25041b4a3959c6c0fd7575a6408aee8a451ccae8c5e66cc7a9160dc38b581db2b8ddddf6c1737c1654c4cc2f093e8916d6c7b4ec4acd628746bc29f5ae23fec8a67961614bda1962b29688100837538ef48c286ac2769005b07f30c556d9089ec874761016b6a185c942066e20e7c44cca64fc45a2d427db78408f793596b3a80e95404e0760fe8bf3312cd5ef89444a6cdce383e2dabf4f7ed196b279aa70c151895364192ae5059e00d406499cafe39c1fe9f2e530381b5cbbab419b5c48aed15b0706be411ac8983ad45512deca19c9ac84b9f39b2643e6bfff6a831fc5f9bccafce0aa5f6b386db7889ce5e23652812b51be90dc1bf5e8cdb7093fbe669080915de5da4f3b4244242ab2a415c5e834544db28d24a17e88c027573e8782c402dfd6edee246c3da3b396346de402f49828a14cd0a17dbba6da9801bed91fbc4524a2de8e079844e3e3ce35eb7e08ed5d51a5c0fe60f1fa2b9a5311461efc845746921e565031394ffab67601bf8f38aca34218775adc192c37dad6a2c9c4fbd8ce9dd6690ab94915574e73af99c26c39b7bd2bc290d3bee1b47be37ec867ad0b153079c9b8391ed8267dc1e73b39fc5755fb3658134beae954fd596cca4b279dc1275eb6d4b78965e63826b7514008f062694abc4f25522328c883a59230df34ac1ceca83699e7241e0b62eb02283f5c861a77ea82634e528c3b9304fac0219324678712db537af110dba489ef36c2489dd388bfeaebc0eb61c5c94b76e04ee7a47a50ecd7d066b3b4ce9e0212d5542f6b213edd62e31d4c7b3226e803cc86705b9d71378633e60130c428d9bce65824c1a70bba2220f6fab3d21a78db7cb0d5d4aff67ca50e9133540b4a10418b1f89f65bbf94905e36029bee231b64860b37c670f6504594843cc31283b5df8bf121509e668acdcc5bb5b091a8e1da28da1d6202f23308d5051b3981b4bbe1d6abfa6ff1a9e90e1d7569a478ee962f5964ce42d59159d03c06f2e7ad3c534ea1af76f859995d68b9f8c35cb882aa5de596bd012f0db8d19a8744b2bb790a42e26e6c0a4c79fd30ffcd13e49098117562dcb6a3f01c98ac3681358bfae3bff818085a4c8eb1a34012ed4aa16f01faaba65e74dfe2c32e3347d9bf8cba77e0e65b8a4aadd79684df5fc0dbadbe76cda6aa63718dda18e9e9e95505c6b5bd77175c817d3d31ac0ead1ae5336deccd90f3f2fee34fea10eef3257f85bb243cd5c6420210f1e6ac40ea0159b1c0d7275d2a0f0a1790e3bb321e1d12db0c8fdb26ec25d1256b06bd64de56e653f8d37454f89b3b3b78e42686244c04a7881ca6c6e1f282f5a0a4ee36a1937a6d5ee3f5f1104921e3c4b8fbbc82129c98b49b133d5d7ace47e55ee427d6b0426baad3182f3bf5f072042519c912c224a36eef503a2e8ba0d29339838bcc17a5a9a26e3d2f342259754be2d709fa53e0148642dda3c70bfedbc7bf167cf53ea8e1248dc9032f45abffe22cc1c62c9d4206f09addb6dd0b429730ba9e9bccb5aca8f3be91cc118d80571145560e00c2f0f4b20c42910ae7c57e431a56605364bd5456031b2c400497660938f07475b6ac01645c67725cfa1a491c7a068eabff7b781e512029e4b8545018d54e5c575c974091b57eb2f1b067445436dbf7ddf26a99951f77a227c82c5bff88601e4f63954f6a48de3692e69f6a095c9eb091516c10eda3a811ebcae0f6186802a0718a93c8e597d8af3409de6a24ec56e0a8067d957fdcfd45f0a21cf3bf9413e074fe6b7747389ae7dcd8eb4ab4ae43ca2f7f36321637746cc5b70e268b676cddc3e05bec8e4db2ceb90cada8f444821ef580a2f308f6ef49324f696155a02400ce090020d95d6ef35331830e5298492f463ca5484374af4ca5d609c29021adb1780f7b17d23f6f4ac7ee421195b499734ab6014d3b10e4fae078c08e2e255bec1cb33f82428f87fb5978eb22ddb13d90ed569c75fabd7133f60a50dcfd2e2b85e464efab83f3e38185e1f631d8ad0e55db4877a62df67e90caece2803ea68316643ab0b3ab77b70401af03d25b8321a8a7495e4d736791efac8288b01a4c91c02d339003843b555cf06d322e3eb0ac61a674276b2a9cb64132dcc68cea9d53c21ebf5ce624e2b555415f6d8e89690cc197c607dcb6f8f08d4154d99ea580094959458f6868e6d67fdcfdb31ee83af1b9284ec8cd31fdc35fb934e3390d1c3dda97a47d788cf648175c9b8846eaabe0e76030758160ce709048cac1d8203b0711f28f16298b20fb295d21b589cce93d614ce5c5a3d9885d5ab013e8275999092d1360b8b164feb5bc1f0d97a158911dd5e69e3884fc07857a9d1a18a2b9732f7d78e8271d9f6f6e5eca5174b225b34f8ed888a47f382bba195e98827b91032d0ebd4ff70f34cc21fd5d64bc0c11514406eded4730250ed014573f1338b5d6d50184c82fdad5b969b114cc62bb460c5e2bfce01a92615a01ba7ad0863398bb660b9ff57afe00ac360e3e19b25c20659a73b73e2cdd35a6e260b1e04dbb0c27537899dc13cd8a4b0f297ee3b41ff40a8284952f54ba839c35a0604fa68f0c8f8a6175c69d8ec335f916594945ea1d509548a8a301bdea393a9e0ca1ff889c744d38d4ff8a0ccd3e6876013eacc5a63016229f02a24c92eec2474d8f12dcb6035ef0c571193aeda1ec37fe0c873b533c4eb7ebcd7a2b40d75ddf28375e4f1ee131c658537b8d3b7c46a9cdc7d020df9d16219df4a2c4784f71a6a546edecd6b5a4a5697628901283c0e41a5759120c617fa728250246d4be532e8b87ea3bfafe3370c847f3f1f81fbc6db19b3a20d7cff7695f6ca7854ce7c89be27828660cffce0b702e5d44d2803c4da383ff18e23c7fa44e99d06ef235754ce13251f968a11afa7d61f717c4b6917b8554f3e78f35c6588525a7db5fd26ca59d2ed239b879cd1e3297116963b920707d6550972af0c30bf0a5e9e4c5dac24d111a2eeec2094a4420dcf770cb05c112b71820e4f0184d2158e4951a1bb215e8abed3f96b51f6597102dd2a4487ccb1299c3afa454b53fbc4bd4b37cef70f6d1e66123d5e0d488b786a114df000dae129ab076e6d657e8f0bd81273875ebb40d1f1a8aa0d0a7a71835b7f0e2537e9fd7603459b2c9a0ca87e763b9f5d75eb0c3ec6fa40b5d68f363969139c341535834c6311579a293d5f6c30fbe9f232afcae8e9114007afe0ebe2bb59f0a2f5e6e91d3ad8279b813cdabb762ab1077cf6c28fe22f37d701d2e6d8038eb44bc7cd2cb7f3ff6dd8e9114328078c2d02d6120a6cd02510a918f66205b40ca5ef6c4aeb202757e78b1f91e9345a4cbfed1ee2f2ec1fe5c1e9ca51b13858cc74c5e721da6635c238f7ac69b444818d86e8b15d43bfd4c6ef3055fe2a94a8a67133a2deefb09c8a5345bb847da3eed211344aa972cefdf07358e97a449769fbd461af82644f2b8e1fc03f4d31cf15f79199241ff0e78f4cbec4aa18dbabf2efd0ef4afc4c0967f61175f83d38171584b2160da68d9df799501363587d02a99e935a37c4277c3aafd56825ba1a381b79ebcd4d06df68e4f0f62369c52c62dd401ab6be5e25527f06d576b446edc464f17f0525a71ca80520c2915bbff035b21c992946e326742bb6019d067ce543d2035b8a4798a38782d12699bedccd0d8e1e6a73137f85dedd0f345ee42c3dc614467e41f4f90aa0ccb9766e395ff0f2c148755b6b19e138aabaf7f1e962608ce4357ef4554eed1e67dc20ca5e6d2f70126b05cf2fb508f5b27c092ba4458fe9951a776e780051fb8dacfd33543dc9037a0e968cd954cfe7c8a207eee717315cde1bb47e08194c90bacf4c2197f5f024d1c2840b98b47781ff7e0f35c52def88fac4e429b247780c34babbcc9a7c98dc0f2c14bf4def83db936e56fdb8db97df139c2421ce6ad124e14f6446d9529cb5c36f58036b27399e90c76959f468a17198f9f37ca016ed6f5d6890915fbdfcdb0d9c4ffeb0c34e9cc9a8d3b908dbf010b714710b2135f8d4ebb274bc7ff85714a315a529dd110f6e783dc675c5d8e68882792b135d40e67c3b4de28caab29703d6ea22f8fc15f947c2b30aebdae7483b63f415b0efc8914fbb5df99c4e1086679b9a4cdf94cad3dab77e2aadb934291939bc70fbb4de933e68dc6fbab87e8f6806cf57259e841ec3fc532056321e0bb4ffb7787e8b2080967510aa8ec8f16dc7368d806fdd0f1ba8c2207a354e36c39ad1daa2a224a6ca383e883674dbb253cbb0da2cc479303fb8e5a8ca17f9c6383123b665d6ff410d2212062810e3ac07bb05418083926a5a3fc49177febdb8dbfc5fd86aea52e67dca119b8f2598d7acd3338223c57d771dc853cbc649153ee819084cdedac1dbbeef5e9cf6f3a4b0a22a96081356229c12210a5227d75606a92e5cc9da60a3f4adb3e40dd44b35cee365bce9afa19688ea3fb5130b39a71aecb5876c4640e81c41d945162ad32544609187fdef386eb2bb6ce4028218c141a76baef6973947f3c048e73838d505bb7a3b002fd08fb8c9b570a2140ec4020a9616bcaeddf9d3e609c17b9c61fafc8785f790964afc6a2c73ebf7d88819de72620a15b4e63818c1fe87a1c0b3de65eacf0c57b4f2c364e3affed482804b65fa7d89e8202866ab6286f74fc504b61e781178d9c8e2f5f10d35922f2685771444f0e988e9aef9d43c34af64d627825c33d48e16d0195b0a53ec4443c3dd5e7cafa6f457349d8b37fedfeba79f387be8ebf5e7225d9f070f2a45a1644d716de13dd0ebc501d6deb74e01d7fe99ae40f75e50c78fcd639b895138172a27ebab358ca379db9c6444faaa213329cb2afa307f1ff72bec79623673786bc0b8d6500e6ba86b3eb6e2636a8e65d74c3e707f2f683f9683e28964682ae63141ab42deea415f6060f20fee745ad8f89cecbb97fdbf971f7709864cd44341f43f0454dc4f0444c47f431b5fb39922c3046189dc0fbf6ba56ca2ffb2bded3aff4674cf1272d64dd35ee844626682dd33df28a0e648e786fe46d35577466169672d4e3264f2cf89836f9c6371791a68a2718b6ea026fa34d9f0ac9c023846d0d739601ee80676fa1042d1478727a9c01c3edc657a962b5eb9b3fda2fc76f9e58a25a169fefa2ef659a84d354f159d7aa0b3d7d38be408ee617e4d08858f7725a363ae754ff9fb04f0b7ae9117cb435c2fdb34115343afc69d710975514ee589bec4c087a87804601df9c4f7ba84f17206505acf9910d043b45d0edffea817dee8ddbc19f396868d3827b0bc2183093bdca1376693a849e07574bb552043fdebb43ba29ccef9ad7a9cd587d7296af441558b24e8ed7829097e7d9f4bd29720b3f2862e5afd5ff02fdbe29cb9f51b9c77639df4c28cf85b57804567d1d70d619b5b0d3eeede4c6a5f3fa9a1312b9648ed7dc289f1392a99d9eec9c1802e49bdf29cf181d19c4f1d4347e2e9c16f719bd0e653bac879ca581546c38dc6c0b0bcd4b75236847ab567fad5f0849364189951d5f2ca72a9ebe14269668aa0b5c46a8d5edca6fead88cc1a1a20a2192ac2bb7b308c35a8b58d85fb1b44ec910932abd100efd686ace1a51ac6c19e29526425ef7b9a5db7ec62b36ab11c0ce504ce07610eeea8573f3c4182142a67aa1316094ed6f6805ef6c1e5bae0e353a6d9154596caa5bc2910ccc97e646408b6c6c1cf07e442641d26395d884fca2fced2aaa3fadc30d55073d938e5f16f0d183ff109014cfe9bf0ee0c8aa69ed8126e48aece21d65ab6b50b82757082e8f17c31b8f89d8b52ef19599ec40076dc84d6f8dc6707752db712c4100ad05096b4771c92ad5a881889ec0e218c4d47b2f2dc787be87f7372bd6e86b43d08bd63c6a962e8827108cedf43bf1a8f996a707614b219d9a6c8ca00371aa9d5d1fb65509fb7c1c60e354c4ce29c32005a70eb2c5243eb0cbc8cc4bbf45f284efb20cb1dc2e1193c5fcfbc263173cf71f95c2eb281b5b1ae0a4a562b551dc1a2312f3b30af1a39bd1e410f38c561fe329f86d0af1eda32838473eb3aec8513b0cabd62cc810f192cf40b9431531402204fa217cb488abb82eee558b5adb6bbb11bea060ba58c6a7ef4a79a734813579efaa8a8e7da4250268bfeb98deb709ba142ac5553017bbf6e3680b08fd484efc4da6ee809782517402ff34f9209784e0cd5605e2f847d1ae6b8afebfbbe04c4fa709e6da61dbb70a333fcf3b6e403228ea0621ee17d28db85f434cdde373822c8106c7b7895464247050e8550667d5065e72c0668f9c0a5fadaf747d5615ff0eea5497509b39c0ee22c55fa67114e155e4340bbede0ea364a05dc54c19a6dfb220d09e5740fbd3cf8cfcf2f8b28a9f41b84c6a72af0e6eae02e310f87a97c52886e0a87ff15b4e5e7da2ff102df2448102c3bef7908cdbf904ed8e95600824ce5fd5ac69fea7b2bd66186d7ef0681bcd637d687b994d29e03eb39ab67745c5d3781bbc2fa2e81eefc7d075709aabc00d8d76e695b683461b997f9e9da851875061ec88d9773a87f37a43329075180761f5a88c803939ff2e2e92ec050d8cea51312bbc86d388af4d0057c1868a8498d15a782cc3a2d7c5125a32c90db9bd4887efd615ffc64e5bf569b31735fe9b4116d4ffdf74866c88151428e03f9291f3c35284a4c315b20f0cca4ad3648e3e0c4cd3e6768540ca21149d0b18f00e53ef243d7a042501a9797355a408c0128437f4460828bd1eecad944e6cc0df16276f94aeeac4ebb29a31a6eccfb445f0f95c70849b2b20554073da53d0b8a2fbf986c638c1b08788d0c988b10f054d81dc2fa4e1e9c398b6e937f781cbbb962b3a521704609888ca6c8c5e92504a4b9b48739698a56e1ba93b031605b7fbcfc67830fdcae1cb21aae54d6e0e9133b140c13961e612145e1de4de8a457572ffec96e84b5748e683315b74967f72559291d8500a36128d84ad984ce98c7b2acb9622209167f0104aace36bd991ec10a33e2d3dc771d879d23ca66fd07c8f689fde6b146c86be2602d0e0c36a94385972efab823e3f5140cf98eb259b12f6599202a8ea435e42555bb6cd7861c4b5e6562ec6153bb521c8bbca309e383a3a916b3b26d2887d66d0c591d8ced149945bd0268411697a023ebb089f8870b1cff402caf693e3463aa70e0f4088cb91f1a6b4b9aef1c69dfbb3bddc820803e84a6f12df93965dfe4eae52c92172ad314ee8cb62b1b03b7d6bdd1077da40cabcb51d138c99c4902b2e554ed7b0e53a7a76a2f6f089d4a214b685e10c469f3100a0b5fd4830fbb09358dd3be3f53c38410304bd1b6317b4b24ebccc7e1b7cfe8db85a25c7be2cf8f5a9a393850b1cc97db791938713a0e4d21ca301bfa5f8e9312fb4962ec5b419b7db5c0b30650f827d8896ad86194d2903d5c4c2950d490ef2055db0b520ea1213b16c4f29613764b879d6b35a016ed8591e2d175e5cd51c2d4174a9713f0100d93907d231495d649fc1e9e217f274ebfe5f464531740070ff43c9cfd1890c7f15656e9f21c409883f7cfcdab8856c784945de1b3d1de403bb3150a1c4d55cb6f15918777c64a1300abb03be8d59200cde131f116bdd6fab6a4e71d75006f7918d48ad3c3aa09978730084988055ce725c93b2db51fa52b1e6ff2d9f60c5f8bcc110434864526da13d8b559ff3e4cd7 \ No newline at end of file diff --git a/src/03/input.test.ts b/src/03/input.test.ts new file mode 100644 index 0000000..3f4712c --- /dev/null +++ b/src/03/input.test.ts @@ -0,0 +1,14 @@ +import { assertEquals } from "@std/assert"; +import { main } from "./main.ts"; + +const target = "input"; + +Deno.test(`correct quotient sum for ${target}`, async () => { + const result = await main(target); + assertEquals(result.quotientSum, 163931492); +}); + +Deno.test(`correct do quotient sum for ${target}`, async () => { + const result = await main(target); + assertEquals(result.doQuotientSum, 76911921); +}); diff --git a/src/03/test.ts b/src/03/test.ts index 2ed8eeb..d7d4c4d 100644 --- a/src/03/test.ts +++ b/src/03/test.ts @@ -1,12 +1,14 @@ import { assertEquals } from "@std/assert"; import { main } from "./main.ts"; -Deno.test("correct quotient sum for sample", async () => { - const result = await main("sample"); +const target = "sample"; + +Deno.test(`correct quotient sum for ${target}`, async () => { + const result = await main(target); assertEquals(result.quotientSum, 161); }); -Deno.test("correct quotient sum for sample with do", async () => { +Deno.test(`correct do quotient sum for sample with do`, async () => { const result = await main("sample-do"); assertEquals(result.doQuotientSum, 48); }); diff --git a/src/04/enput.txt b/src/04/enput.txt new file mode 100644 index 0000000..6464a3f --- /dev/null +++ b/src/04/enput.txt @@ -0,0 +1,2 @@ +178,239,193,42,225,236,123,241,26,17,37,133 +7c88ee245974b4bef301842c342299da06459237fae5c89b1964a04c27f876877ed1025473b3c0711336103f14afcecda66bb1db3d4b9b18e23ac6c4138ec0aa8fbc53cd44ead4fcf8f2dc66bde2a4486143c0f9576e4b947adb1d4d362bfeabe9023deb7d046634044c9cf82214184f9ada37503a711fa010b2fa1d10a6b172426f883792958fa966e8e4e4a693a0dc8b01304f01bbbe14d3b4ead5b2a585d34cef6a35459e5caa8299820e4ae5159b3e4c2518bdf66a2cdede18bb806c20221abf41902840f48bc2ad264e8d12a03feac3b7e66fddf8e8ec6fb59426faacdfd86b9687618c8025a4bc53ebfa22547fc9f66445da6e88eff4c4acdbbaf8ac05c5bbf162eaa7f60d1da0bad70c2564235a13ed3dabffda556a61ccc72de25345e235c408ff4245ae2cfe786d39fe3c76a28e4e3d5bcaefda283ea0a6287de9ae7fa7a85c92497127a441f2b822cb48515facd0349fde65cfa5daa22ffe430bfc685f68e4835b424e15e0d8f8de800356733acc1bed12f5d8d973028d16cb0433c0c5020074ad63e4a63dc8165f8b202c120275c06cc46f9df522b1a7b1f809e621e3897c0260724453b4f4ab7de96307d1c2c3ffd56d134ef456eccbfe5c718726f2df9b25145d91a51af5b32ce522d94718368d8d1559439065fb370ba9d66f1eeb8c5060dccf5d42fabb46cb6ad37cfc27bd2757bbe40c0dc33e285de494aeda156fe51b3391c245c49b163f4f6c83caa78f010b233ecb7f25220c3235ab9f60afaa6dc103e0c592084bb253450d7706d6c09b7aad7319044cfffda096f86221f9ecfba4e8ef7f1a8624284946fced4cd375e59cdb5fbcc136fb66b0c73a213cc1d1535933f66f62443a4a2e17584dd4c2f7c268281548be2fbaf2f2a9e454a83ea25cf23c53499df530e3f352c0a4451305492227da1f59bd97783473aa5c92ed9ea69448e209e6a6ccd00de1c564f6e3c839bd01b6e9a8e7043f39732d1f6ad35c38e581cc7580ec31f93c1d1bce8b70dd7537fd1fadbe4fae5380d8b148e0b53f9219511280fb4d16a5538683060489c6d062a2adf2bccd4fb99daa53f577c692773d63030f7ca63dc3009cacf2260d3b887cdf2c9be1c18c5fdb6517dadb6a5d69b9892d3c4aa0bb04d9878de4d65e4b97e8ca9089430302796698bba2f3b70db4097f8b8f20563ac5b26c86b220b1032728c442bef37babfc7638652a2da3f3332feb31eb5323d631031d98aec2ab05a1832e06ef45fd42a789c14771492e2fc24c14162825e48dd2ecde3168a3ce0029666a9f1aafd21a7f8ba2053f61c0393dc3ed757495df526c370722f8b267036fcb3027b58749b86c3c96d6be32c72d716fb130e2907c9b67ec9bbbd5fb0d01ff2ea0495e6c7eef37482e9a9221b9c2288b28e514332780c45596b48c7c68b3b34962fff8840350c0c46626fa1c981a592b460e998270aac6d103c7d0df34e804b8da9b1ddef151de2125b421f0a8c40e5d4fc643e749edcfd83672869626a577a48d64082269b5695e7e28521f83c011f1c45bdc6b959d225ee09b5b7f2fba220f5a226fe507cd88b6b55a48dc6e690d99d51dab8916c78d090336487ee04306f89e2b4a3299512eea06ab38f6f824305977cb428f7b3ebb7810e945c596c25e467bca2e797e44d0a321e03b41ff547575240e1b71f6c67fb13dd459192055538d8ba9bf84d9ee5d628f39509f0f668f8566c9367fb737b39387007fd1fd3482bfe818f3b2ee2e7027055d8fe638487bbc2745f242ea9fc2d533030d3faf14ee6885e90909e542bc7de4a565a50cb293a9ebf3f454d25a34f27bbbfc9dde929bab1d27ebcc1a903354a9e8e70bf750edceecbb807cfe5f9069d1b88fa9127af2d1df043d1defcb5b7461c8410cf098b7950f59a485ae721c6d066eada5b1774009dd4a038656790f58d2a2da1db68173e05768fb21f125a257b2a2449cbb1943d486632f4971862e760f1d76302e7da311d2877cd2f77923162a1b4275f520d6ca862cc13ebe5ab992a6d984945be85676c3beee811322670571878e965803a117366624da21c48457d4c34bfda0eb781348aea68181c6d3c06821c32697c906020f87a6517eaaf536b88955edd95581558e1cd11f657277c590d0debfe35dc189318825737bb3828892e98075acc429a4c9ddd137788d81f6dc37fe61cade4267972a5ff73ee8e0b8e7efbf81ce11c216a26fcf0ad78a8901cbde5b4b1394533d5fb32a5f7330d2df20b6c4e08f54e0c758aab4a39eb4c01f68475a6fe55ec48a65043a77115716418afff821fd938bbcc8de3936f152a2becdbebddd6e1c1113e3f65ad7536d04d2ccda994a03946e89332afffa0a96879c264fceead062782610c7785e92387bb5e08f90e79eb89a43477871d797faa4a3a256ac5ed7fe452393649dc4bbb8b1fbf112d6f5a17c30af6b724c0d16cf47585f9ab1fe424a1f3605bb72c0d6c82b464550105d60990ed596beedffb4a85493819dc36ef317e937b52280e607e729a38b755de0bb3f72b036802e49a9375ddc2679249157991a6d8232ddcb5da5f50507a508286d774861a833480abed1adadd3e8e29d94e6649460d0c9922553aae49b4b71241e893fef98d7788a84d80c55bd39ce21ff91d15c2b52b55c10bc72967f9a773f8b1ca2555ce65093af2cb5ba3ef1545b195f3520711d1181d4f8038b84db838bd5ec07fe73b0949f261e072398b00a34560de637101a81f57246f79e39b89a4f3eb8102747258d930e7b25f82d96ffaab93343ddf9dfd3e5a49fa22271adc209cee6398cb95ccb9bcb870d5d4b630e00ab3744110cdd383611f9eef47f66a8a27e5b74744fc6445d275c05a25b771f2b609ff6b52476940c9be325cdf29bf6d8d32e8ab2296bddc44086d9d6de538ed4a9250f32c6054e2615c8f79c0c0c8fe473f10a8157f0a21f0c72552291d16043cd736f6159a814b40798559a3aa24e9785970dc9d242fdadae344930c8dbe7c4763c3f0ce67ab6ea67e45d202e5de545d3aadce2cc5e1c391508f1cdb8d9456c8d57a33f28a907856b8e0f373b32a9f0ffc319b53df8e675529d7ff028f20d15fa575d22c13bab361f67efcf47a594f1db64c9e2a07d8fdf1306499a506aad78025e5cc1a2d3036757838d2e0829781b985f41beb3eb8ac22a325be3783b5c5b53dc7a10bb62c23a3fce312e5bb6a196883f5aa16a6abd479586065f99d68b8e649f84db3559a3dc47d57253c4557a5dde1c6fbb1456ecc3b8fa6cc514e76bb6fa58a9a592dc00815d43430cd151d9faab4dc1e510d84e0ebbb09867a0c279a3adb185d09e4ea9bad8fcbb52e15ad39db9707d87992c30a8124ca4b1d5db0288a8dbf3f0fe1806f9bf9b249e601531dc366caa97d98f6bcf1a1b95e99ecaad2c504b7aecad9b94536e9418ff506554371432cf1884a2b3c52b0c1dba7808e4580be1781600632dc8a27c6f13c1a83f60d6d1c3596387e993b3d1d3dc653eaf45c5e49713ae24254b1952121a79902b8bb058e2d8024734b3db106c50f986f82d23aa3e951c769ac4f8036296d8a02a84cb3417995ab535595e5316dea64796947fcf58131cf35c90bdcf706fdd2f96eb4db883ecbf38ab54c0e4b8229559577b65b1cc16a4492774e74ff6d469fb461a2a23ca21155d13978ed58a29bf196e7dd183fb39858439deaad43523c112d2811e9991939064d8367947ede903a3f5733f8c0daaf9020ce29d0fb8767f4506884a11426464f68b218d8e2e8aaf08c850dfdd5b6be38d014c94bde327df8b6f3c837607d20a438818223187a6db785b5b21c3154474e3fe98bdd9daab9de21fe0b30e6da2303e23385b8011aeb09ab8ccabaff47cf3e18d63e65f0f25242858d939f3d5b81f63d792ce950bf3c31ec98ceb0c4d1470d95124334225abc3b4802e399cc24fba87d744a537d0373b20f0d3933522983810ed28356afa08e635d8c7b8bd316f6429fb450040705d43fe6847185163a1056de92f7b2520402456c91e66badfda88bfc414370aa8540e5eb8be922e4e8762e244d68822ad38413e1138ee243279a293eb951663908cddc16d72ff0cecc55f25f987244e5454538fa8eabc374a1279167718daa8c959651e88d443c899077fc990b30c6ba40053a9a014f0ba84d98163381fb48430050e4ca87b8c7a90603d1ea9e0336517a707cf29747ee68edbafd929b08f01e8482465708e0b3405e91b53b3547a112830760d8a855581c58727ed2eb3824e1fb42ec81e79463c20e3ef53be9ac6beff95e2faddb7c10081fdd7c90aaff28d61d7a6a875e71b96564cfd1fdcb20c885414725d4bfd3443d37261652447313ac18402dd3ebf811e55ccefe94b1694d7a4733bc93fabb1ef80150dface2e1c4e9ad2c48c4ce30d66ecad4bdf4deec9885dd5943f7b67c8c419adcaf1c4a2fe4c8617cf9db49caffba59931db2e97749eb917793d6a7f2beeb817a822e6de81cb0e02460c1ee6a808850f49b690a267efcf9996d8b29e57eb3b0bcad7e7d1541e0f9d8ff9f40ffc4d154e290e8094340832b2a5d8d6f46d4cfbe2e62be360a490dd381d615cdeb97004591a3651e5dc0b1b7511d302be68125a8e36f1de381c77be1c7d06950de48b28e25021067bf4b0f31da8b51088b9990f2bd4c8dc1925865e06eb80b0785d2953119b527cc1024c1d8932c976229ffe5073e8f4abf9adfabd6fcb2b7929c6b58b6c9e3c9d8126a41f0d1d1be061a470d6949dd9a4ea70bbc6a7ffac6bfc14ac1ca6c305c3643d8c4dd3fc53823d12c7fa478942ac164d4caaa81e4d8cf4dcdceabdba26edbcc69c9c11146df954a45d445fd8d270bbb4a772c35eb6e9d53553dcee2ba21980f10690415f1e7bbf204a279ba4a19ef16da44c82e207d5af34eaa22746e5c9e7489b9f80c0b08b03a5c0354bef0cc2555c39acd9b81c38b8f265d9d33dc8bfcf9e7bbe107af8d66887f315eb58a4b16105fa9072709b177f563a0b5bcdbf2a1c26c64e54be5e6e6c05d5ecbdf5fbd83ac51f264db1f7762ff2897ca7a7f8c902def6f2263d79fc842d44ab7a3b7c76d5476e11f8e2976cc75780b67a89abd14457455121b4c3d6fae0f54eb821b5154069e3258c3646f3cd2ae5bd77173024d97d65a73b8cda8e33f5bff9a9859e2dbd954f5dea915a125c0bea63ac23609b0951c5d995542c86f1bb1892ad421a54622c66251c895bc776d113025e4539c2511e3d9f08cd8fdc99e5e2e26bea0546a10002ee5238bf5e0e5373bc1bef1ffab90cdf2f543fd8b6d85649b77ae99fad1885c543c6de60eea5bc6940245b2cdafa348af6c6fe8e475b1d69879d88991cb5b249cad1030d57aabf655d7d2a673b1d71c38042b24681404468c7e4f654080c0e149169ab1c04ac31d5279398d58945894e7e596d1356ad564289b2f49a94e04fa93c73e8e4493449c997ec8908834ca2bd35bd2347f1f14f21ac9a743ad83512326b5edb62125c8ea3eeb6ebdf10afaa2558eb3bd57fa772435e32ef1df8bb70d908722b7f1538f063602864d7e3d337e69ec48ebea7a96a6ef2b1ebc517b12c454459eae2702e19d180ca288c7884cc98305812d1b2b38c2394df9d0dd1aaaa99f39fc85c09261599421cc430895c122bc84be175c5cdea6174da91d7ef0e1ef401fec09771cb5f03e904fd9cd969d3dafe6e278d4a4f87b1bced952c1b3dcf576a2505d4cefb5e31ccb7b972ea8694af8c13b0a3b6b5786272fc9825c578aaeee2d051039df07d5ad6b14ed9707d2223b8c41d38cc0d1c3e070304df295fd5b596ae77fe210d6fec9cbd5cb52901f69e7305e410a55474da9e757243876fee8080b72633591c766f5b57c19effb81b288c3fd29fd1b53ca626f36aa4562e129039fcc867b11a914c74de7480ecdcd40e88f8ab9248a6c284970d12dbe53b503cf6971f67255d906b58c5655773d585882b875d9c22b4e7498004ab8354958f998bf05444fff467623b86458526702871722c52a94dc24b8bea77c9aacfd13b5dd87ad719f9b82cdf65d7b3b0c49bffefe53bad2f047e87b601fe27da479a8180254323e856e33526529be0ec298ab410f4a03971886b0a9d796c79327b789cb6b59c847ee9e95b28aad3121169691f2e0900088746751f124b20f0010d961efdfdb645f2c8df1a980ada1783c14c6e67c92402f2fa91b670fa8aae5ace2532cf72848ee08fbea128c32de672f875864987d6bb57aa9b9c7befd5f0617413cf1be1f1f4e7efc61ebca1c8800a42d42142a42734d0cdd9ad8a043de5274010c7d041cafdad0753685c339f2f421f873d5c8ca630f5800815e65f725d40aa27bb0a054479ce81f8d04eb09ed6cc9f34c3970bd015f4f3f8c203beb8813e34616172d415846e7d6301f0f13c9460024cc93888b9eff319432436dbda85c1c491e8ca4d58e9a9c5c6d0d88abce0d65f1d06d753ea30cc0f8adc2b72405987b8fc5da02d353f1418cea91346b3999cafd9e03497a3f8a36186b01fc518e71f6e19196cdbcaa0b4c543bd6cc8eb45aa5b31ac2f2b416a7153db44aea014e7655ffdc639b52a2a34d31535508b2ef4aa2be264061e49558286c7ba37db79e43c6b1813c87277acc96651c516e91c8aeafc19d566fa3de679c48d9fe277d0a3df2404e850f4a4ce113b2aad129fddaa3a0c366f70f01885a5b46a554c24b5ac9955cae8e24909bd816d2c42aa672fbe8bdcdf3c58150b8854d4f6a7a000d40d3f22cc01a758d4a9aba86e7a7d1a941d30442c8bd9ef7a230726dcf1443c974508c8ad54169b3ea223124211269adac068e411e1ab2728e94852ec33641df30ea35013d24fb2f5a75d1ad9c5119a39d3cf5c268d336c7868ce24da17fd6a2df0ac873470b1271a9b27d0bfc75438579cb3d2ab9592e9758f1e9a105197f4d4adc90647e39685103793daa349b8418869fc078a94e2bb829fcaffeef36833ef490dea94615a63a12a8e96ab82959e1e4cccd40fe6d7a12ee07540e274c6939138ff67746adfb47f58ad5362e26d24318cc13ccf216d5fc7eded8837e26486a66ed2dbd2a308fd56063b339b32255d028179f4566c00f6f89ba12fe8eb3d730605f741edf957a62e7d7252bb99ee4cc024bd7c652175394507f535e1531f869c9292a0088be182e8ad013dfcee57720b32aa9c035c5949556a321763681d9f66cfcdedb1785e0dfab5c056e955143e7e6f9f9236219522103f287454a65a6b5eedce3e0695f019746f94d3f8e0f26f36b9b6b434230436179217781e9395217f5071ed68227d6a8cd31955370b9f326b48a54429b7e3d8a078b80f6afc09952f43b2e46aa79cf51c58242bee545b2b123ddf74f8926054ae69c98e7eb363b4af4a809c09a3f17b9050366bf28ea5abc728f6d8703118cce7dc783d04e7d180679a2b416cc79087cfa51bdc445e17631063a547a4056b84170d393ac8d2cc5eea7e7c920f57defda3f8a278b6378b280161c5731b25f59bcb6abb6f212e09dc68386b09e0b4a2b45cf80a9333df4b9ac1ae7c60a549ea5b4d1bee3469807393a80012662e39d074fe8b6382cf6e83658b620c1ea3876bcea8a66d6ee69eb99f98ebad142fb81eba490169217cc03393c7a7bb0eddbd3963b2654fd6280f4aa5d12e5f143f3e97d49166970882cf57e1d3716a272aa470bf0af87708b908e73d5372bd4972bc628128a5fc7b6a2e62f9b74deb60b8613e10e3e061afba0f7ea8657d2c9d4094711882c8a777ef2b7a8c07f75d09d8710b190ff9d8c2866198b6dcd4959cf1a0f8f9c7d2e258482822728129e31af6db468b8cd6c81779b82f5e43a28244eb311c8d3849b7454d93e79ee80c44ad2bf11dfdd11c6af7137a27f428bd3d7cae072c6fd5be399db511cb3eedfb3b1a0fac59ee63d54ed2b6a483bdddb45232839d9820d5a7bba843941831232487d730be49225587c8d04ea64e56da7a5296b3eabdab3178a3589814ebbc33a632a97dea249ac06909c366688ee57236ffa0889fb7bb62c3bf04de603b5e3278b0c9312982bc1eeca492730746b917cc0f244a3b08f42e94b2dd122e9725f23717f435154b66ec1ff3a6a75d1c94a451e5d631958589ddbfdb34eb2a32ac5912e8b46f2f8b0ee9085ef925d7cf6a29676152f24322778096d4dc5e3c3a5618c272649d6b253948d046175ae40c85c67e880a5448e488824188fc0e58caed7bc1eb0d0a94232334cce308bf42c35209e8328ece5a13e3d5697dadee50ec455056739b02bb8fa17058584d3beeabbae6c3265e871e73e52bb1853b6a3a5edd9c4db91a0a64bc22d1509db83690db3d04a20f7c0ba4e324487570c57dee019897af28d3e00676c10cfe4e71c8b56b86e7f830747916b4ae34a5af3d8f2c1a2e3c9bb039c5982ee0163476e8edaa0bf071ffcae9a23b5421be5481fec326072302e67d65b172ae280d0f9a53b67b9fc19763de6bfa5f01e086408c3267c02ece9ffc10934945e77992c326621d4764e9cded8dd1e84f676b4aabefa99e9760fd6d4dd3c50e36b13b4dedc5899c3559bf079bbfcfa410ec3a5ebfd83df251a29f157aa16b2bf6d3f21268bb09ab63d7e4afb066259c562c3714e0c0f82487d461156e3b62575e78b45c70cd92b55bf8842ddb1108f1b033de3f9182dafc74e21c28ce61070fb8d9a3c4132d9f54388fdd07d2533f16f844b9dcf7b5c95325e258c49ec75e99502e2381da2f6370ce4eb16bce9428bd81de32d07dc4e0a5f143533e64e6c07a2f1a61e9cf829417f4ebd5397fa328aeb89945f2744a13ffd523f75b6a4544c7cd7464442c10e8986c209de00417701d6b8e4e19534cbb7875806b722664a395ce8c8c5117ff84a44724673bf7e41b243588d7dd3102574961b894262d6ece220c24d7d6543851b03afca817b3e1a67ff57d60f7d0ba348d47ce686904fff8e5c1cdd16cc63fb71552aab3283a4a0e03e26e9a5b45ceb58959f47a325a70fbacbb55209131eaec2404e1d563ecee37b645d0f91e8235b88a744bb61a272af6089694e7c3c06247ffc82825b8ce15b06f2b4cb129382d1224608bb091153b4e559d5b7fc09f6510e73640a548b2854dd9b24606354fa146b1cf5824a0a4a40004a60c59d123881fec0c3b21b0ee84b3b393a07af0ac27771ecac91c2c63ca6118f04d3fa35d8655720cae3c5d3f9587cf924ce8c6473a7ad108598c007520148e5eb4ecf6b03076b55e3fa22618cef61f47c7c529252ffc427bd68b44d7ac9db6eeb6e00855493ca1d8be0cfac98d6dd6ec9a3e7e3138f7af347e2d88a190945a73ac61050be91a5c00f8176facb252008af4cd8f3f09a3f02f7989717a31b4488b3589d70c79fdc10c0c1413b4dd108499d73ac85e381ab434f74d8549841b378b717e97e694fa8691e1924e45afbe120dcae7a6bdc6acc69f88e3f7512f90a1c1069cf7358dae98a2cf3a2a605a06c30a1cc596679fa429d273fb31ed621dc834d78cde6b9cd044d0f5a65f91d2b2f5896ed3b334c6608a6462c096a0499a8da4d17d059ec610226ef2968281e37886e606a381aed56032e664dcec4093050fded5637ade2585a6d8f7505fb0e4491b53275cc94d6b90782d46ef9f22a291231cb6e5580446bce9307dff4fd9bbd91ea1fb59d1b74e20e35beeb745ce9ff6d69f030a3babe1fa6e59a5f6d49d50ebab4539aae4002854d4c5312ea182c59bf19f711d87c7260db7d7326a0db0fcd92d39edc1bd943827af9ffd8fd811d8b13da34f76ccbfa42365529b1ee03a28225ae1f517fe7b2445f686c58f634b16fab79d44657f9556a7ed193ba87c71ea42f737bd53d65f884b3c5846713a1cea5d5592ab6597d67cdf18cbd13753729ad43d72d4a47c71f2119e9c19526a61451dc01f32c4c886de63a0d1e0a47a1cb0604b7bb06c4c7342d48811ea4d9d2f5d9a07d4e24cc11f1a96e5cfa862faa2c49aa4f8d23ffca98509849b510113513b831d13b25ffebe84a1f98c4353bfd2a218fd4e2abc930b0fb789edc27a58487e2c2b80bad4a50130c7d1fc6e5644e0ae435a1a3c32d5dddb1eaf6d87af4b490e470715fe9e0d569eb3675ee474ab0f45ac68dc7b5ac74ecad51d27f7b3f12911717de1aba470b2cdc3e359b32e10914a6d91347d4c7f0e24a5fd66545d0e2150bed65eee73a5a5e4bf69f31c8fb68f3bd28620d83c7c9d250e33b5ece4203392b245b6c354d015f8973880b677e036b75d8c60dbfafbbdd7499b3f94f43c18b06eb0b79e56fa33b4ac4924604b1ced65c06dba98efcc3985ebc7e866b146813de8073bce931868e78e5b0dc38f81de532f6e1e31b5360812b297c9c7745f93065734f642b8e29c00000cf61efd0771f4dcbe3d92e1cc96e391a746556c86327d0f1c7e55b39e90641f294b272b8c4837087196121537b08494db4fb5e46d584d5cbe8c7fb127ebbb4b485fa9ebe4c53d9a20dc7365b9eb8d21b313b7aa2e6a694f49d4cdb657384cc3fe73ca2e53e917f4e28d9c864c30a78d7910381366471d7aa30998b167e34bd31adc28f30862d366b7aca46c01e913a5ac1922fe133ee31b86c6cd12d647a25d7feece396d0e23cb966b0c4558156458b27d4bd3e28996ce1e0a4f1babf7def3ca7f9c0803a644eec1095dd399daadc30f5562c3e9ab40e9806e62a208f4b8b9383652a6657855187ede44112ce53c8bb64a61d3e69492c37bf0ef65b56419d7770a35b9c01bc3d3aeea6e09759d35093a9c0e2fa4361f0f80bf9d315454660c01041b413b9c5f03ab393090c90fdba22d1a49b368ac4d779bc1fb65859a3f7b96170536583311164836f4e519e074e20feed795a348551addf5aceb78a9f2a69ddeb2a878e4c0283721df691e5e9ed6d8600d3ca4f125ec21cce6a97e64159bf2e695558961dd4b20438f5631c43d9f89670834893b9ce13fb74064df7777b271cf2bab9786e9b4d68c4717ac2e6ac8478c61d796bf94f8890dd06000d241d4d89020d9cca9fe082162ae6a0c4580e8d8cd45774d9c0afcb93dbdcf071f813d9a5eb7bd1b1cc28d9a63dfea559a4a57f458af1fc1d843206d68ef6887cbb97f73c795d3901be291a6917ab1f55ebcb2fc2f7d19f6a33f7b54d84dae98fad977724af05f70949b364e5027206b4a91b590f69b06212867bab4d8ce7abcc848cdddbdc36b3dcfa27429f4f6a4f0a877bece4f58b6c4d4be7155d41351192dafbbd68a75bdbb782e11a97d791afd8c1a7c4c3ecb7fee0891ff83fd0ed348823eceeafbc57dca41a9879ca95409996ed87d71d8c00bcd282b9fceeb9b18b24891a2b39a4ef0293f8ac18988de19fc9572614270008405c87ce4f424d59966eefa61c9ae3e5c2552eb5b93d007c2549255417239af243282e9b0ff6ddea0c9ba424b76762946cb786df6d69df315c192b739976c85a3fc9eadc977ab1e7124a7c3b57ca719b6e0b07050a656cc34fb4aede51d402752cff3835ce692f8c875ea822e1abe144de5ec8840691d47bc56dd08f8fec8f8ee373584c279aded0f372cbcba981cf1b404ea488f234d2800ced74524f9b349de9943d72875804650e60583df693cd83326fab52d733f65e4bfa0b7eb3ed91a28ef9fc3ac7291ce696fc0508015798bd608ec7ce7580254da071f3116778b9c3e8ad126b3103866c10a82d1a169692fb46b40150f59f34844e2a74c36cc671186b4c3a1200bd3e9879753518cc2c23908a9c9f550a15ca00bca8ae54429b20cd37ae41827f329ad782b17fe6d3da3e3ecac552a40b2a01c9c3d763483eca6bd249d82f822b791520f90fdd82608430d8241c2f7417b01ab2b8184174c82132fddabbbeb3e2b5086acf193df519e476fc669a3c0bfe49628d2b1cd813ad9caaa5c20277d874c6b08fc5c268b5206fb7f6371d42143b2926bd03c84cd25614594c4a371cfa79605187d4dedc455a9d6da6934eb215ecd26d53e0e9590451ae7f984f508c4f6949888707588853bb53b805640e1c9928f6405ade99e947db1aada0d804378090d76882c834bcd8e74db9e97645d2109fb8feaa439d9fa0891001e227fda671ed9696256387336b80c44cf2233c56a33255142ca8df00c18969208e2f919db13c806a953f713b079b94cc080b41f2cec840546a39cd6c0a57b4b0d740e2bfbd88cc55a3e8d819e5e92df15151b4f21c102fdf9a4b087bc0522f6121a93044339a394689957c3b977b68a0c474b835cb6c86691f455cc6f88923406b232adc2194985f9eb541f391d798e562ec4397e84b8eb109d11103eabb7908f2a533dd5bb7782e768df9e347fb2a8e52d46d2d8643c9209bf71f40fb008477406661e1d1ce5530b38bc84510375bda00180916d593c88d9282c2fabe889058d237a5f53e5be864e4c1ce9759b01b9e178f3852aa54262d592ccd002eaed3223db879b466a5b72ed968a0094588c4a281a8818c18bee3b069a134e6865ca1390e65a02533cfffb06c59eb72a9bcc544fea4cb247d633097bb0fd3839cce789aad180f46cbf1a726af1fce63017c8f33d7119d67a18423bf781c6674b90ee1de41bac6f1c4b076cc85bf2d3b9278f5e984721a95e71cd7f59d02d8e99a983f2d1aec5a0857b235ee4961617afb10cca249adfe801823fc55595dccbe7067caf83c37c7d1e9ee5c4da576f7b1cc002226c41fa713b51de8324d6ff7467b68bbfccdc4a970c68c4e886d11e04754eae989887725d591555505cf042d1450b07a42b9232ffa20c29bd9981aec20bf1798d468ab2f4a6813040d61b56ded1117cbaa47a9b6a29004a2d019f3cf1a0ba1fcca375ad1fba930986a47a66739eefe8b5e8c75642bc1a6346bca183fc04e3014d211ea44caa5968b9661b8e2457562e5fb688775d0ebe0ca64b220cdb238abd5ce61311d028269f2eca03b15df54ba018b507d3d3d80569356576f752423fb2af7d50a2ad404cb21ac85a32cb5b270b9c61af2c1fab99d06d3427731900184f698cb1749dbf52a37686826c708154dd6ea03956cac80a1c124cc658b6ad3ae21fec894964a3625367651233ee743473428e9f1985315922c916ef4475da594faf87afbae0ebdad0b9f31fc337e23286c151a9dcd957c5c5f126be2db699fb45a3ad4836ad6786cc8bffb392e6af63a95a44f514440ad9d6dc84411fbde1c2254c9389dc25eda086c50f5a30723b74db6b28d7835222908a680e6d83ddfae243092a706424a9f026665fd0a74c759ec8db243463380edc9e223b5cd4b025955e958419068a70dc7b3d3548fa0839d5d1a933dac12d339a40ca99156a893d0154e8d939a5c94b22face52c1a6cc8a63905c7e5812530dc2c2a78801af304d05af432fa77af5d9430bca4532dbcf4b01d2e57a3e10fb00d8a5f28e302b0264251d8ae695f6351d58e6024fe8055325164c7f7d888521e81867f116e49e7098292f830f240c9d4c96451a3058e26f28327262e636baa7f346684cd4563a0aa4d90d19d9a0bb1f7ab0f5c10362429472b08d2d9078d38c788ecb35363873ab120636b500d335d02354c6ec5c8c20d481572642b8959ff6aebcef47c8cc8033c1b6b49146e0ec4371bcc3a31c097830cac01e58f5618d9410c252a08774d6b4b0b1584a7fc1050923a2c30b04d4997980066ec0cc72b8c6ffb3045c380139f008cd85e579dc8c709d8b33a05266cd5bdf6f0ca800da3a0719136e2d187ed46b615e9ca076e5d1ba930156c91d8afc28767ba12f16b68c96992270aa35e645eb8299ec67c576c01f9e61d09e1ce11ac549e394ef48dccefb40f7bea67d00cc164e332f4f06552ce046c3f06020d25382a21ece4b73da26e14c9c416c5624878a38436c194dfe25bddae1c2a36ccd547273535cb4c536692646ad82a2353dba27b549595bfc6be35d95df35239523cfbcce1ef094d3ee1d21c0168258f64ee0cd4be68410d02dcc3c02c3877960c602108621b42c273bd5ff21b0dcf3296052d937b3f45af89d6fa809ebbbef1975463340a5ae534758cf953d569b0cdefdfc85410a3c074b68ff5da402a78ed85883e8f3a8d6c694b806f9c5fd27433c667571f2b6ed042c7c4896757a9abffaf943d9b89ae0bb569715a7291e8b4de5f481133b2f792ad61e09e7280581547f2fb6be1edc9128143c50b9a9a313ca3425e758974d427178745edc219a7205560decbeedca2a2b61e4da67934ce97f86dbf708ba6e14618acb96585c2092a4acccf43bf140435508edb9b265f09e9c1a76f34a7b31cfb8bfcdc6b3a3628292d287335f2bfbed6e6a9b36ca5325559f6186bfbcabfb94a9d35d5aba896df58962cedd4cd950c18190c3b2a57cc4d8bf7b99555bb23188c4712513739dec43b60f06fd348dc193bf7135033c148030e14325f42d6d9b6a4d0bea7af37f85a8597a688341257ffd464f05e110a7e505264da567bf70a941208d0a6bffc8fd9d5e5ad3a589c9e539b2e69e2763a38f847c5902966e232f221cd75406e3db64fba448139aeff447e33d393166ab1a32ed4eac0f0ef3a580aa1db402c6fbe3303472ed0be9c9afbea3cbb9b8b88b2da25668673bfc70e95a77d1334b1d7f16d3216cd1f2f3fe1451d29488a0bf2cfe6e2c5f60fc70813dfcb31eddebc1d94bc390cc0e72cc30d5b7a9947d051c88c372e991384b556b02b1e11f660e0348dc54b5afd1f194f239971db1813e83ce520fa499fa9934bc5e616dbaa7771475b22e269be08cd642dd8a10729b080769c035bd94a7742b0181b1a5b8beb1a7ff7929112c6dfb022683052a376327dcc2aac21ec66db6fe5c4067967f21f868b468b5b5a463b13cb79cae090a43461d9a9b19886afad4f2e76ed9b6e3bd296c42278a8b6a30f3a9b3639d85f7e60fad46ae3ceed39038669f1bf38a511711c79abd76fd0c8faf676f8ce4bc7bd7c7388841a61bab1f401b29b2b2db68ca71f225479230bf3c84040a250205d5142c9ec223750d0ac56be41d3f3fe9606183ccd1dd4c3e92142fd33f603e576c24dd1dbda48ca943803b585db362b598b3f5356c8cb9f566c0c8390a8b1d19eb37f41f220e367b5a2611d9d4dc9b874053ecc486e03e847df9afdcedc502ad87edf51b7b2e0edfd7d4baa8c2143830da410f80870c069c2baccec9aa759e61489e3c8a6797196b8b130c1395c8dde6ad8a8378d4c2a06eb2cd0f4c3705fa226ff58418b71ad7bbf39aa7830aeb30df8ede2a269fe97a3633a14d30f67e87b29ffda5602f84ba65c6d4b8d9912d046942924dec86292fbb861cb161468f4e8c7948177239b726501401fe20ea1c66a012ebb3d8e9ca00cd0c997eb3d265a7c84df4847734a60e8aa4596bde93b4c1da8e31eb57b40b5b24cba09a1141598d2eecd665fee42fba55630bce3da06c64963492119eb67e870910f057b53e4c8394f255fbc83923f19c802e8688d1f9fb3bbe9803f9f0c2754145038e9f3661ecb78bd31c0b8ef446839722accb8bceea4921e25edfe1939c686fc02b97a17ee9b3299f834a1819956e8bd2d9e24b6af1fd7156232a60332bbf0d201cdffe240e7778a6b3e95e632fecc2b0cf93b788115047dc79c0e6f7dcb7346f045ff773a7fda1ee00fe0d2c7e2a9ac2f5e97446fc89856f15ee45b5c08d7e5eb19c7ac1bc5e545f340cd46c5a123f00dd488a181d7ef5c997b8d71cbd461b2979f4a4c1bc5bafdff23d60a9aef8c7a087931bd424217abc42d3c16b8c9e342f11c8d4b78be54adea64cae068287cccae64ceacf2e37dda32e3fa7f33c42d5bdf6f8e296a543646385eca5d80c7d86e2ecd551d225b38787bae0689c92ae9e3a2f0c82daa479347a2228dbea195b34343faa96a813381ec74be6e4eb4c1d2cdc83a9fdf5b4408ac5f8830d5076fe024352b280363bcf7ce06f5c7a8d4aa80b5888e7779203be7e89367655fffdd9f18b22647b94e342592717ae7a79006bfe1f04f8ca79295f4d6e289244d442dda0269173a714692946c548f3495e845851d11458c040b1144d1036ffdbab2ef80cf1b4def975de4c1cc0e69fe1caf0db3ab9b9b0ffc7c36db3f955300f9e6f0659c2f7ae7b6901baff36d0d82d6d2ea339df556e40c417e4cc4195297c31f9263a9bc0b280b922ef7095e88ff0fdff1a18d8edfd0f29ef5eb07eb3239c6cc368b8f58378d55e2bb4e7cd5b11685edcb7989aa7aed1535eae6052adb93172a5f247141a5ad902755a5343ef415a0a62d43bfcf1088fe8d811370c783de3081f8ec9cef53c48ab7e1a4e037b7c7c9bf86f08e1f010663214be0d665eb352685a3df8a2bb0b48e9b9f45fdeedd59d8a23de6c9cdd1923b306ac04e7c8f523b30b89d310ef071d9c796b289cb60ba02438520f60ecb6a3e65aca51c8d3ba29bd1247196228dc77fc7c9cd5fbcf2f828c0fabf243e31fca824460f677fcf15a936ea18643fa6775986bed132dd13c7e10f7525750346a5a581503930fb90f280fc23bb2e10f70bec75704492671c2de84729d16d0d33ff86d356448a0f53efbe15a8af3a1f41c2158209ff1b3bbe36be44ed5e94ba6de0b34f77eb525cb7c4ea4d27c94ab145dac6ffd5621d81a6aa70f2fd879b0dbc684af2a95ffb079630ba5609d9e9359d773fac17e4e7d1a6cdb9dc4c6a6b78ff5eb3dd67e2b1fb5cf70e34144a7bc655a330f1460083a769122f84831e7252c77052c67bca9b630d1d1168ab8d27f053b8a24512bdc0033cd78359d1bbd21316b8268eddf99267e0b9d63d520e9448ecd84ece14dc18a2de16f6be37f8f0b905bb9ded301689bb68ecca8fab513a18dee5264106176c04d8735fe19a3f09c25f829c6183fe6307c9d1de11da8b44b2c04deb073848d1adb6a60f6bfec0535ae794001a00d42109f7c9325a11e1b9df4e0199b30b491a3875753a732c41d37a7545742966b50a67e0a30913345ec8b6e54bd9ad1df26bcf2de607e004259b8205500bdfe716f5c01eb3f64f72c17762d8cfddc931b2bad30c7b8eb62957b45926c57b490dbc56e166eb2fa525833e59532575f2c63f5d8cfcae601c32bef5fd8fb1a837d56d119b65db75e4af0bfe185ab960b18c7585a5f99f587668a028ed866ff3aeb156de6967fcee3eea8286a64667711aa5f210af61fcd36769d16de2a9af652971153e59d9420782bce3eb836a7b5da1ffffe1bb3a1af644c8169b903d4c102e2c7a980d1128ecf4d26456e34b5fafbe4965dcffff72ba7351e29f78fe5f826de85cce467f0f2fc32dc3d7dfc81bc0766f71f5c940b1484a7b90fadbde234313cd4d39afc2202d3c6a37686fad7cd5918142bf7ba7ee72226a391efc19e287826b0e37af849e9cb9ebae46cf68626ea24bd55a187396f65b79050128f19ef5473f6d56e42e97f081832bd2665bd9c816d444d3d74e51a48f6016d43e6ff0b20bab8b620d25b3aa7e5bd0d2563b7ba34a072d037279a11c4f8d96df915f804943bf4f6a580efe0ad862b0aaeb329dba354fae97999cf2a0b50782bb6cd89e262085094857f0f52c2d90bf826d41c51ebf9cb0101fb75c38cc12e440a928840995e1c0c3193aa4b5da1aa164ed897143e52688a5ab9144aed309dc31b281aa82fd76eaee7c11602eb95736cbb51bfeefcd04b2aa252fb0d82912af242367ebdfa7dd904b0a7221b224e48511279eed6c57a63f7c2d5de75fa4eecb2de903c6f12c705277846d4778bcb06c6b529203ec825b4a87abf79fffc3556de7f1d33e09b121ceaa027cd9033d13f6edd1a654384a0419c1016b6d9440c5298c92dc4090044b29e9fd8fd58f48e4aff686a9a52256e44c7aabd029a65d6a3693b734246cd5da1ce1ea797489ba83e77266dabfda8b47d83010dbd29a1022e43f1ce85b32bb4a4735481d1ec1a25f666c640fb8b6e772f86b41f54aa49ccf14a88d9b00fdd075791f8ca6937c3bf9fb7887beaf2912e2ebe6ce8a8ab33914cdd39830aea62308b9b65dd4af2b2224ece2a5cdca6fc3c93c0b91a28bd66d6e158bb4570c2536d27bf0e7600d06f4d237884576afec6e0100d9d4d7862a648a83b7c97384f8f935d8756bdcb1fd17edbbf0f6002bd65651c2be9e3aed4407ab444c755e97a9a2a740a8f94a58e5fc6310cf05d127afb32aff89ca43c950b2be7a86326a8aface706fc23210c1dbf9d7329cae28cc60e112e30cabb5df967f6be2d4312ca51befe3db323d86997180e925dfbb83504c4bb99337623b34efb7c065a2d00e7350a49c9ee8261c762c08b03f366f744e472bc6415fa0b91b60957168ffe2bf1bc02ff364dbab7c52166ba9960defdbbb6c7f89914f3061b7124692cf8dc36c432c3cfa4b1c1540402b59f3076d8502a9b984dfdbe6fa7849b39b197d4412e52154256a05bdb0ee76b490ad7d8177d2df08041ceb379b7bd615a416ea653c9b232d7f04e9ef894e1464de8b22994fcafbfe00c495392b5259c06e4d9069aa32753e4ad32b592d6e23a4bf8691ba382c506a9e2dff4e3b359e9c5f547a81ff155f88a0c49582529322c89bf515530b942b367b051ba23836f00ef00ce598fc615fbf6e399a3e97b9abea10410781e5c90c823d96a92b89eba06da732f0c87229ea63c700b276a93b366d8cefeb5b9bc99d8f8cf0eb10254152fef98ffd2b3e9488567e4980fe3d7be789a74d27896e02110c421d3b4d7bb281e1e66b4cac44fae439649ac9d2fe8fd48df79b5cd6e59e9861489c2daea17fb3e2612b278bc58899caf74b0b80d632460bbd74001be05776d1ceb3b2775b483344e5462cf765f5ea500a1c5a6ee2c8b43d4242dd094f4f54ce94a8e954705bd125ff34ca38d820a47d9ed1fbd11b1acd9a1f40ca9298b05dde98887a0c3cc3d6a2b0ce6dfd8420130e52264aa19971e9bdfb47c5d8b9818f359803046814b5703a7c8ede84507464d206ac03c3bdedc9b34ec71a88b6645e62f7a9a4659a0f34d0fd7239e60b357809f87e91365b9fd88442f5b4f514db3cf90eee6184fa104c765e98c01055792f57b8cc9c148a62f5781162c34e02e72df6c1f4767cd08ab9081e6c1a6346ecd2b5b87b286e79ff939a78f18d8a2d85b3ce88abd88bdc003915e1398f287d97d6a2a0eb7defc9b37d77ad547376d6190422e0b26f3d3a686ebaa05f00f965c39abef888ba71d4a828fbd7de1a5df245737dd032e3f5432d98f42269be0fba696d8516e585268a730b77da803ee4627412821bb67ac9f8aab737c1271d1b3a5c1975bdee7bf5778a17b5c5db921c9c064469c82dd24c346728ee35fb8634d71881866b102c491f44f75e8bcbe04a41b1c0bb1513d65bf4c6d80c72c819e975e44ae216e68547b22dd51cd77a35a54575973adfc2fab7e7dd4fbb58c2d299f5856cc7eb47ee040ea7402667516ba2bcae86563b67169539b77ec290de77f6c80bc2232725f09e8a8ac4829149d82808575b5a9ce63be1ba572d634062a07ba24fb839f6043630b460068af8cfb7c6a453eb299f7a5aaade3848c4f88ccd75492399cd46dba6e26943dfdfa015da0e367046174574c03e8171ae7b14e6bb9909c8e3ba0bae16074e0fbd9e33cc380d0032e3898a1bfbe53178a6f925d8dc9938adf802d78a5ee65b1aa1525b543423a5910f921debf6564a995b7d08685e717a6f0bb00770b8e51bae697a1b620df28505df86534f44f2db2fbf5aa73b8c8c52c2e6339fdc7dabdba113b6ed45dcb4f2b6f26f89c9ec9f1d5f9aad94df824ff044ec866ea9c91c5c98da18ae1b65fdfce8a0e897b29bb2f28eae73e352e56c7a3ff63653cc32891269333eee19cf52152c9d0013d8d4ea910ba7a9873575c4c108232784e67559bf173ad9243283350fc5f4de82e91c725af4f9b2ff91b3138f79776fa0d696ff64c0b40800182020dafea1829082c36b663fd0bf3e87794b62ea6252792007ba3fffda5d15e933c69b61aea68cff50efc0e8b073ef089ec27715b8c58c3b93e22268c3551d6a0484e79fe3a314cbde0b9916017038821d25b7f3ff3e1020da5d77b3e8459ac67d2c9ada1e45ce09112fe997ed37aa11da3b62bc13440373ceef56c040b23fcbf2ca397fa1140771df8a824d23835c081e4b9f04d3408287331ed70ae4deab3403311ff02b7c6be6c7759710b00c5f912d40515c15abdafb73ef94b37f514a3a78ea1c6eeed7353fe93ee8c330dae5bb1752d00de67f779f9dea800f6f839df724d33a256fbcc66dce473d234ea2f5232967ccb85fba4182469a2d717b86d0ab654c03d1a8e748a248a14efe800dd42ba660ebd616bedd38091c7804b9a5f16b11da017397e6ea14dafc4238cb95edd5cd0973ca6d7e7f1bff5fb7831eec236dc05efb55af3259db3566a0e8ab3fe0b81ee5374cebf4e79ee2eb7a090abc1486e261811178438756a2537cae0d03732fb685ac6e9b8a0fd77157e3b9e8e8b58c4daac8727f258739b1824cd1a62ae80886e02e3cfa040e91f40a361109be5374e36845b046875a436cd2a4c7e96a49d483a1d5e097174106b535beb1203d947c91f23c14be6eb4989959540025eb214c4170a4c1f6dc1c6d84c698f56be66498accd89f1eb6e4e41802ef05e611f82dc0c8a9e55209942873ae3c00e7e667bf7794cea4c572d3e0394f4fd32eb93e7ab3a7d8ebaebab751bc3b5917b07c737047c5960ebe37471617e94f28cc33e9bb82e6b20d9b55a2a54bfc1c5ddb8b054a1d1c69d1d959ce9adc68979877db801655703fcb436148a88fa6420c016b933a786aa18305dc841d8d16ff4f0d460003470d2ad5a0819253d2a218234480b395feb00e654afb6179be98e09f5cae2e1b7dccc8ece1f2b554e34910c3c8ee6c2ad20dff32bca0052f730011825ce76322671f7b7b5719107481e4ea8cb6b48f9256a4f15ec01695c33cbfed353b391906d458da4208351b8bdc9f072ae3153ce6c4b8aed852301dad6dd1365010e778ab67401ec2fb57136983fbfdcf43350c1e586ab35a05f03e5e9ef89d3eaa2b3dafda64c7adf1209e5ae9d517fe3175a503ea9b7595b233f69db4d377c3a85624716b2c57b30db04c44a3ae569aa1bf23e310a61bc9a2abda1dd7345b80ea5855a1414efb4e39f8f55f22d293064728f54d78d2fa0a9a717407bbc1907b626e1de270265d7efd91f90f102d3a78a3bb44b77a7257b7b9916378b692e42402b845c17d232a8380cda792073862a04232cc4f22a7accb136ccc75e87728f1a14890abe3565feffc55b9ffb16b69c0576e407adc0bb6cd49bd678af2bdc1ecf204d46356980414e9a08ebeac223128c17ab7e3254a8bf0bcce6507a051f4992c1f0ce7b52d48901ceed03ac3f92c6c38a2a10b81c1227e3c2221fe826dbc3bec787e4737edb2e2d096245bd86b3cb5f318b461ffade538d1cf579ac90be14b62302e5544deeeafbdb370cc01c26b9a2358f6aaa39b5fc8c2726710daeb056204eb141d50b362f73c2fcc7d71ceb9b37d3485d6ca67a25f2bb1a1be1f17bb158be74104af69bbb529b6a2b18cbc724123358316f288d132a621e4d4133c250f509dcbafaf0792a526e602088472e9e075cbb5a9b4fd6715d1a52fc7400e6b094781b2a5cc7ee739e5484f81b3dafa46de62e73271dea8dac285922a973b838e7727d79be26d4a1cbd3b1f3e966596145c333bea64d024f56eb33a7caa8830d30c38532803c151b3ed9fd0b997f01425be6dbea5dfe71fb93a97eb5b29d8448b2b74290a637aefd84ca76a61a877c1cfcc26fe80f6bbd5dfae60bd7a4dd98fa3e8222957ad4a80a639652b9c2c3e9949aaa0ae20cd12c89d6142c5dcd31b85adac85a76ddabaad287f908f0f1ccf88e0658f464ec74c2f9930697def0e12e8add77c8dc9d1ad8a2cb5ef3c7f75dbb188a01630d6629e34c33514b54353fbdd96ea31faa22bc64d49d3c3ec1a3565f4189e5f6f5168dc44f7b82eaad8f904d82c354099e3a37dcd76d165b7e03793626e7441e5aaa81287a3983aa223ecfc9007d5dae89fe66371e7a5391ae07356546de80aaec965874d86e36ccf6be59ee26ae464b9c5e945323354c4fc72e0e33b2e9ebf843abd49e91ee2145a8490dd4b3a27e4b5af9f30582c80c3a8b227aea165c87b5f30ca716452a239b7ad61b7d40e330a3c7a0b28adb49f969a5d26ab97ff8cc4559c969c6784ce19f472c039efb25a1d4a5cc237cd8005942ff4d7024c8e55d34aab859ebd3a9b4c70272aa22c3066aaab91817539da53bb1f379c92bcbc8f4e78e8232a31e25f61c86877d8c09742ec3757fc65b17975b6ea7da38531ba47a2ce6c53759ccf28313036d61337cc27969572a7d1faa1b73fe730c7ee0be4f11d173e77409f460448cc447645a6c4f3c483295544be61e4fb689d808569be6a353d53bc13124d80e83245f72080011fd7bb807456f5f983a6d11018d4ccebf16e496c3f08031a221c757698bdbd15c81dd914978899169973a5540b1c0cecf395a68fbc4235aaeb79bfb916c37e6813b975ee298c52d0bce7eff830a6d7096f5ac8cd3b7fcb775f9a28c08442e009ec718957746ab4c2d7ff171e6ed6a2c139c430172571e827a31886906cb55e37e1ec432984f36b1dc181d508b61362be064dda7823db1fd49ddb5c3db05fe2a7e0d4567f72ace0a44dbc7925cf5c1f9fa18b19b7e2cfdce70fa2a2b6341c23d765739480b7787eafe2017822b620ee690fd1057903e25adccb4e35b0f4ecae65553003fe0bf318b3137f01606be1ec976f6c6ef1bc15b11a458875641c722c37e055cd8ab6977af5dbeeb50bc37a2f6219a46b1825db93486d17c862b099ee09a4e252b1969a3a8f41545b6f752602eec80fa363008bf154b42ff32ba321b966ecff9b5771cfa00fd4861315ada58146793e921f98c72f867a9d4b6c2668366ba7891cfd0c3454925c2a8ac4a21aeb5d33d0dc81d22ca2f1a8653aa44f4341c70bfa49e98298c5492a9907829d58e60ab4a2b70891640be2c450d5b7def5123703fb42b7164de71577dc37419de31ab3c2c44576ddcfeedf723ffb46034607fdf980af43b68dc7aea0499a59152aff99f7f575b84b0e486475edf1dca90047bf9b2d3f57f84d45e923127e03261d80003f9b8a910bd19b5b1f3d3f0ea714727a4a56283bba58e40a222a17f3cc5aa1189d5242f9f06496a6d6763e4c8c8b0da319832a31b74726a7e69a642746121b831309e703b4137f3b2b4a1218a6043ae3236e3464885780f1ccf35c397c7415e0d0bf2157e27e03dc56e9926b3f41cb1eb31d4b7416e9fa56f43a17257a177aa09f40051ea67be4c016e3ba43159c84ca5efbabc92d0a41ed66e056765cf2ed64c130e38bd31d8c09a7858cde8fe3a2516167f4f96978631dbebe6da252dc7120fa28ce6d1ce865415de3c6e30c6bb857e7cd0cfff9d851b51c0e562a48a651c08a6e390d44a0d5b7b52f7313b45db7fed0858514d56fd8f47191d0d3dd70162ecaebd3ea2775d991f405040b6b9080cf344f4a47ffe19b3ade354b43e948c1567112e5d047be416e490dc67ad109219fcedc7b8722e081ada4d637671c840035fa7fb824e2af01b3ae08b9633e0bcee595de12efcbd787b1ad637d1ae51485cc0ca41ca88d5d0ae26479edb607b640d2a7fe63bd2f7b8833d21978458423dd8d5006a1e62a2ae21be6540c4ca45e99b479a7e42174e7d9bab6fb440e982f0c2f90064bb69cb395d18d7d521092facbe80ebfd9b88faad25e59d95f52e20bc28dd8c6fdcf3afeebea3ffcc62f78bd2778cc6a97ddf4a839d33f103e034cd118edf5b060465bf860b13a45d4330ac2f9a679ee2a17f009664e642bdd91892250e86c149d9824d3cd693992720e11ca5f4e8c0f8335a54c99b28f91da047d9ab95c1384faf5d2658a3ee626314707aa0fd937699c6d6de6e337007e3029846f70fac3eea79e16beae2e613312b219588406e57f1db779297a467c4cb797bac2d47741fbafe8172336c0d5586a14d28d3b7f4e7e9e63cce29d995fbf25adefdf4f5b1a68d92e0c47971ff8fc7122e4d5ff210880a85e840d5fecaeaf86250559ece2b8a4d8037938301ee7bc366469ef3acab58c5750fda8dcdf1073ef79cebffc8afdf1ffdf77c128ae114f157eb260ad10fc13db06bbd00bfc7aea5ba7ee121fc97c1d7144849fd2786e276e5eafa59fa7c60dfb80b531ce985d6c56dcfdc19bc92df208dbac449560393ba48a015770326f273b06febfdcfc66ee43839732b6be5849f7469c3f3a3ade45a50ae8f108072bc83a1f3c5e4b53a25391cabfc883f9fe72c20ad414da151ae3686dbed6688ab127997542877b57b4998ebc0bb0cc03f864bb3c8e1e233e1973a6dea2ad6757707e3932ad38577fdb0398d319fc6eefc523c7610dcb661380c90ea57334cff7afc41f0a1fc7f4803952915f7b3d9206969b99f2ea406547b43641b168708cee202da2b409f2da21740ad490a3a670e21429a2c8b9ee441818af79d126950639deae5d6c206c9f3c6d99362b344083d81203e8168020b19210a9191c1a229788e94052d6f9309a0d1436e50eedd964cba031f49b9d6afdf2e652e2b4cda5cc61bb2639ee636b27b5c49d2321e3c53acb29c03a978ebc585fed6b377413674550beddc80f6d6788aa5db76b429312440836e2c3f42abf359afd60e470416e2c70f789d77c80b49105f4ee89b354ace1b1fc8aeb08bb99ad288be579d1748dfc28929d3e646ef9f99cb91717ed51a2b33afa2d2a889341d4d2dd6d7f2861ef278d346cbda8a2981506800bc9ceafe109d66afd62452880aea1c070c3ee681b15b1f2c93067c26369a79442d25ba0bdcebd326e408388c4174bf6320b4565130e80f0ef758a78fadff1cdbcd175fb8708d797384e06b17cd25f19067c6836fac6729a21fa76bf8204ac77db616a1576911bc3df1f9fde520a5ff3fc88010d68ad0dca9a5dd441efcc769a879ee6f27465f3cd9bdae376680527cd76f739171c61def345e38ac0031dbceadb0b38945505a09e0595ec20a0c1d9be9d534a5cecd1dc143e98a745d2e4d07652ebb75f9e1c9c73ff61faf69201e33118f2de115b661b075c248944e46a329c4bbbd91a53916ee46b4ea37203051c649324cb835b3a25d6993ce319f29f711900712157cb5061f35e5f5df33c03a2c66f625b2115ea1866709331ca65aee7bb1a262b4196ad75ef511c92e4e21ad9c30fadd5c7c4f531c90306e70b3de5f80ec42b4204cdc34b9979f83dc2df95d70b76eadc4cd3d89edd984744181de8de6b58ac98f35d853834415de80ddd6baa63c6ee97ea285a0e00048e2fed8953f20ab243ff504608163f9fa631d716ea7abb06f25c05809fcf82fc898b3907a8e3c7123e19b4ce0c5948cfa36224bf872f138d6ae7955778c3df33f54a2e91eabf8fba1a65326bfd58296c8c1c75f43975bdf188b2a50815d97cadd543b3123f0bd3ac375287c0fa6c16bcef6aaff09e6867afa435a89ed3f2a5a660c08b316e5144a409eb1e72224b97f065f6ef47b4dabfc28eedb442f2339ef754e325b0863fd61aa5be8a03f793bd08a5c01cf6099d8788a4f28b43ca8fa1422a6ca3bb46665ea78674f5225355a9fa6f78599400cf986a2727b9310c7c057859b22f43e841705d0ccfff68403d0e32974aaddcacd597b308955dcf0bedce9840ac19b51414aca405fd3120aab20fac7204ed5e377ee3db859a50fe19cfbf73712f5e6f1c5d7e059cf0d04c8b2fddf462998d2df0f0a2951aa319966a709ee2421d05cf311a26220ab7fc3fb4b3b36c450e87124225843f03c5c9dd94860e4c28f3f39074881fb1166fd5829f56ff09956f36b68688fa9e33237abcb2ae771a84b9f7f7e575c409473e622139cd42de49c54a963b244478eec91081fdb0694e228f6a4c5f5b7b776b8fa2943c649a4c1b01d050965e84830039f6d90292737e823b1de01dcb66ce37bec2be1fed648fcb78c1b78d9164978c437f9db038336f1175a56949a52685d7072507873d4e150e4dae753f142bfe49ed1aef6d20958d53aefd0fe29f14cb1200ea435b660af67eb6fa1b8616e0d9a036a30f006a467cb7adf196ee76daeaf99294c706220f6b901683f23c5900de17fc115e9cefff7f89ef8dae6bf7bf8fdddc2c2960bc2979ad90395bf7b95944ab5cb6d549ce5978ae11f07931ff4aa829baef34d8ce9f0fd6670943d4738dac80140ac76558041e83e9f726c3e434bb6cb0832ea7c13ec54436fd85e96327a838ca69798b9a723c5c42a96f1a54d53cd072277b3d67521613a74932fef30ef8ab8e142b04fbcf74be41fee44c9912ac94eaec2faf4323c4b526cc04909f9c6ff35673170a8070e772eceff8bffd2c16f1250ea240dd38c8691e063372f1485310dc6f550ecd082e64bbdaeb56821aee3609f42f10bc0732a884bc6198769e48d692b6795be0428ff002b9637a64ebe7d7ffec1cc00db996abc132d02eef615aaa27cf2766ce94499d1a05c55f5362ed0d91991ab7884129fd682ca1f9c4e32f8255321256fbb6f4b11c1aa12322053eb477f6d0d2148650470be22d734b44f6c767611790d3a5330bab2a6ea94c95938c1df7adc9405bcf5e49cba0a10666ba8c95f07d61f0ce26ffded7a8673f8cc16a55b04ed55305a6fc32cf09169b60a33574e3b45ed10cfaecae0e84b169efe6349cf1989b2e583affca9cf3b1f01c793b85a4447b3eb441065fbb54e9ceb3a391b035831d7f77c50337c06d4c34ce38b6b13acbfef9108f97c21a8d6862c0e274b21b39049b793f09652c877f748f68515157ac4dd32203fa01677c178f2f2bcc911aaf605591a709f3e10a1c51ac1d59fa48ab5d7f3ca21369f0148b1338e86f9fcc970dbc6876f2cf5d81907e70baee394bf955410ad1cf470598a247ac27f84f6ac788244be64710a9a25da4c44372d8888f88f35f9e302484404202619669accb229e58f45a43e762d21fbecc3f66255885b66c8f00697e2bddd87b5837e02c5074126321ce7d6167af25b4188fa3d5336b578aa1f00ee020eea39b64db057ceb9ee2f0898169575b2e361c2c8587cdb57211adeeb2eb482d1e8c5006c0c65c2d537754856bee2134709fdbd8787e068742a2a03f31b77c897f77008c47ba8694ecc9c8dccd69e4ff0496f3de7e22420049e397147b54d059f0782ec0e4393de01b34494515bde9334921aaa7aea552af9df4dc8ccef7e5f22454e3b0b040b6209e1995a5e3da1fd2df27ebe2de212b51b75184d645486fe771b1ede351740456fe34b7384c3c28e8232e15937bb9e47811a88f5b7532642183a634c0da2c33210332dc8aeb20720b94509bc37ac08c5fb08193c959b53f56d90ade7fd7837431679fd191eabedf3769deee1866f85300079802225da588a8d304ad415a43f53500163604657504af5258accdf1501d41742d1e5b474f9fcf485367c999c53357b16622a701c66c8f1ba18976db773764a245a2838e5c9fd19dcbf9837f53791a243b0ef744fa81e07a1804e62190c7d1dbdd4266396e3d47ad42271135365dec034a6bcd82fad840df3d8cfc20fd049be27d2420585664aa4f9b00ff941e70f13e340fe1568df764be380bb5f69a25f8a0263536ebd0edcc6c6dcb0fefd1a1f2e2a6491a053d7e431cb232bc566d005494850e73619f25fb71bf36e0fa2202ddb7605c444b3e4c9c852e3107ee5ea9ee1d3830754a59cc44b8be5977e3a0646cb5fddebf99928c4031be3a68e764cb8547575d54c9d5f002199d6e7e831c9e2536c7052cb1be10f2297992a5acf0de4bd93944be9e34276fb51d0b013067b8705bab9e73d516e0b92c082cb8ebe95118202fc60fd44fcfd60d5109748cdcc423fb86dc3af3a3a7d8892f2ef6ff1cf8947dabf8e204e801fcf78a13088e85565fbea99fe171c69e658f722818feb456ad211dc7d64293be87bcf6e14e3eabf0787550c9c6249cd0b6e653778af9dede092ab9a7e16398df926abae8 \ No newline at end of file diff --git a/src/04/input.test.ts b/src/04/input.test.ts new file mode 100644 index 0000000..e60d789 --- /dev/null +++ b/src/04/input.test.ts @@ -0,0 +1,14 @@ +import { assertEquals } from "@std/assert"; +import { main } from "./main.ts"; + +const target = "input"; + +Deno.test(`correct xmas count for ${target}`, async () => { + const result = await main(target); + assertEquals(result.wordCount, 2718); +}); + +Deno.test(`correct x-mas count for ${target}`, async () => { + const result = await main(target); + assertEquals(result.xCount, 2046); +}); diff --git a/src/04/test.ts b/src/04/test.ts index c90e0eb..2068947 100644 --- a/src/04/test.ts +++ b/src/04/test.ts @@ -1,12 +1,14 @@ import { assertEquals } from "@std/assert"; import { main } from "./main.ts"; -Deno.test("correct xmas count for sample", async () => { - const result = await main("sample"); +const target = "sample"; + +Deno.test(`correct xmas count for ${target}`, async () => { + const result = await main(target); assertEquals(result.wordCount, 18); }); -Deno.test("correct x-mas count for sample", async () => { - const result = await main("sample"); +Deno.test(`correct x-mas count for ${target}`, async () => { + const result = await main(target); assertEquals(result.xCount, 9); }); diff --git a/src/05/enput.txt b/src/05/enput.txt new file mode 100644 index 0000000..9c49324 --- /dev/null +++ b/src/05/enput.txt @@ -0,0 +1,2 @@ +20,252,197,95,159,150,254,82,11,124,141,28 +24fa7079ded60ef3ece964fe2c748bbefcc446764dadacc35f0fe597cc424287815e33b5d6735c72fa4b5732ccedee4a4f126aba7579022562fa43517e1481b5e4f7ed00ce9bcc89e2e9fd2ac5fcc5b0e2fc2fc4af1b85c9cfcddc44cde2f328976f0df06fcdc7969224c73bae74d12306fe884c2d01d6e477d8ddccdd9a7585b01886ff77929addb68903afc5e60daa85ca5517c71ac3e84bab0f5e90da72d402281ef3befbd0c44cd2c1c98707cd46153e12ef310e5a17618b4e1d89ab6d94022d08a094147f157624013a7b80e09a0c57b506f0109377277ac88a9f28704bb47cbcc6a83dda3a656e3a4c795af14287ebeae5d53f18cdd2654a0b36504a153a82bd207ef61b6f80dcc42bd4dd70845238853ed420ea843d69a23ed555ba14ce642045bfb6dd103a843eafee441d31982baec886a4b34e06535cb82d908e47972c4bf1ed17ad813e769d0f490243a3cc5336ab0e1699093e201bf1578d4738e663faae57d2683415a6b3a9194b3d222e596afb465a66877d20987cc4c07354a944c3feea6ad3e7afe1bd72aa6205d5d59f1e50790a8f9d58c8552e3dcb6116ea8c6f7f5142018e0f1cfc06856a0d42e6e8d2de8c58aa260ffcd5e9bc5f7f3e9b52b429e2dd088e7affcbce9d2da01a308a0e5f48737e7f6a6775ef58847961a372255741ff98526bcc85ca36b471a6ca4e1e94de3a4e9e17aca4eab9d7dd5feb9813c33e24a85a0b60b748544d63c18ec2708862353402159d40adbe5aa593eb38df7b395177f51ae021dd31dea26cb64c5b69ae9eef83e42138321f15b671fcbb26fda4e25b509704a24d3ad2a3d32d3c510af9b0c5df42451fb13a20c804e38cbc3d72a1380479fff66bdcd14ae2a0068e29b540c3d0c62f26566c35fef41b0df7aaa11222b578e43a4d8226ec8c384814a98771dd34bcc1687f3ce6e5140552da6abf15b5048f23144bb502d778a1fddfc2fcb468984314704d6ff15b87cd82f7280a46fa15d446bfbad9caabbd3ad06214b9c6ebb9c0c803aa355e3e27f0233aaaf27ccdba5ce718224b3702749ef638790223bb7dffae34b2912018893c35597921e4543f957857c6da62a9c04e44f1a22dbac91b2b80fa33f148f048b4ffa38294032724d2a9b1d8fdc106212d0c1d5eccd54daccb11ac4094a1e7297a9f2eed5a50fae93ce9122fc635286afe892a9eea090fd1c3a115c2e81ad4f6ee086cc511f298b68432de25e05ab653c032fa44913087b5d7f7f8a850f6488c80a67556e58b695b70689b534d575de1aa13d12b4dbd8e0d52c6bb9e3eefc6540245063d5019a411f0cea1668036c57e5bd4e3bf78c38a0a66f9ee030a048b45254ad1133adbd5429cb6dea7c0b48f5897ded5f79c365af3f6165eab02c82fd62d6e5d0edfe6ad5a4e91274c7e9d3cf2ef822d8452e9ff28ebc7f72ef1ea7132a9bd54ac58325cac61f10e8ab3f08461e6f611117fc332ef7ef47214102941439269c68a56bcf8b178b07e61c4f51efe2252c53b964cef719ca3b326cafbd36626fa26286bfed07ab3eeb857ccba866494a00a5f5d7736d66856e18fba3907f6dc8f6bc96f381509bc9363b0df384a0e92bded50763e7222be52cfd00ca2d7064c662bb8116bb0a45102304bd5bfe0f4aafc553874779098f4cea2a2534e057b4024052875cd1d89e016a811b09335efea3cd9f3c3359e87a98f95f774b1fb36fc49dafe752603b9246df4d84bf0a28077d34961bcd5fffb0b4544f3cdc996eaded82f17326adbf68aa375f24d52de28c341943d0e3589375293fe17ee1af1642af6432eac1ab9c394cb27f993e605647c895b748ff0b2b699362c7711b609aa80d2663d49d4bbec6b2f6cf3cd2a0a5287eef66122e65244f9a50d58f4d5b50a2a1093892b853104132a7eb3e2f7ce298a9d2d72e0c304c5e9ed1029f0a9a4616111ed20152b0ca6e378e941ed50ca47b87cdd4623fe7503136e8ed7977f9d649460309edfd7bc2a0d70dbfcebe0a91fd121c104f540287a59c0f4d0bec126172d8154daa2ca0dc0f11ac584eec01f8b5ff052e8a4dddacdcae958a1eafc25bbbb41930858b0084995ef3d9a1c6b0af6b31e90a662186064c3f137663c318e8d0ad40b9b35700afaacdb048c9180d3ab41f79dcaebc1c31ec0f261515628f6e734c152dff46665f5198eb944931071b2429867adbc6b3f66eed581f6aa271ba5e71454b7f76a3e62c94168aa9985afb9a2e17307c57052d2fd05ffc62305f9bec9484392c318035da6099c9e23ea1b254ef3d615b6b436b16fcd006c8d3750b65d357dbc2824821aea8aa91adec48d43a9141e81b1bdc68149b75cc60c16e95ea814730c1f15b2210e6aeee21fdb827f6939c01607cf8aeda4648790b88623f39a50224e22c8a04d6c3b6c8f4422f080c044f9f4793d87c479ac35f4b9598c804a217e65d06b55a960d468d05507521b3eeb7354b3199968962c01b07a951904ac3765767e7a4003182b8583d0d761b842cbad00a11862453a8f66837fc6454d439711daf9ad985f42e54d11512964aca25849d0596a89b8cd01b0356fd455c6809fa14a57da5cdfbd647da99b28cb26bf3ebc989f02f2a7b03c6873d7fe7f2d55eab3c66ee37098b37361b9404bcbc2ecd2f63b8b6b59d54130151d4148915cd8b43e046f8dafa6415defc8e7f46cd6d13714e23e73915e548d5fe2730693ed397f053f8a6513bd64c5e2c13988b1aa7d6aa812b27d852538dd86511371478a6928137e1dc7e0e38a53cdf39d3f20183e8e4f33286a80abf96f0f954d449b17f96b8e63d2ea679cf4306d8ab351ad5e2e42012c605ecd386964d74d5c2712c8458239cc754933b94f52d0b6564d72e50273f6f48eee5befadd8db25a76d0d1cdd00c50a385e86fbae1c72ac2c79377c01b84ef26e857d7a91f8b2485a7ee378a9474236c36d17d5d7b08a815c00e54fe7cfc5fa93135194bfeae3082c361b909ef5c1f6b6e3b28b8539a295299a366db62701eeb024a9e531243429cc447f5bc94e65c015485e0248fde71e60e14baf0a0a957256c8b39750e4c3cc6b8ded69a7fe66af9b5c893e8b9240bf121badae389c99062c4d4bb6baeb24e9c4941d98d3fe9c67f2413d1a597a5b7159468be478176de71b4ceaae24a8a97edb46f5460e7578faff975c62ae72a4442db3a2a2cfc0e008da71ac084f7ac6318bbc6c0a41080536de9663c3b241e4b625561cd622414bc3536ac319c85444218b63565c2420f8761e9b7437c85e5848a18bd8cc586d3ef75931d231308ef01f4122ec050de7244511b0b8e3cfdfe2500e0ac9eb6965447c0c22bef5465503e30730b03a5a2043dfa1dd19d4cb456c1f5b9087942013ae33c9ef85bb9461a29b931f9b896ca5ca2c2841b0d06c1dbcab9c8a595d65dc15f699a09f82ae1e2185a2d4ba1628ac551433a74fe4e7b9c51f73f86f935803c9a09dc8b8914f609bedcc99fa2c4005fa27978bf71e12b598806d1a04d331e5c0917d91a071aa998deac194417241fd251a48a0c517db86e29ff6add01b1f92465359b188948887fbf35285f5aedc1bd35d1887ed4e20b17cff4f3100974fb59c94d8d0f258ca5266ff4068c7001b5c10d0132fd035133d53d9cef16a7006baff5fbe3578a487bd42ae1ed0659bd3bd28c93375731ce98d58452f228e2a26af63cfc61c09d7165da9934791eac05faf01e3c62081ddd401cd9a2f47adcfc7637c51a3d5f2c0d0c7d48eba8a35ad7ef20deda044d692308ab34842ce6f5d45e0659bf305cdf45d906e263e9b2c385b67e707eaff446939e600d770bbe856882241090cb22b73e6da5ff8517d1115b45c3414e41bd7eabf847d77f71f729c6b6d6d6ee2ba640b94d173f3e24eadec85f2669d6e2b5b81007798b5e11ca57cc7343016b33da86c4da190b6e6bd95ebd93afa0608561af7b119498335787e6763788cce8ba05c20b18d0be0115e883e03f575d76945a42030f8601b2dd12b78eafa4458e462cd3c2f21ac41a14313a280cf2a5cba9baf384b905be17761d9ea28c3bca179b42c2041897ec0eecb756b1b8a057d47aed1541f5e4fdbb3fd8cec2005e5139903f60b1a87c3b77d38577e8897351f80ce2ad9d422dd93f1fbe1ee8dae272d107d3ac0a6a69e940e7a1df39b4abe516ae022272e3e452b100a7b5b2097693fa2fc5413efbdb751a056ebc37feaf92a5cf8607f92a11bedb2071e9da86a89bb3b43ad68108d776f1ff276297b15afdd28150159a61eb41e824ddd6dac0a45446ac98f8f193b54532d72fabede3530e83714d59a6350668e08ed17fcc2a17eb5bf9a3d6719955ad1c4f0895ef75992ba86a2567e367ce326a16341ad303ac500c2ee174bd5a60c97773e4cd168f6a826f6da1decc8bc744d33d15df648474586d0a5fc09456ad19b1dd542ebfb652a41b04cfc7f884335b7b90e99ccfa873568094809ec194a094ff98fae8003130c0714a580eb0bcf93c7d0fa35daed7d8f249f253bfc2fdc4eed0c535f5d7e46514c1a0489f3bf6d22ef4f25960a94822d92eb7f70918fbebd53755c5808c47e0c9debf6b732fbb53d62cc801fcd1433c44d20e4a5fa9dd6f6c202080be900af15ae0f844556e1d17a8baa82b225052a8625276fcd640549257b6e661d6b8d953b86c19efb667b13f9e9e5cc2a1022e5fdf4c64ff1de3510ff4ede70cbd5494fbfbf72994671b297c95bbe333188df1a80ff2539340af7582c83c9db769c6d3ee26e8b836843ea3238b5da0e610694f0950925224fd14dd9e238b5c746793ce889a5fda949a8950eb90ce6fb937810f92ce7643193e05204abd6003fa7bc18f0f947a993118c267d27c436f2daedae67cf2cdbdde84a59fbb55eca9bcedb35352516034cb1ff0f17fc18217d0ac227a394183a4098c79eb98d88bbd8e8ee74d31ac0adfeb4e86cbcafa3d50d00ab82feebf9f22399e3a74b9514967e0bcfac2c1ec06cbb3cdda28681d15db2c3a6eb57413c7e47df5f7bede3a7a5376921b8f796f65c736d313fb2fad2e0415984893cb858315a6ef5a800d81531ffaf4e25fc912ce2695bbcf3f6d5b2f57d4119a88e8bf2c8855f193cae62d409bcc86a773d8c710b81a59a0d921aedbc6f94cad97e933f4e7b576bd91367d24b34b3aa6325bee6ddcd3159d23948d52feae05d655d4794603d554377db7d12d453418364ce6c3092b0da502773d13e277d70b68c1f6305d3dcdbcfd686fcb374e58df29b884ac5b78b13d251d62f1c1fbd84a5e10f1d8a07786f19988fb41b27d88d01aded38d1e96a7a74420ebe75e076046015e796e4fa9a2f7c6132fd26f14668fa7bb9db2ae4122302d434775b0b7c3df9857a576a991c0574e501a33c11e36ffeff8d610a628160392ec0948399b7954ee438e1da079ff034b0d15585b2700b72063ff84620211c1569ae73eecc43854fe6848623eaf144e4dd84e20ebfbb2b7fc8af9bf4c1aab57cac31afc0dba4e7f75b13a1967103cf04914b830bf7552000fa43f8256bd1f12c07306f3b03f994f43a257b88102dfdb2ccb0be1176e345fcc4dbd524af6425aeee58626ecdbbb58d1df9db17a1c54f0717e2b959ddc52d3f72157fec98510ea741246f4687e857d6f019db08262696fe9f6f6d449748181f24913d053f1afe8b5d524443bc7a976145b7e6018f09ed27b386437eb1738db835e2820ef2108697896a76442f99ad689c3638ef5eecfd07750e527d2b168b7c0d0df1f57b107358167ff29f8d8cb2d8b0641caaaa9a6fdf64e129cce86e6200a3934e0f4c1cb1d16935b0de5f537e2ab026304e14b0e22b70ef969d87fa216fe4e7cc18403d30a137476440d1f43c0610a6fbac82d8a28292fdb8602bfd35231c3542e8b90c927f494b1a529236030aad47a7bef4b434bd8941d0380585438202b9e0d98fc0a7052cc3661fb19787ee5ee61e1c12d8164e228c39c36cd486b062fba39455a6eb5fa1efc587ab73f2811de0edf6f06fa902b18bfef723d1e2b6c1f71f4d6639f7afa46c966c62217d305d024516b6eb510ba4c11a9c10b90c33da23c737706921d63976502c2eac19ef639bd6623fc5ef9299b248619df7958f5c9df27d6020cea94e6fd30ac7bd4d6f6ccdd1b3b7646d71b3078057adbbcd805107043257afb574b48d9b7c55b88ca336af57f3bf2b3bd102fce410484311076796d4031260d5c8cf60d9dfbd583d5fe04a6285baa1dca8864d7332f4bd82cd837a8bc5eaaee2a9dedf98e26de90f1f4b1151a1fd3a061ec14243c6fc0e6c2e2caf98e47e73ba378312a811ce0694b5b50c843ef57f679a737f4ca28ea25f3c7aac907bf5422c7a2e319dbf2c70c4bfc18a1d6d70f6d7165dedef3ed86b99a997fd91f0583626eed9ee9a63bdbaa2dbfbf3a28df67d1cfb57e66e2c0aa2bbbfe883dcf945a61d6527bee0561f04c28ca23fb7001725b0303b60f7a2c5fa186a4cb29ad2927715d237708325238e361291c42610974ea9a08b5b250f8ad01b177e045cc16b68e143905877f6758ecdee40b95ebacd59307ff204ebce693c2f8a79d877382b6f87ea300e83e1178ce65bba168dbf8a875caf5c2b94fc855962bc64c0d638e25c632b925a6b531f50764e64d65cb5b944ee3acbc70cb84c6c1f6a9806f15c88044601c74820b12927f294bb3c37a991984696857c159d4e524c2442f655fd71aca9a6d95832e3f455dead8865f3800a475f7433037c036ca412b3c2bc575958497e5a6b40859bb7be37698c1ce6fe7c92b76c26cb99fbac1b86484186871d8c059f9557b153f7122301fe8d1f26fd9aa7bd565a2d8005cb2734f03ddad2242eca38593672442e528f8bd363058140dc9bb2e95bc7da2c739f0d379febd0a657ebaaf84f1b9f3e91c9e672245c849cd3a1111fef57fc21a40ed985241de32ae4bf780a416e0eb2232e62293d3a084a1e17be4d6f415d46fd315155f0795768ef714015712fd3b05275f8dbd971fd2b3d7caddcd0e44923c30a70a616c20ad8ffd66acb47e0fd895df0e2f562dc2bdbf6967b7b6332c91ed2a75eaea928301e5ee258dd25ef4980be18233885f1c7e4db18dab3b530a52a2cd6a0bbf6ce6e20b799e5160c1716dd9b3af1a1a3664ac29719292028bb0d2331e2162fb6f06e91e028c0d66fb3a7155158adeb6f4a62c7938f06d1933df3f9f10123fa955de40a3303c44cb2bb3694446ac4c0b46ab804a57047f0a0bc31c380ce61fa71429a23bc6f6909f9c2429bf28acd9fc66dc17f6ca6888adc73cc17fb89be442628e2440a00a977c015637859a6d8643e90a8f4ee6900c5b2732ede2dedc2bc8900c6d75df0247d93dee3b080e18d1179b6873c44202d7c0e5da0941d11eb553d970bcf7349625a87357e22bd5117944b3f28d9918e05e13dae34aa8b8f2287c4523d7b4976b695495a0c70d6b9af325a028c414170529a28ba90387bfc4282b509313c66a30360cc99147fe01cf144673fadbac4d933b15cc426aff64f1c5823fda8e020149994cfb3bd1859c6612710ce5a7e26226c24ae68f38d534d009d245020b034587124a7d743b391de4d3af48dde5a232f8dfd2a65cb1c0a2c04a8c0b4b20afaedc4d9870249f5a448b1b6dc78d50f400a12d72e97259c222b5f6a777a2c5ac4b64c01e153b06a7898e8fc9042e47e3a60f1bf2b27b843db06ad1a68aa051ea094a67e26bffec46d6ee71494170c5d2da7950e28d37b28cc9f7299b2ce89cb6976f1cea48568f6f89e4d1efa351b42ef9f3bae98d02614db68fe592aa63a028e2cf7609df58bf5fe59f5a6e7e092f0abde62b04b4128086b807aee83e221ff68b9153696f7da40a29135bd1d6ca2b5fb749cdd20eeb207f2ed2ddcc369db37e4ab405f840096045ca4cb4d70c2d3e1d02b7f53457571e5d3b922727f02a5d46873c7e7150bb310f4ebd772ba62ed4418f35799862445b575c9473ec4a8d4373f21d9fac0c6cd4e160fd840301b9ba619b0e1a9800f6bd42a849280cfcc4260cb2d214bd2b586b8e968aeef980613e9d00575b9a856cf344b50bc3c1752681f53f2374abdf71bf55e20c10a94299aa9297ecc5772ab672c9403edd81fc4e5068df115cb996cf1207ba63ff0076c090c301130e2ce32f5b064bc8630637a0e15d4005e69e9d2118d2e71ae662ebc1fffd1d5f8cbc85bbcbed94da89dd8e8d86e84ab587468e9b85dadd252027e65be4d998c8ce43d99336e2b4d3de00ce7d5fed58b14af8d1291be1c3fbb50573f2739356790e608a014564d9b29da71ce29c7eb3cfc2e07c6e54bc611041cb766ecd81a860afaeded914f693d89247f6b4158947279ca9709d15bf929d45f846429ab7936c2b3257cfc23534afad3609d814e2833699fbcda16a2fea002cb913421249d758c6bf5b20ab17c8488f1940839235436432ffc7bd9d2eab53208fe9e6fa28f956733d400b21c45c06ae938d52d68f11382e96841efa954a36bad27237e62e4da379c5747148dc7145d09ff68e8d21d74775b9393e14acc7cf6d25c926d063b57d853b2776b880d1f41dfd6afbacd9d918e168c975981fbe9a315e12a386b820069df5cc11e8c5bbc70a5b3d84e638803a75479bffbd15fe566c971deb0acf12a8c7a8b9ec0026e01e40482d97f422fafd7ded23c00d0e83710767a0176fff1a70579171b2bdd6ac3ab11bf38c6fd7d8562d631c3df0c8574b383f70f8eaae77c0858e7649675adc366f5e4816d5d7e933a30171999028c34e05b116415cdab16d0d6e6b4613b0c43cbe6fe121dc8fc3307c8414591929f850e3c8d1aa67c3c863f0a7f5ea42f03081e6457dbe0ae4717b585d68188c5d5f735e1602731264856acd86ac47eb3011435ab818463fd3f5c5e7ffd3496ce54242ecd3f54aa03a9a04e96fd5ca18bd436bd481801ef80416c5d82a86fede26c5c328d5f9888e048e6f387cc8bb6a320d157c7b2256ce3269e6f570928a75912c64a187cd32e37e5d149301e4d8ac6fe6dc297684e507378e29a7d65957f3ce802d88eaf4addc717aaf9e5aa4013503f2093d3c0f30e36f41c9c7f10d5aa748911dc9e96c8a03e7275604e5c873b844d6a3c2267db3e5d670d4d1ada0acbc4dd7b37d53406ad3619d695e65e239c87e8534075f55c1f0de861de83a0919b7b3b45b157a383441c37286f8da54cdfdf5d144ffd88d8391a3dea2e7ad2c813e343c50d17650c6a4a4cc62d72cc06a418a489b4742eb51174390e5ff6b9016a6c14e29f05c200b4c21ab026ee7672c5468cd55ca5c6c2d7368ece8d0311c6b21dc55cd20f91d536232a9cc33c9bf7cd8e748d1a50bddf5a1936c4d906d12aca4b59c404fdaaf8ff29af7882ed333bcf95df95904278cd01098d3c0b4bbc0e5a15ea5af9a438bdf6b684fffef5db945592a341926064ea5b60738fd9c5a88f62400589a3286a554c18eebc74c1aa08f4b6f7568ab37aa3a086b5ded600180c5e12462ed2f08277f28815cbe19c6510b33eefc7dedfa2a33415bfd4efcccf2e6a4efc001b13531d29813011f2a0fa04cb9f9ffff86694c8b8efe7dab43382d3bad9223e042163f5e6960b4c8abb95f5d1883ed9481dbf393d41a584f3b2ea9feb744cbe9dccebfd33333a3a5f1e27b0ae403e53c012f16d91185fb5a9612ae7945cd787b236de1c76aa1500f13a939ea2eaa3539b231f24b81e501d538347256bf23823780a7d4c7b698ef13d808980f5ee38b58a866b74e1f951be739d02904f62da2fa4261a9dae671448536812aea7431431a19ff5e3354d332fc058f523d6e3006294f226ef507a09a3ce7aff5b7726f2163c4475b652b22a7fe0d0a4c1537e2060ee7880f87b8b1ca71b6181fbdd5f245a8f30938011f98a84996ff86969dcab7b584ea5bf840a6c7aafe6f9a85fc6439c5d1ebce89f2174a476f45e1194a0ed30dd0692e4f187b46d7e2c408f9f4eb56bdab2762ba4c13ca8494f488b2b2a609ed8be66920391b3413f8195fdc1a07aee7d8c321c643e01ce0925d73289374211941eabb0fa6d33d336a1bda72e150fbd34460e67e7fda0caa1e61beca7d28fae4f86d28a6f0a04b4ab1e1aba03b59e39a3ee03fa390341395dd8abec77a7280758a3dc4b1db34fe0a768dbb4e44d62c8352b64e63cc3d2a5adc877fe5a8ad62b63e66c95707a61693329ca524b05915769e2fc37c02cc240a9e7e44e387e39108a7aeb531c7170407a7236c361325b00b5d2cff0cf05e76193ff9277047a6c149ec50423c6208b2d31bec5ee1312b6a7ec4b870435696141a1289342fbff54b7145c99f72b689971295b156437304104fc73da3f393ad485dbde9ea1154997fde6ebb6f94b47959c61556cbb17f954d980f621921c783a7bf7d1972ba1e85e21bdf3129a9d3956fb34fe72a057f7d698e831b3ada7b616e36731d3dff37fe9aa133feebf00bdcec0e53e195e4a8659fe28a5a3e7f89f0eaa30ba9cd0fd096b34348aa0689f464219bc51d4b8e21571b9ddcb25a6347b90d3caf9c261868d96f09c742cc52231584fb8542c5f9c94db8c9411f5e9ab3921f81c77ff13e441b9fb975b3faf6a44e0f000015a7da3d52293519ca402ee9aa8740df9ddd9f1c73320d64d0be34210a69812756dc26371a4aa96b5a700686396c99bb41d3b6815cd6b597a67936afad90f51d7f73bab39344e38045c1c9f478ff49233b3480e77a5dd515f75ce7ff13a7ccef7ad2d553c1375aa11a80e98fef7156d3c3148c169c20e2c6b7dd2c3a5b5d18d6e947921505113b931010a046e1b215cbe205bd63fbb8db6c070e845d3c69e6eeb6c06d05b3aa269d978ebd584d1e11bb8af2576726705d581c6e2db9d19d63af4d3196af9188ad3b83f17a57ceb4db26899d17dfe13edea7039b0f74b4cb06fad0c3dace6a75303ec16a1ed32271b39253f72f9690386abb0c00f36b80d698a76d56e5df35b2d9883e761871fc64fe77ebf0476b2ab1612944a26a856f37869c2748076ca417bcbda4171647b12857f040e220c5b8879c6d4430cab02fd8a54ec5c63198e07e07e44432428fab65f8fbece78caf0886cdbfd471e822b1fcde20eb3dcf5fd54239b4730f2d34b75bfc4cd6b25f17961df685b53a28ada40c1d29b5ee980c97b200be5e9e598cd9464330e35a02a09ca2b10297b3b50721bb87e829f1b5d944ea1609fcd4013effc188408871ff8acc95a3fed698adb311a4d02b794f767495f3a82a5db0d7f87656bb7dee5ffd31aaaf79fe647e5939bdef60213f2b814ce6486875f85bc88c6103eb8c9cd3325d674a38a1f3e906a11a6395c764c6f3cb27defc932a54a5de7088aa2454c391957ce4946ea2fd7e052bf1d6789601a857b79862fc6ccb84f7e59b9746b517cac0d0b09a1b5776069c33cf223436b48f2ad923174978df17189b2165d1cf13c6fe76e67746f9ffdc6d7e4126692f4c6a26ee88f2fe5c2164ba35c3e088fb7fefbe837d1de17461c907a9bbcff50ec135e13361e239c0f69943db94bcc47cfc1a5b9719af3fa1403021ad6167fd83ae8d0aa6928dbdea7dc4a918c45bee050e68ae63489f592648802605699a32445962bf4ef2ea1ea07f875c713331592d3b82442760a121a40c7d4f832f8bd65028c56ee189004fb792ddbb11e19dcae7be08238d417785611eec1d088338ea501b11b1418cc4488acbd86c6cec998b5d595f230562acf8ec6518cb2ed93da8e66fffb1498658e2ef1f122f25805b9b1563a607fb9b34f972dd6e21162584f29ed8750ae78e35130da2c81ce1baaa8c0abf9192aadf71a319190235c527e7a04831edbf71ebe1335e338e3223b9a5f167a491640d297f653a128be0950c909f8edbd7133672fb9882dc817450ba6ecaf9dc14728fc15fe5913d46f5d4728e7517aa29a0e6da377b32cc83aa5f7ef05c7cfb7eaae28e6bc2c0b93ddc1b0090fa123a0da8da06fce40a4fc35e42fc6361a25c7f7ef01ad87f1b6e015a2eb7ea8f1052286844053680f1d8d4c7e068657837fca4fbcc3190ed519f6c0e07900ba53496dc35abffb6b12d2d3ed47bf06c6ece7d2a61f84ded7360f034362de9d3c6bbcf2bba8b8d743d61178d99091fc91a1618167a0f69cd32e580d922118da56a8963bb551b4c182d0a62d1d292ae7bb67e97e13da778f9b2614bc9353540814a56fa0977cce895fcdc5268ca57362ef1ed922a3fe52aa8fc971e72d07438774811aa1cd9ca471a0a7cd203ba1d66eb533cc065e019b521b8d11c206ede0d8cf7a809f46445cb23d9f1f16f4876e6be33621a98d66c481bb659dde981b0fedba3adde295daec0a7b5ec7b4fff64b834191f787edf2fa183ac89abf0b40c523beb46002f47a2dfc1d0927c078366a6e088d7ff35b9c58c617e802a818f632452578d49b8168e9a6c3abae74efd8d3a6e0764575e3411499bd9b9ef0a53f91b5e148e83a12ef2ebeaf88bbe9f4c54b6484dbb833a2ccf406a24dcfb88c4d3386ebdf8053aaceb7155b469ab612477d514c12e0fe52adfabdc4e63a846f2ddfc4714aad4685749e07001793e01f6c4ffb51d919f68af7621ef68168094cc3e312473e36348f618aafab9b502111b767778285856cd6fc631940b07c84e27a6cef94ff91b207271d648a5eda7212b94205708ec31985b3df3f6b234cf083c002675e3da18fce594e7629ff89e301b63ac8e1ee6226fd4f8cfb03fa5f4d12f4ad338702eee076d7c1800b39eaedf1d243b63573f93244859b2a1545483ca25b1a6e80fbda0b68a5da867689b97fe3df6176dbb30a3510dd9af6185862e72a6a6b62c4ce52581d03dd49a49d1ac9d8cc464286a94f297a19647d0a6e51c7427af4540f3f92bad44e96405b0d7c3b2144b5bf42c3eb1bf08d4326f59a958501191004e0bf1799e4f28939777811f4a3c40b851536ca5283606f835960ca95b1c30eb47202a21ed2a1822ac5bcdafb3c3c1b0d9d9d2e1f4e06058c9d5f0a34bfae240f1ff141e4aa8bc5db582ce7b9898355c66119b5d3399906d893fbda4c94f41b167aa9fa81471e68f6f97461e02b4d9f190b7b9eae881ce639dcfe9fdaf6a316aa6a3031e117b09b8cde4a27cabfe8db8873cee70820c119faff20bc4c3d4510ea38c9def05f645aed017f98452d0fcc810979aedec61669177b465601fd891bcd2558d6fc36cb5b50457f9888da3049b696c06d4fd26bd14372c32565ef432af253add8ba99345a4d67ef5321e0923f2b84e0c03cd165a680a03f25217260f35f2eee949ce5d2274e062cccef7d683de417302a8077f35e1d4954e31ad6d8b416e5b5327d806c2321db45a745804944f0d9fb79030ca00241b5a535c6851a09c59bb1ca083dd57315f25b1ca37cecb33c5d7b42ab05cb064078cc9abd4eaf2cebb645feb5eb75cd093bbd10677b1158833db591ad024b7939a7c26d22312518ad96fc9ccc62911ec8d151c203c1744c8fbb2c82d27324cbe1abeca7f7e888905d3c386bf46b79f44d0ab01c52187ad75e94aba79d4f151763a49f4e58f3574995e4f50e5ba1b02a770bf08a1083ac3acc18d509186df53094e009b540f2a58fa73913e79c448309fb0dc20e67c5d739bd3a35d3f94a2a5856a273fb7a21ef1777a2cae8b67fc1fa884a420be94878f6aa202ad6745b3a9cb3e89dce9e10b04b101b1453c4969104a0aa620d88cead76322fce6d4276d71ca8c83b0c176be61f477183b36146189b860446646391aaa6922972a6e24959b74714b024e40cfda4fd08a6735c0df460bb500d3c02042d93c74684388f2b911ae779906558ad996f0f06ef7193fb35f1fa98bc05eb2ed153d400b66e938b9573ce1cb905e75183da5ba24d61e7525903386c32026a0c9638466e7746446a1d4651a33b7f79b288bbebe97923965af49509d0779ef6eb8befd8b4083ffd00da5f54ca8920bc6dfea3a8902fd409aa5ece117132989c06f90f94a498e4323ee98234069d44233d80cb007c057e818826f1ccf9814f9c4ef5abe93027ec15d66aa5644743f27ec9c5e3ff628ac26a89cdd3c2db01ffb155b8da0c19c427c03dd5018590e17d1b50d605bea1ca81c15981ad2be67f8badca0d819f65b72c04fbaf4b12e298b9be4a524b4cc93c9550851bd600707ba05b24c603bdfc4898f605e2606b86e0c2dfac7d7209179d269d9a746242186907d73f6aaefbff318c174db24079b60558fa8230ece966fefa59edca50ea672947d1ac22738a224a0a5771cbe84a4e3006339baee1b3d7990cb4903d2c5fcef2468275f7cb58232438be41744a0925b5e8a17024eaf1e7b8ce1387a0761cc42d484ac4f8e8b69023136263b738449f4d99557bffbdf7a4918578874012a755182dd4ff3d77537c94c66a32ef5eeb90589a4bff2f2069939d307cba32a944a333e3fba74f64cbee2a09d819ddadf388a5ee574ff78643863401be13633d3726162fbbe316c005b8dd7f4a6783dfaee9ea5acaa0e5a19bf8a699bfd43132d42d0f4e33739369151f864bb430787c4c8ceed31b24606833eb2ef05491823b6eb4594879bd13e399cea339fdf785090ca908a7f8b7fbc8d35d4bf8657e2417bd6f6558b0372d9c82ad41bbb7a58782da9feab3bcd0e144683604b3d3ca00edc39c0e48ce554e1e5bf9126bc9f8d07c51d05817c69bb0d0f1cbb049e12fe0b9bf2101b4ebbc15c4914c7c2acfab4bb87f844e7a9d3b50885b1d85e1001c06aa427ef2ced9746bf38813d46240d4cc49a800afd130973ecc8b2dc3a472e7fee129a4a61f929b60d3f071de972916b223a39544b22eb86f4277579baa0638328803ae84af70a153b67f1838e52833647016b2a8acafb43c2f8167b6b401282221467893f33cff9751f1ba466bc774c8be57a01aef77428a24ec4d31e8833d1dfd2e057fe4d6cdc009d65518df9424a2b719a32679eb35c012bec327476cf0f2bb5ba9cf34743c0c4b5e56b377f7ebcc00576428eaff0a26669851a3dfa5d44ce397c42ece420fe81fc03b61abd34fdd1e5d9b86c5e1bf35516a22308e69390f5ac74690e98ab6c6fa74aa73a919450bdd0433ef0be46b0ec2510f519d6da368d2c73e928d5898bcc12a980eef086c911629daefc7bf6bbcc245bab80f4fe2a638bf739e2b74e9f842452db7f99fae063c7fc16d6b20c65af409ec100d2e8cbca08d9435f97f18f8d1eaf38d30b3b29314d94cb6eb20b58c970e00eadd779060cbb38b83d32ba22b49067e29e793bff7fb5c47fc069e44aab9a1607196032dd6dc4856b87adc50a4e86bcb4fb330a953e1107e77e1d2cee2516436fbd76e091015f3ac199b38b2d6ba5692832487668063868117fb7fa837e334dd0ae1e234352aa56daa812bd0443cd7dd11f1c4f029c9640fe6eff3e84a1e0ee166ef9aed61994b239d1f86016590ef5572c4ab30c558d501689069a45f896f76c132c141e8d01cceb5eeca3d1ae8c76c580929539ae45ec97fb1e7f1a830dd615f31c4559125d9f3f62954bbc146618388070f0cb06977486af3e8211fc81be5e5476eeebd14e0bd2da15a9e2898fa289263efba0ffad9ad6b8fc479795fbfc0b0c772e39634242bef923e5679204da97ebf8c6664a693fc0bba2a899bf317ad69d6459b3857a935779b64b8f0eca94992578c5fd327c9e9080a59eb97e3826bd00304fde388aa63f495f2b2d58cfd7615bee23186c08fe4db74d29d7ed28798c71798aa11964f93ee4aa520ac880159dfbbcef3b83b9bd27c27ed4db475d9935403dc633821965fcbb83abb6d1e475ec609a5f2b7d244e5b1e1661b56dae3784bbb081e066bce89d8c4b0d8f2688ed36fde17d688675d57cf26247a6c794df8bd64ac98dbeff2dcc24437a9e4ec52dae801b125371ac7f1c3db20ae91a73306d15b74ce4b03a10c1a8122fcf9f30ebc2d24707bb6bd58a6028bd5b704bf9ffe7d3cb8504c37f8613195f0d096c973778fd5136d4078f245ec0a33b39883ed24a74fc371487d72a71c388916a484cb35e5084db04e72c71dbe85ac34b6df2d43aeb8423798d458de6930f1c94a63ed3fcb9ca5afb4a1b3ef89f2b94717d77439fb911f0c4d67fe896679e5016c5432f825d80abbe421e9c58d0de035467aa754def9593ff05a71c1c33705515ac452d09e1d5ea383209fd108746cd7e07e900d93d76916c62dfd891f068d299812c9e0133845e9ba44de67948bcb9ce7058da6743b36de05d9eeec7a5db1bb24fc389050efa86b0cdbec3cf909f55ac6e04df9d1ad4b7d91a33924f75c261e8ce4b9001ba010b7994e27bf7edda61dacb40d267bd4f9b0ea52cc79c3986f85915d34f4bf119e4462fe6cb097f2bf24cdca5e1dfcb320a0e3024beb8fa9c050514ea606fc5254b61fe30f842e19d1d83f9e559a798dfd6f90fd6cb666468acac62294b89b0de1c439c315fee5bfdb6f1026f55ba81b98b225097c97c65495ef41bb21bf4e3870667566a5538c6ca3aea474d24bff4187ce6294851771095404f01190b65a4585367a07dd5dad882f619f4a8dbe8d22def7fc681e6eb3da93e41aafbbe9f8ea9eda99e35d2098fa21acb5796b12d1bab98f3ee803b0f3e825381c6327c867c5f159d521e8baee90c936e5c9bce757cce6c0349d925739b531860deba4d597eb561de5bfb55dd073a91365f32ce77f28e1c671e998eb14c208cc1493f6b30bf3be63a49f9524ff63c2ee07849384fd9df6066ae25bd9caa09c9254ae8fd0df2650e0dede73a910a62fce2f662451342ca02f05629a97857501ea69be565b3e2b517d49649b4f3882846f0dfde6a5fde1d7c4e8c47e28f0bbf89b16ac0226b00c05e7d4c5bb297f36ab770b986b2b85b8d714618a6885db0f915e63d0033bbc60bcdb0a7677dee4d9263b14c6896f020107290ca506d89ff561965f26e67e2e3e66c5bdb6d1bc7998948d801148e71300fee74e05aed3c3a03b1a8baeaa06a3e63aae7c5c4a94c119fdd0386c542793a00618cd581638343aecda6c883e7ab99495acf2067c3c897dbc4c0ef3b59d7882c1a4770a5206ffedb7d7d6587bc9eab136d47a878f6fea38e773f5ad6e3b768743315508a86586b592193046d1f60f82fdbeddc116b9045bb44c874b9673086fc19abe507b34c04bbe59688405e48331f149035eac679c81311afae0066929b522c1ca40bf6bc4f8a07b6bc9642cdacfc83f560211e11fe5ad8afb764f2b8034f71d2f978a686b74a46302b012ca5da8280b1903eed1c26de209f5bfe4ca21b4cc003221723eed6c79cfa4c1c2b6f0994a8d605e34a2187ce0069b219b5ab081ade658e38279ded21081932ffc820363fe5cad0c602478ad974dfeb997b25c0f99b2a8327cd0eb30483d989d6dd1a0c443de711a16ccbb4a2ef54c9937723e7f78f88b143f6060e00ff53da54c00179a96e2daa80409aaed63279bfc289f239207bf4fe87d83097ec22335e4f3c3b231cd2f82cbb3ff841ddba64bdf43fa9edaa0f544e47a5d18d8a61ebe3604cc1f3858ced30610effdbc7ccda64af4ad1a333d64c1ce7031711682234f084b60272a4c0670af7559866d2a6d37e14a4a650f5fcaf8b4da979d45611d8f8f0af32e3e55c2bf3a46e452d9fb1bc84f05c2afe1884a55cab8e9533c1358cf2bf83e74b048dfbb6d7dc5e299874ad3b6e75c4bf426c3756c4ec541ccfabd8200464b0484d3f17286cb1a6e36707870d27af542481c01a43dd7321cba76d0f910dfd94e28e46c50dd46fa22e87e3e50973d5bcb878753aee405a9ab416ba554eddfe5689ab81ca9b077db1ba096346a3f7e78eb9cd5e18d92ffebd1a21841004864cd16e6a41d4a7014bea9b6392dbf2cba86bb429db67405d46d5d840c6c0ee1fea4c0a58fee68c38f26c7f8c3be7ad987ba2213ab6023a4d4e0381042206ff7a77629052351b134586eb2d65844d5dc3e35ede3b0aa88afe4fa7d607cbfaf8a493ac2afa792b59656edc211c3470ade24ec9450de916621803cdfc031ae010c5a6d233ded1d44809b6ba634fb70240bede7962ec949a0c9a40521c06c552e28112082c5bac5d454f936a3353f45355a95117a5916b2d6d732823c2fec1d5c4efa9cfd92dd64defe4293904ad0f02c6daa2159c3d7d41f239b9ac46121b4266957cbf3e72f8437e5c9818cc4d9732ecaecf748ff0a65678341c754ebda6df759c1be5afb0e01fb8bcf589db00b58b69961ceb54649d45c0e8a1fc1ceecffdb34861d92acaee6c15cf774d22ee7050b7e4b5eafa97920da19ac1ddc14a9affe5838047499e314608edf6da130144e5c080b97a454c5b2cf5794208f778bc71011c27f233311f33c2a4cf94b1089e40982681fea185d37d2b1b924d735dab4c0360714714554b9cd202917c8a5d7f7519264b949a4835573845e49156d42cc9a66c0afc8bdde22b8f7183e9f48fe987eb891c1bb0c346d384a33452ea42e0a9dd1c29126e7bc4c246ecdf42caf73b526f76e03ff293ca78a3a49f390296b455d3292f224289f37d2911b502090a69cf823a344f2333f2539a5cce8afcb21a2c9f42c3e7bac0e70c0f25280da057e1dbc19e6946be06b3f009fec6a49e2a9dc16fed94a52ba449d6a2d6678c12f1863196aca126c63ec2a97d0027c9fc960a9ca37a3abae6a709b8b2d73e17ce124bfa43027bc2d94f5a3e25ee8388b69d7d73b68647a056fa6684fc639c133a282a6d929e3d4a1e66a5121e02f5e4b14d27f1b7fce24596b1e4c872b73c0d2c2d9ff0b9dee4dc5daaf4a185db1b37d677b96a7001af0d47d3e4e9d3ac43f777b448fc65850ad3be74c86305737dcd3c39ca6f1eec9d0e70e337c81cc706dfc45e7b1c6aec8bd2c116cc0473d4b88bdfaccb367be4994a983b80bb97b5b7dc7b421d5c7f28c76e5317b513de3c5d2356e3cedd33e730edb69b3abfa589dfa7f716100c9287d768f9e0a1abdf66738b793fa45878ae5b01fa2fd7ca3efb774d5c73d848bd3c21b59926bc497b1dd055e5005aa62d5cf491cfaa22545e2851941e794db47a036a2e737ba1165ad2cc2713e1e24c25f027aeb6cf886b32a06e6c7bc6b470bb2a74da21bb398d83130a1d4162450e1c6cf9fd79dda0323cfe1788e3aa3f42c8934e5d584438a2025eea4679fc3150bc0d204724cdc64599bec9c4c15b2be691e03d04d725525d96bca25454f2a5cb7bd00c6580c448e7210fe1f15b91d01860b60bb2fdb114c6d901a619cd71a25013fd66e6ab639b21f4f222d551b8de4d84dc695cc54e7b7c103f63cc9cef231b6d1105ea76882bd44b08ee7adc9b2b831afa43204f49e158f9469025a1c1edaeb50edaefc47a1b94bfdc8806c23918a8ddd4ea5eb7b978dcf7a66bad34f18cc313ba1ae773e8a174a8b5a152612b4da61fd6564475627c35af3060dfa1c72d471fe8c17c2c4041d7bbef1439957ad839fdabfefb5702cee9fc4434bf35bb5ce09c50677041f3e735a7fb17dd44479b0a3718b3ba96c942fbccf7dcdc98d582ae115a540d99363910c575285f72b079b74bd1798dd03402dbd5f003091b07b0217282816f0785192685fdc2f2282ce409705881b037f72ade7bdf7ad0f252796c7fb5d843578bc8805172d8f76ecadc45e0b3a620b498672813f4d9d4def205c0f7ee69f43ee6c257e7e886b100faeb0cd29cd468862a73ed0b0a691a5f8d56ca4a678b86f9c607ba52442733dccee9730f4ab6ce852c7bf54e7389ada093751303f0fb92e9196c13686dade1e3501f0f71e329f772e53e646a28dd51b867a2b1c49d169e7e6b6f29e6901ede8f8edd231b0cd9b2d0b4cfe2db78856c33286a5979abec3a6cd36bdd374ac70483249f7d68fb132366ad6be62e32545478c03472d66d3f8bd113f6f53ef970de18484946fd4e0dcecbc2dccc6da5a3512ee3821141b554664406aeaacae10fe63fd761a7c17ba3b9d92b7cca4321e26b6fd62e8c9e8fd7677646e4e6442cc6dc2a34d95665cdd40e45e184868ceb8ef2c65288be8a6521559e9a9c9be8b739df6eeb0dc4ef2fb2c1ae853a99bb2bdd99e9230b10eba250b5fb047ea1f12c44b798a6002c49f1a5f56a0852bf21dd3f8956e28c9fb634056c34b6a22f856944c67f688a6459e599c35e5da8db6a9653b2ed52e79cc46a1bba6f916fd71bdd1209ab206f2352ab876b54234f5e1d97d0c41773d33cbd0e85469e92a15641a43fbf56d0f52b202bb5fea87adf2c6d90f8afdb1b036d6ffd12e00302dd5e066728705222af35fc13394b7f922e25a72c865b03dafb4f4415e825ecca931c8ccd2d9541cea59c09808fc9d80e3424de9768e47883fbf14da4ae90cd2a6f010112ad4aeb89e39738cf956f0291c808c8521cd04ab4657e6475dd310ad06e5e606b5314afdf215d0c3b53e053a790d29447522e452c3d1503fdcb476a221374a790171a494a57337a4b9036c7190d319510ab73eb5b095024fa5427d6659724561e2dd43922ca4e8fff02daf82ec5bdaa0c45ebc08cd372bd5313c9d8d432b3bc362ff51999f25ed3c4a1a2f4227200c6718c7ccbf8c1461628491603219e43f6166ce4d6582038f9ecc328f2af3acb53fd6113aa9c5365df6fd3b90732f546c3d8c1174bcbecbc177a1eb3546d84688055b942d2fc6fb4bd5b0fd100dd2567f28d1853645b1d95309986d1a081de8936b86b3ceaa675ebafb0ec8a0640e848e595a88c81c78e5dc940da31bc4c4135efd67f1f5b0bfc21e3caad4b29ef4f55972f14dc0a8df0a5cda561ec11810b7c935f10a3871529b76cdcafd94984cd3a406644749e6e50ef3d382abe16f5cd960765c9ab22e354f681f30478c799d9e30d2c999e602042260b1fdb120e1c998059b42b40e4ff7496faa7307e55a13ed6c13aa272e3ce301d5b903618033339737e125e898ff764a61d4c80b3b9ddef4deb36b049dc2d87c47adeea06c3c6040af7157ffa0880d839d38b66dae538293b2e8301858a84627eb875aaf04fb5fff5c92454f1f41b3cd930a92584f4aeb538383982e375252cd53232e078f083ac2780745abd1f64f4495031e00a06d87cd6316e2d640bba50d2a7b776aa091fbb4d10bb4014940651b1f5203d0b9d295b0487e5226a680359fa9407b801acadfc71b582628431a987fe62f2275f9f5acac1cf5cde8033dcf228caaa4b7c92d77604182856a90d604893007332fb67edf3a9818aa56caee370f61e8e09e2d9a2bb65196b2b1623f8e555398f2531ea9c66d7468ffa6783872b056217985cc344ab6870e8506042a09a89b7f21f0080586309c6817dccf9fa4369d7b126124f3c745cf1c31469bdaea5f9777039cbee4fdbc9c17540d552ac31512e3d4ca2eabacbcfc4f51a4520395102909a5ad121122fc057415f6dab0d996d528cf74ced3011f5cccd25bbd738c807ecc55212f21fb6323ec732245d84ebc1dd8184376d62d6486525b8c0fcfe0ac3ad59b4107ffdc664051548dd80969cab3cae5f3acb3f12968bf1c25b08f8029805ae5e8463a83c553dde82d4e6fd3412f0e1fbc6d66456caf21332bdc38b3adb2d6d4d695a2f7d912fde7d357beed6444d42608cd823e72175a2820b0f3e33f46ba22a494cf8506c16038268b1ab359a4aefe3931e7051edf805efa8d1d28bfc7f8a9fc0ca3841cd5e890e8617b2b4ecfea6fdd0d63024d2597487173aece2399da2335d9829864dca25644b1f0bbeb0a1d4ea0730329c772518858478df3a3f0800c7ba3b4d610550bc714bb2e168bfd9dea0c1a8c0e56194a6313e9245c35f3ce6d41fb9de655abd78a85c46e56a325c088e1a51686a0fc79200824d0fcbd5effce4dbf96f8ce4b674d7f32eb7cc58e653e5d34a5f41c5c3b7a14fd1edd715c9775ea855f2f6632b2a7b5a1ebb5389bb6bfe34f0f4d20329f16e3b2d7867e523b8ee9868e60baa23e915358fdf41c59aac49ebc2518a8defb66849cbd4dd4336f4c21527e9962183acb572584853e6ccd1299ff325d9bcff9d1be000f96cfc486547c6b3cd26b810cd5b5422cd6aa48be173eb0d8bdd85c2f15e47001e6a388ab27270eb905162a159dfecf78c7a3e8f75e25774c05a1e2f27f6931900a6b2a5a4f9fc2aa05d0e01301eac3345b5e5b39c17ce6567abfe93ff6ee14c3e61d48cccf0ecd32d9d4311bce7f96dcba5c10ed03565e211d80337c222214367730ba336681bbaf87234acf6fc535b392bb52f1cb387c8c6149d57d69fa0c85168ba8849570d700fee4016074b75fe51951c347ea6d6f9f3ae6673e1191611b4d6f33095637d3b67baf7a06661895c05e5f0eaa3790503f867e86cbc62828c5edc6e8183e7dfb903a7c3d52f632bdaa0d24ffcfdf6e14aa118c5ebd3d8609e89bf0a3d2490d3882d4cb338a7a7c7568d4406cbc3347468434d8f343534b76e3af350ee994560d1e798e6a29f383899900e2ce9dbfe58a32f3c2d512807b9c9d235745a5b81e15ee2b3e7534d4b714529f12dfeeee52dd4e2a87f00c294cec08029c51a3544f1624758cf95c0b1e2de6be29071602f95f9b7b62f2fb33bf1da5f27f16ce28a23809bddb90ba034d799a6017eef3752f28ad2c1d06a5bc4716554f63cce5a635bbde3d74a75c52c5e7979fcf01b8a4fdffdc6e588b2039ccc60cc7efc7c67cfb4644d5a6ab3a0399dc7aec8d826ed7e5e0c803798b6cfee52c0d1402b7298c6ff40369159ad21dec095b6f684b8d83b5bc4707e3e939d12e33dbf31733776a5e75bfc4fb49970a8be10c0a592b6075021a86ab490fff2f7486baa6a0589e1f538d030ce5de5474c024eaffd0f4922ea99e5f8d5ca501360eee336448344c9c70a837f8c50957d434b2b26088da7fb1c7910bbe0bcea6c6350b14ac76e2851ea96d450f2a1bfe4d3ec8358063f101a900051184d7e722e2adc0 \ No newline at end of file diff --git a/src/05/input.test.ts b/src/05/input.test.ts new file mode 100644 index 0000000..553304a --- /dev/null +++ b/src/05/input.test.ts @@ -0,0 +1,14 @@ +import { assertEquals } from "@std/assert"; +import { main } from "./main.ts"; + +const target = "input"; + +Deno.test(`correct legal update middle page sum for ${target}`, async () => { + const result = await main(target); + assertEquals(result.legalUpdateMiddlePageSum, 5955); +}); + +Deno.test(`correct fixed update middle page sum for ${target}`, async () => { + const result = await main(target); + assertEquals(result.fixedUpdateMiddlePageSum, 4030); +}); diff --git a/src/05/test.ts b/src/05/test.ts index 3a4d5c7..3a99de3 100644 --- a/src/05/test.ts +++ b/src/05/test.ts @@ -1,12 +1,14 @@ import { assertEquals } from "@std/assert"; import { main } from "./main.ts"; -Deno.test("correct legal update middle page sum for sample", async () => { - const result = await main("sample"); +const target = "sample"; + +Deno.test(`correct legal update middle page sum for ${target}`, async () => { + const result = await main(target); assertEquals(result.legalUpdateMiddlePageSum, 143); }); -Deno.test("correct fixed update middle page sum for sample", async () => { - const result = await main("sample"); +Deno.test(`correct fixed update middle page sum for ${target}`, async () => { + const result = await main(target); assertEquals(result.fixedUpdateMiddlePageSum, 123); }); diff --git a/src/06/enput.txt b/src/06/enput.txt new file mode 100644 index 0000000..2bf7417 --- /dev/null +++ b/src/06/enput.txt @@ -0,0 +1,2 @@ +15,150,236,204,227,70,191,81,13,56,216,77 +9fa0c9c8f944fd914d3b6a187c1c985b30153cde4ce04719a8f1b8914c13163984279b726e073bc674bb520ce7459d60c656f48b3f476f8fbd84fa1e216d63007f3740a47af71686fa48b43b785c1dd1e41830d4e7e5ec0050a93693a8daac486e97165c056f5d8bf6a0cddceb50ed1aae94f23d8efe197d6fb2d9c9db2985e774cde1f750da83462b6c5a88d53c5692df8fd11a81d269c0e834495ade15e3892975be8a5a8aaf040dab15f9efc88ead1837d479320e16a39436ba075068a113c48e1f058fde5d26c4d94b5a6335b3ae1599a26146d771493caa215f6d1e849eb623023eb20121db764a0a37cf19ccfa125c35969a314971e020a1fa5700f72429fc8d96f8f8edcd0d8e1bd1cddebc87fb857200a99e9136b9406dad608d6d6f23de40fc0efd08568db721403bd1a8c1313465d330fbff0ccc85dc39cfb08957f33024367544b665c0576635e7e7816602c37d04f8d6880f20dc897a7a8dc3a3f53698762f3fe344f4e274077d4324bfe966c2c122b3b2ef7bfe14d399fb859818941d9e52b76f6d62b0132624805b62b236568224951ea3f49f3d55f85089779cbd865264bb85f3820c81f457eb7ff92ac6479d5d3b097a14ae4c207a7761995fc0a7127a859c3163e359a7c4d49eaff648228f54ee5cf1dff3cbd4c2ee9ab889d3f597814dd4be7e52825bb17389a5bf6867083ee2eb2e0c46ef7f61c0b1c12315a403b5182987bc2ef213c56481dc15556065afeb8b47ccfa71d27353a59b5f35b00555e5769ccec82b0590d68c320ec97d40ef86cac89143cc4d5b2086618ebd297adaa9771671943d05f0f3095797318f83e82eef0ca99d11ede42a86aca15ec980b5e50c6fdc6f3787d259d58c2a3f7a24ccf6acf8acb8f24e5b80d66a9763224fa08301a689829fcd94aaba9ae9bf9ce54b60ce7d283aabd773dc97c61c08fd93efef5eda458bcc393ea57e190902a441681469304163943290a873abfef05310b4308c5334893bdfda6c72c919707e560b2390e66a86fb0f9bf6689a72ae11644849a5df6c99ba5dc73828b93ca02ac40454f77c13214604b5c4cf3411c804065dd59d21f31282b8d1972f9e2409a952f73018a8aeb9f85031715775c7c1a156ca4ea3cb60cb3b780fc7b0a7925aa075555b4d7a46b0e26bf41908802b35e32f0f2c438a9759cefcab41dd151346bbebf0f8f99edb4d7d6ced7f253533c40178e0329ce5297eeb8fe78081ce51bd2bc4845397ea8b1b9738b80f7a09d98dd14700f4ad722a512ac485e52cf3e72d820ba8a03d7acfa22ab2b2070ca4c527242cd4be3658f52ef30f92bd10157fea88506147895fb848108d0202ea79cd42ea918e198ea7c726b7f42a6a54c044edd8e487850e395f0396750d4f0f472e993815e166f3c624324d9deb4d4db4bc90484c6881a4c85f8a95fba5d03dcc91764d6f8c1c80617b3d16839a6002c03cf3195e378ca039243aa1cffc8dcc7f27fd3d3cbb27aedcc1744d1428242da35ccec6f2da08a432db5470d12283cd94bd8b1f4660e0022f81e083f507de28f75a15d893b451774fe8cb66a927d299a5a23f048c127082193df9458c4d5e0016e6cb273b51c03dffc39a99f295abcf99bda4b7037139282fe5d280a75640f6c8bf8a4cc90cac0860433064386aefa8a6340c55e422109445ff124aac48f979ce40be21154ca7aa2886e98b0c0536ace064aabefd16127afd11505e010a2a188a99c7d8813b20492c4b1c1a68850affe29ff7b65e3956a5119888978411b99542b89c58025b41acd2ea565dafc361b7ec4291b4781baabaecc0c363bfda6ae407b28a6d3c275458d1f525b99e3fbc17023b3827ad19bc1b824fb11b1a615077a52332a33751a2a8edf44f437636e28b4a9bbdabe92433875fc7f79363604cdf7c67a94d1ea8e924b87568b2077a4974f8373ae940ff51b0fe6786b2f147388963a8c4fd13374cc8f146bc65719db0b1e814bd155e03d760d89703bc6faaac70c8eef5dc03ee758dcabe6980194a18ac7b06b246fa42dae4c3a6ce77896089d6b4ce34d57c8b9bd3cf6265e59243044469e8b0a2cf0621947f07f7ba0893e721d23f0dfa5b3d583d891019d956ba362c3d44983d4e9db60896a885c15782f188ef5d40f44ea6e9a7679a05cce8d077bacb32d8d4b4fa1a9e24787fbcf605e29e3c96f8ebe0d73ae2b4cdd759a0220424a95652191e7369e26331355d708b4e68ea6ced43b7dd1dd3437eaa1e23678dcf92b0c7bfc2f498349ac6eb7b2f256c23557306f4e4c7182cfe0c39ae7b03d2274bfab4669e4a5bf3e1590c796881df6d3eef3194060088f5a4c4d949442d55b8cce8080f121b556a8a45896e2c110aaf4cd5858958dd0f57ea74c52fa4c893196da7160a405871ed9243a678d2309ded924a370c4d00f134a2cef179403971589c3284ce31243e196e3249a8829fccfed493c5865fc0a9fb45d4fe7aa731977f6029ffc47e372215708799a6a3ac2fbb2d6a0cdfda288c4e236fe7c9d11e36ab4cca4dc5afdbfda6073d5d7d7eee2269b4627b9f782d79a8c8e296e09b978ec6dfb7a0a3f94f63f2f15c722683c2887be81fc7d93ff23150d0a8bac182897d7a88c9edccf897f010189ad26ae15467726713cd07937b87c59a573d1df440f7820922b168336b94e060d87c7f897d5107cb8f3dd5e840297c4a282724dd4f06f49ce1ae3389917cb799fe962e6625d807f1ae703b916a9e2c91b966315e62c436652cdb7fe3708d0c4c5d1ed463c205288d00b8b5ec6a54c8834c239083ea3a6097c4ba8e4d3910527ef06f449642f6f0aa1c92d459834652fabd4e5ac3d2ae43bff20c061d2b23b089a43eee328619ee08adc18f419c9c6131440ed2b4253b9b6a126c5db73ffaef9064bcdad498e690bb9d7dcb3f1248c78ffaddd4fa6f0599b4fe44ae15c3a62582f04b396e83e8879148515f58351f2871d7a18867502037682b4efd85496bba2ceec837f14925a3bfbb63d62d13f458f56f8a982afb892086cf8085492ff7046c798b4e747732fcefdc2b99664a2b1949cae18aa7e21d2212f6b4ece95af1c5f9f7dd522fd3a032f6608e5a7ceda590e614e7cac102bc4622f5e58502ac460dba523ef7a624586a903ec466ed14f81b416417e557f3c05f313c40e785dd7b224cd334f5c593930723bc0cd8b9b0095309a7223a1bbd9515cac7b2f2478ccba1600c2248cea7dc54aaee20f37f02995b2169cb51dec78fec4badd0c5aff98c7f423673297beadc36ff9b1f19a85f2b4682ec5a15359eea91760e59b2fa88caeee9ffde69708e981ae707b85c9db33840d0d5cf8655309dd47f3e299cba550e158cdb849531311df57897a37a148b11fbefd2ea8be7da3f8bd765937b1501b989ef4aa632dc8f52ec48018cfeb6396a3d051198763bcd8425f82edfbd6bb6f6d060250b13bbab18056c2ee70f1f436f37483654d77573c56caa81e5dd6e619acc503b9e96517ae5943bb30e75516d6a8967de66cff093d21520d178fcf99bc091ab83e1a9654927ce7d373c26b06d2aad14f6447b6172d59a22e28bae73014783869a098fc452f9f258987c7977b58d35e5b4e15cdbe1f9c1419840b35f1034f4e88b924e97e5c1ec4ed2e43cd6b6e3b3f886feb90a5425bf3bcaa53a5f28de75614ff2b1c2a8393e060b63b0b6c5406d0dc234ca1b8c5d108118ab1a0bee18de4e694e327d941373590a936972342e3cdd81e1b3bb724fc9e440b1006d4b534c8b50ce4cd02d5b5f3446aaa0de0943510459932d7489d43ca5f1b7fdae973f2723b3c2e74434e668d94ce42026995458b7edc49b74cb519c96f18d9a121df6967b4763a48f3f2a21665532e3e940ae69dd7fc632db071e7a512503d27897fda64b7bf8bbc3711872be9c501908616ec9195dbdbc7e6043a216b7df710f3696352d2fc844614ad5697f8ddc9bc3661904bd7443992798f6e5e19d21dfede46d69f90a9eda96ff2992fd7ac770a68c51fb60016682c6e2c1f67c31a4ac1384b894a3815987808c4754600e4bf52c6255ebd3c5e8da5b1852e61d7114ab9199a87f53f6eca0cbb157d91c46c22d87a4d96d562f86e58baae00e568a5d87a509812b730dbf416417001fdea24cd2d65cc1499743fa73cd9c123c67f74c731b4253e0fbcf15c1fc0411168b278cfe5d0298154375e4e9d757fb1ff71bd3ea358c655c8c164c07fe68424c81322e74276983630e64f109adf3e133a68fb4e2c66dc88a178ad49770e6685830c83e8a139fb27a70124e3c161615ac41fa4a9aca4916908b6da0e01a860db0fe05e880f338011fe87c6e70c86cb078822bddcaebfbe5060bbb6d0df29a0bffdfb88764b96da5711176c7070ff924f3eaca3fd370add9c2b0cb7c0ccaef2990353877de3fc9e4df55de4bf76471510f0759b62beba3cd19be32d81b280c824f41ab5018b1b8520c034367c167da2068a8709a0efa1b72701b8bc16043405be6ac51f55284c4d1c6c785234c3c3809a74073de69dc1b482ebc7a80ee01b1feb3e4a6e9110b42bebac035d492e09b97f0fb04f32dbc6661d23216295312dfed875349e7b8b0c5c1dfeb3b78c41a2f536f5359edc8d023920fc61c597e7790f3aadb7eb4ab6522b701362880ded276bce7cc006eb95dcc1c7b21afd349f8419cc2ba46c75690810a8403271b617439c362cc9b1acb72b045f401678d5ae7ca3642c380dee51814695f849e304b308b8eb8373c66aa9e4faeac993af712c61931c9127213daa79e2d49e8354782a90529ea7f4ccd97c342f92d7b4a85c41d3aba1700f10f58db6e9974c2897b50ec1f49ba5124d4569267a6bd06c90207eb1553f594878cfcfb1aceac3654e894069dae27490686ff283c25f8103b61379464e5c951ed182a9614c55dd3ac5add3194968a3a8f9eebb453982117e4eb674947e17040a7eaa80a6510b24d7cbd71ba06926ebb7476db5634c02c3920f76505d9f99fe6bb9950b23bf253c4ab502e629a74ffdd866b22856043e30b5a8538c18dcbfeb5f0ad79a5650b754c45b38ec5a1761d46067805934a1fa9569364fc3460615c4d562c16627338b4ceadfc3badf458a60c2d811ac417131b7724ef2cffd15d7ac5028b63371ba63ae206208df1f36e20addcf4a9ffd11d4fb09b6f012f2f0c065147a90179b8276f70e1dd206d9f4ad93ee8d25a9a8e4a9f574c30e30e2428ca00049571dd78996b101260001970a192d9849432c14d9c583bd6e9cbdb1dd4a49d0f7cca22c05f655f1dd90782c423b65263b0f8ede9f49105475eb4d62cb3f3fa865ae25b5cdbfeca3d900706cf60a0c354a53fc52b522e1f6f75f4f32965949579381d6ff85018e481e0b3ff38cae78816952283e3b4e99cd8e5cc57aedfccf410696737b436457b628ef539c53debd14acfd1bd395aa73667caeab10bc609bac0b8fa57d8b0dd1f6b1b993387a6e9db1fde8e608a87bee074e84ce743df710eb257a291df9825e2d8b90f576b3a5467d743e5c42c48d1c3d183f504c5613af20cdf87ba08be98a781af573767d957bf2ef2ad461ad62b790da4c39b6f3faa3ec00e382d166cdabc745d05c682d7e455403afffd0ea20e03073a37e4b63da571cc67910d4b35a4460a8dc5264a55a6319bfee4f2c5f6d9065288f4d4987792c165fed272ce8d08447db8f167954c16577b30057e92277562076e51f63c7ccb08bf661d7ad82c3754aba5db96932ce212472d12eabb2d74d6451b244364dd6d80a88b8242f61579490f6cc00c7e77ac1b439b9c57e3791470e9af6c847444892e50f792519e00277691d530b42fcf6cef70706c9685c17d85d32005cd11920f810c91235ffff4fb5e2f9400b9cd7d5c3e0cb1966ced0d2c0539d343ae07d0403f1849455c7ddc91e6c0139a757ec6db2efda27f1bb0d5e6d3fb116f200a84aec2f1ad31f3b1f5a9b8215d2d36fb6f2559ea76e5818e8349bbc08fba894e4e94d448119d8472a4716599a5d2e3e712467fe651bbdd08ce3eb2419c525ebd09deb68189bec491c58dbf162b90abf43ce6f95ad8d6c74916e4e6981f96c6f67cb27268dcd6afcc8684d8caa844dbca06aa8fa351ce200d83828ec7496a2f1d8f1a028104135e016b47321a32ef0c607781b3ad365e7bd529ec138d0409281390a54ec8ad8c7b2f60c1e03eca4a683507b78fc3a5e6398290aba0f1af4cd13b055197a628bf8981ad34a876a98e9dd141e339324ca01ebb5771043bb3e4a5810def3c995248d9460008311663d9eef901e159b7ac9a6110c0e2896edef0adb28f48851e250fa44efb0534c4e438405b48fb6ff1b37ffed68ad19eba542facdd6dfe0958d54e1069fc8751a2b43d2f4a7cebe4a6bce145c86e80cdff2039813fe113594935e444c8f5e5b5dfb5c028d0b8623b85d95301043915b1fdc31c94fea8f6dc8c365ee1dea8f51455909ee22ff75095c47fc18929504259e6c523892393b655bb1fa268f3ed0adbca41077ee3acb07151925b559e55e5959a669b80edeffe503666db0974d23a6ff45637fd13ea9625f22ed75df1d5f20af476aaa279f09cff86015ac59fc119b4535632f0ba715b14b7a675e8d68f66718e8619f18c7251a4bb1f618ee8c32ec84db880c59404716acec955941b4918fb8073fefdb6c7652fd6612aed3bc3df7f05290a2a9fcb4374bcc85821a1566ece700b03b9bf537cb5ef46a8fb2e8cefed69e3da3b93bd33c5572c6db4f9f9d77a20a29084cdbbe5fc6451e33e4eabb2a4624bd0991bb9cea573ab26360c5d02df22f508f2f495deab9549fcb9d0b3ab1f00f431adbd15be2e4cc77a904c368b903c72736cc79b80edd93bcddb8f15c4baf3bdc27c9ad663d4da6ea715a4c6af4991614ad911a07f9f3097b4dbe5cd5ec8bde542b5819db07d1db87f934d7b04150cbd4df1b15e5d646f4a1cd11951f575c395444fb4d4b7a6be7954470f8b7383c9130c9b82eea5a06ee23335383c286770712b68808b1839493a06bdf6e05d73423ee81784929fda4207bea76216654cad00827ac1e574d224bf800320ea82345fa6aab6011f3e38216e35afc11a49f25db2edca96005b0e1d9fc4462490cefc5a8ff874dc111a8e4845953781d6eee72f68821cfecb375be8e5a6abd307d8067f6f44ad9cdc6fa1a60c162c5979b5226c6927408219e57f1f1a3709a3877238c37a62314b7ad3573fd58f3d4f798e4407c14529a646a9372ec23bedee89459f185388d57a5aaaf8a3804091b3d6dce02e367f960ac947c10102b4f2d4cb1fb2cf71c612ec97e6fbb8cb2a60c27f7d28e8609725a7e08941b09069389e94866a2b4d8f5ad5243b38409c0f2a3c04670810b97cb66a42906923dba22c6a4bf4bcde76e2325ddca9f526c63614976cd21c1703458106ca95c028ab518a00c53be6af919fe43057319120afa1966ca0ab707f05cfe063f2591f45be184cc3f6940fa99e1a1123091b43a8315b37147d8ac30464976b1a75d2043901fadcef31396560a6d6b63c85a44cb5a61711ee1bfdc65d67db27a72dd5cc96338e535e9537c2df5f361cdee8e971e0eb0dda59799c057b2358214faae323952912fef212a56dd1158377f91ac9a03da0527540b55790c2a26c4ce48acc96d06f36c7cb7aadc91755082474852c5ee3b6da5151247346e521e4ffe0baad8e429ff5ced234cdc370e3b8f5d90872740393a1ed61506ae68c2624e972a2a504d63202b465404ecb91df4ebb6839f907b19aeb380261a3b0da9aa6dde8de6b6db88e7bf45010071f6c38d32e6c75711b4fccb0fe9b1a43cddb36afb5490c45d96a0dec67e373d8aff932c630488eea791088f8c9c8d65234a1d945ee59300f262130a19693708eb91c9381da34c3744133f9950c0cfc39a9bb9bd002616a14bd71f73d167480f6127f4479f4f9c5ea6130422cef1f2a4db04499bbdab8ac4c43e1945f96ea4f6f056c23011013553937aaea4047e71407114d0abbc67aa01487dad4200b781488f06b0d2b40d0d2f73a8dcaac5250ff439c6c5cc6d36a983cdd95a5e4a5a467f70d045501176c5a4ffaf5d4d7ffdd092d65f41c860e7bfd67c35c1e22b647ade6241b063f7185f98497187024fef7182392db77ac84d47d6957e99c507a715cc2dc408c68857ef31eb3162887fd0a92e407248637aa7f725d7fd13297f4d290ce1c97fe39cbc6d60153d4b28f1bd4c7068e620b2703152818b9ffa62ffd3ed5cd3ce7b6523912b94ab15720603c7c9b9cf8bf980b09ad2b5d2e1c0fb07a5cc1942f41df1864d61a7a7d37dba73b192b2beec27d613874dbcc806f7aa1074dc1f61c4cb20ba446456382e80058f6d39fc004e3290b6c3cb18481dba9dd8b82d4de4a474f5ef01e479cc7bc15b8c0fa54a07beaf324453528360371636bdd4e8254ed34326f6987a54a3c64fd0d6874eaa0d0717902a754ac455ba416457a0f1519f403dbea64c88a5c6281b32209ed0fbfce34ac53ba24242de7a9f3cb9514e242127652a95eb19a16a850eeb296a560b66163d61e5d2e46d006ba42c0129bd3aab3eac07b42aea252696d5dcc8ee1b66feba8a5535e32f0e92b0b16bef574904d67bd69f60b327223d13891fdf65dce7ca860177e9c3d82cc00c7a648dabeb1994fb71979d0759739993b6e3c2e2afaba66bd30f8e43d4971e0b37c2f260b9d21dac1f4ffa3634366c854c2c4150db9646bd251185151715bb34a4139a293bb988b8ba76ffa198854e939533dd1537327c0dd384441a58ffd0c473870c88511efc6926d62e19ab6873af86b7db03d2124a5aeb85a209e5be7dcd67c2d44bc38e203b3b5c81bcdec1b110b7ca48d4f3366d58929e194da3a03028dce36aea61f6d124c91224e51d570b3b88244fd3d926992b1639d37d964e527b1e54e202b332aed64c7a797b21382a2f4b825f031ca3827e289035c93cbfefae100c14381c053404d99420256adf2802beb60ba2280ce0ea2118c3ec518bf21c0de627411b62f6459384e41bad37511a17125d6951f750846fd533a10b4383412c44dc30256b7a1fa86d830f9898be4c85f15b4e20905453e893a127b94164f175dfd21589c373fa642ae26437b9993fbacfb8f59b9a30989de2cee1b51b9ca33cd402835ef59f25cbbad5f2e7d38ba48ddc8495afca4cfc1c61407e150b10e632a222d0866b278c7268d820203de0f9f3339f79d5f87e35ca3c43cfbbf5cc385045f7dc246b3a8b9a48c1276d3e3af26cc9bcf5d5f5ea0804e197f7414db5b777fe8af6947855e72c319e7bf71d50181eb545073f750b5c0b393b2eb0503c27db166985522cd328c4fba71110f6deec30264efacaa41289df6e1a266712b2091f27a3525864535636c50010a1945ce021324293369ac0feccca5fa73c447dda427e2d646338ce5151c3ee6c334da2c341fe72a3059333127c5f38c166beed7c6cb2dfcd5bd0f6ba4ac512b64985175455a11d567da62fa621e32558ebe9d53fdfe5ccaac0c6b5140bcec800b77fa7abd3f74d9e6aca3e4282472ec5fc478367b9c047ba7fe3dd1af2945835a0f433f19f53cecf21b9465cb57a8e8d3056b05a1982b23d94a8855c01d4d3aa3901f7cf16859ae2548244dad055859f3d00f7d6eb94459affdbab36dd24d584e011a166c5e472493af7d2cfec126227f27549eb4ce0b354ff0cc871792051a948169d4fa684bda71ae8cbec27ef333cd3b74f8a4135c88a9bc935d6d138546e06fecd0934eafd431fbd955d3f05a326174d54a594fbbc11befb68695b24c3785c3102a70a4f19236cf4c59f71a10bb9be61f7689fe45aed8573a4f070a53824d5ead237531e8d86a5638863a01967f3da985fff8e0e87a103fc01952da64031a28785401596ea8e4f4f6f067ace02f5c79ac58cc9b56770e5bb6f4ee089314a287ce0bbe255a7b5b2f0a135c7a745bf2b77977be9b2b7d146f317100ec089e2521793adc9caee892f6dcf6ea3d5a431fe2a3de27c82aa41d0d2f5d9fafb5e1604905b5f2794fadb376dd42d6014de21a08bbe71cd3981e5fb54f6837c665e0f700596949014a8f1585c56802622aeadee6ed25b1a991fa75bfb1b712d453b1ae9a60198f8bd8cb6ec18cd113c516903ef7c13b64ee54617d5d72c2d70699ddd4b24be5ec9908b59655dfa34a666b4abe4c21ffb56b4ec576973cc9cd8301d9f4dbedc4df977378547d1a8e307907abb3d33bb9d3063ddfe15f4e86b59837f027c481817ade146913c211348362d903666d83656f90d20b318e9b0de6c3d104edc96f4c1874dd4ac79b76f6b97a6743cae4baabdb3881dad81f3f1730b045ceb31079d8ce3f6838a39b515d47c8df3a3e06774d9f6645c3bd7b36074e961a76dfb780c5745cab85b54fccf491ab89205c953210188b71ee67c48a0a77e618181fb17db505866ae8be7b2a96cbbbd940421e1f3e889656966ea87c7142ea1a921cd6fd4df376f1385f16b4ca785f5e0b99000834b904f295b8ca21a416231e76c156a33e2daabfa164b147f754a34195c380e047661a801b1528427c851c635328ff4295f07c4cff539ac0f44ae55768033a57dbdcf3f08d2345f485e8d5eba635dbb69eac108858c7d2b6eeef68fd2d33d1b9dd86afd22e65f466300714cdb13e13494fa80c34fcabbe41ab7b932351f48f5bb03b0732cd71fa09220a9b74e1a746c24f1d8f557e9e97608cc45c40add844685b1eca0a21dfef040bf33e6fbbd2ceac8c49037c865edffd7f749f18ee74b5c5eb34cb2d272f9ebd35dca0dfd7630b9807ae028f9ceed8afd29db163aeff83c1060c328975115f2736c53388a5241f125b099292117e3e03a23113bcf87c849d5e7068b21b4571970d48a1331a9b6793fa57fea2e4523f2a43ff000c8e2ec7dd35a1bddd05f2cd476de2125a2359649542d4b7a038bd412d16ae426159f66be249c9430238edd0e970a20075b4124585e921e58608212fa6067e99fabb835cb35fb46e95b61d6d15b038cdc354ce3b6a880e2c420e1f3a25f6d58d5e23ce76cd6d7632e7e32604bd76858e56172d7541337ff3f7041f161a0c31550d58c330dc1c39da93e885601b9f0dfa6ab3dc44ea8adb6acb68f9ab1d54aa594839f28bba72707c4241ceec5de4d70c2554d0d3f5702b0ed2163f0555ff02120111fa9c6954833397a3f66cb887711ae224a1d1f3bd376a597f05ee1d55f8dc838e3164da3b2fcf15352aafbb175d6a9314b336a07c6b6fce80f6a2cfe24e2e7c97d6e870f81e5ae1c5ed636e7b3a7464043ba7621f930219a23a50b3d923af48a6c2dda31f07cac2c400dc50aa797c5ea728f6ce9f61f4335799a71314d0c38587c7e33bbb4b8ba4d933585f93b71860ddc58163250eafdf2aad1052b2197952b0b046291685ca397a3e0d48e6ca45b608b1297803b7adc85c99239151215f7da526f6f9a5ef2b1ae9b4adecdb3511f7bc98747ce647a3742adf8ffac3d683b216e154b0c1f83b92c2a29e324a59b87c03aad82a104003a95bb6cb91fb58749b5bccfe50dd6fe1595ceef06a706ef70221af834c175eea16603aa81ad966d5144c50c92627f0a076aeab44af91926e6e3b1380e1baddba54b4ee2e89c6e15a346b04e0fcec1cd3f3b0f940ca87486570faba7fd191bda829798b200f310f3a5f26ee4b5258fac3430e317e545bf19740688b7b63396a80fe8111c1efec00e180266a4ce051e53314606d77ac8954c9c345ba9e991d32efe9655b477fd48ca50bddde6fdf778d448f948635c69b2940a29a0abb280fbd870827543705fbd47cd77f82e01156b77a07363649a7655bac7e2bec90604d4407a27fe03b6a46ba8864982c483c85bb57a1bf572eab3010426d62cf80f5b401694581825ea4a337bcb07bac6e465002d4bcbf01dc3732e114048d37b8ace72c5251fef9aa3c74773af2afb87c94348d219ff388834338f0060c5b1340ad11713cfcdd17c5c736afbbb0c3ba68b7fd40880e15e2b7d9fd2cf2a73897316dab7cb4fda38992ef5cb4f02b42d99589a79e40c0140694d4f1bc137ec12d3081b557bc30d3938d6fadfc0534b3784c79ce349539cc93a87ad721290ac2c9a7d92f11d56609ea4a673fbaea226934beb2a606aadcaf03b2628a84b5301607aa133e8924beb9cc337acff279e6b79aca20d596383d571df7c2eb0948984068113b669ca11cbf58f7b7d2a59db259b366839172fb716a6ce014a02eddb6e691a2838bff79ef2e5f99219b189f3da60f74832331a6e1f350b23b523a0575d74cfbad9245ba99967c4c86839f79e53b409920e213c46efffbd86fe7880b24d5a2c5bd89dd3813592371806abcd32408b158f5abe6b3e39b5a9a2b184aa2234fabb520786eb4a77198f9b9d0e53fc796c66e708b96820d16e904efab9c895a7f6523f03357a3b5a81ee88fde64950bea89233df8bbe5dc95216eb439e91d3581d8e91c84800b3a88ddf188a2a70e08b6b0805fe58d99171a18c10f40598302607f8a51e51360f2da587344fdc3a060da1d02822842428dd8848d2aec8c3e80e0f14e0cb756ab1dd25bf1ad68488e8521e7bb78202c3c27c6e8087bd6d203ab524c2b97bad60f76917d810effd35cfef3e10edb7f26d649363056011986e4d778d5cb754e83b89c79dc19325d414b3c8428e54a09a780463e4d5bf1b66d5fd5bfcb9fa7fcce75465e505cc5d157f783abad2fd4ff355ff3c4966722b61632b57cf492311b30108c039921ce56a7e0a0cf0217267f647a046c8069674f99ab2af882ce1c4fed3aaaef1d15823538744b5a816964b49d1f5225c7d998a5644f6ceeb9f52ae06d391bf8f02ad6a54387cc4ea1ebc8ec4df5d9484c5ce8fe9c086abacef26d95ba287d528e99478f27c9cdb86b09c036e100df06dea8d4f194508ee8717fe04e8d50d1c6c0026378eb4dd6cf9c4ff45866a20c5543724d964485edceec206ff300c11a47b9577ede8264fac93fddafd1deaec343abd20969cef4957c12e74710212e55c19f03f49603a43ffddbc22ff2152bd650203117fda6351bff6fef0c5aadeaf54a8035f979ff4a34bc95edd0aa77e501d232cbc40e0b6620ee610e6cc0891fe39060902a8c986d8f7a80dfb500aa9732c059b44357351386b7abdc0f9228a32a5481e2f7150a78ff41fabd20fa235182f4a3f9552d0b1bd121b7239fe178684f8fcf86a564d19fdef2a87f1c171421492d950acd74a9c1d2da8a2d8af3bd1273f17a85ebbc040b33631126535a16c41ececb7027e174ce4d7df3c1066dbb5c43f1a63f2788d48346e747d9b9027bb1ad062a8ec86a8c90ded49ba6823ddd37ba5d2f483540984c5eb8974064f2e0a4fe87c44b285f51b1d01cd9f70b88ac7125553c869c392c06027d542d2d3ae9a071b85012ffc1ed1384b4b2997353a1896fd903a85d4bd69b24255f904bd66fe5d3299e75336e1f7ec56ddcbe96a2fbca5b4b7b75452b2837fbcef6b7f6f38700950c98637b7e403322efff5761e81a957625b2dd8432f0552128a0a3c9ae363811c7c36cd9b05b0802cf85d8ad778f33f9ea1bc0bd42c140ccc3db8a2469841524653c2f33ceb9aab90b9a3b0f7c3f6179a6f0b4e96439bdcbe41a298c83bf3c9c99858e7122f587dd2cffe0d0ddcf0e3233d5e11ce7c3e599c80528937055601264f954282ad7c0457f712807ecbd0bce34aec9ccea2478d5fdeea594d2f660c0e04ddb70151b073de7021ae03102e383e165f2f4925ea18f964e5c174d0cdd70788c37d7fb92edeb9dda61ecbd8fc802f87ccfd7f168013440b8859af5608a6d29feca64b1d62c1ef12bdb54270cb0ce92495eb7b7f06a28536a201eaa1b1624045f825d8f0816073285fefcbc3d272ba21638ef7df0ef5531a1208039a58148de6b85aee3d087850ec51b4430627268b25cb3496410bc7fbab996f41e91349f3c334aaf4b4e20d049c1762dc538d2c31b2dc2eaa4c42da030365ac370658edba5a219e3b1ec2fcf7ddd3f844f77ed223e9526986038f13c73969c50898b018fb32e517f3a59e462a03367dd235cc829280be9c9bd85cd59dc8f78a6cf0c1dfed7223ecf96d0f162b9c2ee3b1d04b0315f2533621e2761c29111d60bee36bac820984efedf06b646daa8260129e3e80c5900961712098ee17030f6fe0ee2c50d458f45b9b96496a69d0ac1bf7299f911176aca195e596a22f7f0da1439c47798c7dc3f345634ce4d69b109e30f028200174e00a7166edfe710630681c64a2baf4494bd205278723c3d079c40c4a601c4ef853519e35aaec5060baa44553231f9abdbcdff430822d7cb781330b1eb5a24b50f37089555910c84a8563bd5914b6f793052a43b237b391f0b1bf15a8e85386fad3c7b1589dad22d47b24d13aa998aa022caceefcfcc00b5084eea7001dba7ea19ea3f322d1747527765a3be17a480e8c3400ca6a20ce8514a33c0db86757908470b3c3d3cae11f0facfa59b09edea94a319d08f28b06234c30ae66bafbdb441198c9eb16c6da1ba8d5e8c499280a6d6fd1a9dd53751a02b80156ad6292474e90ab9b78e2a81123d47ac59c7a719711c7d48ede709754ac159c43b7a6265ea198d0ae99dca6d6b5fa5fb4763db5b5d0b20e34069f01e4cf0f97635f3cc41d9ae1706d05214de9541d3b26afba36f130850bcf880259efd6f1248b8b6a3f0213c4cc435d87d9fc701d8c6c688e8e5c72341ff9b37cd2e67e9462465f3a416baa2f7d4d017bd90f3e1d10cad35056bd7200802f380e8fab00623482103b284f8dd851422da656110652b44e7bca251b79e6751b989eff01939c9181da8e8f77b597ce76ae68f74353f4ed3134d1c8dd00cbefe539e90f40f496bfe60856e1753ccb9228f746017b1dac1b07c0c49b1bf320f8c6e06112d536944d74dac4f0dd3a92a304ed900353be6560935e84aea41f75960495e20215e7baab62c50af6e9fd82282620225b870cb03c533b096d50ba1da31fa6b80dea1f0d1528903423baeb3c531280d9604080e3478486ef3d8ee7751e247b64fe54982faf6bc648219e902815551160a9199ed17afc5575284870bb57f21b77b20df02e26946212d69b3667f479377a6e8505836b26c8dd4df0831c7a28c78039d7788a488353387af3e9b3a4e583c2fe98cdaf7138cd59c692e87cf15b1928862ebe44bdc2b0e8a0ec6abe9c2cf514476303633d062d31a15731db587361a4cf87cfd8e58eb8fb47055b4cbe911f0214b5a61c02904d05bd991aedf0852ce4718a4310de019e8cb61065d36907b5ca305b7ad5ad0f98dc712e13ee3db7702859b8faaf2ae7ee7706e9c0301c835329e0d12a9d0693d5a925d99ca35c3644033e738356efcaba92f7dde5304fbfacdb9fcf25d9b1dc3f523310308fc594fe7968c37cec528e399845bc0e10646dec2c0c88b2dfb7652406a5f705f15087878079f1594cdca2287d66b8e0980f8cc04078becb553861120163bcc429222ecbd167131cc6239bb79b39f610834b1bee700181b83835d39dfa7945f4c099527b6ce349d56a355e4425440a6bd321d244da26c8b951129cb179bc5e2f0fb7ccf47a604c68c7395f2057bb41c60a060d4a3c78a392b4762a1263a013d093ec742e3928358e4cc79108b82bc0ba35899ebd3f14accffd976955f100404bf879326166705599628f16a4c241633350847c5824661da56429cedb596389a17b94d776fa0c82ee5c94bf530f548c94c54ad9634f4716adc8a10e6205445639b752170d6a6e464d55a1a29a6a6dfbe2943a473fc6db18f52b7e21ca3ead340eced0ad44336c739a7df6f38604d20c946a72782cd1c8150c99a257df04889492a9eb0de707a562f01c4c63d418f57776cfb31178bb49c4e116bcf331656b56dd766c3ae262b4218149e69ceeaaf98fbd5b84877eceab20694f2813f395c3ec6857b069b315f404bca101556f10c527a91e85f2aacdf400faf80be72e2c70e6bf7a926b90344f9865575101b13ace7aa89b3237a9bd6233815a24536b3e7aca183351c84544814ecc84e7e888e63fd7a69d3244a9d17821b52ec3720c5f61c50c164828fb80a05c1466f4a83ec18a9927b8ece09a9092dfd4c3820b7dbbb115f642c824db2dae069bd0cdc2b842ef5aff43d164c69acd52524d2d8885dddcef97e78630f581b8ce56c5517d2afa7cfb3eaf250ecf06b07a2b2738098c32c8c56da54af734254935438e8187300649613f67d80b9cbb645bf7526e2b6291197b6c0e24c37fb2078d96645f6e8929b56ae239d4dad6e0f58db031bcfad9af26e0169c5fcd38cf652dbff34dbff9782b786e44fef39533e131d81e614bc998822d0f86391fc07fdf7e7256089a022893558c587938d8bf3d313d01f5ccf35e8efc734ba685cb32297bee0b74a889cfbd245ab94f20331238d28c45a8ff84f6dee832e9cf7038285427d018da6ff2d02ce80d943b2137c9330440611675e61c9831967f2581e8d36a8eb2201aa2efb20d5ca7c8f881fe04ab10d063784da35e355f1aa5f996a69478d5edf0022aae8a92af0fed3ed4ce1267cfc55984691bbc0ce29c65ff20a1d33be187aa258db43740cb763a956b63ddf92edec7a3a2aea48c444f3abf8cbbe61f6802c10db16ab33cd9557eea49aa9664be757e68ed8298d22caeec987aa46e530bde1bc3a757a090e51dba1a123a33bea06e91eac9a272da8939834cee0279a416d6d179d4f738957f5df9f1c1b1e6d0b7f190d0bc7d9e9a657ab285376daee013dc40ee9ebe238d3922bfa98270c81cb2d25ac20d1dff33bbf0c971330fb8dbb0a8847eb2cbe8c92b8f367d1e467c79d6204c8cae9dfe2f8bafafd9001935eba2b13a0ac60be9fef87f759fb4f410e5a3eafeeaff2cbea16975cf011a3cbc65b04ef03e2a88aeee36eed8d68beeddf2256898bf276f355191af6f49c4d0d30f776ffefd1f83b3feb6291d9a7a0889c1a55c160821780680a674dea39ee8e869a4c76eb5028e66d4acd1688e5a1b24f0f76f5303c7663d949fc8fd3f2a639d4cf29984dcd73bdf8b7cdb6a079d21eb4fbd4b9053d80fb0f21aa642f2b59cfa25b69ee2a9bb2141217b6ef18e406f78bbf2e6450497e25a78ca386717655220683ccc510737b3e2c74a6c1ccc89af045dd72d09d44c31019f6661846950ae9e478b836d6697d5b6487e7b057505ee1758b6da89ef86f62cbafd3786a5e34bd77e84aea98c534bc341a4d81b31d168a8eadaa1d7d5f1af925f8c4cca6c332c71ecf06c858995fdc8b6ebab992e957238eb9e20cd0616d6c35556ed6c32843684801024a73def2b24653a3bd883307671092a6adab4dad92a84c7f08f2fc001b269ceccd0d25f2ff47893bbd6d58f42ef095042431b82eefd7ad159b97213c16dec1d43c0b192afa57400d7850b075f119fea572eeef34e6a2df6a1ac261b65e7d96b4c1bede1bb848382ba80d2321135c86afcec9b649f0d93fe5375072a1d81f9a7f8350cef788350fdfcf534f2d816211e5140184d18c882bb41219b091b10cbd6f4a839e8c88519b3c87f0dcda8c4dfaa65a43d0fc88cd63e0cf414d8f00800d6a9e88fbe438d335b721bc2676ce9b0a33488375d9eaca288751b8a5067dc9be91db770f96139c65806ffc89061ca835083172de3998218e47951c6245ce6fbfe85b35a8cca9df96e9ec2eca286483c9f4be6320bf08740831fbb9e6444c06eac83d713e2895840a3633df9b0c027323f761ac9d3dd085a0259afc7e2a39e5e42e22eca0b15e4bf028416bd5a15c37dbe4f502c280ce0a730c8fb5a5806e400da1bccbe5cc990d9148c18c07aa2b50c9708a6e90e7bd0cfe68a4e05cc8fba63e9da9c90d554032ce654930bd08b34b8cadaefe3b62f7b8711d8567b42e28a45c6447ff95abb794502ea1580fc3ad7f73ebf6b6b43f21455729892be8e7f3ce997055489396133a6d77e47aee92201edd8cf9b91a9b98f18bdcf8212c7824adc992aaf7eaea3edbeaa507e8a8f0034e1a0639085efc20d58a467779fd51176de18c157fb3afc3ebe95a10d9067d6d11c0f2e8b1d2ecebca9a3c365370e2c391073d9b995ad11cd0d3eaa255690718aed83de37e96f5c6d6b7d50466824daa3535fbadaf491c9f5d07a59f6470a1b9ae5d975af2c4aab685bed1e72b5d88c8992cd0348d4ede4851cfc2c806ad1fd13362993bb456090a9eb2929726474f60537948a14d04b715e696ce19585aac8ba4d1ccff99f856047c61343a3548facfce9048c8eeef45b82e7138da3222b738721f7e71841f9d7290e8197b4ca1a8d03f0dbe5856105762765d72b24e3ec2e018f0d8090225231d668f392f9ca6c72de3df489b50a207c2c970d1f2e352495be02240b0cb413b4156cbb94599b0f433648fa9ff23da89d7d413d988eb19cecd14de8f18fac6337b572377b785dd1107aad33c727fac5d6228c3a2c769757da3cb196c63c59c00061dcb50040e6c7e82501b234a07954e3cbd2bc2b92259544c62c42aa57f783ef07766e4a2ad1122cc7f9ac6832f973e553088ba4cb309fbdf0234ba3190d747b2fb3e05abe8f283e226d1edb96dc4d4fb9278f5117c38020905165a334a5f392c96a50161691e428451d39a00fffa4846655cb1513f3abb2cce6229bf06187b6dced7c65b232818dd76813cfe1070bca4f82b6d7b9ce2f45fd1683914269f8cff9aec7f7875372b262fe16b59cb229804db6affd59551b186134ad8f64be6421203ab65166ab40d7b2b2dd62f4d716c33287ac48841d05c706755e019db9c3636a26190bee8b12297ec5f9a29cf6309befb8e9d82d368535b090b2c0486481a8a8f1fae606432723050a6e78b1eef00ebce905c3e026dcc4b9910e3d41a5a0835eaf31dd56c49b3cf1381f967e44946049139c8f40134ccedbb2cc977df90a0214ba2a5eea202efbdd23456f1b6305fa8857fab5e80868857899d599bfe9a5364d24a2d17126dddbd2443c558b08d02cfcb9c91f92af604d7702bcdd48b349b7a55419822fe284134111cf1cd4256c2a3ddd454bba701018dbddaa74264438069bd09075b6f933350e9cdba6129fe34c96193771c1225202d722ceb54da4d8250b19e749795f96d95dbb18e9a495224e9aa30fb4cfcb348fa48ab72e9a6cc767aa486f238d1cc86f94faa51afdac97be20c946b0c8082c423e6043c97062de426bb538a59deeef525db654e9cb2e3e6b3b71f1c8fa0a0b0d0fce2f698be2af72c8294225787ab56fe4b9b0a8028c05a5ae75f72313564ec2d27e96272b681813818d27df9c1badc72c4f3bfc095943d9b4ca52596ad8c2243275f65ccb4335067f05dce263e0b30832c3bde5be8232a1b719a7e8453a82a73aa475c43f467c41d0cffb53c296e138a6a1e3dca33638ab7662a4db565801942fac442b4fb49293ddf444927f4f4ed59a9bf53b8c7524b0991697c9b64668f1c6a2201621e8c3c389ca705437cf6ba0103512ee9c24d631b8cfbcdeeb992ef82f25de86d4fbef78b7153ea90034f250c3f7f0f95a996e4df2f3c777b1c8773de0e26906f4ac45e9fb7d3cd2de502b100fb4910705d9346e2ef615225d6ae2be3fd42409775c4b4e9039617fb1f03761ef7a0736bfc6f79d54c728caba2f1c06116106dc051dfc0089f9c5c67359d87ded23dae5f4684762c1135c09a563fdfbba81a13d5c0f8168e78653d57fdfab6630aab9277e03ecefcb90c94f26fbeab21992c2d6c4e5ff809b473a2c82ae10c7d1029dcf2d7a8d2ef7a8653b075cb200264577798748a4f34b77f0cb83e5b103ce9086ee8063154d443a459054c0fd2f2193a0911c6a7d86c8d27d5b07771e2cb4c2a7afe783484e5461eda95c985a59773f56efe1f4355863f895c41c01ba14c89337e7a14a76cb2a6741a5ff51620aaaeb37f3a66feb9e99257c27ed5a1e918d6060d0455cedb9e218e77e095b71d0b8f735229fe234ca5b0b8f0548093f3989ae52ada5375194bc3ed8780571d8992e265267e1ee6e2cda9e4db937cb0109eca6a69cfccb3f945f0f3198eb8ef6e62bfbbedc512849fc0d3e1b1994a299c4c9c904f9f8dbce286b65c4a8c679c22993673e2a088d7728490ab296a4ac092a9dd3c422c9a06f17bbfe262007c416f55aefa451887833595c6f72e43d4f990c3c19d5423bda67b47b1d355cd369a8574ad7bd9553bba778d7a66d3f309e50e806bb53bd2244cd029aac489c006a11fb7fec0061e84b482c1625114cfe1f50ff3b96094daec5b504f8101cbb87c79178b16256cbcf2571ffd87437baa79fb266c16a7f5ddeed7f0b2914b7e9a58a8ea52ea8f8a83ec7573a7bac17444daee59e7cceae28dcc5e16815ff1a3165c843d73928781f3863120c078f0d52b3fdeadc7308092b57e3c5bba93de1b02422c64b80e38c6fec22414241a159412846eeb9cd3faa1d891b00ec86636874cc371bf1e8c46030d3e835c99f4438fcbe9f92e60b8b15df5f18b1c4e452c289ed62682686fe184815d8f440180abb3afaa4e9eaa2dd5f6a39e8d744d92cbbd2ba86b3a093c50ba3fc6dc31c73744a765ef2fee3827fb7222170d06a3b51ff55d0cf6f60f0a6d24649562d96c346647d806cc135c5f1ab256e7cf412578cc939001c02cd73a7a283d8a37fb5015bdd25082be9cf10d2112570f26095639b19a082cca4ec2f4342dab1af5d8798f662b46d15d525254ce1d3697744e03225525797c499347c57e461241a955a1dce6233978b7ea63240b4a03b960a3e5d2ff52cc9a486698bdb1776faca0eec2a7280a59e7b0de5f40a3c90d3092e190960011cb2a46a25891ed226876cda17fe810743043d4e22d6a549b9e157457591e17c097bc7b95b71b183e5c8cc7d16944056eea32f9bf2f7564e710416d520e725659b7ee510f01b72ba53fab42fb3b35a805b37a5666522b52ca1b5c9d1433f66ef56b31b0fefbfee1da9c8ace415431af4940e87eb08234c9249f34eac55f649b85ac50fb90343bd4cb961158a9ccf9e1cf461f44d6b888a3d9cbfaff163c6dbf75ca00eee46a6342e89f8bb15433255e681287c06e0e20761d9f49cf1ee64c0a18210f66308dc00ee78ef4917bb476c2e8a36bd28cad81c66485114e829bca53d0bab6c1a37d9ebf9d9091cc6971f9dd5462684b1fec1ee50802ee2c8f7759fa636e0283a6efc5eee7e3e2805b7b2a03c8176fe7a1017280670e7cc477ce0e53e6b7e4b0f7a9fdbec233b59e9ce08d4d1e282597c259687dcdfe621a5948c2c4f96464a5c4cb9e02fdd20fd8a4aba9338d1d44c323e23b86844d8ebcc73386be2415f1c3f7f0a282aba16c01692c3204b54cf37952c7355155deacbbea8824a035831ea1e7463f5ec36dd98d12b933bf26d75763443ee8b5d3fb5e6810714100d1d9038e91e776c182cf8598c5eb2a6a3647f1935ac0988e57d044244c5eb9cb2c828f7b835cc99c256766e7c3449000ca4e7ae84d4f10e8ee6ae16bee8bc7db25eaea09cd02582bd0cf6545a55ebd946471d1e8200f7fc9d84fd5dc0c1a90f94b49c4d358f134566f3be7e3e33425e67f42ce30829a568c68ef902086d8a728cfec245a0f4ad5cace394e6c0bd713f0c9c3a13a15b06654ab438403dac6b99a0bc97945210e470c46b93b2bc19bf9fc7aebf0a378ad8a7f7a3bdf7209d81dae96f915c1d5c113437c0bac29ba79d3f84048197ce31647ac1584c1c85a09a5c334dd2544b98a74e23c1712bd835ae87135dc05718b2176e25d3f8f0078be87b4c71d26c9e11473db2ed0528ce6d40bb7e2182b689755d2f7267c7337abb9057d224e893649b8263ef71fd4df77296e616f80fa26ee9fdf49c46a04e42fc1b6e0dc60b64c77f05375f69c59870479f4ebf28d733671099b186182a1e963c360747eb0336be9c8bdd6049a835f720af24289e71304f81675b95a354e7039faaefaa958cf76958222bb082201f9364bcd2b932f8652c45fddbebe6f2a8647d0c83816bb9f0f561d7e36ac844069eb958d98322f3d6671ea64f8beedd37a1f477d75f0841fc3429fc7fff908fe71f31df521823c514111838a60bc538cffbab5941638a863011d0131a88e59ddb32d1947a89909d0e77bc13b8f5f5804cce1efe6a48ac4555fd9fe4b57c5b410649a9c22341c9915db60f0bc39905f9aac1a9fc454a1e518fece83747fe8ae2914f2a21173829ce5ed296336ab3a74aed128c3642f55df5164066df0cde03237b16b3e0ef7a35aeb28d9e80ed9af049ac7a2198984e9edff4d7cff077c06e8d8a984017cb5cd40b70fe990650513489d5742747c13d878d0e435705a959dda01b70841887956ce190b3d50a6f4111c6db59b36e9cfc7d11f265fe00e8e0e6e735dc78232c2c2fb1aef7699e67566f583ec3579a173223268340c088af3efc490dc4efb12e6c205edf56eeac6b24137f2e07eb90233c181a71495d677fc1c3105931a5fdea166dfe296e0554f3c297db7dec33d00f72a753b7b209301755470e3736fed8a9ec8138d8686cff1f9901dba3134af948a40a3a6e18fbd57b94864dbf86de351c65443ee6c1d7af31a81f332d7557bc09fe8ff0f73a8e5f2258b445a881eb2e9ea16c547feb7b596e6a496cdc44446c740727bf5e391c10aa6a1ba81a3f5e7264aa2e8f71a07db750349f2e03411a121199092662147e62273c0abb8e8ba7fb8fbe45740b5805282eecaf6cc258740e027d2c4b3f0961388e3c0355df99f8a737d66d74e66c5ef1195da1186aeb8dada6138acbd492a817fb4686bc4627c2fcb652d392015fe1622adb510527dc9cc74301ccb5906584d31d3e6c83c07d239958cd165b92c9644a063e178feaee81d48d8091e49339895c4becd68badad10373584a81b7dc79f64333544cc00b43fc3cd8afa554446f32ef5944195d9cdaa55eb6e6828f635e5cece34b576a9490a14d5ced2046ad90f2bee023ac998995cbd4ef1c7dca67b122ecf9fed15ae8c31f8ac9d5f57d3af6e26715ae0ab3be052175a8e95766dce1915122d57e8630b229a0f6aafc3093bbb4d82e2998f961d26ec32935c3fd7e433a9819d708c732641790a57f1d98258e0f2b8d95f2dda33aed9d2a6320662aa502fca75ef9472ef8130753c13f031f57235a3c7f256cb717b18b77d39f46ced8ae9e352433d79beb0fa0c829cdec669cf0592344f7de51001d4e5c31ebaa912c6ebdba2636a8ff1157d93467e891d831b50816a9b90233c047b4c02f8f878b3b76922883c1c5afe890fbec209a949ffa634f8f930f5c9bb3af965af358b2db620ded7a99587b3487c641e3cd107a12370edbc5628ce95da79f6215a3c7540f5d150ae924bae021f93497513d3777fdd50bf5af2df3715af7e8325c8dc2cd42df343dd7afbf979c033ee04459763910baf72d3983a3f8c77d33254de2eceede699416b7259a24013493f26da1bd4505a1019bb8af425ef604c0c5f9cf5a2b6d9a6e32a0357efe2f29b6b418e2295bcd1e23d93100126991abe05586b07709343552e9ec29ee119c8e58039f3beaf4e461e01429a96d58fc48e01720691510f9bc7c41c93c451007b8014cb336163284e7450e32f6981cb71621089bfb66f3c2b913bb06c8660fc974bcf3ddc358517cc872f882268f0a2bce93a89d232d47f6ad5a8a3aed44a5b8f83b98a8bae1ba9a8e1d548d28df1d01006215d320b3a2ff1d7ae6c16d067c667d074e458b83991c481a61ffcc4ea2d1507adbd8f213674bc4fb33c756d1c021679de8673592b455b02c565cb868fa3376242b7db41f11305727dd8b2640c6103b0a4a0fdd8a70b1c3ad809a9fb01ac9ca4cd12555f469d3b6434029bcc8e6f91a5c50331043bced4b194b0fdd01121c7b5783abd04681450f25e972e4e079f32dabcca0702f67c03abdab3ada77ab28b453fb6b79475a910a8386912813705556abccadae411ca8e5ded8c35dc2d9fbac51bb47eb339119aae9663372a11a450d90c8e57d6fb7d1d9a156245f23aab3f41810f106de8d6081fa56516ddffe2d2edb71770904ca6fb9b278bd70edce9d942db978010d66abe481fd96be5a0fbb9d40c19a9433c91e2a29ffbcaefd66d23a279aeac2b2254385c7c9fa7b0a5cd09a61129da82b7f10 \ No newline at end of file diff --git a/src/06/help.js b/src/06/help.js deleted file mode 100644 index 82f8748..0000000 --- a/src/06/help.js +++ /dev/null @@ -1,124 +0,0 @@ -Object.defineProperties(Array.prototype, { - sum: { - value: function () { - return this.map(Number).reduce((p, a) => p + a, 0); - }, - }, - sortf: { - value: function () { - return this.sort((a, b) => a - b); - }, - }, - prod: { - value: function () { - return this.map(Number).reduce((p, a) => p * a, 1); - }, - }, - rotate: { - value: function (n) { - n = n % this.length; - while (this.length && n < 0) n += this.length; - this.push.apply(this, this.splice(0, n)); - return this; - }, - }, - firstn: { - value: function (n) { - return n >= 0 ? this.sort((a, b) => b - a).slice(0, n) : []; - }, - }, - occur: { - value: function () { - return this.reduce((acc, curr) => { - acc[curr] = acc[curr] + 1 || 1; - return acc; - }, {}); - }, - }, -}); -Number.prototype.mod = function (n) { - return ((this % n) + n) % n; -}; - -const input = require("fs") - .readFileSync(`${String(__dirname).replace(/\\/g, "/")}/input.txt`, "utf8") - .replace(/\r/g, ""); - -const dirs = [ - [-1, 0], - [0, 1], - [1, 0], - [0, -1], -]; -const grid = input.split("\n").map((e) => e.split("")); -let startpos = [-1, -1]; -let startdir = 0; -for (let i = 0; i < grid.length; i++) { - for (let j = 0; j < grid[i].length; j++) { - if (grid[i][j] == "^") { - startpos = [i, j]; - grid[i][j] = "."; - break; - } - } - if (startpos[0] !== -1) break; -} -let pos = [...startpos]; -let dir = startdir; - -visited = new Set(); -visited.add(`${pos[0]},${pos[1]}`); -const turnRight = (d) => { - return (d + 1) % 4; -}; -const ingrid = (row, col) => - row >= 0 && row < grid.length && col >= 0 && col < grid[0].length; - -while (true) { - let nextpos = [pos[0] + dirs[dir][0], pos[1] + dirs[dir][1]]; - if (!ingrid(nextpos[0], nextpos[1])) { - break; - } - if (grid[nextpos[0]][nextpos[1]] === "#") { - dir++; - dir %= 4; - } else { - pos = [nextpos[0], nextpos[1]]; - visited.add(`${pos[0]},${pos[1]}`); - } -} - -console.log(visited.size); - -let loops = (obs) => { - let temp = grid.map((e) => e.map((e) => e)); - temp[obs[0]][obs[1]] = "#"; - let pos = [...startpos]; - let dir = startdir; - let visited = new Set(); - while (true) { - let state = `${pos[0]},${pos[1]},${dirs[dir][0]},${dirs[dir][1]}`; - if (visited.has(state)) return true; - visited.add(state); - let nextpos = [pos[0] + dirs[dir][0], pos[1] + dirs[dir][1]]; - if (!ingrid(nextpos[0], nextpos[1])) return false; - if (temp[nextpos[0]][nextpos[1]] == "#") { - dir++; - dir %= 4; - } else { - pos = [nextpos[0], nextpos[1]]; - } - } -}; -let loopPositions = 0; -for (let i = 0; i < grid.length; i++) { - for (let j = 0; j < grid[0].length; j++) { - if (!visited.has(`${i},${j}`)) continue; - if (grid[i][j] == "#") continue; - if (i == startpos[0] && j == startpos[1]) continue; - if (loops([i, j])) { - loopPositions++; - } - } -} -console.log(loopPositions); //2.116s :( diff --git a/src/06/input.test.ts b/src/06/input.test.ts new file mode 100644 index 0000000..3741538 --- /dev/null +++ b/src/06/input.test.ts @@ -0,0 +1,14 @@ +import { assertEquals } from "@std/assert"; +import { main } from "./main.ts"; + +const target = "input"; + +Deno.test(`correct position count for ${target}`, async () => { + const result = await main(target); + assertEquals(result.positionCount, 5312); +}); + +Deno.test(`correct loop count for ${target}`, async () => { + const result = await main(target); + assertEquals(result.loopCount, 1748); +}); diff --git a/src/06/test.ts b/src/06/test.ts index 949b288..238068e 100644 --- a/src/06/test.ts +++ b/src/06/test.ts @@ -1,12 +1,14 @@ import { assertEquals } from "@std/assert"; import { main } from "./main.ts"; -Deno.test("correct position count for sample", async () => { - const result = await main("sample"); +const target = "sample"; + +Deno.test(`correct position count for ${target}`, async () => { + const result = await main(target); assertEquals(result.positionCount, 41); }); -Deno.test("correct loop count for sample", async () => { - const result = await main("sample"); +Deno.test(`correct loop count for ${target}`, async () => { + const result = await main(target); assertEquals(result.loopCount, 6); }); diff --git a/src/encrypt.ts b/src/encrypt.ts new file mode 100644 index 0000000..7532313 --- /dev/null +++ b/src/encrypt.ts @@ -0,0 +1,108 @@ +import "@std/dotenv/load"; +import { parseArgs } from "@std/cli/parse-args"; +import { crypto } from "@std/crypto/crypto"; +import { decodeHex, encodeHex } from "@std/encoding/hex"; + +const flags = parseArgs(Deno.args, { + boolean: ["decrypt"], + string: ["get"], +}); + +if (flags.decrypt && flags.get) { + throw new Error("Cannot provide both --decrypt and --get flags"); +} + +const keyString = Deno.env.get("INPUT_KEY"); +if (!keyString) { + throw new Error("Missing INPUT_KEY environment variable"); +} + +const encoder = new TextEncoder(); +const key = await crypto.subtle.importKey( + "raw", + new Uint8Array( + await crypto.subtle.digest("SHA-256", encoder.encode(keyString)), + ).slice(0, 16), + "AES-GCM", + true, + ["encrypt", "decrypt"], +); + +const srcDirPath = `${new URL(".", import.meta.url).pathname}`; + +if (flags.decrypt) { + console.log("Decrypting all enput.txt files..."); + for await (const dirEntry of Deno.readDir(srcDirPath)) { + if (dirEntry.isDirectory && dirEntry.name.match(/^\d{2}$/)) { + const targetDirPath = `${srcDirPath}${dirEntry.name}/`; + const enputPath = `${targetDirPath}enput.txt`; + + let enput = ""; + try { + enput = await Deno.readTextFile(enputPath); + } catch { + continue; + } + const [iv, encrypted] = enput.split("\n"); + const decrypted = await crypto.subtle.decrypt( + { name: "AES-GCM", iv: Uint8Array.from(iv.split(",").map(Number)) }, + key, + decodeHex(encrypted), + ); + + const decoder = new TextDecoder(); + await Deno.writeTextFile( + `${targetDirPath}input.txt`, + decoder.decode(decrypted), + ); + } + } + + console.log("Done."); + Deno.exit(); +} + +if (!flags.get) { + throw new Error("Must provide either --decrypt or --get flag"); +} + +if (!flags.get.match(/^\d{2}$/)) { + throw new Error("--get flag must be a two-digit number"); +} + +const aocSession = Deno.env.get("AOC_SESSION"); +if (!aocSession) { + throw new Error("Missing AOC_SESSION environment variable"); +} + +console.log(`Fetching input for day ${flags.get}...`); + +const headers = new Headers(); +headers.append("Cookie", `session=${aocSession}`); +const input = await fetch( + `https://adventofcode.com/2024/day/${Number(flags.get)}/input`, + { + headers, + }, +); +const text = await input.text(); + +await Deno.writeTextFile(`${srcDirPath}${flags.get}/input.txt`, text); + +console.log(`Encrypting input for day ${flags.get}...`); + +const iv = crypto.getRandomValues(new Uint8Array(12)); +const encrypted = encodeHex( + await crypto.subtle.encrypt( + { name: "AES-GCM", iv }, + key, + encoder.encode(text), + ), +); + +await Deno.writeTextFile( + `${srcDirPath}${flags.get}/enput.txt`, + `${iv}\n${encrypted}`, +); + +console.log("Done.");