In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Lemmings Follow Terrain

Lemmings Follow Terrain:
Efficient renderer and manager for multiple sprites.
Animated bitmaps with variable framerates & a single
enterframe to control everyone.
Runs @60 fps under 1.3ghz Atom @1000 lemmings
Runs @45 fps (Froyo 2.2) under Android Snapdragon 1 Ghz @1000 lemmings
Update 2011: runs @50 fps (Froyo 2.2) with vector casting - gained 5fps!
@by Hasufel 2010-2011
/**
 * Copyright Hasufel ( http://wonderfl.net/user/Hasufel )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/cNNW
 */

package {
    //*******************************************************
    //Lemmings Follow Terrain:
    //Efficient renderer and manager for multiple sprites.
    //Animated bitmaps with variable framerates & a single
    //enterframe to control everyone.
    //Runs @60 fps under 1.3ghz Atom @1000 lemmings
    //Runs @45 fps (Froyo 2.2) under Android Snapdragon 1 Ghz @1000 lemmings
    //Update 2011: runs @50 fps (Froyo 2.2) with vector casting - gained 5fps!
    //@by Hasufel 2010-2011
    //*******************************************************/
        
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.utils.ByteArray;
    import flash.utils.getTimer;
    import flash.utils.Timer;

    import net.hires.debug.Stats;

    [SWF(width=465, height=465, backgroundColor=0,frameRate=60)]

    public class LemmingsFollowTerrain extends Sprite {
        private const _stageW:uint = stage.stageWidth;
        private const _stageH:uint = stage.stageHeight;
        private const _graphicsData:Array =["47494638396130000a0091030000b5005a63ffffefdeffffff21f90401000003002c0000000030000a000002759c6f308aedadd883a0269b16c2ab327f449b540921605e24faa167daad8224d4470dbb09bedb06bf0b01078200a278f4118d37e6cf4954229b4d670d3a350460832dc24b0d2f8da6a23580857a53602d17fd255fe15ab59d5887d1c707381b4d06c864d64756e7277803239502c4a80819d5685200003b",
"47494638396130000a0091030000b5005a63ffffefdeffffff21f90401000003002c0000000030000a000002779c3f90c8ddaa9c0334267a60b69563a381d6207ca45981a5b51ead1801af40bbb5cbd2115d1a3cd2f3e90e0101a26833129506e43279640e9c4d6a91492505805b57b729751a03d6325669147cb5dc6377fc255fab6edff4ab5e93dde87b757f47a624680728d77588264592a6c868f708d42814295000003b",
"47494638396118000a0091030000b5005a63ffffefdeffffff21f90401000003002c0000000018000a000002411c3c6997c7fd00104a5278571ea2b77e4d9e012a41a00c67ba722a0a9e9e20737430d7494bad57bb43998441d78b457c8d6a1d9987494b455952e126714d691505003b",
"47494638396118000a0091030000b5005a63ffffefde00000021f90401000003002c0000000018000a00000240dc7076a8c8ab86006f56aaac113c73c64ddba7044164a2a734a4a1d909b02407f16ca4ac9bafbdba69f984409a4ea2e3c004c81333d781a282ad67e4cac25e0b003b",
"474946383961d101d101d50000216321739c005001005002008132038484844f0100f5d6d63b3df031b500f5d6d53c3df0823203a253003c3ef063637531b600f6d7d6f6d6d663637482330462627432b600424253b485003b3def424254a35400a35300823303626374414153b38500ce7300ad52106300009c311000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021f90400000000002c00000000d101d1010006ffc0917038221185c6a2886414898ecb1029141251abcb2255c9ec56b1cbe957dafc2647ce67b2eba43e89246b95393476edf83097195ec7ef575545717264744969712123552561605d686e5e568a84574f734e84677570916f745695436945487c726f75aa749f839c76a74c605c7aa862818b485fa6a747709fa2a892a442a67e978270ad7868b0a359b364c09d77cf83c552a54ebfb36c84a1ae48dec0b67168a18563a46e4bdd8f89a29383b57fb7b0ba5bbcd1abc1de679abc791730dc9839b4d649e9564a8c9c12104be4ea23c48dbb8358c42842e22422c4576cf4c84ad8edde382ffaeaf4621810d63d967626f11188668a423783da50b986c8dfa1ff5487bed9235830572095fdc8717b790b1c48a023eb21235a27d9bb92ae3a7922678de8a62117033934a506532446636222fc93ae26464c390b9dfda6742eb927f85ca569a3d3a2948c9bd204f208f1af482516df255ef8970d61c2df66fa3a24932d3c9bfa04a5bac253d85535b462aea37305add1b56f091189a2d9e567620e9d5e7e8b73f3ce483d6b26f44884371ec930b5accd327b15a7af53e82a15b606ef1f45bb30ad94be574409c341a193c2ccd948e99dbafaa4f6b7dc25b679c6d2a9c115ae0d4935d5433c7eecb3fd96459598448c34ff31aed75e88269677f7fd1588780aa9564d605924779b42c4f98549340782c7a041a541134e3e027687ffd622e01d48892e0a1ee31015fdcdf7df86016a311a81201a921024c9d9b5e035ea6dc2063b2485178a47f5edf5607865bcc5d73a72d8240d6c50cd22554954a172a1758ed8c4493129d2074d465c9141659629b272554ca6416796244652289d6163ea38a33c7e2979e65895b597df50424624e6950e7a49249a10aa1927609f85000000f281c91b47636a5126844522f91e28b869755760e7e8c4d783a3cc715047406eb9495a58cc19561f711c7a28197846c6146c9511e7dc425f12860e09873aa7286422e41a4e5633ed9a2220fdd0426a5f0d9e7a477cef2951dda4f3a056c9b48564d2e63b1045d1e8288f114be3a0c8aaa5e9b242366ba7aac27ae4ff2d9cc7568bde36c794c41e2c5c55b5472a0ce2b5d83b685648827f8161882063ca08a2c93b8706a0aa95bd96b12232a1b938e0878cd49a65c2e93eb6b07e900d91717ff1b809e88896205bf171d856797019544e74965f9b4ea891158cf677eb3135810c6da424530bd7ca8165cb7084541efab1d04a52d40c661b991b25877774360b729a1cec631f7ab0c6ad967d14a64aa732ef44b3b311290c80c2b79eeddc9e543ffaa72a890aabf0d11e194df7d12ebb0233d8eeccbc0b21739760b644eb3db30444ab5a3912dc8af542b021166b1c80d9810f6b96deecf09d91d87f838a780010dd6cf8bf9fdf9d77127b6324ae6cb33e24b293a710755aeaf60475ff5f37e9328e8e3696404e18e867db5d82f0a18fc86e92a5d2e350c6a0df5dbaf31f63b77862da995109e409073f79f367d7ddfce76a7f32d07d9274b11f1dbbaa9abda2d24f4d3de38fb3d17d44f3833f390084d57f74fb76e80ef736dcb90dc5c093ade06403678861c7a764268b51342d6342da4545cc573c23cc077feb1bdef780b4b391cda86485c818fea0a73fe8a5eb50e2130c88cac73189e06a841a1ce1fd34b841fd254c61a051844fb4c0071262b0728a0a920a19c14212cc8d3f67ab610d93483c0d9ad01129d40911afe72711016a30fba90b40d4a240eae8682b081c41f4bee2a41e0a6b84c1c3200c6d7539d4650e23a39282084d58c227a6ffef503b0280346262c6bad91071c3a3e1efbe87b18f042c872b12e3ddd0b8c65de5301a6be0611c0019c81f6e507084ace3f34cf8482e4d63466c3255f220630d4be9f02660085829ca9131463525581f6362f052c4bf043a107e96b0e3092fa94b30052f306a7be51fe60344fad1af9893435c097da51fd27de4088b64e4d1f4481079ac287fc76c643287a7c9b2e9321d4c0196767a46ab9ff9e737bfa9474d6ef2356021e414e9720929df30cd1b76337f5194c3140d114867f6124cbcfc677fd258932696a037c45494419328483f6e5008fe5124ddec66d0f4a10100b88a284453b4d06432344501bddb13f0e8cf6756e46b7064cd46ba559565f9a12fff89a1c84b71235145e5ec9c258d651243aab12260145164e4e324b929d05df1b4a8f49ba513a7a9d00b72739bbf6b644d3fe243654ef486ce6b2420b17ab17fa20b4cfe5b4cef5a7850734083253075535e54738d7892554f16ccaaf6ce78c3cf88f3704a452a47f5eacbc155b4a9240c292f37fa4c3afe309a5015e83d8de955adce272b608387009d590e9708246a9e22c85a5841a3b782a908e79cea34ef77d4fc2591828b82681af9ba57d60ef47e7975ad69071a51de3cd16c7f356a621b2b5bc909cb44a9cc085b4967d6d8cd44376e4944e198d10bfeb4d2a465b563324b3bc8a3cab298bdcdaec6ec495dbd3a96927aa2aa78a1e757e70d0ea9df75ffed6279a5c0afb889b8664d275f7e55cd033647533ba1db01094b5e0c322fb7dc541576b54be0a46eafc0fa0d2f7f273ac3f42aeabc08f66e77f5a4422cb49463f4fac57093f705dde4651515b6897e6fa1cbb939f831101ee80f4f1c61d6666fc22d1e2f55452bc2f2de6dc031b6e37a17552d4df4e409cffc094dc87324cb18873d9bea632bd1d74b13ff17b000ce315f9908e3164f15a2343e210c590c522e4bf9683076d6915689d09c44ad1ad6c8064d0b5231c6dded174df6b247709c54ab7eb9c0d3bd7396ae1cde68ea58cf029d302f7e35bab3844e3de3b88b864b6106d8fc0759713b1a3c4b2c67c65e4c9a80ceae9333fd595d46f98c9cf6f46fffc51154cca4c1855939c271cbe39e542b4531ad809ec7745c69f07214d3a166eda673edda2a8394d7746c655c9e6195505cb87f82c1dc556ee387d5242f7292ce3253c17cc7a5021ba9bbbe367affac6dd94e61431a76359a8b31e685d8d281f312f3434c38eb604f1ba0eaeb7651e92cef27d69ab6f5d6abba97910a13a93a53f86d5cc100d852bc6cca8e0b2630976d9c6fe9debbe1807537c4ff790cea186b0b63a30b8624a4430371492f8948477e112e6df52ab4c113b7f7c353cef27cab072e1fa29971e45b918b146cbe7bf8858e04437160af76e52d0f64d0874e740ab7b75f03292e3778b429f78401554f776fa49f5872290b0fe82dc77ad1b72eff65e00a49e45bd89d3944a1c2c074871a0d4259287b9970407f9aeb708f7bd0219b3931d322be0657c61fccf2de3c0417136c6ffb9ddf2ef7c21bbedb2131d3dee181e5baaccd5806a71e2ee202d349b0fda0c0f6f5e137cff9ae87c6653a19899ece018aa807777751875f5a2e5ff51c6bbdf3b08fbd5e17df29b32f83b01c814abf2fc138d748283c819771a65f2ffbe21b5fd6a70c5b5f088b08578d035930e94478bed0f33e739af8c7cfbef6c15430534fe440a30fa37a72cf37f2ec97883fb9fcf6d7cffed80ba76f9388ec26c25fafd52c7d2f912cdc193a15d7f6fbffff00a82e6a421cc971245b635268c607c4960800c416ac961ffd1780123881ffc68712b6870aa9148165b51a49765f90956c6eb46cfc44812458829b970f0cb11ccf015a11455fee6022ced10f16666edae14026788338c875127364b1e30d2a422e9c4180a2203055534e9cd17a3998844aa86de7712552d11ff1c27bb7772915c2395494114b98855a986fcf1183f182228f551db5b71e6c5073a57273e8b6856ab886a11612d0c00560381fca45224dd00931b36c14324c6cb8877cd862fd230bce6605c3b2212b210deb1141b6c72a4cd6878cd888ac752b32257282f85823612673e00d0c2236a0d7358ed8899e6847b81176a081451d538666c82fd6047960876e83f089aef88a1f33264de04ad4d7825bc1127d930d3bd70fd32278ffb0f88bc0785025e23e80c7520d111f41884e50125982108ccef88c1f412e31581a3f685915c37439f47cd5823bd0d88dc0a861a1172f34a6823c64110a182fead071388184ded88e5ba866ace10e9eb328d710837d018864268921e78efce8888e627b9d328ee8241907514a0a081fa39204fdb8907b281cba412a39b581ac701c32818e66e081cdc7901af98e223121fc0285e6d06a41318716b64e1e16911b999214084e65f13e28d952f6628ddd278497e5592a7993000887395191282991f87840c8d174ffc6163d899346a97dceb208e984197bf60ac5001442120d914180475995fec7223cb11b4d291021e67b1393053b010b563996482926b8e00eff365571635887a65088cd0795641997c6c79258334a9ff5877291763b39271ca88174d3000c800104309802300003600006300002509802909886d99806d0988759988a19998a49992540000620979ce93cf45223e0b795abd44ea61873e8200f8b083d18400118d00083c9000c400014709995e99894599889d9988cf9988689989929009d199c19b32cce52307bb6946d4110b7180ab938694f249820b0010de09ab1399804109b0cb098da69988f6999b7a99dda999903209ce469538b230688016d41068867318b3018419a980dba34980a50011690001000010880000bc09f0e9001fb19a0fbb9000b70000710010aa000078aa001ba0005300183599eff120a8551137ada12264a800dee5117d7e03807c3087ee93c83790005709f10b00009e0002a8a000eb0002adaa22d9a012eea001180a0082a012cba9f05f00017309e13faa3fbe11cf7406cdf86a1385383e2c647e6880e61a94b8549000520010500010950a5fb9900fc69a007800032da9ffeb90008aa00fcd99f0e500015a00104a09840faa3528217e146087b5697a3312ff6281739c18e8ab298ae5900249a9f297a9f07a00010a0a512b0a504daa2061a01038a0024caa303c0006abaa612fa6d9331792cf85992b80fc7760f05b94e40f64487e99a50aa000550a5f8799f0a9000851aa809eaa2817a002d8a0061faa01af0a48529a9e5b96fa43610ff45397abe400caae677efb410217a348a29aaa35aaaa64aa5557aa0acea000720010abaaa1220a513f001693a009ab999b82a9c15473d462109bb520dc4b61cfcf7996d56ac1fa3a783b901501a01536a01264aa5839a001160a00a1aad0a20ad8d7a010200a9024000b7daadde5a616f201d68209ae2d3124b5729a57738a02a00a24a9d515a00167bb1189bb11acba3699aa6017b98041b9cdad00b48770c202993e512827a07729d60478de99a1de09a0d20000f500115f0000f3001399bb3133001368bb30fe001385b0117d0a302ebb11e1bb29ce9758201764a6931f1c532e506891781355781a76072acd70998334b00221ab002400188399bc0a9b4ff6449775f637753905a9e601265578403e71de9d44b8539b1da1ab0cec30006a0b7649bad667bb650998c16464ff4e70c1b5790fc2733ee75074e3a00769b9d5e7b379a99a6002bb03efab755590f172782a257b83417733e53b5044294ce69428ac9011dfbb1914b37d9399b96ebb7985b95b4b712da8150f467567728854e371667a64b86d9008679b4ff9ab7602bb0605bb6b16b94e9b98d72b20f464a0c88d8388a388b5e7153a6abad8a29bcab7b34933b00b36900b09bbc37d97dcdb5266e70b21c41979ac87714d1835f84b5fdb1989af9af010bbe79fba8d8abad9129be37f97e9b53355f03b1a195a169871301970caf9690a0bab79179b4de9bb7ffe00bb6e09b98fcab92c9778951a08f07588ab2539306d88be084081908bf8f9198d9aabd221ac1276c98153cbedab2968cf3a92d1875e49294bd3720e5e78bc2029e8b7999c87b343dac9b97c9ad2dbc919abb89f228c3b672a496b57fdb682d19f2c424ac281a50c4e29b7879c9bbf3c8b6fe3019b00673d532b2a330c559f200569cbc68fb82496207e80b3bf9f8c130d20da747b8ba3401679cbc4c5b64c3f5bcc17a9076e725eea53ba870c7843c62ed252b8ccbc72f971f8ca21722b777f1c789853cc9a3067dc796962e5892a838127d2317dfa6ae941ccacfd463ca397ee61912c9a81b5ad10a4d372dbd2aca93acab20064d69998963fc0fa06b84ffa59205b0dccbf4482bc4a1ca0aa9287632865359858c7185f3e7cbbddc84a55688c242921e42806f2b703005cacc5cc45d6892ab08a7bb822fd718728603063348b5bbfccad97cc5bba780908c85c45c89920210295b739c6b93e9accd5c50596bd97aff0116f187686606468f9c9af77cc7904853adbcc52a0210e2281c64d48391a496db50d0931c8a4f5b0f22f2ca7668276211cc31c9157840d1932c8be7211832a7d0a175661e7ab54bf26fc529d2b13c8cfd93d1978aa12df16d4b0a1a3591618c26c0307dc7ae711985d010980c0a9e6aa764986803b1c13f7dc6e098240d3dccc7d9c45f1c962ecd813ad1d4850c8f46f12c4adcc6b6c02f6dabcaffc0e0335a4dc8ffd8380199c8985ad64ef9148f9632676dc50e190fe00188e30aac9ea07f3d0d2f1a327273ddc2c8351198021abf5559ab560e22691ecf11d8828d29dfd7c1af7c6cfba66c2b7b16aae0d815ac937cc09367a0c8d04bce726ccef3f5636babd9e29b9491b183edd631c1e0b6079c24d7cc1e5780da570c310e5b9259f6dac88624416806329323596ddbb1cb0ce2a0c571e8da6a360cb98c8697888eeb40dc787c219d3d2e090bd6651d59baebca717110d28dc7a1e8bf7194d7f612bd8af7c95b1216dffdb7c4a9761632750bcd0aea4bacecabd2153289eb4db065c41acb5bdb0a7b9a7860c082ac21a8d408f9ddad9665a17282df8f3591ffa812c21f6c6e278316cc284707bea6003ea4a3787160dd8550879047a7b8ec84ce1b995ed827ca6d5aae67051df1fd6acee7c41ee9b4db009f063e96d9833f4b446f5a4da92c61a91da751ac86d5e4f729f4ec4097202738a93026a6e4dba33e37aee45b565426bea6ba9ae2c9a5d04ae7c66104c76057a1521777533e47b415e6b1a44c9473434dfe6250de60b125e606663439ee5827fe8d488710471159407e7e7d7c9a7f7ce4da882ff09d3eada5584eb565ab15e796d648372e380e852e889e2e50ce4d04815b66a30c4c0e5b675e39611ee9da93e66994e986aee329f972eb88b02af483e904051dd8c8226c0cf8d7e55dd5e838dee8b17e418a7ee8ff1041e99d0e5b9ffe629fcee69d2e604f9e46bdae3d27a64668c395c75d9cc943447fb1e6ba3eeb6f9e3d93be3d4aae0cc13eeca2de8f622c08618c742d3e6c7697b626a99777b5c8818ee3b3b4ebd10eeaa6353871be62d62eec7af407ec6ee9d02e4b9f3ee9681e00f8be534dcee40e163c88d166cbf59e6cd206685150d0ceeb671e3c64177dcc2e45203205f9ce6d4ef58e57aef0cb671ff10d1c419dcaedbb5f38621f8612ef4c5eed978eedb01543f3fee4fc6eedfe1e8e7b31799cd0ec151f02a4e5efca6ef3a342f120aaf3a425e74f9578776d8a0a927ac61606323fef4d5ff0f60005471e5c0bbf0401af55df453c8bfee8447583696c61bfc2e3ffd016d72c2b94af3d6e3dad0a9403e50216f1cb7ef340ffec4ecff339e2f32f4c3e7f718cd7f3751807f5c820f5ee41f5186744702eebfc501d88163527a11a08d905bf3ef372703646df1848cf104a7f174ca03e9c8eebb9aeed9efef0f93ee77287c582cb787161338a1f125109f61916d13aa78e561fed7e2f2fab31f57c8f1f461400b37ff09e9af03433f8498f2fc636f99f7c8ec1df1e989ffbf44e39616dd258335cdc9ce1ad60f74a72f8358f9a6796e28dcf04438fe99fafed007fe9578fe984977d47ccbe61d93fd6cb52d68468095287e3566c3d16f09343fc32a20ebc8afcc6452e1a010421d290241a8d8ac6916828722a494be2f0884c2e91ff4752e8f95c3aa7d36ad3684c120301403a700d778bc2ad5cc4150aebcc773224ac1e999cfc8a929eb8f4089daca4a0ca9afaf4d8d800f842d424030249d2d6d82a31393b01464b4a4d4f51535557595b5d5f615f090fedc0eab8feac4858ad10a7bc6ac100b1a28ac7a2686bd32a910ebbbe7cc5b4aeccc0889cbd9ec2888e15ab7d19b51c9102bb0e89ca1703c5a5e2b88aa98afeb6a7fa7ef31ef37211fbe4e4c9a1dcb325c75e9c3a5b0c6e2b07695a3130c9d479d105708ba010232ede09452a56478f1f41862c452ed9b992638ef05a1426cba37e4cb2005212f39e9d26142166ac88ce4d9475e4daddd2d3250fa274547eca1b0a69089e77dcde683bff3827df9d847b2ce69a374f229525906ecd39e7558a3d5adbe6d16bea8fcf527d7ff815dcc7670b498c5ea2c0a58b2de345266b0094082c927061c3b22cdec1f7b2dfd328bcb8d1bc79e4a5525b64ff41eb5791d141be18fd223468151fd6b070a616cc43da314f8ba3671e535b90ccd3d5b1db89bd99f75843997aee806d2c65ee2d6c12b57055b4e86b32b1d67833312b68f295dc0fada213a76468d776a10e87176fb8d94be9ef563b935744a5d6983197cf11b63e6f7d4376062def1eff7ae9db73d762eb1ab604710b17bd02940f2694c6e82a2fa1c2322fb2b21443a425941c8aaeaee08a1aeabd31c0f2e643e622d30621f3865bb08a40cc8383252dff8e2b03ba177b2983a221d8184fc71d633148289fea2ab0402c46686fab150b490c0f874624a9347826248318e85e9390acf32a2a6a1a40840b6e2c0da7bb25b9b47c83a6a9e78c0bad38099b3166cc2cb883a9b110b5594917e3a0bb30b90c91d40912f5d6d34a416f66f12a1173a8ec291ca0967a478d5106e351d2494b1870a08bacc086b7c720cb054a2a6a618a50c71a047437201b098aa92efb204e2f3c8932d14b255d4512d667dcbc90903e31920f50330415350eb2460475b3c6849cafbe7c4e8409a1f736255298396384a725978e23483432065aab2a849e74ed165138a2d4dcf17439e44872e2f1c215f7a23dd126cb78dab427503dbbea974afffe3411584fe964e4c45efbb5e6df7902d6c48f377d9209993963b516cadba0aa0f4077d041162c20b94973a861792bf661b3508483446615132338b104a4adadaa708b4b8849528134d273718ea599b76822a6c13a6009590c47eef32318a8a6b1101903631e9043a224beb345eae445166a3b33a633b567c96c8ce5649d5d36217f995bc721c6d053d2644341a38354b611c4185bfc8401c7e333809baa22bacbee12cd09b1a46592484779b4dc9c1167259e5c991b6616587a5668347bda86d0d09d8c21f9cb3e2b0c46d98616c31c54aa20aef3f28452e6666564b3cefacf7372f3693876b3fc82bee636ae6d33a53906dde0b2037587ee42acfe3c8bcdff92d4ae406a2bab9a561501113e569b3b09e5d1c4b157e58c373d9591bd7743e60a6fa646865ac583bf48317c16b52e8a63a458bf6cef6bd2abd3eef83599bfa9fa5f2fc763d32df6127110623d4759518890629cfd058454e2ab9d2dd4613574a48980d6d24343b875139800c75b59e1d0af9a3428a26da1709c78d4f5b297c24af1cc37b7d3832b2ce61e99b0e57805bb20f76602c2f095e7190a0b5b7290e722cbe087793fac211d4c34c434518b4a14e41d85e4409c264c918010a4ccc700e2992515627fd649c46e0cc82540a5af20eaca9485a267b70bea4d48ccab16d6b045146d85a07a92a09e0a11a72522b590187d608583d2622f0c96cf4a7042ffcf4592f4c3894d6d6b51bc61543cb4c13351e535bdd3450695c23182e0e1473e5160ed32f5277b19c5931d82c2259de5193390616e4881c7c7aaf893bb4c318b2bdb4f1767b42bfa70f14ccb13cedac416bad610cc4b96b0a3cdf078ae80792a582158459ef4b42732d9ee2e105a65e632e20de3654c3aa24306e990a72135c26f8225499d3887b6467fb47133b5a4a4eeec013d58d6d2103391180169c341c68c92279a79c6b568392c5c4c105b77f107501cf8202a62a939751b1afef0a9b75071c184853b5c32756412dcdc494fda534b081f641bf6b5a85e14ba8d243b06d1bcf963a2e5d8035026c88fb6202f6d2fdd6512394944927026a6b322c62bff5359cf7e406b3b1b34ca797617b27912af9e187aa5b7a8c821e25527867bd2669262a22912b58d5b4649df121bb31114625447fe8bcce204a5bd8944333972a45c4a43b50eb01e049840544d12654444261e343303f40a2c19daaa793129a1d1ab2255da411be1d045862b594738231750da99e3393fad914384daaa6865d193049d95591904ba02e2431fe5ab583b064936946ef21383bb19590bf34eccd48241bb48c56943f92da744e35077adc5de36f6c4470a44839aece069b6f421ccda0e5745a54372850610e6e2257acc3d24fddcb3a0290a253b44dd6522164b9dc6b64b1e90b5583f3344bce1b40a39ba74a540b0b8c4f888ce56e924676d9484ff898bc2162401ad1828c7948a3251a6264cbb58f3cc6946fa31108d41e924190932df7d76a39ff5f4cebe763a50560acf914f3d2cdeaaf014ad5cd00d8cd1c456d8a694ebee2fbbcb625fbe72c5a47d35ca86ca0a1ba20ec2d99d252696793b03866f0a9d9c1a075263e52f488432c8e0b6ca0a02b6d69820a4396852c8574531311ce289c99a66c96beecc32bf968420125b9867f704ce3acf34e1a455186c7b22166ac530329779eaac5d65c90ee1ac88e7a027ba29961158b101277a08f15334ce9dc1863a588436a8440b452cb95e7b6458703220567e4759962060ee650a4dea5b13ab48d6c3bbdc89c60605577a10a94a526b1117abbc6c16514d541dff37916561461201e939a44d0b8dc4540192c8ec85166900e892479c7320c5569bb5d8683e03bc8c90ee718d9795513e53fd07dcaceabde68e60239196742bc2591f098aca99a8685c0d89d9a1dd34b37f463bc772f299e6b4b1718a943bb3a5e89a631992d708e675b32e276b88caba9a95b0d6e9662573307a34f65ad0daf00e79bd38b9388bcec12ee74265e4c0a97ce55f6138d648bb29a13a71cf35003924b0fa7189c078fbdba9689fc9a7f30e3f6a1a6045bc5a3ca446c4f968f67c47755e3a6c415de20c8445d81db18bdd0163ef5e13bc6711efbe33d46fda34695dbeb309c3d511b78ed73650837c3333713ea48f67032a67be71c3ea11a21d3b65ffbd7e590ebb26120d176d30ace069b92b8a674f4b9b4415eb4235d89ecccd5a3f72ca015f2268fc699023623689383ffa72f77c62a75a95e320e3ccd1d7cc5dd12877bcb23304d69f2c3f0cedbbe2cbc333993481a72c91b6d083bafab5326e198b387131739cb7db185f0c67a43c47770777c1c84b0bf78980e6289e851f2c173bdca1cd1a180468fe3ca6a9b9cb2e88779e10828a2d671a22db77b9a4fa98cd60e25d8d69fc8ea5ecd7eb7c63605867d3a8df3de857b293dd1da8f9394f7536f49c0e75f9a7f6f2f61f12cdca26764b729c00997ccfe54a827736296dcc8d998aea5fb48a6d3e6ec508eebcfecce6e6c374768f727ce7fa48aed7268e71d6ffea92e2cc030d2bfbdae6d8ec43685cccd54a6f71c2ef34ba832654a45dce0fe22e673f5ce64144a425f04426e02ef0fe2a5f0e6955fea64ed8ab4060e6c02c01520ef014266aa8a2427808e1141cd0954aab724e6bb84aa9d5ce4a366a62d9b0206c16aa74b4ae67c8afeb48f0eb8ccfe17e0ce21c28b77eedf4b86e22d830a6dc0be3606a80a6494ad08f8a6ac417168678a82956742de8e2052ef22d06e96a4e108fccb0e36fae049cd4e0094d01d0f8cc50eac7084ca1f37e8ceeac661a1a68bb3869d8082a0c632976846cda3271f4e0a5f456830eb72436bcaaaa5ccc0d872db464089aae2f98dc04bc6884f4e2efc96031f5aa21984e89b7b290487eff0d5e888251ee23faa026d0c0ac56d248948cace57c65a2eca22c706c24a80e4e76ae687a0c97ce40e652e980aae93ca4ae42f44cc9a6437ad6efedc231823e8fe1422f7f5c515060f1f556045e12a87790a6e2a4c861f2a6fdf6018d7a51b41a4e36628396cc0ed7c0d01385a4f2b023ef18c5bac806e25ec770588eac382cb88c83e380af141c0fd80c6d2c104db09264737aa5df5ee3ef56efd298ae45d68e926670057b23910e8a207b01a8148193aa8ece384e1030efbcaeede158b0381cf29ab803203b0bce4e52360a7216df0c57f2cd76304b047363adc48ba65a4d2ba9c1943e6791ce8066eeee7ff42c148b4611c0519016e70d87ccd7a4eaedbaff695396e26bcc219ee80f2963efcf4ec30f3b0e7a72d00503a9d762309e72920fb78427afafc1daca3e1ce11789f130a563e4aaf2953ab017d7273304e2158125a686ab1e17841653836a66b0cd00ef64ae02342cea2393e92c5412227087b47a416006f15374a308650e4d74a5aa507027b748a9f2ef0af6afa6f4860d8f242ecfad294f6c5fdc603097b246ce4d16afa406b3cfc368a782d66c40fecdccc80b298bad39c3c73ab4ebf42c2eb994a368b82ad010259146720205ab98caade506aaf114c4e0de8e8abca5e2d08411d92ed172310f83306970d3171bb244722cb858ac1e1de6749653b2d82539655132ec3064fc82e166901f654d1cd368942afff20a43cb93502c41b96f29c1254a3eb0fcf0aca77e64f758244e0462783650be80e6ee66c86adce6b776a5d2a02d4361ef0ba071f634a6d77e32bdb8f348fbd356b09338230c2f2663a3e20ea5ec50505c093ef2e7402a941731c38a72013df628f006acad502bb930534c479061c6930fcb8e3247283731c87d84b12bbf69fe649407c30f3fb88c2978a8936cabe5f064b7c6a2602ead21470ec40ea59a2c12a904a843495460bae147f7a8c5f682c448e2b7b88b4311ee5125ef361dd0f9028224a3e31d498d21b8827c5e7122433516578454e15055c92f3b8f743b15b28210abf35a154a304f3304e43798d118fcd426f24d8018f0eef48a2162946f7effe2cf24a3127023e9d0aadfc4300dcb730c31034f25b3af424cae8434523de82be225863cb0616ea83987b1f98c61818eb15c9d667676c619486e622c151ee0f58b828d4c4e91ad62554df58345994a3a26f5f1e8915808565c42154a16a67f50cd249c623b7c4f4f57e9a8e4ab8024325da805443a0487e8a060916216fd51e8cae9404a45c43a969bb4ab4d5e15543d56dfa0c1bb0cb631c9a7471de15819029ee2cca9b66bbe7888cdbc71385acf3bdc8c5a9969327bc34cb6435baf48291665282754cfce044640e36c30b55f9c625b88ef008d52b3a634ca30a5ba4605d022f6931caf1d796ac37eb35ef5b121980763e1f5439eadfefa6927cd365d57ff6f42af55b4a0f459804b2e128d3ef96189d8ef570fe59a0641af8ca52f58066f9d36658b6d553fd65575e7591fac64370a2fb76743b648945a3223c075084c811b2cb15266290be169243b6b64a21662e8674e02f74567c47f60d6318caa6799a846c20d4b73830bacb00aacf06775b6da207266f5cea59a216a4312146dd49c220411f713118b573554b7a1ccf068770e23f0756eaf056d2bb65d870a4632d66dc950eb64655e1aca47ce8b0e42b73d1ed25bf9a68ba45747d5264cf08656eea410d245f72808753527668fb575b7b123149770f1d76bf4b765d46d1bf7f4d21424661db36e13a91e0ef87512d859ba84b7f6667cc5c4770f366667f7328bffc876e70c4fa7292074f54728435879691a46e14fd3b7f81ac6d9f6929e742f197c418ed415d66eb4047ee67211f778a92f79e3b742e6b70e46a13e21877a29d87827f67dc9c754ca777faa363160727ebfe732b7270f02236ff224581b915fa6587e9cf8c1ea376f0b377fdb267559078abd861e2f7369472b8a40a30e7c306605cc095b7815600f8e2397e744498a47d7a5aed68aeb4677510182014582137086670fbe4e33ffbac08e3dc29031384c2aa34f5725664f38cafee756b7e312d2a01428e15f1c4130d4e039224361f52a12e518204cb279f2a27f76b87aa1977598f897a24f88834e8e2977c6d2554c02f115f6eb8e476262520cbf184142f8ffd261b54794a5e099d415aefe368a7f103903a1140499eeae36985f418b2d848ba59958436e5eb9ebc584b56b9ba0124b80134839004e610ddab91352678ea73654046a85afd614e2596ac3c573968d92f974815bc3861d588ec0779d98ec9741c29d85d9c93a865d2b282cb8a48bd7c915c8059d15c79533f997c6ad6159d91414baeb461994d939244cd92b50799393999595000002514cfcc21f3a312f3c1a9405639d51e1934159a1ad392d62f8a589e0732159151e7273132b899e787e869521a8f9b06aaa2815d94f93409b3f42a717fa735d34d81a719f3cd724a90016a8c7a259219f2f95b4a856a0d081aad1da935f8baa3f42ac93ae086311c6beffc79a01230e00e06445e39e7578ab518170c03a9d47ba7052c12961a725d0b7af61b304085b180c1b93e358a39199a31f180be1e398bdf88fa33ab16381adab5a6af0811fc9b9090a831400a32386baa73b77130203743ba19d473aa7edcea35f9b304efb3eac576fac9a5310bb0dfee2ae4f87097a57af5561bf5abbb505ec6db910b8fb7ab6f118b90dc5adc7f9ad25da75d0e8a4373a0e94b914985b24387ba1b7f150ad12b87685300643aa9fc9b3f1fab0cbbba68ddb14705a30ba9b94c363b1d35bb4377b0dfee2afffc0dcf87a15bc6de5da7bb073c3b5f7bb66b65ba807bc0187c15b5d3ab573bb484a00bafb45baab76a26f5a3c0e5c98590d396aff30e9e891bbcb5bb36bc6b97db1af65fbb5705ab05921c34182b952b87e3ba2b8b3b153469bc55dbb5ccc5bbe77c40c46414e0ddbbe5da1b6bf15b7b95ab74d3c3c6c3c7d576a46de8448892f25403ca74382a545801222adc0fd3bd264dcc693dc238c608559181ca17cb3ad47c4f71ac2c95bc42d4aa481b9cb43e20b20c544589a2762a1ca4df67c81dcabc5c3ccb1966e7439115d02b8d17cca439cd0037caa871bbedfdbbf7524a80fe3ab619377c79cbc63fc7a725cbb27e5cb4b59b675987701d8b7ad1c6ea74885f8fc616fe50b4fa729269dd0753ca10f7d3ce2bb9d77e4d2a77ae5feba7743067b2a5ac4dd9cbcc78ad659a1c8daa0f8aafac8a4fffbdab88e6d0ec32309a3f77804d81bbdd7635cca79e18674bd8462fdc82765cd5b3dcd17bdd89f5093fb50d5c962d949bbd9a11dd15328db5d9ddaf1b8ab49bd7a36fb5c0003c091fcdbc1fd61b56a3cc7e6400c43146a5a24663cdfd91cd60bbd156222de2fe1c8761dc9d39de053c873ba724f4a47876bfcdc05bed45b98dd6bdddd697cdd4d88bf849de36361e021ded8c102d61a93e87661d0db9da633fee45541daefbbdbdb43853e99e6e95dde1d5ee69ff0574e49b2566324d23c3c34fe8e75fe1598fd88717ee524cda2927e156edde78fec3e0d063abbc388a3fcd1a95edb311ce35fc1d3b1a7128f9e524421ea13bdeb8d953ade6dcc7c102390ff3ceed51ee6f75c9df97cd57386ecbf2de7f77cee0135ef4836da849bbb8ddeef9fddd23d02efcf65eac94aefe5def0f92b2435455749a2f0b91ef20d7ea6133f7b181fa31cfff2311f24dbcd9aa2b4222cffdf437fcfcb9ee8affdee3e1ff5539fac3011aa4932f6d5fee13bd1e57166f5179ff7d3def6637361bbd62b9d00f8bb1eedc53e677c9f523adff8bddb5a86ffeb6ec1f97d7ef58b44f7a91fbeb39fe0dfd59ec85432077ffb17dafa2d5efc35dffc173a5d0696d1746faed17ffcdf1cc2b1dff997fffdb107dfdc41144da6c9ec1f084ac221b1683c2293ca25d338223e9bd229b56abd62b3da2db75b248942a2b09834129142e7f0980d8e7ae3fff239bd8e84dbf3fa3dbfef578ea4850c8e09a2b111168a04fe353a3e42464a4e52561a819185a4b90d8a758a2d92588e92969a9ea2a6561d169298059ab98eccd2ca9689a8e6eaeef2f6fa520982b9be067a2ecebe9a9181fd363b3f4347f7b9a2c1ca0e83d206d6264a7b7f83878b97901d0fbb26820d226f8e898dc3c7cbcf4f6ab6b1b3952ba7ad19e3d2030c287020964ee7907d2a44485da631041f428c4830519b50ee066d2ad3c91d1a891e3f829496f01eb27c1bd180ca167225cb96a73682ba8692634c7d675ce2cca9b34fa28dc360691274cb269e9d468f22a562ec939a7398d46144696f56d2aa56af0ec9c4f4d0cf4088b28579230a2bd9b2ff2e0d11f2d434ccac996d62122b6a762edd81504762ea74466d3e65dbfed50d2c589ed68ac54eae6978ec0cacc18e1f7f4bd98e5a4a357bd3722d091832e7cebbc4786d852d1b268e8b2d86f0ac7af5cb36d416635358da6fb543ac6fe38e64c822c98ce69eb233283737f1e2540008095002b9117f8bd0c88225fdcda1b65a531bcf2e8ef911eeb900805f1e20fc90f114ab592316dd9ac58cefb4c337e2bdc8fcf9c793d847027e3c72e543f6e7470a80e00118007f0194c38636ebd5b28d369c84119f71f501c05f09fe09415e86152257df721f1231e085217208e27f1d8e67a0810412782087013ed26185014837e08c50b9614e830efea4cc570e4998ff5b8a28ceb8e2802ebe3824910512a9227f4932b92487cf0dd36285daac381e250422b3d7302a16a91628d025239d365e0195107641b2d6225759ae9857084e2228cc8c45cac9219d603ac9d59d2a9230e31ac2b8960c3524b8a8e57f7e70d9654c23a463e08f6cad17cb5f8c85a6605b6cc603238c19e2a7048501c8629835a1b543aa8f63b0138b4217410a691a4e96da9b4c92b2f7e8366950a3e79d1b2ada9db0fa81ba2178673875923db5a1d35757c4b0dae55d4151c5692a9e9a086c78182e57e2a8db92182c11438ae7951a633a480b2b9a7802e93d7121eb4e3bee406a993aeeb20a2f1a002c064b45eba811962b80ca72a49ee1722722b706ef57ffa9589e4cf61cbb14a9ab1ea1ac1e22dc22d656f26d7f086ba927980c2b295e914f22492e7305aafa14464151a3595b2eb37b8e39d14267aacd52f13acccd65588ae32d98d953333559de09a5af275b09658a34b65a8b306f0c7a5882e8198a6c6818595712c793a8fc26ca00e4f9f49e27fb0927a91799cde79fdbaa885045188be694757327e65457fe3ec7cddccfd5dd6c5769a55418cf6c8546e78da1b485ace2673f7d4cbf8c5d23758f94b971e65fae0a35663b5f4322a3aa89fde6aa5b00cb3a27c1a447ed32ace7cecaa791575efc9668aca447bab3174b571d9aedcd0d17efb395ba50b345cb09da504f8920e926c0b1b1361907ae1eca4f92ff2effd63e3e7364b13ad465bc1447a06fe1e9b7e6e2cbf88379cdcbd63ae8a3ab2ffb63ba1f70a08aa7575ac6e80445a9fb1595697db660c8e5b8a788a0608421cee1df322a5306abe9c380f29a57a6ba5799584dcc7a3623445b349291dcb5426a64c2d8f132388825bc06741e1bd1892c2432ee05036654c3c4ccf4d72a9af52c66a1a9a1ce90753f032d486fa3d9190c13189dea700e73a009a21083c13da015a218f5a24c42944138655d847011638556da772ecbf8501f5c4344ce9ac29ee8c4e235ed128a6bcab12628ecac0db7c15672bcd5b6a625aa4872c35ba1f426c2beedd1307db41b3efaf614570060410bb2550797d83e920cca7a5adb8d226bc1ffc8cb5ce4351ad44431ba6806bdbcac8a253448b466a6451b4ea78cecca44f204b1abef19ea2299388c31181221284c272f721ccc0a17e62d91d5090d6a93de208ce415fded0e77a59aa121b9681a9fd17099370be303e185c623b6825dc70cde2b8067bdf099318851cb1bafb0581a76580d9a6b40969812c23783f4e86ef71a0aa60a09c04fbc61248a848d336749452e126208a7e2db5b5c5197fed89169247be1aa4a87aa94e40f80024b202278e5866bc4717f4eac68d1c864b778aa6757e861e70df5079c30aad1a3950b29e72a063bcc843068142494c33aa717b9a12b5dfdf05954b456d2063e3067f46adc8e082aa657364b9625d09c3d855186b9ffb00898907b1cedfe97af33ad2b2e4de4dfcea0688c336dd589295562bfee550d5ea52ba4921b69feeca623db15eaac9c0c6997d6fac9ad781453c50b8bbaaeca9e72803582bd3b2634550a1b03ba13999fcc18e3d478c5fca1d31069754a1f1752161b81496c4e221bdb8a68341dd2b0929af94d23338998a2660a9d9804aaf060a851d1a2f37d5db264b48e683ac44d8d41e9d1605fa4d5bf7136884a1693a766a876a65b30c67768cacbfad21330c944f19cf45a471a57d5931d9a495dd4ad9c3d553996a4884e71b5aaad4c6612c87b0c92bb521b67a126e6c070ae77a0ed65a3567cdac98ba671b61553af6abb32df0a96c4b8faad2741c9102b81190aff9b331ba926631230a6eeb794667228b4d4039dcf229126cbf82662abd80a4d4d8dad81bd6727aac2a291c1ef5d58656eed9e7928d1ecaa412d3565eafc0152191fd3a535ce47ce023cb798d9b6b1648ab1b4724ce3bb52ebacba2d2774448a19a185252c30bbddb3721b0c08abb66a7bf3a180e335db4d6883baf7bc0e6818cb9753d1378a12d61c32dfa209a4ec47bcaf89a1cd6446d93622b07f72b5947efd5235a678ae187c4e2ba6a208e8bf45f466498d64ef6231d7a2fad9d0f5e22b3e828610e3bd827034394930709bafb396c44154ea2f4fa3c8548ba96f415301ebc4ce98c528db783756c61c5a070c565872d3282d425a22ef2bc8c031518846ffa4a9c0602b1d7c8ec41edfb3f590adb9581e079b9921de26878b8dda631b8429c258dfa32fdc474cc60679af7617f37c3713e82d91478bdcb6adb52c53ea5c0fcc6546b075f0da3f7876998cecc6729a3459889d306948d4866b61617bce093f19a3cce6e994d534e4058bf4c68e4a4b25e139c9101f4a97975b38150979108c26d837d9544b3b7c02414c231381ef0a1e9b2d97b5be2ab955998bf82c6077b87f2966291333ee13df37b981761c9900dfecb1ee7c40aeead44cfecde6bc80dc4db1984bd3a5a1880e15d1684113dac0d64c0baad509d70f4f18ea77214ad62c5d2945c8758ad30aea157b924592d704a0374d6b388f980e2e5b71ee40f9a4ff5b1ffc2ff7f6642193cbe73a9a2ccee090b2223a89338798c8f141f7d7c824e52461c182c4bca7c3b101e6c7f00845ad1d35db41f8646bcecaebe9455bbd789c9ef10d495d3b6bccb59db60018e081e69ec4735b2d5f36c4d44f12dd3209475dfe2afc68ac23a74eb61d5e9b3b64ba7974dba828de25271e8fb1bd9c444b0f38d2d5e0e03681ac4ced7a6e553ec6b8c6159eae3d6f8d8d944b637475c615b17cbfb4bf6f32c84153ddd74f07d3b5a1523b37f2ce618bda01b94b98dd4e1735dbf644cd69d410f758d25d990e4cd8de2b5510ac9c5a05091e90b0c49124dd7aa4de3e601d5d81d58af1572acdd9627855025ddcfef1588f0559bce499bcc80bff96cd5e92b15fc60995714111a17dd97ac190d9cdd4fb590ea08191c8e9485ffd1699505d9825503600c5c3edc8fd1d0a13991a15915204a6926bc89614fe1d17b58495485c8c75de6b5d9be4885de8a99569d416ec418c08f5c85b6c9ee5c1db5ec11298690e7a701d1b46e1d7e9c84158ce0ea2d641905645c19cf3c9c9e00956a9105624118fcc7d4f546892e0989a38d1d44a55992c6dc5b34cca5eb05932fc8d9e7dd7470c08fad155e9955f7ee994a574e0243d9ab47c5dba75cebe711980751ffc110fe0009bf2f9d0e8c5052966ca98b8a2a8e50e8ea11170d5950fc5976b14d7cf915bdf2897f6d85299f48c94f1962a9d8bb5d5e12445d6f60c8dff94158d29e11c4af09bbf6d584784c49d781e839ce10a3a1dc4299d329da3566906fd908e7bd50bfd3499c52919291a5e7fd955081edec7f15914665c2ead14df8054c66ddb4082dca085567655e07a859043b29b077ed8c771d196f1a0f9e162b42d8f49141e5f3c0a1841589b8946394e49040ea38cb961e5d10d752c9f50a1640061578ef82294c1d8a4519ebf785d0c32e25cc1231fee1e183e48aad15500b51150124ad780a04c0ea50e41d8228824c8291dbfe5cf2d40e3c369d53535e44876d08b699d03d18d62d41c5592a4c080a295c455d849122a4da237cd4662d0cf3a5a9fade08c46bc0c5219e02e2ae4bb2483b209172b5697e4e50e088e53ffd98d576e8910e5dc5a00a9179520ce8a4562956de5430a0cee88d44029d2e5f006663ec802ce635251604358e5e005d1dffc9844d848af4d0d1c4a123ed620f905dad4bd614b02ce1125464951cc7285dc74549a431e86cd68e508bd26410664e30065bacc15da69d557d9e671e2e23fe94be6950924f9c6840563bbed6352aed352b61b5f2850350d5f2258e09a8da4fe9cc7bf41841722c8f8d162b4dc61a5e5a186999ea2b1202ba0c341ca535ec557d911995276e6b2845f03ae950eaa5b08b2df013a5ea5a920b5c8148ca1e3ddac61cd01dadebc987515e49c99dfe1f98b6226287fca0d06c5a55e02e7b2d40681dd9a9be9593ea4e78b0c593eda20ff152a9b00d11fde6c836bea24f9a183ac20c4f52882f2716256aa975e4ee1256d68aa156664815e8fc6939a800f614185291e653c49cb68c0c5656cc5547c1ac341a99206e96de29424addf83deda2a96a289ead549396569b2d22b3ec54380c96adacb600ea79c3a5fcc2921a5dde8b6ad649f55199be18d42de5f81ca12567a29f281a906c1e362e6cdc321db173545e7f0550e2daa7f35e595325cb6396a9adca1a446e9cbe9e4825ee82199e2e6c5528f92671b7ad93a9d5add40203cb9e978e4c8cfc964a25ee8504e962ecaa8e9655f66b4db5f112853fa96b6394c6614940f3a685cc00eaa44e2db9dd9da5d58b2961bb4d8a7bcb49d695ca9fd5dc7ffb3ea68b46a5793e6d6324c18975a0a2e558b102018e03c247b246260e59769fac4abf24b8fca1863a2115b7ddc1f6ae4c6c5527e6d5024fa632c026950d2951046d9768e10d760d3fb55ce29d98e0c315c26459d64302c4d6414a83ed2065586ab280b5aa428c49c03ed3d2a930ada613edc146891ac16d98388249ad196bbbe1941340ad4fd6b3002ea60ce16103a9f50f655d265d7ef291f7a608f736ee2dab9925ef0cfa6c2cca45e13602196579a15a769c4b97250d33203bf60ebfefcc3b4668c95be4a463cec5f55a69a60eb2516ade99cd47024410880476c025de5f0e4d08e5627be5140c42b6ea16375452477f2ace93460b011e853be86864ae4ff2b1d6b98c98a4742206a8812c098edb2128ecc1984b9dae1cd399c1bd90b15de0f72b8e4e630079ff86ba71546651858ae4445e0696c4f706c8321d8274a01810010b06a0fd7c8e081baeb43c8a3bb7c0252e1df91f2669fad1ffd05aa513215723966cb25a9c25aca29612cc48e1d372ec3d4adee8f3428bb14c1be00c02af986e07927e1b28b918c8b77ac8878f84785ec63d47aa7f472af453d573a98efd752ed664c0179d0db60ddcc5085a3a399267a0a84135d46e7302224216af5b9d5afb61be4451df0520ecaf2a8c2e2c3d432cffa3ad84c349cfd3558cc9c0783c02f7d80c777c50688beee837c2f77184811846f8714cb526dc31074f0177d70ffafe182a9d965f2f8c3e392eecb5a41b0e468bcc046c45265b4fd0debd24384d6a3782623a81de8c6d102b4f2431fe6ecc0fa4d4eeda292216be38e94e51217b9415fe5d2f0a50664f794ca12684856dc278f78b1321881855c08b798cca25c821910c18575f1f5ee0bacbe31363c8fce99197852461a6481b8b8529449d79392a5619ad444c4683fd8dec7f25837896b8d92dc355846005f9bba3a960c0560597553eba89e1d160da6612f1e7fa7113762a97205ab3081b80801621214ef1c41f886af062f413510812af70a67214a180bd430a870b37870a180f016f8311c6e0de589d8a951698a02313de48ef24c2b68ba159736b0fdf924e1226812cb4affb88d5ebf985733f2c6e7511ce748991058c32ecbdba4f9b2f0d1421b534713a0b238d3821fc74c0697870b0d4b12c8421168037d8c0718a07113c03119e3d74d70012afbdc5949456e96a704259e3ccf43367ada3fb0d14f24a77d82dfe81a517ede2bc38aed16c926225a59669c2e3e08742c8f3127b2c1068f741cb4332c6b0b3b7f0a13a4701300481abff42c63e56ce08e17a8712a7f4f6dbad1632ee67ca221394284946d30fc626fd0fcb422879ff22a6d2c4d2d37fde0bfe8d40441c51fc12f435fc290914d69b8eec6d0c14a93f0caf4b3a8d4f412c43413248958df413a7f41a0249256dff0117cab703d3259de4dfe127544c0f5a760f2dfe5e2ffb7d9c4449fad152ba25351746fed06ca8d012e6b413ee370e3c9b516ec747788ce599f701650855bebc79338b61610881ce4474a3585efe9960cea755898642ce7ca14d212a3f2c557b06f374e60bca98f6302280775a4087c761768c84ce74165cb07f560b61788137e844c71b7ae723f76eac104af0ef20a166b390a3714986ade26b593d5d24f23cf045ba1a6c9b683d136268c4b7093756f7b01663f4d68ff81489b756677015bcfc1313dea21f6b063054f5050b73f739913a07377a10e8291731464f7e9d2e4528c32359c711e84077033b8148c4c23a4b374bc77b7c8817ccbc1d62015f2ddf7dfd52433804485d0412880476fed4afff037561bd8ff73e9324fbb713dd3c15a33b77997351f6c765aebc7caccb81260781c9cd347f1f2ecfe8bbf2d4b32c36c7537376f97782b24123449016f971ad68cec64d3871eac377a37c27ab77714e0788e6fc885eff8152c52e91071793eeb9449c55e4b04926bc12270c87789783e4fc108f04ba0044ade1e0a2944f82828c708b7b73ba3ed585bf8854bb87262cee806f5ec91d96484049b974f3f63b95ac71910cb399fbf8880888784bbf372efc71c38fa7cf74869fbdfec225641015088eb01708b78f9cc882f68f928a08884573a1877cba7dfc71fd459b9e99de34910169e3a28eec1a5473a84fb392ff4b9ad334aa6fbc199c4aff88639b1b4b752bb1243907affcbbad9dccc9191f4b84b3f7b8c287b29ac7a1f3c41b9ca74ad773b25249a23365f5003b8691a392f311eb22f418d7fc7b70b88bc6fc1b85741c29cbb24c46175584f4e0e6dc2a6f6bb3b469ce17b126c3ba687bb80f4bb147079a083f1c33f4221712803ceee6eb97b9bb6c9c1c437c53742c363ba8d0b94c457783358541a02ddfdca9cbb72fc6afc497a3f83c8c3baac9bbcc23fc3785abc7d95677761e1cbafc608273cb437c3b00b84be5f01c8cbba689ef973dd77affffcd4dc46c8e83434283d3420bd155c7d7ba3e831c0849906b5cb339041b106d5fbb6d5af44c4277dceff48998dba32ba1c4992a81b4cbd099f3df9cc3914108437ba6116a1c9ff208b23f4fd7ad02bfdd6c7c7cd8343bdc676a6e43059babc3daa79672c3cde3f866b91523b807d42ffd8794247c753be71ec5d44332fcf923ad48b86e167e0e71b07629351f8c8aa709903e49393eed23b2fa97e7198cbab9d8ecfe98d370917464acda5dffef0ef442bd552ab32a10f2be239ab53d2a03ef143ff2fd09278e7f120857d6b4b793442caec3c7ff47b7f2ed8d24290141a3e106cfdb59b1d18ccd88fb77c7ffb3f04ebdbd84f1721373c8f523f19776f8ff7bafffe0304108c48a4d0307414914422e4523482129dce917378bd4285cae7937b0d844b6372d97c46a7d56b76dbfd86c7e5737add7ec7e7f57bfefeba543a2a4a6afa4a9a6202ff1c3af422a9528aea5a44220900b804e8d3dce4ecf4fc040d151d251d8a0c6142ed3a32c59a0a342a0a64229ac55ae43a0208c324f5fd050e161e262e8683229c525d6c1494bd62fd4b9c4cd44286660db33cc3cc34fe060f171f270fad42455aae4a824e44da426e62155474bc9e5f0ad1be24bbb4ec2d1750e04082058bad4ba54acb2d670dd915a19730c4236b8f122212d16dd7be5dfc0c7e041952e4c834f1d21db247c548ac5c1321a2b302c99e3522aa965824e28fd7bf7f247dfe041a54981065379155a4c54c55c388afe039fad334dfca101bb5f1ea2654eb56ae5ddf441904a8caa32c44eb854527cfa9a92db620b233f5b2e691abff007ac59bff57efc8b15bc46e811933252e25351da5120bf7b0334685a53c838964a73f8f7b2d5fc66cccb1a427eb2819857a13d01421506c2681575a10b37a5ddc31a56bb76766dab56d7392d6d60ba142b8764fabe6885e1653eca2b8522489ac2c56f9f471f4765bfa74ea6d4243451a18bb622ec91733ee6c04ae169459149d93b65450ddcad5ddbfbf2d73fc61771813d1328b5a8af341acc57f712534ddceca25214c66832f4105f322ee08a200638c35c5dadacc2176921364047488eb6ca1f1c8bad0b01136ba6b41134f24a9b1c322c98709840a6b5131025b34ac96cfa68224b5994ae3629deebc8002abf65024b2c880cca289a808a192e51c20299c4b8a40ff287969192b16a2c937b350994535ba3a2a213a23c724f320e438cbf01efd0a1b0b8ba684586aca0c1da42212a88abbe5153625e2a84c3fff04a6b42d8b40263cd39cd8300abfd6795099b44e5a8b4d09e3cc8f4944631303d05fc43483534d6d7b8ab726ac7862a21f1122aa4785801355aad2b893100b0a2fb4d02e4f3fdd84b24c022883325c6f83d347c4d0a110954253e5d19eb2a6d2309a775cc32ed5d10a94112eb478b3ebd73d2cd9a6a3ab34eac8dbe86ec583dc30b52505ce891e4aa516415b2cf40b2c77c431cecd5ca389d6e28c55d64d7ce4dcc62773cd4d63e0730ba6c31b5d79fa96b2c9780913cc843b0db7045efb91b85374fb204b5d9bff2069e4494351ab88c54b5dc2878af91ee2d2af15fdb509cea910e4460d82edb83593712bbe780c5f7dee87e29e7a8e385ba27f7e835b9d014049b64b5ae296239e3236d86230bd856e6a71310e78e33b84f518b85b1ccb92ad92077c2d191ad7c465d44493c517e44b6d159a9fa3334663604e75b5780ca7a316526ba519eed661a7c3557a61876f5eda92e2eae4506d075d2262f0c3fbe6fa40a60b632f8096b0d67c6bafe948d5d4298d335b34d4c5daf19a56348cb21a1ffb95333fd7765355342e01d9a75bc00f9fba6b9f79eeb562ac03bf04a5e33d77eee1a8430fa0699dc280fa77e709ee48490d55422a97fdf269f611711b469cb2c7416b0510f5ff34845d1fd0f5a8dac42d93b5d458169d71ecce8ed15e24b54378bcc88d24122945ade64757c05ad376423de7904867bf839ef4ead212faa02f34927349fb1678bef0a40f83ec8348ef7256346918e61939ea1188204796ba7cab85da8b59eb18f11644852f0922ac59dec4c4b7bb756d48d2e90e94daa21045f1473c1de492d9ecb41fb0ed2b22e959cd7c0ec3963c2962171c3cce05f733390dbad07315eca016d747b9895c632aa741599b5c14c3ee9d511936ac84dd8af70fb060e445639b0933d40817c4313015576486095dc122d791e65543e886d28a2647bf298e7c8203ddcd2c93af3016a25df991cb8514b1bbf094077737990962ce63442602e6ff433871854bb8678d197e6f8debaa440060b84af2780f8d704ca12641332041fe81902adc253b9087386915052e8c80c7ff1a358996b5c52ca574a5ea6065363dfe060c969b1ef016d7b9ce399066c01acd31d5831ad6d1825f81945393d614a27be5687bb8c0a46174f99f7a10467d101924928039b22af6b27ffad4253f65751cd1082a9ab7c3631e7b64cd212c90798d90c66898230b77d4621a79a2601bf1032363fea14778ea24882811cb6f41cd2a6150e049abc71e074a522fce2482c796c10a97d5c83155c20f413d8a90d3282a404a92022f6bb7a1f49d469a095dc8429fd90e44dc716c492d2880401a098a701451adf9e814434aab9671a86c78ff8c86526825bb5ac6e2199d0c63ac92128d8a0e228901724e189fb93e2cc2547dce0161e5e8161f5f1a22218f31197d4ad810369575753122abfe0813d687d4841149094f06dfe251506a95aa5c0de87d28db088b5c96998dbd682bce74888952039fa1ddac83ce2628931dc724ce994b3d6a99b2132a31a12c49cf58ed57d628c9d096b304a54669083e3a91e06aa0c24e611c348b84e826b901c5699bee54ceab66288f819ddd1770fad85012179614dd905b6135c3b04814b76db50546615b9f92ddd6a605326d875cd7db2725358b856a6c449c411156cac93e49f210fa5edbae27a6ce843842eb7cef590b5f025442456ce8372f03a5f56ed1450282abff3cbcb7da5041c280d1ba93a452d59d86d8d0280811287c67b1dbf97ed85fc849227bfb6b56c7924c5101eee080e7d19b501e783eac7d6e8fc918980bb17621a3ea829175c496986c77bf3636a354ea494da322148f504db254b5511b9069a919664d964f5741da769c8d64be49078381fc20b832135257ca0d4329586021d390884c96c776cbf208da96b1755464f226632b11fed6f222fa21d4758b18af66818780213e3471d67c9dd9b68fc8fd6b9dba4883922615f3aac7cc6a679779ba3896e8a57ec97216255a460aa95a30af2bd961c3b6bb1de90f803c650a69a6386ac4d4f8c9be3db47da892e7e2b651ca40ba2ea5ef61e9fb1439d38e8551a76fff6c5ffc81e734b68e0a21a404a768adb93362c9352214ab1b293387c16a2ded8a2dfad6d456454897b1e82e9da92417dd378bb76875ac45fb3ac2eef9def7f69e63c7c23a287194311f93497b918c1388301be1f53d724f39ade857313adc8f26776875d43d6646851e85208b13474ae65a57242eabb13601336ea309c9057f2fce6d7c391ea57d70c3d43eb19dfdf4c8e73acdabdb2554e2b4470c213c2979cf63437035e53be328219975c9753322cc7d713843ddbfcaa0ca9f858372fdaa3cdbddc1f460901d404e0eb0ea0564eb5b37cef476b9392d8991d5000d211ec8a4cd7f791ef49e79b3c53e0d6faf3f31094cccbaaeb79fad386c37289616a550ff7c7378dcf042f9a61bcf673b377b4daae6d264b3e072475f7ee59a8f8b0987d371b78b728ae6d9ef8857f53f912f43295124cee95ded6cb103f0e365ef3cb61b1dabfeb5083623757286a06c91636ba461120e09aeedf7715cb7d77fe599d76ab55e2042713899d1a6d25545dcdf607ffaf4ad6f0cbbeafe76b8a37e38d37a4c3bde9e0edc4b45f7f4b093b39119ca513dce80779652d06faa3a997c87c7fce90fd1da9f2a2a32725a09794a05878b0988030b8953aee9291f972a072739897378070bd439405b272a080b0033bcc5a821eb532c298922fb390f25d33495512ecfdb3a8a120cd778945c7b3fb67a41cf90887083a2e6883dca53a7e9b2a740ffea9018bb20730ac026432669c1b4f9238ffaa38ffb431fb533a3b8338ea4a096dfc38871f338a39aba93828e1f120835a921fec839e79a2e99690e4d32281bf32044f1377bb327d81a2895712d482bb7ac933d0a4b0e8a682c048c86013c93de3bbdd28a2bfb7396274c33a8daa94fdba59f82857302108928ba1f6ca7200c9178d241b0939229d30f88128c6be9bab3fbbcfc0bbd1dc31421f1c271a0a2b4f90dd0b2205209b17b61333bc91282e22c93230c54538cea23311f31286a603959e1bcb0323429dc97dc82442844a5c72946b182444b2c4248843276c2a4abf2b99a62ac617b9b9ada13c432144634274ee42a557a8607c99765f9419a32bd90fff33f4edabff1438cc9a8188128a1bf529bbed023dad18ff8ab2debeb4598ca34fe99bf33dbb9c5e0c711ccbce6304115d9a9fec3c4787b147ae28e4de49f95f0bde5fa46b4892ece0aa49c6b2e4503bbecba27d89bb1c36ab6dd1a4196f1281bc1bd7fa2a22459a8c77a926bdb3803d213b989c18618a62f3cc0f3bb2401193e67ca4761110fa133b30ff1377c84bab291af5bb4c57ed1a5b00ab461f1aa7264b2732494c9a14272f41073dc0c1141c958980a6691beeb2815615416e702a049892de942b5217c0d5351bc8f6c0d6d7ba22b113acada12d20292d1d31fe3c0c3020c4496681ee8288715ac0fd262317f6ca3a4caaa1c59bafb2a3f986aaf48ffb42fbfaca5c9241bff800665a9210aca3123bb206159251263c9b39c17fed3b56b1096dda93b3373cad3c1a79f6333cad230b1fc4069d93d5883b42023b1fda2931393143c192d78bac1273ca5f250c6c530466760a971a0b748530f56eb97d468cabbfa8baaf229144227db0236c60ca2c9fc40b00b487c0c2908c946c2d846cbcb4e786a447074bb48ecca49d48224d2b7d08c2d5a73c9b30419d62c337dd329a96c9264832818293da3f2415cbc8f4483339b803d4c64476f9c48873410be018796788b838cc11f13add549c9d7c486f53cc9f469c97d9b4e0ffcb7b8644fead40daa04c0c22aa43564d00e09519bcaaf43d429e2e4c6f5e4b8566b41a8ff6c4af29c3214ec988ffa3894c84f3153bece3b24a47bb559713bd7c310ac1c47775aa2c1e84a9a6a296390a97bd2cbfadb8d352ba26f7351d6202200a338fa70c930034d492b1b14348f9fbb435a244263d14879f991470153b93ca656e98f9184516a24ca5a439d1ac1ce3605b8d80b3ad7e1d146f3d1af02b87aa1535ee4ccb98b11e4d84c1a7116686343edbc4b2409a7e01a01532c06e6a2043eb3417891517bc312495028fc4a36d36cc357b52db64116daa9b5eebcb79e8bb8b0cca9db8491dc0431b4bc8e3b5dcb3aa5ae8a84cb69734a207b2ac77b0ac6942d93a34aa2dbb5e9f34ea5784346d94a5800c15ec486c9ba0895b492ebbcd55f85afe0ff6834459240dc004bc43c0e99bc4bf370ad8a220f507d36473514fa99d111cb9f251aba301b28fd6325fe1c4aff74190085b55bcbb038b14df0fcd50f1352c583567a15c115e1ad27f1c8843bd47facc6262ccbe162d5612d55e22c965191195ab8411393515a8dc8055cc7be1b0aa6f2c0cc540974e211530225e853d5a7b0d96e8b4b8945539cf8d913bb59ddf3ce7779359f2d2b24b94f23adc65b038ed63458340baf848dd86462d0827c3eb2f129e9ab4e8a753cadf2afefc1cf00719b9c2ac39c4531f63bc3831cb6c702af21b414feb80a338189a105321cb1aa391ca96de4b9fd7ac5c752d6b58bd581a3266905d172b42bab2351d77c452f71b11fff9d3dee1052596bda3195c53994ba369c37f63c950e9458f02c49ad152d0ced92d9c13c8b54999ccd9d3113ab1a7909b8f50f2ba85ad4f28d8cb8395f10c05b65a5d2b95d884ab4183c3994990b3ffbdd7933d1b89bd76c4cb2c493950d1551f49c58ce15d4d2ed41a3a3a62b1ba81d7d5e463da11b73d125ab2ccc1c542f488b47c4583574cbac6cca1bbd94c69343dbbb40d655d36531a74c1c0e3dbb92dfbc2819e3ad2f39c551909788951b8eb253e24da7961916f008b003661ffb02baa2fd1edc54dac41b5ca370da8bb5e05eacaf2b73d68405ba7bdd566a2d5467e5595bfb5a230d908f4a5fde45351555b50dad275d0c4372b28f841ce09badd7f2ff3a59b7f2cd75e1c6bda3b3d97a09e10986d365ccd954c74b73ac3eebaa3c9b2626663f7d15dca7e85b721adc9644de45f34b5a4b36af554ab01dcbbe50b00d5e56c6dbded02dcab238ca184e436ee55cc4dd37189e3d8e42960181b03ce197a33824e96b2ab989ab8313b79eb2505832b60d41be51b80f3ebeaf972944d9ea35ba8305fe2895f03ba2f188e418ae5977790c03dae2783d3caccda985035da29cc5d115c1adb5cc0a0e54b1aa3ef2084f5e1cd40a7e53a4dd3f53460aa3b42d3746e11545c4e5f062471d4b6a7112edb210b5859666c334854b8bbff38585435c9a20c50f613f649d29b762913188adb2a8e606661d042e4e2679e039ecd964ff89a1330a8b7bccdc50c1ba4465e3e0248d0e04b4fc59a7dd65537da2e3e415ac12cddc5df30efb95bd7b4ee2a0bc3e1952099485162d4241294a09fcb8bf489dcb53c5b8a8f8829a0386997accbe129400d03cf98ddac868c4a7110133e8e8d038093751e626b6b3de98e2c0fdce56b8e27641438d0d5f0dac45a5dc50334c6700d9ca6febe09f8db522e3b05299c51dbc5a80c3cfe93d4a5c9d15a25d55fad193391cea9460a5b54aba979438cbc3365fdc3a0af505ee02343a26813258ca3bcd202a2403e30ae012286b47590ec1b0406b4159751a294dae2c4e165ef34a63c323e75e9e58154e49d655a85433d4e90c25e2734d729d67a7763ef4b063faffe1590ed5cfc785e13fc3607e8ee6807d36a99b9c94912656711494b9d0ce2ede100006793ababb055f33e04475e0118ab2393668edbf6092be350df213dedb460c6f46b46679d2ad433f9de3c7686d6361d5477c03cebb65b27cc3e5cf92211e0b5319556eaa4e638e3d536ded5aa3fd37deb5a8a3bbcb0cfec7887a3bb2d5cb7811ef5e63d09bcc87d30ece7d2b53413903a18c8918e606a2298969996f6ea34f9316bc61f1687693e2f3558f4be644466ed3c81468c88c96e046091b4e0a0996ad5de6a95e858da323509e7a9de99222befe6459addec5e560862bd154bace68feb12a39dd135409f6dba29185e22b0086dd86124b52ad21408390ed1559ffd282bcb1ef34c07133e85d2cc32bc273ca4b796b48ee5ba2fa6fc4ac3733055a6d056f2a8d57dce9b8e7434ed9849951820d9465147aa6a9a8cc1fd9c457f0e5511f1cd67ed5461109db7a0d31837ddf382ca8678de4f44368f8e3a48b7e695255e0981a699b4190b50e931ecf032f481ed766123da6edb0e166dc4e40394d40227f5ada915656b52f5bc4e3c1dba87174c5e5667387382bc2ea6cd339b8433f1f34e74e9ea6e5c10dd32814f2992263c7255aeefcaa2acef095d06db5000f79f2b325b8e8462d5e2e0d8435f8995d680362df8475c08498000080c444b0c8bf259f928c3b336e13e17fcb31b0a52597569225991c2dbace70b2a50c4dd083ffe39770ae09d879a66f1f04275da1ec045f81a574d77a111691f24301195133d1f8bb6b5d24de6dffe88abadf451006a7fb8dc83b4836301e9712743d78828e186b9fe195de858bf88665217ff4816bf013dc29082ee73b3967ae5d32023db4d8a5c18a8aa8c4a81771f338d8daf638617112a3c258f0ede3a5de3117e5571ecdd75b3a52eb4bad04dac608964b4c33b3661fb4d666532006253d054a260484c70a234e8385df83788c983b2074a631f4930d395428036be87a97869cda06354649066f26412adc6df11678acb726941d83f0232d0cbcabf4fb2c8c2c505301f7a02fea8ec7d94fcaded2562d336c7746f3b73ddd2425ef35cdf229d81e8722ffe5d0a5d0ac3e2f189d30f662ff846197fa63588264b7229761bf6370ae4d0e5e486cc19957bf011aa71a7733e3da867b3f246fe89d12e743c79f627243c8013ffdc34f40b0173068c3d1bfcd35548bdc862e6b3e46d4b8b6873403ebe3789ac68f4e299aa83b4778ab788375ad838467f811719c7e8878cfb804d306fd74efedb48b90b8e6f6ea62cd5e839b10a219e181988d8078cbccbcb459b1aef28bd3223c9686eb4c0e7d20108946a46288440c8942cc23b23962929a4c5171baa49284a3eec8aafc6ebde3edb2d8ad8688c4acb5588acb4780bafc8ecfebf7fc7e490948457465b6d5b445e25752170010a00819e9e7d8e80820a968791967172754ffb789490828f4a676a494a58434955ad5ba8a1515952a84e62572572917f0a8dbb8182c5cd285247715b656558a06d0956b9b06765402fb8644eb46661b3d455ba4fafa75da24e45a2e955a58ba863684786565c566b836589a198ab98f194e257fa5d812374332f572c42f613e4a0815ea61b4a9a1274efa249962e6ee9591331c550d5985cad61456020706cc856757895e782cc9a91807cd1d5324db00586509a527645812fde949b29e496403459ec2e291d5328de04a9d41facee91236b89ed62363462726890ebbe269e526501b7b609ca682c4d297d7b5147ba965bb6857a7966f45950b986d69385b52a6b681060f5b53805cf41c5c09ac254c3cf3ffee042eb6a50e22957806f9cc3304abd9351745227143f448c77251e4998657b6d0b86e4b63359ddb952b5c87f5fe998632508d2db49716cfde07b1ee5a862ef3c8c614120dabb0f2748b4615afb297c431c17de173b0f7433f32ef78194117c016cafbde8153572c09d33481cced9d66a824c6cf659e89195da5f43a11b01d1eff5d9e6d5cc092ca17e62c039e22c0f80660240c09171b238d4018d75a9941b6d92c561dd31d1f7341c45b576c38e8d2610a19880846c524171473420162c848e7ad97972befb512df5fbab0f55f8391b882d479073e838e3c2132e8a3828f5018a15b7bf4589e6545099604380a25a60924fdf133a2969598a8d010d7e4f1ffdd85f7b0a3cc38577068cc4fb1d0e32273cfc9b8451e4cee7367927c849115216045c50e1709fa419d9efc2cd86070d8c185a2696f408688427680e8e05a5d1073a987958062286344d431657a326ac587998365a1a1139705f4245c79762add81e53ce522225f0cda47a1b0468228800f2e0ad710925d368717fe7da96ba7df7568dc8248fa6820281839130fb17df0170f7af43841ea24703dbbab1c1e3d372558360aa625b8e1eaa25d836979f81ba77a4eb8e9ba985ad74727ea02286c239721f41d267458211e0022416a85bd2f29dc4720ffdc474a7ef23ca325c32126d9eb76f1ee7b65761613c3ac7111711c2f655b6e25a1b59866fa71cb780452ff466068de1555c52eef91ec6c19c30a255b139e0c6b7a938c6c31a53d93c8d2cd4afb610e2df4b873e090b82c2d29c978b6bbebd15ed16b35a36de64b74d172756d58d2549fed987e033d2dab2a6c0881367086e66ca8d65d2df92ab42ce7da1bd9df6647f7d57ec7adac7d6468e65e7e46102ec9e017af6bb77f1532bc37d88c7c0cca4179f3e638e3492e7bab40590d9995e74a033d77dd93db6b6cc597b72ce1e60a766e7a836c3b816158ed6451bbcbb427247b42bd05cf28aede3204bb25c463f77bef5e4b790b2b4d85d19cf39817cdf3f25e557e7c71624ff8adf5545bf6d9a318667b04f7e2af2f77a791cf667c262f35dff14ae1b3ef3221816223ffe573e5e00f40c2a1ee73fea11ff0b0b6b5007eac7f26f94e7a9a0308054a7069068484fad2e5b29dc566820a33572da83408316081091c2c21f6d6d5ba43dd4c839233e1aece30ab0bcd0343cbe8960b6f5842f0c4af52193460057188998da8032ffc8b9a128088c41c1243522bfc61127d941b57845054f778c513af88bf045dd05bbe73221667e3b0f9884a30a3f8a2196b87ab1d3acf8b675ccb8b264615aa10a2186daca3e9d4d83b36dad1210409035620d50e6cec7190842c64126b38c3398ea5390531a4231f0949f191820bd7381c81ce12c94c6a7293f943d0e820f31743248c93a42ca5297df441338c711e9f89e0295f09cb584a824f18b906ff6aa627cb5cea72974052c7c1ea338610ec7298c42ce57bdca31cfd19a998cc6ca6216b13c347117109ceaca635cfe8c128d6f21958b8a637bf09447fa0c335ada42638cf894e05464c1058c1063ed209cf78d62e99b3f8a3037927cf7cea536949585b7ade26c777ee73a004dd95650a7438d129a54e056da8437f830c5f320132b548a4ca1e8ad18c464294a01103678a6292466a74a424e5837a96011651d6b00c256da94b8f21ab114ec36105bae84b6fba4f4711517a0e0ce12a6c88d3a0c6b32f78e9a71fe5380ed10875a9fab4d51c89622a322c83a95485677ec8f7a7ab0ca21647acaa5799b989475c222b348c1a7d3e3ac9afaad55e0cd2e36c38ffa5092910d136298d2226d72acfb6b6a4851acbc72ede4229cf4104148ea8e880624a0a6b9804afdfacc860ed37bf3b80c8b1c1706c9600eb12cbc68512d921ec97b244c1455022848c88e636cea10e1b8994b1cefcd966ddb2a9cf6ae2b372896d66e9d559d9fe6c789933980849d0db007c47736e5dc80355d50bdd48b32cb9e1863880ca5a5d660e209a3b88199800db0000e441bdb86e089497ddeaf662bbe2056e2f1ad527324e2638fa282e459c911ef4b4c6355b35c22bccbac5e8d64eaff982977fe71700a8092a2085484580cb3760e5f06548ca98026c059c19028b60bc0c4c649522f3331305d6387de5f03008fb5bfbda880a818c07044583a3ffcce8d777f0b2ec5f259b59c5bc18c08b71ad23c6529a01ddf3ba23ccf13b766c0ea84c65a238ae451cb9e95bc431584d45704b40069b611853e7b19895ad236e710fa35ef2a7d36c8f9844438415674dc676a8f26d396bdbd96609bcb985728c454b2f13e3485563f80b37f9029d7894849b9f241f9ee95467512a672c8995538c5435e10ceb96bd68eead9ae9d54ecd58679d38f6a8590e964231632cb3d4b5ad77d99c5d349317b7dec5ad5bc07b59b7ac482a62f28c9f9ec16a03d95291670a5d3fa5226b3f01051ba748dcac526c0f3384babb3fbe9515863d6c4a64c64cb71a347b7ce9366da2e7c7d0d5b457fa7660594758c1cc9d688343f060046fff7b39dd4e132a60cbd9ccb56174e54a917920dc6ed384108e63880abb87e8eebf541234428c51dbd4769a44a7261a0309f08190d5ddcf902f7451b98f534e5aa09909aad936b5b6643de4626a0db91447767848d8e1b422739c7f7786a1599c46b05063d52931c2517ce2535110e22220e422b0329d6b5f214dd21430432d2b5b634ba938c1c8f72ef72c50c1273f69633541e22891c7059092587c61522e73d5799bf002e7d93a7616e1c3fd0c1f3a4758506ff83a7dcc7bde76eadae54d91b35c6f31b1e564cb9f6ad7f5dbaf5bf69f7f039aab48aa3fdcb3977470c3515aa8a832ece1f557486135f8b6ef610325c3b17c95bf2b3933baddac3cceae1ad7fff37975ee6c2d644aba9ad64d69b667e0fb4ff980d2ef9bc735ac632606f54cfcc8649d621fb935202328251c6880423afe111a2dcc7e1a593815285123f8430479e2501d09338c4d9f6a6334e39730339c39db693497ba12eb16ba67e4ed8e408ba9fb97be06f8a32f90c4b3d281d183bb51bce16e76b893fcf7a84dc7dbefcef7cfeaa709967db50c646924a638de456754c10c1ba74aa6c26e330566a2c17146b56dd1b0558be752d56779a786798a066190124a52a474073874dc022335974c2686732e971bce474e4f3568fcd32245e40d2b7780335476d3336b416149eb3673dfb6732db8552307102e2862ec048103562656517c622284e8935222f4ff5bc7b71cf7016b24d65284056ac8866e1322723a56263cb62c6b977326160bcdc57e60c87678a773a632153f571371a47028f28560183a0816734e953e2e7838cb360f02e86a73584ee9036bc526864725101a316feb562db3762137f730aab170ab2725ebd61e253558e9d669e8566a6eb775e2c76c24577b70d71a8a053adbd07f7e577cbff68129823b09f54744967afab67aac04728888659012331c4525a3c281a0a38442188882c10d3da536d0b788808278b1370aabd111e4f6853dd586445216c2347d70166a1b68191d186186d56a37787feaf58b23b17f504072538417188174a8c5192e782ef4d47195348ef8f78d77687670c48ab676264b66ff15b6086b77268490e70dccb663aa644fe316473384885b1777f49650de583e5e367d99931d5b586c33d734f1077889e88e6e082730c883ed460f39682bdcd491a93476ec661d70074c19898772b7836c7008f4718dcbc22270a21b6f342788667e3b654b8b278c90d80db5687e40f64fb2e00513955eb9388e6d3081e8f050b1736a9a086863f76ea7d27272c51a6d88877af80424f67c23a1910ff47ab4202023a74c0a15717107935e898760098787770692f69127554935e26b28d517c1765835511fd0b77afaa32dcea8191d572500098e25164820696cf27154d2874e10b95badc7719de78966787784b18aafe85387601b28f696ed48606598634656ff77255976f4070e2d378aada899c247726040129db16f4c0123f8910c01074703370f742773ddb79647c853d2536f27210bd43314d1531596c47b824450ecf533e4e78fa71955a4b86d449258ec388ee6f7768137975228773e185f6a308a2f898cb7841ac5498e01590f9ec78231390a20e578829714b2c76fa7f21444277480a98f53f48be42824b938430dc65c33276991591b0a57508d56073278828bf78ede986be0b84d28f963b5011a68b24d8d326f0ba591a8f28e6ad08fff077922611e774693bd06423ec85325a11ade60955cd94a34a55aff009ffb110eac087fb18852219654ae585f51f06a124846c87820f92710cbf920a8c79ee8d98da262ff9060e0a366297ab07723d3839746609aaa588beef499bca67cad799ae4e617f07096524a572ca9767d099db9a79634d57bde768eb2e90f02299262214775252b31779e87502655948e1b919469c980cc7057790591489a9471478b71497b0cb7877e942227097eb8b05208263a419877f4659cdc54257f718ee3974cdd308fa8619a92fa41f5f79b1bf134693a9d29759a00188d7c78262fe96c20581adf816f77fa18e1e78d91176282d64e1cd128cee11efa04654bfa7a23ca865fc97e4adaa088188cd23023b8c34ab612a2a529a110e378a39194aa29add25383e55967fab1975fe98b7286831b9197e6735002285520f58a41169cd96a906289ae14b5ff9d4389558ffaa1a57711bf874ff1d45b5b0a92e7d71c597a4f24da9d38f84080678411d599a60aa6558a14181a9b058baa3df59f302269ad5aad6394a599ea8971f88619f1b02387304b775a6fe20e88885e2a023d308462e9c57f7f2a7773099c892397cee54af03458c9ba96df8a4cd6093ae523a51aba92217a540412927c06a6a409a9e9b58db3269822c49a5d080ffac6558b68808f4845205b8b00a5aeee9748cfea403f458cdb5061b92882b260ae6e0323dbca9741aaab3f358246995fd6c410581ab20b0b52d6aaa5d379a5163b8a781799f2e77b88f428e239ad40fbb1e90787a989a6f444468b2bb902db762df8a54e75b5258895cc07b7af08ff35edb72c16969bdfaa6047298c25789e3d698b3de15c4ab85ae70411e699a94cda340719a59eea75366873a9279021c5556fe419ecf1b0995bbac57b9a7718b2b456a71fd99a13b996207480a4779bd0bb90c228a2ac7b2bc7a8bab5db937ec2654c4a447178b2da6b80dce25db7462415e74c9e6530d97baddc3660964a7e7d226b7538a2dcf980a5c7749a99aabc37afdf0a8bd1c3994eb891d7b8b40bd79bbb28b702f61818d26c6578a26d08bbc7489106b95372fabdeb9b6f70129343fba97656547bfa846651af3a22bb9a90a0b8db6ab0a7b8defaa5b019b150dac22d3c7ffb3b0aa2097b0aac979acb7e95897f3969aa21f454ff3495a9298fa721ff936b03775c3bb53332afa638be0f0881b6e7c4878a6529b28fbdb99bd2705fed111487f606296c0924a05d95fab482e2a11b4bad89b35cfb4bbfeea67b98fb8bb6d48ccdabb05bbca70e984adb50675c48ae80e9adee38991f7abcb813c6c36bb0f7fbb002a82a034a87285a08ec78c75936910c7c7ced7a747578846a228dded4b3c269aa405bb533b7b9aeb795dd3aca99cba282f1c8d38b9f095cc4efea889fd88f114cbe789c50d3fb99325a6ff6362329cacbce96aa8a95117c08667919ccb6c70db3fc36cc470a56ccbc347b8725415f233a12e0f4943ce7b1a76a3eeb39b9295a941a7b3e1c7bbbbebb53ce886b5f4ac49f69800431c5d0ccc4f337ffcdcee8c0735978871748be7c6108f6c0668267e8803eab29964ba9b174926b366bc8917cae932cce897a8f1dfc9d8cb94b07115284e9bb837bae9d2c84a5cc676f1c61a3bbb4db6a62cadac5db426245059d0cedbc0ead9f47476e8e68205ca9387f675f4fba1f45649b48f71ee8d81e847617ad80d3835744c90ccce9c9cc413868de9169480880284dd1ba64d1cd6c49130c8c858c95e48b7fbf793eed2c2451cc8a191969bafc4f8e0cacca8cd4621b1824711459f1b64a178a401d646d1d2862c772f78bae9d777bcbb17f1e34186f7dd3e248206f89d0c37cb7777014002d05e0040ae9f7a7225bce5ead97fc38c1cecbd1f65c15c089b1f347718b1cff8771eaa6fb2cd0fd9cd03a39806e9da6f1e111a9f1d6da6082dcb2084c8c7328619baafd6b208184a72d7fd0e4da362dd4492cd3c851071f641478544cef1ba68d6bae198dafcb2aa7b2ecce536bb5b3d7b820e9d2b508a03edddb2efadb312d817e476403ed131208127c5c24ba833087e012f5f640c01507a7a65df39a62da89defd7397e7c0d74be1d76e6d15ecfb24a072d761004e15e5c5e2e867b587c9446ca314274dc039d9f658941303bbf869c4cddccb3003d7f82dd7305b7cfc2d76607c3b53c018c075133db14e8c240ede7a6ee451288741099ca05d5886db60ac4d890c1d6b78dbd1883eefb6db51ad189e404b9c014e2e9754048230087effc4f5d8bab81cc8cecd7efc7688e15ad5feacd0aebd0e9c91e323b4e35202af1fc1c9538371e2c126c9900d2e4b31bc301766f3de881211c5f23544b1c92c8704f0050dff091f775a14a790de8b7d4030b5bd5de54de42c9608a2a2ddc036846cab381d83094eccbcd6ae3aec9b1f3cd44a4c9da8926bd0da17f4ade7f65dcd9cba6f4313446a69cd9f9e129da0e69b45755ff13525401301751329673033c113335ea120aee2227e258e955c70f34d4435852b2844cf57da17dee14a611ff52cc1e61153ee4cc5568cc0c79cb1143aebd158eb1d75eb803818f9363b79f0c0d92e6f65537dc93240acbeeadd1e19e2716c27631963fe11658e69677e372e36ffa8d7b470b5b90e79fda3163eb98aa3bc87debb45e9a3c1a77c002d0bf45806f04abcedd07da81007eb5e1dc3e9eeea6a8fdc6e1d149d33c3a50f7a065d1eb318cf1232012359fe3261e32eeba2eee927e13348e2e3b9048561caebd64073dedda49bfe76755cc4742da31f47a38779d48f5aa2104cd1ad0e8c032119d7012081431134f63809d1257e15ee1c63eed35b183e9351302419a43293f95d9c326514184ee5a64d4b260c15fa5691478868ae38188cb15195241e59212db1eb2ae08225e48171dbb3eaf9822c2403f28e41e2464ff51a45e22aff851922c3d0fe04325fd4746ae1b8594e3f770e41c71ff41330d4615eceb0f298903793e23df2b3ff3d3a945f2a4cf228e34394f82c3cae2d4a4123bd6657a9f51cf231bc884a8ce66def8317fac2130a1be62e5e2221ee552ca0a4297de32b15c4fbb0a4352d8b6910da8271e21c8736d0f8ec6534f5672eaf15dac32b1141f7be52fd9dc53a5906369c70f4c37fa079d38b2a43c2b9838faac2260992f58406bc11c3fc5692127aa2f948cf23bce23128742921d4fda2f51b401000948845e31199542e994de7131a954ea94640a0da148d48008028241291465c6e8844123db765ae5a0c0e8de6e034a9781f298759e7d52b40c88f304948a8af30aaaca48cacc98b2852b16890f21233537373e98a7344cceb4b2c0de04d0d8f0de00e8cd4f12c6d2d2a91f3cc10919613ca16379788b1f111b26ff2d2b2f7183939198b730b30b5c4d36d6ff1abab8b94ec744c595790b89b094b30bcd1f7b769109c92b9dcfd1d7ea99d1330717d4a5410ba683a5ee9f09ebf219ec25143272c90a679fe183644c62b53a0610bab04a2e850de15630e075eec358dda9f68043141c4781265169325118d64472ea5b812304f762cd80f4ac78d8a56c6f4f9f39d4689ec0202b5199364b23d07450e05fa146a5426f90e152bfaf368caa4c896e22b72556a58b1282d7aa4b2336a56b23d33190c898f6dd820003b"];

        private var _renderData:BitmapData = new BitmapData(_stageW,_stageW,true,0x00FFFFFF);
        private var _renderRect:Rectangle = new Rectangle(0,0,_stageW,_stageH);
        private var _terrainData:BitmapData;
        private var _terrainBitmap:Bitmap;
        private var _loader:Loader;
        private var _assetsMemoryBank:Vector.<BitmapData> = new Vector.<BitmapData>;
        private var _assetsNum:uint = 0;
        private var _maxLemmingsNum:uint = 167; //try up to 5000 lemmings: no problem
        private var _onScreenLemmingsNum:uint = 0;
        private var _lemmings:Vector.<LemmingSprite> = new Vector.<LemmingSprite>;
        private var _generateTimer:uint;
        private var _generationTime:uint = 500; //generation of a lemming every xxx ms. Try tweak it
        private var _lemmingVx:Number = .4; //horizontal translation of lemming
        private var _lemmingVy:Number = 1;    //vertical translation of lemming while falling

        public function LemmingsFollowTerrain (){
            Wonderfl.capture_delay(20);
            setProps(stage, {quality:StageQuality.LOW,scaleMode:StageScaleMode.NO_SCALE,align:StageAlign.TOP_LEFT});
            prepareAsset(0);
        }

        private function prepareAsset(n:int):void{
            var bytes:ByteArray = new ByteArray();
            var data1:Array=_graphicsData[n].split("");
            var data2:Array=[];
            var d1l:int = data1.length;
            for (var i:int=0;i<d1l;i+=2){
                data2.push("0x"+data1[i]+data1[i+1]);
            }
            var d2l:int = data2.length;
            for (var j:int=0;j<d2l;++j){
                bytes[j] = data2[j];
            }
            _loader = new Loader();
            _loader.contentLoaderInfo.addEventListener(Event.COMPLETE,assetLoaded);
            _loader.loadBytes(bytes);
        }

        private function assetLoaded(event:Event):void {
            var t:BitmapData = new BitmapData(_loader.content.width,_loader.content.height,true,0x00FFFFFF);
            t.draw(_loader.content);
            _assetsMemoryBank.push(t);
            _assetsNum++;
            if (_assetsNum<_graphicsData.length) {prepareAsset(_assetsNum);}
            else {initAnimation();}
        }

        private function initAnimation():void {
            //prepare terrain
            _terrainData = new BitmapData(_assetsMemoryBank[4].width, _assetsMemoryBank[4].height,true,0x00FFFFFF);
            _terrainData.draw(_assetsMemoryBank[4]);
            addChild(new Bitmap(_terrainData));
            //render will hold lemmings
            addChild(new Bitmap(_renderData));
            addChild( new Stats() );
            _generateTimer = getTimer();
            addEventListener(Event.ENTER_FRAME, renderDisplay);
        }

        private function renderDisplay(e:Event):void {
            var t:uint = getTimer();
            //update lemming generation every _generationTime ms
            if (_onScreenLemmingsNum<_maxLemmingsNum && t-_generateTimer > _generationTime) {
                _generateTimer = t;
                _onScreenLemmingsNum++;
                addLemming();
            }

            var z:uint=_onScreenLemmingsNum;
            _renderData.lock();
            _renderData.fillRect(_renderRect,0x00FFFFFF);
            while(z--){
                var a:LemmingSprite = _lemmings[z>>0];
                moveLogic(a);
                a.x+=a.vx;
                a.y+=a.vy;
                if (t - a.ti >=a.spd){
                    a.im = (++a.im)%a.imArL; //update frame to display
                    a.ti = t; //update inner time
                }
                _renderData.copyPixels(_assetsMemoryBank[a.bmd],new Rectangle(a.imAr[a.im]*a.imW,0,a.imW,a.imH),new Point(a.x,a.y),null, null, true);//null, null, true for transparency
            }
            _renderData.unlock();
        }


        private function addLemming():void {
            _lemmings.push(createLemming(90,65,_lemmingVx,_lemmingVy,_lemmingVx,0,[0,1,2,3,4,5,6,7],0,70,randomNumber(0,8),6));
        }

        private function moveLogic(d:LemmingSprite):void{
            var xx:uint = Math.round(d.x);
            var yy:uint = Math.round(d.y);
            if (yy>_terrainData.height) {d.vx=0,d.vy=0;d.xFactor=1;d.x=90,d.y=65;d.imAr = [0,1,2,3,4,5,6,7]; d.bmd=0; return;}
            //test pixel under position (lemmign sprite is 6 pixels in width, get at 3)
            var p:uint = _terrainData.getPixel(xx+3,yy+d.imH);
            if (p == 0) {
                d.vx=0;
                d.vy=d.ovy;
                d.fallRepeat++;
                if (d.fallRepeat>=5 && (d.bmd==0 || d.bmd==1)) {
                    if (d.xFactor == 1) {
                        d.bmd = 2;
                    }
                    else if (d.xFactor == -1) {
                        d.bmd = 3;
                    }
                    d.imAr=[0,1,2,3];
                    d.imArL = d.imAr.length;
                    d.im = randomNumber(0,d.imArL-1);
                }
            }
            else {
                d.fallRepeat = 0;
                d.vx = d.ovx * d.xFactor;
                d.vy = 0;
                //test pixel on xfactor side of sprite
                var sum:uint=0;
                for (var i:uint=1;i<6;++i) {
                    p = _terrainData.getPixel(xx+3+d.xFactor,yy+d.imH - i);
                    if (p!=0) {sum++;}
                }
                if (sum<4) {
                    // there is sum pixels, move accordingly
                    d.vy = -(d.ovy * sum);
                }
                else {
                    d.xFactor = -(d.xFactor);//obstacle too high, inverse xfactor (lemming will go other way)
                }
                if (d.bmd != 0 && d.bmd != 1) {
                    d.imAr=[0,1,2,3,4,5,6,7];
                    d.imArL=d.imAr.length;
                    d.im = randomNumber(0,d.imArL-1)
                }
                if (d.xFactor == -1) {
                    d.bmd = 1;
                }
                else {
                    d.bmd = 0;
                }
            }
        }



        private function createLemming(x:Number,y:Number,ovx:Number,ovy:Number,vx:Number,vy:Number,imAr:Array,bmd:uint,spd:uint,im:uint,imW:uint):LemmingSprite {
            var p:LemmingSprite=new LemmingSprite();
            setProps(p, {x:x,y:y,ovx:ovx,ovy:ovy,vx:vx,vy:vy,imAr:imAr,imArL:imAr.length,bmd:bmd,spd:spd,ti:getTimer(),im:im,imW:imW,imH:_assetsMemoryBank[bmd].height});
            return( p );
        }

        private function randomNumber(low:uint, high:uint):uint{
            return Math.round(Math.random() * (high - low) + low);
        }

        private function setProps(o:*,p:Object):void {
            for (var k:String in p) {o[k]=p[k];}
        }
    }
}

class LemmingSprite {
    public var x:Number;//current x
    public var y:uint;//current y
    public var xFactor:int = 1; //1 for left, -1 for right
    public var ovx:Number;//original vx
    public var ovy:Number;//original vy
    public var vx:Number;//translation in x
    public var vy:Number;//translation in y
    public var imAr:Array;//frames array
    public var imArL:uint;//precomputed length for the frames array
    public var bmd:uint;//bitmapData reference
    public var spd:uint;//frequence in ms of animation
    public var ti:uint;//inner time
    public var im:uint;//current frame counter
    public var imW:uint;//width for subdivision
    public var imH:uint;//height for subdivision
    public var fallRepeat:uint = 0; //Repeat falling counter
}