diff --git a/.agents/skills/atlas/assets/seed/catalog.json b/.agents/skills/atlas/assets/seed/catalog.json index 482b95489..1b4569c77 100644 --- a/.agents/skills/atlas/assets/seed/catalog.json +++ b/.agents/skills/atlas/assets/seed/catalog.json @@ -1 +1 @@ -{"records":["000ada42299601fba29016e5c0e0d4012876fb42670bb10fa0b1315477254ba4","003893cc49855d17a15295d7adbe57ee301ea20281dff216461baee0810853ff","0052dfb9eafceabaa590f4497e4d42f19020718c84b981d265edefd432ccf8dd","00641d046d6869fdd0023ab3df99e0e67a6ea28f0dcb701f622b1cec8b3e07c6","0066d4a624c02398f21b4d7a736a9fb5101ed8b6b13ceeab46907e9401af98ff","026a241141ee10eb829aa6ce461969242d5c1d45fe9ca19f08ef4ea880877676","026b08fb343aefe19177e95b759560d340d372def4b71acf613fefee3438ade2","0357495d23fac4fad210b6dd7ed7cc57dd33d107e1659a81f085cad78300797f","036c148f6d0e89858c9bf4cf380272ca6904bb4ca277a909fb71c47f5450cef7","04652cbc95ac4dcd21b837b38f2ca5a0ccd4d0946bc13fdb31c9c15a578d3a2d","04d17203f03279980862496517a1f0861be5f6cc8063bfbf92f8f8ac19744fdd","04e404d89dca295564813149472b1de8e6c43357e2f6d91d169ded7600ed3a02","0509e5c6fdbd2dde0c0db8558647080560714804d00e4f9268342f2e84858a3d","06ad2c8aa0ff3b862edf3ba99e0e4e8801ee163709e66333cd06c3fc61232b05","076259a45e71df780b012d29618c17739246c86321d2ff05a6c272bcca8db675","076fa091c878b19cf56a94be0966dbcd58d52c1839f9d4b85bbfdef650cbdb88","08b3dc660b9d2bbbe75b590b2b86d941bf935a254cd5f09de71ee6894f4048b6","09e90ad705af012a8c36efbf296757f35adf9c9ce3b8908791c75d72c192973f","0a6d7dc5b64970bfdadc9049ace95e8bc163fc421beea70129ff0eaa692c6d06","0a862ee40916522f8ae5f14b3e084bf5f2e6488185583346db96ced16ce7619e","0a9df276d42b56d98a7802befc2404204e0e5ee8bc7f5c032f7bb29aa4ae2091","0ad4403c8f4078dbfa543310c69bd1dfc768e305987214ffc37d7b2600c4687c","0b2d1557ff6df5f4d65d540a5403b07ba81b381dfc799b7884ac72dfa6ee7753","0c22360d4653eb0f450e4d3d34564875f1660cfcb2d546095d98b3faa3967cbc","0c7d3f36e3bb4270edbf7abd99cd2dab772df274cad1c27c7e87e302b8eb1c23","0da4d093b49c0a1f654b38008bb01195e816829279ca1989bd2448194e15361b","0e560af7d9dd2e0f2f588a74cd35512973747f20bdfe0bee0bc889105ea53dc9","0ea7107c2c8edaab3ff2bae32f63cfbef6903a51cdaff257278f757ed5ef429d","0eef4d717eb03f0906aa3be7336aa71f831726afabe8a56077b76f6e82fd08e1","0f11324ad653d8d841962b0eeae9f68b80243d4ef7df4f2404ed4c3e45ba5197","11fe30832d93706c60efd836b09f35f049c4a715ad6144cf277ca240c5780704","1244d27db0cf5075353bcc622d0fb3b5ca6a7d08526e2c5754e8b745c250bf3f","126c817ad25ca9cbac2a0f7446e76c79852459ac7b9c61e3ba5d5cbfe5d37dfb","13824d6bce0f961c89eef4bd3c8a72ae6ecf7a1339b9e06eec964dc5c12dc544","13d0363b8d765c87a57eb42c4988320a9c2e7fa09024aa972f4b13d7699a552d","14156f1c6bf0fa8dfcb5cfafac09e012db446d528dad0e4301404fd693b9bed3","155fe673b8ae12549c978e1bf1d5c43e360937fcf2135cdcd5aea6f6c771da44","15d41240067e2335a0354a4e910b6610f2b8f079b8f67186f10181622b4a8999","1746f4f9d47b7dc42280dd34e664b3ec410d3cc69ac76933707499ffa34c79d4","1754adaf40732c3a8c73d2285c25a8b6c8c9d3e68370de618a0ffa8f3e60fb6d","1945f527afc3c2930ec4d7fa57ebb2ef7dd6321c0dd3ab9233c9963e9e613165","19d657b67672257ece127f3b957674b7fb4780843148db0a36a0b329c2a418ba","19e75be8ed4dfba2a6f8034154052160a7a181b17d887b3e8724f3e3c111c31e","1a24f6ef0c08a898f309c1b925fc19b29526f913a61a1dfe4b1a4308ebdd97ac","1b3ec24337f0252a00cfeb6df0a0f5d2b6d737dbea61b8d0b4a643f4c686df6a","1b5351b2dc647aba864e387168db5128435cb80da94fc42581cd60a05fc34b9a","1b8cad98d53da179ab05eb47c1783f4c8b45b9f39c635e7a337285f5cd9621c1","1cfd18d1b12b25604d818389a34bbaa746f450e70246c7f4242fc4e215fc46a4","1da011289116fe88fe92cb8f0e83ed7ccbbca251681d4e136c5a61c40364f8d3","1ec9445b242d2a2e149fe71c67bf13d8c0e4ebe5a6ed7b022656b9941973909d","1edc36731a9c76ad07d269d8b4fd84c8c956bb43d6f56de17d6208164856ffbe","1fec5a63a7b2b212e3e5d5222e49061f3b924966c9741294f5630836be8a3925","20901b579f69cc97eb56b492938864667576e1c9bfacf13f8a529c4f6e543448","20d01a387b4d0801cb588492ede88cae7bade9b7ea3591d9e954add1e67cf4ce","21338155cb4f52c49e5072c877771be67c75590d9b238ea025fba5209fd6e018","22ef13e60456fe9046dfe72f20122362aeefbbb445632231b8e364ed9b50e135","23af79bd1e7995fc8162ddc4d830318acb054bbfcc9c7d5cb141ec306da67386","24373b643450d9dd3b8a5b0e74a5fec2844cd8cbca7d8a57dbc8b9ad9eade9dc","24d4f2730d94d1b7f149771ef0e59192f4936d142b21f4a56b1a391e4514d38d","252de742c26409c837ef491f55eb03ffcc99da13fb1a2f8ab66efbfb0c081a2f","253bb17320020b6a5ef8f0958856f6c565a239b4dc246d9e825f8b14da9ca8de","2591526ddabbea03fbdc38bf172bc54f42df9bc51eba7ad2b70d6e67215f08f1","26259abc7fe745f52e06f2aa2abb0e50f189bc7608065f04d5c669a0a99941cd","26290a0990d6dac0ce9448e05eb934210603356043dcf14a5d80585288e2aa92","26d6b31965013079d4db67a2c403e01f21e3c30ae65953400dbed92e289a0925","288daf614247c260cb673d8674e8b3874ccc4e269347836851f702d7ac8e2f7c","28abfaf6d50ca38af0b88aa50524200c17af9000da83ddbab3d8f9e06e020fa5","2905a2b4a58bd9ec1c4f77fd3d1d246c02caa49d806272756dd039c79521442f","291d3db272eae084d34c04bc1305f2abb26a7e7acbc5515208469b46719a4ed1","2a38ddebfe3380232e35d5a24f9cb9f7c38abbc9c68add4ea5952c1e65d328d2","2b4f7c8dcc95ca8182105b9b6806391666e6a2c3a5c80d3ce5a5f04fd6cf9122","2b5e739c8f9602c585e67554c457e6e53351679afd56ff324f8fecc80f0891f1","2bc251ffb58a0d03480748058eff4c44079a0f21d75743063cef50263982337a","2c76ce93500601e281a41f5985fe4e3926fc8bc9d01ee687f14052cb553ad2d2","2d46924a94c85f4275a449dd3d9eb6c602cf8a9104db19d224e3aa469b858d06","2d5048eeef90792c0a2b9aed7305598a28db2103fed3903462c6c1882733c3e8","2d599c722a08306b98f2d833fb3e4a7acb9dea92e6a58820caa2f65c09803fb8","2df1610ac1b912232030b5507e5e944515b0f1549bf2b76ecfb12baf0f40ccea","2e1bc31ff6b6fb14d0ca8703a02833db749b03e172f2e91f9423f0751e88c256","2e872e9d3ab8b553270e79673060c50c1afd68a41fcf9fdd0a13cba80be0dfaf","2ecd502add2d801eebed39411fadc9a80098ba9ce04a5f4b728a0e4e331232d6","2f7357367d921995f4c6fdaa693392adcd2df4860ef4d25c8dc47f7ddea8c755","2fb2ed7902a8e35dc36489a23245d963026d688008c92fed6fdc1f6bc27198a6","2febddcced970d495778f33fff212929ac99c23adc42be0c1062f5c8676ffce0","3018f389f6928af5830bdd081c9d03530a379f37d1c2f9196e6fb3c44eb337d5","310bfb5b2d061bb733771e5cb7b3b7d25db43af5eda9f806169b7ef9330c2fe7","31fe4b51d55cd99a4692d2cb787d362cb4c0d0998d3e001efdb5cb7ed838340f","32f69a7b8997ae98b9305ee578145d795dbcd39ca4469bf2465e57a0295cda51","335683e33b94cb86b5e426b4faed200673bf850151191a08458136ceb164fd4e","3407ec53a884d3945d86a88d6b9a883419dd426e96b1108a8e6686f30397a629","3442ba5c7643c793f62d90ca841f7891b3dbf97f028bc7b62f8b4f88c1266d1c","34463778cf2d29e3896a65613cf9e3eb3e9f2d8946d17f12b609e70eec63d128","348ba129b7b9c94e24fa8ddb81024e777c60448d1b5d49f7b2075591b23c13b1","35da3938b72cf3520e126ad595157104b69ab748904c7b4e12f563d6b103172b","3600e7356a3741ef02f8b2ffa6a6b5d822dcbb170771f2ea33312dff4470f431","37c8908ea2a349cd3034018027160ad810b28ad1fc203a9a353971e1f7396b4c","37e39faee019bb041627510f1f02746ba9a85696417a083b438eb4974b72c2bf","38a75fd804821f4836f0a7ba8d41af3d3a3a5f5d7dcea68487009297824258d9","38c6396e645750efcb2f187c36c383471b3b0b59290e3b42cfcb9668594cd0c3","3962789d05f324d436a363700cbb5ced5aba791d782b3c0ea73221fe0c1f0b97","3966e5e53811c43962f5d0953e5da4753eacefbea27ecba9d36af2fd8e4fd52f","397476cf107b48e7a662264f8fea9f880231fd3d1e0401622650f214cfaa35c7","3ad8b0398ba6c354c9e31b7438b2515579fc0b1f17de4b35a914c862a3a11e3b","3b3c6cf083b12a840565e00458e2fd4ee8a61f97cda452703a6b13d7776b6c13","3b4af144afed3d52dd2e1f64e23bc25b3475eee5f7af3bde9886761b15c33dfd","3b5d82795e9f5d1992ab67e078fcf1108247ab9b6d1baeac944d3ec0294cec5d","3bce154e59c5c45216bb5372a352e948d6cb365bb1bd47d4666ae0412e507ca4","3c75b650f3fa8217597b01d3aaf25427ae2a658a7c966afeecdb391d3ba547ea","3d0274f77576abdbdf442c8843e955e1bbc91e9f8cbfe3646b119337cdb13c96","3d642ccf9ca4a0f7f5dde1b41f65c99e9c447cbb9e64883b67e4fdf76f216f52","3d9fd2c5877483382f0c7331206393e42827b5dccfd60549a6771b7a5659e524","3dbf6d1c2c8db1a7e3988e2a84b67a4e1d7c8304661652ffa94db3b7eee08edb","3dfcea4ee3d0d0ed09b1f77bac48b33b64ab4620cbfc74fe0e4201b4cdb81ce6","3dffc36586e9078f750b0a2b4cc2c70a17a81294903186dbe8cc47cf8055b9bd","3e2f66baa16c7ea936eba34720a55897438f60b343cbe8fda4eab1e5dde044eb","3f5465798dbc2ad279ca4849d5d0f819bad01455e0dd2a9d98afd4b55cfbd7ee","40de9f41f9a9f56ef6a51d065270e875b4a85cf043b7c4a0173b2510de4979ea","4134a3936170c1fb5fa6d2e2329185a981436477a66b7d31e827c363691bad50","414259a2fda4a1a49729be6fb1aced4675ee9cbdf990aaafb8e5b3153b54d64d","41baa5d98b5bab2ee01cad50c05b83edd8cdfeeb00f30b9406b4b2ec6d13d738","41c768ea17144c6ec225e9a65d4c3c127fdd7264dcba1a89aa17b20fd5d7e3ee","42aeb46fcc3d10b95e4067bc9cda875fa933b4102873f67c7bf1f8ca6799a598","4320b92712bc14dbe10b56f1cd3d1bdc093fc4be6016732839d0be4dd4d027d3","444342c21a4743af5961beeebb88088f5d2a0649f76c71973a7706a744f5efd2","4457ab439bc8f212d83442dc7500e9d45ffac849d0f77cb97686d9b0672fc3dc","461d34fb1d53849951a7e715e52342372d779299fbcad210794235c610dadf64","46a24cd8e385b748f40d9271b1e856dd6d68c91ab356abb11ff6b65f1ef936bf","46cdf2c207f79d388001f6636dfb7a98bb2ba72b9d1c6df4938f0a27691e07a6","471570cdf8144df0c32aba1730aba24c7e42e5ec317af771ffa169f5c842d117","47b5cb2b011c0f7012d75e88eb86a10f3f0bd48545db139669e654cac1f69650","480f1ede18ae031b164d49d676feeb1090fb33932676ff52e1e2eb24e8d154cd","48262b98c0bdbd5ee2314345726d23630ec1771735db8fe5f1a8590b662c9962","482cd15ecd9cfbd8e1943c0fcde0bbf1d875392dc2a701b698f48bfba684a062","4855e1947afc954cb1b20bb45e7af10b098fa34714bd32e9bc77941cf58fdaaa","48797c44c92cb34fd9a57a08020b45c6920b2268dc8ad616c0f814a3710d5316","48d094622ada1806cb30335926007c1abc476b1f7b45a2e250c490afa25e847b","48de3afdc6ee73ed121d1433bc6367a399286d5f8c2c63670a0b3b9752a36175","49e8cf09e38acefd3a0fa62d048028286d3b47b5ceccd8f51f10022978c47820","49ee4a3f2a8918bdbbafb312cfa807d9982800d13d29ee292c6c0daad8b9b8f1","4a724a6a842a132c2185279513f341b79f9be93e42660f1255770eeae3b1323c","4aecbdfafb68feb3124c39219498241864bcf1ceaf87fbf80598b1dd87a9191d","4b364ecb35ad02b06b6b0f32b6a29202f2c835e1ac0d70b89fd0278271799dbb","4b6ab2768e1ff3716ac8565201c031a820c208db9ea6ae1495dd782e7557a3ab","4be7778c4f491d55154a028d9a9dbb35059953fbcd243e0206902a6e64645efb","4c8c327dacf345e184042092e96ad3ea02ed4cece57dac5fa68ea52fbb5a6adf","4d5a44ba07fafeab823b54a21846269330ce35b4c190f3ddd5434bc8530d9b41","4d86a2764c55b5c5f675fddad8850ce4ceab160ac5c164a299fc098899d31aa9","4da0a5be70e8af9c39623deac83822749482187f6a0fc3d186dcfddaa7111576","4ece7844e2b35705ac39fa25913f6909aad5b4b7446bd637ced46b47c0db135c","4ef30f11bd4dd9d2eef8716d88a83010546e54594b2726de84f6d587651ee940","4f03e231c0dc5c9bb2874f6856382d5b205758af9678fffdc7552d4e4ae9866e","4f1e58fc658a4ceda181e2a7fa249305b09b573ffd68c2489f204f4957224957","4f2750b974c1404acb721ffc84cbd1d0756a24211dd6f6503c10ea74dbc45676","4f6fcf4dd7e73d86e06bdb9c14a1078b61c0efb2663ced9bfbc5f46fbb4c6d8e","5029c7b222158ab3f325168fa543d84fd2332d2e3e38db1ce7b83899cef201d1","509ec9c08864b9dd0029f32ffeac85fbac863e2dad459994c65b7cb5264faffa","50fd7e982eb2d2813634b7c44e102788a1a1cd4910a27acbcf219f76314fa322","52049cc9cee43bb27229e6b3e983e02c6aa20dd7d153b13e3c74bc6d2b47cf92","521ed246c4119acd6b579b6eefa23389a1655df54aa35de7671743979ebfc68d","5382c901d160ca2d79888d8acd7a690a5349826b5da486274b0800c9d7513f11","540879695d41205515aaabe5466971014cb43b960a26b8e5958e37fed63df762","548d237f42167af5cf5caa0ba20f0e7a6387deb6f27765637f078325172396a7","55267f058e9f085117765e4ca72ce875b622ceaceed964f6c396073214835c28","5560616d1e72f0a539f9ebbfea3b7d195c1ef5622f97994af1963748d4f97533","556ee783d8e2e4ca50f656c095758be613983f904d998a6534fb155510114f21","55a4711e799294d06988ab4acf77eacd7d424123082bba3ec987dff0ae13999c","55ae095961d78a1514c4dd1e63d477c60179a8662571ab5a90abd3eb2b83eb10","55dcc23ce52b3918a60029d9398f262216471c280bfe66421cc63240533a6087","566ddcfc45ea5edc695626826ed185930e910fd9107c5bc1844c717b714c15b2","56e7158313357bb145bd98c5f790e569be2203fb2601565a30091a597a7e7ff5","581337891936ba630d34ce9f6b803b82a2130791510f15bab24a07332400417f","5962dd14d3923433cf723d698d1af19ac37a270b6e88445643fc56a646faab5b","5a2064cdf51026eed65457c05f34bec919b31d96d35c29498d298685965f0b5a","5b77bd6dfa81cc339e729e4195e258facbfeb64b9c680512f742e3fb1961fdd5","5c0206d9d014821b52a43d7b222327a89d4ee2f5b1e21813dfa659a69f7426b5","5c3527e43fe24c5aa171c6fa4a3de7fe5e78f2527aed0dd19cb21d154d43da21","5c79c77f00167ca140127b00f1a79e1ffac621e46fc461089594206a7df8d7cc","5ca67643d5111fffd21deb18569162733e846965bf05fe6eb33ccd37c964025a","5d015880319af666943e68169ca906bf2f0c813d8bf2c5c0262aeb5a40366350","5e3a589b627edaf7005c60382475fae7229adc4ffbaab6d6fd03e9f08a0a8e19","5e43baca07fb966bf1c4b3ac06bb819577e477a84c5d8d3a9a19c391ada2e0b5","5f2a75b89983d1005a38afa2cabccc3a39f31989807120281d8505ffd564e0c6","5f43c837f39d207c35a58e9b36fe3144017b2012ac7da334714247606f1906d2","5f4fa6dde5930fe1b42f805895f0f5fb135c2b3ff9830f2bd30ae7526a3295a1","600ec184ee9964881bcaeaf72ad38a72db05d5b629d301cb323fa1ee9369b572","62a713311297a7145d3610ee60dd6626ee543645a1918b050c629207561efb5e","630fdcff1f227b5baf5d10bd78ef0fde68791ac0cd8a15f65065f5cc4501b17b","63113617f2e4ee6b827a69bce6afb3949190a282f5feaaa9e2c9f82372623bb8","6312b7a9f8252f49b8ea0cbd0580b80bbb221db574ea74939823ed9d4140d73f","63544fa69b09916d52b305700eb9816305ff22b77162a44edd13897acea3a655","6385459222fba2c3302d3f2e38c57fcfe0f1829679fead6cffa1964248767d5e","63a4394e689acf4a4762cfb4df691d05f923fdf592fd2f8ea41e6a54f98d1136","65725e1cd3323fdf44ec47067fd6670b441ff5f82e99485e1a4fc7d475f14340","65d5b7eff9d03761c8206218159bb34883c09052d6a1959d040f711a881b4d4f","6601b2bb6c908a46ae2985d4683c8baeeec87b0688b9b33d3e8900286bf4d6ae","666e7f698fbeef24e13e91ccfa334cf781233e060fa86bcd7d4d0eb00b30f3d5","66d414618d4283838bddb6b9fd4b5221c280a7f6a715b622143d3bea76bfe1f6","671168c05789fc651cd961a5a15e10adbb76656b802cb0fcbab468ab76412ca2","671d95a6c09bb7b05a5721d52cb761300a2c8f376aac20be2948b7e97bf302b7","680de944f1f5380c579003e329ed6f10702ec8ebaaa8208743775588d2424d05","6989ec486a05550633170d2aa79188ad9b03aeea6c7859dbf18790ba78c5427a","69ebfc7eb8427db3c5c59bdde652d0cb269426126f8540b1b58caa29ccf130e2","69edc4285578313d1dd2f914d69add075a7b354f7fba717606d1abe15292576b","6a34d9279cae58765d6ee4a980192c0e15f3ca217b9f1815861d472a281b3cf8","6b00dccaa7deabc750679ab085b237a2bd025bd971ee1eb7bdc333b393b19084","6c3c592efe9c684ada5661b8cc88a5c3f6e57c841db06b9e070687504cbf6236","6ce6d164c3e31463fb9e144fdf91413e55d077cfc4f25092bb02923fb538a84f","6e08a638e1e28020923effd4c65fc517dbe7b06100ff76cde74e427191503b84","6f3a7020233cd77cfe59eefec0a277f6dda323743c8d80e4e54a95cd3cbc23cf","6fccc6f0c5fa71c43211785dced8abd0f3295040eab56063f4e8d77f1c09b8ef","700cd21af9ed7e81900fad9d52de2fb11db48e64b038e4293168f85e5dd0e043","702d1dfa75e92a916a446429f474d4c296e6ea4e8c487995852d0525e8440659","704cf778db6086c3e282c81249fb0ef09c1d7c2043335ef74c7ecb69bb3e84ad","7075f89b1271fd04fa02d4db95c0f0bd6bdec24e53a7953d7afaeba40e17e8e0","71ef1ed2d5e4bc7eebe7a73bb3e9423e5bc2f8319186380fe8b38334952d3b01","7256ba00af1cf759b95b7bf8ae3b9943f31349bd10a7652a26bb419b368d73a3","7369b339daca0fcf46ac7fe82d65ae95c75d7dbcaaae51209e6d90b6587a014e","73ec844fb3e2b9febd00ba37508b284fad141630f03cb9f74e36a195180f5054","7410de003c7b582e30470d1209eefc796a70c76fe8d61dd9ccfe01ecfa41310c","741c27b54c49167abef1d8633e3743b0e98f82a73731e744b6671e119a1c6310","74b5d2ed555740db7b4b0ea9b73f8fe00965fea8e14d4f075eec26ef7a189c68","75aaecf53db10459d768a6873f6783e7d7110aa510c2894378df027c1b03584c","76bf5a9c126db6eb466287a7c0d823327ee9882a70eaaa6efb03d169b5dba808","781a64598efb2a11156f07271ba1c14c4f6b3d73aa2943b26eae02063df7af70","786b0c2856bf1f3f809e5903b0a971f1e072af5635aa50bbb9b1449f96d7b694","799abc1e8d381b8d97349479139985e383bb49179b5a80f39807cb35a3ee78ce","79faec494bdd6d098c9d2a9d8559f822938c6b2104188db95321d89e7a732979","79fb2e6e6a91117b6aefbdaabda23ccfa596620f548ee5075993a8dc7a8b872f","7a032dbf0351aa32c77c8d187f7eb697500ff186c88c5946ecc15adc972246a6","7a134e7f1822183ed1c0ded720971539350feaaf92612761210cfc3ccdc55870","7aa52373f2721dd76fc8eeb3d6061794f27ea8d11e96bcb1ff25a97994a77d5c","7ad4ef4b8d3221758a9e7f9577750ee03f6cba11c8eae8bf25f74a3131bd21a2","7af2394d2e697f355439e841b6323ffbbf8b90b2e48bf64873791fbbfdf15b44","7b947ed0a9e6e7ba180921434b993c62ac70bbaba6af0a1618569a2d4b705201","7baa35131ece7ed9860607157d2531d4d70a061bdc9bb9876e20328f127cec53","7c2a1c4c4c03e3d68d63e0ab58e4e34d3f2bc1a4a837a055fd13a4e9f95ce6cb","7cbf970a11bdb91a40e248eee97ef789205910ebc913349698fc75ed35e82fdf","7d6133667f81aa66a98755d253ea43301b45ada338225df034d2ffdfc79829e7","7dd54213b65fa0a6ce5aa3c204b5209b67ec16306b776aed7dcf9e6601d74235","7e89b59b456dde4bbbdbf8079665bd82c51d8e500018472981c15618b3893959","7ead0c68ffa0ced241af74dde58b3831343dff3f7eaab64bddb9954545b7ba12","7efb464c6d7b469303c43f718063d8456df6fe43534b5d8a4229f5b9ba9705cd","7f8188b57ad3b0c28210c95954e5623376a4262dd5e75f002700c6094b8d6b6c","7f91dfc2ea1a3131c4090375db0f489c2a572e245ade6cda4ebd440446d6d60e","7fcb8cba3ed0ee9c342947aa88f0f699bb4f5c23244d21c6c739c9b66d7c6101","800060d7b4934508d0277f90a464e3112fd2fc99af4ef23825d09b0ff53f91c3","800a802a4ce9e597a102f0a566535c1f9f7adfc60c41af6bd2db4fb7fe3c0d0e","820c12fcbded9048a363b9e0ebbc48b24f85fd4a68131b5dfc1b19057bf09ddb","824bff7541ec2a4b0be126f0b0791314d568a0eb4e29073de4f9dbe0ee4918b8","82c419e5de083e423330432c9d45c744043d1bccd8eeccb41e3014ce9ae3c32f","83347356a898238c013dff73246440e361a9e24cc3c4e0fe0e850467772b4938","8343a4211a4d0ffdb320d5a4305174d85bb707d15dad978f6436297d022daa11","83a06a604bbe36d72da976fcdeb88665c762b0f0de44193576ef2e0cf29aa9ad","83a97b9ebb29f5cd014ef5e178970a601ee92c44678f05d1860b383c5f63b79d","85a962a7c23c14dff8d683e738b53f422221697b213cafeb616d3a172a6c4223","85e961266b36e0f8ec2a477f1f1dfe7ad748fdde9d906f7bd3241e6924866ea9","8629fddeb4f273b35df69d4d28923adc14eff59d919b1a495d1a68818137c561","872ab2b2d65fe685b91e355f5af051c85b79569ece16448160d01fef38039624","87789dab547842b4e0c822758e1325a3cbb046063e11e105a4779b3741e01cde","87f2b3634baa504f2ed9508c6cf6a47bbfb36214a177eb13d70d6a987706818c","88b615ef6a31bd9958e98b8ea522f49f0360ccac5d9fa8deb9e3ef3fe3147d9d","89a96597dc9c218633adaf94bb5d6dcf4cad8f5e0b6f5522a28e3ce8d8b2865f","89cafbb20d6029656266d8cb0f85103fa519c8032598282fea58c94cc59c4125","89f2105745b3a7cfd30e7d7c598d6c8fdde0a599f30fd0db7382cba50412445e","8b3eec010d1eae43a28c88434f2410a751f790a9d6ec4a08e75e68c171629ab2","8cce78271b4f001606069a575a172041fbddc52de6b582c920aa3d3b5d5b67ae","8cecfa09651c40be4d7c11c117c80e1911dc75bf6f1cc34be64706823cc024c3","8d250acd40c8a24ba0d51cc73e65bba6856509b5fbf4c7d7a435897a01c6e764","8df1420c27503370db9382f68a0af8d2b4d56f9dbc94b24ffae450a905083a79","8e7371228a726f381fb811d1d812c39917788a3df7e53dba1a3c364e755a0c03","8f3827158091bbed154d21c843284ad472a4552da2eeb858748aa29676e45662","8f4a21c70e4b933eaa4f9cee119945dd2ebeac532e82d34e17511b38cf03608c","8f6debc54d2bd7abb42f581f2204fc78b27ff8c67ee4b6392b4d71c5f983ee9d","8fae27ba5117e202afbd523b249fc454912571900fc909f5419b8ac96c773c44","902b958b4db7d8d8bf73a82a8aa86e5485b39477047c8ad60175d118fe31d987","9056c360e59fc78edde932b54124df317f2f04a90c0c6eb7825a87b89edf1ca0","90aff66decaa3a0998e9a6741963713c0c82fc70da505519e3d60204bf715fa0","90dc4cac6326293bb54486d3c873b83299e9a5ec8c86a68bf1cc131f5e4e2437","918126027fabb7947dd4ae810dd561ac22167102f9f978f86906624ebe88c9ea","91b495938bc6015970bb02c844368d3eee84425b472772cdb374a5347db86de9","91c9ced5e9ab8da897b7f69166a7d0bade5c58d511b42d60d5430d536da45d09","922a332aa100d622da733aea8fc74094739bb63cd480d3349a14d2418ab6b1bb","941f70c384905ab77cb9a88e2671301117e4df553da6fc7a09210710deb9b6ca","9442788fa51227044803f1d3efdfc1c2b2da372871a85f0f7a6bb3596a5c003f","9460f427df72c238c4b55f39c8864f1fa3685b0716a53227ea6f7b591d955c82","947a1cdd43831936480167169d30334f818bb5d882650a3547827c05204af111","95f0c5f3b9071db39fd72b88ec9fb2079ce7553fd5884fa527bc9216777d7c10","96c4c83df72e9d860e2ee51f1a74bc867c4a45efc8bf11bf88aa82e368b89aa4","971f59cc197732d0c0b6b8aabbbefca4550fb8fb04f8522bdb4257c05a28848a","97edc66e594bae06bb273db84a35d84c8162a1fdf55ed46d781419a9f6a2e4f2","985638a05562bb796911ec231d306b81e36ed6b58219b3bde874559e9600b59f","98a097d6ebb754334250dfd3ccc5f3dfaf5966524758cbfc9e10adf4a0229693","98c7e4bc2f05e9b4ca703db4a02347db7355a44f04e3a4003e26c46a56bded2c","98ecc99d3396aa9a35ce97456be66c1aac0cc05bab88aa99109649291e61bc0a","9944d1a9674e555a41d31d069d136461eb06dd4052d40f2e4ea4368dd978e01b","9a8f2389b8ebc29d3769868ff8b918fdeb2236d88192fcf76ab0ea3db0857fac","9af18d8cfee466bc061271d82254d7ea638b59b8d5a3901c6610d5baed85c38b","9b01e565a1541f9e652d7afbe62e3bbff28430c1ccac2226ea434f45fc9a99d0","9b466e8fcabe551bb6292d23a359be3ea15b7627a6ad9c9e6a4ff11444c20860","9bac7daf255467f47b83723095f93fa4b574d5fc08593f48825a2b2ebb8e2dd8","9bbd03293bf53e9db51401d157b3eb2aa51e9c70449350e98b9a0a3fc9a684ce","9c3b318c461b56a8d277133a6b947ef5618690ec281c42e9de6c27f22458d4d4","9cef1feab6841836dc20527fcc8ad9979671fe811ff80a5a33bae113fcbebb97","9cf90b3aa59f3ca0e40fd9e1fec9703428752d63bded6b091d28f614c9ba99ae","9d1a0da545eb6b2e16b18fdd305a2c000ff2340c19ac843914b45f6a4f936227","9d8637e5adebaca208f21af0a254e80712988867411be560031f4b7a23cc04f6","9e77badd0923fd79ca9761a41780ee4dd4f9ca9b62512f4fb59c7f8418494da0","9eb67ea41c5bcb9557ba51bbbd1b321a78f16335cadebbed848d8e6c1fc68bab","9ed400941ed49b2d90ebe3cc111d90d8bc966608ca61fe9bc315a3c1dbe8bc1b","9fb8c5aa087d38dab064a2d6054826377eea3dda98229725c2523f63a87e4750","a0ff0d0bb3a3c801b637d091293f2eeaac68e934274e4116d298ba60ec3461cc","a1baa1f699fd4ce19e8ef6cdfe346e1b0be63e16d5c5cd5feddcccb16a62f269","a2aec2d2f35d7174801247141d637e77c4f34e478c575b0e0a04c6251efaf993","a3c84d76be9d891812e795dd46470c2978dceeff928d729c0d5dd6def599923b","a3d6708506fb5c28f45f0d610bedba11b1ec7bcdb363ffff3aa4cddfa515f56a","a476183540f2e7121e533bf2dd9125dc071c81acc880e88cb435cad7a6d35b97","a4a8cca930cdfd15285ac3a7aa757d61501fb77fc12a7c3fbd78c096b279cf63","a50654761d6812cd811df02199e1b7b25c9b0d65e591f65430f9277ec43d9c50","a514a8c0898b6697696ca6f0ed9a43bf8993085b2db4299e3e9f8e3419c4a5ee","a644885c31f390b5e6b7fe2fc8d086d9144699295ccb6ffa51b3f7c76c8ca71a","a64e8aee389ae696d0d4b045c0153092113fa522ed5a0fd9b5658b8418db4ded","a6c531ed9bbafabfdd649f3030daf2f24461163aaf99dc73bb24dddb77bbcb90","a7ff7302e668dcea1cd1db2241ff95c0d73534539bd03fdefebbfb57f60d3849","a8b4a33078335d2811bffb78eee49aab5fcb31597dae366d43e20c7f7800994b","a91a47fb4fa5c1b1a834fa602030e435ad641240e6ceeb99eeeab7341ca09dec","a91c8a1431a4120667cd523cf56bac004794fc5b8b24275ad2f9c8a15c75fba1","a986593807953215f834ba73e7d2565659b32aa849986013f8614bb1c61ea8cf","aa131e74e695292adab9f57b3ccc5a503a836dd4b95a3b2b107c69f35dba3637","aa4103342641899dc00c22207c13ac31c0c73afd97771b0a9b249187d979625d","aa70263d079788757f176da269e554fef9240845706f87a93101591f8114e807","acae1db4aeb323f3b637fa11b087c3827a2fb6d69718362f54e3bc48f70ef7d8","acd7884bca46ea9422503cead985691da05cca25bd5ed52a199783cae7b8b01f","ad0e6d78c1e450e19bfca4a0e904644ab0ae315607811a28ac3dba20de869786","ae43a4d252290ec0e18c64dd58d51bc885020b2473e71e3ed0741184c9f006b7","ae69fe306bf5db346ddfa4367cda24c95e44213baca27b0ee7d7167bcdd85af6","ae8c200dbcea29f43b29974cc247d70647c80d5d76385396f1c82ee9f669e2f1","aec13a075b84253397fb97e1c93a23e1aaee6d6bff2a9161bfd00a5b1d7611de","af12215a96963c1e7e5d766ed994695e423e4780ed0b3007aed87b150d090c05","af6b60ae365a6cbeb140430b030bdb667f53a2a97508ae92dfc9ed91ca73b54a","b09355a97e3aef396f681943b37a404a98fccc6bcb97781eddb2fc000d1d985d","b0ecfca0d114bae34ffa62ac3ea05159a4415fc6eb73ab1fcc4d79f657268f19","b25c41f19ba40e646fd9b6f82051ee4c38985539e445b26bd628eae98537df53","b262187aa66e8a97083bf7f79b91595bf7a4077abe7f8be5b00b4998f4579d20","b3f50ed7eac0e9c54b74c4f4e02297dd2d2465ce4b699bcc15cfddf54c0f0f81","b4091f93c3d96e36b0708f5dcd46e0e7a0a48f098036ccef6164e4a6429ed94c","b4093c67a9195ee7d28d2575e967ac80057b92339489c244243c7c504c669ff0","b44352445272089cf90967d4d413cf7009bed0ac19f3fa95cb831d5ebad081c3","b4ce73bea5219f1b27bffb36c6a9dee14447a710a8938db807770083db4552ac","b4f2140fb766faf0065a563ac3664f395b24c81dab0d0d0d01df47b22e888d29","b5102ef50e7d4ed1925af5a8b45192e737df02fafb75d7065995a2bb93d2e8e1","b5428b5775526a00645566822530fb969b82247ba83f2c80c06d34151e1f9061","b5c085be21651d8579e52cd3ffe4abe6b7f45c5a9ee84d38c47b4734409918d8","b6cf3b02f36e0efa93b04667cdc5701340033a09e41a7196277cf6756999a666","b77c6669bcd54e0fa949faf2f7205f2631acfbc1ccf79f93f8dab5c5717f0e93","b7fda8f4bf81f8213d18e3c314df5100ccb6b8db7aed6b70aaf202deb606a14f","b7ffd6cddb12384224772e8de79aec89d8f4bca966a3c2a05763889f92a6db5c","b83b7229045affbb98f8fc46f289ad05e6626ef52e3ed2f7e70d332a54a69e2a","b83f5334b85422ac110a24286d5af7003f2fb5b0d783efe257b38a2281656422","b8abe10a2a92bf537a49e8dee92baf8de3ed591848a1b25151dab0d7ab3134e5","b8b8c5cad182083f45ce2d05d036e6bfe91cde1fb63f2e5a97c683bb7ef7ea0f","b96cea09313d481dfff1ed1a2c552ea29e8fe68f52139458996a4e36157748d2","b96f9beb6d6d8fbf88c4b8b2b807a362f2640479cab6173cf64c7710817785a0","b9ad2510d8249ec4c8e7fd8b2471727aa1bd0ce8f3dde78e545fb2f8f2985a1d","ba5c707cf9be40fe966c08807779994e20ca3f30ea9d73e26ce31ca334c05640","ba7d7464da8e13722232c8f86273774054693681becc450a68aea21a5a0e9b91","ba87e5d43ddb10937bb17941f055f80a223d0981fbba44107aeec8530e3a7774","bac3431138e986d6426c1e81bdfe0a968394896c0751cbbcc8f36002fd0ed069","bad8f17b1d399ea125c524895571601c90b6c93418c248bd4ebcc7886bae9878","bb230236c4ab6353afb4147014c93204d3d1eb8a6d18558075df5fe79ed7f392","bb7fa81e41820d63d58313460f5a3999a1f9fc2cd2fb10cbb5b41a931d8be6a2","bcbef69f1ba50e45f3faf1b4529c32cdcf1e5a6612b5bcbc6aa6790ee14b54eb","bd3bf6053f4d423ff21f7ffbed9d0e68f3ea64b7292c048e9a37ade342bb7b39","bd714f38c881208f1190ad714bf8fa5aa63adf302bdaa8ad8810ff279e43459e","be75cc1ee935f783be39978de91ae196c16141d4096e16eb6d07f59583296b4b","be8c3cb2d8d67e63c8b069920b74c6272922febbc6a0a2c4a0072a7a213681d2","beed0f36d9b1b9a20bfbf89c96862482b8d5b9d4284bc89539efe9c9b11f000d","bfd21b5c8eb26e9d475868bb30d66ee08f20876e9df5cd06aa8fec01ffe666df","bfe97e65f2cbe6bcd0f14ff57ea4dc1dedb2e5f0db92d04d0982cf1932ac1c3e","c055d3cfd85b2ed4607b0d9d3a15ab7204c9f149599f748347dca4afe102af0c","c112d36ba38c362da1c022945db5b6bbdc3014685ca9bb7d940f5086f00a675c","c23a43ed460117f663cec698412729fd91b5aaceb48cc4e55a785b525661bf1a","c23cf45c1dcb748145d87f5c173dd3c8becaf9e3f6fdcb3e2ca91d6726b0842a","c24546a064b9315172ce0f951bd5fa2cd1b9884231cf1bdc1dc714771f1b3886","c29b8d250a7b5e73f4ef675329da2251b8de032501e4836445b6aafd90c645fa","c2e96d98c8ebc10237a2af1c224f626acfb9072c83078f4a8c6d9ef0a58b4a8e","c329c9df0dae8a036da9be440432d045be3ee13cf5664cfa6ccf11576ed11acb","c4600cd5358b5798a075beb54539d952f200def1c9a573bd237c795fd33ba36f","c4ebd58c4ff78c9fc0cd17d80ed563520f7908f9d1106735ca0f5a7abed202a6","c5db39bbdc8c2bd2aa7b58c28c3df9e407955cc3250ce7825c842cc4c30eaca3","c65325f807190f7084346376e2f48fc2b6bb946004a1fac1d8d117930e93d462","c6752cc3c7ad06d1e9f127365f078919ac46b77f8a8fe413650094d914838ec3","c6867ec30530fd3feca89a4e968522f783b636b165ef74f288c42dd50bd51a3d","c6bfbb004af355e96ed5b4c8c9b8b7a96d1c08d24bcde7c666728eb9497d6d71","c77c4d3f536cda10a71fe6a9cd17ea7c1408200e2f7aa7c5325d6915ff250c85","c82f38f23e7ed3e1024661b7a22ff694e88d3b268240e2bfc98e630df8a062d0","c8bd340e6fc7fa3e97415f7ad4c22c51d88c6e77f782c12923e841c04d3f882b","c93cd4cb5cf38fe6221fa8ae171ff54240b5f99ba80cd740ffac69c57e5fa381","ca50b525d7aa7762c56f402696dd464841daf19b036bb932e325090004b4cd71","cad13b6653fd9f811e67d13c5f01f9dec047f8c384097cee01dd2e2db39e539f","cc24c3770587f2421514fa399d2617201752bdca145ac39058de91d45d3d19c1","cd2da00f6f1bad8fb7c1b87cff80e122eb017e44a471cdea769efc67db369038","cdbb7338988f2fd35fd92f21909b7801d9954d1c7ca78401f52c9313f21fb6dc","ce887fb65b6977a2046e7583d704863624e55909ebcc9c3ed065b3d13079a410","cf9223c369b6fb7baa52f301f904352ba8e8d5e4c2a06f70de6ef1cf76fe1b84","cfb9705939742247da0cb71fdfd8b5f7a1bef6f1c2f0979a8f42e54c4a480980","cfc3b5044af37ae7485fba8067dcb22b2438bdaa6e3a30c22ce0f9e2c00aa597","d0481d9b6111ab4afba0462e88970b863284807ff44ca97364c84952e3f88583","d0973a1aca6a118375b466d6e91821f8450110fdf042ac848ee16912012d2b0f","d0df3068db679e24d9487ee09a6462ac5cf3df30f46ee466b66feb6dd5ff71e2","d151ffa66d8d096e0272f0dfff6c27e978cfda570f7498a727593081888b4ebe","d227e0a73e3c5452bc5ab41ea2c695dfc0ff9b0c1c81e59ab3173f796a4157cf","d268e680ee1136a239a40ebf005b30db6f3b52a228016f3193496f86250f15c3","d2989a1607fd5303615937b8c117d127b1b1cde519662ab1e1324390220e8612","d2cba4dbbfe3d026f825a8b470a2f6011f9b8e245cf042ae8889afbb17dac6b2","d2e4c515093f8a2aa824c8b542a016e5c321065f4525931b2fac4f8af2fe52c6","d31e8aa21d1498f2d4a07c4cc89ea6f5a6d3ce54d334dbff230e0f55db35c85e","d36034e2f9cc642d0f9f24cf834fa741bac5b8b139cbd2f50e2065161c9f3cb0","d36eb7456d2a42d1cffa4b60708e2bd3116f7f6758c96bbc0fee0f1704ad8a79","d37de74aadd5916eeae243decf347821c4e946356b9f70471658638ac3092f91","d3cf9b1433fd9a083c60baf6ade1df7f2a33e0cc7d519f491f9d6a93139a41e4","d49d02cad8bbfeac607457b08aac6068916ef45d8f6c980279d6e654407cc7be","d4f51c31a454d9abac29457cbbc21e1b5767c0eac1b37c41ee787a3efb05c80f","d52ca358246f638d0e11a061e97863697df44f43b093d6e8b84ba67b5838f2fb","d555a0d2329caace197c1468fe6708349125762377ee3bd04b031b7eacfc26aa","d581443d0b6b42c76b816edc6946ce01a639ae42653ddc8cc2d6a89ce14fe947","d5c084e12da4a5111487c166b879042a21a056f761ee22d9237cb4f65f366341","d6077d547aa21ea10a9bdf6c752b8d1a0a6382b4b43a0fdf790f245e66a609fc","d67e8c1aaab1ce6ec1755599ecde153c47c6b90dd4c301663abe9057bc31af57","d67ec5caeb2af5f9c57533a34cbde7daba5f5b2e5e6ce34c3250893eef25f13c","d6abcc1484c3df45bde915abf48324af1e995c3266a3c6c069e98e94c8d9a4d7","d7a44c85c25ceb7d42280f0c2576de52a3b3cc3ad2333e788ecdc7f7f7fe4b3b","d84489933b19a8b073c65a0386e39e5067830facdc365ced6efe1948c7201771","d8c8b3c52c89cd715a7fdd2759a6f73c3a5f505303b110656cc35f7549a37cfb","d8ca8e025e226ad6bdd32a6a9fceae2982b0413a0ad09314558b54bdc724bf99","d8d03142030c11a0aa1012102fce2b202baf88e424a1236832937e87450dc579","d9823dfddf6c507ec030fce4bd2d98fbda18e595c2ebc563574d9196cc7a5e33","d9b0972f3406075b860ba7cd2e71d4492c826960319b10389c2c2820e2981254","da37a61fab07ec8856b725854e4064f55a59149aa69cad1bcbf89ec478b9f578","daa0fc9f9dd08cb2dc48bf33c9808cfeebff77cb9fba48f98ef597bb9dd6df55","dad01e5bfb13a6c4419f4d24fa8dbb424e93a1c4be656b0e5dd48ac546e0a0d9","db049e7abb7c75b608ae25cc8a9f95959f7aedaa53e22390290319cc2eed3977","db21a75b4fa6165f75268963474f3262124795d816ba80f685bab2c6eaedb028","db66a999537b941fa6d512908894ba86e8dadd0e14b290ebc119555b7e60264c","dc8c31e3075adeb63113852569b83dcd432485621eb77fef62cf3cce5c84a214","dd97ab52fd89f42352c595ce137684cc519c473fa17969e8a6adcde7322a4748","dda0a34d6704887eb36bbc0173334b49d755cac8cea3bbd17bfa972f04183dd4","ddbda9408727a19a4a55d516bed99331edf67d8301de9c78564716465c949619","de0f295bd0e46f29db1167d6c21bda624887c8543545d0c37d662e5b1b312341","de9a46da1f4605525b484a228f8bf356a9d900ecd16473faf77944b22575c141","e0288c94ca9c16a6de217e6baeed720fcf83e401bec45bd15ca47ba8fc9b44dd","e1667469384ec775a3df665679cb3fef057dc84dcb18ed8db8b9c5723835968a","e16c328504278cfe520d6d99990f2a4370cc48159aba86694d0f7598fd4b0611","e24df071f5325bb3a5b20f355143556bc7712535ee8b6ce4c426598f06fd2448","e28d8e6b71264d0bfab853e63178f2c151367cce0dbd16125596ff3604b6658d","e2c734504d211580b4e6674eb1c7d31fb6fb730c037210c34c980a96f9098269","e39ee882667ef28feb4971b73f9a01d3d72c557e1e56d59487af8e0f1b21edbd","e3f19c383354cdf45311f92f00b90fed25dfba7e9892ab2f5f3aa4885876b75f","e409fbfe439455330c0fe003de860e30f7093cc3cc83a32f886c9b539a29f60b","e519e78acf2938460c7ee053981c744dafc7642fd03b56a117d5fec78d258b90","e5db07b7fb0eed216d838fbeb9491257cf54f9bd537a68c8edae7a89fe64c8d8","e6300ee8e6c2c4ce6d7ab02b7b06fd1cabe3c5c52b99a6ea3ea8b5acd5092e0b","e65e28b172b77d093f5425112bdae7ab93756487226fd7363057f85bb2a2556d","e734d068446591aba283d136c21b4fb0209f91352cb4fc6589bd651cdbfec163","e7556cd0bdd06760602ef78c5e3b30b4dbe175f96b7147b56ee2ec181a4c5ea3","e7a333109a7aaec2b71048868500c15e721900628eb48790dfeaa1fd4c2dabc3","e7c9175fbfd9fd84bed95d552bc0a439b07a233c3e91fb39ae2f23197ee53f1b","e7ed299ecf44d4a96c228e9aa30312f405df34d6bea99d4b0f7074c79705a671","e8bc1b4f162c4066d74e5d1b3dcbe344742279b6856736c2e1690dbaa7bcf932","e981ced1bfce64a19fa8de1cd518a93f4669d01548f4819d0e1dbb50d266fe04","ea1b8a251ecc1fd96697d0c602d3e14ec46383d27bb9485a0326cea5576ffacb","ea311dca2ef14e02b9aae563bb28dc737b04b7f01c1ceb2be3d92007d2c74ac6","ea8e5b79bbe5329ae8437677c8316f2f9fd75bb1d40c88308c269140a7e564c7","eb708890ac7e19bd53007ccece064f7e2a069a3751270b4fdafdd1668136dee7","eb996138bc91c0ee63bafe1ba10b130ff5a2fc82aa4918296222e0a831a569fe","eba6e8e5a12a86f17fade41bef365aa95491c469e18aa91aef64908a4263c905","ebcf0bdb3541c8bfb7c9a53f632329b77341cba6f1a2fa0dc9704acfa3276dca","ebd87e3505f3a1adff0c86ffec6c380734df718301b216b7ee089c174130de60","ecd5e83ba8c8eba6cef9c3da1edb8a84e3dfb4ed71d9a2c1908f2c4d26b26737","edc160a11c07dda8072748b66db7f27b6cd8efbd1faa3f6c826a0fe445859c17","edfcbe4773eac1fe2964179a4ad21294efede89568f2efd8e283ac18bc5693b1","f0f90dee84db760cc1bb0f6e6983d4de0e3d5d9f4adf7b2b52f0d3dbe6d585a4","f1297fd9ecf981024e1544f7f048705377b53219240274bb803ac30e4a52084f","f1d4a6e98f41ab3f6cfd67cddeab9d0ed287b92cb3dbe575e3ce61925510a792","f21c3a9267110e469f224ac7eb76ca5bb084fc90df014f1ca6791d5770483944","f260b4b268e85a8f1b04b2fc69ffc0bca473d2e42de6f2f70128bedc16558201","f379a1b9e29aa7fc25c4c0c897eaa3c0e90d66a201a0ade8cbf523a5cdc8cf50","f3e04891c79b604f9235f438adfa49ee27db43d25c7be0d1cc06ae53b8f6d2d8","f46904e701174fe2850798d9e1b077bdac42fcac01dbc385298da01118c82aa6","f4de28905adbfe6ae4bc38f8bf5f47a444aa8d0f2023faaa431d6f72f9a3edea","f53265f53af0b0856911ab08b373736964d0c443e8ba61d7f1d45f5e5b04edf3","f5403593ba12130c04827f88d019103e924651caa518b7c290673a02f7cb409f","f5681dfc71121ed0f88146a19479675f2fabc6ed376fd5d162e50d815c048d66","f686173d310f41e26e3fe8a7c1dbf4313e4d793323335348badbcf4633f5d699","f6f5046c1263095a69e774716b0cd0907f6795af8ad683c5f41846d4c54a3449","f700bd87d4a758bb71f47731121a9b2259a9ffbd50b584b82f4e6a1f205c276a","f704c9c9e2cab1ed44578f48d161320b5fb4384ecdd8b40a5e22c4078a8594da","f7993302f695430a0ee938b1b3684fdfec4055bddb378b52c81785c0319e8c98","f89156489d35f9992d5971a52a6e03a7d7f095e15c2c782e85efb1408a2bd6be","f99ef6fa3c9c6bf572ec69eb6eeea9f88ce6590d3a5565bec62b001b6f2a376a","fa2dfc22b4fdbcf402a822e8dd376925655d997a0f96284a60f10665ba3581ba","fa3df5f8349aec4805bbcd279b88697def63f2462d8ada0b5fe1d9983d9a6daa","fa6b97cbca1d4f09662e706293b0aec1eb76b8e2277441f54ab6c548b5423236","faac0c3fa7cdf67b452d407e9a1db5cbe1e9140ecfe300200b0b0a6279c97c66","facb45d3084caa490d9b0ac2bcfcee89629a4c3db5926ec9256a9d27d25559ee","fbc8b53b5c6f3727c084e5e0429e410a3fed5a17e1a0144692fd196d9836a4bb","fbd74e4b8dc748b2efdd70aaab07adb80d7f15a38c1261de85bdfd9591ff106a","fc475f9c2d8bee2ffea435e86e6b39b6e3e071143a4a1fdf6765b0da13b66de6","fd04d7588bb9e6ca0a8b65ed0c9635082a9ee5f46b2d1b5b25866a072236c1fc","fd60f2a432086c6fc4a4c39d8d2d6edf5794c763c05a6401db2bb5fa2c601775","fd618761103380d690cb98804e8f116b6c66ef049fbf67c1a059ce49188658b3","fedf2577267d6dcd060ebc4ee8de6ccdafa60ab26b78d74c1e8c784252fecb17","ff532716738e2fc716c10797d9717f324cca3a1234320a84a73a0b89569f11ab","ffd0fe3449e449c7b9fcdcc7e2c1ffb677e57ad935a252de88a0122d437efa67","ffde5c700732beac27a9b5162213d387422ce199400e56d9cefe550005b6a542"],"schema":"fsgg.atlas/1"} +{"records":["000ada42299601fba29016e5c0e0d4012876fb42670bb10fa0b1315477254ba4","003893cc49855d17a15295d7adbe57ee301ea20281dff216461baee0810853ff","0052dfb9eafceabaa590f4497e4d42f19020718c84b981d265edefd432ccf8dd","00641d046d6869fdd0023ab3df99e0e67a6ea28f0dcb701f622b1cec8b3e07c6","0066d4a624c02398f21b4d7a736a9fb5101ed8b6b13ceeab46907e9401af98ff","026a241141ee10eb829aa6ce461969242d5c1d45fe9ca19f08ef4ea880877676","026b08fb343aefe19177e95b759560d340d372def4b71acf613fefee3438ade2","0357495d23fac4fad210b6dd7ed7cc57dd33d107e1659a81f085cad78300797f","036c148f6d0e89858c9bf4cf380272ca6904bb4ca277a909fb71c47f5450cef7","04652cbc95ac4dcd21b837b38f2ca5a0ccd4d0946bc13fdb31c9c15a578d3a2d","04d17203f03279980862496517a1f0861be5f6cc8063bfbf92f8f8ac19744fdd","04e404d89dca295564813149472b1de8e6c43357e2f6d91d169ded7600ed3a02","0509e5c6fdbd2dde0c0db8558647080560714804d00e4f9268342f2e84858a3d","06ad2c8aa0ff3b862edf3ba99e0e4e8801ee163709e66333cd06c3fc61232b05","076259a45e71df780b012d29618c17739246c86321d2ff05a6c272bcca8db675","076fa091c878b19cf56a94be0966dbcd58d52c1839f9d4b85bbfdef650cbdb88","08b3dc660b9d2bbbe75b590b2b86d941bf935a254cd5f09de71ee6894f4048b6","09e90ad705af012a8c36efbf296757f35adf9c9ce3b8908791c75d72c192973f","0a6d7dc5b64970bfdadc9049ace95e8bc163fc421beea70129ff0eaa692c6d06","0a862ee40916522f8ae5f14b3e084bf5f2e6488185583346db96ced16ce7619e","0a9df276d42b56d98a7802befc2404204e0e5ee8bc7f5c032f7bb29aa4ae2091","0ad4403c8f4078dbfa543310c69bd1dfc768e305987214ffc37d7b2600c4687c","0b2d1557ff6df5f4d65d540a5403b07ba81b381dfc799b7884ac72dfa6ee7753","0c22360d4653eb0f450e4d3d34564875f1660cfcb2d546095d98b3faa3967cbc","0c7d3f36e3bb4270edbf7abd99cd2dab772df274cad1c27c7e87e302b8eb1c23","0da4d093b49c0a1f654b38008bb01195e816829279ca1989bd2448194e15361b","0e560af7d9dd2e0f2f588a74cd35512973747f20bdfe0bee0bc889105ea53dc9","0ea7107c2c8edaab3ff2bae32f63cfbef6903a51cdaff257278f757ed5ef429d","0eef4d717eb03f0906aa3be7336aa71f831726afabe8a56077b76f6e82fd08e1","0f11324ad653d8d841962b0eeae9f68b80243d4ef7df4f2404ed4c3e45ba5197","11fe30832d93706c60efd836b09f35f049c4a715ad6144cf277ca240c5780704","1244d27db0cf5075353bcc622d0fb3b5ca6a7d08526e2c5754e8b745c250bf3f","126c817ad25ca9cbac2a0f7446e76c79852459ac7b9c61e3ba5d5cbfe5d37dfb","13824d6bce0f961c89eef4bd3c8a72ae6ecf7a1339b9e06eec964dc5c12dc544","13d0363b8d765c87a57eb42c4988320a9c2e7fa09024aa972f4b13d7699a552d","14156f1c6bf0fa8dfcb5cfafac09e012db446d528dad0e4301404fd693b9bed3","155fe673b8ae12549c978e1bf1d5c43e360937fcf2135cdcd5aea6f6c771da44","15d41240067e2335a0354a4e910b6610f2b8f079b8f67186f10181622b4a8999","1746f4f9d47b7dc42280dd34e664b3ec410d3cc69ac76933707499ffa34c79d4","1754adaf40732c3a8c73d2285c25a8b6c8c9d3e68370de618a0ffa8f3e60fb6d","1945f527afc3c2930ec4d7fa57ebb2ef7dd6321c0dd3ab9233c9963e9e613165","19d657b67672257ece127f3b957674b7fb4780843148db0a36a0b329c2a418ba","19e75be8ed4dfba2a6f8034154052160a7a181b17d887b3e8724f3e3c111c31e","1a24f6ef0c08a898f309c1b925fc19b29526f913a61a1dfe4b1a4308ebdd97ac","1b3ec24337f0252a00cfeb6df0a0f5d2b6d737dbea61b8d0b4a643f4c686df6a","1b5351b2dc647aba864e387168db5128435cb80da94fc42581cd60a05fc34b9a","1b8cad98d53da179ab05eb47c1783f4c8b45b9f39c635e7a337285f5cd9621c1","1cfd18d1b12b25604d818389a34bbaa746f450e70246c7f4242fc4e215fc46a4","1da011289116fe88fe92cb8f0e83ed7ccbbca251681d4e136c5a61c40364f8d3","1ec9445b242d2a2e149fe71c67bf13d8c0e4ebe5a6ed7b022656b9941973909d","1edc36731a9c76ad07d269d8b4fd84c8c956bb43d6f56de17d6208164856ffbe","1fec5a63a7b2b212e3e5d5222e49061f3b924966c9741294f5630836be8a3925","20901b579f69cc97eb56b492938864667576e1c9bfacf13f8a529c4f6e543448","20d01a387b4d0801cb588492ede88cae7bade9b7ea3591d9e954add1e67cf4ce","21338155cb4f52c49e5072c877771be67c75590d9b238ea025fba5209fd6e018","22ef13e60456fe9046dfe72f20122362aeefbbb445632231b8e364ed9b50e135","23af79bd1e7995fc8162ddc4d830318acb054bbfcc9c7d5cb141ec306da67386","24373b643450d9dd3b8a5b0e74a5fec2844cd8cbca7d8a57dbc8b9ad9eade9dc","24d4f2730d94d1b7f149771ef0e59192f4936d142b21f4a56b1a391e4514d38d","252de742c26409c837ef491f55eb03ffcc99da13fb1a2f8ab66efbfb0c081a2f","253bb17320020b6a5ef8f0958856f6c565a239b4dc246d9e825f8b14da9ca8de","2591526ddabbea03fbdc38bf172bc54f42df9bc51eba7ad2b70d6e67215f08f1","26259abc7fe745f52e06f2aa2abb0e50f189bc7608065f04d5c669a0a99941cd","26290a0990d6dac0ce9448e05eb934210603356043dcf14a5d80585288e2aa92","26d6b31965013079d4db67a2c403e01f21e3c30ae65953400dbed92e289a0925","288daf614247c260cb673d8674e8b3874ccc4e269347836851f702d7ac8e2f7c","28abfaf6d50ca38af0b88aa50524200c17af9000da83ddbab3d8f9e06e020fa5","2905a2b4a58bd9ec1c4f77fd3d1d246c02caa49d806272756dd039c79521442f","291d3db272eae084d34c04bc1305f2abb26a7e7acbc5515208469b46719a4ed1","2a38ddebfe3380232e35d5a24f9cb9f7c38abbc9c68add4ea5952c1e65d328d2","2b4f7c8dcc95ca8182105b9b6806391666e6a2c3a5c80d3ce5a5f04fd6cf9122","2b5e739c8f9602c585e67554c457e6e53351679afd56ff324f8fecc80f0891f1","2bc251ffb58a0d03480748058eff4c44079a0f21d75743063cef50263982337a","2c76ce93500601e281a41f5985fe4e3926fc8bc9d01ee687f14052cb553ad2d2","2d46924a94c85f4275a449dd3d9eb6c602cf8a9104db19d224e3aa469b858d06","2d5048eeef90792c0a2b9aed7305598a28db2103fed3903462c6c1882733c3e8","2d599c722a08306b98f2d833fb3e4a7acb9dea92e6a58820caa2f65c09803fb8","2df1610ac1b912232030b5507e5e944515b0f1549bf2b76ecfb12baf0f40ccea","2e1bc31ff6b6fb14d0ca8703a02833db749b03e172f2e91f9423f0751e88c256","2e872e9d3ab8b553270e79673060c50c1afd68a41fcf9fdd0a13cba80be0dfaf","2ecd502add2d801eebed39411fadc9a80098ba9ce04a5f4b728a0e4e331232d6","2f7357367d921995f4c6fdaa693392adcd2df4860ef4d25c8dc47f7ddea8c755","2fb2ed7902a8e35dc36489a23245d963026d688008c92fed6fdc1f6bc27198a6","2febddcced970d495778f33fff212929ac99c23adc42be0c1062f5c8676ffce0","3018f389f6928af5830bdd081c9d03530a379f37d1c2f9196e6fb3c44eb337d5","310bfb5b2d061bb733771e5cb7b3b7d25db43af5eda9f806169b7ef9330c2fe7","31fe4b51d55cd99a4692d2cb787d362cb4c0d0998d3e001efdb5cb7ed838340f","32f69a7b8997ae98b9305ee578145d795dbcd39ca4469bf2465e57a0295cda51","335683e33b94cb86b5e426b4faed200673bf850151191a08458136ceb164fd4e","3407ec53a884d3945d86a88d6b9a883419dd426e96b1108a8e6686f30397a629","3442ba5c7643c793f62d90ca841f7891b3dbf97f028bc7b62f8b4f88c1266d1c","34463778cf2d29e3896a65613cf9e3eb3e9f2d8946d17f12b609e70eec63d128","348ba129b7b9c94e24fa8ddb81024e777c60448d1b5d49f7b2075591b23c13b1","35da3938b72cf3520e126ad595157104b69ab748904c7b4e12f563d6b103172b","3600e7356a3741ef02f8b2ffa6a6b5d822dcbb170771f2ea33312dff4470f431","37c8908ea2a349cd3034018027160ad810b28ad1fc203a9a353971e1f7396b4c","37e39faee019bb041627510f1f02746ba9a85696417a083b438eb4974b72c2bf","38a75fd804821f4836f0a7ba8d41af3d3a3a5f5d7dcea68487009297824258d9","38c6396e645750efcb2f187c36c383471b3b0b59290e3b42cfcb9668594cd0c3","3962789d05f324d436a363700cbb5ced5aba791d782b3c0ea73221fe0c1f0b97","3966e5e53811c43962f5d0953e5da4753eacefbea27ecba9d36af2fd8e4fd52f","397476cf107b48e7a662264f8fea9f880231fd3d1e0401622650f214cfaa35c7","3ad8b0398ba6c354c9e31b7438b2515579fc0b1f17de4b35a914c862a3a11e3b","3b3c6cf083b12a840565e00458e2fd4ee8a61f97cda452703a6b13d7776b6c13","3b4af144afed3d52dd2e1f64e23bc25b3475eee5f7af3bde9886761b15c33dfd","3b5d82795e9f5d1992ab67e078fcf1108247ab9b6d1baeac944d3ec0294cec5d","3bce154e59c5c45216bb5372a352e948d6cb365bb1bd47d4666ae0412e507ca4","3c75b650f3fa8217597b01d3aaf25427ae2a658a7c966afeecdb391d3ba547ea","3d0274f77576abdbdf442c8843e955e1bbc91e9f8cbfe3646b119337cdb13c96","3d642ccf9ca4a0f7f5dde1b41f65c99e9c447cbb9e64883b67e4fdf76f216f52","3d9fd2c5877483382f0c7331206393e42827b5dccfd60549a6771b7a5659e524","3dbf6d1c2c8db1a7e3988e2a84b67a4e1d7c8304661652ffa94db3b7eee08edb","3dfcea4ee3d0d0ed09b1f77bac48b33b64ab4620cbfc74fe0e4201b4cdb81ce6","3dffc36586e9078f750b0a2b4cc2c70a17a81294903186dbe8cc47cf8055b9bd","3e2f66baa16c7ea936eba34720a55897438f60b343cbe8fda4eab1e5dde044eb","3f5465798dbc2ad279ca4849d5d0f819bad01455e0dd2a9d98afd4b55cfbd7ee","40de9f41f9a9f56ef6a51d065270e875b4a85cf043b7c4a0173b2510de4979ea","4134a3936170c1fb5fa6d2e2329185a981436477a66b7d31e827c363691bad50","414259a2fda4a1a49729be6fb1aced4675ee9cbdf990aaafb8e5b3153b54d64d","41baa5d98b5bab2ee01cad50c05b83edd8cdfeeb00f30b9406b4b2ec6d13d738","41c768ea17144c6ec225e9a65d4c3c127fdd7264dcba1a89aa17b20fd5d7e3ee","42aeb46fcc3d10b95e4067bc9cda875fa933b4102873f67c7bf1f8ca6799a598","4320b92712bc14dbe10b56f1cd3d1bdc093fc4be6016732839d0be4dd4d027d3","444342c21a4743af5961beeebb88088f5d2a0649f76c71973a7706a744f5efd2","4457ab439bc8f212d83442dc7500e9d45ffac849d0f77cb97686d9b0672fc3dc","461d34fb1d53849951a7e715e52342372d779299fbcad210794235c610dadf64","46a24cd8e385b748f40d9271b1e856dd6d68c91ab356abb11ff6b65f1ef936bf","46cdf2c207f79d388001f6636dfb7a98bb2ba72b9d1c6df4938f0a27691e07a6","471570cdf8144df0c32aba1730aba24c7e42e5ec317af771ffa169f5c842d117","47b5cb2b011c0f7012d75e88eb86a10f3f0bd48545db139669e654cac1f69650","480f1ede18ae031b164d49d676feeb1090fb33932676ff52e1e2eb24e8d154cd","48262b98c0bdbd5ee2314345726d23630ec1771735db8fe5f1a8590b662c9962","482cd15ecd9cfbd8e1943c0fcde0bbf1d875392dc2a701b698f48bfba684a062","4855e1947afc954cb1b20bb45e7af10b098fa34714bd32e9bc77941cf58fdaaa","48797c44c92cb34fd9a57a08020b45c6920b2268dc8ad616c0f814a3710d5316","48d094622ada1806cb30335926007c1abc476b1f7b45a2e250c490afa25e847b","48de3afdc6ee73ed121d1433bc6367a399286d5f8c2c63670a0b3b9752a36175","49e8cf09e38acefd3a0fa62d048028286d3b47b5ceccd8f51f10022978c47820","49ee4a3f2a8918bdbbafb312cfa807d9982800d13d29ee292c6c0daad8b9b8f1","4a724a6a842a132c2185279513f341b79f9be93e42660f1255770eeae3b1323c","4aecbdfafb68feb3124c39219498241864bcf1ceaf87fbf80598b1dd87a9191d","4b364ecb35ad02b06b6b0f32b6a29202f2c835e1ac0d70b89fd0278271799dbb","4b6ab2768e1ff3716ac8565201c031a820c208db9ea6ae1495dd782e7557a3ab","4be7778c4f491d55154a028d9a9dbb35059953fbcd243e0206902a6e64645efb","4c8c327dacf345e184042092e96ad3ea02ed4cece57dac5fa68ea52fbb5a6adf","4d5a44ba07fafeab823b54a21846269330ce35b4c190f3ddd5434bc8530d9b41","4d86a2764c55b5c5f675fddad8850ce4ceab160ac5c164a299fc098899d31aa9","4da0a5be70e8af9c39623deac83822749482187f6a0fc3d186dcfddaa7111576","4ece7844e2b35705ac39fa25913f6909aad5b4b7446bd637ced46b47c0db135c","4ef30f11bd4dd9d2eef8716d88a83010546e54594b2726de84f6d587651ee940","4f03e231c0dc5c9bb2874f6856382d5b205758af9678fffdc7552d4e4ae9866e","4f1e58fc658a4ceda181e2a7fa249305b09b573ffd68c2489f204f4957224957","4f2750b974c1404acb721ffc84cbd1d0756a24211dd6f6503c10ea74dbc45676","4f6fcf4dd7e73d86e06bdb9c14a1078b61c0efb2663ced9bfbc5f46fbb4c6d8e","5029c7b222158ab3f325168fa543d84fd2332d2e3e38db1ce7b83899cef201d1","509ec9c08864b9dd0029f32ffeac85fbac863e2dad459994c65b7cb5264faffa","50fd7e982eb2d2813634b7c44e102788a1a1cd4910a27acbcf219f76314fa322","52049cc9cee43bb27229e6b3e983e02c6aa20dd7d153b13e3c74bc6d2b47cf92","521ed246c4119acd6b579b6eefa23389a1655df54aa35de7671743979ebfc68d","5382c901d160ca2d79888d8acd7a690a5349826b5da486274b0800c9d7513f11","540879695d41205515aaabe5466971014cb43b960a26b8e5958e37fed63df762","548d237f42167af5cf5caa0ba20f0e7a6387deb6f27765637f078325172396a7","55267f058e9f085117765e4ca72ce875b622ceaceed964f6c396073214835c28","5560616d1e72f0a539f9ebbfea3b7d195c1ef5622f97994af1963748d4f97533","556ee783d8e2e4ca50f656c095758be613983f904d998a6534fb155510114f21","55a4711e799294d06988ab4acf77eacd7d424123082bba3ec987dff0ae13999c","55ae095961d78a1514c4dd1e63d477c60179a8662571ab5a90abd3eb2b83eb10","55dcc23ce52b3918a60029d9398f262216471c280bfe66421cc63240533a6087","566ddcfc45ea5edc695626826ed185930e910fd9107c5bc1844c717b714c15b2","56e7158313357bb145bd98c5f790e569be2203fb2601565a30091a597a7e7ff5","581337891936ba630d34ce9f6b803b82a2130791510f15bab24a07332400417f","58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608","5962dd14d3923433cf723d698d1af19ac37a270b6e88445643fc56a646faab5b","5a2064cdf51026eed65457c05f34bec919b31d96d35c29498d298685965f0b5a","5b77bd6dfa81cc339e729e4195e258facbfeb64b9c680512f742e3fb1961fdd5","5c0206d9d014821b52a43d7b222327a89d4ee2f5b1e21813dfa659a69f7426b5","5c3527e43fe24c5aa171c6fa4a3de7fe5e78f2527aed0dd19cb21d154d43da21","5c79c77f00167ca140127b00f1a79e1ffac621e46fc461089594206a7df8d7cc","5ca67643d5111fffd21deb18569162733e846965bf05fe6eb33ccd37c964025a","5d015880319af666943e68169ca906bf2f0c813d8bf2c5c0262aeb5a40366350","5e3a589b627edaf7005c60382475fae7229adc4ffbaab6d6fd03e9f08a0a8e19","5e43baca07fb966bf1c4b3ac06bb819577e477a84c5d8d3a9a19c391ada2e0b5","5f2a75b89983d1005a38afa2cabccc3a39f31989807120281d8505ffd564e0c6","5f43c837f39d207c35a58e9b36fe3144017b2012ac7da334714247606f1906d2","5f4fa6dde5930fe1b42f805895f0f5fb135c2b3ff9830f2bd30ae7526a3295a1","600ec184ee9964881bcaeaf72ad38a72db05d5b629d301cb323fa1ee9369b572","62a713311297a7145d3610ee60dd6626ee543645a1918b050c629207561efb5e","630fdcff1f227b5baf5d10bd78ef0fde68791ac0cd8a15f65065f5cc4501b17b","63113617f2e4ee6b827a69bce6afb3949190a282f5feaaa9e2c9f82372623bb8","6312b7a9f8252f49b8ea0cbd0580b80bbb221db574ea74939823ed9d4140d73f","63544fa69b09916d52b305700eb9816305ff22b77162a44edd13897acea3a655","6385459222fba2c3302d3f2e38c57fcfe0f1829679fead6cffa1964248767d5e","63a4394e689acf4a4762cfb4df691d05f923fdf592fd2f8ea41e6a54f98d1136","65725e1cd3323fdf44ec47067fd6670b441ff5f82e99485e1a4fc7d475f14340","65d5b7eff9d03761c8206218159bb34883c09052d6a1959d040f711a881b4d4f","6601b2bb6c908a46ae2985d4683c8baeeec87b0688b9b33d3e8900286bf4d6ae","666e7f698fbeef24e13e91ccfa334cf781233e060fa86bcd7d4d0eb00b30f3d5","66d414618d4283838bddb6b9fd4b5221c280a7f6a715b622143d3bea76bfe1f6","671168c05789fc651cd961a5a15e10adbb76656b802cb0fcbab468ab76412ca2","671d95a6c09bb7b05a5721d52cb761300a2c8f376aac20be2948b7e97bf302b7","680de944f1f5380c579003e329ed6f10702ec8ebaaa8208743775588d2424d05","6989ec486a05550633170d2aa79188ad9b03aeea6c7859dbf18790ba78c5427a","69ebfc7eb8427db3c5c59bdde652d0cb269426126f8540b1b58caa29ccf130e2","69edc4285578313d1dd2f914d69add075a7b354f7fba717606d1abe15292576b","6a34d9279cae58765d6ee4a980192c0e15f3ca217b9f1815861d472a281b3cf8","6b00dccaa7deabc750679ab085b237a2bd025bd971ee1eb7bdc333b393b19084","6c3c592efe9c684ada5661b8cc88a5c3f6e57c841db06b9e070687504cbf6236","6ce6d164c3e31463fb9e144fdf91413e55d077cfc4f25092bb02923fb538a84f","6e08a638e1e28020923effd4c65fc517dbe7b06100ff76cde74e427191503b84","6f3a7020233cd77cfe59eefec0a277f6dda323743c8d80e4e54a95cd3cbc23cf","6fccc6f0c5fa71c43211785dced8abd0f3295040eab56063f4e8d77f1c09b8ef","700cd21af9ed7e81900fad9d52de2fb11db48e64b038e4293168f85e5dd0e043","702d1dfa75e92a916a446429f474d4c296e6ea4e8c487995852d0525e8440659","704cf778db6086c3e282c81249fb0ef09c1d7c2043335ef74c7ecb69bb3e84ad","7075f89b1271fd04fa02d4db95c0f0bd6bdec24e53a7953d7afaeba40e17e8e0","71ef1ed2d5e4bc7eebe7a73bb3e9423e5bc2f8319186380fe8b38334952d3b01","7256ba00af1cf759b95b7bf8ae3b9943f31349bd10a7652a26bb419b368d73a3","7369b339daca0fcf46ac7fe82d65ae95c75d7dbcaaae51209e6d90b6587a014e","73ec844fb3e2b9febd00ba37508b284fad141630f03cb9f74e36a195180f5054","7410de003c7b582e30470d1209eefc796a70c76fe8d61dd9ccfe01ecfa41310c","741c27b54c49167abef1d8633e3743b0e98f82a73731e744b6671e119a1c6310","74b5d2ed555740db7b4b0ea9b73f8fe00965fea8e14d4f075eec26ef7a189c68","75aaecf53db10459d768a6873f6783e7d7110aa510c2894378df027c1b03584c","76bf5a9c126db6eb466287a7c0d823327ee9882a70eaaa6efb03d169b5dba808","781a64598efb2a11156f07271ba1c14c4f6b3d73aa2943b26eae02063df7af70","786b0c2856bf1f3f809e5903b0a971f1e072af5635aa50bbb9b1449f96d7b694","799abc1e8d381b8d97349479139985e383bb49179b5a80f39807cb35a3ee78ce","79faec494bdd6d098c9d2a9d8559f822938c6b2104188db95321d89e7a732979","79fb2e6e6a91117b6aefbdaabda23ccfa596620f548ee5075993a8dc7a8b872f","7a032dbf0351aa32c77c8d187f7eb697500ff186c88c5946ecc15adc972246a6","7a134e7f1822183ed1c0ded720971539350feaaf92612761210cfc3ccdc55870","7aa52373f2721dd76fc8eeb3d6061794f27ea8d11e96bcb1ff25a97994a77d5c","7ad4ef4b8d3221758a9e7f9577750ee03f6cba11c8eae8bf25f74a3131bd21a2","7af2394d2e697f355439e841b6323ffbbf8b90b2e48bf64873791fbbfdf15b44","7b947ed0a9e6e7ba180921434b993c62ac70bbaba6af0a1618569a2d4b705201","7baa35131ece7ed9860607157d2531d4d70a061bdc9bb9876e20328f127cec53","7c2a1c4c4c03e3d68d63e0ab58e4e34d3f2bc1a4a837a055fd13a4e9f95ce6cb","7cbf970a11bdb91a40e248eee97ef789205910ebc913349698fc75ed35e82fdf","7d6133667f81aa66a98755d253ea43301b45ada338225df034d2ffdfc79829e7","7dd54213b65fa0a6ce5aa3c204b5209b67ec16306b776aed7dcf9e6601d74235","7e89b59b456dde4bbbdbf8079665bd82c51d8e500018472981c15618b3893959","7ead0c68ffa0ced241af74dde58b3831343dff3f7eaab64bddb9954545b7ba12","7efb464c6d7b469303c43f718063d8456df6fe43534b5d8a4229f5b9ba9705cd","7f8188b57ad3b0c28210c95954e5623376a4262dd5e75f002700c6094b8d6b6c","7f91dfc2ea1a3131c4090375db0f489c2a572e245ade6cda4ebd440446d6d60e","7fcb8cba3ed0ee9c342947aa88f0f699bb4f5c23244d21c6c739c9b66d7c6101","800060d7b4934508d0277f90a464e3112fd2fc99af4ef23825d09b0ff53f91c3","800a802a4ce9e597a102f0a566535c1f9f7adfc60c41af6bd2db4fb7fe3c0d0e","820c12fcbded9048a363b9e0ebbc48b24f85fd4a68131b5dfc1b19057bf09ddb","824bff7541ec2a4b0be126f0b0791314d568a0eb4e29073de4f9dbe0ee4918b8","82c419e5de083e423330432c9d45c744043d1bccd8eeccb41e3014ce9ae3c32f","83347356a898238c013dff73246440e361a9e24cc3c4e0fe0e850467772b4938","8343a4211a4d0ffdb320d5a4305174d85bb707d15dad978f6436297d022daa11","83a06a604bbe36d72da976fcdeb88665c762b0f0de44193576ef2e0cf29aa9ad","83a97b9ebb29f5cd014ef5e178970a601ee92c44678f05d1860b383c5f63b79d","85a962a7c23c14dff8d683e738b53f422221697b213cafeb616d3a172a6c4223","85e961266b36e0f8ec2a477f1f1dfe7ad748fdde9d906f7bd3241e6924866ea9","8629fddeb4f273b35df69d4d28923adc14eff59d919b1a495d1a68818137c561","872ab2b2d65fe685b91e355f5af051c85b79569ece16448160d01fef38039624","87789dab547842b4e0c822758e1325a3cbb046063e11e105a4779b3741e01cde","87f2b3634baa504f2ed9508c6cf6a47bbfb36214a177eb13d70d6a987706818c","88b615ef6a31bd9958e98b8ea522f49f0360ccac5d9fa8deb9e3ef3fe3147d9d","89a96597dc9c218633adaf94bb5d6dcf4cad8f5e0b6f5522a28e3ce8d8b2865f","89cafbb20d6029656266d8cb0f85103fa519c8032598282fea58c94cc59c4125","89f2105745b3a7cfd30e7d7c598d6c8fdde0a599f30fd0db7382cba50412445e","8b3eec010d1eae43a28c88434f2410a751f790a9d6ec4a08e75e68c171629ab2","8cce78271b4f001606069a575a172041fbddc52de6b582c920aa3d3b5d5b67ae","8cecfa09651c40be4d7c11c117c80e1911dc75bf6f1cc34be64706823cc024c3","8d250acd40c8a24ba0d51cc73e65bba6856509b5fbf4c7d7a435897a01c6e764","8df1420c27503370db9382f68a0af8d2b4d56f9dbc94b24ffae450a905083a79","8e7371228a726f381fb811d1d812c39917788a3df7e53dba1a3c364e755a0c03","8f3827158091bbed154d21c843284ad472a4552da2eeb858748aa29676e45662","8f4a21c70e4b933eaa4f9cee119945dd2ebeac532e82d34e17511b38cf03608c","8f6debc54d2bd7abb42f581f2204fc78b27ff8c67ee4b6392b4d71c5f983ee9d","8fae27ba5117e202afbd523b249fc454912571900fc909f5419b8ac96c773c44","902b958b4db7d8d8bf73a82a8aa86e5485b39477047c8ad60175d118fe31d987","9056c360e59fc78edde932b54124df317f2f04a90c0c6eb7825a87b89edf1ca0","90aff66decaa3a0998e9a6741963713c0c82fc70da505519e3d60204bf715fa0","90dc4cac6326293bb54486d3c873b83299e9a5ec8c86a68bf1cc131f5e4e2437","918126027fabb7947dd4ae810dd561ac22167102f9f978f86906624ebe88c9ea","91b495938bc6015970bb02c844368d3eee84425b472772cdb374a5347db86de9","91c9ced5e9ab8da897b7f69166a7d0bade5c58d511b42d60d5430d536da45d09","922a332aa100d622da733aea8fc74094739bb63cd480d3349a14d2418ab6b1bb","941f70c384905ab77cb9a88e2671301117e4df553da6fc7a09210710deb9b6ca","9442788fa51227044803f1d3efdfc1c2b2da372871a85f0f7a6bb3596a5c003f","9460f427df72c238c4b55f39c8864f1fa3685b0716a53227ea6f7b591d955c82","947a1cdd43831936480167169d30334f818bb5d882650a3547827c05204af111","95f0c5f3b9071db39fd72b88ec9fb2079ce7553fd5884fa527bc9216777d7c10","96c4c83df72e9d860e2ee51f1a74bc867c4a45efc8bf11bf88aa82e368b89aa4","971f59cc197732d0c0b6b8aabbbefca4550fb8fb04f8522bdb4257c05a28848a","97edc66e594bae06bb273db84a35d84c8162a1fdf55ed46d781419a9f6a2e4f2","985638a05562bb796911ec231d306b81e36ed6b58219b3bde874559e9600b59f","98a097d6ebb754334250dfd3ccc5f3dfaf5966524758cbfc9e10adf4a0229693","98c7e4bc2f05e9b4ca703db4a02347db7355a44f04e3a4003e26c46a56bded2c","98ecc99d3396aa9a35ce97456be66c1aac0cc05bab88aa99109649291e61bc0a","9944d1a9674e555a41d31d069d136461eb06dd4052d40f2e4ea4368dd978e01b","9a8f2389b8ebc29d3769868ff8b918fdeb2236d88192fcf76ab0ea3db0857fac","9af18d8cfee466bc061271d82254d7ea638b59b8d5a3901c6610d5baed85c38b","9b01e565a1541f9e652d7afbe62e3bbff28430c1ccac2226ea434f45fc9a99d0","9b466e8fcabe551bb6292d23a359be3ea15b7627a6ad9c9e6a4ff11444c20860","9bac7daf255467f47b83723095f93fa4b574d5fc08593f48825a2b2ebb8e2dd8","9bbd03293bf53e9db51401d157b3eb2aa51e9c70449350e98b9a0a3fc9a684ce","9c3b318c461b56a8d277133a6b947ef5618690ec281c42e9de6c27f22458d4d4","9cef1feab6841836dc20527fcc8ad9979671fe811ff80a5a33bae113fcbebb97","9cf90b3aa59f3ca0e40fd9e1fec9703428752d63bded6b091d28f614c9ba99ae","9d1a0da545eb6b2e16b18fdd305a2c000ff2340c19ac843914b45f6a4f936227","9d8637e5adebaca208f21af0a254e80712988867411be560031f4b7a23cc04f6","9e77badd0923fd79ca9761a41780ee4dd4f9ca9b62512f4fb59c7f8418494da0","9eb67ea41c5bcb9557ba51bbbd1b321a78f16335cadebbed848d8e6c1fc68bab","9ed400941ed49b2d90ebe3cc111d90d8bc966608ca61fe9bc315a3c1dbe8bc1b","9fb8c5aa087d38dab064a2d6054826377eea3dda98229725c2523f63a87e4750","a0ff0d0bb3a3c801b637d091293f2eeaac68e934274e4116d298ba60ec3461cc","a1baa1f699fd4ce19e8ef6cdfe346e1b0be63e16d5c5cd5feddcccb16a62f269","a2aec2d2f35d7174801247141d637e77c4f34e478c575b0e0a04c6251efaf993","a3c84d76be9d891812e795dd46470c2978dceeff928d729c0d5dd6def599923b","a3d6708506fb5c28f45f0d610bedba11b1ec7bcdb363ffff3aa4cddfa515f56a","a476183540f2e7121e533bf2dd9125dc071c81acc880e88cb435cad7a6d35b97","a4a8cca930cdfd15285ac3a7aa757d61501fb77fc12a7c3fbd78c096b279cf63","a50654761d6812cd811df02199e1b7b25c9b0d65e591f65430f9277ec43d9c50","a514a8c0898b6697696ca6f0ed9a43bf8993085b2db4299e3e9f8e3419c4a5ee","a644885c31f390b5e6b7fe2fc8d086d9144699295ccb6ffa51b3f7c76c8ca71a","a64e8aee389ae696d0d4b045c0153092113fa522ed5a0fd9b5658b8418db4ded","a6c531ed9bbafabfdd649f3030daf2f24461163aaf99dc73bb24dddb77bbcb90","a7ff7302e668dcea1cd1db2241ff95c0d73534539bd03fdefebbfb57f60d3849","a8b4a33078335d2811bffb78eee49aab5fcb31597dae366d43e20c7f7800994b","a91a47fb4fa5c1b1a834fa602030e435ad641240e6ceeb99eeeab7341ca09dec","a91c8a1431a4120667cd523cf56bac004794fc5b8b24275ad2f9c8a15c75fba1","a986593807953215f834ba73e7d2565659b32aa849986013f8614bb1c61ea8cf","aa131e74e695292adab9f57b3ccc5a503a836dd4b95a3b2b107c69f35dba3637","aa4103342641899dc00c22207c13ac31c0c73afd97771b0a9b249187d979625d","aa70263d079788757f176da269e554fef9240845706f87a93101591f8114e807","acae1db4aeb323f3b637fa11b087c3827a2fb6d69718362f54e3bc48f70ef7d8","acd7884bca46ea9422503cead985691da05cca25bd5ed52a199783cae7b8b01f","ad0e6d78c1e450e19bfca4a0e904644ab0ae315607811a28ac3dba20de869786","ae43a4d252290ec0e18c64dd58d51bc885020b2473e71e3ed0741184c9f006b7","ae69fe306bf5db346ddfa4367cda24c95e44213baca27b0ee7d7167bcdd85af6","ae8c200dbcea29f43b29974cc247d70647c80d5d76385396f1c82ee9f669e2f1","aec13a075b84253397fb97e1c93a23e1aaee6d6bff2a9161bfd00a5b1d7611de","af12215a96963c1e7e5d766ed994695e423e4780ed0b3007aed87b150d090c05","af6b60ae365a6cbeb140430b030bdb667f53a2a97508ae92dfc9ed91ca73b54a","b09355a97e3aef396f681943b37a404a98fccc6bcb97781eddb2fc000d1d985d","b0ecfca0d114bae34ffa62ac3ea05159a4415fc6eb73ab1fcc4d79f657268f19","b25c41f19ba40e646fd9b6f82051ee4c38985539e445b26bd628eae98537df53","b262187aa66e8a97083bf7f79b91595bf7a4077abe7f8be5b00b4998f4579d20","b3f50ed7eac0e9c54b74c4f4e02297dd2d2465ce4b699bcc15cfddf54c0f0f81","b4091f93c3d96e36b0708f5dcd46e0e7a0a48f098036ccef6164e4a6429ed94c","b4093c67a9195ee7d28d2575e967ac80057b92339489c244243c7c504c669ff0","b44352445272089cf90967d4d413cf7009bed0ac19f3fa95cb831d5ebad081c3","b4ce73bea5219f1b27bffb36c6a9dee14447a710a8938db807770083db4552ac","b4f2140fb766faf0065a563ac3664f395b24c81dab0d0d0d01df47b22e888d29","b5102ef50e7d4ed1925af5a8b45192e737df02fafb75d7065995a2bb93d2e8e1","b5428b5775526a00645566822530fb969b82247ba83f2c80c06d34151e1f9061","b5c085be21651d8579e52cd3ffe4abe6b7f45c5a9ee84d38c47b4734409918d8","b6cf3b02f36e0efa93b04667cdc5701340033a09e41a7196277cf6756999a666","b77c6669bcd54e0fa949faf2f7205f2631acfbc1ccf79f93f8dab5c5717f0e93","b7fda8f4bf81f8213d18e3c314df5100ccb6b8db7aed6b70aaf202deb606a14f","b7ffd6cddb12384224772e8de79aec89d8f4bca966a3c2a05763889f92a6db5c","b83b7229045affbb98f8fc46f289ad05e6626ef52e3ed2f7e70d332a54a69e2a","b83f5334b85422ac110a24286d5af7003f2fb5b0d783efe257b38a2281656422","b8abe10a2a92bf537a49e8dee92baf8de3ed591848a1b25151dab0d7ab3134e5","b8b8c5cad182083f45ce2d05d036e6bfe91cde1fb63f2e5a97c683bb7ef7ea0f","b96cea09313d481dfff1ed1a2c552ea29e8fe68f52139458996a4e36157748d2","b96f9beb6d6d8fbf88c4b8b2b807a362f2640479cab6173cf64c7710817785a0","b9ad2510d8249ec4c8e7fd8b2471727aa1bd0ce8f3dde78e545fb2f8f2985a1d","ba5c707cf9be40fe966c08807779994e20ca3f30ea9d73e26ce31ca334c05640","ba7d7464da8e13722232c8f86273774054693681becc450a68aea21a5a0e9b91","ba87e5d43ddb10937bb17941f055f80a223d0981fbba44107aeec8530e3a7774","bac3431138e986d6426c1e81bdfe0a968394896c0751cbbcc8f36002fd0ed069","bad8f17b1d399ea125c524895571601c90b6c93418c248bd4ebcc7886bae9878","bb230236c4ab6353afb4147014c93204d3d1eb8a6d18558075df5fe79ed7f392","bb7fa81e41820d63d58313460f5a3999a1f9fc2cd2fb10cbb5b41a931d8be6a2","bcbef69f1ba50e45f3faf1b4529c32cdcf1e5a6612b5bcbc6aa6790ee14b54eb","bd3bf6053f4d423ff21f7ffbed9d0e68f3ea64b7292c048e9a37ade342bb7b39","bd714f38c881208f1190ad714bf8fa5aa63adf302bdaa8ad8810ff279e43459e","be75cc1ee935f783be39978de91ae196c16141d4096e16eb6d07f59583296b4b","be8c3cb2d8d67e63c8b069920b74c6272922febbc6a0a2c4a0072a7a213681d2","beed0f36d9b1b9a20bfbf89c96862482b8d5b9d4284bc89539efe9c9b11f000d","bfd21b5c8eb26e9d475868bb30d66ee08f20876e9df5cd06aa8fec01ffe666df","bfe97e65f2cbe6bcd0f14ff57ea4dc1dedb2e5f0db92d04d0982cf1932ac1c3e","c055d3cfd85b2ed4607b0d9d3a15ab7204c9f149599f748347dca4afe102af0c","c112d36ba38c362da1c022945db5b6bbdc3014685ca9bb7d940f5086f00a675c","c23a43ed460117f663cec698412729fd91b5aaceb48cc4e55a785b525661bf1a","c23cf45c1dcb748145d87f5c173dd3c8becaf9e3f6fdcb3e2ca91d6726b0842a","c24546a064b9315172ce0f951bd5fa2cd1b9884231cf1bdc1dc714771f1b3886","c29b8d250a7b5e73f4ef675329da2251b8de032501e4836445b6aafd90c645fa","c2e96d98c8ebc10237a2af1c224f626acfb9072c83078f4a8c6d9ef0a58b4a8e","c329c9df0dae8a036da9be440432d045be3ee13cf5664cfa6ccf11576ed11acb","c4600cd5358b5798a075beb54539d952f200def1c9a573bd237c795fd33ba36f","c4ebd58c4ff78c9fc0cd17d80ed563520f7908f9d1106735ca0f5a7abed202a6","c5db39bbdc8c2bd2aa7b58c28c3df9e407955cc3250ce7825c842cc4c30eaca3","c65325f807190f7084346376e2f48fc2b6bb946004a1fac1d8d117930e93d462","c6752cc3c7ad06d1e9f127365f078919ac46b77f8a8fe413650094d914838ec3","c6867ec30530fd3feca89a4e968522f783b636b165ef74f288c42dd50bd51a3d","c6bfbb004af355e96ed5b4c8c9b8b7a96d1c08d24bcde7c666728eb9497d6d71","c77c4d3f536cda10a71fe6a9cd17ea7c1408200e2f7aa7c5325d6915ff250c85","c82f38f23e7ed3e1024661b7a22ff694e88d3b268240e2bfc98e630df8a062d0","c8bd340e6fc7fa3e97415f7ad4c22c51d88c6e77f782c12923e841c04d3f882b","c93cd4cb5cf38fe6221fa8ae171ff54240b5f99ba80cd740ffac69c57e5fa381","ca50b525d7aa7762c56f402696dd464841daf19b036bb932e325090004b4cd71","cad13b6653fd9f811e67d13c5f01f9dec047f8c384097cee01dd2e2db39e539f","cc24c3770587f2421514fa399d2617201752bdca145ac39058de91d45d3d19c1","cd2da00f6f1bad8fb7c1b87cff80e122eb017e44a471cdea769efc67db369038","cdbb7338988f2fd35fd92f21909b7801d9954d1c7ca78401f52c9313f21fb6dc","ce887fb65b6977a2046e7583d704863624e55909ebcc9c3ed065b3d13079a410","cf9223c369b6fb7baa52f301f904352ba8e8d5e4c2a06f70de6ef1cf76fe1b84","cfb9705939742247da0cb71fdfd8b5f7a1bef6f1c2f0979a8f42e54c4a480980","cfc3b5044af37ae7485fba8067dcb22b2438bdaa6e3a30c22ce0f9e2c00aa597","d0481d9b6111ab4afba0462e88970b863284807ff44ca97364c84952e3f88583","d0973a1aca6a118375b466d6e91821f8450110fdf042ac848ee16912012d2b0f","d0df3068db679e24d9487ee09a6462ac5cf3df30f46ee466b66feb6dd5ff71e2","d151ffa66d8d096e0272f0dfff6c27e978cfda570f7498a727593081888b4ebe","d227e0a73e3c5452bc5ab41ea2c695dfc0ff9b0c1c81e59ab3173f796a4157cf","d268e680ee1136a239a40ebf005b30db6f3b52a228016f3193496f86250f15c3","d2989a1607fd5303615937b8c117d127b1b1cde519662ab1e1324390220e8612","d2cba4dbbfe3d026f825a8b470a2f6011f9b8e245cf042ae8889afbb17dac6b2","d2e4c515093f8a2aa824c8b542a016e5c321065f4525931b2fac4f8af2fe52c6","d31e8aa21d1498f2d4a07c4cc89ea6f5a6d3ce54d334dbff230e0f55db35c85e","d36034e2f9cc642d0f9f24cf834fa741bac5b8b139cbd2f50e2065161c9f3cb0","d36eb7456d2a42d1cffa4b60708e2bd3116f7f6758c96bbc0fee0f1704ad8a79","d37de74aadd5916eeae243decf347821c4e946356b9f70471658638ac3092f91","d3cf9b1433fd9a083c60baf6ade1df7f2a33e0cc7d519f491f9d6a93139a41e4","d49d02cad8bbfeac607457b08aac6068916ef45d8f6c980279d6e654407cc7be","d4f51c31a454d9abac29457cbbc21e1b5767c0eac1b37c41ee787a3efb05c80f","d52ca358246f638d0e11a061e97863697df44f43b093d6e8b84ba67b5838f2fb","d555a0d2329caace197c1468fe6708349125762377ee3bd04b031b7eacfc26aa","d581443d0b6b42c76b816edc6946ce01a639ae42653ddc8cc2d6a89ce14fe947","d5c084e12da4a5111487c166b879042a21a056f761ee22d9237cb4f65f366341","d6077d547aa21ea10a9bdf6c752b8d1a0a6382b4b43a0fdf790f245e66a609fc","d67e8c1aaab1ce6ec1755599ecde153c47c6b90dd4c301663abe9057bc31af57","d67ec5caeb2af5f9c57533a34cbde7daba5f5b2e5e6ce34c3250893eef25f13c","d6abcc1484c3df45bde915abf48324af1e995c3266a3c6c069e98e94c8d9a4d7","d7a44c85c25ceb7d42280f0c2576de52a3b3cc3ad2333e788ecdc7f7f7fe4b3b","d84489933b19a8b073c65a0386e39e5067830facdc365ced6efe1948c7201771","d8c8b3c52c89cd715a7fdd2759a6f73c3a5f505303b110656cc35f7549a37cfb","d8ca8e025e226ad6bdd32a6a9fceae2982b0413a0ad09314558b54bdc724bf99","d8d03142030c11a0aa1012102fce2b202baf88e424a1236832937e87450dc579","d9823dfddf6c507ec030fce4bd2d98fbda18e595c2ebc563574d9196cc7a5e33","d9b0972f3406075b860ba7cd2e71d4492c826960319b10389c2c2820e2981254","da37a61fab07ec8856b725854e4064f55a59149aa69cad1bcbf89ec478b9f578","daa0fc9f9dd08cb2dc48bf33c9808cfeebff77cb9fba48f98ef597bb9dd6df55","dad01e5bfb13a6c4419f4d24fa8dbb424e93a1c4be656b0e5dd48ac546e0a0d9","db049e7abb7c75b608ae25cc8a9f95959f7aedaa53e22390290319cc2eed3977","db21a75b4fa6165f75268963474f3262124795d816ba80f685bab2c6eaedb028","db66a999537b941fa6d512908894ba86e8dadd0e14b290ebc119555b7e60264c","dc8c31e3075adeb63113852569b83dcd432485621eb77fef62cf3cce5c84a214","dd97ab52fd89f42352c595ce137684cc519c473fa17969e8a6adcde7322a4748","dda0a34d6704887eb36bbc0173334b49d755cac8cea3bbd17bfa972f04183dd4","ddbda9408727a19a4a55d516bed99331edf67d8301de9c78564716465c949619","de0f295bd0e46f29db1167d6c21bda624887c8543545d0c37d662e5b1b312341","de9a46da1f4605525b484a228f8bf356a9d900ecd16473faf77944b22575c141","e0288c94ca9c16a6de217e6baeed720fcf83e401bec45bd15ca47ba8fc9b44dd","e1667469384ec775a3df665679cb3fef057dc84dcb18ed8db8b9c5723835968a","e16c328504278cfe520d6d99990f2a4370cc48159aba86694d0f7598fd4b0611","e24df071f5325bb3a5b20f355143556bc7712535ee8b6ce4c426598f06fd2448","e28d8e6b71264d0bfab853e63178f2c151367cce0dbd16125596ff3604b6658d","e2c734504d211580b4e6674eb1c7d31fb6fb730c037210c34c980a96f9098269","e39ee882667ef28feb4971b73f9a01d3d72c557e1e56d59487af8e0f1b21edbd","e3f19c383354cdf45311f92f00b90fed25dfba7e9892ab2f5f3aa4885876b75f","e409fbfe439455330c0fe003de860e30f7093cc3cc83a32f886c9b539a29f60b","e519e78acf2938460c7ee053981c744dafc7642fd03b56a117d5fec78d258b90","e5db07b7fb0eed216d838fbeb9491257cf54f9bd537a68c8edae7a89fe64c8d8","e6300ee8e6c2c4ce6d7ab02b7b06fd1cabe3c5c52b99a6ea3ea8b5acd5092e0b","e65e28b172b77d093f5425112bdae7ab93756487226fd7363057f85bb2a2556d","e734d068446591aba283d136c21b4fb0209f91352cb4fc6589bd651cdbfec163","e7556cd0bdd06760602ef78c5e3b30b4dbe175f96b7147b56ee2ec181a4c5ea3","e7a333109a7aaec2b71048868500c15e721900628eb48790dfeaa1fd4c2dabc3","e7c9175fbfd9fd84bed95d552bc0a439b07a233c3e91fb39ae2f23197ee53f1b","e7ed299ecf44d4a96c228e9aa30312f405df34d6bea99d4b0f7074c79705a671","e8bc1b4f162c4066d74e5d1b3dcbe344742279b6856736c2e1690dbaa7bcf932","e981ced1bfce64a19fa8de1cd518a93f4669d01548f4819d0e1dbb50d266fe04","ea1b8a251ecc1fd96697d0c602d3e14ec46383d27bb9485a0326cea5576ffacb","ea311dca2ef14e02b9aae563bb28dc737b04b7f01c1ceb2be3d92007d2c74ac6","ea8e5b79bbe5329ae8437677c8316f2f9fd75bb1d40c88308c269140a7e564c7","eb708890ac7e19bd53007ccece064f7e2a069a3751270b4fdafdd1668136dee7","eb996138bc91c0ee63bafe1ba10b130ff5a2fc82aa4918296222e0a831a569fe","eba6e8e5a12a86f17fade41bef365aa95491c469e18aa91aef64908a4263c905","ebcf0bdb3541c8bfb7c9a53f632329b77341cba6f1a2fa0dc9704acfa3276dca","ebd87e3505f3a1adff0c86ffec6c380734df718301b216b7ee089c174130de60","ecd5e83ba8c8eba6cef9c3da1edb8a84e3dfb4ed71d9a2c1908f2c4d26b26737","edc160a11c07dda8072748b66db7f27b6cd8efbd1faa3f6c826a0fe445859c17","edfcbe4773eac1fe2964179a4ad21294efede89568f2efd8e283ac18bc5693b1","f0f90dee84db760cc1bb0f6e6983d4de0e3d5d9f4adf7b2b52f0d3dbe6d585a4","f1297fd9ecf981024e1544f7f048705377b53219240274bb803ac30e4a52084f","f1d4a6e98f41ab3f6cfd67cddeab9d0ed287b92cb3dbe575e3ce61925510a792","f21c3a9267110e469f224ac7eb76ca5bb084fc90df014f1ca6791d5770483944","f260b4b268e85a8f1b04b2fc69ffc0bca473d2e42de6f2f70128bedc16558201","f379a1b9e29aa7fc25c4c0c897eaa3c0e90d66a201a0ade8cbf523a5cdc8cf50","f3e04891c79b604f9235f438adfa49ee27db43d25c7be0d1cc06ae53b8f6d2d8","f46904e701174fe2850798d9e1b077bdac42fcac01dbc385298da01118c82aa6","f4de28905adbfe6ae4bc38f8bf5f47a444aa8d0f2023faaa431d6f72f9a3edea","f53265f53af0b0856911ab08b373736964d0c443e8ba61d7f1d45f5e5b04edf3","f5403593ba12130c04827f88d019103e924651caa518b7c290673a02f7cb409f","f5681dfc71121ed0f88146a19479675f2fabc6ed376fd5d162e50d815c048d66","f686173d310f41e26e3fe8a7c1dbf4313e4d793323335348badbcf4633f5d699","f6f5046c1263095a69e774716b0cd0907f6795af8ad683c5f41846d4c54a3449","f700bd87d4a758bb71f47731121a9b2259a9ffbd50b584b82f4e6a1f205c276a","f704c9c9e2cab1ed44578f48d161320b5fb4384ecdd8b40a5e22c4078a8594da","f7993302f695430a0ee938b1b3684fdfec4055bddb378b52c81785c0319e8c98","f89156489d35f9992d5971a52a6e03a7d7f095e15c2c782e85efb1408a2bd6be","f99ef6fa3c9c6bf572ec69eb6eeea9f88ce6590d3a5565bec62b001b6f2a376a","fa2dfc22b4fdbcf402a822e8dd376925655d997a0f96284a60f10665ba3581ba","fa3df5f8349aec4805bbcd279b88697def63f2462d8ada0b5fe1d9983d9a6daa","fa6b97cbca1d4f09662e706293b0aec1eb76b8e2277441f54ab6c548b5423236","faac0c3fa7cdf67b452d407e9a1db5cbe1e9140ecfe300200b0b0a6279c97c66","facb45d3084caa490d9b0ac2bcfcee89629a4c3db5926ec9256a9d27d25559ee","fbc8b53b5c6f3727c084e5e0429e410a3fed5a17e1a0144692fd196d9836a4bb","fbd74e4b8dc748b2efdd70aaab07adb80d7f15a38c1261de85bdfd9591ff106a","fc475f9c2d8bee2ffea435e86e6b39b6e3e071143a4a1fdf6765b0da13b66de6","fd04d7588bb9e6ca0a8b65ed0c9635082a9ee5f46b2d1b5b25866a072236c1fc","fd60f2a432086c6fc4a4c39d8d2d6edf5794c763c05a6401db2bb5fa2c601775","fd618761103380d690cb98804e8f116b6c66ef049fbf67c1a059ce49188658b3","fedf2577267d6dcd060ebc4ee8de6ccdafa60ab26b78d74c1e8c784252fecb17","ff532716738e2fc716c10797d9717f324cca3a1234320a84a73a0b89569f11ab","ffd0fe3449e449c7b9fcdcc7e2c1ffb677e57ad935a252de88a0122d437efa67","ffde5c700732beac27a9b5162213d387422ce199400e56d9cefe550005b6a542"],"schema":"fsgg.atlas/1"} diff --git a/.agents/skills/atlas/assets/seed/records/58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608.json b/.agents/skills/atlas/assets/seed/records/58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608.json new file mode 100644 index 000000000..3ee7bb61f --- /dev/null +++ b/.agents/skills/atlas/assets/seed/records/58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608.json @@ -0,0 +1 @@ +{"citations":[{"path":"scripts/fdev-lane-capacity.py","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"3657c8432792a461dc26f97a0375c3a7f8ead038408ada4b3b1bc8e3cd650467"},{"path":"scripts/fdev-tmp-cleanup.py","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"6fcb5fe6d16fc56f042c152502d1024aae5b5e7f0214b54fa26147fe7f08a083"},{"path":"deployment/fdev-chromium/fdev-chromium-env","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"8cbc5e158b1619c23cd4666667e1d5c316de6229f71ccf5a888576050ab3b2a5"},{"path":"docs/coordination/fdev-host-hygiene.md","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"af791bd6cf7e83c3cc0ff28e5b725b3ea1248daf657c1c257e282379b8635e61"}],"conflictsWith":[],"id":"environment/fdev-host-hygiene","kind":"lesson","recordedAt":"2026-11-02T06:57:04Z","repository":"FS-GG/.github","schema":"fsgg.atlas/1","status":"recorded","summary":"Observed 2026-11-02 (FS-GG/.github#5240): /tmp on fdev is a 16 GB tmpfs shared by every lane; it filled (about 15k entries, 9.5 GB; fifteen browser-smoke mktemp trees of about 232 MB each and a 725 MB fsgg-gate-engine cache were the bulk) and caused 38 spurious SDD test failures while many browser smokes ran and the quiet-host probe did not admit for 60 minutes. Delivered on routine/5240-fdev-host-hygiene (cited files at the cited revision; merge and install are separate effects). (1) scripts/fdev-lane-capacity.py holds at 2 or more headless Chromium MAIN processes (argv[0] Chromium binary, --headless, --remote-debugging-pipe|port, no --type=; renderer/GPU/zygote/crashpad children and node/timeout launchers do not count; --browser-hold-at, 0 disables) and when /tmp has under 3 GiB free (--min-tmp-gib, --tmp-path), JSON browsers.count/pids and tmp_free_gib. LESSON: Chromium rewrites its process title, so on fdev /proc//cmdline is ONE space-joined string with a trailing NUL, for the main process and every --type= child; a NUL-split parser sees one word and never counts a browser, so the probe splits a single spaced field and takes argv[0] from readlink exe; checked live: one real Playwright chrome-headless-shell -> count 1, two -> hold. (2) deployment/fdev-chromium/fdev-chromium-env is now the repository source of the wrapper (it was only ~/.local/bin; environment/fdev-headless-chromium says it is not in Git, which this supersedes in fact but not by digest) and defaults TMPDIR to /home/developer/.cache/fsgg-tmp unless set, mkdir -p then chmod 0700 (shellcheck SC2174 forbids mkdir -p -m); capped at 32 bytes because a Unix socket path is at most 107 bytes and the SDD race test binds /sdd-race-characterization-<32 hex>/inputs/socket (TMPDIR plus 73); mixed TMPDIR values may fragment MSBuild node reuse; --print-tmpdir serves .NET runs. (3) scripts/fdev-tmp-cleanup.py is dry-run unless --apply and removes only known names (fsgg-sdd-tests--* idle 1 h; fsgg-sdd-, fsgg-ai-tests/ai-tr/resolver/cli-tests-cache-sandbox-, playwright_chromiumdev_profile-*, org.chromium.Chromium.*, and tmp.* only with driver/run-smoke.mjs, idle 6 h because they carry no PID) whose owner is dead (PID absent, and no live process references the path via cmdline, environ, cwd, fd, maps or /proc/net/unix, relative words resolved against the process cwd and symlink aliases by realpath). It refuses to delete while a same-user process cannot be inspected (non-dumpable processes have a root-owned /proc dir; allowlist systemd --user, (sd-pam), sshd), uses an iterative O_NOFOLLOW directory-fd removal that never follows a symlink or crosses a mount, and refuses euid 0. playwright-artifacts-* and fsgg-gate-* are deliberately not swept. Hourly user timer templates (minute 37) and install.py tmp-cleanup and chromium-env effects ship in source; Root installs after merge. Limits: a dry run on the real host listed 874 of 1077 matched entries (3.3 GiB) removable and removed nothing; the probe samples, it does not reserve; lanes still need TMPDIR set to the disk path for the pressure to drop at the source.","supersedes":[],"tags":["fdev","tmp","tmpfs","cleanup","capacity","browser","chromium","tmpdir","unix-socket","environment","testing"],"title":"fdev host hygiene: /tmp is a shared 16 GB tmpfs, so hold on browser count and /tmp headroom, use a short disk TMPDIR, and sweep only dead harness dirs"} diff --git a/.claude/skills/atlas/assets/seed/catalog.json b/.claude/skills/atlas/assets/seed/catalog.json index 482b95489..1b4569c77 100644 --- a/.claude/skills/atlas/assets/seed/catalog.json +++ b/.claude/skills/atlas/assets/seed/catalog.json @@ -1 +1 @@ -{"records":["000ada42299601fba29016e5c0e0d4012876fb42670bb10fa0b1315477254ba4","003893cc49855d17a15295d7adbe57ee301ea20281dff216461baee0810853ff","0052dfb9eafceabaa590f4497e4d42f19020718c84b981d265edefd432ccf8dd","00641d046d6869fdd0023ab3df99e0e67a6ea28f0dcb701f622b1cec8b3e07c6","0066d4a624c02398f21b4d7a736a9fb5101ed8b6b13ceeab46907e9401af98ff","026a241141ee10eb829aa6ce461969242d5c1d45fe9ca19f08ef4ea880877676","026b08fb343aefe19177e95b759560d340d372def4b71acf613fefee3438ade2","0357495d23fac4fad210b6dd7ed7cc57dd33d107e1659a81f085cad78300797f","036c148f6d0e89858c9bf4cf380272ca6904bb4ca277a909fb71c47f5450cef7","04652cbc95ac4dcd21b837b38f2ca5a0ccd4d0946bc13fdb31c9c15a578d3a2d","04d17203f03279980862496517a1f0861be5f6cc8063bfbf92f8f8ac19744fdd","04e404d89dca295564813149472b1de8e6c43357e2f6d91d169ded7600ed3a02","0509e5c6fdbd2dde0c0db8558647080560714804d00e4f9268342f2e84858a3d","06ad2c8aa0ff3b862edf3ba99e0e4e8801ee163709e66333cd06c3fc61232b05","076259a45e71df780b012d29618c17739246c86321d2ff05a6c272bcca8db675","076fa091c878b19cf56a94be0966dbcd58d52c1839f9d4b85bbfdef650cbdb88","08b3dc660b9d2bbbe75b590b2b86d941bf935a254cd5f09de71ee6894f4048b6","09e90ad705af012a8c36efbf296757f35adf9c9ce3b8908791c75d72c192973f","0a6d7dc5b64970bfdadc9049ace95e8bc163fc421beea70129ff0eaa692c6d06","0a862ee40916522f8ae5f14b3e084bf5f2e6488185583346db96ced16ce7619e","0a9df276d42b56d98a7802befc2404204e0e5ee8bc7f5c032f7bb29aa4ae2091","0ad4403c8f4078dbfa543310c69bd1dfc768e305987214ffc37d7b2600c4687c","0b2d1557ff6df5f4d65d540a5403b07ba81b381dfc799b7884ac72dfa6ee7753","0c22360d4653eb0f450e4d3d34564875f1660cfcb2d546095d98b3faa3967cbc","0c7d3f36e3bb4270edbf7abd99cd2dab772df274cad1c27c7e87e302b8eb1c23","0da4d093b49c0a1f654b38008bb01195e816829279ca1989bd2448194e15361b","0e560af7d9dd2e0f2f588a74cd35512973747f20bdfe0bee0bc889105ea53dc9","0ea7107c2c8edaab3ff2bae32f63cfbef6903a51cdaff257278f757ed5ef429d","0eef4d717eb03f0906aa3be7336aa71f831726afabe8a56077b76f6e82fd08e1","0f11324ad653d8d841962b0eeae9f68b80243d4ef7df4f2404ed4c3e45ba5197","11fe30832d93706c60efd836b09f35f049c4a715ad6144cf277ca240c5780704","1244d27db0cf5075353bcc622d0fb3b5ca6a7d08526e2c5754e8b745c250bf3f","126c817ad25ca9cbac2a0f7446e76c79852459ac7b9c61e3ba5d5cbfe5d37dfb","13824d6bce0f961c89eef4bd3c8a72ae6ecf7a1339b9e06eec964dc5c12dc544","13d0363b8d765c87a57eb42c4988320a9c2e7fa09024aa972f4b13d7699a552d","14156f1c6bf0fa8dfcb5cfafac09e012db446d528dad0e4301404fd693b9bed3","155fe673b8ae12549c978e1bf1d5c43e360937fcf2135cdcd5aea6f6c771da44","15d41240067e2335a0354a4e910b6610f2b8f079b8f67186f10181622b4a8999","1746f4f9d47b7dc42280dd34e664b3ec410d3cc69ac76933707499ffa34c79d4","1754adaf40732c3a8c73d2285c25a8b6c8c9d3e68370de618a0ffa8f3e60fb6d","1945f527afc3c2930ec4d7fa57ebb2ef7dd6321c0dd3ab9233c9963e9e613165","19d657b67672257ece127f3b957674b7fb4780843148db0a36a0b329c2a418ba","19e75be8ed4dfba2a6f8034154052160a7a181b17d887b3e8724f3e3c111c31e","1a24f6ef0c08a898f309c1b925fc19b29526f913a61a1dfe4b1a4308ebdd97ac","1b3ec24337f0252a00cfeb6df0a0f5d2b6d737dbea61b8d0b4a643f4c686df6a","1b5351b2dc647aba864e387168db5128435cb80da94fc42581cd60a05fc34b9a","1b8cad98d53da179ab05eb47c1783f4c8b45b9f39c635e7a337285f5cd9621c1","1cfd18d1b12b25604d818389a34bbaa746f450e70246c7f4242fc4e215fc46a4","1da011289116fe88fe92cb8f0e83ed7ccbbca251681d4e136c5a61c40364f8d3","1ec9445b242d2a2e149fe71c67bf13d8c0e4ebe5a6ed7b022656b9941973909d","1edc36731a9c76ad07d269d8b4fd84c8c956bb43d6f56de17d6208164856ffbe","1fec5a63a7b2b212e3e5d5222e49061f3b924966c9741294f5630836be8a3925","20901b579f69cc97eb56b492938864667576e1c9bfacf13f8a529c4f6e543448","20d01a387b4d0801cb588492ede88cae7bade9b7ea3591d9e954add1e67cf4ce","21338155cb4f52c49e5072c877771be67c75590d9b238ea025fba5209fd6e018","22ef13e60456fe9046dfe72f20122362aeefbbb445632231b8e364ed9b50e135","23af79bd1e7995fc8162ddc4d830318acb054bbfcc9c7d5cb141ec306da67386","24373b643450d9dd3b8a5b0e74a5fec2844cd8cbca7d8a57dbc8b9ad9eade9dc","24d4f2730d94d1b7f149771ef0e59192f4936d142b21f4a56b1a391e4514d38d","252de742c26409c837ef491f55eb03ffcc99da13fb1a2f8ab66efbfb0c081a2f","253bb17320020b6a5ef8f0958856f6c565a239b4dc246d9e825f8b14da9ca8de","2591526ddabbea03fbdc38bf172bc54f42df9bc51eba7ad2b70d6e67215f08f1","26259abc7fe745f52e06f2aa2abb0e50f189bc7608065f04d5c669a0a99941cd","26290a0990d6dac0ce9448e05eb934210603356043dcf14a5d80585288e2aa92","26d6b31965013079d4db67a2c403e01f21e3c30ae65953400dbed92e289a0925","288daf614247c260cb673d8674e8b3874ccc4e269347836851f702d7ac8e2f7c","28abfaf6d50ca38af0b88aa50524200c17af9000da83ddbab3d8f9e06e020fa5","2905a2b4a58bd9ec1c4f77fd3d1d246c02caa49d806272756dd039c79521442f","291d3db272eae084d34c04bc1305f2abb26a7e7acbc5515208469b46719a4ed1","2a38ddebfe3380232e35d5a24f9cb9f7c38abbc9c68add4ea5952c1e65d328d2","2b4f7c8dcc95ca8182105b9b6806391666e6a2c3a5c80d3ce5a5f04fd6cf9122","2b5e739c8f9602c585e67554c457e6e53351679afd56ff324f8fecc80f0891f1","2bc251ffb58a0d03480748058eff4c44079a0f21d75743063cef50263982337a","2c76ce93500601e281a41f5985fe4e3926fc8bc9d01ee687f14052cb553ad2d2","2d46924a94c85f4275a449dd3d9eb6c602cf8a9104db19d224e3aa469b858d06","2d5048eeef90792c0a2b9aed7305598a28db2103fed3903462c6c1882733c3e8","2d599c722a08306b98f2d833fb3e4a7acb9dea92e6a58820caa2f65c09803fb8","2df1610ac1b912232030b5507e5e944515b0f1549bf2b76ecfb12baf0f40ccea","2e1bc31ff6b6fb14d0ca8703a02833db749b03e172f2e91f9423f0751e88c256","2e872e9d3ab8b553270e79673060c50c1afd68a41fcf9fdd0a13cba80be0dfaf","2ecd502add2d801eebed39411fadc9a80098ba9ce04a5f4b728a0e4e331232d6","2f7357367d921995f4c6fdaa693392adcd2df4860ef4d25c8dc47f7ddea8c755","2fb2ed7902a8e35dc36489a23245d963026d688008c92fed6fdc1f6bc27198a6","2febddcced970d495778f33fff212929ac99c23adc42be0c1062f5c8676ffce0","3018f389f6928af5830bdd081c9d03530a379f37d1c2f9196e6fb3c44eb337d5","310bfb5b2d061bb733771e5cb7b3b7d25db43af5eda9f806169b7ef9330c2fe7","31fe4b51d55cd99a4692d2cb787d362cb4c0d0998d3e001efdb5cb7ed838340f","32f69a7b8997ae98b9305ee578145d795dbcd39ca4469bf2465e57a0295cda51","335683e33b94cb86b5e426b4faed200673bf850151191a08458136ceb164fd4e","3407ec53a884d3945d86a88d6b9a883419dd426e96b1108a8e6686f30397a629","3442ba5c7643c793f62d90ca841f7891b3dbf97f028bc7b62f8b4f88c1266d1c","34463778cf2d29e3896a65613cf9e3eb3e9f2d8946d17f12b609e70eec63d128","348ba129b7b9c94e24fa8ddb81024e777c60448d1b5d49f7b2075591b23c13b1","35da3938b72cf3520e126ad595157104b69ab748904c7b4e12f563d6b103172b","3600e7356a3741ef02f8b2ffa6a6b5d822dcbb170771f2ea33312dff4470f431","37c8908ea2a349cd3034018027160ad810b28ad1fc203a9a353971e1f7396b4c","37e39faee019bb041627510f1f02746ba9a85696417a083b438eb4974b72c2bf","38a75fd804821f4836f0a7ba8d41af3d3a3a5f5d7dcea68487009297824258d9","38c6396e645750efcb2f187c36c383471b3b0b59290e3b42cfcb9668594cd0c3","3962789d05f324d436a363700cbb5ced5aba791d782b3c0ea73221fe0c1f0b97","3966e5e53811c43962f5d0953e5da4753eacefbea27ecba9d36af2fd8e4fd52f","397476cf107b48e7a662264f8fea9f880231fd3d1e0401622650f214cfaa35c7","3ad8b0398ba6c354c9e31b7438b2515579fc0b1f17de4b35a914c862a3a11e3b","3b3c6cf083b12a840565e00458e2fd4ee8a61f97cda452703a6b13d7776b6c13","3b4af144afed3d52dd2e1f64e23bc25b3475eee5f7af3bde9886761b15c33dfd","3b5d82795e9f5d1992ab67e078fcf1108247ab9b6d1baeac944d3ec0294cec5d","3bce154e59c5c45216bb5372a352e948d6cb365bb1bd47d4666ae0412e507ca4","3c75b650f3fa8217597b01d3aaf25427ae2a658a7c966afeecdb391d3ba547ea","3d0274f77576abdbdf442c8843e955e1bbc91e9f8cbfe3646b119337cdb13c96","3d642ccf9ca4a0f7f5dde1b41f65c99e9c447cbb9e64883b67e4fdf76f216f52","3d9fd2c5877483382f0c7331206393e42827b5dccfd60549a6771b7a5659e524","3dbf6d1c2c8db1a7e3988e2a84b67a4e1d7c8304661652ffa94db3b7eee08edb","3dfcea4ee3d0d0ed09b1f77bac48b33b64ab4620cbfc74fe0e4201b4cdb81ce6","3dffc36586e9078f750b0a2b4cc2c70a17a81294903186dbe8cc47cf8055b9bd","3e2f66baa16c7ea936eba34720a55897438f60b343cbe8fda4eab1e5dde044eb","3f5465798dbc2ad279ca4849d5d0f819bad01455e0dd2a9d98afd4b55cfbd7ee","40de9f41f9a9f56ef6a51d065270e875b4a85cf043b7c4a0173b2510de4979ea","4134a3936170c1fb5fa6d2e2329185a981436477a66b7d31e827c363691bad50","414259a2fda4a1a49729be6fb1aced4675ee9cbdf990aaafb8e5b3153b54d64d","41baa5d98b5bab2ee01cad50c05b83edd8cdfeeb00f30b9406b4b2ec6d13d738","41c768ea17144c6ec225e9a65d4c3c127fdd7264dcba1a89aa17b20fd5d7e3ee","42aeb46fcc3d10b95e4067bc9cda875fa933b4102873f67c7bf1f8ca6799a598","4320b92712bc14dbe10b56f1cd3d1bdc093fc4be6016732839d0be4dd4d027d3","444342c21a4743af5961beeebb88088f5d2a0649f76c71973a7706a744f5efd2","4457ab439bc8f212d83442dc7500e9d45ffac849d0f77cb97686d9b0672fc3dc","461d34fb1d53849951a7e715e52342372d779299fbcad210794235c610dadf64","46a24cd8e385b748f40d9271b1e856dd6d68c91ab356abb11ff6b65f1ef936bf","46cdf2c207f79d388001f6636dfb7a98bb2ba72b9d1c6df4938f0a27691e07a6","471570cdf8144df0c32aba1730aba24c7e42e5ec317af771ffa169f5c842d117","47b5cb2b011c0f7012d75e88eb86a10f3f0bd48545db139669e654cac1f69650","480f1ede18ae031b164d49d676feeb1090fb33932676ff52e1e2eb24e8d154cd","48262b98c0bdbd5ee2314345726d23630ec1771735db8fe5f1a8590b662c9962","482cd15ecd9cfbd8e1943c0fcde0bbf1d875392dc2a701b698f48bfba684a062","4855e1947afc954cb1b20bb45e7af10b098fa34714bd32e9bc77941cf58fdaaa","48797c44c92cb34fd9a57a08020b45c6920b2268dc8ad616c0f814a3710d5316","48d094622ada1806cb30335926007c1abc476b1f7b45a2e250c490afa25e847b","48de3afdc6ee73ed121d1433bc6367a399286d5f8c2c63670a0b3b9752a36175","49e8cf09e38acefd3a0fa62d048028286d3b47b5ceccd8f51f10022978c47820","49ee4a3f2a8918bdbbafb312cfa807d9982800d13d29ee292c6c0daad8b9b8f1","4a724a6a842a132c2185279513f341b79f9be93e42660f1255770eeae3b1323c","4aecbdfafb68feb3124c39219498241864bcf1ceaf87fbf80598b1dd87a9191d","4b364ecb35ad02b06b6b0f32b6a29202f2c835e1ac0d70b89fd0278271799dbb","4b6ab2768e1ff3716ac8565201c031a820c208db9ea6ae1495dd782e7557a3ab","4be7778c4f491d55154a028d9a9dbb35059953fbcd243e0206902a6e64645efb","4c8c327dacf345e184042092e96ad3ea02ed4cece57dac5fa68ea52fbb5a6adf","4d5a44ba07fafeab823b54a21846269330ce35b4c190f3ddd5434bc8530d9b41","4d86a2764c55b5c5f675fddad8850ce4ceab160ac5c164a299fc098899d31aa9","4da0a5be70e8af9c39623deac83822749482187f6a0fc3d186dcfddaa7111576","4ece7844e2b35705ac39fa25913f6909aad5b4b7446bd637ced46b47c0db135c","4ef30f11bd4dd9d2eef8716d88a83010546e54594b2726de84f6d587651ee940","4f03e231c0dc5c9bb2874f6856382d5b205758af9678fffdc7552d4e4ae9866e","4f1e58fc658a4ceda181e2a7fa249305b09b573ffd68c2489f204f4957224957","4f2750b974c1404acb721ffc84cbd1d0756a24211dd6f6503c10ea74dbc45676","4f6fcf4dd7e73d86e06bdb9c14a1078b61c0efb2663ced9bfbc5f46fbb4c6d8e","5029c7b222158ab3f325168fa543d84fd2332d2e3e38db1ce7b83899cef201d1","509ec9c08864b9dd0029f32ffeac85fbac863e2dad459994c65b7cb5264faffa","50fd7e982eb2d2813634b7c44e102788a1a1cd4910a27acbcf219f76314fa322","52049cc9cee43bb27229e6b3e983e02c6aa20dd7d153b13e3c74bc6d2b47cf92","521ed246c4119acd6b579b6eefa23389a1655df54aa35de7671743979ebfc68d","5382c901d160ca2d79888d8acd7a690a5349826b5da486274b0800c9d7513f11","540879695d41205515aaabe5466971014cb43b960a26b8e5958e37fed63df762","548d237f42167af5cf5caa0ba20f0e7a6387deb6f27765637f078325172396a7","55267f058e9f085117765e4ca72ce875b622ceaceed964f6c396073214835c28","5560616d1e72f0a539f9ebbfea3b7d195c1ef5622f97994af1963748d4f97533","556ee783d8e2e4ca50f656c095758be613983f904d998a6534fb155510114f21","55a4711e799294d06988ab4acf77eacd7d424123082bba3ec987dff0ae13999c","55ae095961d78a1514c4dd1e63d477c60179a8662571ab5a90abd3eb2b83eb10","55dcc23ce52b3918a60029d9398f262216471c280bfe66421cc63240533a6087","566ddcfc45ea5edc695626826ed185930e910fd9107c5bc1844c717b714c15b2","56e7158313357bb145bd98c5f790e569be2203fb2601565a30091a597a7e7ff5","581337891936ba630d34ce9f6b803b82a2130791510f15bab24a07332400417f","5962dd14d3923433cf723d698d1af19ac37a270b6e88445643fc56a646faab5b","5a2064cdf51026eed65457c05f34bec919b31d96d35c29498d298685965f0b5a","5b77bd6dfa81cc339e729e4195e258facbfeb64b9c680512f742e3fb1961fdd5","5c0206d9d014821b52a43d7b222327a89d4ee2f5b1e21813dfa659a69f7426b5","5c3527e43fe24c5aa171c6fa4a3de7fe5e78f2527aed0dd19cb21d154d43da21","5c79c77f00167ca140127b00f1a79e1ffac621e46fc461089594206a7df8d7cc","5ca67643d5111fffd21deb18569162733e846965bf05fe6eb33ccd37c964025a","5d015880319af666943e68169ca906bf2f0c813d8bf2c5c0262aeb5a40366350","5e3a589b627edaf7005c60382475fae7229adc4ffbaab6d6fd03e9f08a0a8e19","5e43baca07fb966bf1c4b3ac06bb819577e477a84c5d8d3a9a19c391ada2e0b5","5f2a75b89983d1005a38afa2cabccc3a39f31989807120281d8505ffd564e0c6","5f43c837f39d207c35a58e9b36fe3144017b2012ac7da334714247606f1906d2","5f4fa6dde5930fe1b42f805895f0f5fb135c2b3ff9830f2bd30ae7526a3295a1","600ec184ee9964881bcaeaf72ad38a72db05d5b629d301cb323fa1ee9369b572","62a713311297a7145d3610ee60dd6626ee543645a1918b050c629207561efb5e","630fdcff1f227b5baf5d10bd78ef0fde68791ac0cd8a15f65065f5cc4501b17b","63113617f2e4ee6b827a69bce6afb3949190a282f5feaaa9e2c9f82372623bb8","6312b7a9f8252f49b8ea0cbd0580b80bbb221db574ea74939823ed9d4140d73f","63544fa69b09916d52b305700eb9816305ff22b77162a44edd13897acea3a655","6385459222fba2c3302d3f2e38c57fcfe0f1829679fead6cffa1964248767d5e","63a4394e689acf4a4762cfb4df691d05f923fdf592fd2f8ea41e6a54f98d1136","65725e1cd3323fdf44ec47067fd6670b441ff5f82e99485e1a4fc7d475f14340","65d5b7eff9d03761c8206218159bb34883c09052d6a1959d040f711a881b4d4f","6601b2bb6c908a46ae2985d4683c8baeeec87b0688b9b33d3e8900286bf4d6ae","666e7f698fbeef24e13e91ccfa334cf781233e060fa86bcd7d4d0eb00b30f3d5","66d414618d4283838bddb6b9fd4b5221c280a7f6a715b622143d3bea76bfe1f6","671168c05789fc651cd961a5a15e10adbb76656b802cb0fcbab468ab76412ca2","671d95a6c09bb7b05a5721d52cb761300a2c8f376aac20be2948b7e97bf302b7","680de944f1f5380c579003e329ed6f10702ec8ebaaa8208743775588d2424d05","6989ec486a05550633170d2aa79188ad9b03aeea6c7859dbf18790ba78c5427a","69ebfc7eb8427db3c5c59bdde652d0cb269426126f8540b1b58caa29ccf130e2","69edc4285578313d1dd2f914d69add075a7b354f7fba717606d1abe15292576b","6a34d9279cae58765d6ee4a980192c0e15f3ca217b9f1815861d472a281b3cf8","6b00dccaa7deabc750679ab085b237a2bd025bd971ee1eb7bdc333b393b19084","6c3c592efe9c684ada5661b8cc88a5c3f6e57c841db06b9e070687504cbf6236","6ce6d164c3e31463fb9e144fdf91413e55d077cfc4f25092bb02923fb538a84f","6e08a638e1e28020923effd4c65fc517dbe7b06100ff76cde74e427191503b84","6f3a7020233cd77cfe59eefec0a277f6dda323743c8d80e4e54a95cd3cbc23cf","6fccc6f0c5fa71c43211785dced8abd0f3295040eab56063f4e8d77f1c09b8ef","700cd21af9ed7e81900fad9d52de2fb11db48e64b038e4293168f85e5dd0e043","702d1dfa75e92a916a446429f474d4c296e6ea4e8c487995852d0525e8440659","704cf778db6086c3e282c81249fb0ef09c1d7c2043335ef74c7ecb69bb3e84ad","7075f89b1271fd04fa02d4db95c0f0bd6bdec24e53a7953d7afaeba40e17e8e0","71ef1ed2d5e4bc7eebe7a73bb3e9423e5bc2f8319186380fe8b38334952d3b01","7256ba00af1cf759b95b7bf8ae3b9943f31349bd10a7652a26bb419b368d73a3","7369b339daca0fcf46ac7fe82d65ae95c75d7dbcaaae51209e6d90b6587a014e","73ec844fb3e2b9febd00ba37508b284fad141630f03cb9f74e36a195180f5054","7410de003c7b582e30470d1209eefc796a70c76fe8d61dd9ccfe01ecfa41310c","741c27b54c49167abef1d8633e3743b0e98f82a73731e744b6671e119a1c6310","74b5d2ed555740db7b4b0ea9b73f8fe00965fea8e14d4f075eec26ef7a189c68","75aaecf53db10459d768a6873f6783e7d7110aa510c2894378df027c1b03584c","76bf5a9c126db6eb466287a7c0d823327ee9882a70eaaa6efb03d169b5dba808","781a64598efb2a11156f07271ba1c14c4f6b3d73aa2943b26eae02063df7af70","786b0c2856bf1f3f809e5903b0a971f1e072af5635aa50bbb9b1449f96d7b694","799abc1e8d381b8d97349479139985e383bb49179b5a80f39807cb35a3ee78ce","79faec494bdd6d098c9d2a9d8559f822938c6b2104188db95321d89e7a732979","79fb2e6e6a91117b6aefbdaabda23ccfa596620f548ee5075993a8dc7a8b872f","7a032dbf0351aa32c77c8d187f7eb697500ff186c88c5946ecc15adc972246a6","7a134e7f1822183ed1c0ded720971539350feaaf92612761210cfc3ccdc55870","7aa52373f2721dd76fc8eeb3d6061794f27ea8d11e96bcb1ff25a97994a77d5c","7ad4ef4b8d3221758a9e7f9577750ee03f6cba11c8eae8bf25f74a3131bd21a2","7af2394d2e697f355439e841b6323ffbbf8b90b2e48bf64873791fbbfdf15b44","7b947ed0a9e6e7ba180921434b993c62ac70bbaba6af0a1618569a2d4b705201","7baa35131ece7ed9860607157d2531d4d70a061bdc9bb9876e20328f127cec53","7c2a1c4c4c03e3d68d63e0ab58e4e34d3f2bc1a4a837a055fd13a4e9f95ce6cb","7cbf970a11bdb91a40e248eee97ef789205910ebc913349698fc75ed35e82fdf","7d6133667f81aa66a98755d253ea43301b45ada338225df034d2ffdfc79829e7","7dd54213b65fa0a6ce5aa3c204b5209b67ec16306b776aed7dcf9e6601d74235","7e89b59b456dde4bbbdbf8079665bd82c51d8e500018472981c15618b3893959","7ead0c68ffa0ced241af74dde58b3831343dff3f7eaab64bddb9954545b7ba12","7efb464c6d7b469303c43f718063d8456df6fe43534b5d8a4229f5b9ba9705cd","7f8188b57ad3b0c28210c95954e5623376a4262dd5e75f002700c6094b8d6b6c","7f91dfc2ea1a3131c4090375db0f489c2a572e245ade6cda4ebd440446d6d60e","7fcb8cba3ed0ee9c342947aa88f0f699bb4f5c23244d21c6c739c9b66d7c6101","800060d7b4934508d0277f90a464e3112fd2fc99af4ef23825d09b0ff53f91c3","800a802a4ce9e597a102f0a566535c1f9f7adfc60c41af6bd2db4fb7fe3c0d0e","820c12fcbded9048a363b9e0ebbc48b24f85fd4a68131b5dfc1b19057bf09ddb","824bff7541ec2a4b0be126f0b0791314d568a0eb4e29073de4f9dbe0ee4918b8","82c419e5de083e423330432c9d45c744043d1bccd8eeccb41e3014ce9ae3c32f","83347356a898238c013dff73246440e361a9e24cc3c4e0fe0e850467772b4938","8343a4211a4d0ffdb320d5a4305174d85bb707d15dad978f6436297d022daa11","83a06a604bbe36d72da976fcdeb88665c762b0f0de44193576ef2e0cf29aa9ad","83a97b9ebb29f5cd014ef5e178970a601ee92c44678f05d1860b383c5f63b79d","85a962a7c23c14dff8d683e738b53f422221697b213cafeb616d3a172a6c4223","85e961266b36e0f8ec2a477f1f1dfe7ad748fdde9d906f7bd3241e6924866ea9","8629fddeb4f273b35df69d4d28923adc14eff59d919b1a495d1a68818137c561","872ab2b2d65fe685b91e355f5af051c85b79569ece16448160d01fef38039624","87789dab547842b4e0c822758e1325a3cbb046063e11e105a4779b3741e01cde","87f2b3634baa504f2ed9508c6cf6a47bbfb36214a177eb13d70d6a987706818c","88b615ef6a31bd9958e98b8ea522f49f0360ccac5d9fa8deb9e3ef3fe3147d9d","89a96597dc9c218633adaf94bb5d6dcf4cad8f5e0b6f5522a28e3ce8d8b2865f","89cafbb20d6029656266d8cb0f85103fa519c8032598282fea58c94cc59c4125","89f2105745b3a7cfd30e7d7c598d6c8fdde0a599f30fd0db7382cba50412445e","8b3eec010d1eae43a28c88434f2410a751f790a9d6ec4a08e75e68c171629ab2","8cce78271b4f001606069a575a172041fbddc52de6b582c920aa3d3b5d5b67ae","8cecfa09651c40be4d7c11c117c80e1911dc75bf6f1cc34be64706823cc024c3","8d250acd40c8a24ba0d51cc73e65bba6856509b5fbf4c7d7a435897a01c6e764","8df1420c27503370db9382f68a0af8d2b4d56f9dbc94b24ffae450a905083a79","8e7371228a726f381fb811d1d812c39917788a3df7e53dba1a3c364e755a0c03","8f3827158091bbed154d21c843284ad472a4552da2eeb858748aa29676e45662","8f4a21c70e4b933eaa4f9cee119945dd2ebeac532e82d34e17511b38cf03608c","8f6debc54d2bd7abb42f581f2204fc78b27ff8c67ee4b6392b4d71c5f983ee9d","8fae27ba5117e202afbd523b249fc454912571900fc909f5419b8ac96c773c44","902b958b4db7d8d8bf73a82a8aa86e5485b39477047c8ad60175d118fe31d987","9056c360e59fc78edde932b54124df317f2f04a90c0c6eb7825a87b89edf1ca0","90aff66decaa3a0998e9a6741963713c0c82fc70da505519e3d60204bf715fa0","90dc4cac6326293bb54486d3c873b83299e9a5ec8c86a68bf1cc131f5e4e2437","918126027fabb7947dd4ae810dd561ac22167102f9f978f86906624ebe88c9ea","91b495938bc6015970bb02c844368d3eee84425b472772cdb374a5347db86de9","91c9ced5e9ab8da897b7f69166a7d0bade5c58d511b42d60d5430d536da45d09","922a332aa100d622da733aea8fc74094739bb63cd480d3349a14d2418ab6b1bb","941f70c384905ab77cb9a88e2671301117e4df553da6fc7a09210710deb9b6ca","9442788fa51227044803f1d3efdfc1c2b2da372871a85f0f7a6bb3596a5c003f","9460f427df72c238c4b55f39c8864f1fa3685b0716a53227ea6f7b591d955c82","947a1cdd43831936480167169d30334f818bb5d882650a3547827c05204af111","95f0c5f3b9071db39fd72b88ec9fb2079ce7553fd5884fa527bc9216777d7c10","96c4c83df72e9d860e2ee51f1a74bc867c4a45efc8bf11bf88aa82e368b89aa4","971f59cc197732d0c0b6b8aabbbefca4550fb8fb04f8522bdb4257c05a28848a","97edc66e594bae06bb273db84a35d84c8162a1fdf55ed46d781419a9f6a2e4f2","985638a05562bb796911ec231d306b81e36ed6b58219b3bde874559e9600b59f","98a097d6ebb754334250dfd3ccc5f3dfaf5966524758cbfc9e10adf4a0229693","98c7e4bc2f05e9b4ca703db4a02347db7355a44f04e3a4003e26c46a56bded2c","98ecc99d3396aa9a35ce97456be66c1aac0cc05bab88aa99109649291e61bc0a","9944d1a9674e555a41d31d069d136461eb06dd4052d40f2e4ea4368dd978e01b","9a8f2389b8ebc29d3769868ff8b918fdeb2236d88192fcf76ab0ea3db0857fac","9af18d8cfee466bc061271d82254d7ea638b59b8d5a3901c6610d5baed85c38b","9b01e565a1541f9e652d7afbe62e3bbff28430c1ccac2226ea434f45fc9a99d0","9b466e8fcabe551bb6292d23a359be3ea15b7627a6ad9c9e6a4ff11444c20860","9bac7daf255467f47b83723095f93fa4b574d5fc08593f48825a2b2ebb8e2dd8","9bbd03293bf53e9db51401d157b3eb2aa51e9c70449350e98b9a0a3fc9a684ce","9c3b318c461b56a8d277133a6b947ef5618690ec281c42e9de6c27f22458d4d4","9cef1feab6841836dc20527fcc8ad9979671fe811ff80a5a33bae113fcbebb97","9cf90b3aa59f3ca0e40fd9e1fec9703428752d63bded6b091d28f614c9ba99ae","9d1a0da545eb6b2e16b18fdd305a2c000ff2340c19ac843914b45f6a4f936227","9d8637e5adebaca208f21af0a254e80712988867411be560031f4b7a23cc04f6","9e77badd0923fd79ca9761a41780ee4dd4f9ca9b62512f4fb59c7f8418494da0","9eb67ea41c5bcb9557ba51bbbd1b321a78f16335cadebbed848d8e6c1fc68bab","9ed400941ed49b2d90ebe3cc111d90d8bc966608ca61fe9bc315a3c1dbe8bc1b","9fb8c5aa087d38dab064a2d6054826377eea3dda98229725c2523f63a87e4750","a0ff0d0bb3a3c801b637d091293f2eeaac68e934274e4116d298ba60ec3461cc","a1baa1f699fd4ce19e8ef6cdfe346e1b0be63e16d5c5cd5feddcccb16a62f269","a2aec2d2f35d7174801247141d637e77c4f34e478c575b0e0a04c6251efaf993","a3c84d76be9d891812e795dd46470c2978dceeff928d729c0d5dd6def599923b","a3d6708506fb5c28f45f0d610bedba11b1ec7bcdb363ffff3aa4cddfa515f56a","a476183540f2e7121e533bf2dd9125dc071c81acc880e88cb435cad7a6d35b97","a4a8cca930cdfd15285ac3a7aa757d61501fb77fc12a7c3fbd78c096b279cf63","a50654761d6812cd811df02199e1b7b25c9b0d65e591f65430f9277ec43d9c50","a514a8c0898b6697696ca6f0ed9a43bf8993085b2db4299e3e9f8e3419c4a5ee","a644885c31f390b5e6b7fe2fc8d086d9144699295ccb6ffa51b3f7c76c8ca71a","a64e8aee389ae696d0d4b045c0153092113fa522ed5a0fd9b5658b8418db4ded","a6c531ed9bbafabfdd649f3030daf2f24461163aaf99dc73bb24dddb77bbcb90","a7ff7302e668dcea1cd1db2241ff95c0d73534539bd03fdefebbfb57f60d3849","a8b4a33078335d2811bffb78eee49aab5fcb31597dae366d43e20c7f7800994b","a91a47fb4fa5c1b1a834fa602030e435ad641240e6ceeb99eeeab7341ca09dec","a91c8a1431a4120667cd523cf56bac004794fc5b8b24275ad2f9c8a15c75fba1","a986593807953215f834ba73e7d2565659b32aa849986013f8614bb1c61ea8cf","aa131e74e695292adab9f57b3ccc5a503a836dd4b95a3b2b107c69f35dba3637","aa4103342641899dc00c22207c13ac31c0c73afd97771b0a9b249187d979625d","aa70263d079788757f176da269e554fef9240845706f87a93101591f8114e807","acae1db4aeb323f3b637fa11b087c3827a2fb6d69718362f54e3bc48f70ef7d8","acd7884bca46ea9422503cead985691da05cca25bd5ed52a199783cae7b8b01f","ad0e6d78c1e450e19bfca4a0e904644ab0ae315607811a28ac3dba20de869786","ae43a4d252290ec0e18c64dd58d51bc885020b2473e71e3ed0741184c9f006b7","ae69fe306bf5db346ddfa4367cda24c95e44213baca27b0ee7d7167bcdd85af6","ae8c200dbcea29f43b29974cc247d70647c80d5d76385396f1c82ee9f669e2f1","aec13a075b84253397fb97e1c93a23e1aaee6d6bff2a9161bfd00a5b1d7611de","af12215a96963c1e7e5d766ed994695e423e4780ed0b3007aed87b150d090c05","af6b60ae365a6cbeb140430b030bdb667f53a2a97508ae92dfc9ed91ca73b54a","b09355a97e3aef396f681943b37a404a98fccc6bcb97781eddb2fc000d1d985d","b0ecfca0d114bae34ffa62ac3ea05159a4415fc6eb73ab1fcc4d79f657268f19","b25c41f19ba40e646fd9b6f82051ee4c38985539e445b26bd628eae98537df53","b262187aa66e8a97083bf7f79b91595bf7a4077abe7f8be5b00b4998f4579d20","b3f50ed7eac0e9c54b74c4f4e02297dd2d2465ce4b699bcc15cfddf54c0f0f81","b4091f93c3d96e36b0708f5dcd46e0e7a0a48f098036ccef6164e4a6429ed94c","b4093c67a9195ee7d28d2575e967ac80057b92339489c244243c7c504c669ff0","b44352445272089cf90967d4d413cf7009bed0ac19f3fa95cb831d5ebad081c3","b4ce73bea5219f1b27bffb36c6a9dee14447a710a8938db807770083db4552ac","b4f2140fb766faf0065a563ac3664f395b24c81dab0d0d0d01df47b22e888d29","b5102ef50e7d4ed1925af5a8b45192e737df02fafb75d7065995a2bb93d2e8e1","b5428b5775526a00645566822530fb969b82247ba83f2c80c06d34151e1f9061","b5c085be21651d8579e52cd3ffe4abe6b7f45c5a9ee84d38c47b4734409918d8","b6cf3b02f36e0efa93b04667cdc5701340033a09e41a7196277cf6756999a666","b77c6669bcd54e0fa949faf2f7205f2631acfbc1ccf79f93f8dab5c5717f0e93","b7fda8f4bf81f8213d18e3c314df5100ccb6b8db7aed6b70aaf202deb606a14f","b7ffd6cddb12384224772e8de79aec89d8f4bca966a3c2a05763889f92a6db5c","b83b7229045affbb98f8fc46f289ad05e6626ef52e3ed2f7e70d332a54a69e2a","b83f5334b85422ac110a24286d5af7003f2fb5b0d783efe257b38a2281656422","b8abe10a2a92bf537a49e8dee92baf8de3ed591848a1b25151dab0d7ab3134e5","b8b8c5cad182083f45ce2d05d036e6bfe91cde1fb63f2e5a97c683bb7ef7ea0f","b96cea09313d481dfff1ed1a2c552ea29e8fe68f52139458996a4e36157748d2","b96f9beb6d6d8fbf88c4b8b2b807a362f2640479cab6173cf64c7710817785a0","b9ad2510d8249ec4c8e7fd8b2471727aa1bd0ce8f3dde78e545fb2f8f2985a1d","ba5c707cf9be40fe966c08807779994e20ca3f30ea9d73e26ce31ca334c05640","ba7d7464da8e13722232c8f86273774054693681becc450a68aea21a5a0e9b91","ba87e5d43ddb10937bb17941f055f80a223d0981fbba44107aeec8530e3a7774","bac3431138e986d6426c1e81bdfe0a968394896c0751cbbcc8f36002fd0ed069","bad8f17b1d399ea125c524895571601c90b6c93418c248bd4ebcc7886bae9878","bb230236c4ab6353afb4147014c93204d3d1eb8a6d18558075df5fe79ed7f392","bb7fa81e41820d63d58313460f5a3999a1f9fc2cd2fb10cbb5b41a931d8be6a2","bcbef69f1ba50e45f3faf1b4529c32cdcf1e5a6612b5bcbc6aa6790ee14b54eb","bd3bf6053f4d423ff21f7ffbed9d0e68f3ea64b7292c048e9a37ade342bb7b39","bd714f38c881208f1190ad714bf8fa5aa63adf302bdaa8ad8810ff279e43459e","be75cc1ee935f783be39978de91ae196c16141d4096e16eb6d07f59583296b4b","be8c3cb2d8d67e63c8b069920b74c6272922febbc6a0a2c4a0072a7a213681d2","beed0f36d9b1b9a20bfbf89c96862482b8d5b9d4284bc89539efe9c9b11f000d","bfd21b5c8eb26e9d475868bb30d66ee08f20876e9df5cd06aa8fec01ffe666df","bfe97e65f2cbe6bcd0f14ff57ea4dc1dedb2e5f0db92d04d0982cf1932ac1c3e","c055d3cfd85b2ed4607b0d9d3a15ab7204c9f149599f748347dca4afe102af0c","c112d36ba38c362da1c022945db5b6bbdc3014685ca9bb7d940f5086f00a675c","c23a43ed460117f663cec698412729fd91b5aaceb48cc4e55a785b525661bf1a","c23cf45c1dcb748145d87f5c173dd3c8becaf9e3f6fdcb3e2ca91d6726b0842a","c24546a064b9315172ce0f951bd5fa2cd1b9884231cf1bdc1dc714771f1b3886","c29b8d250a7b5e73f4ef675329da2251b8de032501e4836445b6aafd90c645fa","c2e96d98c8ebc10237a2af1c224f626acfb9072c83078f4a8c6d9ef0a58b4a8e","c329c9df0dae8a036da9be440432d045be3ee13cf5664cfa6ccf11576ed11acb","c4600cd5358b5798a075beb54539d952f200def1c9a573bd237c795fd33ba36f","c4ebd58c4ff78c9fc0cd17d80ed563520f7908f9d1106735ca0f5a7abed202a6","c5db39bbdc8c2bd2aa7b58c28c3df9e407955cc3250ce7825c842cc4c30eaca3","c65325f807190f7084346376e2f48fc2b6bb946004a1fac1d8d117930e93d462","c6752cc3c7ad06d1e9f127365f078919ac46b77f8a8fe413650094d914838ec3","c6867ec30530fd3feca89a4e968522f783b636b165ef74f288c42dd50bd51a3d","c6bfbb004af355e96ed5b4c8c9b8b7a96d1c08d24bcde7c666728eb9497d6d71","c77c4d3f536cda10a71fe6a9cd17ea7c1408200e2f7aa7c5325d6915ff250c85","c82f38f23e7ed3e1024661b7a22ff694e88d3b268240e2bfc98e630df8a062d0","c8bd340e6fc7fa3e97415f7ad4c22c51d88c6e77f782c12923e841c04d3f882b","c93cd4cb5cf38fe6221fa8ae171ff54240b5f99ba80cd740ffac69c57e5fa381","ca50b525d7aa7762c56f402696dd464841daf19b036bb932e325090004b4cd71","cad13b6653fd9f811e67d13c5f01f9dec047f8c384097cee01dd2e2db39e539f","cc24c3770587f2421514fa399d2617201752bdca145ac39058de91d45d3d19c1","cd2da00f6f1bad8fb7c1b87cff80e122eb017e44a471cdea769efc67db369038","cdbb7338988f2fd35fd92f21909b7801d9954d1c7ca78401f52c9313f21fb6dc","ce887fb65b6977a2046e7583d704863624e55909ebcc9c3ed065b3d13079a410","cf9223c369b6fb7baa52f301f904352ba8e8d5e4c2a06f70de6ef1cf76fe1b84","cfb9705939742247da0cb71fdfd8b5f7a1bef6f1c2f0979a8f42e54c4a480980","cfc3b5044af37ae7485fba8067dcb22b2438bdaa6e3a30c22ce0f9e2c00aa597","d0481d9b6111ab4afba0462e88970b863284807ff44ca97364c84952e3f88583","d0973a1aca6a118375b466d6e91821f8450110fdf042ac848ee16912012d2b0f","d0df3068db679e24d9487ee09a6462ac5cf3df30f46ee466b66feb6dd5ff71e2","d151ffa66d8d096e0272f0dfff6c27e978cfda570f7498a727593081888b4ebe","d227e0a73e3c5452bc5ab41ea2c695dfc0ff9b0c1c81e59ab3173f796a4157cf","d268e680ee1136a239a40ebf005b30db6f3b52a228016f3193496f86250f15c3","d2989a1607fd5303615937b8c117d127b1b1cde519662ab1e1324390220e8612","d2cba4dbbfe3d026f825a8b470a2f6011f9b8e245cf042ae8889afbb17dac6b2","d2e4c515093f8a2aa824c8b542a016e5c321065f4525931b2fac4f8af2fe52c6","d31e8aa21d1498f2d4a07c4cc89ea6f5a6d3ce54d334dbff230e0f55db35c85e","d36034e2f9cc642d0f9f24cf834fa741bac5b8b139cbd2f50e2065161c9f3cb0","d36eb7456d2a42d1cffa4b60708e2bd3116f7f6758c96bbc0fee0f1704ad8a79","d37de74aadd5916eeae243decf347821c4e946356b9f70471658638ac3092f91","d3cf9b1433fd9a083c60baf6ade1df7f2a33e0cc7d519f491f9d6a93139a41e4","d49d02cad8bbfeac607457b08aac6068916ef45d8f6c980279d6e654407cc7be","d4f51c31a454d9abac29457cbbc21e1b5767c0eac1b37c41ee787a3efb05c80f","d52ca358246f638d0e11a061e97863697df44f43b093d6e8b84ba67b5838f2fb","d555a0d2329caace197c1468fe6708349125762377ee3bd04b031b7eacfc26aa","d581443d0b6b42c76b816edc6946ce01a639ae42653ddc8cc2d6a89ce14fe947","d5c084e12da4a5111487c166b879042a21a056f761ee22d9237cb4f65f366341","d6077d547aa21ea10a9bdf6c752b8d1a0a6382b4b43a0fdf790f245e66a609fc","d67e8c1aaab1ce6ec1755599ecde153c47c6b90dd4c301663abe9057bc31af57","d67ec5caeb2af5f9c57533a34cbde7daba5f5b2e5e6ce34c3250893eef25f13c","d6abcc1484c3df45bde915abf48324af1e995c3266a3c6c069e98e94c8d9a4d7","d7a44c85c25ceb7d42280f0c2576de52a3b3cc3ad2333e788ecdc7f7f7fe4b3b","d84489933b19a8b073c65a0386e39e5067830facdc365ced6efe1948c7201771","d8c8b3c52c89cd715a7fdd2759a6f73c3a5f505303b110656cc35f7549a37cfb","d8ca8e025e226ad6bdd32a6a9fceae2982b0413a0ad09314558b54bdc724bf99","d8d03142030c11a0aa1012102fce2b202baf88e424a1236832937e87450dc579","d9823dfddf6c507ec030fce4bd2d98fbda18e595c2ebc563574d9196cc7a5e33","d9b0972f3406075b860ba7cd2e71d4492c826960319b10389c2c2820e2981254","da37a61fab07ec8856b725854e4064f55a59149aa69cad1bcbf89ec478b9f578","daa0fc9f9dd08cb2dc48bf33c9808cfeebff77cb9fba48f98ef597bb9dd6df55","dad01e5bfb13a6c4419f4d24fa8dbb424e93a1c4be656b0e5dd48ac546e0a0d9","db049e7abb7c75b608ae25cc8a9f95959f7aedaa53e22390290319cc2eed3977","db21a75b4fa6165f75268963474f3262124795d816ba80f685bab2c6eaedb028","db66a999537b941fa6d512908894ba86e8dadd0e14b290ebc119555b7e60264c","dc8c31e3075adeb63113852569b83dcd432485621eb77fef62cf3cce5c84a214","dd97ab52fd89f42352c595ce137684cc519c473fa17969e8a6adcde7322a4748","dda0a34d6704887eb36bbc0173334b49d755cac8cea3bbd17bfa972f04183dd4","ddbda9408727a19a4a55d516bed99331edf67d8301de9c78564716465c949619","de0f295bd0e46f29db1167d6c21bda624887c8543545d0c37d662e5b1b312341","de9a46da1f4605525b484a228f8bf356a9d900ecd16473faf77944b22575c141","e0288c94ca9c16a6de217e6baeed720fcf83e401bec45bd15ca47ba8fc9b44dd","e1667469384ec775a3df665679cb3fef057dc84dcb18ed8db8b9c5723835968a","e16c328504278cfe520d6d99990f2a4370cc48159aba86694d0f7598fd4b0611","e24df071f5325bb3a5b20f355143556bc7712535ee8b6ce4c426598f06fd2448","e28d8e6b71264d0bfab853e63178f2c151367cce0dbd16125596ff3604b6658d","e2c734504d211580b4e6674eb1c7d31fb6fb730c037210c34c980a96f9098269","e39ee882667ef28feb4971b73f9a01d3d72c557e1e56d59487af8e0f1b21edbd","e3f19c383354cdf45311f92f00b90fed25dfba7e9892ab2f5f3aa4885876b75f","e409fbfe439455330c0fe003de860e30f7093cc3cc83a32f886c9b539a29f60b","e519e78acf2938460c7ee053981c744dafc7642fd03b56a117d5fec78d258b90","e5db07b7fb0eed216d838fbeb9491257cf54f9bd537a68c8edae7a89fe64c8d8","e6300ee8e6c2c4ce6d7ab02b7b06fd1cabe3c5c52b99a6ea3ea8b5acd5092e0b","e65e28b172b77d093f5425112bdae7ab93756487226fd7363057f85bb2a2556d","e734d068446591aba283d136c21b4fb0209f91352cb4fc6589bd651cdbfec163","e7556cd0bdd06760602ef78c5e3b30b4dbe175f96b7147b56ee2ec181a4c5ea3","e7a333109a7aaec2b71048868500c15e721900628eb48790dfeaa1fd4c2dabc3","e7c9175fbfd9fd84bed95d552bc0a439b07a233c3e91fb39ae2f23197ee53f1b","e7ed299ecf44d4a96c228e9aa30312f405df34d6bea99d4b0f7074c79705a671","e8bc1b4f162c4066d74e5d1b3dcbe344742279b6856736c2e1690dbaa7bcf932","e981ced1bfce64a19fa8de1cd518a93f4669d01548f4819d0e1dbb50d266fe04","ea1b8a251ecc1fd96697d0c602d3e14ec46383d27bb9485a0326cea5576ffacb","ea311dca2ef14e02b9aae563bb28dc737b04b7f01c1ceb2be3d92007d2c74ac6","ea8e5b79bbe5329ae8437677c8316f2f9fd75bb1d40c88308c269140a7e564c7","eb708890ac7e19bd53007ccece064f7e2a069a3751270b4fdafdd1668136dee7","eb996138bc91c0ee63bafe1ba10b130ff5a2fc82aa4918296222e0a831a569fe","eba6e8e5a12a86f17fade41bef365aa95491c469e18aa91aef64908a4263c905","ebcf0bdb3541c8bfb7c9a53f632329b77341cba6f1a2fa0dc9704acfa3276dca","ebd87e3505f3a1adff0c86ffec6c380734df718301b216b7ee089c174130de60","ecd5e83ba8c8eba6cef9c3da1edb8a84e3dfb4ed71d9a2c1908f2c4d26b26737","edc160a11c07dda8072748b66db7f27b6cd8efbd1faa3f6c826a0fe445859c17","edfcbe4773eac1fe2964179a4ad21294efede89568f2efd8e283ac18bc5693b1","f0f90dee84db760cc1bb0f6e6983d4de0e3d5d9f4adf7b2b52f0d3dbe6d585a4","f1297fd9ecf981024e1544f7f048705377b53219240274bb803ac30e4a52084f","f1d4a6e98f41ab3f6cfd67cddeab9d0ed287b92cb3dbe575e3ce61925510a792","f21c3a9267110e469f224ac7eb76ca5bb084fc90df014f1ca6791d5770483944","f260b4b268e85a8f1b04b2fc69ffc0bca473d2e42de6f2f70128bedc16558201","f379a1b9e29aa7fc25c4c0c897eaa3c0e90d66a201a0ade8cbf523a5cdc8cf50","f3e04891c79b604f9235f438adfa49ee27db43d25c7be0d1cc06ae53b8f6d2d8","f46904e701174fe2850798d9e1b077bdac42fcac01dbc385298da01118c82aa6","f4de28905adbfe6ae4bc38f8bf5f47a444aa8d0f2023faaa431d6f72f9a3edea","f53265f53af0b0856911ab08b373736964d0c443e8ba61d7f1d45f5e5b04edf3","f5403593ba12130c04827f88d019103e924651caa518b7c290673a02f7cb409f","f5681dfc71121ed0f88146a19479675f2fabc6ed376fd5d162e50d815c048d66","f686173d310f41e26e3fe8a7c1dbf4313e4d793323335348badbcf4633f5d699","f6f5046c1263095a69e774716b0cd0907f6795af8ad683c5f41846d4c54a3449","f700bd87d4a758bb71f47731121a9b2259a9ffbd50b584b82f4e6a1f205c276a","f704c9c9e2cab1ed44578f48d161320b5fb4384ecdd8b40a5e22c4078a8594da","f7993302f695430a0ee938b1b3684fdfec4055bddb378b52c81785c0319e8c98","f89156489d35f9992d5971a52a6e03a7d7f095e15c2c782e85efb1408a2bd6be","f99ef6fa3c9c6bf572ec69eb6eeea9f88ce6590d3a5565bec62b001b6f2a376a","fa2dfc22b4fdbcf402a822e8dd376925655d997a0f96284a60f10665ba3581ba","fa3df5f8349aec4805bbcd279b88697def63f2462d8ada0b5fe1d9983d9a6daa","fa6b97cbca1d4f09662e706293b0aec1eb76b8e2277441f54ab6c548b5423236","faac0c3fa7cdf67b452d407e9a1db5cbe1e9140ecfe300200b0b0a6279c97c66","facb45d3084caa490d9b0ac2bcfcee89629a4c3db5926ec9256a9d27d25559ee","fbc8b53b5c6f3727c084e5e0429e410a3fed5a17e1a0144692fd196d9836a4bb","fbd74e4b8dc748b2efdd70aaab07adb80d7f15a38c1261de85bdfd9591ff106a","fc475f9c2d8bee2ffea435e86e6b39b6e3e071143a4a1fdf6765b0da13b66de6","fd04d7588bb9e6ca0a8b65ed0c9635082a9ee5f46b2d1b5b25866a072236c1fc","fd60f2a432086c6fc4a4c39d8d2d6edf5794c763c05a6401db2bb5fa2c601775","fd618761103380d690cb98804e8f116b6c66ef049fbf67c1a059ce49188658b3","fedf2577267d6dcd060ebc4ee8de6ccdafa60ab26b78d74c1e8c784252fecb17","ff532716738e2fc716c10797d9717f324cca3a1234320a84a73a0b89569f11ab","ffd0fe3449e449c7b9fcdcc7e2c1ffb677e57ad935a252de88a0122d437efa67","ffde5c700732beac27a9b5162213d387422ce199400e56d9cefe550005b6a542"],"schema":"fsgg.atlas/1"} +{"records":["000ada42299601fba29016e5c0e0d4012876fb42670bb10fa0b1315477254ba4","003893cc49855d17a15295d7adbe57ee301ea20281dff216461baee0810853ff","0052dfb9eafceabaa590f4497e4d42f19020718c84b981d265edefd432ccf8dd","00641d046d6869fdd0023ab3df99e0e67a6ea28f0dcb701f622b1cec8b3e07c6","0066d4a624c02398f21b4d7a736a9fb5101ed8b6b13ceeab46907e9401af98ff","026a241141ee10eb829aa6ce461969242d5c1d45fe9ca19f08ef4ea880877676","026b08fb343aefe19177e95b759560d340d372def4b71acf613fefee3438ade2","0357495d23fac4fad210b6dd7ed7cc57dd33d107e1659a81f085cad78300797f","036c148f6d0e89858c9bf4cf380272ca6904bb4ca277a909fb71c47f5450cef7","04652cbc95ac4dcd21b837b38f2ca5a0ccd4d0946bc13fdb31c9c15a578d3a2d","04d17203f03279980862496517a1f0861be5f6cc8063bfbf92f8f8ac19744fdd","04e404d89dca295564813149472b1de8e6c43357e2f6d91d169ded7600ed3a02","0509e5c6fdbd2dde0c0db8558647080560714804d00e4f9268342f2e84858a3d","06ad2c8aa0ff3b862edf3ba99e0e4e8801ee163709e66333cd06c3fc61232b05","076259a45e71df780b012d29618c17739246c86321d2ff05a6c272bcca8db675","076fa091c878b19cf56a94be0966dbcd58d52c1839f9d4b85bbfdef650cbdb88","08b3dc660b9d2bbbe75b590b2b86d941bf935a254cd5f09de71ee6894f4048b6","09e90ad705af012a8c36efbf296757f35adf9c9ce3b8908791c75d72c192973f","0a6d7dc5b64970bfdadc9049ace95e8bc163fc421beea70129ff0eaa692c6d06","0a862ee40916522f8ae5f14b3e084bf5f2e6488185583346db96ced16ce7619e","0a9df276d42b56d98a7802befc2404204e0e5ee8bc7f5c032f7bb29aa4ae2091","0ad4403c8f4078dbfa543310c69bd1dfc768e305987214ffc37d7b2600c4687c","0b2d1557ff6df5f4d65d540a5403b07ba81b381dfc799b7884ac72dfa6ee7753","0c22360d4653eb0f450e4d3d34564875f1660cfcb2d546095d98b3faa3967cbc","0c7d3f36e3bb4270edbf7abd99cd2dab772df274cad1c27c7e87e302b8eb1c23","0da4d093b49c0a1f654b38008bb01195e816829279ca1989bd2448194e15361b","0e560af7d9dd2e0f2f588a74cd35512973747f20bdfe0bee0bc889105ea53dc9","0ea7107c2c8edaab3ff2bae32f63cfbef6903a51cdaff257278f757ed5ef429d","0eef4d717eb03f0906aa3be7336aa71f831726afabe8a56077b76f6e82fd08e1","0f11324ad653d8d841962b0eeae9f68b80243d4ef7df4f2404ed4c3e45ba5197","11fe30832d93706c60efd836b09f35f049c4a715ad6144cf277ca240c5780704","1244d27db0cf5075353bcc622d0fb3b5ca6a7d08526e2c5754e8b745c250bf3f","126c817ad25ca9cbac2a0f7446e76c79852459ac7b9c61e3ba5d5cbfe5d37dfb","13824d6bce0f961c89eef4bd3c8a72ae6ecf7a1339b9e06eec964dc5c12dc544","13d0363b8d765c87a57eb42c4988320a9c2e7fa09024aa972f4b13d7699a552d","14156f1c6bf0fa8dfcb5cfafac09e012db446d528dad0e4301404fd693b9bed3","155fe673b8ae12549c978e1bf1d5c43e360937fcf2135cdcd5aea6f6c771da44","15d41240067e2335a0354a4e910b6610f2b8f079b8f67186f10181622b4a8999","1746f4f9d47b7dc42280dd34e664b3ec410d3cc69ac76933707499ffa34c79d4","1754adaf40732c3a8c73d2285c25a8b6c8c9d3e68370de618a0ffa8f3e60fb6d","1945f527afc3c2930ec4d7fa57ebb2ef7dd6321c0dd3ab9233c9963e9e613165","19d657b67672257ece127f3b957674b7fb4780843148db0a36a0b329c2a418ba","19e75be8ed4dfba2a6f8034154052160a7a181b17d887b3e8724f3e3c111c31e","1a24f6ef0c08a898f309c1b925fc19b29526f913a61a1dfe4b1a4308ebdd97ac","1b3ec24337f0252a00cfeb6df0a0f5d2b6d737dbea61b8d0b4a643f4c686df6a","1b5351b2dc647aba864e387168db5128435cb80da94fc42581cd60a05fc34b9a","1b8cad98d53da179ab05eb47c1783f4c8b45b9f39c635e7a337285f5cd9621c1","1cfd18d1b12b25604d818389a34bbaa746f450e70246c7f4242fc4e215fc46a4","1da011289116fe88fe92cb8f0e83ed7ccbbca251681d4e136c5a61c40364f8d3","1ec9445b242d2a2e149fe71c67bf13d8c0e4ebe5a6ed7b022656b9941973909d","1edc36731a9c76ad07d269d8b4fd84c8c956bb43d6f56de17d6208164856ffbe","1fec5a63a7b2b212e3e5d5222e49061f3b924966c9741294f5630836be8a3925","20901b579f69cc97eb56b492938864667576e1c9bfacf13f8a529c4f6e543448","20d01a387b4d0801cb588492ede88cae7bade9b7ea3591d9e954add1e67cf4ce","21338155cb4f52c49e5072c877771be67c75590d9b238ea025fba5209fd6e018","22ef13e60456fe9046dfe72f20122362aeefbbb445632231b8e364ed9b50e135","23af79bd1e7995fc8162ddc4d830318acb054bbfcc9c7d5cb141ec306da67386","24373b643450d9dd3b8a5b0e74a5fec2844cd8cbca7d8a57dbc8b9ad9eade9dc","24d4f2730d94d1b7f149771ef0e59192f4936d142b21f4a56b1a391e4514d38d","252de742c26409c837ef491f55eb03ffcc99da13fb1a2f8ab66efbfb0c081a2f","253bb17320020b6a5ef8f0958856f6c565a239b4dc246d9e825f8b14da9ca8de","2591526ddabbea03fbdc38bf172bc54f42df9bc51eba7ad2b70d6e67215f08f1","26259abc7fe745f52e06f2aa2abb0e50f189bc7608065f04d5c669a0a99941cd","26290a0990d6dac0ce9448e05eb934210603356043dcf14a5d80585288e2aa92","26d6b31965013079d4db67a2c403e01f21e3c30ae65953400dbed92e289a0925","288daf614247c260cb673d8674e8b3874ccc4e269347836851f702d7ac8e2f7c","28abfaf6d50ca38af0b88aa50524200c17af9000da83ddbab3d8f9e06e020fa5","2905a2b4a58bd9ec1c4f77fd3d1d246c02caa49d806272756dd039c79521442f","291d3db272eae084d34c04bc1305f2abb26a7e7acbc5515208469b46719a4ed1","2a38ddebfe3380232e35d5a24f9cb9f7c38abbc9c68add4ea5952c1e65d328d2","2b4f7c8dcc95ca8182105b9b6806391666e6a2c3a5c80d3ce5a5f04fd6cf9122","2b5e739c8f9602c585e67554c457e6e53351679afd56ff324f8fecc80f0891f1","2bc251ffb58a0d03480748058eff4c44079a0f21d75743063cef50263982337a","2c76ce93500601e281a41f5985fe4e3926fc8bc9d01ee687f14052cb553ad2d2","2d46924a94c85f4275a449dd3d9eb6c602cf8a9104db19d224e3aa469b858d06","2d5048eeef90792c0a2b9aed7305598a28db2103fed3903462c6c1882733c3e8","2d599c722a08306b98f2d833fb3e4a7acb9dea92e6a58820caa2f65c09803fb8","2df1610ac1b912232030b5507e5e944515b0f1549bf2b76ecfb12baf0f40ccea","2e1bc31ff6b6fb14d0ca8703a02833db749b03e172f2e91f9423f0751e88c256","2e872e9d3ab8b553270e79673060c50c1afd68a41fcf9fdd0a13cba80be0dfaf","2ecd502add2d801eebed39411fadc9a80098ba9ce04a5f4b728a0e4e331232d6","2f7357367d921995f4c6fdaa693392adcd2df4860ef4d25c8dc47f7ddea8c755","2fb2ed7902a8e35dc36489a23245d963026d688008c92fed6fdc1f6bc27198a6","2febddcced970d495778f33fff212929ac99c23adc42be0c1062f5c8676ffce0","3018f389f6928af5830bdd081c9d03530a379f37d1c2f9196e6fb3c44eb337d5","310bfb5b2d061bb733771e5cb7b3b7d25db43af5eda9f806169b7ef9330c2fe7","31fe4b51d55cd99a4692d2cb787d362cb4c0d0998d3e001efdb5cb7ed838340f","32f69a7b8997ae98b9305ee578145d795dbcd39ca4469bf2465e57a0295cda51","335683e33b94cb86b5e426b4faed200673bf850151191a08458136ceb164fd4e","3407ec53a884d3945d86a88d6b9a883419dd426e96b1108a8e6686f30397a629","3442ba5c7643c793f62d90ca841f7891b3dbf97f028bc7b62f8b4f88c1266d1c","34463778cf2d29e3896a65613cf9e3eb3e9f2d8946d17f12b609e70eec63d128","348ba129b7b9c94e24fa8ddb81024e777c60448d1b5d49f7b2075591b23c13b1","35da3938b72cf3520e126ad595157104b69ab748904c7b4e12f563d6b103172b","3600e7356a3741ef02f8b2ffa6a6b5d822dcbb170771f2ea33312dff4470f431","37c8908ea2a349cd3034018027160ad810b28ad1fc203a9a353971e1f7396b4c","37e39faee019bb041627510f1f02746ba9a85696417a083b438eb4974b72c2bf","38a75fd804821f4836f0a7ba8d41af3d3a3a5f5d7dcea68487009297824258d9","38c6396e645750efcb2f187c36c383471b3b0b59290e3b42cfcb9668594cd0c3","3962789d05f324d436a363700cbb5ced5aba791d782b3c0ea73221fe0c1f0b97","3966e5e53811c43962f5d0953e5da4753eacefbea27ecba9d36af2fd8e4fd52f","397476cf107b48e7a662264f8fea9f880231fd3d1e0401622650f214cfaa35c7","3ad8b0398ba6c354c9e31b7438b2515579fc0b1f17de4b35a914c862a3a11e3b","3b3c6cf083b12a840565e00458e2fd4ee8a61f97cda452703a6b13d7776b6c13","3b4af144afed3d52dd2e1f64e23bc25b3475eee5f7af3bde9886761b15c33dfd","3b5d82795e9f5d1992ab67e078fcf1108247ab9b6d1baeac944d3ec0294cec5d","3bce154e59c5c45216bb5372a352e948d6cb365bb1bd47d4666ae0412e507ca4","3c75b650f3fa8217597b01d3aaf25427ae2a658a7c966afeecdb391d3ba547ea","3d0274f77576abdbdf442c8843e955e1bbc91e9f8cbfe3646b119337cdb13c96","3d642ccf9ca4a0f7f5dde1b41f65c99e9c447cbb9e64883b67e4fdf76f216f52","3d9fd2c5877483382f0c7331206393e42827b5dccfd60549a6771b7a5659e524","3dbf6d1c2c8db1a7e3988e2a84b67a4e1d7c8304661652ffa94db3b7eee08edb","3dfcea4ee3d0d0ed09b1f77bac48b33b64ab4620cbfc74fe0e4201b4cdb81ce6","3dffc36586e9078f750b0a2b4cc2c70a17a81294903186dbe8cc47cf8055b9bd","3e2f66baa16c7ea936eba34720a55897438f60b343cbe8fda4eab1e5dde044eb","3f5465798dbc2ad279ca4849d5d0f819bad01455e0dd2a9d98afd4b55cfbd7ee","40de9f41f9a9f56ef6a51d065270e875b4a85cf043b7c4a0173b2510de4979ea","4134a3936170c1fb5fa6d2e2329185a981436477a66b7d31e827c363691bad50","414259a2fda4a1a49729be6fb1aced4675ee9cbdf990aaafb8e5b3153b54d64d","41baa5d98b5bab2ee01cad50c05b83edd8cdfeeb00f30b9406b4b2ec6d13d738","41c768ea17144c6ec225e9a65d4c3c127fdd7264dcba1a89aa17b20fd5d7e3ee","42aeb46fcc3d10b95e4067bc9cda875fa933b4102873f67c7bf1f8ca6799a598","4320b92712bc14dbe10b56f1cd3d1bdc093fc4be6016732839d0be4dd4d027d3","444342c21a4743af5961beeebb88088f5d2a0649f76c71973a7706a744f5efd2","4457ab439bc8f212d83442dc7500e9d45ffac849d0f77cb97686d9b0672fc3dc","461d34fb1d53849951a7e715e52342372d779299fbcad210794235c610dadf64","46a24cd8e385b748f40d9271b1e856dd6d68c91ab356abb11ff6b65f1ef936bf","46cdf2c207f79d388001f6636dfb7a98bb2ba72b9d1c6df4938f0a27691e07a6","471570cdf8144df0c32aba1730aba24c7e42e5ec317af771ffa169f5c842d117","47b5cb2b011c0f7012d75e88eb86a10f3f0bd48545db139669e654cac1f69650","480f1ede18ae031b164d49d676feeb1090fb33932676ff52e1e2eb24e8d154cd","48262b98c0bdbd5ee2314345726d23630ec1771735db8fe5f1a8590b662c9962","482cd15ecd9cfbd8e1943c0fcde0bbf1d875392dc2a701b698f48bfba684a062","4855e1947afc954cb1b20bb45e7af10b098fa34714bd32e9bc77941cf58fdaaa","48797c44c92cb34fd9a57a08020b45c6920b2268dc8ad616c0f814a3710d5316","48d094622ada1806cb30335926007c1abc476b1f7b45a2e250c490afa25e847b","48de3afdc6ee73ed121d1433bc6367a399286d5f8c2c63670a0b3b9752a36175","49e8cf09e38acefd3a0fa62d048028286d3b47b5ceccd8f51f10022978c47820","49ee4a3f2a8918bdbbafb312cfa807d9982800d13d29ee292c6c0daad8b9b8f1","4a724a6a842a132c2185279513f341b79f9be93e42660f1255770eeae3b1323c","4aecbdfafb68feb3124c39219498241864bcf1ceaf87fbf80598b1dd87a9191d","4b364ecb35ad02b06b6b0f32b6a29202f2c835e1ac0d70b89fd0278271799dbb","4b6ab2768e1ff3716ac8565201c031a820c208db9ea6ae1495dd782e7557a3ab","4be7778c4f491d55154a028d9a9dbb35059953fbcd243e0206902a6e64645efb","4c8c327dacf345e184042092e96ad3ea02ed4cece57dac5fa68ea52fbb5a6adf","4d5a44ba07fafeab823b54a21846269330ce35b4c190f3ddd5434bc8530d9b41","4d86a2764c55b5c5f675fddad8850ce4ceab160ac5c164a299fc098899d31aa9","4da0a5be70e8af9c39623deac83822749482187f6a0fc3d186dcfddaa7111576","4ece7844e2b35705ac39fa25913f6909aad5b4b7446bd637ced46b47c0db135c","4ef30f11bd4dd9d2eef8716d88a83010546e54594b2726de84f6d587651ee940","4f03e231c0dc5c9bb2874f6856382d5b205758af9678fffdc7552d4e4ae9866e","4f1e58fc658a4ceda181e2a7fa249305b09b573ffd68c2489f204f4957224957","4f2750b974c1404acb721ffc84cbd1d0756a24211dd6f6503c10ea74dbc45676","4f6fcf4dd7e73d86e06bdb9c14a1078b61c0efb2663ced9bfbc5f46fbb4c6d8e","5029c7b222158ab3f325168fa543d84fd2332d2e3e38db1ce7b83899cef201d1","509ec9c08864b9dd0029f32ffeac85fbac863e2dad459994c65b7cb5264faffa","50fd7e982eb2d2813634b7c44e102788a1a1cd4910a27acbcf219f76314fa322","52049cc9cee43bb27229e6b3e983e02c6aa20dd7d153b13e3c74bc6d2b47cf92","521ed246c4119acd6b579b6eefa23389a1655df54aa35de7671743979ebfc68d","5382c901d160ca2d79888d8acd7a690a5349826b5da486274b0800c9d7513f11","540879695d41205515aaabe5466971014cb43b960a26b8e5958e37fed63df762","548d237f42167af5cf5caa0ba20f0e7a6387deb6f27765637f078325172396a7","55267f058e9f085117765e4ca72ce875b622ceaceed964f6c396073214835c28","5560616d1e72f0a539f9ebbfea3b7d195c1ef5622f97994af1963748d4f97533","556ee783d8e2e4ca50f656c095758be613983f904d998a6534fb155510114f21","55a4711e799294d06988ab4acf77eacd7d424123082bba3ec987dff0ae13999c","55ae095961d78a1514c4dd1e63d477c60179a8662571ab5a90abd3eb2b83eb10","55dcc23ce52b3918a60029d9398f262216471c280bfe66421cc63240533a6087","566ddcfc45ea5edc695626826ed185930e910fd9107c5bc1844c717b714c15b2","56e7158313357bb145bd98c5f790e569be2203fb2601565a30091a597a7e7ff5","581337891936ba630d34ce9f6b803b82a2130791510f15bab24a07332400417f","58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608","5962dd14d3923433cf723d698d1af19ac37a270b6e88445643fc56a646faab5b","5a2064cdf51026eed65457c05f34bec919b31d96d35c29498d298685965f0b5a","5b77bd6dfa81cc339e729e4195e258facbfeb64b9c680512f742e3fb1961fdd5","5c0206d9d014821b52a43d7b222327a89d4ee2f5b1e21813dfa659a69f7426b5","5c3527e43fe24c5aa171c6fa4a3de7fe5e78f2527aed0dd19cb21d154d43da21","5c79c77f00167ca140127b00f1a79e1ffac621e46fc461089594206a7df8d7cc","5ca67643d5111fffd21deb18569162733e846965bf05fe6eb33ccd37c964025a","5d015880319af666943e68169ca906bf2f0c813d8bf2c5c0262aeb5a40366350","5e3a589b627edaf7005c60382475fae7229adc4ffbaab6d6fd03e9f08a0a8e19","5e43baca07fb966bf1c4b3ac06bb819577e477a84c5d8d3a9a19c391ada2e0b5","5f2a75b89983d1005a38afa2cabccc3a39f31989807120281d8505ffd564e0c6","5f43c837f39d207c35a58e9b36fe3144017b2012ac7da334714247606f1906d2","5f4fa6dde5930fe1b42f805895f0f5fb135c2b3ff9830f2bd30ae7526a3295a1","600ec184ee9964881bcaeaf72ad38a72db05d5b629d301cb323fa1ee9369b572","62a713311297a7145d3610ee60dd6626ee543645a1918b050c629207561efb5e","630fdcff1f227b5baf5d10bd78ef0fde68791ac0cd8a15f65065f5cc4501b17b","63113617f2e4ee6b827a69bce6afb3949190a282f5feaaa9e2c9f82372623bb8","6312b7a9f8252f49b8ea0cbd0580b80bbb221db574ea74939823ed9d4140d73f","63544fa69b09916d52b305700eb9816305ff22b77162a44edd13897acea3a655","6385459222fba2c3302d3f2e38c57fcfe0f1829679fead6cffa1964248767d5e","63a4394e689acf4a4762cfb4df691d05f923fdf592fd2f8ea41e6a54f98d1136","65725e1cd3323fdf44ec47067fd6670b441ff5f82e99485e1a4fc7d475f14340","65d5b7eff9d03761c8206218159bb34883c09052d6a1959d040f711a881b4d4f","6601b2bb6c908a46ae2985d4683c8baeeec87b0688b9b33d3e8900286bf4d6ae","666e7f698fbeef24e13e91ccfa334cf781233e060fa86bcd7d4d0eb00b30f3d5","66d414618d4283838bddb6b9fd4b5221c280a7f6a715b622143d3bea76bfe1f6","671168c05789fc651cd961a5a15e10adbb76656b802cb0fcbab468ab76412ca2","671d95a6c09bb7b05a5721d52cb761300a2c8f376aac20be2948b7e97bf302b7","680de944f1f5380c579003e329ed6f10702ec8ebaaa8208743775588d2424d05","6989ec486a05550633170d2aa79188ad9b03aeea6c7859dbf18790ba78c5427a","69ebfc7eb8427db3c5c59bdde652d0cb269426126f8540b1b58caa29ccf130e2","69edc4285578313d1dd2f914d69add075a7b354f7fba717606d1abe15292576b","6a34d9279cae58765d6ee4a980192c0e15f3ca217b9f1815861d472a281b3cf8","6b00dccaa7deabc750679ab085b237a2bd025bd971ee1eb7bdc333b393b19084","6c3c592efe9c684ada5661b8cc88a5c3f6e57c841db06b9e070687504cbf6236","6ce6d164c3e31463fb9e144fdf91413e55d077cfc4f25092bb02923fb538a84f","6e08a638e1e28020923effd4c65fc517dbe7b06100ff76cde74e427191503b84","6f3a7020233cd77cfe59eefec0a277f6dda323743c8d80e4e54a95cd3cbc23cf","6fccc6f0c5fa71c43211785dced8abd0f3295040eab56063f4e8d77f1c09b8ef","700cd21af9ed7e81900fad9d52de2fb11db48e64b038e4293168f85e5dd0e043","702d1dfa75e92a916a446429f474d4c296e6ea4e8c487995852d0525e8440659","704cf778db6086c3e282c81249fb0ef09c1d7c2043335ef74c7ecb69bb3e84ad","7075f89b1271fd04fa02d4db95c0f0bd6bdec24e53a7953d7afaeba40e17e8e0","71ef1ed2d5e4bc7eebe7a73bb3e9423e5bc2f8319186380fe8b38334952d3b01","7256ba00af1cf759b95b7bf8ae3b9943f31349bd10a7652a26bb419b368d73a3","7369b339daca0fcf46ac7fe82d65ae95c75d7dbcaaae51209e6d90b6587a014e","73ec844fb3e2b9febd00ba37508b284fad141630f03cb9f74e36a195180f5054","7410de003c7b582e30470d1209eefc796a70c76fe8d61dd9ccfe01ecfa41310c","741c27b54c49167abef1d8633e3743b0e98f82a73731e744b6671e119a1c6310","74b5d2ed555740db7b4b0ea9b73f8fe00965fea8e14d4f075eec26ef7a189c68","75aaecf53db10459d768a6873f6783e7d7110aa510c2894378df027c1b03584c","76bf5a9c126db6eb466287a7c0d823327ee9882a70eaaa6efb03d169b5dba808","781a64598efb2a11156f07271ba1c14c4f6b3d73aa2943b26eae02063df7af70","786b0c2856bf1f3f809e5903b0a971f1e072af5635aa50bbb9b1449f96d7b694","799abc1e8d381b8d97349479139985e383bb49179b5a80f39807cb35a3ee78ce","79faec494bdd6d098c9d2a9d8559f822938c6b2104188db95321d89e7a732979","79fb2e6e6a91117b6aefbdaabda23ccfa596620f548ee5075993a8dc7a8b872f","7a032dbf0351aa32c77c8d187f7eb697500ff186c88c5946ecc15adc972246a6","7a134e7f1822183ed1c0ded720971539350feaaf92612761210cfc3ccdc55870","7aa52373f2721dd76fc8eeb3d6061794f27ea8d11e96bcb1ff25a97994a77d5c","7ad4ef4b8d3221758a9e7f9577750ee03f6cba11c8eae8bf25f74a3131bd21a2","7af2394d2e697f355439e841b6323ffbbf8b90b2e48bf64873791fbbfdf15b44","7b947ed0a9e6e7ba180921434b993c62ac70bbaba6af0a1618569a2d4b705201","7baa35131ece7ed9860607157d2531d4d70a061bdc9bb9876e20328f127cec53","7c2a1c4c4c03e3d68d63e0ab58e4e34d3f2bc1a4a837a055fd13a4e9f95ce6cb","7cbf970a11bdb91a40e248eee97ef789205910ebc913349698fc75ed35e82fdf","7d6133667f81aa66a98755d253ea43301b45ada338225df034d2ffdfc79829e7","7dd54213b65fa0a6ce5aa3c204b5209b67ec16306b776aed7dcf9e6601d74235","7e89b59b456dde4bbbdbf8079665bd82c51d8e500018472981c15618b3893959","7ead0c68ffa0ced241af74dde58b3831343dff3f7eaab64bddb9954545b7ba12","7efb464c6d7b469303c43f718063d8456df6fe43534b5d8a4229f5b9ba9705cd","7f8188b57ad3b0c28210c95954e5623376a4262dd5e75f002700c6094b8d6b6c","7f91dfc2ea1a3131c4090375db0f489c2a572e245ade6cda4ebd440446d6d60e","7fcb8cba3ed0ee9c342947aa88f0f699bb4f5c23244d21c6c739c9b66d7c6101","800060d7b4934508d0277f90a464e3112fd2fc99af4ef23825d09b0ff53f91c3","800a802a4ce9e597a102f0a566535c1f9f7adfc60c41af6bd2db4fb7fe3c0d0e","820c12fcbded9048a363b9e0ebbc48b24f85fd4a68131b5dfc1b19057bf09ddb","824bff7541ec2a4b0be126f0b0791314d568a0eb4e29073de4f9dbe0ee4918b8","82c419e5de083e423330432c9d45c744043d1bccd8eeccb41e3014ce9ae3c32f","83347356a898238c013dff73246440e361a9e24cc3c4e0fe0e850467772b4938","8343a4211a4d0ffdb320d5a4305174d85bb707d15dad978f6436297d022daa11","83a06a604bbe36d72da976fcdeb88665c762b0f0de44193576ef2e0cf29aa9ad","83a97b9ebb29f5cd014ef5e178970a601ee92c44678f05d1860b383c5f63b79d","85a962a7c23c14dff8d683e738b53f422221697b213cafeb616d3a172a6c4223","85e961266b36e0f8ec2a477f1f1dfe7ad748fdde9d906f7bd3241e6924866ea9","8629fddeb4f273b35df69d4d28923adc14eff59d919b1a495d1a68818137c561","872ab2b2d65fe685b91e355f5af051c85b79569ece16448160d01fef38039624","87789dab547842b4e0c822758e1325a3cbb046063e11e105a4779b3741e01cde","87f2b3634baa504f2ed9508c6cf6a47bbfb36214a177eb13d70d6a987706818c","88b615ef6a31bd9958e98b8ea522f49f0360ccac5d9fa8deb9e3ef3fe3147d9d","89a96597dc9c218633adaf94bb5d6dcf4cad8f5e0b6f5522a28e3ce8d8b2865f","89cafbb20d6029656266d8cb0f85103fa519c8032598282fea58c94cc59c4125","89f2105745b3a7cfd30e7d7c598d6c8fdde0a599f30fd0db7382cba50412445e","8b3eec010d1eae43a28c88434f2410a751f790a9d6ec4a08e75e68c171629ab2","8cce78271b4f001606069a575a172041fbddc52de6b582c920aa3d3b5d5b67ae","8cecfa09651c40be4d7c11c117c80e1911dc75bf6f1cc34be64706823cc024c3","8d250acd40c8a24ba0d51cc73e65bba6856509b5fbf4c7d7a435897a01c6e764","8df1420c27503370db9382f68a0af8d2b4d56f9dbc94b24ffae450a905083a79","8e7371228a726f381fb811d1d812c39917788a3df7e53dba1a3c364e755a0c03","8f3827158091bbed154d21c843284ad472a4552da2eeb858748aa29676e45662","8f4a21c70e4b933eaa4f9cee119945dd2ebeac532e82d34e17511b38cf03608c","8f6debc54d2bd7abb42f581f2204fc78b27ff8c67ee4b6392b4d71c5f983ee9d","8fae27ba5117e202afbd523b249fc454912571900fc909f5419b8ac96c773c44","902b958b4db7d8d8bf73a82a8aa86e5485b39477047c8ad60175d118fe31d987","9056c360e59fc78edde932b54124df317f2f04a90c0c6eb7825a87b89edf1ca0","90aff66decaa3a0998e9a6741963713c0c82fc70da505519e3d60204bf715fa0","90dc4cac6326293bb54486d3c873b83299e9a5ec8c86a68bf1cc131f5e4e2437","918126027fabb7947dd4ae810dd561ac22167102f9f978f86906624ebe88c9ea","91b495938bc6015970bb02c844368d3eee84425b472772cdb374a5347db86de9","91c9ced5e9ab8da897b7f69166a7d0bade5c58d511b42d60d5430d536da45d09","922a332aa100d622da733aea8fc74094739bb63cd480d3349a14d2418ab6b1bb","941f70c384905ab77cb9a88e2671301117e4df553da6fc7a09210710deb9b6ca","9442788fa51227044803f1d3efdfc1c2b2da372871a85f0f7a6bb3596a5c003f","9460f427df72c238c4b55f39c8864f1fa3685b0716a53227ea6f7b591d955c82","947a1cdd43831936480167169d30334f818bb5d882650a3547827c05204af111","95f0c5f3b9071db39fd72b88ec9fb2079ce7553fd5884fa527bc9216777d7c10","96c4c83df72e9d860e2ee51f1a74bc867c4a45efc8bf11bf88aa82e368b89aa4","971f59cc197732d0c0b6b8aabbbefca4550fb8fb04f8522bdb4257c05a28848a","97edc66e594bae06bb273db84a35d84c8162a1fdf55ed46d781419a9f6a2e4f2","985638a05562bb796911ec231d306b81e36ed6b58219b3bde874559e9600b59f","98a097d6ebb754334250dfd3ccc5f3dfaf5966524758cbfc9e10adf4a0229693","98c7e4bc2f05e9b4ca703db4a02347db7355a44f04e3a4003e26c46a56bded2c","98ecc99d3396aa9a35ce97456be66c1aac0cc05bab88aa99109649291e61bc0a","9944d1a9674e555a41d31d069d136461eb06dd4052d40f2e4ea4368dd978e01b","9a8f2389b8ebc29d3769868ff8b918fdeb2236d88192fcf76ab0ea3db0857fac","9af18d8cfee466bc061271d82254d7ea638b59b8d5a3901c6610d5baed85c38b","9b01e565a1541f9e652d7afbe62e3bbff28430c1ccac2226ea434f45fc9a99d0","9b466e8fcabe551bb6292d23a359be3ea15b7627a6ad9c9e6a4ff11444c20860","9bac7daf255467f47b83723095f93fa4b574d5fc08593f48825a2b2ebb8e2dd8","9bbd03293bf53e9db51401d157b3eb2aa51e9c70449350e98b9a0a3fc9a684ce","9c3b318c461b56a8d277133a6b947ef5618690ec281c42e9de6c27f22458d4d4","9cef1feab6841836dc20527fcc8ad9979671fe811ff80a5a33bae113fcbebb97","9cf90b3aa59f3ca0e40fd9e1fec9703428752d63bded6b091d28f614c9ba99ae","9d1a0da545eb6b2e16b18fdd305a2c000ff2340c19ac843914b45f6a4f936227","9d8637e5adebaca208f21af0a254e80712988867411be560031f4b7a23cc04f6","9e77badd0923fd79ca9761a41780ee4dd4f9ca9b62512f4fb59c7f8418494da0","9eb67ea41c5bcb9557ba51bbbd1b321a78f16335cadebbed848d8e6c1fc68bab","9ed400941ed49b2d90ebe3cc111d90d8bc966608ca61fe9bc315a3c1dbe8bc1b","9fb8c5aa087d38dab064a2d6054826377eea3dda98229725c2523f63a87e4750","a0ff0d0bb3a3c801b637d091293f2eeaac68e934274e4116d298ba60ec3461cc","a1baa1f699fd4ce19e8ef6cdfe346e1b0be63e16d5c5cd5feddcccb16a62f269","a2aec2d2f35d7174801247141d637e77c4f34e478c575b0e0a04c6251efaf993","a3c84d76be9d891812e795dd46470c2978dceeff928d729c0d5dd6def599923b","a3d6708506fb5c28f45f0d610bedba11b1ec7bcdb363ffff3aa4cddfa515f56a","a476183540f2e7121e533bf2dd9125dc071c81acc880e88cb435cad7a6d35b97","a4a8cca930cdfd15285ac3a7aa757d61501fb77fc12a7c3fbd78c096b279cf63","a50654761d6812cd811df02199e1b7b25c9b0d65e591f65430f9277ec43d9c50","a514a8c0898b6697696ca6f0ed9a43bf8993085b2db4299e3e9f8e3419c4a5ee","a644885c31f390b5e6b7fe2fc8d086d9144699295ccb6ffa51b3f7c76c8ca71a","a64e8aee389ae696d0d4b045c0153092113fa522ed5a0fd9b5658b8418db4ded","a6c531ed9bbafabfdd649f3030daf2f24461163aaf99dc73bb24dddb77bbcb90","a7ff7302e668dcea1cd1db2241ff95c0d73534539bd03fdefebbfb57f60d3849","a8b4a33078335d2811bffb78eee49aab5fcb31597dae366d43e20c7f7800994b","a91a47fb4fa5c1b1a834fa602030e435ad641240e6ceeb99eeeab7341ca09dec","a91c8a1431a4120667cd523cf56bac004794fc5b8b24275ad2f9c8a15c75fba1","a986593807953215f834ba73e7d2565659b32aa849986013f8614bb1c61ea8cf","aa131e74e695292adab9f57b3ccc5a503a836dd4b95a3b2b107c69f35dba3637","aa4103342641899dc00c22207c13ac31c0c73afd97771b0a9b249187d979625d","aa70263d079788757f176da269e554fef9240845706f87a93101591f8114e807","acae1db4aeb323f3b637fa11b087c3827a2fb6d69718362f54e3bc48f70ef7d8","acd7884bca46ea9422503cead985691da05cca25bd5ed52a199783cae7b8b01f","ad0e6d78c1e450e19bfca4a0e904644ab0ae315607811a28ac3dba20de869786","ae43a4d252290ec0e18c64dd58d51bc885020b2473e71e3ed0741184c9f006b7","ae69fe306bf5db346ddfa4367cda24c95e44213baca27b0ee7d7167bcdd85af6","ae8c200dbcea29f43b29974cc247d70647c80d5d76385396f1c82ee9f669e2f1","aec13a075b84253397fb97e1c93a23e1aaee6d6bff2a9161bfd00a5b1d7611de","af12215a96963c1e7e5d766ed994695e423e4780ed0b3007aed87b150d090c05","af6b60ae365a6cbeb140430b030bdb667f53a2a97508ae92dfc9ed91ca73b54a","b09355a97e3aef396f681943b37a404a98fccc6bcb97781eddb2fc000d1d985d","b0ecfca0d114bae34ffa62ac3ea05159a4415fc6eb73ab1fcc4d79f657268f19","b25c41f19ba40e646fd9b6f82051ee4c38985539e445b26bd628eae98537df53","b262187aa66e8a97083bf7f79b91595bf7a4077abe7f8be5b00b4998f4579d20","b3f50ed7eac0e9c54b74c4f4e02297dd2d2465ce4b699bcc15cfddf54c0f0f81","b4091f93c3d96e36b0708f5dcd46e0e7a0a48f098036ccef6164e4a6429ed94c","b4093c67a9195ee7d28d2575e967ac80057b92339489c244243c7c504c669ff0","b44352445272089cf90967d4d413cf7009bed0ac19f3fa95cb831d5ebad081c3","b4ce73bea5219f1b27bffb36c6a9dee14447a710a8938db807770083db4552ac","b4f2140fb766faf0065a563ac3664f395b24c81dab0d0d0d01df47b22e888d29","b5102ef50e7d4ed1925af5a8b45192e737df02fafb75d7065995a2bb93d2e8e1","b5428b5775526a00645566822530fb969b82247ba83f2c80c06d34151e1f9061","b5c085be21651d8579e52cd3ffe4abe6b7f45c5a9ee84d38c47b4734409918d8","b6cf3b02f36e0efa93b04667cdc5701340033a09e41a7196277cf6756999a666","b77c6669bcd54e0fa949faf2f7205f2631acfbc1ccf79f93f8dab5c5717f0e93","b7fda8f4bf81f8213d18e3c314df5100ccb6b8db7aed6b70aaf202deb606a14f","b7ffd6cddb12384224772e8de79aec89d8f4bca966a3c2a05763889f92a6db5c","b83b7229045affbb98f8fc46f289ad05e6626ef52e3ed2f7e70d332a54a69e2a","b83f5334b85422ac110a24286d5af7003f2fb5b0d783efe257b38a2281656422","b8abe10a2a92bf537a49e8dee92baf8de3ed591848a1b25151dab0d7ab3134e5","b8b8c5cad182083f45ce2d05d036e6bfe91cde1fb63f2e5a97c683bb7ef7ea0f","b96cea09313d481dfff1ed1a2c552ea29e8fe68f52139458996a4e36157748d2","b96f9beb6d6d8fbf88c4b8b2b807a362f2640479cab6173cf64c7710817785a0","b9ad2510d8249ec4c8e7fd8b2471727aa1bd0ce8f3dde78e545fb2f8f2985a1d","ba5c707cf9be40fe966c08807779994e20ca3f30ea9d73e26ce31ca334c05640","ba7d7464da8e13722232c8f86273774054693681becc450a68aea21a5a0e9b91","ba87e5d43ddb10937bb17941f055f80a223d0981fbba44107aeec8530e3a7774","bac3431138e986d6426c1e81bdfe0a968394896c0751cbbcc8f36002fd0ed069","bad8f17b1d399ea125c524895571601c90b6c93418c248bd4ebcc7886bae9878","bb230236c4ab6353afb4147014c93204d3d1eb8a6d18558075df5fe79ed7f392","bb7fa81e41820d63d58313460f5a3999a1f9fc2cd2fb10cbb5b41a931d8be6a2","bcbef69f1ba50e45f3faf1b4529c32cdcf1e5a6612b5bcbc6aa6790ee14b54eb","bd3bf6053f4d423ff21f7ffbed9d0e68f3ea64b7292c048e9a37ade342bb7b39","bd714f38c881208f1190ad714bf8fa5aa63adf302bdaa8ad8810ff279e43459e","be75cc1ee935f783be39978de91ae196c16141d4096e16eb6d07f59583296b4b","be8c3cb2d8d67e63c8b069920b74c6272922febbc6a0a2c4a0072a7a213681d2","beed0f36d9b1b9a20bfbf89c96862482b8d5b9d4284bc89539efe9c9b11f000d","bfd21b5c8eb26e9d475868bb30d66ee08f20876e9df5cd06aa8fec01ffe666df","bfe97e65f2cbe6bcd0f14ff57ea4dc1dedb2e5f0db92d04d0982cf1932ac1c3e","c055d3cfd85b2ed4607b0d9d3a15ab7204c9f149599f748347dca4afe102af0c","c112d36ba38c362da1c022945db5b6bbdc3014685ca9bb7d940f5086f00a675c","c23a43ed460117f663cec698412729fd91b5aaceb48cc4e55a785b525661bf1a","c23cf45c1dcb748145d87f5c173dd3c8becaf9e3f6fdcb3e2ca91d6726b0842a","c24546a064b9315172ce0f951bd5fa2cd1b9884231cf1bdc1dc714771f1b3886","c29b8d250a7b5e73f4ef675329da2251b8de032501e4836445b6aafd90c645fa","c2e96d98c8ebc10237a2af1c224f626acfb9072c83078f4a8c6d9ef0a58b4a8e","c329c9df0dae8a036da9be440432d045be3ee13cf5664cfa6ccf11576ed11acb","c4600cd5358b5798a075beb54539d952f200def1c9a573bd237c795fd33ba36f","c4ebd58c4ff78c9fc0cd17d80ed563520f7908f9d1106735ca0f5a7abed202a6","c5db39bbdc8c2bd2aa7b58c28c3df9e407955cc3250ce7825c842cc4c30eaca3","c65325f807190f7084346376e2f48fc2b6bb946004a1fac1d8d117930e93d462","c6752cc3c7ad06d1e9f127365f078919ac46b77f8a8fe413650094d914838ec3","c6867ec30530fd3feca89a4e968522f783b636b165ef74f288c42dd50bd51a3d","c6bfbb004af355e96ed5b4c8c9b8b7a96d1c08d24bcde7c666728eb9497d6d71","c77c4d3f536cda10a71fe6a9cd17ea7c1408200e2f7aa7c5325d6915ff250c85","c82f38f23e7ed3e1024661b7a22ff694e88d3b268240e2bfc98e630df8a062d0","c8bd340e6fc7fa3e97415f7ad4c22c51d88c6e77f782c12923e841c04d3f882b","c93cd4cb5cf38fe6221fa8ae171ff54240b5f99ba80cd740ffac69c57e5fa381","ca50b525d7aa7762c56f402696dd464841daf19b036bb932e325090004b4cd71","cad13b6653fd9f811e67d13c5f01f9dec047f8c384097cee01dd2e2db39e539f","cc24c3770587f2421514fa399d2617201752bdca145ac39058de91d45d3d19c1","cd2da00f6f1bad8fb7c1b87cff80e122eb017e44a471cdea769efc67db369038","cdbb7338988f2fd35fd92f21909b7801d9954d1c7ca78401f52c9313f21fb6dc","ce887fb65b6977a2046e7583d704863624e55909ebcc9c3ed065b3d13079a410","cf9223c369b6fb7baa52f301f904352ba8e8d5e4c2a06f70de6ef1cf76fe1b84","cfb9705939742247da0cb71fdfd8b5f7a1bef6f1c2f0979a8f42e54c4a480980","cfc3b5044af37ae7485fba8067dcb22b2438bdaa6e3a30c22ce0f9e2c00aa597","d0481d9b6111ab4afba0462e88970b863284807ff44ca97364c84952e3f88583","d0973a1aca6a118375b466d6e91821f8450110fdf042ac848ee16912012d2b0f","d0df3068db679e24d9487ee09a6462ac5cf3df30f46ee466b66feb6dd5ff71e2","d151ffa66d8d096e0272f0dfff6c27e978cfda570f7498a727593081888b4ebe","d227e0a73e3c5452bc5ab41ea2c695dfc0ff9b0c1c81e59ab3173f796a4157cf","d268e680ee1136a239a40ebf005b30db6f3b52a228016f3193496f86250f15c3","d2989a1607fd5303615937b8c117d127b1b1cde519662ab1e1324390220e8612","d2cba4dbbfe3d026f825a8b470a2f6011f9b8e245cf042ae8889afbb17dac6b2","d2e4c515093f8a2aa824c8b542a016e5c321065f4525931b2fac4f8af2fe52c6","d31e8aa21d1498f2d4a07c4cc89ea6f5a6d3ce54d334dbff230e0f55db35c85e","d36034e2f9cc642d0f9f24cf834fa741bac5b8b139cbd2f50e2065161c9f3cb0","d36eb7456d2a42d1cffa4b60708e2bd3116f7f6758c96bbc0fee0f1704ad8a79","d37de74aadd5916eeae243decf347821c4e946356b9f70471658638ac3092f91","d3cf9b1433fd9a083c60baf6ade1df7f2a33e0cc7d519f491f9d6a93139a41e4","d49d02cad8bbfeac607457b08aac6068916ef45d8f6c980279d6e654407cc7be","d4f51c31a454d9abac29457cbbc21e1b5767c0eac1b37c41ee787a3efb05c80f","d52ca358246f638d0e11a061e97863697df44f43b093d6e8b84ba67b5838f2fb","d555a0d2329caace197c1468fe6708349125762377ee3bd04b031b7eacfc26aa","d581443d0b6b42c76b816edc6946ce01a639ae42653ddc8cc2d6a89ce14fe947","d5c084e12da4a5111487c166b879042a21a056f761ee22d9237cb4f65f366341","d6077d547aa21ea10a9bdf6c752b8d1a0a6382b4b43a0fdf790f245e66a609fc","d67e8c1aaab1ce6ec1755599ecde153c47c6b90dd4c301663abe9057bc31af57","d67ec5caeb2af5f9c57533a34cbde7daba5f5b2e5e6ce34c3250893eef25f13c","d6abcc1484c3df45bde915abf48324af1e995c3266a3c6c069e98e94c8d9a4d7","d7a44c85c25ceb7d42280f0c2576de52a3b3cc3ad2333e788ecdc7f7f7fe4b3b","d84489933b19a8b073c65a0386e39e5067830facdc365ced6efe1948c7201771","d8c8b3c52c89cd715a7fdd2759a6f73c3a5f505303b110656cc35f7549a37cfb","d8ca8e025e226ad6bdd32a6a9fceae2982b0413a0ad09314558b54bdc724bf99","d8d03142030c11a0aa1012102fce2b202baf88e424a1236832937e87450dc579","d9823dfddf6c507ec030fce4bd2d98fbda18e595c2ebc563574d9196cc7a5e33","d9b0972f3406075b860ba7cd2e71d4492c826960319b10389c2c2820e2981254","da37a61fab07ec8856b725854e4064f55a59149aa69cad1bcbf89ec478b9f578","daa0fc9f9dd08cb2dc48bf33c9808cfeebff77cb9fba48f98ef597bb9dd6df55","dad01e5bfb13a6c4419f4d24fa8dbb424e93a1c4be656b0e5dd48ac546e0a0d9","db049e7abb7c75b608ae25cc8a9f95959f7aedaa53e22390290319cc2eed3977","db21a75b4fa6165f75268963474f3262124795d816ba80f685bab2c6eaedb028","db66a999537b941fa6d512908894ba86e8dadd0e14b290ebc119555b7e60264c","dc8c31e3075adeb63113852569b83dcd432485621eb77fef62cf3cce5c84a214","dd97ab52fd89f42352c595ce137684cc519c473fa17969e8a6adcde7322a4748","dda0a34d6704887eb36bbc0173334b49d755cac8cea3bbd17bfa972f04183dd4","ddbda9408727a19a4a55d516bed99331edf67d8301de9c78564716465c949619","de0f295bd0e46f29db1167d6c21bda624887c8543545d0c37d662e5b1b312341","de9a46da1f4605525b484a228f8bf356a9d900ecd16473faf77944b22575c141","e0288c94ca9c16a6de217e6baeed720fcf83e401bec45bd15ca47ba8fc9b44dd","e1667469384ec775a3df665679cb3fef057dc84dcb18ed8db8b9c5723835968a","e16c328504278cfe520d6d99990f2a4370cc48159aba86694d0f7598fd4b0611","e24df071f5325bb3a5b20f355143556bc7712535ee8b6ce4c426598f06fd2448","e28d8e6b71264d0bfab853e63178f2c151367cce0dbd16125596ff3604b6658d","e2c734504d211580b4e6674eb1c7d31fb6fb730c037210c34c980a96f9098269","e39ee882667ef28feb4971b73f9a01d3d72c557e1e56d59487af8e0f1b21edbd","e3f19c383354cdf45311f92f00b90fed25dfba7e9892ab2f5f3aa4885876b75f","e409fbfe439455330c0fe003de860e30f7093cc3cc83a32f886c9b539a29f60b","e519e78acf2938460c7ee053981c744dafc7642fd03b56a117d5fec78d258b90","e5db07b7fb0eed216d838fbeb9491257cf54f9bd537a68c8edae7a89fe64c8d8","e6300ee8e6c2c4ce6d7ab02b7b06fd1cabe3c5c52b99a6ea3ea8b5acd5092e0b","e65e28b172b77d093f5425112bdae7ab93756487226fd7363057f85bb2a2556d","e734d068446591aba283d136c21b4fb0209f91352cb4fc6589bd651cdbfec163","e7556cd0bdd06760602ef78c5e3b30b4dbe175f96b7147b56ee2ec181a4c5ea3","e7a333109a7aaec2b71048868500c15e721900628eb48790dfeaa1fd4c2dabc3","e7c9175fbfd9fd84bed95d552bc0a439b07a233c3e91fb39ae2f23197ee53f1b","e7ed299ecf44d4a96c228e9aa30312f405df34d6bea99d4b0f7074c79705a671","e8bc1b4f162c4066d74e5d1b3dcbe344742279b6856736c2e1690dbaa7bcf932","e981ced1bfce64a19fa8de1cd518a93f4669d01548f4819d0e1dbb50d266fe04","ea1b8a251ecc1fd96697d0c602d3e14ec46383d27bb9485a0326cea5576ffacb","ea311dca2ef14e02b9aae563bb28dc737b04b7f01c1ceb2be3d92007d2c74ac6","ea8e5b79bbe5329ae8437677c8316f2f9fd75bb1d40c88308c269140a7e564c7","eb708890ac7e19bd53007ccece064f7e2a069a3751270b4fdafdd1668136dee7","eb996138bc91c0ee63bafe1ba10b130ff5a2fc82aa4918296222e0a831a569fe","eba6e8e5a12a86f17fade41bef365aa95491c469e18aa91aef64908a4263c905","ebcf0bdb3541c8bfb7c9a53f632329b77341cba6f1a2fa0dc9704acfa3276dca","ebd87e3505f3a1adff0c86ffec6c380734df718301b216b7ee089c174130de60","ecd5e83ba8c8eba6cef9c3da1edb8a84e3dfb4ed71d9a2c1908f2c4d26b26737","edc160a11c07dda8072748b66db7f27b6cd8efbd1faa3f6c826a0fe445859c17","edfcbe4773eac1fe2964179a4ad21294efede89568f2efd8e283ac18bc5693b1","f0f90dee84db760cc1bb0f6e6983d4de0e3d5d9f4adf7b2b52f0d3dbe6d585a4","f1297fd9ecf981024e1544f7f048705377b53219240274bb803ac30e4a52084f","f1d4a6e98f41ab3f6cfd67cddeab9d0ed287b92cb3dbe575e3ce61925510a792","f21c3a9267110e469f224ac7eb76ca5bb084fc90df014f1ca6791d5770483944","f260b4b268e85a8f1b04b2fc69ffc0bca473d2e42de6f2f70128bedc16558201","f379a1b9e29aa7fc25c4c0c897eaa3c0e90d66a201a0ade8cbf523a5cdc8cf50","f3e04891c79b604f9235f438adfa49ee27db43d25c7be0d1cc06ae53b8f6d2d8","f46904e701174fe2850798d9e1b077bdac42fcac01dbc385298da01118c82aa6","f4de28905adbfe6ae4bc38f8bf5f47a444aa8d0f2023faaa431d6f72f9a3edea","f53265f53af0b0856911ab08b373736964d0c443e8ba61d7f1d45f5e5b04edf3","f5403593ba12130c04827f88d019103e924651caa518b7c290673a02f7cb409f","f5681dfc71121ed0f88146a19479675f2fabc6ed376fd5d162e50d815c048d66","f686173d310f41e26e3fe8a7c1dbf4313e4d793323335348badbcf4633f5d699","f6f5046c1263095a69e774716b0cd0907f6795af8ad683c5f41846d4c54a3449","f700bd87d4a758bb71f47731121a9b2259a9ffbd50b584b82f4e6a1f205c276a","f704c9c9e2cab1ed44578f48d161320b5fb4384ecdd8b40a5e22c4078a8594da","f7993302f695430a0ee938b1b3684fdfec4055bddb378b52c81785c0319e8c98","f89156489d35f9992d5971a52a6e03a7d7f095e15c2c782e85efb1408a2bd6be","f99ef6fa3c9c6bf572ec69eb6eeea9f88ce6590d3a5565bec62b001b6f2a376a","fa2dfc22b4fdbcf402a822e8dd376925655d997a0f96284a60f10665ba3581ba","fa3df5f8349aec4805bbcd279b88697def63f2462d8ada0b5fe1d9983d9a6daa","fa6b97cbca1d4f09662e706293b0aec1eb76b8e2277441f54ab6c548b5423236","faac0c3fa7cdf67b452d407e9a1db5cbe1e9140ecfe300200b0b0a6279c97c66","facb45d3084caa490d9b0ac2bcfcee89629a4c3db5926ec9256a9d27d25559ee","fbc8b53b5c6f3727c084e5e0429e410a3fed5a17e1a0144692fd196d9836a4bb","fbd74e4b8dc748b2efdd70aaab07adb80d7f15a38c1261de85bdfd9591ff106a","fc475f9c2d8bee2ffea435e86e6b39b6e3e071143a4a1fdf6765b0da13b66de6","fd04d7588bb9e6ca0a8b65ed0c9635082a9ee5f46b2d1b5b25866a072236c1fc","fd60f2a432086c6fc4a4c39d8d2d6edf5794c763c05a6401db2bb5fa2c601775","fd618761103380d690cb98804e8f116b6c66ef049fbf67c1a059ce49188658b3","fedf2577267d6dcd060ebc4ee8de6ccdafa60ab26b78d74c1e8c784252fecb17","ff532716738e2fc716c10797d9717f324cca3a1234320a84a73a0b89569f11ab","ffd0fe3449e449c7b9fcdcc7e2c1ffb677e57ad935a252de88a0122d437efa67","ffde5c700732beac27a9b5162213d387422ce199400e56d9cefe550005b6a542"],"schema":"fsgg.atlas/1"} diff --git a/.claude/skills/atlas/assets/seed/records/58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608.json b/.claude/skills/atlas/assets/seed/records/58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608.json new file mode 100644 index 000000000..3ee7bb61f --- /dev/null +++ b/.claude/skills/atlas/assets/seed/records/58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608.json @@ -0,0 +1 @@ +{"citations":[{"path":"scripts/fdev-lane-capacity.py","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"3657c8432792a461dc26f97a0375c3a7f8ead038408ada4b3b1bc8e3cd650467"},{"path":"scripts/fdev-tmp-cleanup.py","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"6fcb5fe6d16fc56f042c152502d1024aae5b5e7f0214b54fa26147fe7f08a083"},{"path":"deployment/fdev-chromium/fdev-chromium-env","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"8cbc5e158b1619c23cd4666667e1d5c316de6229f71ccf5a888576050ab3b2a5"},{"path":"docs/coordination/fdev-host-hygiene.md","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"af791bd6cf7e83c3cc0ff28e5b725b3ea1248daf657c1c257e282379b8635e61"}],"conflictsWith":[],"id":"environment/fdev-host-hygiene","kind":"lesson","recordedAt":"2026-11-02T06:57:04Z","repository":"FS-GG/.github","schema":"fsgg.atlas/1","status":"recorded","summary":"Observed 2026-11-02 (FS-GG/.github#5240): /tmp on fdev is a 16 GB tmpfs shared by every lane; it filled (about 15k entries, 9.5 GB; fifteen browser-smoke mktemp trees of about 232 MB each and a 725 MB fsgg-gate-engine cache were the bulk) and caused 38 spurious SDD test failures while many browser smokes ran and the quiet-host probe did not admit for 60 minutes. Delivered on routine/5240-fdev-host-hygiene (cited files at the cited revision; merge and install are separate effects). (1) scripts/fdev-lane-capacity.py holds at 2 or more headless Chromium MAIN processes (argv[0] Chromium binary, --headless, --remote-debugging-pipe|port, no --type=; renderer/GPU/zygote/crashpad children and node/timeout launchers do not count; --browser-hold-at, 0 disables) and when /tmp has under 3 GiB free (--min-tmp-gib, --tmp-path), JSON browsers.count/pids and tmp_free_gib. LESSON: Chromium rewrites its process title, so on fdev /proc//cmdline is ONE space-joined string with a trailing NUL, for the main process and every --type= child; a NUL-split parser sees one word and never counts a browser, so the probe splits a single spaced field and takes argv[0] from readlink exe; checked live: one real Playwright chrome-headless-shell -> count 1, two -> hold. (2) deployment/fdev-chromium/fdev-chromium-env is now the repository source of the wrapper (it was only ~/.local/bin; environment/fdev-headless-chromium says it is not in Git, which this supersedes in fact but not by digest) and defaults TMPDIR to /home/developer/.cache/fsgg-tmp unless set, mkdir -p then chmod 0700 (shellcheck SC2174 forbids mkdir -p -m); capped at 32 bytes because a Unix socket path is at most 107 bytes and the SDD race test binds /sdd-race-characterization-<32 hex>/inputs/socket (TMPDIR plus 73); mixed TMPDIR values may fragment MSBuild node reuse; --print-tmpdir serves .NET runs. (3) scripts/fdev-tmp-cleanup.py is dry-run unless --apply and removes only known names (fsgg-sdd-tests--* idle 1 h; fsgg-sdd-, fsgg-ai-tests/ai-tr/resolver/cli-tests-cache-sandbox-, playwright_chromiumdev_profile-*, org.chromium.Chromium.*, and tmp.* only with driver/run-smoke.mjs, idle 6 h because they carry no PID) whose owner is dead (PID absent, and no live process references the path via cmdline, environ, cwd, fd, maps or /proc/net/unix, relative words resolved against the process cwd and symlink aliases by realpath). It refuses to delete while a same-user process cannot be inspected (non-dumpable processes have a root-owned /proc dir; allowlist systemd --user, (sd-pam), sshd), uses an iterative O_NOFOLLOW directory-fd removal that never follows a symlink or crosses a mount, and refuses euid 0. playwright-artifacts-* and fsgg-gate-* are deliberately not swept. Hourly user timer templates (minute 37) and install.py tmp-cleanup and chromium-env effects ship in source; Root installs after merge. Limits: a dry run on the real host listed 874 of 1077 matched entries (3.3 GiB) removable and removed nothing; the probe samples, it does not reserve; lanes still need TMPDIR set to the disk path for the pressure to drop at the source.","supersedes":[],"tags":["fdev","tmp","tmpfs","cleanup","capacity","browser","chromium","tmpdir","unix-socket","environment","testing"],"title":"fdev host hygiene: /tmp is a shared 16 GB tmpfs, so hold on browser count and /tmp headroom, use a short disk TMPDIR, and sweep only dead harness dirs"} diff --git a/.github/workflows/fdev-board-tend-selftest.yml b/.github/workflows/fdev-board-tend-selftest.yml index 97a9920db..eca53ad58 100644 --- a/.github/workflows/fdev-board-tend-selftest.yml +++ b/.github/workflows/fdev-board-tend-selftest.yml @@ -9,12 +9,16 @@ on: pull_request: paths: - "deployment/fdev-board-tend/**" + - "deployment/fdev-chromium/**" + - "scripts/fdev-tmp-cleanup.py" - "tests/fdev-board-tend/**" - ".github/workflows/fdev-board-tend-selftest.yml" push: branches: [main] paths: - "deployment/fdev-board-tend/**" + - "deployment/fdev-chromium/**" + - "scripts/fdev-tmp-cleanup.py" - "tests/fdev-board-tend/**" - ".github/workflows/fdev-board-tend-selftest.yml" workflow_dispatch: diff --git a/.github/workflows/fdev-host-hygiene-selftest.yml b/.github/workflows/fdev-host-hygiene-selftest.yml new file mode 100644 index 000000000..2f722cbd6 --- /dev/null +++ b/.github/workflows/fdev-host-hygiene-selftest.yml @@ -0,0 +1,45 @@ +name: fdev-host-hygiene-selftest + +# fdev host hygiene (.github#5240): scripts/fdev-tmp-cleanup.py removes dead harness temp directories from the shared +# /tmp tmpfs (dry-run unless --apply), and deployment/fdev-chromium/fdev-chromium-env defaults TMPDIR to a short +# disk-backed path. The capacity probe's browser and /tmp holds are covered by fdev-lane-capacity-selftest. These +# fixtures build a fake temp root and a fake procfs, offline and credential-free, and never touch the runner's /tmp +# procfs, systemd or a real browser. +on: + pull_request: + paths: + - "scripts/fdev-tmp-cleanup.py" + - "deployment/fdev-chromium/**" + - "tests/fdev-tmp-cleanup/**" + - "tests/fdev-chromium-env/**" + - ".github/workflows/fdev-host-hygiene-selftest.yml" + push: + branches: [main] + paths: + - "scripts/fdev-tmp-cleanup.py" + - "deployment/fdev-chromium/**" + - "tests/fdev-tmp-cleanup/**" + - "tests/fdev-chromium-env/**" + - ".github/workflows/fdev-host-hygiene-selftest.yml" + workflow_dispatch: + +permissions: + contents: read + +# PR-keyed concurrency (#4730 CI-load): a newer run for the same pull request cancels the superseded +# one. Any other event keys on `github.run_id`, so two events at one ref or sha never drop a run. +concurrency: + group: fdev-host-hygiene-selftest-${{ github.event.pull_request.number || github.run_id }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + fixture: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v7 + - uses: ./.github/actions/setup-policy-python + - name: Run the cleanup fixtures + run: bash tests/fdev-tmp-cleanup/run.sh + - name: Run the chromium wrapper TMPDIR fixtures + run: bash tests/fdev-chromium-env/run.sh diff --git a/deployment/fdev-board-tend/fsgg-tmp-cleanup.service.in b/deployment/fdev-board-tend/fsgg-tmp-cleanup.service.in new file mode 100644 index 000000000..fb437c58c --- /dev/null +++ b/deployment/fdev-board-tend/fsgg-tmp-cleanup.service.in @@ -0,0 +1,20 @@ +# Rendered by deployment/fdev-board-tend/install.py from fsgg-tmp-cleanup.service.in (Refs FS-GG/.github#5240). +# Do not edit the installed copy; change the template and run `install.py tmp-cleanup --force` again. +# Removes dead, idle harness temp directories from /tmp, $TMPDIR and ~/.cache/fsgg-tmp (scripts/fdev-tmp-cleanup.py). +# Only known harness names; only when the owning PID is dead (or no live process references the entry) and +# nothing under it changed for over an hour. Never follows a symlink. Never touches a live run. +[Unit] +Description=FS-GG fdev dead-run temp cleanup (Refs FS-GG/.github#5240) +Documentation=https://github.com/FS-GG/.github/blob/main/docs/coordination/fdev-host-hygiene.md + +[Service] +Type=oneshot +WorkingDirectory=%h +UMask=0077 +NoNewPrivileges=yes +# Housekeeping must never compete with a lane for CPU or disk. +Nice=15 +IOSchedulingClass=idle +TimeoutStartSec=600 +# Deliberately no PrivateTmp: the job exists to see the real /tmp that the lanes share. +ExecStart=/usr/bin/python3 -I @LIBEXEC@/fdev-tmp-cleanup.py --apply diff --git a/deployment/fdev-board-tend/fsgg-tmp-cleanup.timer.in b/deployment/fdev-board-tend/fsgg-tmp-cleanup.timer.in new file mode 100644 index 000000000..6172d1d03 --- /dev/null +++ b/deployment/fdev-board-tend/fsgg-tmp-cleanup.timer.in @@ -0,0 +1,12 @@ +# Rendered by deployment/fdev-board-tend/install.py from fsgg-tmp-cleanup.timer.in (Refs FS-GG/.github#5240). +[Unit] +Description=Hourly FS-GG fdev dead-run temp cleanup (minute 37, away from board tend's :07, the drift observer's :23 and the :53 dispatch) + +[Timer] +OnCalendar=*-*-* *:37:00 +Persistent=true +RandomizedDelaySec=120 +Unit=fsgg-tmp-cleanup.service + +[Install] +WantedBy=timers.target diff --git a/deployment/fdev-board-tend/install.py b/deployment/fdev-board-tend/install.py index df5a6327e..1d56b1135 100644 --- a/deployment/fdev-board-tend/install.py +++ b/deployment/fdev-board-tend/install.py @@ -1,7 +1,7 @@ #!/usr/bin/python3 -I """Install the fdev board-tend units (board-reconciler design section 8, #5136 PR 8). User-level only. -Three subcommands, each writing one kind of thing and nothing else. Every one has --dry-run, which prints what it +Five subcommands, each writing one kind of thing and nothing else. Every one has --dry-run, which prints what it would write and changes nothing. None needs or uses root; every destination must be under $HOME. units Renders fsgg-board-tend.{service,timer} and fsgg-board-tend-daily.{service,timer} into the user @@ -11,6 +11,11 @@ kit-root Writes the two lifecycle-contract.md mirrors of one released ref into the pinned kit root, after checking each against the expected sha256 and for exactly one fsgg:board-tend-contract/v1 marker. enable-file Writes the EMPTY enable file ({"apply": []}) with mode 0600 and never replaces an existing one. + tmp-cleanup Renders fsgg-tmp-cleanup.{service,timer} (hourly dead-run /tmp cleanup, .github#5240) into the user + systemd directory and copies scripts/fdev-tmp-cleanup.py to the libexec directory. The unit runs + the script with --apply. Without --enable it does not touch systemd. + chromium-env Copies deployment/fdev-chromium/fdev-chromium-env to ~/.local/bin (the source of truth for the + installed wrapper, which sets the short disk-backed TMPDIR default, .github#5240). The engine and the kit root are pinned to one release: the engine must live in .../coord-/ and the kit root must be named kit-. @@ -32,6 +37,11 @@ UNIT_TEMPLATES = ("fsgg-board-tend.service", "fsgg-board-tend.timer", "fsgg-board-tend-daily.service", "fsgg-board-tend-daily.timer") TIMERS = ("fsgg-board-tend.timer", "fsgg-board-tend-daily.timer") WRAPPER = "fsgg-board-tend-run.py" +CLEANUP_UNITS = ("fsgg-tmp-cleanup.service", "fsgg-tmp-cleanup.timer") +CLEANUP_TIMER = "fsgg-tmp-cleanup.timer" +CLEANUP_SCRIPT_SOURCE = HERE.parent.parent / "scripts" / "fdev-tmp-cleanup.py" +CLEANUP_SCRIPT = "fdev-tmp-cleanup.py" +CHROMIUM_ENV_SOURCE = HERE.parent / "fdev-chromium" / "fdev-chromium-env" ENABLE_TEMPLATE = "board-tend.json" MIRRORS = (".claude/skills/work-board/references/lifecycle-contract.md", ".agents/skills/work-board/references/lifecycle-contract.md") MARKER_LINE = re.compile(r"^\s*\s*$") @@ -181,6 +191,38 @@ def command_units(args: argparse.Namespace) -> int: return 0 +def command_tmp_cleanup(args: argparse.Namespace) -> int: + if os.geteuid() == 0: + raise Refusal("run as the fdev user, not root") + unit_dir = user_path(args.unit_dir, "--unit-dir") + libexec = user_path(args.libexec_dir, "--libexec-dir") + plan = Plan(args.dry_run) + for name in CLEANUP_UNITS: + text = render((HERE / f"{name}.in").read_text(encoding="utf-8"), {"LIBEXEC": str(libexec)}) + plan.add(unit_dir / name, text.encode("utf-8"), 0o644, args.force) + plan.add(libexec / CLEANUP_SCRIPT, CLEANUP_SCRIPT_SOURCE.read_bytes(), 0o755, args.force) + plan.apply() + commands = [["systemctl", "--user", "daemon-reload"], ["systemctl", "--user", "enable", "--now", CLEANUP_TIMER]] + if not args.enable: + print("systemd not touched; to enable: " + " && ".join(" ".join(c) for c in commands)) + return 0 + for command in commands: + print(("would run " if args.dry_run else "run ") + " ".join(command)) + if not args.dry_run: + subprocess.run(command, check=True, timeout=60) + return 0 + + +def command_chromium_env(args: argparse.Namespace) -> int: + if os.geteuid() == 0: + raise Refusal("run as the fdev user, not root") + dest = user_path(args.dest, "--dest") + plan = Plan(args.dry_run) + plan.add(dest, CHROMIUM_ENV_SOURCE.read_bytes(), 0o755, args.force) + plan.apply() + return 0 + + def markers(text: str) -> list[str]: fenced, found = False, [] for line in text.replace("\r\n", "\n").split("\n"): @@ -259,13 +301,24 @@ def parser() -> argparse.ArgumentParser: enable = sub.add_parser("enable-file") enable.add_argument("--dest", default=str(pathlib.Path(os.environ.get("XDG_CONFIG_HOME") or h / ".config") / "fsgg/board-tend.json")) enable.add_argument("--dry-run", action="store_true") + cleanup = sub.add_parser("tmp-cleanup") + cleanup.add_argument("--unit-dir", default=str(pathlib.Path(os.environ.get("XDG_CONFIG_HOME") or h / ".config") / "systemd/user")) + cleanup.add_argument("--libexec-dir", default=str(h / ".local/libexec")) + cleanup.add_argument("--enable", action="store_true", help="daemon-reload and enable --now the cleanup timer") + cleanup.add_argument("--force", action="store_true", help="replace installed files that differ") + cleanup.add_argument("--dry-run", action="store_true") + chromium = sub.add_parser("chromium-env") + chromium.add_argument("--dest", default=str(h / ".local/bin/fdev-chromium-env")) + chromium.add_argument("--force", action="store_true", help="replace the installed wrapper when it differs") + chromium.add_argument("--dry-run", action="store_true") return root def main(argv: list[str] | None = None) -> int: args = parser().parse_args(argv) try: - return {"units": command_units, "kit-root": command_kit_root, "enable-file": command_enable_file}[args.command](args) + return {"units": command_units, "kit-root": command_kit_root, "enable-file": command_enable_file, + "tmp-cleanup": command_tmp_cleanup, "chromium-env": command_chromium_env}[args.command](args) except Refusal as error: print(f"install.py: refused: {error}", file=sys.stderr) return 2 diff --git a/deployment/fdev-chromium/fdev-chromium-env b/deployment/fdev-chromium/fdev-chromium-env new file mode 100755 index 000000000..ef3cd9978 --- /dev/null +++ b/deployment/fdev-chromium/fdev-chromium-env @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +# fdev-chromium-env: run a command with the fdev Chromium runtime bundle (nss, nspr, at-spi, X libs, fonts) +# on LD_LIBRARY_PATH / FONTCONFIG_FILE, so Playwright's Chromium (headless shell) launches on fdev. +# Bundle: ~/.local/share/fdev-chromium// (see manifest.json). FS-GG/.github#5193. +# Source of truth: deployment/fdev-chromium/fdev-chromium-env in FS-GG/.github; ~/.local/bin holds an installed copy. +# +# fdev-chromium-env [--gpu|--no-gpu] [--bundle DIR] -- +# fdev-chromium-env [--gpu|--no-gpu] --print-env | --print-args | --print-args-json | --check +# fdev-chromium-env --print-tmpdir # the short disk-backed TMPDIR, for non-browser runs: export TMPDIR="$(fdev-chromium-env --print-tmpdir)" +# +# Chromium launch flags cannot be passed by env var (neither Chromium nor Playwright reads one), so this +# exports them for your launcher to pass as `args`: +# FDEV_CHROMIUM_ARGS space-separated +# FDEV_CHROMIUM_ARGS_JSON JSON array e.g. chromium.launch({ args: JSON.parse(process.env.FDEV_CHROMIUM_ARGS_JSON) }) +# +# TMPDIR (FS-GG/.github#5240). /tmp on fdev is a 16 GB tmpfs shared by every lane; browser profiles and test +# trees filled it and failed unrelated tests. When TMPDIR is unset or empty, the command runs with a short +# DISK-backed one, $HOME/.cache/fsgg-tmp (mode 0700, created if absent). A TMPDIR you already set is never changed +# (set TMPDIR=/tmp to opt out). FDEV_TMPDIR overrides the default path. The path must stay short: a Unix socket +# path is at most 107 bytes and harness sockets nest under TMPDIR (the SDD race test binds +# $TMPDIR/sdd-race-characterization-<32 hex>/inputs/socket, TMPDIR plus 73 bytes), so a path +# longer than FDEV_TMPDIR_MAX (default 32) is refused with a warning and TMPDIR is left unset. +# Caveat: MSBuild reuses build nodes (/nodeReuse) only between processes that share a TMPDIR, so lanes that run with +# different TMPDIR values may start separate node pools instead of sharing one. +set -euo pipefail + +# Short disk-backed TMPDIR unless the caller set one. Only the run, --print-env and --print-tmpdir actions resolve it. +resolve_tmpdir() { + [ -z "${TMPDIR:-}" ] || return 0 + local dir="${FDEV_TMPDIR:-$HOME/.cache/fsgg-tmp}" max="${FDEV_TMPDIR_MAX:-32}" + if [ "${#dir}" -gt "$max" ]; then + echo "fdev-chromium-env: warning: TMPDIR default '$dir' is ${#dir} bytes, over the $max-byte budget for Unix socket paths; leaving TMPDIR unset" >&2 + return 0 + fi + if [ -L "$dir" ]; then + echo "fdev-chromium-env: warning: '$dir' is a symlink; leaving TMPDIR unset" >&2 + return 0 + fi + mkdir -p "$dir" 2>/dev/null || true + if [ -d "$dir" ] && [ -O "$dir" ] && [ -w "$dir" ]; then + chmod 0700 "$dir" # also tightens an existing looser directory of ours + export TMPDIR="$dir" + else + echo "fdev-chromium-env: warning: '$dir' is not a writable directory of yours; leaving TMPDIR unset" >&2 + fi +} + +mode=no-gpu +bundle="${FDEV_CHROMIUM_BUNDLE:-$HOME/.local/share/fdev-chromium/current}" +action=run + +usage() { sed -n '2,24p' "$0" | sed 's/^# \{0,1\}//' >&2; } + +while [ $# -gt 0 ]; do + case "$1" in + --gpu) mode=gpu ;; + --no-gpu) mode=no-gpu ;; + --bundle) bundle="${2:?--bundle needs a directory}"; shift ;; + --print-env|--print-args|--print-args-json|--check|--print-tmpdir) action="${1#--}" ;; + -h|--help) usage; exit 0 ;; + --) shift; break ;; + *) echo "fdev-chromium-env: unknown option '$1'" >&2; usage; exit 64 ;; + esac + shift +done + +if [ "$action" = print-tmpdir ]; then resolve_tmpdir; echo "${TMPDIR:-}"; [ -n "${TMPDIR:-}" ]; exit; fi + +bundle="$(readlink -f "$bundle")" +lib="$bundle/root/usr/lib" +conf="$bundle/fonts.conf" +[ -f "$bundle/manifest.json" ] && [ -f "$lib/libnss3.so" ] && [ -f "$conf" ] || { + echo "fdev-chromium-env: no usable bundle at $bundle (expected manifest.json, root/usr/lib/libnss3.so, fonts.conf)" >&2; exit 66; } + +# GPU: ANGLE over Vulkan (RADV) is the proven hardware path on fdev (FS.GG.Game#746 probe F/H: WebGL renderer +# "ANGLE (AMD, Vulkan ... RADV ...)"). Default Chromium flags silently fall back to SwiftShader (software), +# so --no-gpu pins software explicitly. Playwright adds --no-sandbox itself; raw chrome needs it on fdev. +if [ "$mode" = gpu ]; then + args=(--use-angle=vulkan --enable-features=Vulkan --ignore-gpu-blocklist) +else + args=(--disable-gpu --enable-unsafe-swiftshader --use-angle=swiftshader) +fi + +json="["; sep=""; for a in "${args[@]}"; do json+="$sep\"$a\""; sep=","; done; json+="]" + +export LD_LIBRARY_PATH="$lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" +export FONTCONFIG_FILE="$conf" +export FDEV_CHROMIUM_BUNDLE="$bundle" +export FDEV_CHROMIUM_MODE="$mode" +export FDEV_CHROMIUM_ARGS="${args[*]}" +export FDEV_CHROMIUM_ARGS_JSON="$json" + +case "$action" in + print-env) resolve_tmpdir + printf 'LD_LIBRARY_PATH=%s\nFONTCONFIG_FILE=%s\nFDEV_CHROMIUM_MODE=%s\nFDEV_CHROMIUM_ARGS=%s\nTMPDIR=%s\n' "$LD_LIBRARY_PATH" "$FONTCONFIG_FILE" "$mode" "$FDEV_CHROMIUM_ARGS" "${TMPDIR:-}"; exit 0 ;; + print-args) echo "$FDEV_CHROMIUM_ARGS"; exit 0 ;; + print-args-json) echo "$json"; exit 0 ;; + check) + rc=0 + for b in "$HOME"/.cache/ms-playwright/chromium_headless_shell-*/chrome-headless-shell-linux64/chrome-headless-shell \ + "$HOME"/.cache/ms-playwright/chromium-*/chrome-linux64/chrome; do + [ -x "$b" ] || continue + missing="$(ldd "$b" 2>&1 | grep 'not found' || true)" + if [ -n "$missing" ]; then echo "MISSING for $b:"; echo "$missing"; rc=1; else echo "ok $b"; fi + done + fc-match sans-serif | sed 's/^/font sans-serif -> /' + [ "$mode" = gpu ] && [ ! -e /dev/dri/renderD128 ] && echo "warning: --gpu but /dev/dri/renderD128 is absent" >&2 + exit $rc ;; +esac + +[ $# -gt 0 ] || { echo "fdev-chromium-env: no command after --" >&2; usage; exit 64; } +resolve_tmpdir +if [ "$mode" = gpu ] && ! ls /dev/dri/renderD* >/dev/null 2>&1; then + echo "fdev-chromium-env: warning: --gpu but no /dev/dri/renderD*; Chromium will fall back to software" >&2 +fi +exec "$@" diff --git a/docs/atlas/catalog.json b/docs/atlas/catalog.json index 482b95489..1b4569c77 100644 --- a/docs/atlas/catalog.json +++ b/docs/atlas/catalog.json @@ -1 +1 @@ -{"records":["000ada42299601fba29016e5c0e0d4012876fb42670bb10fa0b1315477254ba4","003893cc49855d17a15295d7adbe57ee301ea20281dff216461baee0810853ff","0052dfb9eafceabaa590f4497e4d42f19020718c84b981d265edefd432ccf8dd","00641d046d6869fdd0023ab3df99e0e67a6ea28f0dcb701f622b1cec8b3e07c6","0066d4a624c02398f21b4d7a736a9fb5101ed8b6b13ceeab46907e9401af98ff","026a241141ee10eb829aa6ce461969242d5c1d45fe9ca19f08ef4ea880877676","026b08fb343aefe19177e95b759560d340d372def4b71acf613fefee3438ade2","0357495d23fac4fad210b6dd7ed7cc57dd33d107e1659a81f085cad78300797f","036c148f6d0e89858c9bf4cf380272ca6904bb4ca277a909fb71c47f5450cef7","04652cbc95ac4dcd21b837b38f2ca5a0ccd4d0946bc13fdb31c9c15a578d3a2d","04d17203f03279980862496517a1f0861be5f6cc8063bfbf92f8f8ac19744fdd","04e404d89dca295564813149472b1de8e6c43357e2f6d91d169ded7600ed3a02","0509e5c6fdbd2dde0c0db8558647080560714804d00e4f9268342f2e84858a3d","06ad2c8aa0ff3b862edf3ba99e0e4e8801ee163709e66333cd06c3fc61232b05","076259a45e71df780b012d29618c17739246c86321d2ff05a6c272bcca8db675","076fa091c878b19cf56a94be0966dbcd58d52c1839f9d4b85bbfdef650cbdb88","08b3dc660b9d2bbbe75b590b2b86d941bf935a254cd5f09de71ee6894f4048b6","09e90ad705af012a8c36efbf296757f35adf9c9ce3b8908791c75d72c192973f","0a6d7dc5b64970bfdadc9049ace95e8bc163fc421beea70129ff0eaa692c6d06","0a862ee40916522f8ae5f14b3e084bf5f2e6488185583346db96ced16ce7619e","0a9df276d42b56d98a7802befc2404204e0e5ee8bc7f5c032f7bb29aa4ae2091","0ad4403c8f4078dbfa543310c69bd1dfc768e305987214ffc37d7b2600c4687c","0b2d1557ff6df5f4d65d540a5403b07ba81b381dfc799b7884ac72dfa6ee7753","0c22360d4653eb0f450e4d3d34564875f1660cfcb2d546095d98b3faa3967cbc","0c7d3f36e3bb4270edbf7abd99cd2dab772df274cad1c27c7e87e302b8eb1c23","0da4d093b49c0a1f654b38008bb01195e816829279ca1989bd2448194e15361b","0e560af7d9dd2e0f2f588a74cd35512973747f20bdfe0bee0bc889105ea53dc9","0ea7107c2c8edaab3ff2bae32f63cfbef6903a51cdaff257278f757ed5ef429d","0eef4d717eb03f0906aa3be7336aa71f831726afabe8a56077b76f6e82fd08e1","0f11324ad653d8d841962b0eeae9f68b80243d4ef7df4f2404ed4c3e45ba5197","11fe30832d93706c60efd836b09f35f049c4a715ad6144cf277ca240c5780704","1244d27db0cf5075353bcc622d0fb3b5ca6a7d08526e2c5754e8b745c250bf3f","126c817ad25ca9cbac2a0f7446e76c79852459ac7b9c61e3ba5d5cbfe5d37dfb","13824d6bce0f961c89eef4bd3c8a72ae6ecf7a1339b9e06eec964dc5c12dc544","13d0363b8d765c87a57eb42c4988320a9c2e7fa09024aa972f4b13d7699a552d","14156f1c6bf0fa8dfcb5cfafac09e012db446d528dad0e4301404fd693b9bed3","155fe673b8ae12549c978e1bf1d5c43e360937fcf2135cdcd5aea6f6c771da44","15d41240067e2335a0354a4e910b6610f2b8f079b8f67186f10181622b4a8999","1746f4f9d47b7dc42280dd34e664b3ec410d3cc69ac76933707499ffa34c79d4","1754adaf40732c3a8c73d2285c25a8b6c8c9d3e68370de618a0ffa8f3e60fb6d","1945f527afc3c2930ec4d7fa57ebb2ef7dd6321c0dd3ab9233c9963e9e613165","19d657b67672257ece127f3b957674b7fb4780843148db0a36a0b329c2a418ba","19e75be8ed4dfba2a6f8034154052160a7a181b17d887b3e8724f3e3c111c31e","1a24f6ef0c08a898f309c1b925fc19b29526f913a61a1dfe4b1a4308ebdd97ac","1b3ec24337f0252a00cfeb6df0a0f5d2b6d737dbea61b8d0b4a643f4c686df6a","1b5351b2dc647aba864e387168db5128435cb80da94fc42581cd60a05fc34b9a","1b8cad98d53da179ab05eb47c1783f4c8b45b9f39c635e7a337285f5cd9621c1","1cfd18d1b12b25604d818389a34bbaa746f450e70246c7f4242fc4e215fc46a4","1da011289116fe88fe92cb8f0e83ed7ccbbca251681d4e136c5a61c40364f8d3","1ec9445b242d2a2e149fe71c67bf13d8c0e4ebe5a6ed7b022656b9941973909d","1edc36731a9c76ad07d269d8b4fd84c8c956bb43d6f56de17d6208164856ffbe","1fec5a63a7b2b212e3e5d5222e49061f3b924966c9741294f5630836be8a3925","20901b579f69cc97eb56b492938864667576e1c9bfacf13f8a529c4f6e543448","20d01a387b4d0801cb588492ede88cae7bade9b7ea3591d9e954add1e67cf4ce","21338155cb4f52c49e5072c877771be67c75590d9b238ea025fba5209fd6e018","22ef13e60456fe9046dfe72f20122362aeefbbb445632231b8e364ed9b50e135","23af79bd1e7995fc8162ddc4d830318acb054bbfcc9c7d5cb141ec306da67386","24373b643450d9dd3b8a5b0e74a5fec2844cd8cbca7d8a57dbc8b9ad9eade9dc","24d4f2730d94d1b7f149771ef0e59192f4936d142b21f4a56b1a391e4514d38d","252de742c26409c837ef491f55eb03ffcc99da13fb1a2f8ab66efbfb0c081a2f","253bb17320020b6a5ef8f0958856f6c565a239b4dc246d9e825f8b14da9ca8de","2591526ddabbea03fbdc38bf172bc54f42df9bc51eba7ad2b70d6e67215f08f1","26259abc7fe745f52e06f2aa2abb0e50f189bc7608065f04d5c669a0a99941cd","26290a0990d6dac0ce9448e05eb934210603356043dcf14a5d80585288e2aa92","26d6b31965013079d4db67a2c403e01f21e3c30ae65953400dbed92e289a0925","288daf614247c260cb673d8674e8b3874ccc4e269347836851f702d7ac8e2f7c","28abfaf6d50ca38af0b88aa50524200c17af9000da83ddbab3d8f9e06e020fa5","2905a2b4a58bd9ec1c4f77fd3d1d246c02caa49d806272756dd039c79521442f","291d3db272eae084d34c04bc1305f2abb26a7e7acbc5515208469b46719a4ed1","2a38ddebfe3380232e35d5a24f9cb9f7c38abbc9c68add4ea5952c1e65d328d2","2b4f7c8dcc95ca8182105b9b6806391666e6a2c3a5c80d3ce5a5f04fd6cf9122","2b5e739c8f9602c585e67554c457e6e53351679afd56ff324f8fecc80f0891f1","2bc251ffb58a0d03480748058eff4c44079a0f21d75743063cef50263982337a","2c76ce93500601e281a41f5985fe4e3926fc8bc9d01ee687f14052cb553ad2d2","2d46924a94c85f4275a449dd3d9eb6c602cf8a9104db19d224e3aa469b858d06","2d5048eeef90792c0a2b9aed7305598a28db2103fed3903462c6c1882733c3e8","2d599c722a08306b98f2d833fb3e4a7acb9dea92e6a58820caa2f65c09803fb8","2df1610ac1b912232030b5507e5e944515b0f1549bf2b76ecfb12baf0f40ccea","2e1bc31ff6b6fb14d0ca8703a02833db749b03e172f2e91f9423f0751e88c256","2e872e9d3ab8b553270e79673060c50c1afd68a41fcf9fdd0a13cba80be0dfaf","2ecd502add2d801eebed39411fadc9a80098ba9ce04a5f4b728a0e4e331232d6","2f7357367d921995f4c6fdaa693392adcd2df4860ef4d25c8dc47f7ddea8c755","2fb2ed7902a8e35dc36489a23245d963026d688008c92fed6fdc1f6bc27198a6","2febddcced970d495778f33fff212929ac99c23adc42be0c1062f5c8676ffce0","3018f389f6928af5830bdd081c9d03530a379f37d1c2f9196e6fb3c44eb337d5","310bfb5b2d061bb733771e5cb7b3b7d25db43af5eda9f806169b7ef9330c2fe7","31fe4b51d55cd99a4692d2cb787d362cb4c0d0998d3e001efdb5cb7ed838340f","32f69a7b8997ae98b9305ee578145d795dbcd39ca4469bf2465e57a0295cda51","335683e33b94cb86b5e426b4faed200673bf850151191a08458136ceb164fd4e","3407ec53a884d3945d86a88d6b9a883419dd426e96b1108a8e6686f30397a629","3442ba5c7643c793f62d90ca841f7891b3dbf97f028bc7b62f8b4f88c1266d1c","34463778cf2d29e3896a65613cf9e3eb3e9f2d8946d17f12b609e70eec63d128","348ba129b7b9c94e24fa8ddb81024e777c60448d1b5d49f7b2075591b23c13b1","35da3938b72cf3520e126ad595157104b69ab748904c7b4e12f563d6b103172b","3600e7356a3741ef02f8b2ffa6a6b5d822dcbb170771f2ea33312dff4470f431","37c8908ea2a349cd3034018027160ad810b28ad1fc203a9a353971e1f7396b4c","37e39faee019bb041627510f1f02746ba9a85696417a083b438eb4974b72c2bf","38a75fd804821f4836f0a7ba8d41af3d3a3a5f5d7dcea68487009297824258d9","38c6396e645750efcb2f187c36c383471b3b0b59290e3b42cfcb9668594cd0c3","3962789d05f324d436a363700cbb5ced5aba791d782b3c0ea73221fe0c1f0b97","3966e5e53811c43962f5d0953e5da4753eacefbea27ecba9d36af2fd8e4fd52f","397476cf107b48e7a662264f8fea9f880231fd3d1e0401622650f214cfaa35c7","3ad8b0398ba6c354c9e31b7438b2515579fc0b1f17de4b35a914c862a3a11e3b","3b3c6cf083b12a840565e00458e2fd4ee8a61f97cda452703a6b13d7776b6c13","3b4af144afed3d52dd2e1f64e23bc25b3475eee5f7af3bde9886761b15c33dfd","3b5d82795e9f5d1992ab67e078fcf1108247ab9b6d1baeac944d3ec0294cec5d","3bce154e59c5c45216bb5372a352e948d6cb365bb1bd47d4666ae0412e507ca4","3c75b650f3fa8217597b01d3aaf25427ae2a658a7c966afeecdb391d3ba547ea","3d0274f77576abdbdf442c8843e955e1bbc91e9f8cbfe3646b119337cdb13c96","3d642ccf9ca4a0f7f5dde1b41f65c99e9c447cbb9e64883b67e4fdf76f216f52","3d9fd2c5877483382f0c7331206393e42827b5dccfd60549a6771b7a5659e524","3dbf6d1c2c8db1a7e3988e2a84b67a4e1d7c8304661652ffa94db3b7eee08edb","3dfcea4ee3d0d0ed09b1f77bac48b33b64ab4620cbfc74fe0e4201b4cdb81ce6","3dffc36586e9078f750b0a2b4cc2c70a17a81294903186dbe8cc47cf8055b9bd","3e2f66baa16c7ea936eba34720a55897438f60b343cbe8fda4eab1e5dde044eb","3f5465798dbc2ad279ca4849d5d0f819bad01455e0dd2a9d98afd4b55cfbd7ee","40de9f41f9a9f56ef6a51d065270e875b4a85cf043b7c4a0173b2510de4979ea","4134a3936170c1fb5fa6d2e2329185a981436477a66b7d31e827c363691bad50","414259a2fda4a1a49729be6fb1aced4675ee9cbdf990aaafb8e5b3153b54d64d","41baa5d98b5bab2ee01cad50c05b83edd8cdfeeb00f30b9406b4b2ec6d13d738","41c768ea17144c6ec225e9a65d4c3c127fdd7264dcba1a89aa17b20fd5d7e3ee","42aeb46fcc3d10b95e4067bc9cda875fa933b4102873f67c7bf1f8ca6799a598","4320b92712bc14dbe10b56f1cd3d1bdc093fc4be6016732839d0be4dd4d027d3","444342c21a4743af5961beeebb88088f5d2a0649f76c71973a7706a744f5efd2","4457ab439bc8f212d83442dc7500e9d45ffac849d0f77cb97686d9b0672fc3dc","461d34fb1d53849951a7e715e52342372d779299fbcad210794235c610dadf64","46a24cd8e385b748f40d9271b1e856dd6d68c91ab356abb11ff6b65f1ef936bf","46cdf2c207f79d388001f6636dfb7a98bb2ba72b9d1c6df4938f0a27691e07a6","471570cdf8144df0c32aba1730aba24c7e42e5ec317af771ffa169f5c842d117","47b5cb2b011c0f7012d75e88eb86a10f3f0bd48545db139669e654cac1f69650","480f1ede18ae031b164d49d676feeb1090fb33932676ff52e1e2eb24e8d154cd","48262b98c0bdbd5ee2314345726d23630ec1771735db8fe5f1a8590b662c9962","482cd15ecd9cfbd8e1943c0fcde0bbf1d875392dc2a701b698f48bfba684a062","4855e1947afc954cb1b20bb45e7af10b098fa34714bd32e9bc77941cf58fdaaa","48797c44c92cb34fd9a57a08020b45c6920b2268dc8ad616c0f814a3710d5316","48d094622ada1806cb30335926007c1abc476b1f7b45a2e250c490afa25e847b","48de3afdc6ee73ed121d1433bc6367a399286d5f8c2c63670a0b3b9752a36175","49e8cf09e38acefd3a0fa62d048028286d3b47b5ceccd8f51f10022978c47820","49ee4a3f2a8918bdbbafb312cfa807d9982800d13d29ee292c6c0daad8b9b8f1","4a724a6a842a132c2185279513f341b79f9be93e42660f1255770eeae3b1323c","4aecbdfafb68feb3124c39219498241864bcf1ceaf87fbf80598b1dd87a9191d","4b364ecb35ad02b06b6b0f32b6a29202f2c835e1ac0d70b89fd0278271799dbb","4b6ab2768e1ff3716ac8565201c031a820c208db9ea6ae1495dd782e7557a3ab","4be7778c4f491d55154a028d9a9dbb35059953fbcd243e0206902a6e64645efb","4c8c327dacf345e184042092e96ad3ea02ed4cece57dac5fa68ea52fbb5a6adf","4d5a44ba07fafeab823b54a21846269330ce35b4c190f3ddd5434bc8530d9b41","4d86a2764c55b5c5f675fddad8850ce4ceab160ac5c164a299fc098899d31aa9","4da0a5be70e8af9c39623deac83822749482187f6a0fc3d186dcfddaa7111576","4ece7844e2b35705ac39fa25913f6909aad5b4b7446bd637ced46b47c0db135c","4ef30f11bd4dd9d2eef8716d88a83010546e54594b2726de84f6d587651ee940","4f03e231c0dc5c9bb2874f6856382d5b205758af9678fffdc7552d4e4ae9866e","4f1e58fc658a4ceda181e2a7fa249305b09b573ffd68c2489f204f4957224957","4f2750b974c1404acb721ffc84cbd1d0756a24211dd6f6503c10ea74dbc45676","4f6fcf4dd7e73d86e06bdb9c14a1078b61c0efb2663ced9bfbc5f46fbb4c6d8e","5029c7b222158ab3f325168fa543d84fd2332d2e3e38db1ce7b83899cef201d1","509ec9c08864b9dd0029f32ffeac85fbac863e2dad459994c65b7cb5264faffa","50fd7e982eb2d2813634b7c44e102788a1a1cd4910a27acbcf219f76314fa322","52049cc9cee43bb27229e6b3e983e02c6aa20dd7d153b13e3c74bc6d2b47cf92","521ed246c4119acd6b579b6eefa23389a1655df54aa35de7671743979ebfc68d","5382c901d160ca2d79888d8acd7a690a5349826b5da486274b0800c9d7513f11","540879695d41205515aaabe5466971014cb43b960a26b8e5958e37fed63df762","548d237f42167af5cf5caa0ba20f0e7a6387deb6f27765637f078325172396a7","55267f058e9f085117765e4ca72ce875b622ceaceed964f6c396073214835c28","5560616d1e72f0a539f9ebbfea3b7d195c1ef5622f97994af1963748d4f97533","556ee783d8e2e4ca50f656c095758be613983f904d998a6534fb155510114f21","55a4711e799294d06988ab4acf77eacd7d424123082bba3ec987dff0ae13999c","55ae095961d78a1514c4dd1e63d477c60179a8662571ab5a90abd3eb2b83eb10","55dcc23ce52b3918a60029d9398f262216471c280bfe66421cc63240533a6087","566ddcfc45ea5edc695626826ed185930e910fd9107c5bc1844c717b714c15b2","56e7158313357bb145bd98c5f790e569be2203fb2601565a30091a597a7e7ff5","581337891936ba630d34ce9f6b803b82a2130791510f15bab24a07332400417f","5962dd14d3923433cf723d698d1af19ac37a270b6e88445643fc56a646faab5b","5a2064cdf51026eed65457c05f34bec919b31d96d35c29498d298685965f0b5a","5b77bd6dfa81cc339e729e4195e258facbfeb64b9c680512f742e3fb1961fdd5","5c0206d9d014821b52a43d7b222327a89d4ee2f5b1e21813dfa659a69f7426b5","5c3527e43fe24c5aa171c6fa4a3de7fe5e78f2527aed0dd19cb21d154d43da21","5c79c77f00167ca140127b00f1a79e1ffac621e46fc461089594206a7df8d7cc","5ca67643d5111fffd21deb18569162733e846965bf05fe6eb33ccd37c964025a","5d015880319af666943e68169ca906bf2f0c813d8bf2c5c0262aeb5a40366350","5e3a589b627edaf7005c60382475fae7229adc4ffbaab6d6fd03e9f08a0a8e19","5e43baca07fb966bf1c4b3ac06bb819577e477a84c5d8d3a9a19c391ada2e0b5","5f2a75b89983d1005a38afa2cabccc3a39f31989807120281d8505ffd564e0c6","5f43c837f39d207c35a58e9b36fe3144017b2012ac7da334714247606f1906d2","5f4fa6dde5930fe1b42f805895f0f5fb135c2b3ff9830f2bd30ae7526a3295a1","600ec184ee9964881bcaeaf72ad38a72db05d5b629d301cb323fa1ee9369b572","62a713311297a7145d3610ee60dd6626ee543645a1918b050c629207561efb5e","630fdcff1f227b5baf5d10bd78ef0fde68791ac0cd8a15f65065f5cc4501b17b","63113617f2e4ee6b827a69bce6afb3949190a282f5feaaa9e2c9f82372623bb8","6312b7a9f8252f49b8ea0cbd0580b80bbb221db574ea74939823ed9d4140d73f","63544fa69b09916d52b305700eb9816305ff22b77162a44edd13897acea3a655","6385459222fba2c3302d3f2e38c57fcfe0f1829679fead6cffa1964248767d5e","63a4394e689acf4a4762cfb4df691d05f923fdf592fd2f8ea41e6a54f98d1136","65725e1cd3323fdf44ec47067fd6670b441ff5f82e99485e1a4fc7d475f14340","65d5b7eff9d03761c8206218159bb34883c09052d6a1959d040f711a881b4d4f","6601b2bb6c908a46ae2985d4683c8baeeec87b0688b9b33d3e8900286bf4d6ae","666e7f698fbeef24e13e91ccfa334cf781233e060fa86bcd7d4d0eb00b30f3d5","66d414618d4283838bddb6b9fd4b5221c280a7f6a715b622143d3bea76bfe1f6","671168c05789fc651cd961a5a15e10adbb76656b802cb0fcbab468ab76412ca2","671d95a6c09bb7b05a5721d52cb761300a2c8f376aac20be2948b7e97bf302b7","680de944f1f5380c579003e329ed6f10702ec8ebaaa8208743775588d2424d05","6989ec486a05550633170d2aa79188ad9b03aeea6c7859dbf18790ba78c5427a","69ebfc7eb8427db3c5c59bdde652d0cb269426126f8540b1b58caa29ccf130e2","69edc4285578313d1dd2f914d69add075a7b354f7fba717606d1abe15292576b","6a34d9279cae58765d6ee4a980192c0e15f3ca217b9f1815861d472a281b3cf8","6b00dccaa7deabc750679ab085b237a2bd025bd971ee1eb7bdc333b393b19084","6c3c592efe9c684ada5661b8cc88a5c3f6e57c841db06b9e070687504cbf6236","6ce6d164c3e31463fb9e144fdf91413e55d077cfc4f25092bb02923fb538a84f","6e08a638e1e28020923effd4c65fc517dbe7b06100ff76cde74e427191503b84","6f3a7020233cd77cfe59eefec0a277f6dda323743c8d80e4e54a95cd3cbc23cf","6fccc6f0c5fa71c43211785dced8abd0f3295040eab56063f4e8d77f1c09b8ef","700cd21af9ed7e81900fad9d52de2fb11db48e64b038e4293168f85e5dd0e043","702d1dfa75e92a916a446429f474d4c296e6ea4e8c487995852d0525e8440659","704cf778db6086c3e282c81249fb0ef09c1d7c2043335ef74c7ecb69bb3e84ad","7075f89b1271fd04fa02d4db95c0f0bd6bdec24e53a7953d7afaeba40e17e8e0","71ef1ed2d5e4bc7eebe7a73bb3e9423e5bc2f8319186380fe8b38334952d3b01","7256ba00af1cf759b95b7bf8ae3b9943f31349bd10a7652a26bb419b368d73a3","7369b339daca0fcf46ac7fe82d65ae95c75d7dbcaaae51209e6d90b6587a014e","73ec844fb3e2b9febd00ba37508b284fad141630f03cb9f74e36a195180f5054","7410de003c7b582e30470d1209eefc796a70c76fe8d61dd9ccfe01ecfa41310c","741c27b54c49167abef1d8633e3743b0e98f82a73731e744b6671e119a1c6310","74b5d2ed555740db7b4b0ea9b73f8fe00965fea8e14d4f075eec26ef7a189c68","75aaecf53db10459d768a6873f6783e7d7110aa510c2894378df027c1b03584c","76bf5a9c126db6eb466287a7c0d823327ee9882a70eaaa6efb03d169b5dba808","781a64598efb2a11156f07271ba1c14c4f6b3d73aa2943b26eae02063df7af70","786b0c2856bf1f3f809e5903b0a971f1e072af5635aa50bbb9b1449f96d7b694","799abc1e8d381b8d97349479139985e383bb49179b5a80f39807cb35a3ee78ce","79faec494bdd6d098c9d2a9d8559f822938c6b2104188db95321d89e7a732979","79fb2e6e6a91117b6aefbdaabda23ccfa596620f548ee5075993a8dc7a8b872f","7a032dbf0351aa32c77c8d187f7eb697500ff186c88c5946ecc15adc972246a6","7a134e7f1822183ed1c0ded720971539350feaaf92612761210cfc3ccdc55870","7aa52373f2721dd76fc8eeb3d6061794f27ea8d11e96bcb1ff25a97994a77d5c","7ad4ef4b8d3221758a9e7f9577750ee03f6cba11c8eae8bf25f74a3131bd21a2","7af2394d2e697f355439e841b6323ffbbf8b90b2e48bf64873791fbbfdf15b44","7b947ed0a9e6e7ba180921434b993c62ac70bbaba6af0a1618569a2d4b705201","7baa35131ece7ed9860607157d2531d4d70a061bdc9bb9876e20328f127cec53","7c2a1c4c4c03e3d68d63e0ab58e4e34d3f2bc1a4a837a055fd13a4e9f95ce6cb","7cbf970a11bdb91a40e248eee97ef789205910ebc913349698fc75ed35e82fdf","7d6133667f81aa66a98755d253ea43301b45ada338225df034d2ffdfc79829e7","7dd54213b65fa0a6ce5aa3c204b5209b67ec16306b776aed7dcf9e6601d74235","7e89b59b456dde4bbbdbf8079665bd82c51d8e500018472981c15618b3893959","7ead0c68ffa0ced241af74dde58b3831343dff3f7eaab64bddb9954545b7ba12","7efb464c6d7b469303c43f718063d8456df6fe43534b5d8a4229f5b9ba9705cd","7f8188b57ad3b0c28210c95954e5623376a4262dd5e75f002700c6094b8d6b6c","7f91dfc2ea1a3131c4090375db0f489c2a572e245ade6cda4ebd440446d6d60e","7fcb8cba3ed0ee9c342947aa88f0f699bb4f5c23244d21c6c739c9b66d7c6101","800060d7b4934508d0277f90a464e3112fd2fc99af4ef23825d09b0ff53f91c3","800a802a4ce9e597a102f0a566535c1f9f7adfc60c41af6bd2db4fb7fe3c0d0e","820c12fcbded9048a363b9e0ebbc48b24f85fd4a68131b5dfc1b19057bf09ddb","824bff7541ec2a4b0be126f0b0791314d568a0eb4e29073de4f9dbe0ee4918b8","82c419e5de083e423330432c9d45c744043d1bccd8eeccb41e3014ce9ae3c32f","83347356a898238c013dff73246440e361a9e24cc3c4e0fe0e850467772b4938","8343a4211a4d0ffdb320d5a4305174d85bb707d15dad978f6436297d022daa11","83a06a604bbe36d72da976fcdeb88665c762b0f0de44193576ef2e0cf29aa9ad","83a97b9ebb29f5cd014ef5e178970a601ee92c44678f05d1860b383c5f63b79d","85a962a7c23c14dff8d683e738b53f422221697b213cafeb616d3a172a6c4223","85e961266b36e0f8ec2a477f1f1dfe7ad748fdde9d906f7bd3241e6924866ea9","8629fddeb4f273b35df69d4d28923adc14eff59d919b1a495d1a68818137c561","872ab2b2d65fe685b91e355f5af051c85b79569ece16448160d01fef38039624","87789dab547842b4e0c822758e1325a3cbb046063e11e105a4779b3741e01cde","87f2b3634baa504f2ed9508c6cf6a47bbfb36214a177eb13d70d6a987706818c","88b615ef6a31bd9958e98b8ea522f49f0360ccac5d9fa8deb9e3ef3fe3147d9d","89a96597dc9c218633adaf94bb5d6dcf4cad8f5e0b6f5522a28e3ce8d8b2865f","89cafbb20d6029656266d8cb0f85103fa519c8032598282fea58c94cc59c4125","89f2105745b3a7cfd30e7d7c598d6c8fdde0a599f30fd0db7382cba50412445e","8b3eec010d1eae43a28c88434f2410a751f790a9d6ec4a08e75e68c171629ab2","8cce78271b4f001606069a575a172041fbddc52de6b582c920aa3d3b5d5b67ae","8cecfa09651c40be4d7c11c117c80e1911dc75bf6f1cc34be64706823cc024c3","8d250acd40c8a24ba0d51cc73e65bba6856509b5fbf4c7d7a435897a01c6e764","8df1420c27503370db9382f68a0af8d2b4d56f9dbc94b24ffae450a905083a79","8e7371228a726f381fb811d1d812c39917788a3df7e53dba1a3c364e755a0c03","8f3827158091bbed154d21c843284ad472a4552da2eeb858748aa29676e45662","8f4a21c70e4b933eaa4f9cee119945dd2ebeac532e82d34e17511b38cf03608c","8f6debc54d2bd7abb42f581f2204fc78b27ff8c67ee4b6392b4d71c5f983ee9d","8fae27ba5117e202afbd523b249fc454912571900fc909f5419b8ac96c773c44","902b958b4db7d8d8bf73a82a8aa86e5485b39477047c8ad60175d118fe31d987","9056c360e59fc78edde932b54124df317f2f04a90c0c6eb7825a87b89edf1ca0","90aff66decaa3a0998e9a6741963713c0c82fc70da505519e3d60204bf715fa0","90dc4cac6326293bb54486d3c873b83299e9a5ec8c86a68bf1cc131f5e4e2437","918126027fabb7947dd4ae810dd561ac22167102f9f978f86906624ebe88c9ea","91b495938bc6015970bb02c844368d3eee84425b472772cdb374a5347db86de9","91c9ced5e9ab8da897b7f69166a7d0bade5c58d511b42d60d5430d536da45d09","922a332aa100d622da733aea8fc74094739bb63cd480d3349a14d2418ab6b1bb","941f70c384905ab77cb9a88e2671301117e4df553da6fc7a09210710deb9b6ca","9442788fa51227044803f1d3efdfc1c2b2da372871a85f0f7a6bb3596a5c003f","9460f427df72c238c4b55f39c8864f1fa3685b0716a53227ea6f7b591d955c82","947a1cdd43831936480167169d30334f818bb5d882650a3547827c05204af111","95f0c5f3b9071db39fd72b88ec9fb2079ce7553fd5884fa527bc9216777d7c10","96c4c83df72e9d860e2ee51f1a74bc867c4a45efc8bf11bf88aa82e368b89aa4","971f59cc197732d0c0b6b8aabbbefca4550fb8fb04f8522bdb4257c05a28848a","97edc66e594bae06bb273db84a35d84c8162a1fdf55ed46d781419a9f6a2e4f2","985638a05562bb796911ec231d306b81e36ed6b58219b3bde874559e9600b59f","98a097d6ebb754334250dfd3ccc5f3dfaf5966524758cbfc9e10adf4a0229693","98c7e4bc2f05e9b4ca703db4a02347db7355a44f04e3a4003e26c46a56bded2c","98ecc99d3396aa9a35ce97456be66c1aac0cc05bab88aa99109649291e61bc0a","9944d1a9674e555a41d31d069d136461eb06dd4052d40f2e4ea4368dd978e01b","9a8f2389b8ebc29d3769868ff8b918fdeb2236d88192fcf76ab0ea3db0857fac","9af18d8cfee466bc061271d82254d7ea638b59b8d5a3901c6610d5baed85c38b","9b01e565a1541f9e652d7afbe62e3bbff28430c1ccac2226ea434f45fc9a99d0","9b466e8fcabe551bb6292d23a359be3ea15b7627a6ad9c9e6a4ff11444c20860","9bac7daf255467f47b83723095f93fa4b574d5fc08593f48825a2b2ebb8e2dd8","9bbd03293bf53e9db51401d157b3eb2aa51e9c70449350e98b9a0a3fc9a684ce","9c3b318c461b56a8d277133a6b947ef5618690ec281c42e9de6c27f22458d4d4","9cef1feab6841836dc20527fcc8ad9979671fe811ff80a5a33bae113fcbebb97","9cf90b3aa59f3ca0e40fd9e1fec9703428752d63bded6b091d28f614c9ba99ae","9d1a0da545eb6b2e16b18fdd305a2c000ff2340c19ac843914b45f6a4f936227","9d8637e5adebaca208f21af0a254e80712988867411be560031f4b7a23cc04f6","9e77badd0923fd79ca9761a41780ee4dd4f9ca9b62512f4fb59c7f8418494da0","9eb67ea41c5bcb9557ba51bbbd1b321a78f16335cadebbed848d8e6c1fc68bab","9ed400941ed49b2d90ebe3cc111d90d8bc966608ca61fe9bc315a3c1dbe8bc1b","9fb8c5aa087d38dab064a2d6054826377eea3dda98229725c2523f63a87e4750","a0ff0d0bb3a3c801b637d091293f2eeaac68e934274e4116d298ba60ec3461cc","a1baa1f699fd4ce19e8ef6cdfe346e1b0be63e16d5c5cd5feddcccb16a62f269","a2aec2d2f35d7174801247141d637e77c4f34e478c575b0e0a04c6251efaf993","a3c84d76be9d891812e795dd46470c2978dceeff928d729c0d5dd6def599923b","a3d6708506fb5c28f45f0d610bedba11b1ec7bcdb363ffff3aa4cddfa515f56a","a476183540f2e7121e533bf2dd9125dc071c81acc880e88cb435cad7a6d35b97","a4a8cca930cdfd15285ac3a7aa757d61501fb77fc12a7c3fbd78c096b279cf63","a50654761d6812cd811df02199e1b7b25c9b0d65e591f65430f9277ec43d9c50","a514a8c0898b6697696ca6f0ed9a43bf8993085b2db4299e3e9f8e3419c4a5ee","a644885c31f390b5e6b7fe2fc8d086d9144699295ccb6ffa51b3f7c76c8ca71a","a64e8aee389ae696d0d4b045c0153092113fa522ed5a0fd9b5658b8418db4ded","a6c531ed9bbafabfdd649f3030daf2f24461163aaf99dc73bb24dddb77bbcb90","a7ff7302e668dcea1cd1db2241ff95c0d73534539bd03fdefebbfb57f60d3849","a8b4a33078335d2811bffb78eee49aab5fcb31597dae366d43e20c7f7800994b","a91a47fb4fa5c1b1a834fa602030e435ad641240e6ceeb99eeeab7341ca09dec","a91c8a1431a4120667cd523cf56bac004794fc5b8b24275ad2f9c8a15c75fba1","a986593807953215f834ba73e7d2565659b32aa849986013f8614bb1c61ea8cf","aa131e74e695292adab9f57b3ccc5a503a836dd4b95a3b2b107c69f35dba3637","aa4103342641899dc00c22207c13ac31c0c73afd97771b0a9b249187d979625d","aa70263d079788757f176da269e554fef9240845706f87a93101591f8114e807","acae1db4aeb323f3b637fa11b087c3827a2fb6d69718362f54e3bc48f70ef7d8","acd7884bca46ea9422503cead985691da05cca25bd5ed52a199783cae7b8b01f","ad0e6d78c1e450e19bfca4a0e904644ab0ae315607811a28ac3dba20de869786","ae43a4d252290ec0e18c64dd58d51bc885020b2473e71e3ed0741184c9f006b7","ae69fe306bf5db346ddfa4367cda24c95e44213baca27b0ee7d7167bcdd85af6","ae8c200dbcea29f43b29974cc247d70647c80d5d76385396f1c82ee9f669e2f1","aec13a075b84253397fb97e1c93a23e1aaee6d6bff2a9161bfd00a5b1d7611de","af12215a96963c1e7e5d766ed994695e423e4780ed0b3007aed87b150d090c05","af6b60ae365a6cbeb140430b030bdb667f53a2a97508ae92dfc9ed91ca73b54a","b09355a97e3aef396f681943b37a404a98fccc6bcb97781eddb2fc000d1d985d","b0ecfca0d114bae34ffa62ac3ea05159a4415fc6eb73ab1fcc4d79f657268f19","b25c41f19ba40e646fd9b6f82051ee4c38985539e445b26bd628eae98537df53","b262187aa66e8a97083bf7f79b91595bf7a4077abe7f8be5b00b4998f4579d20","b3f50ed7eac0e9c54b74c4f4e02297dd2d2465ce4b699bcc15cfddf54c0f0f81","b4091f93c3d96e36b0708f5dcd46e0e7a0a48f098036ccef6164e4a6429ed94c","b4093c67a9195ee7d28d2575e967ac80057b92339489c244243c7c504c669ff0","b44352445272089cf90967d4d413cf7009bed0ac19f3fa95cb831d5ebad081c3","b4ce73bea5219f1b27bffb36c6a9dee14447a710a8938db807770083db4552ac","b4f2140fb766faf0065a563ac3664f395b24c81dab0d0d0d01df47b22e888d29","b5102ef50e7d4ed1925af5a8b45192e737df02fafb75d7065995a2bb93d2e8e1","b5428b5775526a00645566822530fb969b82247ba83f2c80c06d34151e1f9061","b5c085be21651d8579e52cd3ffe4abe6b7f45c5a9ee84d38c47b4734409918d8","b6cf3b02f36e0efa93b04667cdc5701340033a09e41a7196277cf6756999a666","b77c6669bcd54e0fa949faf2f7205f2631acfbc1ccf79f93f8dab5c5717f0e93","b7fda8f4bf81f8213d18e3c314df5100ccb6b8db7aed6b70aaf202deb606a14f","b7ffd6cddb12384224772e8de79aec89d8f4bca966a3c2a05763889f92a6db5c","b83b7229045affbb98f8fc46f289ad05e6626ef52e3ed2f7e70d332a54a69e2a","b83f5334b85422ac110a24286d5af7003f2fb5b0d783efe257b38a2281656422","b8abe10a2a92bf537a49e8dee92baf8de3ed591848a1b25151dab0d7ab3134e5","b8b8c5cad182083f45ce2d05d036e6bfe91cde1fb63f2e5a97c683bb7ef7ea0f","b96cea09313d481dfff1ed1a2c552ea29e8fe68f52139458996a4e36157748d2","b96f9beb6d6d8fbf88c4b8b2b807a362f2640479cab6173cf64c7710817785a0","b9ad2510d8249ec4c8e7fd8b2471727aa1bd0ce8f3dde78e545fb2f8f2985a1d","ba5c707cf9be40fe966c08807779994e20ca3f30ea9d73e26ce31ca334c05640","ba7d7464da8e13722232c8f86273774054693681becc450a68aea21a5a0e9b91","ba87e5d43ddb10937bb17941f055f80a223d0981fbba44107aeec8530e3a7774","bac3431138e986d6426c1e81bdfe0a968394896c0751cbbcc8f36002fd0ed069","bad8f17b1d399ea125c524895571601c90b6c93418c248bd4ebcc7886bae9878","bb230236c4ab6353afb4147014c93204d3d1eb8a6d18558075df5fe79ed7f392","bb7fa81e41820d63d58313460f5a3999a1f9fc2cd2fb10cbb5b41a931d8be6a2","bcbef69f1ba50e45f3faf1b4529c32cdcf1e5a6612b5bcbc6aa6790ee14b54eb","bd3bf6053f4d423ff21f7ffbed9d0e68f3ea64b7292c048e9a37ade342bb7b39","bd714f38c881208f1190ad714bf8fa5aa63adf302bdaa8ad8810ff279e43459e","be75cc1ee935f783be39978de91ae196c16141d4096e16eb6d07f59583296b4b","be8c3cb2d8d67e63c8b069920b74c6272922febbc6a0a2c4a0072a7a213681d2","beed0f36d9b1b9a20bfbf89c96862482b8d5b9d4284bc89539efe9c9b11f000d","bfd21b5c8eb26e9d475868bb30d66ee08f20876e9df5cd06aa8fec01ffe666df","bfe97e65f2cbe6bcd0f14ff57ea4dc1dedb2e5f0db92d04d0982cf1932ac1c3e","c055d3cfd85b2ed4607b0d9d3a15ab7204c9f149599f748347dca4afe102af0c","c112d36ba38c362da1c022945db5b6bbdc3014685ca9bb7d940f5086f00a675c","c23a43ed460117f663cec698412729fd91b5aaceb48cc4e55a785b525661bf1a","c23cf45c1dcb748145d87f5c173dd3c8becaf9e3f6fdcb3e2ca91d6726b0842a","c24546a064b9315172ce0f951bd5fa2cd1b9884231cf1bdc1dc714771f1b3886","c29b8d250a7b5e73f4ef675329da2251b8de032501e4836445b6aafd90c645fa","c2e96d98c8ebc10237a2af1c224f626acfb9072c83078f4a8c6d9ef0a58b4a8e","c329c9df0dae8a036da9be440432d045be3ee13cf5664cfa6ccf11576ed11acb","c4600cd5358b5798a075beb54539d952f200def1c9a573bd237c795fd33ba36f","c4ebd58c4ff78c9fc0cd17d80ed563520f7908f9d1106735ca0f5a7abed202a6","c5db39bbdc8c2bd2aa7b58c28c3df9e407955cc3250ce7825c842cc4c30eaca3","c65325f807190f7084346376e2f48fc2b6bb946004a1fac1d8d117930e93d462","c6752cc3c7ad06d1e9f127365f078919ac46b77f8a8fe413650094d914838ec3","c6867ec30530fd3feca89a4e968522f783b636b165ef74f288c42dd50bd51a3d","c6bfbb004af355e96ed5b4c8c9b8b7a96d1c08d24bcde7c666728eb9497d6d71","c77c4d3f536cda10a71fe6a9cd17ea7c1408200e2f7aa7c5325d6915ff250c85","c82f38f23e7ed3e1024661b7a22ff694e88d3b268240e2bfc98e630df8a062d0","c8bd340e6fc7fa3e97415f7ad4c22c51d88c6e77f782c12923e841c04d3f882b","c93cd4cb5cf38fe6221fa8ae171ff54240b5f99ba80cd740ffac69c57e5fa381","ca50b525d7aa7762c56f402696dd464841daf19b036bb932e325090004b4cd71","cad13b6653fd9f811e67d13c5f01f9dec047f8c384097cee01dd2e2db39e539f","cc24c3770587f2421514fa399d2617201752bdca145ac39058de91d45d3d19c1","cd2da00f6f1bad8fb7c1b87cff80e122eb017e44a471cdea769efc67db369038","cdbb7338988f2fd35fd92f21909b7801d9954d1c7ca78401f52c9313f21fb6dc","ce887fb65b6977a2046e7583d704863624e55909ebcc9c3ed065b3d13079a410","cf9223c369b6fb7baa52f301f904352ba8e8d5e4c2a06f70de6ef1cf76fe1b84","cfb9705939742247da0cb71fdfd8b5f7a1bef6f1c2f0979a8f42e54c4a480980","cfc3b5044af37ae7485fba8067dcb22b2438bdaa6e3a30c22ce0f9e2c00aa597","d0481d9b6111ab4afba0462e88970b863284807ff44ca97364c84952e3f88583","d0973a1aca6a118375b466d6e91821f8450110fdf042ac848ee16912012d2b0f","d0df3068db679e24d9487ee09a6462ac5cf3df30f46ee466b66feb6dd5ff71e2","d151ffa66d8d096e0272f0dfff6c27e978cfda570f7498a727593081888b4ebe","d227e0a73e3c5452bc5ab41ea2c695dfc0ff9b0c1c81e59ab3173f796a4157cf","d268e680ee1136a239a40ebf005b30db6f3b52a228016f3193496f86250f15c3","d2989a1607fd5303615937b8c117d127b1b1cde519662ab1e1324390220e8612","d2cba4dbbfe3d026f825a8b470a2f6011f9b8e245cf042ae8889afbb17dac6b2","d2e4c515093f8a2aa824c8b542a016e5c321065f4525931b2fac4f8af2fe52c6","d31e8aa21d1498f2d4a07c4cc89ea6f5a6d3ce54d334dbff230e0f55db35c85e","d36034e2f9cc642d0f9f24cf834fa741bac5b8b139cbd2f50e2065161c9f3cb0","d36eb7456d2a42d1cffa4b60708e2bd3116f7f6758c96bbc0fee0f1704ad8a79","d37de74aadd5916eeae243decf347821c4e946356b9f70471658638ac3092f91","d3cf9b1433fd9a083c60baf6ade1df7f2a33e0cc7d519f491f9d6a93139a41e4","d49d02cad8bbfeac607457b08aac6068916ef45d8f6c980279d6e654407cc7be","d4f51c31a454d9abac29457cbbc21e1b5767c0eac1b37c41ee787a3efb05c80f","d52ca358246f638d0e11a061e97863697df44f43b093d6e8b84ba67b5838f2fb","d555a0d2329caace197c1468fe6708349125762377ee3bd04b031b7eacfc26aa","d581443d0b6b42c76b816edc6946ce01a639ae42653ddc8cc2d6a89ce14fe947","d5c084e12da4a5111487c166b879042a21a056f761ee22d9237cb4f65f366341","d6077d547aa21ea10a9bdf6c752b8d1a0a6382b4b43a0fdf790f245e66a609fc","d67e8c1aaab1ce6ec1755599ecde153c47c6b90dd4c301663abe9057bc31af57","d67ec5caeb2af5f9c57533a34cbde7daba5f5b2e5e6ce34c3250893eef25f13c","d6abcc1484c3df45bde915abf48324af1e995c3266a3c6c069e98e94c8d9a4d7","d7a44c85c25ceb7d42280f0c2576de52a3b3cc3ad2333e788ecdc7f7f7fe4b3b","d84489933b19a8b073c65a0386e39e5067830facdc365ced6efe1948c7201771","d8c8b3c52c89cd715a7fdd2759a6f73c3a5f505303b110656cc35f7549a37cfb","d8ca8e025e226ad6bdd32a6a9fceae2982b0413a0ad09314558b54bdc724bf99","d8d03142030c11a0aa1012102fce2b202baf88e424a1236832937e87450dc579","d9823dfddf6c507ec030fce4bd2d98fbda18e595c2ebc563574d9196cc7a5e33","d9b0972f3406075b860ba7cd2e71d4492c826960319b10389c2c2820e2981254","da37a61fab07ec8856b725854e4064f55a59149aa69cad1bcbf89ec478b9f578","daa0fc9f9dd08cb2dc48bf33c9808cfeebff77cb9fba48f98ef597bb9dd6df55","dad01e5bfb13a6c4419f4d24fa8dbb424e93a1c4be656b0e5dd48ac546e0a0d9","db049e7abb7c75b608ae25cc8a9f95959f7aedaa53e22390290319cc2eed3977","db21a75b4fa6165f75268963474f3262124795d816ba80f685bab2c6eaedb028","db66a999537b941fa6d512908894ba86e8dadd0e14b290ebc119555b7e60264c","dc8c31e3075adeb63113852569b83dcd432485621eb77fef62cf3cce5c84a214","dd97ab52fd89f42352c595ce137684cc519c473fa17969e8a6adcde7322a4748","dda0a34d6704887eb36bbc0173334b49d755cac8cea3bbd17bfa972f04183dd4","ddbda9408727a19a4a55d516bed99331edf67d8301de9c78564716465c949619","de0f295bd0e46f29db1167d6c21bda624887c8543545d0c37d662e5b1b312341","de9a46da1f4605525b484a228f8bf356a9d900ecd16473faf77944b22575c141","e0288c94ca9c16a6de217e6baeed720fcf83e401bec45bd15ca47ba8fc9b44dd","e1667469384ec775a3df665679cb3fef057dc84dcb18ed8db8b9c5723835968a","e16c328504278cfe520d6d99990f2a4370cc48159aba86694d0f7598fd4b0611","e24df071f5325bb3a5b20f355143556bc7712535ee8b6ce4c426598f06fd2448","e28d8e6b71264d0bfab853e63178f2c151367cce0dbd16125596ff3604b6658d","e2c734504d211580b4e6674eb1c7d31fb6fb730c037210c34c980a96f9098269","e39ee882667ef28feb4971b73f9a01d3d72c557e1e56d59487af8e0f1b21edbd","e3f19c383354cdf45311f92f00b90fed25dfba7e9892ab2f5f3aa4885876b75f","e409fbfe439455330c0fe003de860e30f7093cc3cc83a32f886c9b539a29f60b","e519e78acf2938460c7ee053981c744dafc7642fd03b56a117d5fec78d258b90","e5db07b7fb0eed216d838fbeb9491257cf54f9bd537a68c8edae7a89fe64c8d8","e6300ee8e6c2c4ce6d7ab02b7b06fd1cabe3c5c52b99a6ea3ea8b5acd5092e0b","e65e28b172b77d093f5425112bdae7ab93756487226fd7363057f85bb2a2556d","e734d068446591aba283d136c21b4fb0209f91352cb4fc6589bd651cdbfec163","e7556cd0bdd06760602ef78c5e3b30b4dbe175f96b7147b56ee2ec181a4c5ea3","e7a333109a7aaec2b71048868500c15e721900628eb48790dfeaa1fd4c2dabc3","e7c9175fbfd9fd84bed95d552bc0a439b07a233c3e91fb39ae2f23197ee53f1b","e7ed299ecf44d4a96c228e9aa30312f405df34d6bea99d4b0f7074c79705a671","e8bc1b4f162c4066d74e5d1b3dcbe344742279b6856736c2e1690dbaa7bcf932","e981ced1bfce64a19fa8de1cd518a93f4669d01548f4819d0e1dbb50d266fe04","ea1b8a251ecc1fd96697d0c602d3e14ec46383d27bb9485a0326cea5576ffacb","ea311dca2ef14e02b9aae563bb28dc737b04b7f01c1ceb2be3d92007d2c74ac6","ea8e5b79bbe5329ae8437677c8316f2f9fd75bb1d40c88308c269140a7e564c7","eb708890ac7e19bd53007ccece064f7e2a069a3751270b4fdafdd1668136dee7","eb996138bc91c0ee63bafe1ba10b130ff5a2fc82aa4918296222e0a831a569fe","eba6e8e5a12a86f17fade41bef365aa95491c469e18aa91aef64908a4263c905","ebcf0bdb3541c8bfb7c9a53f632329b77341cba6f1a2fa0dc9704acfa3276dca","ebd87e3505f3a1adff0c86ffec6c380734df718301b216b7ee089c174130de60","ecd5e83ba8c8eba6cef9c3da1edb8a84e3dfb4ed71d9a2c1908f2c4d26b26737","edc160a11c07dda8072748b66db7f27b6cd8efbd1faa3f6c826a0fe445859c17","edfcbe4773eac1fe2964179a4ad21294efede89568f2efd8e283ac18bc5693b1","f0f90dee84db760cc1bb0f6e6983d4de0e3d5d9f4adf7b2b52f0d3dbe6d585a4","f1297fd9ecf981024e1544f7f048705377b53219240274bb803ac30e4a52084f","f1d4a6e98f41ab3f6cfd67cddeab9d0ed287b92cb3dbe575e3ce61925510a792","f21c3a9267110e469f224ac7eb76ca5bb084fc90df014f1ca6791d5770483944","f260b4b268e85a8f1b04b2fc69ffc0bca473d2e42de6f2f70128bedc16558201","f379a1b9e29aa7fc25c4c0c897eaa3c0e90d66a201a0ade8cbf523a5cdc8cf50","f3e04891c79b604f9235f438adfa49ee27db43d25c7be0d1cc06ae53b8f6d2d8","f46904e701174fe2850798d9e1b077bdac42fcac01dbc385298da01118c82aa6","f4de28905adbfe6ae4bc38f8bf5f47a444aa8d0f2023faaa431d6f72f9a3edea","f53265f53af0b0856911ab08b373736964d0c443e8ba61d7f1d45f5e5b04edf3","f5403593ba12130c04827f88d019103e924651caa518b7c290673a02f7cb409f","f5681dfc71121ed0f88146a19479675f2fabc6ed376fd5d162e50d815c048d66","f686173d310f41e26e3fe8a7c1dbf4313e4d793323335348badbcf4633f5d699","f6f5046c1263095a69e774716b0cd0907f6795af8ad683c5f41846d4c54a3449","f700bd87d4a758bb71f47731121a9b2259a9ffbd50b584b82f4e6a1f205c276a","f704c9c9e2cab1ed44578f48d161320b5fb4384ecdd8b40a5e22c4078a8594da","f7993302f695430a0ee938b1b3684fdfec4055bddb378b52c81785c0319e8c98","f89156489d35f9992d5971a52a6e03a7d7f095e15c2c782e85efb1408a2bd6be","f99ef6fa3c9c6bf572ec69eb6eeea9f88ce6590d3a5565bec62b001b6f2a376a","fa2dfc22b4fdbcf402a822e8dd376925655d997a0f96284a60f10665ba3581ba","fa3df5f8349aec4805bbcd279b88697def63f2462d8ada0b5fe1d9983d9a6daa","fa6b97cbca1d4f09662e706293b0aec1eb76b8e2277441f54ab6c548b5423236","faac0c3fa7cdf67b452d407e9a1db5cbe1e9140ecfe300200b0b0a6279c97c66","facb45d3084caa490d9b0ac2bcfcee89629a4c3db5926ec9256a9d27d25559ee","fbc8b53b5c6f3727c084e5e0429e410a3fed5a17e1a0144692fd196d9836a4bb","fbd74e4b8dc748b2efdd70aaab07adb80d7f15a38c1261de85bdfd9591ff106a","fc475f9c2d8bee2ffea435e86e6b39b6e3e071143a4a1fdf6765b0da13b66de6","fd04d7588bb9e6ca0a8b65ed0c9635082a9ee5f46b2d1b5b25866a072236c1fc","fd60f2a432086c6fc4a4c39d8d2d6edf5794c763c05a6401db2bb5fa2c601775","fd618761103380d690cb98804e8f116b6c66ef049fbf67c1a059ce49188658b3","fedf2577267d6dcd060ebc4ee8de6ccdafa60ab26b78d74c1e8c784252fecb17","ff532716738e2fc716c10797d9717f324cca3a1234320a84a73a0b89569f11ab","ffd0fe3449e449c7b9fcdcc7e2c1ffb677e57ad935a252de88a0122d437efa67","ffde5c700732beac27a9b5162213d387422ce199400e56d9cefe550005b6a542"],"schema":"fsgg.atlas/1"} +{"records":["000ada42299601fba29016e5c0e0d4012876fb42670bb10fa0b1315477254ba4","003893cc49855d17a15295d7adbe57ee301ea20281dff216461baee0810853ff","0052dfb9eafceabaa590f4497e4d42f19020718c84b981d265edefd432ccf8dd","00641d046d6869fdd0023ab3df99e0e67a6ea28f0dcb701f622b1cec8b3e07c6","0066d4a624c02398f21b4d7a736a9fb5101ed8b6b13ceeab46907e9401af98ff","026a241141ee10eb829aa6ce461969242d5c1d45fe9ca19f08ef4ea880877676","026b08fb343aefe19177e95b759560d340d372def4b71acf613fefee3438ade2","0357495d23fac4fad210b6dd7ed7cc57dd33d107e1659a81f085cad78300797f","036c148f6d0e89858c9bf4cf380272ca6904bb4ca277a909fb71c47f5450cef7","04652cbc95ac4dcd21b837b38f2ca5a0ccd4d0946bc13fdb31c9c15a578d3a2d","04d17203f03279980862496517a1f0861be5f6cc8063bfbf92f8f8ac19744fdd","04e404d89dca295564813149472b1de8e6c43357e2f6d91d169ded7600ed3a02","0509e5c6fdbd2dde0c0db8558647080560714804d00e4f9268342f2e84858a3d","06ad2c8aa0ff3b862edf3ba99e0e4e8801ee163709e66333cd06c3fc61232b05","076259a45e71df780b012d29618c17739246c86321d2ff05a6c272bcca8db675","076fa091c878b19cf56a94be0966dbcd58d52c1839f9d4b85bbfdef650cbdb88","08b3dc660b9d2bbbe75b590b2b86d941bf935a254cd5f09de71ee6894f4048b6","09e90ad705af012a8c36efbf296757f35adf9c9ce3b8908791c75d72c192973f","0a6d7dc5b64970bfdadc9049ace95e8bc163fc421beea70129ff0eaa692c6d06","0a862ee40916522f8ae5f14b3e084bf5f2e6488185583346db96ced16ce7619e","0a9df276d42b56d98a7802befc2404204e0e5ee8bc7f5c032f7bb29aa4ae2091","0ad4403c8f4078dbfa543310c69bd1dfc768e305987214ffc37d7b2600c4687c","0b2d1557ff6df5f4d65d540a5403b07ba81b381dfc799b7884ac72dfa6ee7753","0c22360d4653eb0f450e4d3d34564875f1660cfcb2d546095d98b3faa3967cbc","0c7d3f36e3bb4270edbf7abd99cd2dab772df274cad1c27c7e87e302b8eb1c23","0da4d093b49c0a1f654b38008bb01195e816829279ca1989bd2448194e15361b","0e560af7d9dd2e0f2f588a74cd35512973747f20bdfe0bee0bc889105ea53dc9","0ea7107c2c8edaab3ff2bae32f63cfbef6903a51cdaff257278f757ed5ef429d","0eef4d717eb03f0906aa3be7336aa71f831726afabe8a56077b76f6e82fd08e1","0f11324ad653d8d841962b0eeae9f68b80243d4ef7df4f2404ed4c3e45ba5197","11fe30832d93706c60efd836b09f35f049c4a715ad6144cf277ca240c5780704","1244d27db0cf5075353bcc622d0fb3b5ca6a7d08526e2c5754e8b745c250bf3f","126c817ad25ca9cbac2a0f7446e76c79852459ac7b9c61e3ba5d5cbfe5d37dfb","13824d6bce0f961c89eef4bd3c8a72ae6ecf7a1339b9e06eec964dc5c12dc544","13d0363b8d765c87a57eb42c4988320a9c2e7fa09024aa972f4b13d7699a552d","14156f1c6bf0fa8dfcb5cfafac09e012db446d528dad0e4301404fd693b9bed3","155fe673b8ae12549c978e1bf1d5c43e360937fcf2135cdcd5aea6f6c771da44","15d41240067e2335a0354a4e910b6610f2b8f079b8f67186f10181622b4a8999","1746f4f9d47b7dc42280dd34e664b3ec410d3cc69ac76933707499ffa34c79d4","1754adaf40732c3a8c73d2285c25a8b6c8c9d3e68370de618a0ffa8f3e60fb6d","1945f527afc3c2930ec4d7fa57ebb2ef7dd6321c0dd3ab9233c9963e9e613165","19d657b67672257ece127f3b957674b7fb4780843148db0a36a0b329c2a418ba","19e75be8ed4dfba2a6f8034154052160a7a181b17d887b3e8724f3e3c111c31e","1a24f6ef0c08a898f309c1b925fc19b29526f913a61a1dfe4b1a4308ebdd97ac","1b3ec24337f0252a00cfeb6df0a0f5d2b6d737dbea61b8d0b4a643f4c686df6a","1b5351b2dc647aba864e387168db5128435cb80da94fc42581cd60a05fc34b9a","1b8cad98d53da179ab05eb47c1783f4c8b45b9f39c635e7a337285f5cd9621c1","1cfd18d1b12b25604d818389a34bbaa746f450e70246c7f4242fc4e215fc46a4","1da011289116fe88fe92cb8f0e83ed7ccbbca251681d4e136c5a61c40364f8d3","1ec9445b242d2a2e149fe71c67bf13d8c0e4ebe5a6ed7b022656b9941973909d","1edc36731a9c76ad07d269d8b4fd84c8c956bb43d6f56de17d6208164856ffbe","1fec5a63a7b2b212e3e5d5222e49061f3b924966c9741294f5630836be8a3925","20901b579f69cc97eb56b492938864667576e1c9bfacf13f8a529c4f6e543448","20d01a387b4d0801cb588492ede88cae7bade9b7ea3591d9e954add1e67cf4ce","21338155cb4f52c49e5072c877771be67c75590d9b238ea025fba5209fd6e018","22ef13e60456fe9046dfe72f20122362aeefbbb445632231b8e364ed9b50e135","23af79bd1e7995fc8162ddc4d830318acb054bbfcc9c7d5cb141ec306da67386","24373b643450d9dd3b8a5b0e74a5fec2844cd8cbca7d8a57dbc8b9ad9eade9dc","24d4f2730d94d1b7f149771ef0e59192f4936d142b21f4a56b1a391e4514d38d","252de742c26409c837ef491f55eb03ffcc99da13fb1a2f8ab66efbfb0c081a2f","253bb17320020b6a5ef8f0958856f6c565a239b4dc246d9e825f8b14da9ca8de","2591526ddabbea03fbdc38bf172bc54f42df9bc51eba7ad2b70d6e67215f08f1","26259abc7fe745f52e06f2aa2abb0e50f189bc7608065f04d5c669a0a99941cd","26290a0990d6dac0ce9448e05eb934210603356043dcf14a5d80585288e2aa92","26d6b31965013079d4db67a2c403e01f21e3c30ae65953400dbed92e289a0925","288daf614247c260cb673d8674e8b3874ccc4e269347836851f702d7ac8e2f7c","28abfaf6d50ca38af0b88aa50524200c17af9000da83ddbab3d8f9e06e020fa5","2905a2b4a58bd9ec1c4f77fd3d1d246c02caa49d806272756dd039c79521442f","291d3db272eae084d34c04bc1305f2abb26a7e7acbc5515208469b46719a4ed1","2a38ddebfe3380232e35d5a24f9cb9f7c38abbc9c68add4ea5952c1e65d328d2","2b4f7c8dcc95ca8182105b9b6806391666e6a2c3a5c80d3ce5a5f04fd6cf9122","2b5e739c8f9602c585e67554c457e6e53351679afd56ff324f8fecc80f0891f1","2bc251ffb58a0d03480748058eff4c44079a0f21d75743063cef50263982337a","2c76ce93500601e281a41f5985fe4e3926fc8bc9d01ee687f14052cb553ad2d2","2d46924a94c85f4275a449dd3d9eb6c602cf8a9104db19d224e3aa469b858d06","2d5048eeef90792c0a2b9aed7305598a28db2103fed3903462c6c1882733c3e8","2d599c722a08306b98f2d833fb3e4a7acb9dea92e6a58820caa2f65c09803fb8","2df1610ac1b912232030b5507e5e944515b0f1549bf2b76ecfb12baf0f40ccea","2e1bc31ff6b6fb14d0ca8703a02833db749b03e172f2e91f9423f0751e88c256","2e872e9d3ab8b553270e79673060c50c1afd68a41fcf9fdd0a13cba80be0dfaf","2ecd502add2d801eebed39411fadc9a80098ba9ce04a5f4b728a0e4e331232d6","2f7357367d921995f4c6fdaa693392adcd2df4860ef4d25c8dc47f7ddea8c755","2fb2ed7902a8e35dc36489a23245d963026d688008c92fed6fdc1f6bc27198a6","2febddcced970d495778f33fff212929ac99c23adc42be0c1062f5c8676ffce0","3018f389f6928af5830bdd081c9d03530a379f37d1c2f9196e6fb3c44eb337d5","310bfb5b2d061bb733771e5cb7b3b7d25db43af5eda9f806169b7ef9330c2fe7","31fe4b51d55cd99a4692d2cb787d362cb4c0d0998d3e001efdb5cb7ed838340f","32f69a7b8997ae98b9305ee578145d795dbcd39ca4469bf2465e57a0295cda51","335683e33b94cb86b5e426b4faed200673bf850151191a08458136ceb164fd4e","3407ec53a884d3945d86a88d6b9a883419dd426e96b1108a8e6686f30397a629","3442ba5c7643c793f62d90ca841f7891b3dbf97f028bc7b62f8b4f88c1266d1c","34463778cf2d29e3896a65613cf9e3eb3e9f2d8946d17f12b609e70eec63d128","348ba129b7b9c94e24fa8ddb81024e777c60448d1b5d49f7b2075591b23c13b1","35da3938b72cf3520e126ad595157104b69ab748904c7b4e12f563d6b103172b","3600e7356a3741ef02f8b2ffa6a6b5d822dcbb170771f2ea33312dff4470f431","37c8908ea2a349cd3034018027160ad810b28ad1fc203a9a353971e1f7396b4c","37e39faee019bb041627510f1f02746ba9a85696417a083b438eb4974b72c2bf","38a75fd804821f4836f0a7ba8d41af3d3a3a5f5d7dcea68487009297824258d9","38c6396e645750efcb2f187c36c383471b3b0b59290e3b42cfcb9668594cd0c3","3962789d05f324d436a363700cbb5ced5aba791d782b3c0ea73221fe0c1f0b97","3966e5e53811c43962f5d0953e5da4753eacefbea27ecba9d36af2fd8e4fd52f","397476cf107b48e7a662264f8fea9f880231fd3d1e0401622650f214cfaa35c7","3ad8b0398ba6c354c9e31b7438b2515579fc0b1f17de4b35a914c862a3a11e3b","3b3c6cf083b12a840565e00458e2fd4ee8a61f97cda452703a6b13d7776b6c13","3b4af144afed3d52dd2e1f64e23bc25b3475eee5f7af3bde9886761b15c33dfd","3b5d82795e9f5d1992ab67e078fcf1108247ab9b6d1baeac944d3ec0294cec5d","3bce154e59c5c45216bb5372a352e948d6cb365bb1bd47d4666ae0412e507ca4","3c75b650f3fa8217597b01d3aaf25427ae2a658a7c966afeecdb391d3ba547ea","3d0274f77576abdbdf442c8843e955e1bbc91e9f8cbfe3646b119337cdb13c96","3d642ccf9ca4a0f7f5dde1b41f65c99e9c447cbb9e64883b67e4fdf76f216f52","3d9fd2c5877483382f0c7331206393e42827b5dccfd60549a6771b7a5659e524","3dbf6d1c2c8db1a7e3988e2a84b67a4e1d7c8304661652ffa94db3b7eee08edb","3dfcea4ee3d0d0ed09b1f77bac48b33b64ab4620cbfc74fe0e4201b4cdb81ce6","3dffc36586e9078f750b0a2b4cc2c70a17a81294903186dbe8cc47cf8055b9bd","3e2f66baa16c7ea936eba34720a55897438f60b343cbe8fda4eab1e5dde044eb","3f5465798dbc2ad279ca4849d5d0f819bad01455e0dd2a9d98afd4b55cfbd7ee","40de9f41f9a9f56ef6a51d065270e875b4a85cf043b7c4a0173b2510de4979ea","4134a3936170c1fb5fa6d2e2329185a981436477a66b7d31e827c363691bad50","414259a2fda4a1a49729be6fb1aced4675ee9cbdf990aaafb8e5b3153b54d64d","41baa5d98b5bab2ee01cad50c05b83edd8cdfeeb00f30b9406b4b2ec6d13d738","41c768ea17144c6ec225e9a65d4c3c127fdd7264dcba1a89aa17b20fd5d7e3ee","42aeb46fcc3d10b95e4067bc9cda875fa933b4102873f67c7bf1f8ca6799a598","4320b92712bc14dbe10b56f1cd3d1bdc093fc4be6016732839d0be4dd4d027d3","444342c21a4743af5961beeebb88088f5d2a0649f76c71973a7706a744f5efd2","4457ab439bc8f212d83442dc7500e9d45ffac849d0f77cb97686d9b0672fc3dc","461d34fb1d53849951a7e715e52342372d779299fbcad210794235c610dadf64","46a24cd8e385b748f40d9271b1e856dd6d68c91ab356abb11ff6b65f1ef936bf","46cdf2c207f79d388001f6636dfb7a98bb2ba72b9d1c6df4938f0a27691e07a6","471570cdf8144df0c32aba1730aba24c7e42e5ec317af771ffa169f5c842d117","47b5cb2b011c0f7012d75e88eb86a10f3f0bd48545db139669e654cac1f69650","480f1ede18ae031b164d49d676feeb1090fb33932676ff52e1e2eb24e8d154cd","48262b98c0bdbd5ee2314345726d23630ec1771735db8fe5f1a8590b662c9962","482cd15ecd9cfbd8e1943c0fcde0bbf1d875392dc2a701b698f48bfba684a062","4855e1947afc954cb1b20bb45e7af10b098fa34714bd32e9bc77941cf58fdaaa","48797c44c92cb34fd9a57a08020b45c6920b2268dc8ad616c0f814a3710d5316","48d094622ada1806cb30335926007c1abc476b1f7b45a2e250c490afa25e847b","48de3afdc6ee73ed121d1433bc6367a399286d5f8c2c63670a0b3b9752a36175","49e8cf09e38acefd3a0fa62d048028286d3b47b5ceccd8f51f10022978c47820","49ee4a3f2a8918bdbbafb312cfa807d9982800d13d29ee292c6c0daad8b9b8f1","4a724a6a842a132c2185279513f341b79f9be93e42660f1255770eeae3b1323c","4aecbdfafb68feb3124c39219498241864bcf1ceaf87fbf80598b1dd87a9191d","4b364ecb35ad02b06b6b0f32b6a29202f2c835e1ac0d70b89fd0278271799dbb","4b6ab2768e1ff3716ac8565201c031a820c208db9ea6ae1495dd782e7557a3ab","4be7778c4f491d55154a028d9a9dbb35059953fbcd243e0206902a6e64645efb","4c8c327dacf345e184042092e96ad3ea02ed4cece57dac5fa68ea52fbb5a6adf","4d5a44ba07fafeab823b54a21846269330ce35b4c190f3ddd5434bc8530d9b41","4d86a2764c55b5c5f675fddad8850ce4ceab160ac5c164a299fc098899d31aa9","4da0a5be70e8af9c39623deac83822749482187f6a0fc3d186dcfddaa7111576","4ece7844e2b35705ac39fa25913f6909aad5b4b7446bd637ced46b47c0db135c","4ef30f11bd4dd9d2eef8716d88a83010546e54594b2726de84f6d587651ee940","4f03e231c0dc5c9bb2874f6856382d5b205758af9678fffdc7552d4e4ae9866e","4f1e58fc658a4ceda181e2a7fa249305b09b573ffd68c2489f204f4957224957","4f2750b974c1404acb721ffc84cbd1d0756a24211dd6f6503c10ea74dbc45676","4f6fcf4dd7e73d86e06bdb9c14a1078b61c0efb2663ced9bfbc5f46fbb4c6d8e","5029c7b222158ab3f325168fa543d84fd2332d2e3e38db1ce7b83899cef201d1","509ec9c08864b9dd0029f32ffeac85fbac863e2dad459994c65b7cb5264faffa","50fd7e982eb2d2813634b7c44e102788a1a1cd4910a27acbcf219f76314fa322","52049cc9cee43bb27229e6b3e983e02c6aa20dd7d153b13e3c74bc6d2b47cf92","521ed246c4119acd6b579b6eefa23389a1655df54aa35de7671743979ebfc68d","5382c901d160ca2d79888d8acd7a690a5349826b5da486274b0800c9d7513f11","540879695d41205515aaabe5466971014cb43b960a26b8e5958e37fed63df762","548d237f42167af5cf5caa0ba20f0e7a6387deb6f27765637f078325172396a7","55267f058e9f085117765e4ca72ce875b622ceaceed964f6c396073214835c28","5560616d1e72f0a539f9ebbfea3b7d195c1ef5622f97994af1963748d4f97533","556ee783d8e2e4ca50f656c095758be613983f904d998a6534fb155510114f21","55a4711e799294d06988ab4acf77eacd7d424123082bba3ec987dff0ae13999c","55ae095961d78a1514c4dd1e63d477c60179a8662571ab5a90abd3eb2b83eb10","55dcc23ce52b3918a60029d9398f262216471c280bfe66421cc63240533a6087","566ddcfc45ea5edc695626826ed185930e910fd9107c5bc1844c717b714c15b2","56e7158313357bb145bd98c5f790e569be2203fb2601565a30091a597a7e7ff5","581337891936ba630d34ce9f6b803b82a2130791510f15bab24a07332400417f","58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608","5962dd14d3923433cf723d698d1af19ac37a270b6e88445643fc56a646faab5b","5a2064cdf51026eed65457c05f34bec919b31d96d35c29498d298685965f0b5a","5b77bd6dfa81cc339e729e4195e258facbfeb64b9c680512f742e3fb1961fdd5","5c0206d9d014821b52a43d7b222327a89d4ee2f5b1e21813dfa659a69f7426b5","5c3527e43fe24c5aa171c6fa4a3de7fe5e78f2527aed0dd19cb21d154d43da21","5c79c77f00167ca140127b00f1a79e1ffac621e46fc461089594206a7df8d7cc","5ca67643d5111fffd21deb18569162733e846965bf05fe6eb33ccd37c964025a","5d015880319af666943e68169ca906bf2f0c813d8bf2c5c0262aeb5a40366350","5e3a589b627edaf7005c60382475fae7229adc4ffbaab6d6fd03e9f08a0a8e19","5e43baca07fb966bf1c4b3ac06bb819577e477a84c5d8d3a9a19c391ada2e0b5","5f2a75b89983d1005a38afa2cabccc3a39f31989807120281d8505ffd564e0c6","5f43c837f39d207c35a58e9b36fe3144017b2012ac7da334714247606f1906d2","5f4fa6dde5930fe1b42f805895f0f5fb135c2b3ff9830f2bd30ae7526a3295a1","600ec184ee9964881bcaeaf72ad38a72db05d5b629d301cb323fa1ee9369b572","62a713311297a7145d3610ee60dd6626ee543645a1918b050c629207561efb5e","630fdcff1f227b5baf5d10bd78ef0fde68791ac0cd8a15f65065f5cc4501b17b","63113617f2e4ee6b827a69bce6afb3949190a282f5feaaa9e2c9f82372623bb8","6312b7a9f8252f49b8ea0cbd0580b80bbb221db574ea74939823ed9d4140d73f","63544fa69b09916d52b305700eb9816305ff22b77162a44edd13897acea3a655","6385459222fba2c3302d3f2e38c57fcfe0f1829679fead6cffa1964248767d5e","63a4394e689acf4a4762cfb4df691d05f923fdf592fd2f8ea41e6a54f98d1136","65725e1cd3323fdf44ec47067fd6670b441ff5f82e99485e1a4fc7d475f14340","65d5b7eff9d03761c8206218159bb34883c09052d6a1959d040f711a881b4d4f","6601b2bb6c908a46ae2985d4683c8baeeec87b0688b9b33d3e8900286bf4d6ae","666e7f698fbeef24e13e91ccfa334cf781233e060fa86bcd7d4d0eb00b30f3d5","66d414618d4283838bddb6b9fd4b5221c280a7f6a715b622143d3bea76bfe1f6","671168c05789fc651cd961a5a15e10adbb76656b802cb0fcbab468ab76412ca2","671d95a6c09bb7b05a5721d52cb761300a2c8f376aac20be2948b7e97bf302b7","680de944f1f5380c579003e329ed6f10702ec8ebaaa8208743775588d2424d05","6989ec486a05550633170d2aa79188ad9b03aeea6c7859dbf18790ba78c5427a","69ebfc7eb8427db3c5c59bdde652d0cb269426126f8540b1b58caa29ccf130e2","69edc4285578313d1dd2f914d69add075a7b354f7fba717606d1abe15292576b","6a34d9279cae58765d6ee4a980192c0e15f3ca217b9f1815861d472a281b3cf8","6b00dccaa7deabc750679ab085b237a2bd025bd971ee1eb7bdc333b393b19084","6c3c592efe9c684ada5661b8cc88a5c3f6e57c841db06b9e070687504cbf6236","6ce6d164c3e31463fb9e144fdf91413e55d077cfc4f25092bb02923fb538a84f","6e08a638e1e28020923effd4c65fc517dbe7b06100ff76cde74e427191503b84","6f3a7020233cd77cfe59eefec0a277f6dda323743c8d80e4e54a95cd3cbc23cf","6fccc6f0c5fa71c43211785dced8abd0f3295040eab56063f4e8d77f1c09b8ef","700cd21af9ed7e81900fad9d52de2fb11db48e64b038e4293168f85e5dd0e043","702d1dfa75e92a916a446429f474d4c296e6ea4e8c487995852d0525e8440659","704cf778db6086c3e282c81249fb0ef09c1d7c2043335ef74c7ecb69bb3e84ad","7075f89b1271fd04fa02d4db95c0f0bd6bdec24e53a7953d7afaeba40e17e8e0","71ef1ed2d5e4bc7eebe7a73bb3e9423e5bc2f8319186380fe8b38334952d3b01","7256ba00af1cf759b95b7bf8ae3b9943f31349bd10a7652a26bb419b368d73a3","7369b339daca0fcf46ac7fe82d65ae95c75d7dbcaaae51209e6d90b6587a014e","73ec844fb3e2b9febd00ba37508b284fad141630f03cb9f74e36a195180f5054","7410de003c7b582e30470d1209eefc796a70c76fe8d61dd9ccfe01ecfa41310c","741c27b54c49167abef1d8633e3743b0e98f82a73731e744b6671e119a1c6310","74b5d2ed555740db7b4b0ea9b73f8fe00965fea8e14d4f075eec26ef7a189c68","75aaecf53db10459d768a6873f6783e7d7110aa510c2894378df027c1b03584c","76bf5a9c126db6eb466287a7c0d823327ee9882a70eaaa6efb03d169b5dba808","781a64598efb2a11156f07271ba1c14c4f6b3d73aa2943b26eae02063df7af70","786b0c2856bf1f3f809e5903b0a971f1e072af5635aa50bbb9b1449f96d7b694","799abc1e8d381b8d97349479139985e383bb49179b5a80f39807cb35a3ee78ce","79faec494bdd6d098c9d2a9d8559f822938c6b2104188db95321d89e7a732979","79fb2e6e6a91117b6aefbdaabda23ccfa596620f548ee5075993a8dc7a8b872f","7a032dbf0351aa32c77c8d187f7eb697500ff186c88c5946ecc15adc972246a6","7a134e7f1822183ed1c0ded720971539350feaaf92612761210cfc3ccdc55870","7aa52373f2721dd76fc8eeb3d6061794f27ea8d11e96bcb1ff25a97994a77d5c","7ad4ef4b8d3221758a9e7f9577750ee03f6cba11c8eae8bf25f74a3131bd21a2","7af2394d2e697f355439e841b6323ffbbf8b90b2e48bf64873791fbbfdf15b44","7b947ed0a9e6e7ba180921434b993c62ac70bbaba6af0a1618569a2d4b705201","7baa35131ece7ed9860607157d2531d4d70a061bdc9bb9876e20328f127cec53","7c2a1c4c4c03e3d68d63e0ab58e4e34d3f2bc1a4a837a055fd13a4e9f95ce6cb","7cbf970a11bdb91a40e248eee97ef789205910ebc913349698fc75ed35e82fdf","7d6133667f81aa66a98755d253ea43301b45ada338225df034d2ffdfc79829e7","7dd54213b65fa0a6ce5aa3c204b5209b67ec16306b776aed7dcf9e6601d74235","7e89b59b456dde4bbbdbf8079665bd82c51d8e500018472981c15618b3893959","7ead0c68ffa0ced241af74dde58b3831343dff3f7eaab64bddb9954545b7ba12","7efb464c6d7b469303c43f718063d8456df6fe43534b5d8a4229f5b9ba9705cd","7f8188b57ad3b0c28210c95954e5623376a4262dd5e75f002700c6094b8d6b6c","7f91dfc2ea1a3131c4090375db0f489c2a572e245ade6cda4ebd440446d6d60e","7fcb8cba3ed0ee9c342947aa88f0f699bb4f5c23244d21c6c739c9b66d7c6101","800060d7b4934508d0277f90a464e3112fd2fc99af4ef23825d09b0ff53f91c3","800a802a4ce9e597a102f0a566535c1f9f7adfc60c41af6bd2db4fb7fe3c0d0e","820c12fcbded9048a363b9e0ebbc48b24f85fd4a68131b5dfc1b19057bf09ddb","824bff7541ec2a4b0be126f0b0791314d568a0eb4e29073de4f9dbe0ee4918b8","82c419e5de083e423330432c9d45c744043d1bccd8eeccb41e3014ce9ae3c32f","83347356a898238c013dff73246440e361a9e24cc3c4e0fe0e850467772b4938","8343a4211a4d0ffdb320d5a4305174d85bb707d15dad978f6436297d022daa11","83a06a604bbe36d72da976fcdeb88665c762b0f0de44193576ef2e0cf29aa9ad","83a97b9ebb29f5cd014ef5e178970a601ee92c44678f05d1860b383c5f63b79d","85a962a7c23c14dff8d683e738b53f422221697b213cafeb616d3a172a6c4223","85e961266b36e0f8ec2a477f1f1dfe7ad748fdde9d906f7bd3241e6924866ea9","8629fddeb4f273b35df69d4d28923adc14eff59d919b1a495d1a68818137c561","872ab2b2d65fe685b91e355f5af051c85b79569ece16448160d01fef38039624","87789dab547842b4e0c822758e1325a3cbb046063e11e105a4779b3741e01cde","87f2b3634baa504f2ed9508c6cf6a47bbfb36214a177eb13d70d6a987706818c","88b615ef6a31bd9958e98b8ea522f49f0360ccac5d9fa8deb9e3ef3fe3147d9d","89a96597dc9c218633adaf94bb5d6dcf4cad8f5e0b6f5522a28e3ce8d8b2865f","89cafbb20d6029656266d8cb0f85103fa519c8032598282fea58c94cc59c4125","89f2105745b3a7cfd30e7d7c598d6c8fdde0a599f30fd0db7382cba50412445e","8b3eec010d1eae43a28c88434f2410a751f790a9d6ec4a08e75e68c171629ab2","8cce78271b4f001606069a575a172041fbddc52de6b582c920aa3d3b5d5b67ae","8cecfa09651c40be4d7c11c117c80e1911dc75bf6f1cc34be64706823cc024c3","8d250acd40c8a24ba0d51cc73e65bba6856509b5fbf4c7d7a435897a01c6e764","8df1420c27503370db9382f68a0af8d2b4d56f9dbc94b24ffae450a905083a79","8e7371228a726f381fb811d1d812c39917788a3df7e53dba1a3c364e755a0c03","8f3827158091bbed154d21c843284ad472a4552da2eeb858748aa29676e45662","8f4a21c70e4b933eaa4f9cee119945dd2ebeac532e82d34e17511b38cf03608c","8f6debc54d2bd7abb42f581f2204fc78b27ff8c67ee4b6392b4d71c5f983ee9d","8fae27ba5117e202afbd523b249fc454912571900fc909f5419b8ac96c773c44","902b958b4db7d8d8bf73a82a8aa86e5485b39477047c8ad60175d118fe31d987","9056c360e59fc78edde932b54124df317f2f04a90c0c6eb7825a87b89edf1ca0","90aff66decaa3a0998e9a6741963713c0c82fc70da505519e3d60204bf715fa0","90dc4cac6326293bb54486d3c873b83299e9a5ec8c86a68bf1cc131f5e4e2437","918126027fabb7947dd4ae810dd561ac22167102f9f978f86906624ebe88c9ea","91b495938bc6015970bb02c844368d3eee84425b472772cdb374a5347db86de9","91c9ced5e9ab8da897b7f69166a7d0bade5c58d511b42d60d5430d536da45d09","922a332aa100d622da733aea8fc74094739bb63cd480d3349a14d2418ab6b1bb","941f70c384905ab77cb9a88e2671301117e4df553da6fc7a09210710deb9b6ca","9442788fa51227044803f1d3efdfc1c2b2da372871a85f0f7a6bb3596a5c003f","9460f427df72c238c4b55f39c8864f1fa3685b0716a53227ea6f7b591d955c82","947a1cdd43831936480167169d30334f818bb5d882650a3547827c05204af111","95f0c5f3b9071db39fd72b88ec9fb2079ce7553fd5884fa527bc9216777d7c10","96c4c83df72e9d860e2ee51f1a74bc867c4a45efc8bf11bf88aa82e368b89aa4","971f59cc197732d0c0b6b8aabbbefca4550fb8fb04f8522bdb4257c05a28848a","97edc66e594bae06bb273db84a35d84c8162a1fdf55ed46d781419a9f6a2e4f2","985638a05562bb796911ec231d306b81e36ed6b58219b3bde874559e9600b59f","98a097d6ebb754334250dfd3ccc5f3dfaf5966524758cbfc9e10adf4a0229693","98c7e4bc2f05e9b4ca703db4a02347db7355a44f04e3a4003e26c46a56bded2c","98ecc99d3396aa9a35ce97456be66c1aac0cc05bab88aa99109649291e61bc0a","9944d1a9674e555a41d31d069d136461eb06dd4052d40f2e4ea4368dd978e01b","9a8f2389b8ebc29d3769868ff8b918fdeb2236d88192fcf76ab0ea3db0857fac","9af18d8cfee466bc061271d82254d7ea638b59b8d5a3901c6610d5baed85c38b","9b01e565a1541f9e652d7afbe62e3bbff28430c1ccac2226ea434f45fc9a99d0","9b466e8fcabe551bb6292d23a359be3ea15b7627a6ad9c9e6a4ff11444c20860","9bac7daf255467f47b83723095f93fa4b574d5fc08593f48825a2b2ebb8e2dd8","9bbd03293bf53e9db51401d157b3eb2aa51e9c70449350e98b9a0a3fc9a684ce","9c3b318c461b56a8d277133a6b947ef5618690ec281c42e9de6c27f22458d4d4","9cef1feab6841836dc20527fcc8ad9979671fe811ff80a5a33bae113fcbebb97","9cf90b3aa59f3ca0e40fd9e1fec9703428752d63bded6b091d28f614c9ba99ae","9d1a0da545eb6b2e16b18fdd305a2c000ff2340c19ac843914b45f6a4f936227","9d8637e5adebaca208f21af0a254e80712988867411be560031f4b7a23cc04f6","9e77badd0923fd79ca9761a41780ee4dd4f9ca9b62512f4fb59c7f8418494da0","9eb67ea41c5bcb9557ba51bbbd1b321a78f16335cadebbed848d8e6c1fc68bab","9ed400941ed49b2d90ebe3cc111d90d8bc966608ca61fe9bc315a3c1dbe8bc1b","9fb8c5aa087d38dab064a2d6054826377eea3dda98229725c2523f63a87e4750","a0ff0d0bb3a3c801b637d091293f2eeaac68e934274e4116d298ba60ec3461cc","a1baa1f699fd4ce19e8ef6cdfe346e1b0be63e16d5c5cd5feddcccb16a62f269","a2aec2d2f35d7174801247141d637e77c4f34e478c575b0e0a04c6251efaf993","a3c84d76be9d891812e795dd46470c2978dceeff928d729c0d5dd6def599923b","a3d6708506fb5c28f45f0d610bedba11b1ec7bcdb363ffff3aa4cddfa515f56a","a476183540f2e7121e533bf2dd9125dc071c81acc880e88cb435cad7a6d35b97","a4a8cca930cdfd15285ac3a7aa757d61501fb77fc12a7c3fbd78c096b279cf63","a50654761d6812cd811df02199e1b7b25c9b0d65e591f65430f9277ec43d9c50","a514a8c0898b6697696ca6f0ed9a43bf8993085b2db4299e3e9f8e3419c4a5ee","a644885c31f390b5e6b7fe2fc8d086d9144699295ccb6ffa51b3f7c76c8ca71a","a64e8aee389ae696d0d4b045c0153092113fa522ed5a0fd9b5658b8418db4ded","a6c531ed9bbafabfdd649f3030daf2f24461163aaf99dc73bb24dddb77bbcb90","a7ff7302e668dcea1cd1db2241ff95c0d73534539bd03fdefebbfb57f60d3849","a8b4a33078335d2811bffb78eee49aab5fcb31597dae366d43e20c7f7800994b","a91a47fb4fa5c1b1a834fa602030e435ad641240e6ceeb99eeeab7341ca09dec","a91c8a1431a4120667cd523cf56bac004794fc5b8b24275ad2f9c8a15c75fba1","a986593807953215f834ba73e7d2565659b32aa849986013f8614bb1c61ea8cf","aa131e74e695292adab9f57b3ccc5a503a836dd4b95a3b2b107c69f35dba3637","aa4103342641899dc00c22207c13ac31c0c73afd97771b0a9b249187d979625d","aa70263d079788757f176da269e554fef9240845706f87a93101591f8114e807","acae1db4aeb323f3b637fa11b087c3827a2fb6d69718362f54e3bc48f70ef7d8","acd7884bca46ea9422503cead985691da05cca25bd5ed52a199783cae7b8b01f","ad0e6d78c1e450e19bfca4a0e904644ab0ae315607811a28ac3dba20de869786","ae43a4d252290ec0e18c64dd58d51bc885020b2473e71e3ed0741184c9f006b7","ae69fe306bf5db346ddfa4367cda24c95e44213baca27b0ee7d7167bcdd85af6","ae8c200dbcea29f43b29974cc247d70647c80d5d76385396f1c82ee9f669e2f1","aec13a075b84253397fb97e1c93a23e1aaee6d6bff2a9161bfd00a5b1d7611de","af12215a96963c1e7e5d766ed994695e423e4780ed0b3007aed87b150d090c05","af6b60ae365a6cbeb140430b030bdb667f53a2a97508ae92dfc9ed91ca73b54a","b09355a97e3aef396f681943b37a404a98fccc6bcb97781eddb2fc000d1d985d","b0ecfca0d114bae34ffa62ac3ea05159a4415fc6eb73ab1fcc4d79f657268f19","b25c41f19ba40e646fd9b6f82051ee4c38985539e445b26bd628eae98537df53","b262187aa66e8a97083bf7f79b91595bf7a4077abe7f8be5b00b4998f4579d20","b3f50ed7eac0e9c54b74c4f4e02297dd2d2465ce4b699bcc15cfddf54c0f0f81","b4091f93c3d96e36b0708f5dcd46e0e7a0a48f098036ccef6164e4a6429ed94c","b4093c67a9195ee7d28d2575e967ac80057b92339489c244243c7c504c669ff0","b44352445272089cf90967d4d413cf7009bed0ac19f3fa95cb831d5ebad081c3","b4ce73bea5219f1b27bffb36c6a9dee14447a710a8938db807770083db4552ac","b4f2140fb766faf0065a563ac3664f395b24c81dab0d0d0d01df47b22e888d29","b5102ef50e7d4ed1925af5a8b45192e737df02fafb75d7065995a2bb93d2e8e1","b5428b5775526a00645566822530fb969b82247ba83f2c80c06d34151e1f9061","b5c085be21651d8579e52cd3ffe4abe6b7f45c5a9ee84d38c47b4734409918d8","b6cf3b02f36e0efa93b04667cdc5701340033a09e41a7196277cf6756999a666","b77c6669bcd54e0fa949faf2f7205f2631acfbc1ccf79f93f8dab5c5717f0e93","b7fda8f4bf81f8213d18e3c314df5100ccb6b8db7aed6b70aaf202deb606a14f","b7ffd6cddb12384224772e8de79aec89d8f4bca966a3c2a05763889f92a6db5c","b83b7229045affbb98f8fc46f289ad05e6626ef52e3ed2f7e70d332a54a69e2a","b83f5334b85422ac110a24286d5af7003f2fb5b0d783efe257b38a2281656422","b8abe10a2a92bf537a49e8dee92baf8de3ed591848a1b25151dab0d7ab3134e5","b8b8c5cad182083f45ce2d05d036e6bfe91cde1fb63f2e5a97c683bb7ef7ea0f","b96cea09313d481dfff1ed1a2c552ea29e8fe68f52139458996a4e36157748d2","b96f9beb6d6d8fbf88c4b8b2b807a362f2640479cab6173cf64c7710817785a0","b9ad2510d8249ec4c8e7fd8b2471727aa1bd0ce8f3dde78e545fb2f8f2985a1d","ba5c707cf9be40fe966c08807779994e20ca3f30ea9d73e26ce31ca334c05640","ba7d7464da8e13722232c8f86273774054693681becc450a68aea21a5a0e9b91","ba87e5d43ddb10937bb17941f055f80a223d0981fbba44107aeec8530e3a7774","bac3431138e986d6426c1e81bdfe0a968394896c0751cbbcc8f36002fd0ed069","bad8f17b1d399ea125c524895571601c90b6c93418c248bd4ebcc7886bae9878","bb230236c4ab6353afb4147014c93204d3d1eb8a6d18558075df5fe79ed7f392","bb7fa81e41820d63d58313460f5a3999a1f9fc2cd2fb10cbb5b41a931d8be6a2","bcbef69f1ba50e45f3faf1b4529c32cdcf1e5a6612b5bcbc6aa6790ee14b54eb","bd3bf6053f4d423ff21f7ffbed9d0e68f3ea64b7292c048e9a37ade342bb7b39","bd714f38c881208f1190ad714bf8fa5aa63adf302bdaa8ad8810ff279e43459e","be75cc1ee935f783be39978de91ae196c16141d4096e16eb6d07f59583296b4b","be8c3cb2d8d67e63c8b069920b74c6272922febbc6a0a2c4a0072a7a213681d2","beed0f36d9b1b9a20bfbf89c96862482b8d5b9d4284bc89539efe9c9b11f000d","bfd21b5c8eb26e9d475868bb30d66ee08f20876e9df5cd06aa8fec01ffe666df","bfe97e65f2cbe6bcd0f14ff57ea4dc1dedb2e5f0db92d04d0982cf1932ac1c3e","c055d3cfd85b2ed4607b0d9d3a15ab7204c9f149599f748347dca4afe102af0c","c112d36ba38c362da1c022945db5b6bbdc3014685ca9bb7d940f5086f00a675c","c23a43ed460117f663cec698412729fd91b5aaceb48cc4e55a785b525661bf1a","c23cf45c1dcb748145d87f5c173dd3c8becaf9e3f6fdcb3e2ca91d6726b0842a","c24546a064b9315172ce0f951bd5fa2cd1b9884231cf1bdc1dc714771f1b3886","c29b8d250a7b5e73f4ef675329da2251b8de032501e4836445b6aafd90c645fa","c2e96d98c8ebc10237a2af1c224f626acfb9072c83078f4a8c6d9ef0a58b4a8e","c329c9df0dae8a036da9be440432d045be3ee13cf5664cfa6ccf11576ed11acb","c4600cd5358b5798a075beb54539d952f200def1c9a573bd237c795fd33ba36f","c4ebd58c4ff78c9fc0cd17d80ed563520f7908f9d1106735ca0f5a7abed202a6","c5db39bbdc8c2bd2aa7b58c28c3df9e407955cc3250ce7825c842cc4c30eaca3","c65325f807190f7084346376e2f48fc2b6bb946004a1fac1d8d117930e93d462","c6752cc3c7ad06d1e9f127365f078919ac46b77f8a8fe413650094d914838ec3","c6867ec30530fd3feca89a4e968522f783b636b165ef74f288c42dd50bd51a3d","c6bfbb004af355e96ed5b4c8c9b8b7a96d1c08d24bcde7c666728eb9497d6d71","c77c4d3f536cda10a71fe6a9cd17ea7c1408200e2f7aa7c5325d6915ff250c85","c82f38f23e7ed3e1024661b7a22ff694e88d3b268240e2bfc98e630df8a062d0","c8bd340e6fc7fa3e97415f7ad4c22c51d88c6e77f782c12923e841c04d3f882b","c93cd4cb5cf38fe6221fa8ae171ff54240b5f99ba80cd740ffac69c57e5fa381","ca50b525d7aa7762c56f402696dd464841daf19b036bb932e325090004b4cd71","cad13b6653fd9f811e67d13c5f01f9dec047f8c384097cee01dd2e2db39e539f","cc24c3770587f2421514fa399d2617201752bdca145ac39058de91d45d3d19c1","cd2da00f6f1bad8fb7c1b87cff80e122eb017e44a471cdea769efc67db369038","cdbb7338988f2fd35fd92f21909b7801d9954d1c7ca78401f52c9313f21fb6dc","ce887fb65b6977a2046e7583d704863624e55909ebcc9c3ed065b3d13079a410","cf9223c369b6fb7baa52f301f904352ba8e8d5e4c2a06f70de6ef1cf76fe1b84","cfb9705939742247da0cb71fdfd8b5f7a1bef6f1c2f0979a8f42e54c4a480980","cfc3b5044af37ae7485fba8067dcb22b2438bdaa6e3a30c22ce0f9e2c00aa597","d0481d9b6111ab4afba0462e88970b863284807ff44ca97364c84952e3f88583","d0973a1aca6a118375b466d6e91821f8450110fdf042ac848ee16912012d2b0f","d0df3068db679e24d9487ee09a6462ac5cf3df30f46ee466b66feb6dd5ff71e2","d151ffa66d8d096e0272f0dfff6c27e978cfda570f7498a727593081888b4ebe","d227e0a73e3c5452bc5ab41ea2c695dfc0ff9b0c1c81e59ab3173f796a4157cf","d268e680ee1136a239a40ebf005b30db6f3b52a228016f3193496f86250f15c3","d2989a1607fd5303615937b8c117d127b1b1cde519662ab1e1324390220e8612","d2cba4dbbfe3d026f825a8b470a2f6011f9b8e245cf042ae8889afbb17dac6b2","d2e4c515093f8a2aa824c8b542a016e5c321065f4525931b2fac4f8af2fe52c6","d31e8aa21d1498f2d4a07c4cc89ea6f5a6d3ce54d334dbff230e0f55db35c85e","d36034e2f9cc642d0f9f24cf834fa741bac5b8b139cbd2f50e2065161c9f3cb0","d36eb7456d2a42d1cffa4b60708e2bd3116f7f6758c96bbc0fee0f1704ad8a79","d37de74aadd5916eeae243decf347821c4e946356b9f70471658638ac3092f91","d3cf9b1433fd9a083c60baf6ade1df7f2a33e0cc7d519f491f9d6a93139a41e4","d49d02cad8bbfeac607457b08aac6068916ef45d8f6c980279d6e654407cc7be","d4f51c31a454d9abac29457cbbc21e1b5767c0eac1b37c41ee787a3efb05c80f","d52ca358246f638d0e11a061e97863697df44f43b093d6e8b84ba67b5838f2fb","d555a0d2329caace197c1468fe6708349125762377ee3bd04b031b7eacfc26aa","d581443d0b6b42c76b816edc6946ce01a639ae42653ddc8cc2d6a89ce14fe947","d5c084e12da4a5111487c166b879042a21a056f761ee22d9237cb4f65f366341","d6077d547aa21ea10a9bdf6c752b8d1a0a6382b4b43a0fdf790f245e66a609fc","d67e8c1aaab1ce6ec1755599ecde153c47c6b90dd4c301663abe9057bc31af57","d67ec5caeb2af5f9c57533a34cbde7daba5f5b2e5e6ce34c3250893eef25f13c","d6abcc1484c3df45bde915abf48324af1e995c3266a3c6c069e98e94c8d9a4d7","d7a44c85c25ceb7d42280f0c2576de52a3b3cc3ad2333e788ecdc7f7f7fe4b3b","d84489933b19a8b073c65a0386e39e5067830facdc365ced6efe1948c7201771","d8c8b3c52c89cd715a7fdd2759a6f73c3a5f505303b110656cc35f7549a37cfb","d8ca8e025e226ad6bdd32a6a9fceae2982b0413a0ad09314558b54bdc724bf99","d8d03142030c11a0aa1012102fce2b202baf88e424a1236832937e87450dc579","d9823dfddf6c507ec030fce4bd2d98fbda18e595c2ebc563574d9196cc7a5e33","d9b0972f3406075b860ba7cd2e71d4492c826960319b10389c2c2820e2981254","da37a61fab07ec8856b725854e4064f55a59149aa69cad1bcbf89ec478b9f578","daa0fc9f9dd08cb2dc48bf33c9808cfeebff77cb9fba48f98ef597bb9dd6df55","dad01e5bfb13a6c4419f4d24fa8dbb424e93a1c4be656b0e5dd48ac546e0a0d9","db049e7abb7c75b608ae25cc8a9f95959f7aedaa53e22390290319cc2eed3977","db21a75b4fa6165f75268963474f3262124795d816ba80f685bab2c6eaedb028","db66a999537b941fa6d512908894ba86e8dadd0e14b290ebc119555b7e60264c","dc8c31e3075adeb63113852569b83dcd432485621eb77fef62cf3cce5c84a214","dd97ab52fd89f42352c595ce137684cc519c473fa17969e8a6adcde7322a4748","dda0a34d6704887eb36bbc0173334b49d755cac8cea3bbd17bfa972f04183dd4","ddbda9408727a19a4a55d516bed99331edf67d8301de9c78564716465c949619","de0f295bd0e46f29db1167d6c21bda624887c8543545d0c37d662e5b1b312341","de9a46da1f4605525b484a228f8bf356a9d900ecd16473faf77944b22575c141","e0288c94ca9c16a6de217e6baeed720fcf83e401bec45bd15ca47ba8fc9b44dd","e1667469384ec775a3df665679cb3fef057dc84dcb18ed8db8b9c5723835968a","e16c328504278cfe520d6d99990f2a4370cc48159aba86694d0f7598fd4b0611","e24df071f5325bb3a5b20f355143556bc7712535ee8b6ce4c426598f06fd2448","e28d8e6b71264d0bfab853e63178f2c151367cce0dbd16125596ff3604b6658d","e2c734504d211580b4e6674eb1c7d31fb6fb730c037210c34c980a96f9098269","e39ee882667ef28feb4971b73f9a01d3d72c557e1e56d59487af8e0f1b21edbd","e3f19c383354cdf45311f92f00b90fed25dfba7e9892ab2f5f3aa4885876b75f","e409fbfe439455330c0fe003de860e30f7093cc3cc83a32f886c9b539a29f60b","e519e78acf2938460c7ee053981c744dafc7642fd03b56a117d5fec78d258b90","e5db07b7fb0eed216d838fbeb9491257cf54f9bd537a68c8edae7a89fe64c8d8","e6300ee8e6c2c4ce6d7ab02b7b06fd1cabe3c5c52b99a6ea3ea8b5acd5092e0b","e65e28b172b77d093f5425112bdae7ab93756487226fd7363057f85bb2a2556d","e734d068446591aba283d136c21b4fb0209f91352cb4fc6589bd651cdbfec163","e7556cd0bdd06760602ef78c5e3b30b4dbe175f96b7147b56ee2ec181a4c5ea3","e7a333109a7aaec2b71048868500c15e721900628eb48790dfeaa1fd4c2dabc3","e7c9175fbfd9fd84bed95d552bc0a439b07a233c3e91fb39ae2f23197ee53f1b","e7ed299ecf44d4a96c228e9aa30312f405df34d6bea99d4b0f7074c79705a671","e8bc1b4f162c4066d74e5d1b3dcbe344742279b6856736c2e1690dbaa7bcf932","e981ced1bfce64a19fa8de1cd518a93f4669d01548f4819d0e1dbb50d266fe04","ea1b8a251ecc1fd96697d0c602d3e14ec46383d27bb9485a0326cea5576ffacb","ea311dca2ef14e02b9aae563bb28dc737b04b7f01c1ceb2be3d92007d2c74ac6","ea8e5b79bbe5329ae8437677c8316f2f9fd75bb1d40c88308c269140a7e564c7","eb708890ac7e19bd53007ccece064f7e2a069a3751270b4fdafdd1668136dee7","eb996138bc91c0ee63bafe1ba10b130ff5a2fc82aa4918296222e0a831a569fe","eba6e8e5a12a86f17fade41bef365aa95491c469e18aa91aef64908a4263c905","ebcf0bdb3541c8bfb7c9a53f632329b77341cba6f1a2fa0dc9704acfa3276dca","ebd87e3505f3a1adff0c86ffec6c380734df718301b216b7ee089c174130de60","ecd5e83ba8c8eba6cef9c3da1edb8a84e3dfb4ed71d9a2c1908f2c4d26b26737","edc160a11c07dda8072748b66db7f27b6cd8efbd1faa3f6c826a0fe445859c17","edfcbe4773eac1fe2964179a4ad21294efede89568f2efd8e283ac18bc5693b1","f0f90dee84db760cc1bb0f6e6983d4de0e3d5d9f4adf7b2b52f0d3dbe6d585a4","f1297fd9ecf981024e1544f7f048705377b53219240274bb803ac30e4a52084f","f1d4a6e98f41ab3f6cfd67cddeab9d0ed287b92cb3dbe575e3ce61925510a792","f21c3a9267110e469f224ac7eb76ca5bb084fc90df014f1ca6791d5770483944","f260b4b268e85a8f1b04b2fc69ffc0bca473d2e42de6f2f70128bedc16558201","f379a1b9e29aa7fc25c4c0c897eaa3c0e90d66a201a0ade8cbf523a5cdc8cf50","f3e04891c79b604f9235f438adfa49ee27db43d25c7be0d1cc06ae53b8f6d2d8","f46904e701174fe2850798d9e1b077bdac42fcac01dbc385298da01118c82aa6","f4de28905adbfe6ae4bc38f8bf5f47a444aa8d0f2023faaa431d6f72f9a3edea","f53265f53af0b0856911ab08b373736964d0c443e8ba61d7f1d45f5e5b04edf3","f5403593ba12130c04827f88d019103e924651caa518b7c290673a02f7cb409f","f5681dfc71121ed0f88146a19479675f2fabc6ed376fd5d162e50d815c048d66","f686173d310f41e26e3fe8a7c1dbf4313e4d793323335348badbcf4633f5d699","f6f5046c1263095a69e774716b0cd0907f6795af8ad683c5f41846d4c54a3449","f700bd87d4a758bb71f47731121a9b2259a9ffbd50b584b82f4e6a1f205c276a","f704c9c9e2cab1ed44578f48d161320b5fb4384ecdd8b40a5e22c4078a8594da","f7993302f695430a0ee938b1b3684fdfec4055bddb378b52c81785c0319e8c98","f89156489d35f9992d5971a52a6e03a7d7f095e15c2c782e85efb1408a2bd6be","f99ef6fa3c9c6bf572ec69eb6eeea9f88ce6590d3a5565bec62b001b6f2a376a","fa2dfc22b4fdbcf402a822e8dd376925655d997a0f96284a60f10665ba3581ba","fa3df5f8349aec4805bbcd279b88697def63f2462d8ada0b5fe1d9983d9a6daa","fa6b97cbca1d4f09662e706293b0aec1eb76b8e2277441f54ab6c548b5423236","faac0c3fa7cdf67b452d407e9a1db5cbe1e9140ecfe300200b0b0a6279c97c66","facb45d3084caa490d9b0ac2bcfcee89629a4c3db5926ec9256a9d27d25559ee","fbc8b53b5c6f3727c084e5e0429e410a3fed5a17e1a0144692fd196d9836a4bb","fbd74e4b8dc748b2efdd70aaab07adb80d7f15a38c1261de85bdfd9591ff106a","fc475f9c2d8bee2ffea435e86e6b39b6e3e071143a4a1fdf6765b0da13b66de6","fd04d7588bb9e6ca0a8b65ed0c9635082a9ee5f46b2d1b5b25866a072236c1fc","fd60f2a432086c6fc4a4c39d8d2d6edf5794c763c05a6401db2bb5fa2c601775","fd618761103380d690cb98804e8f116b6c66ef049fbf67c1a059ce49188658b3","fedf2577267d6dcd060ebc4ee8de6ccdafa60ab26b78d74c1e8c784252fecb17","ff532716738e2fc716c10797d9717f324cca3a1234320a84a73a0b89569f11ab","ffd0fe3449e449c7b9fcdcc7e2c1ffb677e57ad935a252de88a0122d437efa67","ffde5c700732beac27a9b5162213d387422ce199400e56d9cefe550005b6a542"],"schema":"fsgg.atlas/1"} diff --git a/docs/atlas/records/58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608.json b/docs/atlas/records/58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608.json new file mode 100644 index 000000000..3ee7bb61f --- /dev/null +++ b/docs/atlas/records/58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608.json @@ -0,0 +1 @@ +{"citations":[{"path":"scripts/fdev-lane-capacity.py","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"3657c8432792a461dc26f97a0375c3a7f8ead038408ada4b3b1bc8e3cd650467"},{"path":"scripts/fdev-tmp-cleanup.py","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"6fcb5fe6d16fc56f042c152502d1024aae5b5e7f0214b54fa26147fe7f08a083"},{"path":"deployment/fdev-chromium/fdev-chromium-env","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"8cbc5e158b1619c23cd4666667e1d5c316de6229f71ccf5a888576050ab3b2a5"},{"path":"docs/coordination/fdev-host-hygiene.md","repository":"FS-GG/.github","revision":"d0571c221bc268be84271453f8c4d9f87406713f","sha256":"af791bd6cf7e83c3cc0ff28e5b725b3ea1248daf657c1c257e282379b8635e61"}],"conflictsWith":[],"id":"environment/fdev-host-hygiene","kind":"lesson","recordedAt":"2026-11-02T06:57:04Z","repository":"FS-GG/.github","schema":"fsgg.atlas/1","status":"recorded","summary":"Observed 2026-11-02 (FS-GG/.github#5240): /tmp on fdev is a 16 GB tmpfs shared by every lane; it filled (about 15k entries, 9.5 GB; fifteen browser-smoke mktemp trees of about 232 MB each and a 725 MB fsgg-gate-engine cache were the bulk) and caused 38 spurious SDD test failures while many browser smokes ran and the quiet-host probe did not admit for 60 minutes. Delivered on routine/5240-fdev-host-hygiene (cited files at the cited revision; merge and install are separate effects). (1) scripts/fdev-lane-capacity.py holds at 2 or more headless Chromium MAIN processes (argv[0] Chromium binary, --headless, --remote-debugging-pipe|port, no --type=; renderer/GPU/zygote/crashpad children and node/timeout launchers do not count; --browser-hold-at, 0 disables) and when /tmp has under 3 GiB free (--min-tmp-gib, --tmp-path), JSON browsers.count/pids and tmp_free_gib. LESSON: Chromium rewrites its process title, so on fdev /proc//cmdline is ONE space-joined string with a trailing NUL, for the main process and every --type= child; a NUL-split parser sees one word and never counts a browser, so the probe splits a single spaced field and takes argv[0] from readlink exe; checked live: one real Playwright chrome-headless-shell -> count 1, two -> hold. (2) deployment/fdev-chromium/fdev-chromium-env is now the repository source of the wrapper (it was only ~/.local/bin; environment/fdev-headless-chromium says it is not in Git, which this supersedes in fact but not by digest) and defaults TMPDIR to /home/developer/.cache/fsgg-tmp unless set, mkdir -p then chmod 0700 (shellcheck SC2174 forbids mkdir -p -m); capped at 32 bytes because a Unix socket path is at most 107 bytes and the SDD race test binds /sdd-race-characterization-<32 hex>/inputs/socket (TMPDIR plus 73); mixed TMPDIR values may fragment MSBuild node reuse; --print-tmpdir serves .NET runs. (3) scripts/fdev-tmp-cleanup.py is dry-run unless --apply and removes only known names (fsgg-sdd-tests--* idle 1 h; fsgg-sdd-, fsgg-ai-tests/ai-tr/resolver/cli-tests-cache-sandbox-, playwright_chromiumdev_profile-*, org.chromium.Chromium.*, and tmp.* only with driver/run-smoke.mjs, idle 6 h because they carry no PID) whose owner is dead (PID absent, and no live process references the path via cmdline, environ, cwd, fd, maps or /proc/net/unix, relative words resolved against the process cwd and symlink aliases by realpath). It refuses to delete while a same-user process cannot be inspected (non-dumpable processes have a root-owned /proc dir; allowlist systemd --user, (sd-pam), sshd), uses an iterative O_NOFOLLOW directory-fd removal that never follows a symlink or crosses a mount, and refuses euid 0. playwright-artifacts-* and fsgg-gate-* are deliberately not swept. Hourly user timer templates (minute 37) and install.py tmp-cleanup and chromium-env effects ship in source; Root installs after merge. Limits: a dry run on the real host listed 874 of 1077 matched entries (3.3 GiB) removable and removed nothing; the probe samples, it does not reserve; lanes still need TMPDIR set to the disk path for the pressure to drop at the source.","supersedes":[],"tags":["fdev","tmp","tmpfs","cleanup","capacity","browser","chromium","tmpdir","unix-socket","environment","testing"],"title":"fdev host hygiene: /tmp is a shared 16 GB tmpfs, so hold on browser count and /tmp headroom, use a short disk TMPDIR, and sweep only dead harness dirs"} diff --git a/docs/coordination/2026-11-01-fdev-headless-chromium.md b/docs/coordination/2026-11-01-fdev-headless-chromium.md index c63583bff..450eb2869 100644 --- a/docs/coordination/2026-11-01-fdev-headless-chromium.md +++ b/docs/coordination/2026-11-01-fdev-headless-chromium.md @@ -18,7 +18,8 @@ fdev-chromium-env --gpu --check # ldd both Playwright binaries, show fdev-chromium-env --gpu --print-args-json # the launch flags for the mode ``` -`~/.local/bin/fdev-chromium-env` prepends the bundle's `usr/lib` to `LD_LIBRARY_PATH` and sets `FONTCONFIG_FILE`. +`~/.local/bin/fdev-chromium-env` (source: `deployment/fdev-chromium/fdev-chromium-env`, installed by `install.py chromium-env`; see +[fdev host hygiene](fdev-host-hygiene.md)) also defaults `TMPDIR` to the short disk path `~/.cache/fsgg-tmp` when unset. It prepends the bundle's `usr/lib` to `LD_LIBRARY_PATH` and sets `FONTCONFIG_FILE`. Neither Chromium nor Playwright reads launch flags from an environment variable, so the wrapper exports them as `FDEV_CHROMIUM_ARGS` (space separated) and `FDEV_CHROMIUM_ARGS_JSON` for your launcher to pass as `args`: diff --git a/docs/coordination/board-tend-fdev-units.md b/docs/coordination/board-tend-fdev-units.md index c47d16f43..d9b9edf85 100644 --- a/docs/coordination/board-tend-fdev-units.md +++ b/docs/coordination/board-tend-fdev-units.md @@ -188,6 +188,12 @@ Outcome and no Blocked card may appear. Day 0 shows 0 would-close, because the d merges, so the week may legitimately end with few or no items. If fewer than 3 distinct would-close items have been compared by day 7, Root either extends the observation or waives the count; this note does not assume which. +## Related user units + +`fsgg-tmp-cleanup.{service,timer}` (hourly dead-run `/tmp` cleanup, #5240) are templated here and installed by their own +`install.py tmp-cleanup` effect; they share nothing with board tend at runtime. See +[fdev host hygiene](fdev-host-hygiene.md). + ## Known limits - The token is the credentials file's `GH_TOKEN`. Whether it carries every scope an eventual `--apply` needs is checked diff --git a/docs/coordination/fdev-host-hygiene.md b/docs/coordination/fdev-host-hygiene.md new file mode 100644 index 000000000..8ca9544d7 --- /dev/null +++ b/docs/coordination/fdev-host-hygiene.md @@ -0,0 +1,183 @@ +# fdev host hygiene: browser-run holds, /tmp headroom, disk-backed test temp and dead-run cleanup + +Delivery: [#5240](https://github.com/FS-GG/.github/issues/5240), under [#4730](https://github.com/FS-GG/.github/issues/4730); +extends the capacity probe of [#5172](https://github.com/FS-GG/.github/issues/5172). + +On 2026-11-02 the quiet-host bench probe never admitted for 60 minutes (load 5 to 9), `/tmp` (a 16 GB tmpfs shared by +every lane) filled and caused 38 spurious SDD test failures, and many browser smokes ran at once. Four pieces, each +source-managed here and installed by Root after merge. + +## 1. Two holds in the capacity probe + +`scripts/fdev-lane-capacity.py` (read-only, one JSON line, exit 0 `admit` or 3 `hold`) now also holds when: + +| Hold | Default | Flag | JSON | +|---|---|---|---| +| At least N headless Chromium **main** processes are running | 2 (`0` disables) | `--browser-hold-at N` | `browsers.count`, `browsers.pids`, `thresholds.browser_hold_at` | +| Free space on `/tmp` is below N GiB | 3 | `--min-tmp-gib N`, `--tmp-path DIR` | `tmp_free_gib`, `tmp_path`, `thresholds.tmp_free_gib_min` | + +A browser run is one process whose `argv[0]` is a Chromium binary (`chrome`, `chromium`, `chromium-browser`, +`google-chrome*`, `chrome-headless-shell`, `headless_shell`), that carries `--headless` (or `--headless=...`) and +`--remote-debugging-pipe` or `--remote-debugging-port`, and has no `--type=`. The renderer, GPU, zygote, utility and +crashpad children of one browser therefore count once, and a `node ... chrome ...` or `timeout 600 node ...` launcher +is not a browser. Chromium rewrites its process title, so on fdev `/proc//cmdline` is **one space-joined string** with a trailing NUL +(for the main process and every `--type=` child). The probe splits a single field that contains spaces on spaces and, for +that rewritten case, takes `argv[0]`'s basename from `readlink /proc//exe` when readable. Fixtures +(`tests/fdev-lane-capacity/fixtures/chromium-*.cmdline`) are captured from a real Playwright `chrome-headless-shell` 1243; +with one such browser running the probe reported `browsers.count 1`, and with two it held (`browser runs 2 >= 2`). +`/tmp` space is reported apart from `disk_free_gb` (which is `$HOME`). An unreadable `/tmp` or +process table is an `unknown:` hold, like every other probe input. Tests: `tests/fdev-lane-capacity/` +(`--proc-root` fixtures, so the host's real processes and `/tmp` never decide a test). + +## 2. A short, disk-backed TMPDIR + +`/tmp` is RAM. The wrapper `fdev-chromium-env` now runs its command with `TMPDIR=$HOME/.cache/fsgg-tmp` (mode 0700, +created on demand) **unless `TMPDIR` is already set and non-empty**, which is never changed (`TMPDIR=/tmp` opts out). +`FDEV_TMPDIR=` overrides the default path. + +The path is deliberately short. A Unix socket path (`sun_path`) holds at most 107 bytes. The SDD race test +(`GenerationSourceRaceCharacterizationTests.fs`) binds `$TMPDIR/sdd-race-characterization-<32 hex>/inputs/socket`, which is +`TMPDIR` plus 73 bytes, so a `TMPDIR` over 34 bytes fails it; a lane's `/home/developer/.fsgg-scratch/788b/tmp5` (39 bytes) +already does. The wrapper refuses a default longer than 32 bytes (`FDEV_TMPDIR_MAX`), warns, and leaves `TMPDIR` unset; +`/home/developer/.cache/fsgg-tmp` is 31 bytes, and a test models that exact socket path against the budget. + +**.NET test runs** do not need the browser libraries on `LD_LIBRARY_PATH`, so take only the directory: + +```bash +export TMPDIR="$(fdev-chromium-env --print-tmpdir)" # prints and creates ~/.cache/fsgg-tmp; exit 1 if it cannot +dotnet test ... +``` + +or run the whole command through the wrapper (`fdev-chromium-env -- dotnet test ...`), which also puts the Chromium +bundle on `LD_LIBRARY_PATH` for that command. Set it for the whole shell that launches `dotnet test`: `dotnet`, +MSBuild and the test host all read `TMPDIR`. Caveat: MSBuild reuses build nodes (`/nodeReuse`) only between processes +that share a `TMPDIR`, so a mix of lanes with different `TMPDIR` values may start separate node pools instead of +sharing one; move lanes to the disk path together where node reuse matters. + +The wrapper had no repository source before this Delivery (it was only `~/.local/bin/fdev-chromium-env`, from #5193). +Its source of truth is now `deployment/fdev-chromium/fdev-chromium-env`; edit that and reinstall. Tests: +`tests/fdev-chromium-env/`. The directory is created with `mkdir -p` and then `chmod 0700`, which also tightens an +existing looser directory of yours (the required shellcheck run forbids `mkdir -p -m`, SC2174). + +## 3. Dead-run cleanup + +`scripts/fdev-tmp-cleanup.py` removes known harness directories from `/tmp`, `$TMPDIR` and `~/.cache/fsgg-tmp`. +**It is a dry run unless `--apply` is given.** + +```bash +python3 -I scripts/fdev-tmp-cleanup.py # dry run: one JSON line, nothing changes +python3 -I scripts/fdev-tmp-cleanup.py --apply # remove +python3 -I scripts/fdev-tmp-cleanup.py --root DIR # sweep only DIR (repeatable; must exist) +python3 -I scripts/fdev-tmp-cleanup.py --min-age-hours 2 +``` + +Known names (an exact shape directly under a root; anything else is never touched, including a bare `tmp.*`): + +| Pattern | Owner test | Idle period | +|---|---|---| +| `fsgg-sdd-tests--<32 hex>` | the PID in the name is dead, and no live process references it | 1 h (`--min-age-hours`) | +| `fsgg-sdd-<32 hex>`, `fsgg-ai-tests-<32 hex>`, `fsgg-ai-tr-<32 hex>`, `fsgg-resolver-<32 hex>`, `fsgg-cli-tests-cache-sandbox-<32 hex>` | no live process references it | **6 h** (`--min-age-hours-pidless`) | +| `playwright_chromiumdev_profile-<6>`, `org.chromium.Chromium.<6>` | no live process references it | **6 h** | +| `tmp.<10>` containing `driver/run-smoke.mjs` (a browser-smoke mktemp tree) | no live process references it | **6 h** | + +A PID-less entry has no PID to prove its run is dead, so it needs a longer quiet period. Root decided on 6 hours +explicitly, against holders that keep a directory only in memory (a process that never opens, maps or names it again). +Not swept on purpose: `playwright-artifacts-*` (empty on the real host, and a live run's artifacts directory is not +referenced by any process) and `fsgg-gate-*` (the gate-engine build cache is reused; there is no per-run pattern). A +directory is removed only when **all** hold: + +1. **The owner is dead.** With a PID in the name, `/proc/` must not exist. In every case no live process may + reference the entry: its path, or a path that resolves to it (a relative word resolved against that process's cwd, a + symlinked alias resolved by `realpath`), as a command-line word or flag value, an environment value, the cwd, an + open file descriptor, a mapped file, or a bound unix socket (`/proc/net/unix`). This is what + `--user-data-dir=/tmp/playwright_chromiumdev_profile-X` and `node /tmp/tmp.X/driver/run-smoke.mjs` give. A PID reused by + an unrelated process keeps the entry. +2. **Idle.** The newest mtime of the entry and everything below it is older than the idle period. A tree with more than + 400000 nodes, or one that crosses a mount point, is kept. +3. **A real directory owned by this user.** A symlink entry is never followed and never removed. +4. **No same-user process is unknown to the scan.** A process of this user whose cwd, fds or environ cannot be read (a + non-dumpable one, whose `/proc/` directory belongs to root, so its owner is read from its `status` file) could hold an + entry invisibly. While one exists, `--apply` refuses to delete anything (exit 3; the pids and names are in + `unreadable`, and a dry run reports `apply_blocked: true`). Exempt by name: `systemd --user`, `(sd-pam)` and sshd. A + transient `sudo` started by the same user is enough to block one run; the next timer run retries. + +Removal is iterative (no recursion; a 1,100-level tree is tested) and walks with directory file descriptors and +`O_NOFOLLOW`, raising the open-file limit to the hard limit first because it holds one descriptor per level. It unlinks a +symlink inside a tree as a link, does not cross filesystems, and chmods read-only directories it owns so `.git` trees go. +The process table is read again before the first deletion and each entry's inode and mtime must be unchanged since the +survey. If the process table cannot be read it exits 3 and removes nothing; euid 0 is refused (exit 2). Killing a process +is never part of it. + +Output keys: `mode`, `roots`, `entries_matched`, `would_remove`, `would_free_bytes`, `removed`, `freed_bytes`, `failed`, +`unreadable`, `apply_blocked`, `by_pattern`, `kept` (by reason: `young`, `pid-alive`, `referenced-by-live-process`, +`symlink`, `not-a-directory`, `not-owned`, `changed-since-survey`, `mount-point`, `tree-too-large`), `removable` (first +`--list-limit` entries). Tests: `tests/fdev-tmp-cleanup/` (fixture tree and fake procfs; live PIDs, live references by each +route, young trees, symlinks, uninspectable same-user processes and unknown names are kept). + +### Dry run on the real host, 2026-11-02 (current code) + +`python3 -I scripts/fdev-tmp-cleanup.py --list-limit 3` against the real `/tmp` while other lanes were running (exit 0, +default dry run, nothing changed, `removed: 0`): + +``` +mode dry-run roots [/tmp] processes_read 376 unreadable [] apply_blocked false +entries_matched 1077 would_remove 874 would_free_bytes 3569328128 (3.3 GiB) kept {young: 203} +by_pattern (removable/matched) browser-smoke 14/14 chromium-temp 444/492 fsgg-sdd-run 124/237 + fsgg-test-root 219/261 playwright-profile 73/73 +``` + +The kept entries are younger than their idle period (1 h or 6 h), which includes the browser smokes running at that moment. + +## 4. The timer + +The unit templates live beside the board-tend units in `deployment/fdev-board-tend/` and are installed by the same +`install.py`, as their own effect (`tmp-cleanup`), so the existing `units` effect, its tests and its rollback are +unchanged: + +| Unit | When | What | +|---|---|---| +| `fsgg-tmp-cleanup.timer` | hourly at minute 37, `Persistent=true`, up to 120 s random delay | starts the service | +| `fsgg-tmp-cleanup.service` | the timer | `python3 -I ~/.local/libexec/fdev-tmp-cleanup.py --apply`; `Type=oneshot`, `Nice=15`, `IOSchedulingClass=idle`, 600 s cap, no `PrivateTmp` (it must see the lanes' real `/tmp`) | + +Minute 37 is away from board tend's :07, the drift observer's :23, the :53 dispatch and the 00:30 daily record. + +## Install (Root, after merge; nothing here changes the host by itself) + +Each command has `--dry-run`, refuses to run as root and refuses a destination outside `$HOME`. From a clone of +FS-GG/.github at the merged commit: + +```bash +# 1. The wrapper (replaces ~/.local/bin/fdev-chromium-env; --force because the installed copy differs) +cp -p ~/.local/bin/fdev-chromium-env ~/.local/bin/fdev-chromium-env.pre-5240 # BACKUP FIRST: the old copy has no other source +python3 -I deployment/fdev-board-tend/install.py chromium-env --dry-run +python3 -I deployment/fdev-board-tend/install.py chromium-env --force + +# 2. The cleanup script, service and timer; --enable runs daemon-reload and enable --now for the timer +python3 -I deployment/fdev-board-tend/install.py tmp-cleanup --dry-run +python3 -I deployment/fdev-board-tend/install.py tmp-cleanup --enable + +# 3. Before enabling the timer, look at what it would remove right now +python3 -I scripts/fdev-tmp-cleanup.py +``` + +The probe needs no install: Root runs `scripts/fdev-lane-capacity.py` from the checkout. + +Verify: `systemctl --user list-timers fsgg-tmp-cleanup.timer`, then after the first run +`journalctl --user -u fsgg-tmp-cleanup.service -n 5` shows the JSON line; `fdev-chromium-env --print-tmpdir` prints +`~/.cache/fsgg-tmp`. + +Rollback: `systemctl --user disable --now fsgg-tmp-cleanup.timer`, delete `~/.config/systemd/user/fsgg-tmp-cleanup.{service,timer}` +and `~/.local/libexec/fdev-tmp-cleanup.py`, then `systemctl --user daemon-reload`. For the wrapper, copy the backup taken in +step 1 back: `install -m 0755 ~/.local/bin/fdev-chromium-env.pre-5240 ~/.local/bin/fdev-chromium-env`. The previous wrapper +exists nowhere else (before this Delivery it was only the installed copy), so keep that backup until the new one has run. + +## Known limits + +- Lanes are expected to run with `TMPDIR` set to the disk path (section 2). Directories that lanes still create in `/tmp` + are cleaned by the timer once idle. A PID-less entry held only in memory by a process the scan can inspect (it never + opens, maps or names the path again) is protected only by the 6-hour idle rule. +- The cleanup does not touch `playwright-artifacts-*`, `fsgg-gate-*`, `tmp.*` trees without the smoke fingerprint, `claude-*` + scratch, MSBuild or `.NET` runtime files (`clr-debug-pipe-*`, `dotnet-diagnostic-*`), or anything outside the table. New + harness patterns are added to the table and to `PATTERNS` with a fixture. +- The probe samples; it does not reserve. A lane admitted at one browser can still start the second before the next + probe, so the browser hold narrows the pile-up rather than serialising it. diff --git a/registry/driver-skill-manifest.json b/registry/driver-skill-manifest.json index 15b091ac5..02cc0187a 100644 --- a/registry/driver-skill-manifest.json +++ b/registry/driver-skill-manifest.json @@ -5,7 +5,7 @@ "id": "atlas", "scope": "driver", "sha256": "a1383a9a8029f91930798e7624f5de87db68b0b6f575ea4d899761449e9fa423", - "tree-sha256": "e3866bc8ac8615d108b925309707b1276c17ca1c8d817a29627f2801bbd36147", + "tree-sha256": "39b0dff12c7b6bececfd290449c356e675d8edd9eb1f40802337f36f9a1e7fff", "files": [ { "path": "SKILL.md", @@ -24,7 +24,7 @@ }, { "path": "assets/seed/catalog.json", - "sha256": "f5b1371ffc526b993e573d3ccd7a5a09f3e2dc2f8b193902d99a7392d5c5936c", + "sha256": "397200b55f62f299951c205dfbf47c5a0cc3c28b0fd504cc827c7eff95699109", "executable": false }, { @@ -882,6 +882,11 @@ "sha256": "581337891936ba630d34ce9f6b803b82a2130791510f15bab24a07332400417f", "executable": false }, + { + "path": "assets/seed/records/58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608.json", + "sha256": "58901d008c36a777dc138fa6b6d198030e0e843bc889cbad3acb954c826b3608", + "executable": false + }, { "path": "assets/seed/records/5962dd14d3923433cf723d698d1af19ac37a270b6e88445643fc56a646faab5b.json", "sha256": "5962dd14d3923433cf723d698d1af19ac37a270b6e88445643fc56a646faab5b", diff --git a/scripts/fdev-lane-capacity.py b/scripts/fdev-lane-capacity.py index 3f14f2dbe..56086cf86 100755 --- a/scripts/fdev-lane-capacity.py +++ b/scripts/fdev-lane-capacity.py @@ -14,6 +14,21 @@ - cgroup v2 memory headroom (memory.max - memory.current) >= min-mem-gib GiB, when a limit is set - free disk at --disk-path (default $HOME) >= min-disk-gb GB (default 20, decimal GB) - active heavy processes <= max-heavy, only when --max-heavy is given (default: reported, not graded) + - fewer than browser-hold-at active headless Chromium browsers (default 2; 0 disables) (#5240) + - free space at --tmp-path (default /tmp, a tmpfs on fdev) >= min-tmp-gib GiB (default 3) (#5240) + +BROWSER RUNS (#5240). Many concurrent browser smokes loaded the host and filled /tmp. A run is one headless +Chromium MAIN process: argv[0] is a Chromium family binary (`chrome`, `chromium`, `chromium-browser`, +`google-chrome*`, `chrome-headless-shell`, `headless_shell`), it carries `--headless` or `--headless=...`, it +carries `--remote-debugging-pipe` or `--remote-debugging-port`, and it has NO `--type=` flag. The renderer, GPU, +zygote, utility and crashpad children of one browser therefore count once (they carry `--type=`, or are +`chrome_crashpad_handler`), and a launcher such as `node ... chrome ...` or `timeout 600 node ...` is not a +browser (only argv[0] is classified). The JSON reports `browsers.count` and the main pids. A browser launched +without --headless or without remote debugging is not counted. + +/tmp SPACE (#5240). `/tmp` on fdev is a 16 GB tmpfs shared by every lane; at 100% the SDD tests fail with +spurious errors. Free space at --tmp-path is reported as `tmp_free_gib` separately from `disk_free_gb` +(which is $HOME). An unreadable --tmp-path is an `unknown:` hold. LANE LIMITS. fdev runs lanes in cgroups, so host-wide numbers can overstate what a lane may use. The probe reads its own cgroup from /self/cgroup (`0::/path`) and walks from that cgroup up to the root @@ -141,19 +156,61 @@ def read_cgroup_limits(args): return cpus, headroom -def count_heavy(proc_root, own_pid): - kinds = {} +BROWSER_EXES = {"chrome", "chromium", "chromium-browser", "chrome-headless-shell", "headless_shell"} + + +def is_browser_main(argv): + """True for a headless, CDP-driven Chromium main process; its renderer/GPU/zygote children are not.""" + if not argv: + return False + exe = os.path.basename(argv[0]) + if exe not in BROWSER_EXES and not exe.startswith("google-chrome"): + return False + rest = argv[1:] + if any(a == "--type" or a.startswith("--type=") for a in rest): + return False + headless = any(a == "--headless" or a.startswith("--headless=") for a in rest) + debugging = any(a == "--remote-debugging-pipe" or a.startswith("--remote-debugging-pipe=") + or a == "--remote-debugging-port" or a.startswith("--remote-debugging-port=") for a in rest) + return headless and debugging + + +def read_argv(proc_dir): + """argv of one process, tolerating a rewritten process title. + + Chromium rewrites its process title, so /proc//cmdline is ONE space-joined string with a trailing NUL + (observed on fdev with Chromium 153) instead of NUL-separated words. A single field that contains spaces + is therefore split on spaces. In that case /exe, when readable, supplies argv[0]'s basename, because a path with + a space in it cannot be recovered from the joined string. + """ + fields = [a for a in read_text(os.path.join(proc_dir, "cmdline")).split("\0") if a] + if len(fields) == 1 and " " in fields[0]: + fields = [a for a in fields[0].split(" ") if a] + try: + exe = os.readlink(os.path.join(proc_dir, "exe")) + except OSError: + exe = None + if exe: # only for a rewritten title: a script run by an interpreter keeps its argv[0] + fields[0] = os.path.basename(exe.replace(" (deleted)", "")) + return fields + + +def scan_processes(proc_root, own_pid): + """(heavy kinds, browser main pids) from one pass over //cmdline.""" + kinds, browsers = {}, [] for entry in os.listdir(proc_root): if not entry.isdigit() or int(entry) == own_pid: continue try: - raw = read_text(os.path.join(proc_root, entry, "cmdline")) + argv = read_argv(os.path.join(proc_root, entry)) except OSError: continue # the process exited between listdir and read - kind = heavy_kind([a for a in raw.split("\0") if a]) + kind = heavy_kind(argv) if kind: kinds[kind] = kinds.get(kind, 0) + 1 - return kinds + if is_browser_main(argv): + browsers.append(int(entry)) + return kinds, sorted(browsers) def probe(args): @@ -202,12 +259,24 @@ def probe(args): out["disk_free_gb"] = None reasons.append("unknown: free disk unreadable (%s)" % type(exc).__name__) + tmp_bytes = None + out["tmp_path"] = args.tmp_path + try: + stat = os.statvfs(args.tmp_path) + tmp_bytes = stat.f_bavail * stat.f_frsize + out["tmp_free_gib"] = round(tmp_bytes / GIB, 2) + except OSError as exc: + out["tmp_free_gib"] = None + reasons.append("unknown: free /tmp space unreadable (%s)" % type(exc).__name__) + try: - kinds = count_heavy(args.proc_root, os.getpid()) + kinds, browser_pids = scan_processes(args.proc_root, os.getpid()) idle = kinds.pop("msbuild-node-idle", 0) out["heavy"] = {"count": sum(kinds.values()), "kinds": kinds, "idle_msbuild_nodes": idle} + out["browsers"] = {"count": len(browser_pids), "pids": browser_pids} except OSError as exc: out["heavy"] = None + out["browsers"] = None reasons.append("unknown: process table unreadable (%s)" % type(exc).__name__) limit = args.max_load_per_core * out["nproc"] if out["nproc"] else None @@ -216,6 +285,8 @@ def probe(args): "mem_available_gib_min": args.min_mem_gib, "disk_free_gb_min": args.min_disk_gb, "heavy_max": args.max_heavy, + "browser_hold_at": args.browser_hold_at, + "tmp_free_gib_min": args.min_tmp_gib, } if out["load5"] is not None: if limit is None: @@ -231,6 +302,10 @@ def probe(args): reasons.append("free disk %.2f GB < %.2f GB at %s" % (out["disk_free_gb"], args.min_disk_gb, args.disk_path)) if args.max_heavy is not None and out["heavy"] is not None and out["heavy"]["count"] > args.max_heavy: reasons.append("heavy processes %d > %d" % (out["heavy"]["count"], args.max_heavy)) + if args.browser_hold_at and out["browsers"] is not None and out["browsers"]["count"] >= args.browser_hold_at: + reasons.append("browser runs %d >= %d (headless Chromium main processes)" % (out["browsers"]["count"], args.browser_hold_at)) + if tmp_bytes is not None and tmp_bytes < args.min_tmp_gib * GIB: + reasons.append("free %s %.2f GiB < %.2f GiB" % (args.tmp_path, out["tmp_free_gib"], args.min_tmp_gib)) out["verdict"] = "hold" if reasons else "admit" out["reasons"] = reasons @@ -266,6 +341,9 @@ def main(argv=None): parser.add_argument("--min-mem-gib", type=finite_number(0.0, True), default=6.0, help="hold when MemAvailable is below this many GiB (default 6)") parser.add_argument("--min-disk-gb", type=finite_number(0.0, True), default=20.0, help="hold when free disk is below this many decimal GB (default 20)") parser.add_argument("--max-heavy", type=cpu_override_zero, default=None, help="optional: hold when more heavy build processes than this (default: report only)") + parser.add_argument("--browser-hold-at", type=cpu_override_zero, default=2, help="hold when at least this many headless Chromium main processes are active; 0 disables (default 2)") + parser.add_argument("--min-tmp-gib", type=finite_number(0.0, True), default=3.0, help="hold when free space at --tmp-path is below this many GiB (default 3)") + parser.add_argument("--tmp-path", default="/tmp", help="path whose filesystem free space is checked as /tmp headroom (default /tmp)") parser.add_argument("--disk-path", default=os.path.expanduser("~"), help="path whose filesystem free space is checked (default $HOME)") parser.add_argument("--proc-root", default="/proc", help="procfs root; tests point it at a fixture tree") parser.add_argument("--cgroup-root", default="/sys/fs/cgroup", help="cgroup v2 mount; tests point it at a fixture tree") diff --git a/scripts/fdev-tmp-cleanup.py b/scripts/fdev-tmp-cleanup.py new file mode 100755 index 000000000..fa740b218 --- /dev/null +++ b/scripts/fdev-tmp-cleanup.py @@ -0,0 +1,500 @@ +#!/usr/bin/env python3 +"""Remove dead harness temp directories from fdev's /tmp (.github#5240). Dry-run unless --apply. + +fdev's /tmp is a 16 GB tmpfs shared by every lane. Test and browser-smoke harnesses leave directories behind +when a run dies, and a full /tmp fails unrelated SDD tests (38 spurious failures on 2026-11-02). This removes +only KNOWN harness directories whose owning run is dead and which have been quiet long enough. + + scripts/fdev-tmp-cleanup.py # DRY RUN (the default): list what would be removed, remove nothing + scripts/fdev-tmp-cleanup.py --apply # remove it (the user timer passes this) + scripts/fdev-tmp-cleanup.py --root DIR ... # roots to sweep (default: /tmp, $TMPDIR if set, ~/.cache/fsgg-tmp) + +It prints ONE JSON line (counts by pattern and by keep reason, the removable entries and their bytes). It exits +0 when it finished, 2 on a usage error, an unsafe root or euid 0, and 3 when it refused to delete: the process +table could not be read, or a same-user process could not be inspected (below). A missing input is a refusal to +delete, never a pass. It never runs as root (euid 0 is refused) and never kills a process. + +KNOWN PATTERNS (an entry directly under a root, matched by exact name shape; nothing else is ever touched): + + owner PID in the name fsgg-sdd-tests--<32 hex> (FS.GG.SDD tests/Shared/TestShared.fs) + idle for over --min-age-hours (default 1) + no PID in the name fsgg-sdd-<32 hex> + fsgg-ai-tests-<32 hex>, fsgg-ai-tr-<32 hex>, fsgg-resolver-<32 hex>, + fsgg-cli-tests-cache-sandbox-<32 hex> + playwright_chromiumdev_profile-<6>, org.chromium.Chromium.<6> + tmp.<10 alphanumerics> that contains driver/run-smoke.mjs (a browser-smoke + mktemp tree; a bare tmp.* is NEVER matched) + idle for over --min-age-hours-pidless (default 6) + +A PID-less entry has no PID to prove the run is dead, so it needs a longer quiet period: 6 hours is an explicit +decision against holders that keep a directory only in memory (a process that never opens, maps or names it again). +Not swept on purpose: playwright-artifacts-* (empty on the real host and a live run's artifacts directory is not +referenced by any process), fsgg-gate-* (the gate-engine build cache is reused, and there is no per-run pattern). + +AN ENTRY IS REMOVED ONLY WHEN ALL OF THESE HOLD + 1. The owner is dead. With a PID in the name, / must not exist. Always, no live process may + reference the entry: its path, or a path that resolves to it (a relative word resolved against that + process's cwd, a symlinked alias resolved by realpath), as a command-line word or flag value, an environment + value, the cwd, an open file descriptor, a mapped file, or a bound unix socket (net/unix). A PID reused by an + unrelated process keeps the entry (safe). + 2. Nothing under it changed for the idle period above: the newest mtime of the entry and every node below it. + A tree of more than 400000 nodes, or one that crosses a mount point, is kept. + 3. It is a real directory owned by this user. A symlink at the entry is never followed and never removed. + 4. No same-user process is unknown to the scan. A process of this user whose cwd, fds or environ cannot be read + (a non-dumpable process, whose /proc entry belongs to root) could hold an entry invisibly, so while one + exists --apply refuses to delete anything (exit 3, reported in `unreadable`). Only a fixed allowlist is + exempt, by name: `systemd --user`, `(sd-pam)` and sshd. The scan decides a process's owner from the Uid line + of its status file, because the /proc directory of such a process is owned by root. + +Removal never follows a symlink: the tree is walked iteratively (no recursion, so depth is unbounded) with +directory file descriptors and O_NOFOLLOW, a symlink inside a tree is unlinked as a link, and the walk does not +cross filesystems. The open-file limit is raised to the hard limit first, because the walk holds one descriptor +per level. Before the first deletion the process table is read again, and each entry's inode and mtime must be +unchanged since it was surveyed. + +Tests point --proc-root at a fixture tree (/cmdline|environ|cwd|fd/N|maps|status, net/unix) and pass --root +and --now. +""" +import argparse +import errno +import json +import math +import os +import re +import resource +import stat +import sys +import time + +HEX32 = r"[0-9a-f]{32}" +RAND6 = r"[A-Za-z0-9]{6}" + +# (name, compiled regex, owner-pid group present, needs the smoke fingerprint) +PATTERNS = [ + ("fsgg-sdd-tests", re.compile(r"fsgg-sdd-tests-(?P\d{1,9})-" + HEX32), True, False), + ("fsgg-sdd-run", re.compile(r"fsgg-sdd-" + HEX32), False, False), + ("fsgg-test-root", re.compile(r"fsgg-(?:ai-tests|ai-tr|resolver|cli-tests-cache-sandbox)-" + HEX32), False, False), + ("playwright-profile", re.compile(r"playwright_chromiumdev_profile-" + RAND6), False, False), + ("chromium-temp", re.compile(r"org\.chromium\.Chromium\." + RAND6), False, False), + ("browser-smoke", re.compile(r"tmp\.[A-Za-z0-9]{10}"), False, True), +] +SMOKE_FINGERPRINT = ("driver", "run-smoke.mjs") +MAX_NODES = 400000 +# Same-user processes the scan may not be able to read, and that can be ignored: systemd --user, (sd-pam), sshd. +ALLOWED_UNREADABLE_COMM = {"(sd-pam)", "sshd", "sshd-session"} +NAME_CHARS = r"[^/\s\x00:=,\"'\\]+" +TOKEN_SPLIT = re.compile(r"[\s\x00=,:;\"']+") + + +def finite_hours(text): + value = float(text) + if not math.isfinite(value) or value < 0: + raise argparse.ArgumentTypeError("must be a finite number >= 0, got %r" % text) + return value + + +def classify(name): + """(pattern, owner pid or None, needs fingerprint) for a known harness name, else None.""" + for label, regex, has_pid, fingerprint in PATTERNS: + match = regex.fullmatch(name) + if match: + return label, int(match.group("pid")) if has_pid else None, fingerprint + return None + + +def has_fingerprint(path): + try: + inner = os.lstat(os.path.join(path, SMOKE_FINGERPRINT[0])) + if not stat.S_ISDIR(inner.st_mode): + return False + return stat.S_ISREG(os.lstat(os.path.join(path, *SMOKE_FINGERPRINT)).st_mode) + except OSError: + return False + + +def read_bytes(path, limit=8 * 1024 * 1024): + try: + with open(path, "rb") as handle: + return handle.read(limit) + except OSError: + return b"" + + +def vanished(exc): + return isinstance(exc, (FileNotFoundError, ProcessLookupError, NotADirectoryError)) + + +def process_uid(base): + """Real uid of a process: the Uid line of its status file (its /proc directory belongs to root when it is + non-dumpable), else the directory's owner.""" + try: + for line in read_bytes(os.path.join(base, "status")).decode("utf-8", "replace").splitlines(): + if line.startswith("Uid:"): + return int(line.split()[1]) + return os.lstat(base).st_uid + except (OSError, ValueError, IndexError): + return None + + +def allowed_unreadable(base, argv): + """True for the fixed allowlist of same-user processes that may stay uninspected, by name.""" + comm = read_bytes(os.path.join(base, "comm")).decode("utf-8", "replace").strip() + if comm in ALLOWED_UNREADABLE_COMM: + return True + first = os.path.basename(argv[0]) if argv else "" + return (first == "systemd" or comm == "systemd") and "--user" in argv + + +def live_references(proc_root, roots, own_pid): + """Top-level names under each root that a live process references, and the processes the scan could not fully read. + + Returns (names {root: set}, stats {processes, unreadable: [{pid, comm}]}). Raises OSError when the process + table itself cannot be listed. + """ + patterns = [re.compile(r"(? 4096: + continue + if token.startswith("/"): + candidate = token + elif cwd and ("/" in token or cwd_in_root(cwd)): + candidate = os.path.normpath(os.path.join(cwd, token)) + else: + continue + if "/" not in candidate[1:]: + continue + note(candidate) + if token.startswith("/") or "/" in token: + note(resolve(candidate)) + + def cwd_in_root(cwd): + return any(cwd == root or cwd.startswith(root + "/") for root in roots) + + for entry in os.listdir(proc_root): + if not entry.isdigit() or int(entry) == own_pid: + continue + base = os.path.join(proc_root, entry) + processes += 1 + mine = process_uid(base) == me + full = True + cwd = None + try: + cwd = os.readlink(os.path.join(base, "cwd")) + note(cwd) + note(resolve(cwd)) + except OSError as exc: + full = full and (vanished(exc) or not mine) + argv = [a for a in read_bytes(os.path.join(base, "cmdline")).decode("utf-8", "replace").split("\x00") if a] + for leaf in ("cmdline", "environ", "maps"): + path = os.path.join(base, leaf) + try: + with open(path, "rb") as handle: + harvest(handle.read(8 * 1024 * 1024), cwd) + except OSError as exc: + if leaf == "environ": + full = full and (vanished(exc) or not mine) + try: + for fd in os.listdir(os.path.join(base, "fd")): + try: + target = os.readlink(os.path.join(base, "fd", fd)) + harvest(target.encode(), None) + note(resolve(target)) if target.startswith("/") else None + except OSError: + pass + except OSError as exc: + full = full and (vanished(exc) or not mine) + if mine and not full and not allowed_unreadable(base, argv): + comm = read_bytes(os.path.join(base, "comm")).decode("utf-8", "replace").strip() + unreadable.append({"pid": int(entry), "comm": comm or (os.path.basename(argv[0]) if argv else "")}) + for line in read_bytes(os.path.join(proc_root, "net", "unix")).splitlines(): + fields = line.split(None, 7) # Num RefCount Protocol Flags Type St Inode Path + if len(fields) == 8: + harvest(fields[7], None) + return names, {"processes": processes, "unreadable": unreadable} + + +def survey(path, top, cutoff): + """Walk one entry without following symlinks: (newest mtime, bytes, nodes, verdict). + + verdict is None, or why the entry must be kept ("young", "mount-point", "tree-too-large", "unreadable"). + Stops at the first node newer than cutoff. + """ + newest = top.st_mtime + total = top.st_blocks * 512 + nodes = 1 + if newest > cutoff: + return newest, total, nodes, "young" + stack = [path] + while stack: + current = stack.pop() + try: + with os.scandir(current) as entries: + for entry in entries: + info = entry.stat(follow_symlinks=False) + nodes += 1 + total += info.st_blocks * 512 + newest = max(newest, info.st_mtime) + if info.st_mtime > cutoff: + return newest, total, nodes, "young" + if nodes > MAX_NODES: + return newest, total, nodes, "tree-too-large" + if stat.S_ISDIR(info.st_mode): + if info.st_dev != top.st_dev: + return newest, total, nodes, "mount-point" + stack.append(entry.path) + except OSError: + return newest, total, nodes, "unreadable" + return newest, total, nodes, None + + +def remove_tree(parent_fd, name, dev): + """Delete parent_fd/name without following any symlink and without crossing filesystems. + + Iterative: one open directory descriptor per level of depth, no recursion. + """ + def open_dir(pfd, child): + info = os.stat(child, dir_fd=pfd, follow_symlinks=False) + if info.st_dev != dev: + raise OSError(errno.EXDEV, "mount point inside the tree", child) + fd = os.open(child, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=pfd) + try: + now = os.fstat(fd) + if (now.st_dev, now.st_ino) != (info.st_dev, info.st_ino): + raise OSError(errno.ESTALE, "entry replaced while opening", child) + if not info.st_mode & stat.S_IWUSR or not info.st_mode & stat.S_IXUSR: + os.fchmod(fd, 0o700) + return [fd, child, pfd, os.listdir(fd)] + except BaseException: + os.close(fd) + raise + + top = os.stat(name, dir_fd=parent_fd, follow_symlinks=False) + if not stat.S_ISDIR(top.st_mode): + os.unlink(name, dir_fd=parent_fd) + return + stack = [open_dir(parent_fd, name)] + try: + while stack: + frame = stack[-1] + if frame[3]: + child = frame[3].pop() + info = os.stat(child, dir_fd=frame[0], follow_symlinks=False) + if stat.S_ISDIR(info.st_mode): + stack.append(open_dir(frame[0], child)) + else: + os.unlink(child, dir_fd=frame[0]) + else: + stack.pop() + os.close(frame[0]) + frame[0] = -1 + os.rmdir(frame[1], dir_fd=frame[2]) + finally: + for frame in stack: + if frame[0] >= 0: + os.close(frame[0]) + + +def raise_open_file_limit(): + soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE) + want = hard if hard != resource.RLIM_INFINITY else 1 << 20 + if soft != resource.RLIM_INFINITY and soft < want: + try: + resource.setrlimit(resource.RLIMIT_NOFILE, (want, hard)) + except (ValueError, OSError): + pass + + +def safe_root(text, home): + """Resolve a root to a directory that is not a symlink, not / and not $HOME or an ancestor of it.""" + path = os.path.abspath(os.path.expanduser(text)) + if os.path.islink(path): + raise ValueError("root %s is a symlink; roots are never followed" % path) + if not os.path.isdir(path): + raise FileNotFoundError(path) + real = os.path.realpath(path) + if real == "/" or real == home or home.startswith(real.rstrip("/") + "/"): + raise ValueError("root %s is / or $HOME or an ancestor of it" % path) + return real + + +def default_roots(home): + roots = ["/tmp"] + if os.environ.get("TMPDIR"): + roots.append(os.environ["TMPDIR"]) + roots.append(os.path.join(home, ".cache", "fsgg-tmp")) + return roots + + +def sweep(args): + home = os.path.realpath(os.path.expanduser("~")) + requested = list(args.root) or default_roots(home) + roots, skipped_roots = [], [] + for text in requested: + try: + path = safe_root(text, home) + except FileNotFoundError: + if args.root: # a root the caller named must exist; a default one may be absent + raise ValueError("root %s does not exist" % text) + skipped_roots.append({"root": text, "reason": "absent"}) + continue + if path not in roots: + roots.append(path) + if not roots: + raise ValueError("no root to sweep") + + now = args.now if args.now is not None else time.time() + cutoff_pid = now - args.min_age_hours * 3600 + cutoff_pidless = now - args.min_age_hours_pidless * 3600 + uid = os.geteuid() + try: + refs, proc_stats = live_references(args.proc_root, roots, os.getpid()) + except OSError as exc: + return None, "process table unreadable (%s)" % type(exc).__name__ + + summary = {"mode": "apply" if args.apply else "dry-run", "roots": roots, "skipped_roots": skipped_roots, + "min_age_hours": args.min_age_hours, "min_age_hours_pidless": args.min_age_hours_pidless, + "processes_read": proc_stats["processes"], "unreadable": proc_stats["unreadable"], + "apply_blocked": bool(proc_stats["unreadable"]), "entries_matched": 0, "would_remove": 0, + "would_free_bytes": 0, "removed": 0, "freed_bytes": 0, "failed": 0, + "by_pattern": {}, "kept": {}, "removable": [], "failures": []} + candidates = [] + for root in roots: + try: + names = sorted(os.listdir(root)) + except OSError: + summary["skipped_roots"].append({"root": root, "reason": "unreadable"}) + continue + for name in names: + known = classify(name) + if known is None: + continue + label, owner_pid, needs_fingerprint = known + path = os.path.join(root, name) + try: + top = os.lstat(path) + except OSError: + continue + keep = None + if stat.S_ISLNK(top.st_mode): + keep = "symlink" + elif not stat.S_ISDIR(top.st_mode): + keep = "not-a-directory" + elif needs_fingerprint and not has_fingerprint(path): + continue # a bare tmp.* is not a harness directory: not matched at all + elif top.st_uid != uid: + keep = "not-owned" + summary["entries_matched"] += 1 + bucket = summary["by_pattern"].setdefault(label, {"matched": 0, "removable": 0}) + bucket["matched"] += 1 + if keep is None and owner_pid is not None and os.path.isdir(os.path.join(args.proc_root, str(owner_pid))): + keep = "pid-alive" + if keep is None and name in refs[root]: + keep = "referenced-by-live-process" + newest = size = None + if keep is None: + newest, size, _, verdict = survey(path, top, cutoff_pid if owner_pid is not None else cutoff_pidless) + keep = verdict + if keep is not None: + summary["kept"][keep] = summary["kept"].get(keep, 0) + 1 + continue + bucket["removable"] += 1 + summary["would_remove"] += 1 + summary["would_free_bytes"] += size + candidates.append((root, name, path, label, owner_pid, top, size, newest)) + summary["removable"].append({"path": path, "pattern": label, "owner": ("pid %d (dead)" % owner_pid) if owner_pid else "no live reference", + "bytes": size, "idle_hours": round((now - newest) / 3600, 2)}) + + if args.apply and proc_stats["unreadable"]: + who = ", ".join("%d (%s)" % (u["pid"], u["comm"]) for u in proc_stats["unreadable"][:5]) + return None, "%d same-user process(es) could not be inspected (%s); an entry could be held invisibly" % (len(proc_stats["unreadable"]), who) + if args.apply and candidates: + raise_open_file_limit() + try: # the table is read again; an entry a process picked up since the survey is kept + fresh, fresh_stats = live_references(args.proc_root, roots, os.getpid()) + except OSError as exc: + return None, "process table unreadable on the second read (%s)" % type(exc).__name__ + if fresh_stats["unreadable"]: + return None, "a same-user process could not be inspected on the second read; nothing was removed" + for root, name, path, label, owner_pid, top, size, newest in candidates: + if name in fresh[root]: + summary["kept"]["referenced-by-live-process"] = summary["kept"].get("referenced-by-live-process", 0) + 1 + continue + try: + again = os.lstat(path) + if (again.st_ino, again.st_dev, again.st_mtime) != (top.st_ino, top.st_dev, top.st_mtime): + summary["kept"]["changed-since-survey"] = summary["kept"].get("changed-since-survey", 0) + 1 + continue + root_fd = os.open(root, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW) + try: + remove_tree(root_fd, name, top.st_dev) + finally: + os.close(root_fd) + summary["removed"] += 1 + summary["freed_bytes"] += size + except FileNotFoundError: + continue + except OSError as exc: + summary["failed"] += 1 + summary["failures"].append({"path": path, "error": type(exc).__name__ + ": " + (exc.strerror or "")}) + summary["removable"] = summary["removable"][:args.list_limit] + summary["removable_listed_of"] = summary["would_remove"] + return summary, None + + +def main(argv=None): + parser = argparse.ArgumentParser(description="Remove dead, idle harness temp directories (dry-run unless --apply).") + parser.add_argument("--apply", action="store_true", help="actually remove; without it nothing is changed") + parser.add_argument("--dry-run", action="store_true", help="the default; accepted so a caller can state it") + parser.add_argument("--root", action="append", default=[], help="a directory to sweep (repeatable; default /tmp, $TMPDIR, ~/.cache/fsgg-tmp)") + parser.add_argument("--min-age-hours", type=finite_hours, default=1.0, help="PID-named patterns: keep anything modified within this many hours (default 1)") + parser.add_argument("--min-age-hours-pidless", type=finite_hours, default=6.0, help="the idle period for patterns with no PID in the name (default 6)") + parser.add_argument("--proc-root", default="/proc", help="procfs root; tests point it at a fixture tree") + parser.add_argument("--now", type=float, default=None, help="epoch seconds to age against (tests)") + parser.add_argument("--list-limit", type=int, default=25, help="how many removable entries to list (default 25)") + args = parser.parse_args(argv) + if os.geteuid() == 0: + print("fdev-tmp-cleanup: refused: run as the fdev user, not root", file=sys.stderr) + return 2 + if args.apply and args.dry_run: + parser.error("--apply and --dry-run are exclusive") + try: + summary, refusal = sweep(args) + except ValueError as exc: + print("fdev-tmp-cleanup: refused: %s" % exc, file=sys.stderr) + return 2 + if summary is None: + print(json.dumps({"mode": "refused", "reason": refusal}, sort_keys=True, separators=(",", ":"))) + print("fdev-tmp-cleanup: %s; nothing was removed" % refusal, file=sys.stderr) + return 3 + print(json.dumps(summary, sort_keys=True, separators=(",", ":"), allow_nan=False)) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/fdev-board-tend/test_fdev_board_tend.py b/tests/fdev-board-tend/test_fdev_board_tend.py index 3fc4632d7..ef302a988 100644 --- a/tests/fdev-board-tend/test_fdev_board_tend.py +++ b/tests/fdev-board-tend/test_fdev_board_tend.py @@ -259,6 +259,105 @@ def test_systemd_accepts_the_rendered_units(self): self.assertEqual(problems, [], done.stderr) +class TmpCleanupInstallTests(FakeHome): + """The hourly dead-run /tmp cleanup timer and the chromium wrapper, installed by their own effects (#5240).""" + + def run_install(self, *argv, expect=0): + out, err = io.StringIO(), io.StringIO() + with contextlib.redirect_stdout(out), contextlib.redirect_stderr(err): + code = INSTALL.main(list(argv)) + self.assertEqual(code, expect, err.getvalue()) + return out.getvalue(), err.getvalue() + + def test_writes_only_the_two_units_and_the_script_and_leaves_the_board_tend_units_alone(self): + before = self.tree() + self.run_install("tmp-cleanup") + self.assertEqual(self.tree() - before, { + ".config/systemd", ".config/systemd/user", ".local/libexec", + ".config/systemd/user/fsgg-tmp-cleanup.service", ".config/systemd/user/fsgg-tmp-cleanup.timer", + ".local/libexec/fdev-tmp-cleanup.py"} - before) + script = self.libexec / "fdev-tmp-cleanup.py" + self.assertEqual(script.read_bytes(), (ROOT / "scripts/fdev-tmp-cleanup.py").read_bytes()) + self.assertEqual(stat.S_IMODE(script.stat().st_mode), 0o755) + + def test_the_service_runs_the_installed_script_with_apply_and_cannot_see_a_private_tmp(self): + self.run_install("tmp-cleanup") + service = (self.unit_dir / "fsgg-tmp-cleanup.service").read_text(encoding="utf-8") + directives = [l for l in service.splitlines() if l.strip() and not l.lstrip().startswith("#")] + self.assertIn("Type=oneshot", directives) + self.assertIn(f"ExecStart=/usr/bin/python3 -I {self.libexec}/fdev-tmp-cleanup.py --apply", directives) + self.assertFalse([l for l in directives if l.startswith(("PrivateTmp", "ProtectHome", "ProtectSystem"))], directives) + self.assertNotIn("@", "\n".join(directives)) + self.assertIn("Nice=15", directives) + self.assertIn("IOSchedulingClass=idle", directives) + + def test_the_timer_is_hourly_at_minute_37_persistent_and_randomised(self): + self.run_install("tmp-cleanup") + timer = (self.unit_dir / "fsgg-tmp-cleanup.timer").read_text(encoding="utf-8") + for line in ("OnCalendar=*-*-* *:37:00", "Persistent=true", "RandomizedDelaySec=120", "Unit=fsgg-tmp-cleanup.service", "WantedBy=timers.target"): + self.assertIn(line, timer.splitlines()) + # minute 37 collides with no other fdev timer: board tend :07, observer :23, dispatch :53, daily 00:30 + self.assertNotIn(":07:00", timer) + + def test_dry_run_writes_nothing_is_idempotent_and_refuses_a_different_file_without_force(self): + before = self.tree() + out, _ = self.run_install("tmp-cleanup", "--dry-run") + self.assertEqual(self.tree(), before) + self.assertIn("would write", out) + self.run_install("tmp-cleanup") + again, _ = self.run_install("tmp-cleanup") + self.assertIn("unchanged", again) + (self.unit_dir / "fsgg-tmp-cleanup.timer").write_text("edited", encoding="utf-8") + _, err = self.run_install("tmp-cleanup", expect=2) + self.assertIn("--force", err) + self.run_install("tmp-cleanup", "--force") + self.assertIn("OnCalendar", (self.unit_dir / "fsgg-tmp-cleanup.timer").read_text(encoding="utf-8")) + + def test_enable_runs_systemctl_for_the_cleanup_timer_only(self): + calls = [] + with mock.patch.object(INSTALL.subprocess, "run", side_effect=lambda cmd, **kw: calls.append(cmd)): + self.run_install("tmp-cleanup", "--enable") + self.assertEqual(calls, [["systemctl", "--user", "daemon-reload"], ["systemctl", "--user", "enable", "--now", "fsgg-tmp-cleanup.timer"]]) + out, _ = self.run_install("tmp-cleanup") + self.assertIn("systemd not touched", out) + + def test_refuses_to_run_as_root_and_paths_outside_home(self): + with mock.patch.object(INSTALL.os, "geteuid", return_value=0): + self.run_install("tmp-cleanup", expect=2) + self.run_install("chromium-env", expect=2) + self.run_install("tmp-cleanup", "--unit-dir", "/etc/systemd/system", expect=2) + self.run_install("chromium-env", "--dest", "/usr/local/bin/fdev-chromium-env", expect=2) + + def test_the_rendered_script_runs_as_a_dry_run_against_an_empty_root(self): + self.run_install("tmp-cleanup") + root = self.home / "sweep" + root.mkdir() + done = subprocess.run([sys.executable, "-I", str(self.libexec / "fdev-tmp-cleanup.py"), "--root", str(root)], capture_output=True, text=True, check=False) + self.assertEqual(done.returncode, 0, done.stderr) + self.assertEqual(json.loads(done.stdout)["mode"], "dry-run") + + @unittest.skipUnless(shutil.which("systemd-analyze"), "systemd-analyze is not available") + def test_systemd_accepts_the_rendered_units(self): + self.run_install("tmp-cleanup") + files = [str(self.unit_dir / n) for n in ("fsgg-tmp-cleanup.service", "fsgg-tmp-cleanup.timer")] + done = subprocess.run(["systemd-analyze", "--user", "verify", *files], capture_output=True, text=True, timeout=60, check=False) + problems = [l for l in (done.stdout + done.stderr).splitlines() if "fsgg-tmp-cleanup" in l and not l.startswith("Could not")] + self.assertEqual(problems, [], done.stderr) + + def test_chromium_env_installs_the_repo_source_executable_and_refuses_to_replace_without_force(self): + dest = self.home / ".local/bin/fdev-chromium-env" + self.run_install("chromium-env", "--dry-run") + self.assertFalse(dest.exists()) + self.run_install("chromium-env") + self.assertEqual(dest.read_bytes(), (ROOT / "deployment/fdev-chromium/fdev-chromium-env").read_bytes()) + self.assertEqual(stat.S_IMODE(dest.stat().st_mode), 0o755) + dest.write_text("#!/bin/sh\n# the old installed copy\n", encoding="utf-8") + _, err = self.run_install("chromium-env", expect=2) + self.assertIn("--force", err) + self.run_install("chromium-env", "--force") + self.assertIn("TMPDIR", dest.read_text(encoding="utf-8")) + + class KitRootTests(FakeHome): def repo(self, *texts): repo = self.home / "repo" diff --git a/tests/fdev-chromium-env/run.sh b/tests/fdev-chromium-env/run.sh new file mode 100755 index 000000000..8bc8134d0 --- /dev/null +++ b/tests/fdev-chromium-env/run.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Fixture for deployment/fdev-chromium/fdev-chromium-env (.github#5240). Offline, credential-free, stdlib only. +set -euo pipefail +HERE="$(cd "$(dirname "$0")" && pwd)" +exec python3 -I -m unittest discover -v -s "$HERE" -p 'test_*.py' diff --git a/tests/fdev-chromium-env/test_fdev_chromium_env.py b/tests/fdev-chromium-env/test_fdev_chromium_env.py new file mode 100644 index 000000000..b69b31950 --- /dev/null +++ b/tests/fdev-chromium-env/test_fdev_chromium_env.py @@ -0,0 +1,124 @@ +"""Fixture tests for the TMPDIR default in deployment/fdev-chromium/fdev-chromium-env (.github#5240). Offline.""" +import os +import stat +import subprocess +import tempfile +import unittest + +HERE = os.path.dirname(os.path.abspath(__file__)) +WRAPPER = os.path.join(HERE, "..", "..", "deployment", "fdev-chromium", "fdev-chromium-env") +# Linux sun_path is 108 bytes including the NUL. The SDD test that failed under a long TMPDIR binds +# Path.Combine(GetTempPath(), "sdd-race-characterization-" + Guid.ToString("N"), "inputs", "socket") +# (FS.GG.SDD tests/FS.GG.SDD.Commands.Tests/GenerationSourceRaceCharacterizationTests.fs). Model it exactly. +SOCKET_BUDGET = 107 +RACE_SOCKET_SUFFIX = "/sdd-race-characterization-" + "0" * 32 + "/inputs/socket" +HARNESS_SUFFIX = len(RACE_SOCKET_SUFFIX) + + +class Wrapper(unittest.TestCase): + def setUp(self): + tmp = tempfile.TemporaryDirectory() + self.addCleanup(tmp.cleanup) + self.home = os.path.realpath(tmp.name) + self.bundle = os.path.join(self.home, "bundle") + os.makedirs(os.path.join(self.bundle, "root", "usr", "lib")) + for rel in ("manifest.json", "fonts.conf", "root/usr/lib/libnss3.so"): + with open(os.path.join(self.bundle, rel), "w") as handle: + handle.write("{}") + + def run_wrapper(self, *args, env=None, tmpdir=None): + full = {"PATH": os.environ["PATH"], "HOME": self.home, "FDEV_TMPDIR_MAX": "200"} # the fixture HOME is long + if tmpdir is not None: + full["TMPDIR"] = tmpdir + full.update(env or {}) + return subprocess.run(["bash", WRAPPER, "--bundle", self.bundle, *args], capture_output=True, text=True, check=False, env=full) + + def printed(self, done): + return dict(line.split("=", 1) for line in done.stdout.splitlines() if "=" in line) + + def test_unset_tmpdir_defaults_to_a_private_disk_directory_under_home(self): + done = self.run_wrapper("--print-env") + want = os.path.join(self.home, ".cache", "fsgg-tmp") + self.assertEqual((done.returncode, self.printed(done)["TMPDIR"]), (0, want), done.stderr) + info = os.lstat(want) + self.assertTrue(stat.S_ISDIR(info.st_mode)) + self.assertEqual(stat.S_IMODE(info.st_mode), 0o700) + + def test_the_command_runs_with_that_tmpdir(self): + done = self.run_wrapper("--", "sh", "-c", "printf %s \"$TMPDIR\"") + self.assertEqual((done.returncode, done.stdout), (0, os.path.join(self.home, ".cache", "fsgg-tmp")), done.stderr) + + def test_a_tmpdir_that_is_already_set_is_never_changed_and_nothing_is_created(self): + for value in ("/tmp", "/somewhere/else"): + done = self.run_wrapper("--", "sh", "-c", "printf %s \"$TMPDIR\"", tmpdir=value) + self.assertEqual((done.returncode, done.stdout), (0, value)) + self.assertFalse(os.path.exists(os.path.join(self.home, ".cache"))) + + def test_an_empty_tmpdir_counts_as_unset(self): + done = self.run_wrapper("--print-env", tmpdir="") + self.assertEqual(self.printed(done)["TMPDIR"], os.path.join(self.home, ".cache", "fsgg-tmp")) + + def test_fdev_tmpdir_overrides_the_default_path(self): + want = os.path.join(self.home, "t") + done = self.run_wrapper("--print-env", env={"FDEV_TMPDIR": want}) + self.assertEqual(self.printed(done)["TMPDIR"], want) + + def test_a_default_that_is_too_long_for_a_unix_socket_is_refused_with_a_warning(self): + done = self.run_wrapper("--print-env", env={"FDEV_TMPDIR_MAX": "20"}) # the fixture HOME path is longer than 20 + self.assertEqual((done.returncode, self.printed(done)["TMPDIR"]), (0, "")) + self.assertIn("budget for Unix socket paths", done.stderr) + self.assertFalse(os.path.exists(os.path.join(self.home, ".cache"))) + + def test_the_shipped_default_leaves_room_for_a_harness_socket_path(self): + # fdev's HOME is /home/developer; the default budget must keep the longest harness socket under sun_path. + default = "/home/developer/.cache/fsgg-tmp" + done = subprocess.run(["bash", "-c", 'grep -o "FDEV_TMPDIR_MAX:-[0-9]*" "$0"', WRAPPER], capture_output=True, text=True, check=True) + budget = int(done.stdout.split("-")[-1]) + self.assertLessEqual(len(default), budget) + self.assertLessEqual(budget + HARNESS_SUFFIX, SOCKET_BUDGET) + + def test_the_modelled_race_socket_path_fits_for_the_default_and_not_for_a_long_tmpdir(self): + default = "/home/developer/.cache/fsgg-tmp" + self.assertEqual(len(default + RACE_SOCKET_SUFFIX), 104) + self.assertLessEqual(len(default + RACE_SOCKET_SUFFIX), SOCKET_BUDGET) + long_tmpdir = "/home/developer/.fsgg-scratch/788b/tmp5" # a lane TMPDIR that is merely 'a bit longer' + self.assertGreater(len(long_tmpdir + RACE_SOCKET_SUFFIX), SOCKET_BUDGET) + + def test_an_existing_looser_directory_is_tightened_to_0700(self): + path = os.path.join(self.home, ".cache", "fsgg-tmp") + os.makedirs(path) + os.chmod(path, 0o755) + self.assertEqual(self.printed(self.run_wrapper("--print-env"))["TMPDIR"], path) + self.assertEqual(stat.S_IMODE(os.lstat(path).st_mode), 0o700) + + def test_a_symlink_or_foreign_default_is_refused(self): + os.makedirs(os.path.join(self.home, ".cache")) + os.symlink("/tmp", os.path.join(self.home, ".cache", "fsgg-tmp")) + done = self.run_wrapper("--print-env") + self.assertEqual(self.printed(done)["TMPDIR"], "") + self.assertIn("is a symlink", done.stderr) + + def test_print_tmpdir_needs_no_bundle_and_fails_when_nothing_resolves(self): + full = {"PATH": os.environ["PATH"], "HOME": self.home, "FDEV_TMPDIR_MAX": "200"} + done = subprocess.run(["bash", WRAPPER, "--print-tmpdir"], capture_output=True, text=True, check=False, env=full) + self.assertEqual((done.returncode, done.stdout.strip()), (0, os.path.join(self.home, ".cache", "fsgg-tmp")), done.stderr) + full["FDEV_TMPDIR_MAX"] = "5" + done = subprocess.run(["bash", WRAPPER, "--print-tmpdir"], capture_output=True, text=True, check=False, env=full) + self.assertEqual((done.returncode, done.stdout.strip()), (1, "")) + + def test_side_effect_free_actions_do_not_create_the_directory(self): + for action in ("--print-args", "--print-args-json"): + self.assertEqual(self.run_wrapper(action).returncode, 0) + self.assertFalse(os.path.exists(os.path.join(self.home, ".cache"))) + + def test_the_bundle_environment_is_unchanged(self): + done = self.run_wrapper("--gpu", "--print-env") + printed = self.printed(done) + self.assertTrue(printed["LD_LIBRARY_PATH"].startswith(os.path.join(self.bundle, "root", "usr", "lib"))) + self.assertEqual(printed["FDEV_CHROMIUM_MODE"], "gpu") + self.assertEqual(self.run_wrapper("--", "true").returncode, 0) + self.assertEqual(self.run_wrapper("--bundle", "/nonexistent", "--print-env").returncode, 66) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/fdev-lane-capacity/fixtures/chromium-gpu-child.cmdline b/tests/fdev-lane-capacity/fixtures/chromium-gpu-child.cmdline new file mode 100644 index 000000000..ba8fd1411 Binary files /dev/null and b/tests/fdev-lane-capacity/fixtures/chromium-gpu-child.cmdline differ diff --git a/tests/fdev-lane-capacity/fixtures/chromium-main.cmdline b/tests/fdev-lane-capacity/fixtures/chromium-main.cmdline new file mode 100644 index 000000000..4ef26eaf4 Binary files /dev/null and b/tests/fdev-lane-capacity/fixtures/chromium-main.cmdline differ diff --git a/tests/fdev-lane-capacity/fixtures/chromium-zygote-child.cmdline b/tests/fdev-lane-capacity/fixtures/chromium-zygote-child.cmdline new file mode 100644 index 000000000..c03793d14 Binary files /dev/null and b/tests/fdev-lane-capacity/fixtures/chromium-zygote-child.cmdline differ diff --git a/tests/fdev-lane-capacity/test_fdev_lane_capacity.py b/tests/fdev-lane-capacity/test_fdev_lane_capacity.py index 56ddaf0bc..d4108366f 100644 --- a/tests/fdev-lane-capacity/test_fdev_lane_capacity.py +++ b/tests/fdev-lane-capacity/test_fdev_lane_capacity.py @@ -41,10 +41,20 @@ def cgroup(self, path="/lane.slice/job.scope", **files): def process(self, pid, *argv): self.write("%d/cmdline" % pid, "\0".join(argv) + "\0") + def process_raw(self, pid, raw, exe=None): + """A cmdline file with these exact bytes (a rewritten process title is one space-joined string), and an exe link.""" + path = os.path.join(self.root, str(pid), "cmdline") + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, "wb") as handle: + handle.write(raw) + if exe: + os.symlink(exe, os.path.join(self.root, str(pid), "exe")) + def run(proc_root, *flags, nproc="12", disk="0"): args = [sys.executable, "-I", PROBE, "--proc-root", proc_root, "--cgroup-root", os.path.join(proc_root, "cg"), - "--nproc", nproc, "--disk-path", proc_root, "--min-disk-gb", disk, *flags] + "--nproc", nproc, "--disk-path", proc_root, "--min-disk-gb", disk, + "--tmp-path", proc_root, "--min-tmp-gib", "0", *flags] # /tmp headroom is the fixture dir's, never the host's done = subprocess.run(args, capture_output=True, text=True, check=False) lines = done.stdout.splitlines() assert len(lines) == 1, "expected exactly one JSON line, got %r (stderr %r)" % (done.stdout, done.stderr) @@ -102,10 +112,12 @@ def test_disk_floor_flag_flips_the_verdict(self): def test_default_thresholds_are_stated(self): Proc(self.root) - done = subprocess.run([sys.executable, "-I", PROBE, "--proc-root", self.root, "--cgroup-root", self.root + "/cg", "--nproc", "12", "--disk-path", self.root], - capture_output=True, text=True, check=False) - t = json.loads(done.stdout)["thresholds"] + done = subprocess.run([sys.executable, "-I", PROBE, "--proc-root", self.root, "--cgroup-root", self.root + "/cg", "--nproc", "12", "--disk-path", self.root, + "--tmp-path", self.root], capture_output=True, text=True, check=False) + out = json.loads(done.stdout) + t = out["thresholds"] self.assertEqual((t["load5_below"], t["mem_available_gib_min"], t["disk_free_gb_min"], t["heavy_max"]), (10.2, 6.0, 20.0, None)) + self.assertEqual((t["browser_hold_at"], t["tmp_free_gib_min"], out["tmp_path"]), (2, 3.0, self.root)) def test_heavy_processes_are_counted_by_kind_and_graded_only_on_request(self): proc = Proc(self.root) @@ -179,7 +191,7 @@ def test_nan_inf_and_negative_load_hold_as_unknown_loadavg(self): def test_output_is_strict_json_with_no_nan_or_infinity(self): Proc(self.root, load="nan inf -inf") done = subprocess.run([sys.executable, "-I", PROBE, "--proc-root", self.root, "--cgroup-root", self.root + "/cg", "--nproc", "12", - "--disk-path", self.root, "--min-disk-gb", "0"], capture_output=True, text=True, check=False) + "--disk-path", self.root, "--min-disk-gb", "0", "--tmp-path", self.root], capture_output=True, text=True, check=False) def refuse(token): raise ValueError("non-strict JSON token " + token) json.loads(done.stdout, parse_constant=refuse) @@ -279,6 +291,159 @@ def test_malformed_cgroup_limit_holds_as_unknown(self): self.assertEqual(run(self.root)[0], 3) + # --- #5240: browser-run concurrency and /tmp headroom ------------------------------------------------- + + PW = "/home/u/.cache/ms-playwright/chromium-1243/chrome-linux64/chrome" + MAIN = ["--headless", "--no-sandbox", "--user-data-dir=/tmp/playwright_chromiumdev_profile-AAAAAA", "--remote-debugging-pipe"] + + def browser(self, proc, pid, exe=None, *flags): + proc.process(pid, exe or self.PW, *(flags or self.MAIN)) + + def test_browser_main_processes_count_once_and_their_children_do_not(self): + proc = Proc(self.root) + self.browser(proc, 100) + for pid, kind in ((101, "zygote"), (102, "gpu-process"), (103, "renderer"), (104, "utility"), (105, "renderer")): + proc.process(pid, self.PW, "--type=" + kind, "--headless", "--no-sandbox", "--user-data-dir=/tmp/playwright_chromiumdev_profile-AAAAAA") + proc.process(106, self.PW.replace("/chrome", "/chrome_crashpad_handler"), "--monitor-self", "--database=/h/Crash Reports") + proc.process(107, "timeout", "600", "node", "/s/probe.mjs", self.PW, "--headless", "--remote-debugging-pipe") # launcher, not a browser + proc.process(108, "node", "/s/probe.mjs", self.PW, "--headless", "--remote-debugging-pipe") + code, out = run(self.root) + self.assertEqual((code, out["verdict"]), (0, "admit")) + self.assertEqual(out["browsers"], {"count": 1, "pids": [100]}) + + def test_two_browser_runs_hold_and_the_threshold_is_configurable(self): + proc = Proc(self.root) + self.browser(proc, 100) + self.browser(proc, 200, "/home/u/.cache/ms-playwright/chromium_headless_shell-1243/chrome-headless-shell-linux64/chrome-headless-shell", + "--headless", "--remote-debugging-pipe") + code, out = run(self.root) + self.assertEqual((code, out["verdict"], out["browsers"]["count"], out["browsers"]["pids"]), (3, "hold", 2, [100, 200])) + self.assertIn("browser runs 2 >= 2 (headless Chromium main processes)", out["reasons"]) + self.assertEqual(run(self.root, "--browser-hold-at", "3")[0], 0) + self.assertEqual(run(self.root, "--browser-hold-at", "0")[0], 0) # 0 disables + self.assertEqual(run(self.root, "--browser-hold-at", "3")[1]["thresholds"]["browser_hold_at"], 3) + self.browser(proc, 300, "/usr/bin/chromium", "--headless=new", "--remote-debugging-port=9222") + self.assertEqual(run(self.root, "--browser-hold-at", "3")[0], 3) + + def test_a_rewritten_process_title_is_one_space_joined_field_and_still_counts(self): + # Captured from a real Playwright chrome-headless-shell 1243 on fdev (Chromium 153): the cmdline file is ONE + # string with spaces and a single trailing NUL, for the main process and for every --type= child alike. + def fixture(name): + with open(os.path.join(HERE, "fixtures", name), "rb") as handle: + return handle.read() + main, gpu, zygote = (fixture(n) for n in ("chromium-main.cmdline", "chromium-gpu-child.cmdline", "chromium-zygote-child.cmdline")) + self.assertEqual((main.count(b"\0"), gpu.count(b"\0")), (1, 1)) # the shape the fix is about + exe = "/home/u/.cache/ms-playwright/chromium_headless_shell-1243/chrome-headless-shell-linux64/chrome-headless-shell" + proc = Proc(self.root) + proc.process_raw(100, main, exe) + proc.process_raw(101, gpu, exe) + proc.process_raw(102, zygote, exe) + code, out = run(self.root) + self.assertEqual((code, out["browsers"]), (0, {"count": 1, "pids": [100]})) + proc.process_raw(200, main.replace(b"profile-F7pDkp", b"profile-Other1"), exe) + code, out = run(self.root) + self.assertEqual((code, out["browsers"]["count"], out["verdict"]), (3, 2, "hold")) + + def test_a_rewritten_title_without_a_readable_exe_is_classified_from_the_first_word(self): + with open(os.path.join(HERE, "fixtures", "chromium-main.cmdline"), "rb") as handle: + main = handle.read() + proc = Proc(self.root) + proc.process_raw(100, main) + self.assertEqual(run(self.root)[1]["browsers"]["count"], 1) + + def test_a_launcher_keeps_its_own_argv0_even_when_it_names_chrome(self): + # Single-field cmdline of a shell wrapper: not a rewritten title of a browser, exe says bash. + proc = Proc(self.root) + proc.process_raw(100, b"/bin/bash -c /x/chrome --headless --remote-debugging-pipe\0", "/usr/bin/bash") + proc.process_raw(101, b"timeout 600 /x/chrome --headless --remote-debugging-pipe\0", "/usr/bin/timeout") + self.assertEqual(run(self.root)[1]["browsers"]["count"], 0) + + def test_one_browser_run_admits(self): + proc = Proc(self.root) + self.browser(proc, 100) + proc.process(101, self.PW, "--type=renderer", "--headless") + proc.process(102, self.PW, "--type=gpu-process", "--headless") + code, out = run(self.root) + self.assertEqual((code, out["browsers"]["count"], out["reasons"]), (0, 1, [])) + + def test_only_headless_cdp_driven_chromium_mains_are_browser_runs(self): + proc = Proc(self.root) + self.browser(proc, 100, None, "--no-sandbox", "--remote-debugging-pipe") # headed + self.browser(proc, 101, None, "--headless", "--no-sandbox") # no CDP + self.browser(proc, 102, "/usr/bin/firefox", "--headless", "--remote-debugging-port=9222") # not Chromium + self.browser(proc, 103, "/usr/bin/vim", "--headless", "--remote-debugging-pipe", "chrome") # name only in argv[1] + self.browser(proc, 104, "/usr/bin/google-chrome-stable", "--headless", "--remote-debugging-port=0") + self.browser(proc, 105, None, "--headless", "--remote-debugging-pipe", "--type=zygote") + code, out = run(self.root, "--browser-hold-at", "1") + self.assertEqual(out["browsers"], {"count": 1, "pids": [104]}) + self.assertEqual(code, 3) + + def test_browser_count_is_independent_of_the_heavy_build_count(self): + proc = Proc(self.root) + proc.process(10, "dotnet", "build") + self.browser(proc, 100) + self.browser(proc, 101) + code, out = run(self.root) + self.assertEqual((out["heavy"]["count"], out["browsers"]["count"]), (1, 2)) + self.assertEqual(code, 3) + + def test_tmp_headroom_is_reported_apart_from_disk_and_a_huge_floor_holds(self): + Proc(self.root) + code, out = run(self.root) + self.assertEqual(code, 0) + self.assertIsInstance(out["tmp_free_gib"], float) + self.assertEqual(out["tmp_path"], self.root) + self.assertIsInstance(out["disk_free_gb"], float) + code, out = run(self.root, "--min-tmp-gib", "1000000") + self.assertEqual((code, out["verdict"]), (3, "hold")) + self.assertEqual(len(out["reasons"]), 1, out["reasons"]) + self.assertTrue(out["reasons"][0].startswith("free %s " % self.root) and out["reasons"][0].endswith("GiB < 1000000.00 GiB"), out["reasons"]) + self.assertEqual(out["thresholds"]["tmp_free_gib_min"], 1000000.0) + + def test_tmp_headroom_boundary_is_exactly_3_gib_by_default(self): + import contextlib + import importlib.util + import io + from unittest import mock + spec = importlib.util.spec_from_file_location("fdev_lane_capacity_stub", PROBE) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + Proc(self.root) + real = os.statvfs + three_gib = 3 * 1024 ** 3 + + def at(free_bytes): + def statvfs(path): + if path == "/stub-tmp": + return mock.Mock(f_bavail=free_bytes // 4096, f_frsize=4096) + return real(path) + return statvfs + + argv = ["--proc-root", self.root, "--cgroup-root", self.root + "/cg", "--nproc", "12", "--disk-path", self.root, "--min-disk-gb", "0", "--tmp-path", "/stub-tmp"] + for free, code in ((three_gib, 0), (three_gib - 4096, 3)): + out = io.StringIO() + with mock.patch.object(module.os, "statvfs", at(free)), contextlib.redirect_stdout(out): + self.assertEqual(module.main(argv), code, out.getvalue()) + self.assertEqual(json.loads(out.getvalue())["tmp_free_gib"], round(free / 1024 ** 3, 2)) + + def test_unreadable_tmp_path_holds_as_unknown(self): + Proc(self.root) + code, out = run(self.root, "--tmp-path", self.root + "/does-not-exist") + self.assertEqual((code, out["verdict"], out["tmp_free_gib"]), (3, "hold", None)) + self.assertTrue(any(r.startswith("unknown: free /tmp space unreadable") for r in out["reasons"]), out["reasons"]) + + def test_unreadable_process_table_holds_and_reports_no_browser_count(self): + Proc(self.root) + code, out = run(self.root, "--proc-root", self.root + "/nowhere") + self.assertEqual((code, out["browsers"]), (3, None)) + + def test_negative_browser_and_tmp_thresholds_are_usage_errors(self): + Proc(self.root) + for flag, value in (("--browser-hold-at", "-1"), ("--min-tmp-gib", "-1"), ("--min-tmp-gib", "nan")): + code = subprocess.run([sys.executable, "-I", PROBE, "--proc-root", self.root, flag, value], capture_output=True, text=True, check=False).returncode + self.assertEqual(code, 2, (flag, value)) + + class LiveHost(unittest.TestCase): def test_runs_on_the_real_proc_and_prints_one_line(self): done = subprocess.run([sys.executable, "-I", PROBE, "--min-disk-gb", "0"], capture_output=True, text=True, check=False) diff --git a/tests/fdev-tmp-cleanup/run.sh b/tests/fdev-tmp-cleanup/run.sh new file mode 100755 index 000000000..571af0850 --- /dev/null +++ b/tests/fdev-tmp-cleanup/run.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +# Fixture for scripts/fdev-tmp-cleanup.py (.github#5240). Offline, credential-free, stdlib only. +set -euo pipefail +HERE="$(cd "$(dirname "$0")" && pwd)" +exec python3 -I -m unittest discover -v -s "$HERE" -p 'test_*.py' diff --git a/tests/fdev-tmp-cleanup/test_fdev_tmp_cleanup.py b/tests/fdev-tmp-cleanup/test_fdev_tmp_cleanup.py new file mode 100644 index 000000000..5f09870d6 --- /dev/null +++ b/tests/fdev-tmp-cleanup/test_fdev_tmp_cleanup.py @@ -0,0 +1,507 @@ +"""Fixture tests for scripts/fdev-tmp-cleanup.py (.github#5240). Offline; stdlib only. + +Each case builds a fake temp root and a fake procfs in a temp dir and runs the script as a subprocess. The +script is never pointed at the real /tmp here. Every "kept" case has a control that is removed under the same +conditions without the one protecting fact, so a script that deleted nothing, or everything, would fail. +""" +import contextlib +import importlib.util +import io +import json +import os +import subprocess +import sys +import tempfile +import time +import unittest +from unittest import mock + +HERE = os.path.dirname(os.path.abspath(__file__)) +SCRIPT = os.path.join(HERE, "..", "..", "scripts", "fdev-tmp-cleanup.py") +HOUR = 3600 +HEX = "0123456789abcdef0123456789abcdef" + + +def put(path, text): + with open(path, "w") as handle: + handle.write(text) + + +def load_module(): + spec = importlib.util.spec_from_file_location("fdev_tmp_cleanup_under_test", SCRIPT) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +class Fixture(unittest.TestCase): + def setUp(self): + tmp = tempfile.TemporaryDirectory() + self.addCleanup(tmp.cleanup) + self.base = os.path.realpath(tmp.name) + self.root = os.path.join(self.base, "tmp") # the swept root + self.proc = os.path.join(self.base, "proc") # the fake procfs + self.outside = os.path.join(self.base, "outside") # something the script must never touch + for d in (self.root, self.proc, self.outside): + os.makedirs(d) + self.now = time.time() + + # --- builders ------------------------------------------------------------------------------------------ + def make(self, name, age_hours=8.0, files=("a/b/c.txt", "d.txt"), mode_dirs=None): + """A directory tree under the root, every node last modified age_hours ago.""" + top = os.path.join(self.root, name) + os.makedirs(top) + for rel in files: + path = os.path.join(top, rel) + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, "w") as handle: + handle.write("x" * 100) + self.age(top, age_hours) + return top + + def age(self, top, age_hours): + stamp = self.now - age_hours * HOUR + for dirpath, dirnames, filenames in os.walk(top, topdown=False): + for name in filenames + dirnames: + path = os.path.join(dirpath, name) + os.utime(path, (stamp, stamp), follow_symlinks=False) + os.utime(dirpath, (stamp, stamp)) + + def process(self, pid, cmdline=(), environ=None, cwd=None, fds=(), maps=""): + base = os.path.join(self.proc, str(pid)) + os.makedirs(os.path.join(base, "fd"), exist_ok=True) + with open(os.path.join(base, "cmdline"), "wb") as handle: + handle.write(b"\0".join(a.encode() for a in cmdline) + b"\0" if cmdline else b"") + with open(os.path.join(base, "environ"), "wb") as handle: + handle.write(b"\0".join(("%s=%s" % kv).encode() for kv in (environ or {}).items())) + with open(os.path.join(base, "maps"), "w") as handle: + handle.write(maps) + if cwd: + os.symlink(cwd, os.path.join(base, "cwd")) + for number, target in enumerate(fds, 3): + os.symlink(target, os.path.join(base, "fd", str(number))) + + def write_status(self, pid, uid=None, comm="sleep"): + uid = os.geteuid() if uid is None else uid + with open(os.path.join(self.proc, str(pid), "status"), "w") as handle: + handle.write("Name:\t%s\nUid:\t%d\t%d\t%d\t%d\n" % (comm, uid, uid, uid, uid)) + with open(os.path.join(self.proc, str(pid), "comm"), "w") as handle: + handle.write(comm + "\n") + + def unix_socket(self, path): + os.makedirs(os.path.join(self.proc, "net"), exist_ok=True) + with open(os.path.join(self.proc, "net", "unix"), "a") as handle: + handle.write("Num RefCount Protocol Flags Type St Inode Path\n0000000000000000: 00000002 00000000 00010000 0001 01 12345 %s\n" % path) + + def run_script(self, *flags, apply=False, root=None, proc=None): + argv = [sys.executable, "-I", SCRIPT, "--root", root or self.root, "--proc-root", proc or self.proc, "--now", repr(self.now), *flags] + if apply: + argv.append("--apply") + done = subprocess.run(argv, capture_output=True, text=True, check=False) + lines = done.stdout.splitlines() + self.assertEqual(len(lines), 1, (done.stdout, done.stderr)) + return done.returncode, json.loads(lines[0]), done.stderr + + def exists(self, name): + return os.path.lexists(os.path.join(self.root, name)) + + def snapshot(self): + return sorted(os.path.join(d, n) for d, ds, fs in os.walk(self.base) for n in ds + fs) + + +class DeadRunCleanup(Fixture): + def test_dry_run_is_the_default_and_changes_nothing(self): + self.make("fsgg-sdd-tests-4242-" + HEX) + self.make("playwright_chromiumdev_profile-aB3dE9") + before = self.snapshot() + code, out, _ = self.run_script() + self.assertEqual((code, out["mode"], out["would_remove"], out["removed"]), (0, "dry-run", 2, 0)) + self.assertEqual(before, self.snapshot()) + self.assertGreater(out["would_free_bytes"], 0) + self.assertEqual({e["owner"] for e in out["removable"]}, {"pid 4242 (dead)", "no live reference"}) + # explicit --dry-run is the same + self.assertEqual(self.run_script("--dry-run")[1]["removed"], 0) + self.assertEqual(before, self.snapshot()) + + def test_apply_removes_a_dead_pid_run_and_only_it(self): + self.make("fsgg-sdd-tests-4242-" + HEX) + self.process(7, ["sleep", "1"]) + code, out, _ = self.run_script(apply=True) + self.assertEqual((code, out["mode"], out["removed"], out["failed"]), (0, "apply", 1, 0)) + self.assertFalse(self.exists("fsgg-sdd-tests-4242-" + HEX)) + self.assertGreater(out["freed_bytes"], 0) + + def test_a_live_pid_keeps_its_run_and_a_dead_pid_with_the_same_shape_is_removed(self): + self.make("fsgg-sdd-tests-4242-" + HEX) + self.make("fsgg-sdd-tests-4243-" + HEX) + self.process(4243, ["dotnet", "test"]) + code, out, _ = self.run_script(apply=True) + self.assertEqual(out["kept"], {"pid-alive": 1}) + self.assertFalse(self.exists("fsgg-sdd-tests-4242-" + HEX)) + self.assertTrue(self.exists("fsgg-sdd-tests-4243-" + HEX)) + self.assertTrue(os.path.exists(os.path.join(self.root, "fsgg-sdd-tests-4243-" + HEX, "a/b/c.txt"))) + + def test_young_runs_are_kept_and_the_age_threshold_is_exclusive_and_configurable(self): + self.make("fsgg-sdd-tests-1-" + HEX, age_hours=0.5) + self.make("fsgg-sdd-tests-2-" + HEX, age_hours=0.99) + self.make("fsgg-sdd-tests-3-" + HEX, age_hours=1.01) + code, out, _ = self.run_script(apply=True) + self.assertEqual(out["kept"], {"young": 2}) + self.assertEqual([self.exists("fsgg-sdd-tests-%d-%s" % (n, HEX)) for n in (1, 2, 3)], [True, True, False]) + code, out, _ = self.run_script("--min-age-hours", "0.25", apply=True) + self.assertFalse(self.exists("fsgg-sdd-tests-1-" + HEX)) + + def test_a_recent_write_deep_in_an_old_tree_keeps_the_whole_tree(self): + top = self.make("fsgg-sdd-" + HEX) + fresh = os.path.join(top, "a", "b", "c.txt") + os.utime(fresh, (self.now - 60, self.now - 60)) # touched a minute ago; every directory above is old + code, out, _ = self.run_script(apply=True) + self.assertEqual((out["kept"], out["removed"]), ({"young": 1}, 0)) + self.assertTrue(os.path.exists(fresh)) + os.utime(fresh, (self.now - 8 * HOUR, self.now - 8 * HOUR)) + self.assertEqual(self.run_script(apply=True)[1]["removed"], 1) + + def test_pidless_run_is_kept_while_any_live_process_references_it_by_any_route(self): + routes = { + "cmdline": dict(cmdline=["node", "{p}/driver/run-smoke.mjs"]), + "cmdline-flag": dict(cmdline=["chrome", "--user-data-dir={p}"]), + "environ": dict(environ={"TMPDIR": "{p}"}), + "cwd": dict(cwd="{p}/sub"), + "fd": dict(fds=["{p}/log.txt"]), + "fd-deleted": dict(fds=["{p}/log.txt (deleted)"]), + "maps": dict(maps="7f00-7f01 r--s 00000000 00:2e 99 {p}/mapped.db\n"), + } + names = {} + for index, (route, _) in enumerate(sorted(routes.items())): + name = "playwright_chromiumdev_profile-r%05d" % index + self.make(name) + names[route] = name + control = "playwright_chromiumdev_profile-ctrl00" + self.make(control) + for pid, (route, spec) in enumerate(sorted(routes.items()), 100): + path = os.path.join(self.root, names[route]) + filled = {k: ([v.format(p=path) for v in val] if isinstance(val, (list, tuple)) else + {kk: vv.format(p=path) for kk, vv in val.items()} if isinstance(val, dict) else val.format(p=path)) + for k, val in spec.items()} + self.process(pid, **filled) + self.unix_socket(os.path.join(self.root, "org.chromium.Chromium.sock01", "SingletonSocket")) + self.make("org.chromium.Chromium.sock01") + code, out, _ = self.run_script(apply=True) + self.assertEqual(out["removed"], 1, out) # only the control + self.assertEqual(out["kept"], {"referenced-by-live-process": len(routes) + 1}) + self.assertFalse(self.exists(control)) + for route, name in names.items(): + self.assertTrue(self.exists(name), route) + self.assertTrue(self.exists("org.chromium.Chromium.sock01")) + + def test_a_reference_to_a_different_root_or_a_name_prefix_does_not_protect(self): + self.make("fsgg-sdd-" + HEX) + other = os.path.join(self.base, "elsewhere", os.path.basename(self.root), "fsgg-sdd-" + HEX) + self.process(9, ["cat", other, self.root + "-2/fsgg-sdd-" + HEX, self.root + "/fsgg-sdd-" + HEX + "0"]) + self.assertEqual(self.run_script(apply=True)[1]["removed"], 1) + + def test_only_known_harness_names_are_matched(self): + keep = ["tmp.abcdefghij", "tmp.abcdefghij2", "fsgg-gate-engine", "fsgg-gate-nightly", "fsgg-sdd-tests-xx-" + HEX, "fsgg-sdd-" + HEX[:-1], + "fsgg-sdd-" + HEX.upper(), "playwright_chromiumdev_profile-", "playwright-artifacts-abcdef", "org.chromium.Chromium", "work-827", + "playwright_chromiumdev_profile-abcdef-more", "fsgg-tok-123", "some-user-data", "fsgg-sdd-" + HEX + ".bak"] + for name in keep: + self.make(name) + self.make("fsgg-sdd-" + "a" * 32) # the one real match, as a control + code, out, _ = self.run_script(apply=True) + self.assertEqual((out["entries_matched"], out["removed"]), (1, 1)) + self.assertFalse(self.exists("fsgg-sdd-" + "a" * 32)) + for name in keep: + self.assertTrue(self.exists(name), name) + + def test_a_browser_smoke_tree_needs_its_fingerprint(self): + self.make("tmp.ABCDEFGHIJ", files=("driver/run-smoke.mjs", "js/index.html")) + self.make("tmp.0123456789", files=("driver/package.json",)) # no run-smoke.mjs + self.make("tmp.KLMNOPQRST", files=("js/index.html",)) # unrelated mktemp + os.makedirs(os.path.join(self.outside, "driver")) + put(os.path.join(self.outside, "driver", "run-smoke.mjs"), "") + os.makedirs(os.path.join(self.root, "tmp.zzzzzzzzzz")) + os.symlink(os.path.join(self.outside, "driver"), os.path.join(self.root, "tmp.zzzzzzzzzz", "driver")) # a symlinked driver is no fingerprint + self.age(os.path.join(self.root, "tmp.zzzzzzzzzz"), 3) + code, out, _ = self.run_script(apply=True) + self.assertEqual((out["entries_matched"], out["removed"], out["by_pattern"]["browser-smoke"]), (1, 1, {"matched": 1, "removable": 1})) + self.assertFalse(self.exists("tmp.ABCDEFGHIJ")) + for name in ("tmp.0123456789", "tmp.KLMNOPQRST", "tmp.zzzzzzzzzz"): + self.assertTrue(self.exists(name), name) + self.assertTrue(os.path.exists(os.path.join(self.outside, "driver", "run-smoke.mjs"))) + + def test_a_live_browser_smoke_is_kept_through_its_command_line(self): + self.make("tmp.ABCDEFGHIJ", files=("driver/run-smoke.mjs",)) + self.process(55, ["node", self.root + "/tmp.ABCDEFGHIJ/driver/run-smoke.mjs", "--headless"]) + code, out, _ = self.run_script(apply=True) + self.assertEqual((out["removed"], out["kept"]), (0, {"referenced-by-live-process": 1})) + + def test_a_symlink_entry_is_never_followed_or_removed(self): + target = os.path.join(self.outside, "precious") + os.makedirs(target) + put(os.path.join(target, "keep.txt"), "keep") + os.symlink(target, os.path.join(self.root, "fsgg-sdd-" + HEX)) + code, out, _ = self.run_script(apply=True) + self.assertEqual((out["removed"], out["kept"]), (0, {"symlink": 1})) + self.assertTrue(os.path.islink(os.path.join(self.root, "fsgg-sdd-" + HEX))) + self.assertTrue(os.path.exists(os.path.join(target, "keep.txt"))) + + def test_symlinks_inside_a_removed_tree_are_unlinked_not_followed(self): + precious = os.path.join(self.outside, "precious") + os.makedirs(precious) + put(os.path.join(precious, "keep.txt"), "keep") + put(os.path.join(self.outside, "file.txt"), "keep") + top = self.make("fsgg-sdd-tests-4242-" + HEX) + os.symlink(precious, os.path.join(top, "to-dir")) + os.symlink(os.path.join(self.outside, "file.txt"), os.path.join(top, "a", "to-file")) + os.symlink(self.outside, os.path.join(top, "a", "b", "to-outside")) + os.symlink("/nonexistent/dangling", os.path.join(top, "dangling")) + self.age(top, 3.0) # the links and the directories that now hold them are old too + code, out, _ = self.run_script(apply=True) + self.assertEqual((out["removed"], out["failed"]), (1, 0), out) + self.assertFalse(self.exists("fsgg-sdd-tests-4242-" + HEX)) + self.assertTrue(os.path.exists(os.path.join(precious, "keep.txt"))) + self.assertTrue(os.path.exists(os.path.join(self.outside, "file.txt"))) + + def test_read_only_trees_are_removed(self): + top = self.make("fsgg-ai-tests-" + HEX, files=("objects/ab/cd.pack", "objects/ef.pack")) + for dirpath, dirnames, filenames in os.walk(top): + for name in filenames: + os.chmod(os.path.join(dirpath, name), 0o444) + for dirpath in (os.path.join(top, "objects", "ab"), os.path.join(top, "objects")): + os.chmod(dirpath, 0o555) + code, out, _ = self.run_script(apply=True) + self.assertEqual((out["removed"], out["failed"]), (1, 0), out) + self.assertFalse(self.exists("fsgg-ai-tests-" + HEX)) + + def test_files_and_directories_that_are_not_directories_are_kept(self): + put(os.path.join(self.root, "fsgg-sdd-" + HEX), "a file with a harness name") + code, out, _ = self.run_script(apply=True) + self.assertEqual((out["removed"], out["kept"]), (0, {"not-a-directory": 1})) + + def test_an_entry_owned_by_someone_else_is_kept(self): + module = load_module() + self.make("fsgg-sdd-tests-4242-" + HEX) + out = io.StringIO() + argv = ["--root", self.root, "--proc-root", self.proc, "--now", repr(self.now), "--apply"] + with mock.patch.object(module.os, "geteuid", return_value=os.geteuid() + 1), contextlib.redirect_stdout(out): + self.assertEqual(module.main(argv), 0) + report = json.loads(out.getvalue()) + self.assertEqual((report["removed"], report["kept"]), (0, {"not-owned": 1})) + self.assertTrue(self.exists("fsgg-sdd-tests-4242-" + HEX)) + + def test_an_entry_a_process_picks_up_after_the_survey_is_kept(self): + module = load_module() + top = self.make("fsgg-resolver-" + HEX) + real = module.live_references + calls = [] + + def racing(proc_root, roots, own_pid): + calls.append(1) + names, stats = real(proc_root, roots, own_pid) + if len(calls) == 2: + names[roots[0]].add("fsgg-resolver-" + HEX) # a process started using it after the first read + return names, stats + + out = io.StringIO() + argv = ["--root", self.root, "--proc-root", self.proc, "--now", repr(self.now), "--apply"] + with mock.patch.object(module, "live_references", racing), contextlib.redirect_stdout(out): + self.assertEqual(module.main(argv), 0) + report = json.loads(out.getvalue()) + self.assertEqual((len(calls), report["removed"], report["kept"]), (2, 0, {"referenced-by-live-process": 1})) + self.assertTrue(os.path.exists(top)) + + def test_an_entry_modified_after_the_survey_is_kept(self): + module = load_module() + top = self.make("fsgg-resolver-" + HEX) + real = module.live_references + calls = [] + + def racing(proc_root, roots, own_pid): + calls.append(1) + if len(calls) == 2: + os.utime(top, (self.now, self.now)) + return real(proc_root, roots, own_pid) + + out = io.StringIO() + argv = ["--root", self.root, "--proc-root", self.proc, "--now", repr(self.now), "--apply"] + with mock.patch.object(module, "live_references", racing), contextlib.redirect_stdout(out): + module.main(argv) + report = json.loads(out.getvalue()) + self.assertEqual((report["removed"], report["kept"]), (0, {"changed-since-survey": 1})) + + def test_several_patterns_in_one_sweep_report_by_pattern(self): + names = ["fsgg-sdd-tests-1-" + HEX, "fsgg-sdd-" + HEX, "fsgg-ai-tr-" + HEX, "fsgg-cli-tests-cache-sandbox-" + HEX, + "playwright_chromiumdev_profile-Zz9Zz9", "org.chromium.Chromium.Ab12Cd"] + for name in names: + self.make(name) + code, out, _ = self.run_script("--list-limit", "2") + self.assertEqual((out["would_remove"], len(out["removable"]), out["removable_listed_of"]), (6, 2, 6)) + self.assertEqual(set(out["by_pattern"]), {"fsgg-sdd-tests", "fsgg-sdd-run", "fsgg-test-root", "playwright-profile", "chromium-temp"}) + + + def test_pidless_patterns_need_six_hours_and_pid_patterns_one(self): + for hours, name in ((5.5, "fsgg-sdd-" + "1" * 32), (6.5, "fsgg-sdd-" + "2" * 32), (1.5, "fsgg-sdd-tests-7-" + HEX), (0.5, "fsgg-sdd-tests-8-" + HEX), + (5.5, "playwright_chromiumdev_profile-aaaaaa"), (6.5, "playwright_chromiumdev_profile-bbbbbb")): + self.make(name, age_hours=hours) + code, out, _ = self.run_script(apply=True) + self.assertEqual((out["min_age_hours"], out["min_age_hours_pidless"], out["removed"], out["kept"]), (1.0, 6.0, 3, {"young": 3})) + self.assertEqual([self.exists(n) for n in ("fsgg-sdd-" + "1" * 32, "fsgg-sdd-" + "2" * 32, "fsgg-sdd-tests-7-" + HEX, "fsgg-sdd-tests-8-" + HEX, + "playwright_chromiumdev_profile-aaaaaa", "playwright_chromiumdev_profile-bbbbbb")], + [True, False, False, True, True, False]) + code, out, _ = self.run_script("--min-age-hours-pidless", "5", apply=True) + self.assertEqual(out["removed"], 2) + + def test_a_relative_word_resolves_against_the_process_cwd_and_a_symlinked_alias_is_a_reference(self): + self.make("fsgg-sdd-" + "1" * 32) + self.make("fsgg-sdd-" + "2" * 32) + self.make("fsgg-sdd-" + "3" * 32) + self.make("fsgg-sdd-" + "5" * 32) + elsewhere = os.path.join(self.base, "elsewhere") + os.makedirs(elsewhere) + os.symlink(os.path.join(self.root, "fsgg-sdd-" + "2" * 32), os.path.join(elsewhere, "alias")) + self.process(10, ["node", "fsgg-sdd-" + "1" * 32 + "/driver/run.mjs"], cwd=self.root) # relative, cwd is the root + self.process(11, ["tail", "-f", os.path.join(elsewhere, "alias", "a", "b", "c.txt")]) # symlinked alias + self.process(12, ["node", "../tmp/fsgg-sdd-" + "3" * 32 + "/x.mjs"], cwd=elsewhere) # relative with .. + self.process(13, ["cat", "alias/d.txt"], cwd=elsewhere) # alias, relative + self.process(14, ["cat", "--file=" + os.path.join(elsewhere, "alias") + "/d.txt"]) # flag value through the alias + code, out, _ = self.run_script(apply=True) + self.assertEqual(out["removed"], 1, out) # only the unreferenced one + self.assertFalse(self.exists("fsgg-sdd-" + "5" * 32)) + for n in "123": + self.assertTrue(self.exists("fsgg-sdd-" + n * 32), n) + + def test_a_same_user_process_that_cannot_be_inspected_blocks_apply_even_if_its_cmdline_reads(self): + if os.geteuid() == 0: + self.skipTest("root can read everything") + self.make("fsgg-sdd-tests-4242-" + HEX) + self.process(30, ["sleep", "1"]) + self.write_status(30) + environ = os.path.join(self.proc, "30", "environ") + os.chmod(environ, 0) + self.addCleanup(os.chmod, environ, 0o600) + before = self.snapshot() + code, out, err = self.run_script(apply=True) + self.assertEqual((code, out["mode"]), (3, "refused")) + self.assertIn("could not be inspected", err) + self.assertIn("30", err) + self.assertEqual(before, self.snapshot()) + # a dry run still reports the removable entry and says apply is blocked + code, out, _ = self.run_script() + self.assertEqual((code, out["would_remove"], out["apply_blocked"], out["unreadable"]), (0, 1, True, [{"pid": 30, "comm": "sleep"}])) + # the fd directory is read the same way + os.chmod(environ, 0o600) + fd_dir = os.path.join(self.proc, "30", "fd") + os.chmod(fd_dir, 0) + self.addCleanup(os.chmod, fd_dir, 0o700) + self.assertEqual(self.run_script(apply=True)[0], 3) + + def test_the_allowlist_a_vanished_process_and_other_users_processes_do_not_block(self): + if os.geteuid() == 0: + self.skipTest("root can read everything") + self.make("fsgg-sdd-tests-4242-" + HEX) + for pid, comm, argv in ((31, "(sd-pam)", ["(sd-pam)"]), (32, "sshd-session", ["sshd-session: dev"]), (33, "systemd", ["/usr/lib/systemd/systemd", "--user"])): + self.process(pid, argv) + self.write_status(pid, comm=comm) + os.chmod(os.path.join(self.proc, str(pid), "environ"), 0) + self.addCleanup(os.chmod, os.path.join(self.proc, str(pid), "environ"), 0o600) + self.process(34, ["sleep", "1"]) + self.write_status(34, uid=os.geteuid() + 1) # another user's process: the scan owes nothing about it + os.chmod(os.path.join(self.proc, "34", "environ"), 0) + self.addCleanup(os.chmod, os.path.join(self.proc, "34", "environ"), 0o600) + self.process(35, ["sleep", "1"]) + self.write_status(35) + code, out, _ = self.run_script(apply=True) + self.assertEqual((code, out["removed"], out["unreadable"]), (0, 1, []), out) + + def test_a_systemd_that_is_not_the_user_manager_is_not_allowlisted(self): + if os.geteuid() == 0: + self.skipTest("root can read everything") + self.make("fsgg-sdd-tests-4242-" + HEX) + self.process(40, ["/usr/lib/systemd/systemd", "--system"]) + self.write_status(40, comm="init-ish") + os.chmod(os.path.join(self.proc, "40", "environ"), 0) + self.addCleanup(os.chmod, os.path.join(self.proc, "40", "environ"), 0o600) + self.assertEqual(self.run_script(apply=True)[0], 3) + + def test_a_tree_deeper_than_the_recursion_limit_is_removed(self): + top = os.path.join(self.root, "fsgg-sdd-tests-4242-" + HEX) + os.mkdir(top) + path = top + for _ in range(1100): + path = os.path.join(path, "d") + os.mkdir(path) + with open(os.path.join(path, "leaf.txt"), "w") as handle: + handle.write("x") + os.symlink(self.outside, os.path.join(path, "out")) + stamp = self.now - 8 * HOUR + walk = top + os.utime(top, (stamp, stamp)) + for _ in range(1100): + walk = os.path.join(walk, "d") + os.utime(walk, (stamp, stamp)) + os.utime(os.path.join(path, "leaf.txt"), (stamp, stamp)) + os.utime(os.path.join(path, "out"), (stamp, stamp), follow_symlinks=False) + self.assertGreater(sys.getrecursionlimit(), 0) + code, out, _ = self.run_script(apply=True) + self.assertEqual((code, out["removed"], out["failed"]), (0, 1, 0), out) + self.assertFalse(self.exists("fsgg-sdd-tests-4242-" + HEX)) + self.assertTrue(os.path.isdir(self.outside)) + + def test_it_refuses_to_run_as_root(self): + module = load_module() + err = io.StringIO() + with mock.patch.object(module.os, "geteuid", return_value=0), contextlib.redirect_stderr(err): + self.assertEqual(module.main(["--root", self.root, "--proc-root", self.proc, "--apply"]), 2) + self.assertIn("not root", err.getvalue()) + + +class Refusals(Fixture): + def test_an_unreadable_process_table_refuses_and_removes_nothing_even_with_apply(self): + self.make("fsgg-sdd-tests-4242-" + HEX) + before = self.snapshot() + code, out, err = self.run_script(apply=True, proc=os.path.join(self.base, "no-such-proc")) + self.assertEqual((code, out["mode"]), (3, "refused")) + self.assertIn("nothing was removed", err) + self.assertEqual(before, self.snapshot()) + + def test_roots_that_are_symlinks_home_or_slash_or_missing_are_refused(self): + link = os.path.join(self.base, "link") + os.symlink(self.root, link) + for root in (link, "/", os.path.expanduser("~"), os.path.dirname(os.path.expanduser("~")), os.path.join(self.base, "missing")): + done = subprocess.run([sys.executable, "-I", SCRIPT, "--root", root, "--proc-root", self.proc, "--apply"], capture_output=True, text=True, check=False) + self.assertEqual((done.returncode, done.stdout), (2, ""), root) + self.assertIn("refused", done.stderr) + + def test_apply_and_dry_run_are_mutually_exclusive_and_bad_ages_are_usage_errors(self): + for flags in (["--apply", "--dry-run"], ["--min-age-hours", "-1"], ["--min-age-hours", "nan"]): + done = subprocess.run([sys.executable, "-I", SCRIPT, "--root", self.root, "--proc-root", self.proc, *flags], capture_output=True, text=True, check=False) + self.assertEqual(done.returncode, 2, flags) + + def test_default_roots_are_tmp_tmpdir_and_the_fsgg_cache_and_absent_ones_are_skipped(self): + module = load_module() + with mock.patch.dict(os.environ, {"TMPDIR": "/var/tmp/x"}): + self.assertEqual(module.default_roots("/home/dev"), ["/tmp", "/var/tmp/x", "/home/dev/.cache/fsgg-tmp"]) + with mock.patch.dict(os.environ, {}, clear=True): + self.assertEqual(module.default_roots("/home/dev"), ["/tmp", "/home/dev/.cache/fsgg-tmp"]) + home = os.path.join(self.base, "home") + cache = os.path.join(home, ".cache", "fsgg-tmp") + os.makedirs(cache) + out = io.StringIO() + with mock.patch.object(module, "default_roots", lambda h: [os.path.join(home, "absent"), cache]), contextlib.redirect_stdout(out): + self.assertEqual(module.main(["--proc-root", self.proc, "--now", repr(self.now)]), 0) + report = json.loads(out.getvalue()) + self.assertEqual((report["roots"], report["skipped_roots"]), ([cache], [{"root": os.path.join(home, "absent"), "reason": "absent"}])) + + +class LiveHost(unittest.TestCase): + def test_dry_run_on_the_real_proc_against_an_empty_root_matches_nothing(self): + with tempfile.TemporaryDirectory() as root: + done = subprocess.run([sys.executable, "-I", SCRIPT, "--root", os.path.realpath(root)], capture_output=True, text=True, check=False) # dry run: --apply may be refused by a host process + self.assertEqual(done.returncode, 0, done.stderr) + report = json.loads(done.stdout) + self.assertEqual((report["entries_matched"], report["removed"]), (0, 0)) + self.assertGreater(report["processes_read"], 0) + + +if __name__ == "__main__": + unittest.main()