Transaction Hash:
Block:
16905835 at Mar-25-2023 05:02:47 PM +UTC
Transaction Fee:
0.042331965224274168 ETH
$92.88
Gas Used:
1,806,456 Gas / 23.433709553 Gwei
Emitted Events:
316 |
TransparentUpgradeableProxy.0x5e3c1311ea442664e8b1611bfabef659120ea7a0a2cfc0667700bebc69cbffe1( 0x5e3c1311ea442664e8b1611bfabef659120ea7a0a2cfc0667700bebc69cbffe1, 0x00000000000000000000000000000000000000000000000000000000000a918b, 0x655dcd01087b0728d5feb31b2cf6680ea6dc99f406aba1f0b2897955c8d3e400, 0000000000000000000000001c479675ad559dc151f6ec7ed3fbf8cee79582b6, 000000000000000000000000000000000000000000000000000000000000000d, 000000000000000000000000c1b634853cb333d3ad8663715b08f41a3aec47cc, 86c9604fe406f17ab98ad81de321e1dc23b9091cf7cc08cd432208340aa8a3d6, 0000000000000000000000000000000000000000000000000000000570daad2b, 00000000000000000000000000000000000000000000000000000000641f2937 )
|
317 |
TransparentUpgradeableProxy.0xff64905f73a67fb594e0f940a8075a860db489ad991e032f48c81123eb52d60b( 0xff64905f73a67fb594e0f940a8075a860db489ad991e032f48c81123eb52d60b, 0x00000000000000000000000000000000000000000000000000000000000a918b, 0000000000000000000000000000000000000000000000000000000000000020, 0000000000000000000000000000000000000000000000000000000000000094, 00000000000000000000000000000000000000000000000000000000641f2937, c1b634853cb333d3ad8663715b08f41a3aec47cc66653c8669e2e090297f73a4, c844adb9b506feee82971881a69c5e5bb59343b4000000000000000000000000, 000000000000000000000000000000000001cbf6000000000000000000000000, 0000000000000000000000000000000570daad2b000000000000000000000000 )
|
318 |
TransparentUpgradeableProxy.0x7394f4a19a13c7b92b5bb71033245305946ef78452f7b4986ac1390b5df4ebd7( 0x7394f4a19a13c7b92b5bb71033245305946ef78452f7b4986ac1390b5df4ebd7, 0x000000000000000000000000000000000000000000000000000000000001cbf6, 0xa92adf543b5b428211652f7a9c7ec682d13f0b02fc44ea45e3cc3a651c19da04, 0xef682736dd2471124dd036eed7d486791fa66d7d852590c82c18c85676da5bc9, 540ee91eed6386657f901eea3f6d2be2f1e69dcc2bda93c553d4c8f90b9e47b4, 00000000000000000000000000000000000000000000000000000000000a915b, 00000000000000000000000000000000000000000000000000000000641dd7b7, 00000000000000000000000000000000000000000000000000000000641f3747, 000000000000000000000000000000000000000000000000000000000101dfeb, 000000000000000000000000000000000000000000000000000000000101f677, 0000000000000000000000000000000000000000000000000000000000000000 )
|
319 |
GasRefunder.RefundedGasCosts( refundee=[Sender] 0xc1b634853cb333d3ad8663715b08f41a3aec47cc, contractAddress=[Receiver] TransparentUpgradeableProxy, success=True, gas=1843340, gasPrice=23433709553, amountPaid=42462801423434859 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x690B9A9E...Db4FaC990
Miner
| (builder0x69) | 3.120565887370446577 Eth | 3.120684198861386689 Eth | 0.000118311490940112 | |
0x8315177a...4DBd7ed3a | (Arbitrum: Bridge) | ||||
0xC1b63485...A3Aec47cc | (Arbitrum: Batch Submitter) |
5.001005511244483385 Eth
Nonce: 66481
|
5.001136347443644076 Eth
Nonce: 66482
| 0.000130836199160691 | |
0xe64a54E2...80E2E4eb5 | 518.20719380744487183 Eth | 518.164731006021436971 Eth | 0.042462801423434859 |
Execution Trace
TransparentUpgradeableProxy.8f111f3c( )
SequencerInbox.addSequencerL2BatchFromOrigin( sequenceNumber=117750, data=0x005B6B15340A696A71D6438BA2A2D7C319E949ABC503A08ED4853F7FFEFD33705C8F75DE0364B7BBFFB7CB1823639715B16387AC8CB9B29E7F6357DE8C9C681AABE251DE9E196335AC88015AE7FF7B193999F1B2868DA913351DB331354C4C4DE44C44FC0F6E9A1BA922294D5253E17ADC5EF309614683E8E641DACE69CF6C22E6FF7F5FCE6AAB08F303C969B98691ACA17B55E3B49648FD10EA22A41A647C745A380F35735AC0E11CB94A113FE285532644391291DD80E943DA35DB3521B23CE03CFFC77BF77D8114929C8480ECF811AA6C099303981C24BB0629A971902007C61E668BFFC36D881FD1C30CD430FF8CFF15C969543395242E0EB25CD3F0853BCF11B051CD389D3DCE768FCEECEDB858F56E5DB9D8013D6BD74BEFAA17BB9E97B5ECF9D769AEFA0E49E1EDA2020F53874976582FD158826122F832BC27436A73809CC384E523706D7DFDC401FB08C9498937205E7104F29557E061061C337AEE30B563F7AD3A5652096E7BB25766BAA0D87C19F32D0F3BF671FD8A8C842DA23519B36806BE15BE9CB7AB288A4849C29A0CB59A816FC5F72597758B0BA608496C56021CEDC4C6B79F804083E0992316CE06C0819FEFC7C39810B04B186D5C596D6C0B124DCC71834431BA8A601A9FAB7A66DDEEFEB4B2FA1751717BE9245693E79660F187FCB9128005CB7E57498B02B819A8947455548047B5C143D9C5B8F879B948F08F93AA6B4BB223DCBA3063920D40F64B9137E41B9770E203E6901B252E1FFCD77D1ECFDECEFF2228C75024F3233BDD8FC2CC6A199868729B4B6C0FE93097684A94295A6F18297C9FB7EA05F619AB028784DA7F92372CAD5C6448FA6DD275C8AF5E3019AFECE790D24FD80F1A6E93FCEB2087A86767EE7F6F7EE4874AAAF459537934EA4BA598C2B528B24D3CD9F11791E38AC3A1CD6FC4C5318AC0960E4DC04B0AA044454A31D0E083455F4D86C9404E07B370811B2ED28EEE1864235AFD42CE20F53F2EF294F5B3AAECEA975FBBD34DA57FF1379ACB954EADA83AC8851ECBD1AC5474F61DE38F3EEAF833EAB47C25D9E52CCED3285D89E5C384EC8136C4E719260D8C0ACB3E0EAD8502B5E2A1C0009E2D0DD23AC1C0EDC2E495E5F725CF56DE509F30A12F95743364B7B3F6DD217D056EA46155ECA5DB08A9677542D9B32003CCF7BFF28F4253FC7CDB23EFCFF1C6C1412C280BC00140FFEFD72004ECC22FAEACD60889262439C6A1F0CD95301B8775A11B2CBD05352125275A7F4B8F3F002D3B89BCD4FED489A552481C12F2FE4157A37993EBFBB73D8639181254DC4CE0C5AA1EFEAE51233D72FEBB0FF5438EED1FB5A6EE9E5E0EEAD91F245ED52BBD6FB32C79CCC9BD5D03661B72BE1F7F0800000000C01704ECA226AEAC360E468B4413921CE350644A1698AB19AD2D20E675C7A0B04FAD39EE71E3820BCC0DD9A8E67C2D13080000804E0E7AF835C2B141A239259353611F120742F91E4464FF6B1D6C0D9DAC8B524D96FEFC04952E2E7B99EC57153D8F5EC2976A21CE8F668DA5466DBC034926E76B9CEE492F5EB98C69D92D559BCF9AEA4E657FFC87C59B7D80963A4B15137DA088D67F634A2E4A7DAA99EEB13EADB29DA191D3AC4855D71F4036AA11D97CA8BF2463A1A0A0A034BEF2526BC2FD188F7F127289AF4A1475ABD4800321951FB71AA96CBEA53AE25D8ADE1F16C13B83C94F515F29BAB044395DCD434D8E1019E5152FF790F3BDB0AF7B1D34C92E6EB4712FB80D26FAC4B3FA13A3A93C381D9C1FF6C53F5AAA0F1D2C906892FD7600C5BA3088D97CA5F29CF8605778FDF0888D7E8526122F81C6098985A955E418CC00120CFB366C602C941C019153209475FE246BB2F4428197922F85E523BFCAE2B210FBD36CE70A3118425CB5965A540AC1FAF7ECEF774DFF3C557EAAD8549B5A8AA411903639B109AA48276A18809E31A8F0A1336CB8D79C2E37F9D700915B4D4D4B492792BA4C7D2677CFA52D6D54698DCAA88D61C39B8BA0C610718103A1FABFB99A6C0B847FA17612B3370D642F2878FBD722FC8B30F057BD28544F4636C4FFAAC8247EE564829C83E2802038D980F27B89944D3D3D6E4C2F43E7D763754B7C6A300A01BB04C3CA765F83ED6D296FD802A637F06660C2F8F49D0FB04D8E25FDCBCE52A7969E04EB4E3969A6467B6341C49738C175AE07DDA70549402D0331BDDACDAB77910D3F518EA57CC24A4B657C09AA475B025C132736E1FC23080D09948955CBDFB667F3B3DA88488731FCD86E1C5F392F32211A0742F3014B5E97BFFFDC586DE76DFB7A9225199B45304CEE50FF5008E8FD30A2F72911221517A1575557390C2EB228DB05A5BD1C8DD5FD96DACA7784EE8ED6BD8C962DC0173689805D8CC695D5C6C98EBC88034519248761BF8FFDB87BBEEDEAD6FFCA1F9057505DB5F76443363AB9DF4F3FB83E43FA4FE8D93364A5C9325818BFBF115682FB563C8075808214E734E08848C1FF7BDC65F15BC12A21442559BC0107382484C0FFD7FCD3F9C9685CCE9C173C3871B482FBBA277D4F4A9B68EB21D5F7ABD359888A5869F0D9C586B46D5EBCFDF0C7B8067A518CEF97A198261796E87381BC586D2C2800C001FCBE4E44C02E507165B528180F05121D2A890150F2440006FE08F8FF4AE02F890BEAC6C85F8650FC5D238B19320F046B5EE789CE47487B891A7060F107B220D1D3A3A6222520312152A1583AEA55C6EE97579E551FCF4DDFF252A741E0A6DD0B51F213CB55C4134C8779AB262A892230B86DFA46E57452EE66DC3D844FFE1201BB488F2BABE52D6E0E8CF14BCC4BA1CD976A0CCC9488ADC7E6377146D0C61B674D649915C3272BC639E9D79A4770F8EFBF91332C111BBC16178712C1213810AA5B5591207FCE25DC56C825B9127937941661793C64B0A9B682365C926729488218F7FD3A034A837A4402EE04A58CB091073E207F9D8DF1C952713EA4FB260F7F8C85290070207DFC0402763162954CC94B9BC4311493D1E0127E7E282082A3B648BC919C8E395B2D788F6C74429BE058A8EFC06E52A31C3A27785F4320D8AC487DA86345AF095091C0DBE7A80A100742932D0C0ED283011B8D5F3D7B78461C9A4AC8FB3598383494A8B3341EE628A1C721171C10F1FCFC52983571D484A5FFF16BA72CBAEDF5D017E2E427A9C6979E9E99FDFB87A039E2123489ED43E3678422515464E51826D85C5ACD68EE7EBA594970635A54AA467E307E125E19DB5E6EAE0E53E346CC1F8FAF57D7110C0CBB3260009084059E2E13EDFC2F1FDFD969BB7EF6C259FB8BE756739529F511D6C3898D1F02849E2F497A7A1641D7E71452DA39D90953E7057D455D2FFA6C50A05602D40B3526331D0897F0EABC7DF0DD27FAC6C7CF239917EF8AFB6E418CAF3B838F34445FA1BE8695665F707421AC369CD175AC617061BD9DE44C3D4E0955E62BD2E18F838358785CC866BDB29CF96CF2D1963285DD6274EDF0A8D0DF851F81ADBD8F476C75D45A7E146D26668C552F5F20390D6068C92C53DDE60076DB903FB0889CD804A4E560248012B3761414F0C241C720BC06CFA30670D580C04680735C3AB09BA7EE4A517FDDC3562104A8BA058D6085248D0E169F54814342226B671FE741AEB79A7EDBF51A05025D22ED925BD5155A1B56839D6A162E53EC1075C35FE4F4D8395F5C5E0E0D624BE5AD1552D92FA943301399F7251FB9A6E87138430B46C02EFCE3CA6A91C8787834C53480C2EF278AC8760FE755F77CCEF29DB33FA58A1AED1BAA87EB9413A71D3EF44703D2D486C2EAEFC5A17094939480FBE7C8ED4DC7A0BF7AF3FD330D9EDC7A7F6F7E883DB8A2E338E00DC0829640B5CA62B2B741241AEF741540D130F13ABB4E4E2460FCAF950E001F5F83E17FA13CF1D8AC73DED48721FCE71BE6BB314F13847B77BB3D124B31596589DCC688115D4632E38C0AECBA94748E93F61367DA847EFB236F99E8714848BCD75B8D986B7AE5D38863DE4B120D51C2F09306C2DFED68B52BBDC68E52171B4804333BC81F72A36D39B72678E92F494E80EDB0F26FF19439CC6DCF7572467DC2E2FF8B1979412F33D72AD1B43AA61D0417351ACB67F9E2D2F22CE22DC91A70F48EBDC0BB5ABD605240C5050E09750BDAFEDE367CE62C2BB14E5254D53E157EC2913AF09677FBDB818D854D4D9413A4AC9EE287749EEF7491BD247290D6F7946720B4A899AB285A7692B6C4B4D68C3213985EEC623CAEAC162F93707F38E8A328E82E311F29DCD3E30D8D068302C6AE24EDB53EE94CD36F231B9DD4EF0B494BB10090AC0CEFAE7CABFFE0145764894BAD77F33E0DE140286285CE449C1F91C5E1BE70E9BCCB7FCC46B24BF3CC727266B0EAF7664D9A0425E44A276761AC9733D9DFE515FF0EB2E8B9574F286FCEBCCA33D6904594B810FB177EF0B9115882E7C7E13D0F8AB9D43ACAE8C0CE143A0D89051156143FB3A52C413034F924F5A482EB715776B8025042FFA6CBEE6E2E2B0BCF02BB24768DB50EE7078EF66B19F9B01E4E6CA2BF010A8D449382D7E75165FCAA76436A879DC4AAF98128D4BD1FC066D5B8C081D097D1E08F23AF0FB4D7E3DE2677C7D85477F9733DF9908A1771BFE093BA656956032475DAA2DB213CA0E99BAE609A8E307E5E333D609CFC15F9ABB3299DB053F669F719BE00F824E2123E8A22A8B16A8FEBAF06D60230745152F36BBC8C7AF30233627A710E19588E9F2F9058B8138F6844D1B38CCB3FE8BAA4705CF0E7F5957625BD62B7B3E115F4D71FF58B722844E9487876331EF4E4E92EBED442BF15BB7FFFF675BB7CDD2266B5C83E0AEAFE454C7E671B480A02C702B0A017482FB0B241B063512AD9E570F4A48E1A0D9684ADE1DBB1E820C0C50523418663EFDAC23ABBA2E5DF2E8375C3ACDF009FFB0616E78D0913D154DB7B0626F72D26026FC5BBB53DE9CCB1CCA9591C42025092F1F23FC81A78C799D01C2428305F0403A434833A9A716E6748DF17F846F1F323ADA8E0C7F25F316D00B86A7E5218084A49BBCDB4A70C843DB7B267F4DB9E79C01CEC9F78C1A56A54DCFA135BC9063D7F230A23CFD434C84C4C9C7D81F8B912A6BB9E12D03238FEBCAF72585A11FA8005730B404B9635331B648B06612E711CABDABF35269EAF7D8D5688D916051161C368869733FF7048A8F5C19DAEEADF58C1B0E047951C43EB0FA430A2E6C463235C866946370D33FA5210581B3FFF5EAB95CA0FB5F63E5889C5DDAEED2EA71861676CF26B398331D1D3F453B8BB028A3CE25DFFE13DEAC5845C3354991256DE54A6261CA020243E47CDC0B5688F87DB348714837CF1BB0106949BBEEE44D13EF4A84EC374707E28EC1C8F539C6F5CD08A760C59051FF38C32BC9DDE2FE7525E746A6E59F2DA55935EC0EBD000DB478D417ADEF6D82DEE219BD8A544C8424C21B98A686400CE22ABAF75A26B28F6E0AD1FA604B529FB94985CC7C6B1827EC474DD2F0B31EABBD74BD67FC44D28638AE67CFECC32F4B524C54F9912E5973A21C477B6905884B3AD99093FA002D4EA702D3DC49C1CCE570C00C44CFA480095AF8FB3968FA39BA9A4BAB3B35AB88FBDB7BB23A01A0F7E0F20B68953ED632FBB00117BEF4B09E48E394CE8203BDF979E9F4C5AB6F7E5CEA203B6512FDDF83D51EBE3399FDB127C06CC0400609A949F1F556BE2149222CB6DF46B67E98DEAAEB0F3B5D4465FA23040CFB1AE2345ED1CBA4CCC677CF5FDB5C2992FDD64007AFB221F6B902526D0F7C022AB1900824181DD198D6827A100ADFF975192911A9A3E2C2846F798BA478E6D9B00E7F3197B7537A3304573D3C5668A5792B7AAA1F52F6CC5CA60F0D4210811C6283D403D1E67DFD3A54B4775C6A1DF321B6D66F9CF6573F0E28072AD97373B27CD110E843A927DB673AB388D25F6C60EE9DCEC4EC4239E9B7E1C81C9765C8B69F701EF0B20F5E443AD9AB0486D5894B81276385FA86E3A1981C1610AFD9FDD333F666F59C2C2A34A1E145657B1F4716EB12306636CFDFE7EA4B9CCCC570F6632BFCF1BF9E8FDA6F424D09E1EDAE2B82FCF0400210ABE3925ADBF1E5AFBB51ACE2110598BC41BC4997223BB36E9C5DB12954A8124883F64C2A14052DCA8EDE37519455EB6504547A3D1C2BD2E5EF19FB4177C4A7AA6E6E9623E49D2972DF2D3B5997812EDDA76EC937613B6BFB593C9F818EF9A1853558A27C81FA50923FA0D3D86AFF7AC76ECF0224ADBEA2ABE638A98B88C8A5E5FE9D0DC6BD1D15526B9E5113F781D5359CE7DC8677F9447E5A18829299E2AF74A1FF927C06F1BF6AE59BB4BF5F3E97A12CD9BAE81560C0EC082688D043CDB8A4853BA44AE4469BADE4CE6F936A527863F93BFC0112D4D55C0A1881220AEDC58F1BEEF48BBBCAA1804147993D9DFA95C002B0F80AE6BBC6BE19010ECAB7AE132EDCBA27DA6FA8FE152BF536ABF12629B26CE9249AF5A96FEC8E7D941BED685F6EDFA91332D93A5C8FDD11B42B7A19F8F7683CAE4DC0D228ADF452E3DC48253001C000000D764202E52295A0CA24148CE59E5DB2C8B9AFFDD27FD6F4AC2FAAC0E4630DABAAB558B8B232076BD89AFF39930E927D406F9DB34A5AF70E58E079D82FD6B631F7ED0DE89A833AEBA86FC04B9D35BA8944A56CB67B9FDE16167E9BE3AA47BE3D3C70E428E4FF6CC6D087937008092884B501C056B998C177971380AA0417161004331CD4730B74309FD32A3545527B954E5F92BD7806CEC347BD2F60399B435FB305307C0D8DD09BE671779AFA57762E33B2A3EFEF8ED45413C328098C8E379C9ED7B20D0B871F059796553D6669FFBE45D10EAB4EDC77FBD563B8F519720985C713FE52404463B46F7220D2CD50AAED41E2C7184876EFF174489FD8A3E4CB1124BF3612FC2226AF43542111741B1932D25AD32C3AF3125C5979364B464D8AB7A75AF183DBA7EB7E63AE41FF3698D3CEB7DC674FBDDFF5A8694A2985D7E87902CD0FCABC112A3C8DDE5771E90011BC2817B744CC1496AA597D6B200EDE8786CB3437DA755A6F971DFA87F0693F861051D06B5B37DFBA1023D1485316A45C95A7BE9CD2565BAB70B25F5FD312DA3A54EE046924A4DAE6061DCC5ADE4D70083F1DEC66EA09E9FD2AC24B69AFC0F1F20AF9CEEFBBBF4C5ECCD8207683B2CC3879F11A4F2451152451439CA1435B1B17B4CD440F7CF6383523FF7804A1538109AC2AC7C3A4E79C2178AFA798EFE8335B4E61754D2E3A2E49CD5E8E594EAADFF0C69BE3F95FA5AEDD8E725BC8A95BEEFF0842AF95640CC8F476C383E55FE31B3E30AD1F82006D66352C11ECC80E183DD05DAD4F9832330F05F51A5E2F9B214394A7CC22B6CD6A59CFA7E936E160F8E980F46113C3E849DD9D2823FF8A959593D958BB2D9AFFEC817793CF78C916A7AE931FBBBCF6B5C4209E54527784FE7AE2EDBEA58A1905F234B102B35A9E9DC9B2ED171285E898B731D0BE22AD40F9D24C85FD15B5D1696BBFC0263268188C5CC7763DAA939F54D817332104E46E1BDB47BF645B627B594EF0E24BB73E2B468CEDEFB1FE9CA93621CE4C75E11B56C7AD2971A2CDBE67736095FCD08F951E9273658F340566C71E2B702E1E2584B2F426232C977E27D483FB466E390C6CE356E90D5E94D44FB5B8619005DD2BE832E8D94232514C2A8599E8ABE5D8EF985BD787F4796D6C797861E494A232260987E73462B24777673A17B55C75C3F138E1A7CC30AEEA4F201E2AFD2FFA4BC7DF527C1873225EF9BD8052CF566DEAE387D7D4BC74A971C18861E35A5514C1BCF50F4CEEAD7B966DC713CE8391A84B5E56CE7E8875633CC27B0B2662DE2A22A8EC8FED6BAED438EC488BA7E1CF795267925285E9BDF83F152987A44DE8DDBA5DADB52DC00A038AF1DF3E3C364C69D5B39710A795955F444AB56E7E30C67F38FE68B2BACEFE616F8E4F721D7A870CB6DDB1553215A5B8F6D12CCEA344BEFC945F861EE7CEBEB58B931B991592867D924C3DA4F63820E1C75B943A4DE37C9D731F376466A59AD8D9B40F746127D778BF0E457A37917BF45C0282C0504542DBDE97B3FE82AB6B6D23D264AB553785617F4B32B68F78B1024FFB6C98FD9904077D58275F8A571F054A285A2B930B632ECDB6AA667E0AB82152CF810800300000000F00D01BBA88B2BAB3544E39DAE0268BC5348223A60EBC00968D6BAAC3C31216E5A15E980C37C5ECB378057399E26D67351DD72471895973E76BB9FB38D3F44FFB4499AD5ED2F1F6FC1518D57DDB9A4CAD88B4A17B6D33790D3E365795AC6EFB130C5B979CBB242139056C670E26B172BCCF029D1F1C3F13258FC2DDE0CCD1F4A24896E98646E9B5A1C2266C53C64C29063CB57667FFBFE2D122DCD0394E34048E4FCA445DE283E48F70E526B1C2FB72934857709B6291B3F98FAAFB6B1EA8D35C4E1A0F6EBBDD6DD653BEBA3041E2F76C177FBD4D5536F907A326101B7B10F1A35B1B002000E0000C04A70C0A115F4E95E42B719D65C31529B5E5DC2CF894FF1C79C5D9D0DEFCC8ADDD264B30C41B576053999DB1898C8305003284D44792932E4B9EE57378C3953DFF9D54C19FD3ED79A9407033A02E0E501FC9A1C1CE117D59D7EDC5E5304C8DE16C4B3B4D66E4FC9295728A1DA04995C676E5231CFFEAEF8E390D0B2BD09816265C0BFF1CEF6FBF09536DB92339F79CDD252C0DFE8600EDFC58615727A5C0EE06F060DCA0F3FEA9B7EB4BB580C4B41CC3FDAB58F4B5C62DC616CA08077AC573662A7C77939488C43D7E7B8D08DD70A95AA0BAE8F15FA58BAE39CE02881523AD5D2647040B2B1E7669877F5D7A4225636FC0BDF1F79D96DE8F4B3EF6E00F879EDCB9E004FEDDC0A0E84AAA464071F5042FA2F03AF2691A21F2F431DFB7AE24C768985EFDD0B722DBC7B1762307DFBB47636D269A947F163B62CFFD7B3AEEE88E1267AFE6233F4FBDB1601AA22E375404D4B9C253AA23874EC68AFAAAC16A047914CCF8395E70D38527EAEF772C22C5AFBC5E550FD6746612B7CE860216535E50F2340ABF6E6B5C00B02485CBB99856D105B6A6C4624FCB2A92EB0E7E6ADA8DBB9F79FE3A85F09237DCD0DF476125F88904A35955D0C3DF73B66729F6BDE098BA0E3AFDEAF4FF5E63927612CB16C9D691582CAFDE5AD240B2DDF8F4BE6F582666E55B2E04068F87EDD9FE34AFA20FB506E817F1221F00F78665F2088DF3640173C8A9FCE6D85640BDC4317C27C5C685F70E6A825C5BFA0E3EBA3BA6DAB22D4276457AAD8A5F4C62228CC7DE907884B501405331F966E1B39F36192B088E7B10A452775A4C70B569FE52E2D397FCEE27B859DDA35632F2EFA9E86EFEFA4CB27652BF99C10EFE6EA0EF9941EB295A29105F773F2F9DBA74B4C4DD4565ABDCAC429FD18FED5F37268A663EFD574F9FD872F19FE8BADDE72A89AC5DB00A98D4E6C024CBCE6EA49BEE7702129FF7BAFD78DABDB29323C8AB551E0EFA3FC39739FA8F0A417CD1AADD436818A9B9F21F1B7EBDF24855BB34DC26AE9A6F68867EDD3CF9AAAAB35B7DE1964448B993870013DBE099C3A5EA86374A45E5856A7792697BACCF00F9E2F7D7BF7EB31EA4AEED1D365BBCF3F28C244760B19D313735ABD0C0E02D9655CCFFED83C13C91191C0A3754CFFB6AB211E1A2D6CB6C9FEC375E77398B3C16A21CC7A83CFBC0F529BEB14E2A9BEA13E94D3871C284589D6981E5B092A25FFFEDEABE231734AC76B38E6EAB3C2D5FDC4F4640F1F95D4858C85ECCA3810B49D6ED3AD2B60AA4CE9A295CCF9FB6CAC7510B8DE6895B46FAA8298A22C29781F9D5ED8B6906C10511C7736A4F9E5A46FD73F552EE81C075487689F7C706C66DE5F9AF08F7BE91334EE6E2CC7558C15F7C82C1C3BA65427EF73AC56F6370FB109550CD8CF80492C5BC49303C7F93D07C55B894AED0F72F3C63BFCD5170939636B157DBE3A8720DDBADFD6FC41A6BF77216A04B5E974778A1523ACB157CC866AFE8425D572A83EA8F0BF6895ACC5DB747C1C669D0200032912920FF1A965EA539F9733936C7407254B16313F47963F17832131656774876D95105D49C66D187B149769BB89A1EE47D75F5FDF05B9C2D8696EDE5DDAD0BDFD216783C5C30070000032F7048EDE2FD4EAD0BF9C86FFE7888B3F2EDF0E6C28FE0549E46561D495A0D24494E02BC128E63C7999CED21E68F719D7C94ACEA74F81E4FB6F7BF636C480FC4205E59F4044BD6B914A2C7F39A43AC9828E3FE4B846EAAED3F930856B6B3187CA5FB341448689E6D8EA8F2AA4961C2BFAF68DF2D6B5AA7BCFA2B0CD4A2B673911E3E41BF00E8C380958A3DF8AA79AEABAAAED07C36309B7240F428B83D20B5E86882ED31D3136FF6F948851DB6628F0943018A5273992B88C00CEAAC455571CCD6203852FFE922639CDD4405A675FF57AE6A89F9B8B7601F5AD9587C2185656BC0BE5532D97F6BF59A35453DB0FA37FC5CD2C5D7FB30DE63671A0ABB850394C7B9FD508D9096FC51611DF6363FC2CFDA13A66827B8F97EAB381D3DF9D287ED1D9546B9AE707AC1988B8F08B33EE1F5CBEFDC4A2A4189EAFEE46D48D9C0993A9E2C509EEFB790AEE8AD489141DE1D22B4849A46B19140AD54A7174231BA4028B8555528EFF94277B494924D86D1B6D7226AEEC3A479842EE63A432D1EF5A1B10448C6C5B299EA432ECAEC27FBEACCACCC59E5BD7178BF563118FAA6B173889BCD0829BFF30BFD73678393A833E7C935AD6B09725564F5B9DA1C0A8BB10DA4D1ACF946F16C27355D751C1D6D78CEF6BFED8DCB26E80AD6DE7C663F7C3110FF1D075D822D9D72326918332C27CEBFFCF801ED5C848D6C6CD20F93C8292EBCE2347C8806A7455AB85D233B57A2383533BF6D1A16D13BB73B843B1274BDC5CB8A21025FC309616680B7D752CA6640DCFBCF538AAFDE4494C6DDEAE4F7AD90558B0ECFD75BD32A0EAC92ECF082632F4F337A26A929EA57CFF9CD7C00C6D0D0B6B2A7DA2506E98E78AA116FD82249815860EBB55211D3FDF1975F1418EC10AAD0A1C08FDD17F881F59B39F6E2277FD9DAE3D5AE40F52F95CB988C276F59F1FF24DDB3E29C46A6BBCBDC1EB8CEC6F99FC344C71F54E9AD7729C518527482651C7CF89887E9D371D47C02E86E3CA6AB9B3C981BA33FA1F636EF64C140607DF9EDFAFA47B5F5037531744A98C6C749AED3FA4246866744AA4BDDD78254DC0FF305240B084B0677D2516BDA3C02F081637D7C1B7FD2A0DD29C6987DCF541D1CE5B34A04177CBF296B44DCE9B78FDC3DB4499AD491AC2AD869527BFAB0221E6088A14A647AA4BD1D33321527209B253DCBD01556DD7E9A365C3852171FDA7B1F31C09C07934B122ADD3BD509449C99F1A454C82408E503C0B49F1BB061D8C5118F577A55F36C0F272EB74FF6EC1748DFD659F568FDFFBC2A2B3A6520FEB1BC356F7EF1814328719CC38ABD9B80C878654BC79A7F6DF92884DF2EA23CCADB22E83B2F5E2B50B2403ED169A23E5F4706FAA565A7CD964E4D2744D3A3DB38D1FFAD2D1CE6C20B9B02473CEF70247A54CB7A3176AC99BA8919A6E981AC3E2BFBAA9B643DBF899441BA3FEAEBF18CBE2AFF6AD593E21DBC21F4D887A67E743226153F5A9283E54CC0B434F0EF9B96DD10FEE9B64B796A91CCCFEEFADF26E6FCB2554B074E99555E42065E8DC7F02D928FC0BF8C7393019C14B4736A36E33732925B47EC1C9C448617DA827A4EF6C862C84441642D4476B58E179EE3D9A27F4973A120BEF9C20C48AE6C42506A80615603C12A8450EEB5589D3ADE5A4FE750B50D877497E8E8BC2267A042A737E3898B220C3F0826FD6ADE2EB08917397D28EF4A1F98185A0DD6BB6EFDBD5454CCE79B292158FC948C4EC178FC83DC30D3AC3189D553016736A5709D54F2BDFF475CAE6300109D4694B1681B4238B80E2697AEF1480AEE1E64E9992B833A9234136102802AA5B25DFAC98A4B110330892C61D4B17D1DDE87887BF4445292C16AF26BF18B58A495CE040083E51FE0B0A78D99348766A74E08620FDF2EBDBBFC13B700D4B1278BD7624B600527D03338D517F7EF634707C853ED1BCA464443B2BFC6A3C50074FEA9582B8C728FC8816FF6169588C1C8D3F8044FEE159A2D80F9A30CB313C672416A119097B2AA0F188B804F1310D07B34151C74B7E492CB7AC119AB27431A1BFFA293C947B29A9E30CC3F61C15F89230BC00A8DBE73D8E17E197FC840C06A0D08641F7407D590D624E8613DBCCA71F0400989AF593337207C885AF0B3D0EF8CD6D3DD76CA56EC7EC04DB6BFD6A2A66C8459082B127F481243CB52BDB223E5E5AB53DAF3937A7850236E54A6F19B2DC5CEED39D2214B0E2FF0E8A3E00F80C009955C5B842D8F9EEAB24328437ED11DC52DCBD7F81173E900DBDB729B8B9EB19EFD0CEDDF4C4506EFF273B1E8F5D7B183825695967B33C75CC4BE7011B28173BD67AC41EBC1A283F11ED416C2F71B3E6991F8A4342D2A16ECCF33FBFD15655ECAD0717EE3F6BF0DB506F1C6E98559A61489F799E430891121D699FA0FFE7D2FB521B19087EB72F4DA3B2B25BDD5EE748FF7DA78199FCFC887E30BBB1DBF2A23AB6BA12149ECFE57AF98B0A9639C85D2193D5543C3215A50E02C579C4D6F697B5C885EB0BF2EEE08B6E477F209D96FEF536C9E3C38A03E19DFEDA4032394E6CC2C5B960A001E7F7E6E4F3092E4BDD2A890D7FD89DCFC9E58E6088E266704848F4E3D07FB17F867CEEEC65AF90BECCEA11545981E16EF814BF61CB3202DF3F4740A06E6BA7F9FDF9D09CF84FA7E40ED54EF1DBCDB3D17653F94F580B34037B2BC5B0F047335D18D349414437D72302B12CA171FCFA872DFD6FE5C34AE0841CC8078D901FF5D44DCACAA5D2718AE31F824FF365DC7CB254A45AA4010DD1778397FFD6ACC7205E425DB200324929621A0BABE2899C085DC2FEB13A728FD8EA971BC714DA764740B1476DE7D8ED85222B8569510DA9773FD724608E3A0544555FE7F262D4DFB33B13A30BB5F13F471EECA5B1AE5BEFA6843BF432EE6A54D272537EEA4566B840F122F861A80747996841469057BAE5BBDC7CD64B6F6AE28B7BAB558C6B92992EEE5088F573507656BE51A837C3DF34E7B7F069F7DFBEDE3DCD8B8B77A54C3D1B4C59EC0AD04AB240B37D22F60D124D78328644B130FE5E0DE293C1C3842B766759C10DF8ED72291B50427E89E45F669E78085B9FAD76BB239D4C56E170C4DF67D8B8632047650B4530E93C2816B2B11C505BBC169F3AEB83E140A8F6EC7A2BA2634FC1F7E09679EC82B91C173767CB36D8E95F47FFCDC2648DBE19621D75B9093C1AC9A1C5EF596D8049206EBAE775D7B2932D63138CB37402864CB0A0CCAA5ADF942EAA51B02E4634C56A2980D2D5511A7D1670908D2EF0CC318C0D4A74BC743D0E4D7F4FFE462EC6378C0E37217C425EF5ED44DEA34957F969BFE0C53ABB0BBEF38A9DB7D1EC6F1EE950A884DF69686FD3617E657ADFAD631B225F1569A30C01B05AB65F9CBD3FE4CD64677BBCEBEE269F9AB2BEE27EFF42B40268313556E0DBA231385FF8C0B527805066A3C9B6B90E5DBDB79308F2F61332A044C33B33483A838AB6F92AEE9871CF0AD25B6D8F5D205CC02B8FEF7BE09DDD3DABC2A46EA921967216E2E507B7D61EDB5D46C366B7341888B8047DE34084916FB2564C1A66948AE1EF37CB70CAC75A4B4A4552BF6D10F59B8613984BA5CD33ABDDFEF82796E6137580BAC5243EE87AD0101CF7F67AC51B172D37B8FA9D4FAE37CD24BB5D965168C239A056336CFEE6BC84F20FD97B0154D66E5B642DAC93ABDA3E01B3FC83E8F1BF0F5DB4EFE0E5C839F34848769C359F065F23FB697D5D25723964450126F4EFCBD727477F8D02BB9A7F2719C33A6F99F6E1E58143255A6D7B0C53453BBB11A5916A70EF189299771CE5E7EC759B08967E72C92DC8C6824E219F880A6EA4BFA85C570D692B8D8D975435FB2490AFCF9366CCDF5EEA1ED2D85DC171D9FA90F041BD2FF84C8A9E428C830BE247FA0BDAF6E27E3132421282F8F6EB7EC11568525E500ECD180EF0925750BCA7E00A2213824A5C6E1585F4B6AFB78D73BD17F153209FBBF04111AC88E188C9C66DFBD02701D2A9AC3CE70E0C2ED686E93BC5043D429EE7D61014FED9FE1A26A761BC5515F6058B9F63667ED845F3BFE5CFE54ADDB2DC1FFA2D145FD01186EAB39233FD8B325BC926E8FDB3A09E4B46F9485D2416863E1E21188CC906298C848CA4FADDF2BEA51C2D9AF8D5D44DDBE9C1DA4B3EF7E93F0D072E03A3E5B869CAE018B16EDE4EA4DAEE2BB81D9C71A6F81E40D686235136287FB853BD4240A500774D24BCDCE5FC772244AF5379800DCD572786273441AEF0961FFFBC5587F15AA30594F5FF2E4DE5DF350C0DD9F651D53A6A38E4CC998D5460B039D3184D5EB5E51EE365A66C4E75FF93BD1884F56F33CB37F8771016F9C4EBBF93843B579504CE8AD6E08ED090C97AFE3D2F959BBBBF0F6440E250B36246D09266F59F3FF544B0C7280FFD62FDF7D6C534D5D50E26FA4302EFFF287CD31399557FDB1F7FADCA9E3D967DCEE95C4621A97FE6F647F6A7A8920F5DFDF1B3CEBC7CC69940E1FA830DC1F225769D28F203F23F3EAB95EC23C48D878F13ADD234F1BA26D3F9B23FCBB0343E66BB173410D550DFC2BE94F7EA55A6C8C17A99F63A30523CF8FAAEEB87ADA2F0340D9FF7CEF6BB4A6498DDABD12F1DBF54E19D5FFF3E4BF4647453120574B696EE52D93F317E2B3ACBD58143420C91C146E2A70FD55794460CE5FF47A73F18DC3099C0D6F17DEA34C9CF3173E280629E9FD6DD099631A98BB7B9BB8234DD493B95A9CDE6DA31BAE1EA949A0DD19BDC659DB28CCE8B2D8715355B0143094FB962E4E889F40FE1C72CDBFF4DE3E0D617BEF2C29319581F2732A69AFF2F10346FE17B503CB84FCA51C6F4B3FF03CD411A418A8B7934821246505A11D7DDC7D323470FDFBB91350C44A76FEF65F84F6BC4FA7E6C2EC6860FD8FDB1652A76E9CC94FDF7AC11A6A385720DA02713BE84FD166FF2170D0061E420B1E7DACF081144B45EE560A926FEBABC89804342D8FA36C75749E8D8428935A1464D1E79A2876A128DE616F1A93B0A500BFE2F52C8504A5B0CC14AD2DAF2B0267D97B9422BB2694EF86AE7302A3A6ED2D3F5C1F710D313254CE01AFE2587489056BE110B1A24D23421A34CFD3CCE08A660D41FF5829388C2EF8A7411611D020603534CA9C2F44ACAD7C8E3E39278DF9130213D285F36F59495CCEFAD50CEEBBF5EDD66BAE64B72E24575C92E4E3DADF9E72CDB2E2A10CBC7FE8DAB8680A146D523217F670B4E963C0DE32F95AA4C766BC94123D96FF9F81904212EFC51B023A3CAEB36DD640E8E23AC2FA43ECD667CE838B13566CB7D2F93A8B519E5680C005DFAFF3248804C61C96702CC7F3175A40385CDFDBFBDC72A632FCC82A51BFA8FF62C69F5207648CB817334DECD26FD65F20DFBD3E76EF4AF330613C6F2D8387E07747A83BCAD1FB0A01C80805D82927165B528D056166DEE260AA07FB4B003A8BC1C248694545EC88A9FC33E1F13C41D6E7A6C2C547EB1886CEC94A7FC6801000000005A5F2D88E58028126A96DA2C57B8CBBCCA8CD7F3066EE0E37BC730C56B18C10FABC7D9BC3DA97806CA8DEDCB8B38731EDE64EF32E703291AF3789B8BB038009209425AA4B83066580513C9893D34158784AC753B4CAC6369444CF51BBEBDF875951AE990F9AE3E397A220BD5CAC71BD9CF0D8905D92464DDDCEC14BFD7D9CBCBAF556DE321D058BAFF6055A67DB37CD06C58A5710A18E09C0DFF1B151227CAB50B0D81084DE41198D25641EA4E452261339E12C65E6302C770FF760724E46828EEF13BC9B812793F6174F76416B7238A224D6D97FB087FB987BFBE311F06F918589F351DD866A67AEFDD522F86705CCAFDBC4B82FF5CC8FCC25CC6DE24A2931712A9CE052D96F7F23DBFCD2DA63324C7B4729EFC42B70CECDD4BFF9358567CCA953EAEA094881741FBF71DC36B4644413DB4F49DB0DA6128F70EDC8589559F15DBDAEDD68FB9A56AB00FE1EDA17E90AC2B7CC7FFAB920FAB961D035FF7E7FAB203A8A0A8FDA50A1C08DDA9F066CF23414BD33111DB550C545FA742F79C435F73117DAE09D3EC0ECC758442D565DEADE94E6998BEAEA4CB545E5A571EACFAFD53F42903CFBBB3982407C24E7A623D02767186C31362D1E3B657E8881984860376C2EB7A005A7CE16F56B5F00AC4934FE39090DDAB1A155791FD8FE7647728BBAEDA0ABAA3B15B1B8233DC91B3B693E53601B1D023B0E2A7ECB7D0A7C5835143BB4BD9A7918874EBA0BCF88FB6165E40B6946DEBE207832288C5973195443F447A76C6071DA1326BD513688CCA59E9E3F8C55F2743440E36AF98F2392AA663572524CC50EF5B4DCACD6A336EA8B8F6F730F2B5A9F6549F87E2AF7E7AA5543326440EFC48FEAF42256AEF6A1C2951FBFE25F5C096F4B76A5C24641638AEFC1C3B313ECA1CDC11C3B67E58745D365CBC51A410C270D295199236E59DCA53FE5B4EAA62CF933F600C6E4E9842674E8A6891B11BCBF98066D2A9F5DFDFB7E7579058107D4F5D23157AE825841F4EA2A0F0486655644D341655FF9CEA28079A1AE9EEF8E8B54234E8809270798EB0E28A175C3801180A5F28BC7E84B920A34ADD82FE5FF38B57B274049E046A2FEA5D321CBCC37C96A4F08F49CB133C335ED3C07E61481433569E90D549BC2396457582FC6D28FC98A60A1C082525798BC58817C23F447CFF639A7CF041806CF141DFFBAC2B768E15CB10BB8CCF90F9ECBD7767FF3503FE53BCF18EA955B9D38F2EDBDE688D3817B8FE94CB89D664C6D2D5888B0A245A2321ADBE4072325CC08E2E5DB65C8EE7F0695B4F777AD6EB972FE0BE9E013F3FC62232D5A91EA8211E9AB2FA6A74BC71F4D3DF6716C72A02E674DC66240920A24902EAA4336DE85FEA438F58023E3D8F457FDDD0CE29A8A8B0319056A051530E64DA8C90F87087F8512082AE9D415C4CF1CDFFB7A5AD6198AF471C61DE7C5D4DF62E34068998E05C4F3FBFFC643CCF1E1B6147729A4AA39386EEA9BC26E1DAF692E96E8FCDF5310B2C35023C82969AD495642C5EE75AE1DB2D8B029A881BBA180E1A242ABF621ED0B8302A7F0D057DD0B5E06A2BD5F23BAC4D00D51E94EB9DB7F51DFA6B4CE967BBC9501D40FE552F774F5FA6461CD6BFB8BADAF131B8D22195D7EDE38E8D6891319D6699ABA78C1757A7C781ACAFD1600DB9EEBCDFACB90A7706C1EC9F41247A02DBC5A839FAC039E5D77E933FE16F3836B5E4C74B7262BD0991918B48FC7B1F5E7D8DF7EC1AF749FE2CEE76990671F879A4A7B6A7996C97E7767154B08F4CCB5DF2B4C67ED6B9635C82B8243CCBA52F000C425C827E2890F6EA7593191E7CC6A878063336D96ABDD4B99A2CD9B038222A0A0E7D905397E8A1DE9101C571DA6DFA5C78BA2C413D0DB1E8B3BB8680FEA4D578D77E523F154CA9D44E6C4273D2D8E45E6F6F2FC48CE58FB79E6CEF3726085E359053B0C765F23F2952FE28DF5F2B0DACA2C8BD673DFCD038F7EA2B374D353185C168F1F0E156123B01E412736377FD4D9E3187D87DADEF1D475CB4DBE47AAEDDFCF234A1C51EB93F5728967AAD26B5D404E2121C894B52918124FA26C592B2119D467ABA7854C000D627B3E7F52C0F0D501C6C3200D62D19B8F09262061714ED99AC4CBDE41D947C7D60BD5C754F624DA90525BFF55A709BD055990DEA2513624C3A93316FA0AEF300AA79F726F3542168A99C1FA241BA164C95349599B1D6DF1F9E1BDC277A797BE1FC96CCE7C27F8125488A7016CF9E220201BBA40899AEE66535B575739861DAB3ACE0A7C43554A1C31149A74D699A17D32E89726521BCDA728C580A445A69AB1B36A8EC6561F5E3B9951B13BC6AC6B204824A2BCDBD1A699D7D1C7958092779A7A65942E7B39443D5C641A8E7EBEBE3E06CEFAD360E02FB302F1323355540039D980F1A9E03E17150F01A8D3021A795B4DB4C543776E15FC4D91DCF77D842C69C2BEF57AA20200405FA113259FD74060020B6BB5157F5270ADFD0B01A3C2308FF8EA83D3FE82027289EC0DF32890C3D24D7A05D9889A60913A9D9DC07C9980D7BE0E6E699D1A01EA749A6D0F966FD6DFFB9DAACD740AD7AB236A009D3106D1ED19B6F273D9CCD4BD5B16C31FA80E146E48C7C6AB564CBC0E30216880C8282A9F5502BFEA0F6D21CA032D076B0E5518D99F7D538E5AA4982C2A19DE9CBB8670E9ECE62CECF62F1BAF47F57106D39B08172D981DCC016AB10509BFF27A066EA3808AA2881D230C44C30F038160C5E19C50A1F36718D89C10A0041C82343E8074B46F3259DF9C90DE76E1F12BE324C19A994A50032A66D0748992B0F3F2B51B33CFDE7FF3CC71BBBEB05D6D2511DCEDFB79F0649541E8360B6F0895B472A719B93C5A949C9ED42F865DEF6BF974DB2BE44A9E83E5E4B048ACEACD6B6149B928B0733483254D12841656682342E6780D666B045A461910A3698CB81AB83ADA21B6011358ED80D7146398B8EE6666DD4F101429EE2EC59EF70967637CB1DA29B46CF4AF8115A104DDCF54D7B32E2B30AB28FA10351CD66449B47F460B6F081C062A5DD4104FD40F5A62929CD1835D54508AE0A330D0170824F427F526C2773698CCD6D2E18488EE951459B758F26B20FA311AC8642D4398EBDEC268801B4465552718143421A65B5612B373FEB9FBC5BA2304679C4987B8D9B74B54A11B9CDE83C45174A30401A9CB5340544BB3DF97B6DFC1C35253FB595968A58A66191B7A9BE737DDB8C69C4BF02CB84A0D026D36C16601434F9536C7732F41CF2AC6F9D97D60B785E6A0553A9640EE91E9673023AD29B6CCD65E612C3EB91B3338425AF86A12C413DF65A89148FB96FA7829924564B5468C22F0C6D2A5B570C5D32F893440FA2D80AB56BDC4E3942D3EE8384D472C903584CD477963DFDBF750A3F49CC13F3BF9447420E5B5AC92254FC6B0790D633E63DEDA2C2485ABBC946E58D00EB236B1D0B9DA0B771ECBF8CADF3E682FCE310B0C63A6062C11AA0055AF945F93189B42E8FF3E144CA2909E836F740C23BFE8AF255A12E01DD8458C3BDAEAA3DD21889A18C340CD2AE3975475F3928DAA8FF173323EE14BF2FCF2CD6B1100350A573BF856C755B3F3B8F4FB3C3ACB59CD6E81B64A467057E74D83E252806649955A82734B0E00230EAD2265EE428CB83F6982E79D17E97DF186D4AFCE0FFE597C68B0FC61BC14BC21CC47D89C9982A3D4572CD252CC039719676B8F7FD51440173557F8A5A0F85A605F5B73F90685C706277404264B1892CECDAF734562AA8475DBB7C7E00E40B8FE5E25EC846F12C5878AFD51542B6A0B9756BFC10DFB7CE31F3FBC3712280AFDA54E4F822839B4B4538E0D6C9358E6105F8A86B676583853D268EFD8BB97E1A1A5B95AB182BBE706F715E609EF00E339B39ADC15A73EDB305D8B68C0B1C08BD91880BEE53B4D5E819BA16E82F6D0846100FFFDD1AEE1EB391A49D3A343B3F8724F5F43D3DF0871B23A6D7939A5C4409052FA4AD944D69EB1B1E4689BEAA0B0EA74F0DBF44C02EE17F0FF5D6EE9E3EB2DFE22E25C22C62C04CE34DE7F9EBACE248B5121F5AC5CFF5E2482C1CFDEBF963753F028CE02BB87B1BEC0D452084DFEE19C4B2B41F9F17B0632B5498BE7EBB216CD6525BF20AEE25B05936EAABE83C3131BF13BC0350072A4C08C20A18D5A318258CEF352F500E036C54AEA89A281D88CF0D9EA74AC6B7B216161B8A4CB0A75A14BBDD8EE65CE0996AB8EBCF77D085077EC71112C0E00019088230FF31D5A8FD6FDF2DA4D1A47DBB4BBC24AA662F8C80C466A47021A984226048CF29E085F830D0CA6B4540263FD1F811C0A4AE7262E387D57EB6BC618D01CFD5DEC7C9DECB25C8CDD921C037D4C735CC3BCCC71DA06B36F8C7A0EC85A30FF899DC371ADD4E39A62CC9843E74E1B49C886CBD6B00D90C97B9FAE82BFAF4B5D5A4D51F3F23D207D20E1EB5A0E238A94639E6BF0375DF48592F5C303DB8AA62C24FC8EA57D87843AD23282E06C1409D44E6518FAABBCD4E4D485223894520E48E017985C515877CBC298B36F3A004E0666AFDE18042B302D611FFB3BC21321466DA9316E1648238580B835AD38912A1127CEEB1155C1DF9908149C077FB5258BD4DD4E91E654913F7EF9DC94ED0F6AABA42AAE9C419C9E5CB7EC3D10E58D07E77C346F12D4B6BA7FFF5664FD40A30CAA9A9223F3790CE02E9A1C3D70E9488EA3F2F5B5F0A9EF8C0362AAA8F8A23202D1840895A18B50C72131217DCD84DC080F66756355D4E336EE92F46A09DACCC75EA9D1427171F1F9A9FDD4275C28CBD6800156E281BD9975D3805EDB49639A527747A91D2EB570FD4596DB777BCB47B2A9F6EC495BA4616E23C4373A019320FB3372E07375606462F4B1C9088A379242F185BCCDF61DD888E527A761DB79A3C4524C29A2EF795A9AC83C8869AE2F1BD2FEF2F48CF5E8C49DC9BFC4B47EB114E69C6D1C3BD30F8EBA78D28A7E4174DF97EA69AA12E41656DF163DCFBF70F20D98979F02C2868E725C48C23203CD0C1393696203F0835D3C8D0B380C2D0885466260AB2058A4314B446819BB70221A01DFB038E9EBB934F8095A73E2F08B034306D84DF365A0BF129D9C0720D62C7F7431650FDA76EE97845366F06E55806D146301844C1602EA25ED49A5E1CA4C7C1A961A83A2577718A188A4C6915D51432B6131A1DCCEFA6F48B7900C1BD21B1C102F1203FB744E5712E08280FA43794D4A33D4D5C4ECC94D215B15DEFC00D9B041D3661A569F5040F0113BC677DBAD7D1ECFD919AC59692E96810060C467F662B0974A77C3B179CE37A232535B2F2B73FE8B84948EF271F1106251800F414D787B4AD3E826B8C395AA6ACD9DE52F77914D7851FBF075F5A14B55BFFDEED86276A6566C32D4405B5C9F0CA17BA32642BDD56AECD118F9B37E515DCBFAC508BFD9640D767AA73D88EEE67392187FCC61DEA64524E9C3A81328C63FA06147F1422DEFA7F02F65C7AE4A18DDA193AC300A73854DB31DF779C8FDEB637363187AA62C6F36B425197A7E90705B967C14826CA029B9C0FD6F7B5FA5F02A148D130FF692F78E577AF3CCC98CB2EAD59D916C450C4A2E2A014FA357F3E8EF925F5F96C9ACA0EBBEDDC0C0EE76D5A6117C9F1AD5FE883FCE584F26AE9EBF459962C02AA1A9CCF52A1795A6EE8290A7B767F7F64BD10CBAC05F74D036A5A7AB9C6551B017F332AE7572DA93EE462D1EC1663ACFA1667650BD75FD0B99125C412B0300A6C793B3921C4FDBFEE119A4D90836B8609C519791EA7C6A104CBA9CD0A8629DDF028D78ED2F3B4584414DD10A361693A11806196467EA20562ED1970665ED7D79619DF46909B12804EF3A945EC86AD08EBA7375C17D39A25306168B7F16F9FB2950D11CA869F5B3921DE920FA8442DEE92DFC2B9211DF0621F9B769579B0893B946FBECFC4D7F1AC916A3D37C2B5E5989C1E799B8C00F3FAB4EE397EC0D37FC6E401C283A86B5FF94E3C236DACB8CF20EF4C8CA21D031A7AF29CEB9927F4C418F99D54B918FF2E9FE58ECFF47393E92C0FB21D4B749F25D2EFF6FE629D2CA89DD3AFE015AE6E0C902C35FF5839A26B027E88069A162D04CB77B4EF1B26FC4F31B2D01AC0BAC0EB8ADF33F7AEEC0B90FE262256658FC16CE41133FBF0B75F78A2E057155C0C7F15892D95F4B43F300D5444B8A2FE4FE0CDE71739B84C9044382C8415206957132B9F77BE8EC1F0225F1F175337D455A50106C5D50FD285697E396D96444912463C45AB08FAC302BC45910CB296AA7249155DB72028E4E122AABC398A21111623FA6502142DBA60957D993409B18621D392877C7DAC2A5545B25CAFFC05EB8AA1BCC0BD048140201048416A1E1322DEFFB1CF98D95772B5216F759A508696575523FBA55ACA17A4C2DE0B261C96B1198B7345D437709432B187D2A25D8DD8D13F1BB3CD0BF4B00EC2801D34870ADF6549C95EA5A7B14FDBC73F1636A75F1B0D3E1741F38A5A97A6CEDC000F23DF8F73534347602922AD87BBBE2F54B1D84FA8EA912BF96C667F13232FC7A2E0C0DD70FE2038F283BB22B8A575199A0313AB480B74FD92F7D55529A20991691EAD9EF1E14801142F1BBFC8C2E63021218140C3DE4067D198447D2D01827A755A3C5A044DA753F974B91AD8261D65E1B0AAEB2761DFF83D1E6A4ACB2018B015DF44C7507EDA3B0F9E711C5D5A045E867C470AF4C0ADA6485ABD9996F9CC80293EF432D9212A796524A578F6C7E5AC256AA9283F55F137D19F575B1BE463DD84A6BFCF698D9D96A3660294DDEC7FBFED2D3528CFB23C6D486A8DF3CD5311A9F1A2BE19A3C3E15FC6BA6714439CCF970A4EB17047C075DF985F858778173C119333DBB3F857CA7DB6B595BCD27969F9EF21AD62ACD282AE79C4B0F7186DB531DB96F3A9C58FFDBAEFD033DAB3580009B359910D46254AD9DAEC8C8102A414F80194048A25960081C44153BA20312F90E6BA10C991AFB3EFABFCAAD8C648939953454B361B65B7F3F7F73DA598156ECE2E18DC7C6D2C80BAF872F8F3AA84A6C848B09722AD44CA57D02F282F31A69195601C39B0790197754D23C7A633D926D8882F8F9D9B119EEAF9A3F5C1D3C347BBBCBE87780F5E4EFA401B5624C5B40C39E7E24CB52FD251DD2AF560F9180AA6E97BD9D3D257239D6F25C318CE2D804CBB62D46DA466EA5DDBBFD33F5D0CED822A7C70D5D9DDA738F660B985C9EFDFBA05B1129F55D8C2775514943DE6BCD6D7B5D3B9EC3156E359367918D57BD63ADE27E8315CBFBFBCAF8224ED920895A8B9A1F1D444F8872CEA5ED5E31D34864261BFCE7CBCAB05918468DEBB55E0833B81D0C3C542F09CDEAEFB770A0F2F88413050ECB7131FBACE56B5A4F512AD2B65823BA713C52AC983F54BD1D667FAF44F7E34E0AF7E45B75D17AAC5243CDEBF83112759A33AE2F89E992C8E52DAB93FFF1A364762FE9F50C823FFE08C34F7544C0EE41114039CF58262C0F447FA305837BFAD256029A96D09B244D2B3045922EBF1C1F0AD710B480D2C41B057134D4B492D6B109FAD101CECD77D460B4746822D25B523C119D6B855529919D620440A7D93A8A8484B48064C2BC3926AA3C5E4E333095F3AAF26CC120E0CDFBBA0A9690D027DB6068192AD4170419654A4965464FA26D620B8C8C733B504F94CABB4D00C4D984FB1BE280496B0C865952C4923B53577EDC166D818AC6729A91569B303D8BA464B28D892CA52520B160D17190713C5674B0A98C366FCB42E9C8C81B8250826216E097A0D1264D7B58A5B52125B52468109A2C0304B496DCDB744B013897025C5139B647C44E71357B481C5AE379557F4A1AAC99CD84E85202EC052522BDAA51A6B1084416A241297CED9724B50FC6B2A442AE69213887E42E8AE40B4045981412891BA025C14083141067B06410833F434D5953CF05A8320B3D620A842ECA945B10641369D2191276B63AC41909315242AF23CD620A8A65191255264869E66D4E77FDF1ED812C112640D82A38896123C20618B25523BB2F3BF555A82A84267B00C8A151FDFDB50735B83D0CE63B99B374333E377B125D41294A19BB1CF246440ED2FC9D08C34898D6152D288944DF74944F21662810E81111EAEEC14E54CF9550CB152C4679AB2BF8DBB6D441E2EB6065B96925AD1C223132EA34C533324469C2049B0B403519BDEE478F8D620E89081A5A45604D250509F8426665AA03D2FC04CED85235E4D6096605754942EACD025D91378251F353525BB95C12CE12D413192E4ED6683E79494E14861C0FD10B17EA55D4FBA3396EFF4A3C9F14530F56B0E6BD5A5CD700901D3ADB1DA2D6DEB7974766B85FF94E68A22C2C7B3D71205F385D0148F89E38C0C4B90F6C36F09A2CAB0A4045B52654023C11FA3AC41F07F0C2C41B17AD620042A7D93284B4A2C6B10FCB9014CCBF29D98201A0626DC3C320C6C0906C7EA45E1AF1BC920330A6C121589FDD692D2204A2B4A2F737167665882136B7708107D1313CD0C4D6B10020F48045E28E6521358D45E9EEA0696A0484B5002AA075B8310F88CC09444223889116C62AC414833494F8C54A06F92A119C5598F48704C4C0CD80E43542672DDD62084F498A8586B106ABBBE8966D647CD38658DD472BD87EA486B105AAFBEC9C7CC4D3D445952468371AC410883369823B594682E26CA922ACE1F847645A6A6E60E1A7B14278C859E2CA9A262E070F0AD4188F0CFD0DB9722E243887D51FE3C38CC1264691913B74B3C5FFF18B096838479163A103502548B681617156F17D140644DC492CA7C420823117C6C90B4062116AC36AC7A05EA908D3D2136475A83509DF54DA2B43D17CE1A843862491D6D0D428633FDC521424E5B86874B844A5BCE404A5B96CAD783CAD7D18E2AD8CEDB83CACAD6D6DBCEC712140DD68EF00169D76249150DD6B6948C026768666668CA4F60719C51A436E1B6062129585B176B0D42AC342BE8EF6F8859A593A4C5926A87D2C848382F8C6C0D420A8CB40621764609DE0DAD29B73508E9D3338C36AD29A56591D4B261003832128B8FFB8EC226C4B706218D185883907E92052D2256C2124663A9B761F8A4388B3BE5CB2422DA92A1191B75FE288B8AD27ED7BA5D6F0D42A68E0AFAE0999AD620648EE815ABF351332AE25DD3C32D14B23D856C07A8DB4439D01C1695A9199DA1092B38D6B4C790012C0E1AF950C8DF31EE8BDB121C4BB0215CAD012C0A92A969028B8430CB85DC1B8B5AB4067D93EC1542C8EFA66C96CF670D425EF1BB625F51BD78D62014FC77514C8C3508855C40BA24E7610D42E134B094920B15A28F61AD41281F0C2C41EBBAB30447E25983500C0D2C210F2ED7C6C01A8492A76F6209CED4345762F91E13400A25300525C033DA128292A919C32F0AE5630A4AA666CF5BA46949158D6505E68DC622B0548FC1B2448DC12210FEA828F306515128199AD15CA350A6525026D57B87B706A1ECC4C4C45882AD41C85EE1EF9BA11919C3640AE52505E5598864AA577C9DD71A844AC040272AADE0B3172982466347E1E38BCC856A610027AAB9F01910B7350835C091D6E149C07FA1E18C22305314F9A88DE526B74974249683A32E18C0A2C05A9131E0EC95970CD1A5E6CFA8A8FF0C2C41313160ED2A196F4D3A240A7A0B2DC15104306B101AD4C032228A2053D3C4922A0A2BB2340E87466A600D4223B106A1690A83776FD123D415439A9DB05012615B42B52DE96A7FE8BBE4204D82142C749C60B2FCC98E369231C2E867479BAB94F25B8D5B39178F8493DB6A09D3B2B424B362D4B706A1635882842D41560812606D2B467D4BD0F59B655E32041F0CDF0A84B5D783610915C0B202AB195882F82DB7C860364AFDC6E6D856A02103984DB9C18F256C2B50E8431ACF0AAE0D8E8DBC04602FA3ADE68B3A05C5A3D7AD4F25000F7DF5BA9B0CACE97B06B6A4C1C30DACC06AFA260ED07856908D6AB3A5B13A80976AD7BC8FAD006CB42710C50D4CABBD34892A0152E89CE57C29D327AB46A75448A7C0B602E31BE01200B46ADA2EEF7500269A2D73C60B18D2DC62FF1C802F2DAC99A5053ED2E2872A72A61FB61E81F0BA018707B4E1418F4B14F0A431B4783B014013646B9A83199A88007DBDF4CCC0848B1E5660632BE8975ACD38566087CC0C2B9A4F559C3B716D62054EB284C204E022C11956E0D8CC0C2BF23A7D132B78B67D149F952D193DA03D91AC2F4E2393D17ECB5608622614FF9443883BF547B115040EF9681F9C1006F728083545EE4922382F0332B182487F29C401B51DD1D4BEC01A7E098178C3E4E6771B6232FA855A21D9EF0D12F3D3E132EA4C555C4A46F2608774A741D628C812457E60432672EDD07D2BE46EE15A29C9A5C11138E0B0FD6943DE541386A3E5511A9CBC034E6A9F14946F81757C1702E78F78AF14D4BA76A2DDA8C9B642BDF5FB3170455668B91386AB8D472170D3308DC38ECE82C0AB08817B83E9719F640C5C76286A0394CC0AE3C2446066CEA5415513A10AE09F1DE356053642083414A600583143C21A02CDDD6ECAF29D052B0DD76A69690981E95A416B32AC1850F54D602D00372C130A69AC944A6A6574CFD4C13E666644B65F8428F3710BB716DF0A9EC6006649896505BD37B0028360D1BA5048B4767D5F64054FA36F1255EFD7B62DEA4C227523B59B01B7C6920A0C8BC6B682873788CA80B3A424880267162746CDD69E1866052F6885DD5CA28D69052F1B191B6B85DD5DFA6B8BBD522B78235352DA4C88AD5F095B96109E15FC41C371582BF8CD0C2B9A654908AF3D00530D14DD34D4F9DC61F95E30A39D85A18F2C86AD605D0E46A115823773B84204B3213C08B0E7BF5A4CD7873ACEA4223A6420FAC64691B8D1635A2146C4C6C65AE161461F4D9D2C0AAD10B398C415120D3B1231CE8E2B1F1D26FD615648C16CD9DB90D12363632D41B038110429D102B7AE153252114428FB4CCC5168854C2510AE901BD9912BF97E3CC8D6CE217A834F825168857C1818AE5002D9503CA69E256A9E54A4DB3688422B94F13072856AC88AAAF11743C8732D96A00E3EDC9C8B422BD4D717AED052D8D0A2C359A17DB2045991B4E99BE8D700001C4768556968F3C9E854EC68B78542A72A183A5C0A3A3FDF55864FC6C18B13256C10CF292BF4278E93E897CAB443622046C5C5C5C0E57EB01CD2F5D95458615004367AC0F8F8F1F9D8F8F878F856182B0651F832FF21A2A274AD30C6F2704D5735FF5D628571542B1D6F2FB2A0D5F5B2A9C589B3DCC7981035C54C2FC48C26AEB070D8B0902575EB7724D2C925866F8515F54C04E5A535ACB1C24A8E4CF8902DBD10EB1371854DCF8E4D06931C57D84E24B6655E9A070156EAE18A77459115CB8EF31E7ACA52F49CB2C2610E03894335B97918B9316A64CDC455C09F5480AD6D08CFE69ADD446B32C5C9EFAE63597CDB274C15DFBAF7E4E938F1A92655E938BEE5CD3547CECE0FAB63F862D4E3E0813D9BF0635E3380407D03D93847AA751038C36269464F9EADB9F355CC7280E32E62632557815FCC81AF1766F610C071B3582C8580AED754D698C5156702C5D1E7DE1F5C715E909CFB01843119163DC1B3E6E03CFBB942F414D213C0E8956BB7B73503D26BB542F8E84E310288ED3803CC6EDC08040FE990959211E68EEBDC095A28B2A163BD422183EA2C6EEDDEC7627F16FB88050A77C8B5207AB6F744FE0804A7896C0A5E7F14B86E310477915208AE33F70317B70DD846922CDB29066EDE1A58ED084FDAB1FE08847C1541F04636F2E16BAF86725B9C803606B13F972B8590268FCD3DB8BEEC55D5507C76F2DF922C911211D1071CCC0842DE64C0238921B48BB542681FA80D8FF3FF2F88902CA19FFCC85CF2D7E9975610FBF057B248AA7F1F84FD1EDE9514B740D8DC12537B68EF57C02022ACBD8F97695BFDE34C042E4FD4DCD5EB7D64BC96350337ADB935A1539D5B14352A671ABB65E903465D83CD1BAF20C3D60CDCA92C1057C641A83FC02C95AF89F5138E721FDB5201DCE363554A807BF56B46C01DF7545A6CB69A4EF8780CCFC56AEA85C35106A0C00B5EA9FE32DAF6D70E8A99067899DF42F9D0151EB13F1775AC845612C50619DA2C18DBE2ED9D3C3CB3CA81D8D92A07B5FB3376A83C167B5DC5022DBFD2789F93F96ECC0543033F8C05BC7B04CCBA801FC302AE5A05B2E3D7427B6A6B4C80256E15B5B156C07258520B7C8AB58E512A01FCA2DAAE9C05E270A7D872ACA48E6F2123CD3B798DE7D961AD1A188D8C56BFAA71DCD11A0D74A9CF6312DD7F938101899CCE452990CBC963B80665145AD7FA3619181AEAB1315A3B0E17C49289B7BC84A2143A468B6AC188F6E8345A5442A343D534687D5D3A0C188499802AD428ADD2813C249D4FF1E902053652C88F0D07A552ADD0D34F061A28F08B050ADE933C976EE17046A393C98653C369468B825CAE300043D176F8510B413349829F650C6DE020FCE7E55BFE4798E067C9CA9F4F43D17F5CF21937AC253D42189D3652342DD5A012D841EE7199B068110E24EED27C32B5A287F16AA004C73F66691889C9D6E787E61905FED1CEF1F06C4B4A536A1A34B454B083A1125AAE308077582E0C0BC26416F07FB3024A58C458A08E2C2520FCD189F92DC0F7CFA7F9CD71BA4CD0389BCA24ED50BAED8070256B017E61F1E1D3D48A4FB1C0370CB5F3FA02AFB2788D8CF42FA8800752B26A062D597D44A80A8AC68081ACCE00ABB2FA8E3855D0083178A57A571960DE02601546950316BD99910907994A1A475803588729A2780C3403469A1FCA3286F03504EC571160BF0051F0360D604B6C4E58DF0D60FB4580ED0342BE939213E36AFC039946B55D8C465404B8C03B4C87343C330D2FB902931F0278BB08F0B67F4A8E6044EB71CC9FAB2C820C885B37E03B4C80EFB77846809F728A1F343723C0DF3F95017EE5695681707E9A1110914FFF7381C812019109C4DF6F4109185C7731BCC6BBAAF32D1B71B736D3C47280783128AE0C882FB59A65580E44B96CB24505E47210F1BC1F46DF674B872B659A1F8401A81F967FE2FF8BDEB9678E1D7DB8F57A17C954AE7AFEFC2052FEBBFF2CF7E669DAAF528D424E95D9B9D9D9CDE78134514B9677C2535251B41F4D32DB404EB796B637A06874B2311D32333232D325197466862C253D25272599CECA4A976464A56642064865149521CBCE4AE9B6238BB3C601A93BBC5876DACFEC9856188CBCFF12D9B8E54E49B584F17699EDB95D803DB9665D19CBBD735F7563A6C1779F5BEDF705496BD7EF30E5E6067F9AECE53D73306ECFC3AC9CD1C2EFEF3F266F5C637722A131E05E163F709E11865F6233F694BCBDFAFAD474DF35D3BDDFF94CAE5A11386C6202BF17BC9280FD4447C8B8D7FF8A387AE4247DF31EE57FAB5D255AF7AA7F727C4AECD49CD9FFA3BF6D7DF8133EF8459714137C664EF1CC214BD63426BEFC7BE5CC75B34727944A9F75AF283E3E6DB4F7F9D72FDC75EB197BF6B69F75F7E2683C7C36E11CF1E92DBDC4E201E19CC463A742E178DCED4D446CEAD46FB5CE9C8AD754D8FDD4937FBEE2CD45AD67DAAD9AC289A567179E780EC50FCF4CD61BF445FB255529A62B0767B6FEE5B27DB7336E016E7EEA9E73225D30C91831B4A6FF4648AF568A7D9DB3A11269DAEA53DA533CE3D1A70835D3CDBCFB954E67DEB54BD4E36F98E6C9A9B5E3CA4DF28345290C6E89EE1ACB1B515736AC9594880AF3F15B683740347AF3C07477D2D88036BAC2ED3CBF614F0C35396FD02009B935385DEEB8A6BA51CA849F2018F89746B1D5DCF89EFA8A64B717610239DBE0EF2D2F723C6B61EF59F0710F2A8B71D9C061753CB396AB75DFD61DA23DE53C9A11EA773A645F98491FD2564DBF0BBC62EFE52D471DFC8897BEBF1C22D48201CE172E46FAE0E46524BCA8E4693EF605ECEDCA7D9A4FD907E4FF08FB71BE717364DB3950C84366547933F2E4889FE3286D27D9581A7846A5EF47DA91D47EF9B4C91DC870AA9C6058F9CD5BBC90CE2846E519FCF0076180A38B0E13C237E1A10CEFCA91FF813E718691C2DD4143F475F390CFFDAA7726FC80ADAA3D869CBA0E59DCEB097EBB117D62443340F53C4FED91CF02974ABBD08A441670C179A8E0B33DF28B9867CE52CC73BB156FD478E7EC250D1910A81B4CF787865CD8E80DF99949A2DA5FA93E52DEE69268CA6B64A23C6F227F12A6A6E6DEDB725CA7EC44E4181CD2B47ACFE5A510AC540DD7F3AF680D3908357C07F40393E5EE8360808AEF6D3CEF37BB5EFD8DE04C7AC52B134D657983EFEF92BFB30F68EE48E8B9B780E7D15041F96A92C7E16931AC60A07D19EE8BC37FD47EDFB26EB896E096EC5F15DD988653B35198DAE55160E1793966650537F006B639C5F827EB552350CB252435E7D1B802EF5C5B83B6186B64BF2902C94A7218F71AC40647A1E40B5C4A9C35B13BB46E702862B3019E20DAD8047D3F1F3EFD1B7F1BFA3B7A6AF48A42206CF562144BEA350854842443992F7F87A4A626FC9619E93246CD475014921FE49DA0CF462CDDB9349BDEFA3C0A731890161F37E97E40E9C1A1A1A1A1494D2E97CB49F2033CD5F45DAEC608258E770AC2439C69104904EF12183069F0EE34FDDA7C6539473AC834C2858780B87880B908A709D28209B6E2DDD9420CC81E42799BDC349EAB1D344C4B39F3FADC49429301A7BDE0BDA54214BC4B60C944D528183CC3963085670172744543995772841B3A05F7678920F901EB959382082C3EAE9C82940722C4A78B81C02FF92F1FFA939E6012EB04B17F192A42E291CC173147524879149A99C901DE358C4B6F826CD13AF164FCBCFDED0A202C6190A30ED665303307AA4F1865BBA3CFDC3E3C2B19F1E2FCEA444BB67A192652DD37C6854D43CAA37ED2693017B1D0BC88758253F9AE7C87B50E897D02D488827D7A7A7C277A8E513A37E3D5FF90EEA52B31F24C47867887DC0975E8182F9BFC413030476C9550BF4ACB3DA341F2EA447E30085F05491063D7E97CD7481C2037745B05748404182DE3498EBAC46DB0D99F8FBB98095AF712F1DC92109CA6F547A2E442BA919639A5BBBB85B8CC398252297747C211A1DA818E6C2D55140D71CC74D0831E9812D5F55DC67E50C9149EFC7E2ADF920CE289372D5CEDC869ABAC9D7BF1EA8DAC62FE9184AD919D84C81C070AC640D328467106B495953FB64BF155EDB68794E36D4A1052420BEC9B3CC25EB864B22A33787F10808237A4E0755AD37630FDF0E01884CFC6E1DEE8B8F52DBA9B769229F52B99FFAFE8A1DE00EB86EEC97301CBE1A2A1DC19638DCD17677F77752CEB3385391EC4DCECBECB1E8AD234013E81B7200D2502FA480011B90A22044FB64B2D9716DB96EE66929869EEC69046A7C2BFAB9B06EDAF8B78FBC474F673F3B4F3E6B00BB471B47277B0032DA7050B5720578E83E42B20FCFF79117299414AE0B27602A14E5F8AB380EC5510A6BFC003299C48F09B9E2403894F7F67FE5DDDD43F841DCCFF72C7C30803B73FE5DB0D3F98E06C4AE5C1307A06FAF47120D8F50BAD9791631B31361206B8AA4F30EE2A6987F82271E473E1ACC30B62100CDC5EDBA0A3DD0F519804DFCC6A6E62746FAED698A9111C63073C4006357988B100F7D0248B07BEAD318EF2B4FC4F6458F2A57B216B411C2013DE10ACFDD949C0841104D20A7D843446813D6310A4D924A3C964268452F805D420F144008390C42F88F8AC7EC42BF1E6AED2F657A9900213323DF9FF48F495F14C8C11D85FF85D87881CA050D63BFFCBEB130A3A9C9DA42665E49E1FD36FF003C7BD2C4844B456BDC7D1048B6917176F3C53D33FDAF059E8B6D406DE3FE2C1074F903600C80F79CC0C858F5AAD358BCF0AADEC535AE7B1275688CC6ACF42D06616DE16E96E286637A38379411FC16E7059839B4CB03C97CD6C43E1B84C8A01A940BC550ECA861CFCAE2C5FC602C0D0835D55B6904E9B3289B5AEF1B39425C9EECE67C742EA6224F1F09C59037D8C3EFACEC19150F8E7D10FF54F919CF6771D75FAAAFF96A69DDC4736316D09CE7CFA75ACB1A5644FDA034F7E41ED37783D1EB3E5B569069A40B730979BB8CBCF95A2B45FD303DD725CFFDFF200068B8641E1FE1DBC7306EE55D7EBE7E9360757497F3E295FB86E35BD35DD7BCE53FBF0D448A27CE61C41611496F32D2294F752E3771568076B7CAAF6AF4E093DCC6672D5C52820EAED22B4FC5ABAD3DE13CF60DBC2898E81EDEBDDBD283837611BB6DBE44422FE0734DD631A06651FFFED03B02ADE7F750A430AA964EC4048331A24FA8BFF22AC8333795B29FC442DB16BAF01123CD7173C1DF9F78759A248E3D70EEC4CB6D43979A6EF099A7CE4FE20AD56D089B886C6F0A638DEEB8A2521E43AA39C1F42EDD39C359AB305726F20DCC2F115EFA97C4A9D039CC3CD82D65E3B53834864FD05B55A52FC713FB5AF8D92AD974B25899AE86E0A0A96A62D255F261F7FD2D3145506B67383196AFFF6A1A30E2AC1E3574B54296F345F72F58FACFA138639B2C53BF1A7C67A883C6EDFD3DB48F358BEEA4AD4BCC790F9FAB1E585962AE42B1D978FFF7781FFF5043DC6A52B8CF6D31F2EDE6709BFBBEF318F03993718793E9FEB04C500C74D44676338A7EE434FAA69F56406B4CC4A524D714B1591F2A8BC70F676E33DA1767512CCEB2D9F0A9402853C243C565C6DE6176C40CCCD9438174FEA5351D5A39E543594164BD8FE9032A9052BCCB3DDE571434DFA30E67A669CA8D9FD3896D05A24C160447A7639CD41186062E027CCC7731A12D81EAB067319AC3F2DDEDE7A148F8BFB3330D92DFDC36113902C12552A2C89082FA0A4B7F723703812583288EF8667EF4BE40FE124CDD6CB07814020F7E43E50C883475479337687CC7F440DDC64DF8F10366BCBE077E395AC9E48750DDCE00D0562C579F0E7253B8260836000FA7331C706216F31D5FEE5A9D8C3B71C4E9337C25FB88233EA609673CAB8291EF89089DB41AC308D9A2EF31C32A2118D4E774AEE898A268FCE7F4E61A37C0022EA068B80A09047305F7C34C570BA8B3AC0645D18D98D51671FE52B9114D5631D9E56CF6DEB4893E26B615DC3323BB667137D415C298C76DDE0DD9BB3BE6900B339BF63CA6DF881F89C6B2CA65EBEF00F5DEB75B98B28A4E8E601CBEA8CCF038307E95375A42E071626C31E646A022C814D944118A0AD7A78ABB8FD05C53437D69CFD2032A953757CE51A07E9B7ABEAAF9F1C99FF1C000301D1E5BCF52342A1BA8466A5BD76C3EF35FD048F4331A2D9F4C753330DC118DD886407D55CE8828E558CF0FD33288D107FD50279BA80A154901B99988F70206BDBE47751ECD007B408752F10793F1CA789B6F1B8C584181884019E1FDF6159B70C7CC49F4E538E68323A7A9B29BFAFF6AE57D8B11623BD96FE8907F414FB4DBB72EB31A1A266F214D638186E1FD45AD2DBC72AD41A64077D644DEEE8BC2584B6EF2B05643F6C922E5871B73F6D17953FAED81E0D4AA6C92275D808B6E373C109317D47B5CC3F910441792E1782B494C396502121D3AAF5D3108D1E4A9763F2AACBF9E75C178A566BC60920A42EE27B42E9287595279F5C15B213A1341D1FE717031681B12683B719AAFD7CF0061D7F3C54536A37EE5FD642B4EC572A950F9D0C9DEAC3D179ABF1081BE6F33843D0FA664B82FE7DFAFE8E9D65E29CD4F15AF6A1691C85C6420DBA99E951C7C2CF36FEA20424F2AB657B7C92403753B3281A26034FEA3F278F5AC429CC9615211F0E173A63937BF5E9342BC2B1AE8E9AE1CDD80F000B52A743827CB8B41751D09C9CD75C74246F5DAD70D009BE45C6106FA7804D6F37FAC85B5F009A1EF4114D2B1AB1C95C9E4649E0FE581D070A15750FAF0500312302AB2269710DD2D25A440753261572767304050639BB8A5BC101B28DA055F855BB80F91EC1DC404EA922DD1FAAA69A53ECEF737D86B89DE44CCF83FFCF689295F23FD7EC2E3D730104AF5CF1CD4D656A15AEB833F9A6C72E85A47EF3A7F7647054F2293B21B89398401CFB82F0E82FF0FFE67294DE485A7D9954295F8C1C2C6B9A078FAFE117A50D3500B8A09A35C9E0F184337A3D08528388F18F28B03A6CA3BED5F7E2583CB6C56A111882A3D4FD8FE1A0338DAC3033B1334487E449DE1FBF741CAA7C83DB37CD5F5408A0C97D8C132BB7637898FC8FB5FCF3AFE6D6909631FB8C7915C68E1EA0F1F4A60D0458A00FFAD0C7A4844D9FE282DC2759C88C58EE6427B2080F2AE2C2AF55DDB8006C93027B1D8CB297B17741537C63EF4F25F57F1634CE94749C7EBFA09A58C41D03513F44783CC9DC690AB0697F2BB38DC609B9259924B97E4F0FE599AA138B750C83C16030180C060381C2FF5F3D10BC470836D07E0C21FFD759F6470D033961CE18CDE9CBCD3D2F53011DE7E257D25004FDEFA180CC67D5940761DBFFF01A4441D99D9F82ED1B3602A919C57088FEF95EF240BD2E815BA7D95279992B2E849FADBBA15F7EE127982ACD79FF206C1E31A7C1FF15C6810E103570BC4E4D38D4E3F184059A8050D46DB864577E8C3535F467A75C2A8C7F4205C251AACEABA5B264F4AFA91686BF6E8A1521EDE0256E2F5023E6D7F6FA2C976501FBE1C71629DDC260669AA92400AC5623069C352FB8D4C79CD1FC3AE58EE8E803627E20F039792985F887394D2876960DEB7E6D73F837F7244AB43792509FC025037C1D50B72DB8D6F45E019F34FEB7C47738A6EAF1604EF719F9C44A84D4C427610CCC764DAB44D286D811EF120DAC55B24EEC911D2EA4ED402E2AF97B91402ECD3140DB36BECFD542C243F83B7CE3B4EF2596B51AD9B13A058A786BA514347E56E00C28575723BB7E7F4968FE6CF9E23D7F26A7BA7565C37A2EC49A5764F66196A91007D89664CDABC55FDA070FD0456981FF5B60EB6FAA11A3A1EFE182451325ECF72880D0F15A9D3CC60ECD43E90BF6F9F54A5D2481EEFA526F5A89F86E51E95C14DB0B00DFF3547BF57194B877CB785D65A9E4ABF2843EDE1FA5EF99A6D2B29C10A58654C0F7DA6B3FCE809953A92168D59DEC6EB6D80945E328FCBDE8D3C98F6565F25E75E0BA5B61A9CF54FCBBFDF86BC1A0A4106F120EE223A1A4715B864BB7536EE9720A0C7410BD04C3FF7D845FA2EA869F7F849F01476BC08B749F947D90F2D80C8855F16658A012DAC784E55DC0D572E42983908A8333A037834016F3B216D66F0182E531B95992173F9253901F0BF2DA9E172C48055B4005C2BAED5A1ED6F319F79A6620F54F8FD09F0FF9D94D0B9043A1530BB5ABFDC83777A9E2AB4FDC8BAC0F36408B7FE135DFD0AA0C3D3546E805B5A2EC4FE8AE42F0D3B27F511CDEB3122DF40380F081C1C47F749361A007C3ECD260B652B5B9946D8DF6DB1815A3584AB8B5CBA86D60937A18BF336D4E8F6DFC338ED22E0BBC48DF3E5230CAD6F3F57D6A3BA1325FD6DBEF457042ABF0FE96E5C34AB61A1E8742DB40D308CFAD0505A9289B78D40DC59E974BDB2026A659CC54E3772943D22EBF608DAE2D135580806068968A00AC8AE48FDE1E56B28D75DFB4F90EB0E5DD74EC63ACA379C47264B05AB60175A933DC2DB1852D59DBF876BAD7E1A4BBBA2B5744B5BAD5CD8E76DF36B648F9CDCB4FF765F0883DF2C8BE7B1F81201DF8FD784D7A048BECBAEFF81EF69F5AD09513A46988DEA8839853F24469049DEB530C47D76BBC92747F1D4575D7DF18D3D63AE10AC87EF51BD63DDB4678BC7813018475E2253DA26F58F1C34A6A7F19EC3660AFCE1014BA812DBFFED25D317FB36145585C80DDE2149BD78BBC1F77234DC87A6CE4C5D27C9B4A163426DC32ACC0DCF0A4F2AF8132E15AFFEB9FC17FBC5BACC1B5ECAD8FDAC8E2B0AA7F7DB2C1A8AD7924C20702C7044BC079057401D4B9CD79E0216C6563A1C90865B9162D7E39A7CC6F2AA2706B4B9605E6B98DFC9B8F4601576A1CC631901E6BC1BC079CDBF56C4103468911D1D01973BA6293AF83159A3689FF3E13ABCEED3B2E007BE4C65180E449D5B221B3512D6CE3D1C7146B17B7CE040C257CCAA977FCF237668A3F2F4BF20D9B0D4F296EA498F35633D58B65EF4422B8A7A9FAA00CAA69B0E8BEB4434C972545E251A92A18BF5E0870725CE9B28D736DE972BB42E505CF08933366881E25C90856DE8FF59F5CF82E01DE8E35D4C848C2416E273DFAE0FA82889B8D176C80E19B068A728BFB14B48433CAB01CCBF4EE25120F6DDEF78DD6343A176830C0A2A80B6AE00705B0321EAAD50C03BA2E4272B6B2710972B64A971C8F4A08DC38B3D1A7F7D07E9864E4137B2C7240ABC1C59A67388DF9D4091D345E78F1F53D76382C9C38B209FB1B1119380C91C97A998BBEDE282E225B4A9631EED9003F0822354A1C82BE6697B643C11D134545D78F1A9D123E8F62C0CF2C3EA0A8AC77BFEB201855867270C3619C3E7796B6A04D8E3D61FAD0E9B4BE5CA387E5399BD04CD849E6D4300806F4B95761AF378F7C4C29D31644670CF106487FAE91D1E93ECDB5537D5463C05905CC7A32AFBE2D1687D4C48BE4E10D254DA80EE7168DE29589719431D0E90D3BC30FC14F0616ACB991F9428AF6F40F5736B26AADC373936F675070D36753A732A9CE7204294C51EEC31794DE97632C1DC5A160F20D14341F1BD1D82CA3F80C97520790EAF3DCD248C22BCE94770DA5915689C86C7AEF1AD852323D78C242EAF54B1AA585268AC60A0B8EFEA42663075D9A192D12FF7C421C5633BD3FA3EA7EF253B8335CB7BAE89599D5955C30FA9FC8F825B184BC92B11BE7A92B289337E51DBE68330020B0B6B7EC488EC53F40E20106ECBAFCDD1C24E72AA3F4A4D8C4ABD3C7ABC7476D8F0A843806C3EF94B62D552B02823749B094141F3D78AE5F58B101EED215A20111C8A2C3FB32EBA8514BFBE7E4108C149A8BA3507EFED0E4359ED62CE3B7818165F449DC8DB026DDC9EF621650ADEA01E10707E4F8F9C1939D5892C0006D1C0ED7179EF29BE0D30B2443B9F29811C743B1131A56C436C8647039394A2480D4E1FB99FBC6A9F3C75279499B68F23BDFDA5C30D5DCDC99DC9351FBEF2DFD886EF0ED053BB0ECEADB3A819C5D79E46065E651AE2ED7407548F92968F2DDA671219E9C7A5581090682F2EB423D045C5B5CDC10BF06E3ECB46EF4E176C2FFD956256725EE33AEEF74C013204B44C7792D4140219E562F5C52898FA86DA180EBD0199936BA5CCC5A6DF22BC17B4B916DD785020EC65639025DAA9D4EFED16C8CCCD041126F32DD0EF2BEA05F9FCDB3BCAF23E3CA85A3FC7F9EF9ED7F1A044C3AAF03BF1A89D4B9D6E9D8D4124D11711B075113F237245C7419CFABCCF26E832F960EF3A1556457836CD153CD90CD70B5BD4E86FF7DC4726B1E170C3B68A5D258171ABA49D53C0AAE292620019B7F29A22D2500DE5D7BC51C0AC9EAE9B089B676437306D79FACA9A4E82B1E43C1E7F554E63BFA6E38B67D7FCD6FE8C324537D86D3026DE6523B9D5494D629FD073B57343546155AEA505A3A7B490F1F95FA8B18EDE81FF899BEC869EF59C127E66A0AD96D39B9586389D3664DA2CCDA4246A5C5B72233F9FDE2F1B96E0291E71580DF140B36DCA5B77B2861BDE52DAAC2228E3ECFEDE8F82E1BD8B45CA2048A9A3340AAAA0F0F04E413868A363949672D8B066100EE905F4FAB90D9B59FA9DDB56E2AC50E265BEE71C284E287DFE0B91C1EE7B85440EF6F10E9B16697FFC64EDD42576D0C35EFDC718251A0755DF08EE85EFE53F19A431568AAE0AE883DCDC1CB3EF1907854A408898961C6586D603B9D6A9A0EC26089133D5A793D47330F9CB17B80BB78FFE49FCC631002875F2DAC93D722F221181A95C7EAF86BFC5FAFD81D479172F5DEB6250C79632E32B76A16CCD73E167C8122FC19B02EC537AE17E09A57C4DAD828D1FB2E54818A7BA5726375771A6F11CEF2184AEBBDC99D89BD85B134A3B2CD7DD12160973C62CEDE13E53CA75E3126C427ABEE9A3675DF1BCB6CBA5733D434529EF0B83F0CE4BF75ECFF7FD75AE68ACA03883F7E441E52277642C34827BA6F3396A98E15BE15934D1F1ECD24A257C0065F77C37D42263874C9477040547933F5366C295E465536EF744B88F05C6F1887D5BDBE9AF855962C044A98801FD5365EB38A0EE90643CF802559FA03E45875E9AE188D4F34C2C6BAEE779F16FA176E780457B263A0B7220BDA0D8FE2D72FCFE8A53A155FADA81053E89AFB556E97205B261B07908B8B411870454353E121C67E33FFCB4D2AFD58539D243A1DE5D92DE0032B0DC36530F1C11360F101A51C89FC97854ED6376F428BADA8F0B620356361D4FD7F9BC6BDE577D8F16BE10787EF074BD0C228E8722208E147A9EE552881C265572E2039A389F84F9D4A644ED11F3EBAE97182FC31A964CA451C00650D87885691688989A29CE1EB36A5BCDC6FC43222D69210F317E51A4353F8A4FAE675BEFCFA3F0388EF3F3EA205EBC90326BCDE866A3BFF8FA4BF3D19FC996A789FA4FB09DEAC2037D20808B6A0FFF99C01AFC68C8513A29B4D5C64F5FBC9F723AAF3374B06C54AC1AC6D1D5F51E384F314B6EBF2B1528F523F820EB1DC0954C05C22848350DD5E87A707B2AEED27BDD1B281378B91B079CC5BF23F8C614707350A0EDCD50E82421E9AA2CA9BA3E083613148A8E783D10CF440F6C20DC27191D06EEBAEA677759939FAA40345F52A4C30ACBCA0241D1CDFC4ED08DE57B63F8330C0A2BF99F3D73F59419A797AE5D1CC399D09A7EF7BB47757843BC95A3F1F27845A00E9FFDE8E1BF676FC3C08F006C5FF2A963511BAA5BA8097BDC1457461AC7BCDA26E70EE5598AF6B2B571BB255344CFA6CD375E01C5634196826427969CDB3756CA39FC85DF9452D17F4DF3FC6B9FF26FD849F34935649F6691F89B905E05D04D76BF8CBB39B2B131EBDEB02E5D09AF239EC2599C4A0FF01E6261CE932DEAB186636F8A5559CABEC6C098F9D7CCBEC76FF8D674E6A4B29F051D1AFFF731D042987F6971A379724DF0B6438CEEF04344C2119A31DF33EFD7199FD41F25F133F8D283A0BFA753AE95E472A61C2297609F28D45E779EA7870FC53571A068DA05AE6200C80E473617EF6D09BFB2954FC6175A191EF8A9D29267EFBC22FA0D66684616C401730F8A15841FF6B35527C7F34E0DD558A5DB05DF73CFD28E4B3785353201DBC976C5722080A7988892A6F8E860BD482C504F0679BFD02254CA40DE682BA5DB04B00E00BC8ECA193C4AA7F02E99E251C3CC36E8A9CA13CEE7A8FC02152377B4DA87D0C30F0BEE538AFDC9C57BE9CE52093CB15347EFE45F4312678D1351FA9E55FFB5C92546E3EDD9E9F52ADC62CBB9A3EC55FD31D53FFB5FB70C62018C6D6A07AF2425DB011F9BF93F96CACEDE083BCF5F3DBEF6BFB952A5F3C2908DB70CF32535C8AE6DEDF4114CC6E1F74F467D40C48CFBD92F8F6F15B176FDD22DEE450FD511CAEF7C907001E745A79A5647EE50EE228F04711A9094501FDFFC0F2BFA8E11ECEE0C0CC323C5DCE6D035DE99984A820877CEA1A499761B0F669B767A5CA2E1BCFC55C560996B8E75E243E9ABF1E6C9B088BEB2E5E88C434BB9EBB7A5FE9753494270B3CE8BCF27D6CD8ABCE4584C583010A722719A5E6D5326E198AFA1E32847FDD85F37129045ECD3429D336BA8A8F22DD88D5C8825F6D0ABF68D593EFA2AC84D2D97A327AE87691629455D6D234A1BD4069127380573C42EEC064D8BB7637BC2DC27F83C659A06A57F44ABA3D6F05F1F51A74CF852C516E64314DC31B43E91DB1D12943B16FC89FB93885206296C6979E4A4154797AD98084AF610884D20CEAE593AF98F4F358BD49681F5B8E43A99A006B03F241A33B37AB15A110CFF414B5C0397ABD1F984DB067C83AAC14F08D37945DCAC33324A62BBD13EEA03693FE9F7788EE7AE81EF4546FDDF7983018C3F9BEB82BF6446DDCA6477B2D9B63CC01EBECD3E1A98289C6CEE99ABFDA5ADE223F9CC1CB780323AA837C8A9A893B8314DA91B26051F9646139FA7E3F288EBFEDCBABA60F984554DDE8A0EDC778999A525B943654285137653247DE327604C521DDA7752DC6DD82C7041884014F4161908F7FFC8C84A19A2FB6FC2975311AB77F10F16211468322932DAFAA9F00D2CA19BEA55303321B6277D69715B8A24D3B994FAEE844B2BE911AC4D235C244FBC1BD3712960E1FD5695E023ED5AD446EEF189E9B09D59C24E7A0D7592E1580A1255C6B90D8D5DDF991603282A21DBDE38C7790303C5C342D8F9B0153854B0D2F1F819D5366FA0B8D370FDA34DE93D464300BF49513DFB798C0E9C58905B74B10181069293BFBD53546B7F6E369CB3E21DDE6119E0FB24344D4DDE90ADAFF6AF97B6180EE8482ADFEC73547A443D597F9350256798FB26F5A869E81D15C9C73AE1F96AEBB7149AF471F8FA3077DC4A93F38C6A23490C2897DD6D8B9DC749D604AA8B95D3DF81B57688B53387B16F581CCC2574404CDDA52D11FA482BF882E3FB159610D6754803A3F01ADE3FFC5DFFAD00C2420FDF47DFC60C6286C8BAB2297869DF9272C780A15678F03FDCB913F4DEDB80C70A93EA260BD3C34E37EA52FE336A4D0C8D9E02487AC03BEF1AE0815293B5B10004E3BBEFA0D0989FCAE97B47E2CA1EF473140EF3E11F1A6691A21AF9EB56216F5067E7E5754307D66FBF84144DDFDFFDFAFC322F1BDD41578C2EE5FFBDD3C240FD3AB6130180CF809E17C47B45C6FE9201BCAE87FE3D06E4333B72055F709201F2B6045B5211F81C16030180C06038140201028FC55A782F11EC1D840B3D1CBBB434FB170387ABE7A4FF9E2D1B619E1EB14DEE8D5FEA4E1B75C193F42E0C50C42DA24E642E37D307CA8CBC4726B28E278DFFC4C2012615A6A7F1641B909EC5E9B4FCDB134A77009A3B0C5D1673E387F6E9D3CFD35E11768F323DFC7560B05E085AF70A062CB17B0ECD74DAC4BEADA9F8826376473D71CB28730FD30473CE405B4B91D59D5A3B2E4413932410182572B188BA5BD47A59B1990950F0DEF48896F00528F8795A63BF1AE44EE7503F80CFE4F5C0A86FCA98D3748150179985B7174122058F7D1AC557B7FED2A6E855869D511FE606EB1988A79893871A640C853094303BA6E860BC98EAC2930273D8A85E87E61F38681AE695689B8DFBE907CBE62DF6481C160F51F53005DE7115D93AA1B5D15F288AE088E4E1A5AADD3325BF2627A3956962F036B211424FB7FB953249712DDDF6CA19A2D79E45A90C6243C810AA4EACB6C68AD389FE4229550EF7E7DEE2BF3A020E837CCC67AB6E763FAA26BD1053420A40A6C8F19F62869988F68ADD0393C03360717E650CA7E23300C184BB517B040588F68E28F60F16C1C9A60613DC400FB4AE112FF14CB04A9051A397F217C5AE57E71BD82587AFACB2124CFBF7DBE1EBEEADC1C0B6B214DD966E443B94D2DE9BF1038A23D6C66CAF4E56C684017D1287A3B707DFF92A418FCB28FFCC648186D39EF5177A69CA01591521A57DF566E3F189B04F25ACA0E5DA695138A700E3CD8A02A00AD435FF5213F7BAB9D43893FE2CFDFABEFE610F8D4699741F8B0B60A80F46388889D0926D379F7E1E003815610345C9F4959D6500D1FF31EBE357AB1077B7FEC1B811DF6C5A9AE20ECFD45D9B5A23B6ACE1BC0DCD038A9C036212D12A3718A24126874520AB750748E5DE276D0F96D4DD032A206C80D8D38C4469190D8AAA2A6E4D7023A816D95A946F1A4D41FF01D2F9DC06E558C2F4BE8DB440F86D97E6B69169A6334245113CE77CA0FD81335D11D16959E5F8386686B88EFEB2819E09531346B0B01EE5BB1C99EECBB1FDA7578E09C8AFDA37CEB703D20B7D56F58F77B4D42E73D098388BDA293B11EEB579BEF038C01200A9F2703A6F1D7BCBC7016349A37712C3697C770659FA1AEE688B28CD3F83299081C5F16E90ED81C80BF0E88E69E22A2369D6C1E685E6C2D76ACE7C4023DBDEDABF1CB4EABBC5DD1112A5CCFF9F6BF38A9BD91F6FE460C5B930033531CB19B7AFE68A369C35FD197EBAEFFBD18F88BDC2603AC8B45F570F7B81E236DFD4D81A8A092EFCAFFAA3B66D07E2072E847EADC265F0E98C358BCA2C534C4FB10E4132AA58FB2DECBCF5DB62766156A090982F76BB4BB58C05A408E9F49A50206A2D61F678BA086388086568C04A7F2FD78E040FE788A2086EFCF75143BEC0E2513C1F97298F48C9B1880266EECEB7E99D57C886816EDFB40F906DB02BFD92414113BA68F8794A0B6D0C25BC3EB4278A254DB35CFE6D475FE73BA229AE39A983720A9BAD6B82191D8003DC2BD98CB3789B653A6C290934470C05D8057B03C152E5E5A6286AC95BFF5E4F05E81B51112E2F1D4F1EFC8C31BD45B1FBDAF3707A5FD406A6E99FC93F17FED3F46C1001D5507A12A4AC46E08F512BC4EBCA00DADF1DF5DCC8932D6F6A3EF856D9CA28ADD50F82A2B0C45084443CA3DDD36121026FF38D85C569628C04FA4C918E745E0E7B39DB9F24A58FA74F32B570D718B39865C4F5AF57E0F24BD6DD73914154ECAFFA3F2292C5822332630D8EE753F7BD5F5755BEDE307A134140E40D178F8A6230DF0C0D26E204F2E10363B1DEA11589A99C398666CD78C8E18F16EFAEC3F9A0EAB005FF863DBE3445421CEB0688B21EC6221FF980F15CEFD6D6A10CAFBAEB39788694DDFE87D1BD00DE77BB509C024C607AA42A6221958C0045BD64240A88485A1DA7DA42B56AF121FF1D5AEFCBF6192C8279E70E9A0F14BBC80C88B2C17B817D41643B52219EBA7BEA060117AF1A8BAEB7D623663E71215412F92DEFC1F49DBD21D8249850E07394ECED5F1BBD670120A00803D9565E11962164452FAED81C425E6F72E552341DE0137FB11969DDA91C3CF137721B43B13623CEF11A277426B02272A11E0214034336972B63F8E13FDCFDD0B8C499F8C489489CFC92E8A5D3F60DDE0BDCF7F3E1D830250992EBDCEB4718424F666B8043A07C2FC1C08F377202C20A89047C6806DB8FFB2EA0D2EA3164902C94130607F4417E9EBF7CCB86B3295FE42D3C738667EC85BFE9C579C4A010D124653B007705F8BFD78C4D47C49107327039BED827A720A92A1D25207CE3F445AF1D18AB6794D23F4A12EA0178DA8D0F35125113DFE2C7A6B2D1960FF3F22C1946CB61A0143076E346D7F024426D7AAB7BA8AE2D81CECB4F09EC7836941ACD85ECE4A8194F73622597363B2740C8FF79DBF512800A2ADF5DC535FA42ECFC86AEF64F8B429C3E9D487B7773E9E4D8717038201C1EB941FFCE91C6DC95C180556FF711323A3B291735DD4E94DC474615265281CBB386F840EDC09E383430778FAB7D0134FD810DE524886EC7A1C600D3F6B6257125B197FF87B96B08005753A523D3BF4AF3448EAD8CE63287A71BC89ACB286D98629CF0D72AEB9B6401FDD170C45277F033DAC9FD725082FA94A3A813BB7F70E4EDABBCEBE8362E61A26F2BB6E73A6EA86A45B2041C8EE8BB355118922D99E7D9ED3C36B14D51A60FEBEFDCF238D7E719D8CB8DC43A32E1B2F117A2CBDC4653BF71049F69986C2B71BE1B19A1C6AA070BA21EFC46B57F7AEC129A7FF5DE7B387F3E5DF5A99F5B55E906BCBEFAF0DD73F1FA6729B2F9CA2117C28E1116ECD58562AE30020627EDC48DE13E40585DF36A55BC6B383F2511B084CA37EE3DA9C8ECC870916C20AB1426C86A19C1F6BAB3ED22150B021A1534581C8411C1BAA5500022DD42152E886CE54E54F484B6FFCA565A07141DA90DB8D151BC4C5200CF8D02F4B4A57AC7C48CE69F2DB3E5189CE241D39D820E22A7207D636CA0459FC0F98CC3A1DFA8DE508A1DA4DB3E4D27FC68F2D027672D13EF96B1F1C453F8A4BF53A3F44E2F8B3085F1905B7F873ABA4F819D9A22ABFD69EC0442B54D28D75DFD20D1EEEAC17B2CC7A8086A98BCD84E82D16C2B01EDA5C02761E982152E3166A1DE6A2BF643950C784F1467D410EDCC7C1909A5E962FFC17DA9E00F6D4441CAC3314871A2369A1B8188401B11BB79A71F8A66D73DF92F24DCBF7FFF2F1EEE261A3DD735F646AACDCA7A5580394F0412B9411C722B4268FF0E8EE608AA86FAA18587A54F9810B7F81809B9960EF5128789B917763902E6623A371B641D9CFEC3F61672B7AED4C92216A02EF8DBB7F1D75C12811598B39A5499D87ABBAF426C7FF78699DDD032B7056E9BEE0283461EAC84D99DE5A9EE82129FBE855DD42764F6A860E50BAD1E536199DBC5A9D455CD72F67BD01000E025533E123230221961CBC773CD97B8E7564DC9B6111AA73E29FCDA525961F4598490737FFD463177A66CAEE8821641C989F523B636BECAAC37E98980F20CAB20BE8FCFB5FB3DD171AE7F129C5BC8F77A93820D19AAC7DE3DB3687811DA9B1B516B92E32B814E9C4F0FE1787F54F4C6EFF3F9F016EC4EA2BBBAC7732CFCF57AFC5EBEAD8522830C1ADA60FDFEC6248ED31A4E6CEBAE1AF4070201008C44F7880421E6E1272EDC9168EDD469F16CF66912D72420FB02375B4A7E2D7B5BFCFB2415B5DC71AC5C86A1BC8A72EAAFCEEF585734F44F09CEE3906E5D782F1D04F083C865C6AA148A77F4BCBDDCFE68466C19927F512F4125489A6A100AA95EA4BB2F4BC8BC99F8C20F32CAA76C2E6519B65F772426C574C2A653C3F48C033B4C3DC2870BB9BADC65D75CBA6F9DCD02F24185F62B98E5EECA519A9E89F25BD1B0F0E45A3FE01156109B64DD41C232A13D8A51BDB576B10B9F47C30CBAE61D008C8D46C2C9707DDD7683930AEC63281AAFBD0DE065000CA4E04A37F2ABF08703319A0358F8B413020FE8CEEEB76AF030DF8A579D4AB8967B84FD1A8A0C67F2B93198BB7344D7E7E03E8AA636556E5879897D096685ACCBA9C0A669FCDF47A4B3151D514FF5D431E99841F8C9B8FB76054E966B50E103D63B643A9EA1E0F496BA3D68F99721899043679C2F80AACAB3C70A73DDBE979EF61AA117A7877B132AD5DFC952C1183B0A58ED26A9343B17E17F0FF3820C3C5EBC61F7FD684C1955C7716845B30F7174B448156AF6657692287F7F9EF56C8F3F404BF0FBCA2EAC78339BF0CBD16B96F449F895AD38D631FE59810A3C5B60FC280E2C322CF960A89ECDFFA765984635615B80989727BE2643D1715223FE23306E900D6E128CEE94D8498F0BE9F06C25A25017626E697CD1BF5ACFE02A77576E5059120100804028166A10FD351F0A23188DFCA61D1E228E8D969832F1B8AF913E775484082719B506CCB8B75453CA06366085619DCBD5BCC67072AB80AF8B11369B4D0EBCA78B0270249E94DB6B8CB781D76965D4653D7CA006A4920F70488E33DA0DF78D2194FB24B35461297FA3B3C21252B4FE20884FEE96ABD3A8B5FF9E6A860342F6E9A213CC0A960A7A5BCE83350534DE4E7D9D49B3F4A28C2F1FCF281C0C32837C1E9F97EE699306C43F34330376B54D2313B01EA74E2BEAAAAA1681F3240C430ED585D742D6C3DD44F434033315A59EDBCEB0016E571D044135C445869EA86C8226F49B6C6AF8464E45EA8BF6CCADA40634DB3BABEAF2B7A29CCB1A71483389FED5CF12455E83BFB1EE755801FC4162FB955D241B154D18696CDA48764E5F2150381BCF8E6F334515BF35E9C617F15630AEDF3077958ED3F861E19C46EC7C5BE6BFCB20DF587404B93ABE1C50EA6109049FF409D10C059C0010574D40D3551B8412E4F69282AB8C363D7F33A14E05E4A6D2A0F0B37437E69D16F0568939E11DE28833656386DFD7F1E5A0104F436B466F6654EB74C29B5BF77DE9DE25D18FF75266D6F884527B15B55D9ACF7513E56171902D02653189A3F12B5B793E225972EA85FC13B70171D4960EA913F6B68100664AEA9DB6823D41D8EE862EBD66D93BF7BEB1FC24D493E84DC04B39A1C2A1F1101C24A5F0245BF0FAEFFEEFCF19A5F05A7A28B5BFBFADBC46D633B223BA095F3C7E58AEB6FA71A926C70A174D513237B723E910C4FBBF317863C4F804A96DD9AFA8E065531E9E2E807A48BBCFDCFB19B146E19D659B4F6933154210C448735ADFEF32835854355A68EE7AC923C86899B320076F56D68F699ABD8F9DF89C077FE880FF35C2CD2127D105725EBC828ECFF50FC6E48FC03136BA0C5A77648C37169F8A9AA0343902AA054DE78E6784726BDBC5B059718DC577B4A43E19D79ACDD3B2B0A50C02A58DDE291520885ABDF86DD8A0CD5E7D4B18B6F4FF2D3B1CA91FB463D5C4AB601CD2562AE3B39D5D54FC319E29322EDC6AE7639B15086939AA7F20FFFF517F560AC850F33609073ED013E368BFD64BFBB9AA7367D6A6931574BA18C80413D829991C9D7D0D09B371AFDF8BE6E0DAF4E17F5C76FFE4E0C8DD2C83D829317A95807B2F124F8631E7AB9500318D861E993B2CE6892D4A2C87361FCA7B9EEE83BB2CC9FFFAD59429CE86F86725838A067933D738795F2398490B7151D7E5A1429F634C3F7E284FBB972C994C5DB46175E19FF6FC6D6BA16DBBB4091FD9BFC6E25F61835BAE0AF55C24A6CD2480CD3B7AF09D023EE141F3ECB01F1938223E58D3EBA5A5B4755497E612FCA973D5E8907A762DF9ACA9704BB51E733841130CFE5E5514D2794DE912D9BBC4223FF363237215C6EDC35B4A30B66323DD51FEE4680B541B3865902E746D6761AFFDE13C29031F6A2DA0D0FDF773CBDC0F35643D80D1FE8D09C4282B7B1E578F7AA787182026AD880ED7A006AA8088A47F338F07E587B7C46C7A0C0D42E44B0EE973304C293484AE9946E18BBE84D323CA3EF8AFFAAF64B548697D64A86F65AA3A971C8DB5CB86224B0252740A3DED166FDC15F3F6D20FEE50465F588FBB65787FE20189057781F3826364063B3BDC4A656F755AB68577E8CED60228EC81518F9BEFB6F0FB08AF51B6FC9B3F3F9F8CEF72BE5EF87BBD0919D773D9D266F139846C3A320B2206A5E421FCEA2E0371E6A85FF90055575B88253C4D86BA97E066938CC6707C1C561D814C24A6CA043627319A23FF0571EDEFA1B477C1E5F2E4B2632984D8EE2F4B7EE8734EF3A68E8AA4225562B9881E0AFFA5EA22CD3A4F63332BBC7A5D274E6BF6FBE4F112FAF6077A05F77DB38C7C3A6F21981FCA00FDED190335D65D67724042B31D622E7D83D3EDFD63FF2A377396934F3680298563B6334E7C70488054CAB234758AFB18A4A291B27EAE03EBE92B2F28448D00896E0A60CA56F4EB40501A8AC5E2D24D7F6CC783EB44C0E67C33CDEB0F35C62B1770DE3678E187D5EDF7B6BEF203C8590B4FB651350B37EE7270A7B0930DF89F6DF379486E17C361BE5471737B047DE71515A793BE86AB35BE9222A75AD2D298A25D6573A2B5665FEDB027CD96B7F09C6E592487B0878BC991EC38B414CBAFCE0BF96AAA393E63D1A33E8E019EED0CEAB58B38441A9BC0585405A65649B0A5EF13E1886052972C58A3F1CAAE9328CC0257CD66CA9FD0EB0FB6207669B3939BEC61C7F8F62BE5E5555AA15F6F705932D9387682372399A0375F0951386374CC3DB121CFF957B90B527C08071AA138AC681583B016E9E3D4A986C2FCD8F09D4FB43ECD142F2B86F44C5A45A001F0263582C2208D1803F12C61AD785391BC2F82C096B5EFB66FCAD0693F1FC1E95F8830865C161226B36B54A95B4926DCDAB2E817543CAFF6878B6C50CA89118649900C597A61A7E86D4751974D8FD8926456D6BE1DA88FCC119B44E8123963FF43464023188138DEB3CA2216BD1331D3D4D560B400A8EE6091B2D4A432CDA2548CD3B8F385CED15B7A4CE9F152DBB474ED0C2899DAB871F4DB9F9A1CBF9996302BE97FE40AD758D26B6075F89E63D2059B5CF0CFA0D9D58B34FEC6AE37A405BA7529817631DA9B051217138581E0403C6A1AF8CCC602D0EDD94AB99F16FF95DD4EDDFC9D69DB9C93B34877AA48B2016008E8ACDEDB94B66B922CCF5B35E7EFFFB5B15C4B39D53D6D6E0EF4B4FB0C6847B37D4E7F936C31415CC17FCC1F074458F25A055AB99E5A64829B7D20C035D6FF1097287B7ADA9BF5D8788745041E55B94D26CFF5E580B650A8953EA245B07DA21D3198735E3E5EB8ADA65CEFF53AF006C84DC3251C9228B7D7282E729497957D7DFB8B94750BE6532AE8E85B14D9EC7D1E2BDC03D72A1E79A1E1BF50F67A314E8BBFFB5972A436AB3252F7E2CA49A5E40A563DBA069621FED3885ECC3564F50F00C107F1A2D4FAF4989ED9A59A5AFEDE6730D8121F9F8F0FE6F7C1D7FA4733F060A1FD0F639A40D7F8450BEDD4BD57F27EA324288E88E7B38A478B091670743573FF49E220EB2FC6842E74BB78329BA361CE4DFD5ED843B038A06F0FC82276B1974AE42FA737205E849C7BADF7FBF5B5185F2A28BF25F6138963F77F4830D4A2B96A72D364D3F831DF13B9BD3727C7A5F0E0596B11D1CB4BBCE805F324C7C0CEBDAF319A4BFBD28407B6924554DD1A4ECE3A75BB936B4EE2D03EA2EDBB9980686803D5138FA95E29653917947FEC382C58F70058E347A4C9997FD0C99728AE42FF43EEDEF25018C655988869C45AA5EA6728F058B50709158C59A91AD429359AEFC62D69ED11F7A1555FEEC345C4F61F6F943EBF8D02DC34B6D30275275195D4C7A04B8FE51A30A75F71E90B6F69004DB079DDBEE9F97F56CE6AEF054C1C704A8C7452C868E1ABEC5B2D138D481606D329D5FA28246925ACC6C088AFC34FA66E93B113B685FF43B3F36952387CE71C1A1914FF13608061624B9AF0E85BFC3D518F2BB8BF2C911967C7CAC5DE1AEF1EE856A0412E8583102DC844C4F57B7503D02238CA6CA37F80F97316F11E548C27B31FF3CBF906D5C5F76837941D047304714F8A2E85C0A9B77BFEDD0A618FE8235C963285EE408B85FF139CDA6935A993F4DED142DB0ED0400743506DB27ADD1DCC8654B7B1FE650B1DB8A4B39CCC2334568C755B7EDD30341E0B6813AE262F1CEFB50829C00429045B6F1FE646748D9EC78439067CFC25E66FDD52B344BDD1739EF1F659D4BA746D64E4B4B6DA5341715D4AEB593B5AE30CB8E3C859C85AE7ECED0329174536AE408C666C7DB2725D95BDC39D7DC1D789EBF7793F5CB5F4E5CC6B00791A1CB6D07D19B2039A129A476770D7A5351A403C1EC2D4CDEAB0E4F3542FF33FF4EDCE2121D863F15427C3DFE227E605195A20AE9867491E6B6F22D63F82A0D32676FE449A71C2543DB9488F4CFA00FA1720EB3B471A4C0AC83A110FF00D045D92C2DF3C8F9ECA57D48B02888B5EC798F18F853A611EE0BFDE75906B49F9F78B90A037F195EE7615BE53AB9D4DA6B6D21C0010A392E23358D0305DD5566113219FF15BF79D0E7E0E5A7D1F9554F83BFE9991B76837F7652EB437BAAB052E264CEC386E0758D99F449645BD187DD77DBD822E475CB6960060E0D3D395D02C4025325076F3EF99A1FE9F00A7770E67E19155C91D55C1B5DF7547974BB5FBD1E16001299A3D5A6940AAFEA81C54AE8F6D69F87EF7FBF33F1FC0A9647622CDFFFF3E9F8ADB9077DD88E46F83BECD9DD6A74300E287B63565D74CAD4FA0BA178A968A5E2D6827BB0F82758973F369FF610040F0446ED62C4E252F93AEE356CE461131BF62631F936257BA2A5778CFFD988070631623162ED26FD30F5C612D3008B5D5A6D1F10AFBE7532A224992F18C151111FD5148408A6F80E643E7DE1B22C83E2839B8F120C9EF6E6DFABE0571904E0C783C69F88363FDD3809390E26FD01BDCE00C6E4B283B33A0B24F5A4D12F9CDDE92F3236A1E03EE165A98F5E9D13A18C052FDD48A2795D06272A68E09FFD3C63C7E32371D70799E5542C14EE1C8439E5A5897CBF6C3063F8E597D4ACFA3DB621AFFFE289882830FFA0D6E9125458AA970608F0540A7AA8806327DEE07F5F3C3F07C8A1E2D0628ADD0B24B8CB68E1734ADDD36BBB38C65B0269247767C94E96D0125CAA32142BFCA2D0E60B5BFF52C2BFFDED5BFC8CB54ED4C110B51E662EC050A0377B09C0C19BE88D67FA97A378049CAEFD1D3B8E1FBA3FC0EBA294AF9CF04768E699A5248EB8BFBF11107DD668FA6B0FD3719C049C3D8FF8A5E4A0F374CCBA8BE72595572AC235407EB1D766CD9A090BF18EC8205D7C3ED8D01A1C96B6B196AE99906180E0D1B7986F006B79E85B2D721BA9743082C491EEAC5F75DC0377A7DC4699D4C0C27EA7B138132AE1BB7AB2C233528748B49D8DD9515B5D53CB28B75968B2DA2331FFC9E2B0154F92E287ECF9ED2B60A06E7859B15DD13B4D911EA678DE4A4C7E4B8AEEE361E362E72B656BE5E96BE70D0A9685E6D8FB644360A90E831B6A6BED35A3468ED0D5C2F88FDB4DCBE09CA88731213BE47B53749511DB82A405FDCF11DCDEFC4D55D71B82FE8483A900EF2441BFA3D24E1BF79F830D73DA6F5C2F3868B94AAFE19F84B92543F9BA78F9F9C1836CEA2D2149F7EB77C46BABAE847F208C47783CC0B46B06E5D1E905A08749388AAA60EBCAC202D164EB18601761BB012763D9A15970057B829BCBB20E7BB10CD588CC557F66F8D0C998433B8EF28C932483302018D8B7FCE7C14088E9E9152C847D3948C8E63311AC791DA0D9423F6AB39A9E0784C4C175157A332ED6941D087AEA27F717A5D8511F6C6A483312D6541C50C7BE7623F5BD9E056F9A056FC0A085A7A7029DCB79F65E1EB1D0BDDFD15B89C90D82EAEA64EFF453C0CB35481613AAB29A98F664BE7E90411D1D92BE23483943220816022696D304521E18C18E41586EDF5E683F523FECDE4CB1FD21193AA4F3C2209915FF56B1A50AF60105D893517FE381EA842F290E3BD3DF8AB688778853A4E5DD8E6A7C608B5E897DC6FC7FF3BD872C51CD0C41D1E9D2EE42DBBD5A347F8294A14C42B63847DB87ADF20450388ECC9A21F1F8B5E5E8E1090ABE85C474B3F3B572B3F27161B7F676B295C9C7351690EC3AE4CABE0CB0B38EC121ECCF96272A147756266EC5351D55B8C33AB9F457010043C2EFD496DA78F98F35513E734FD11A5F71B3A9F5DC1F9353A91E5135F58BA9E9354A197BA9835E0AEBBBE317CCB7D9C34E24BAD5CF4F838C176D2BB7B8190468D517BF36588B28F0E08C059342A9B4C1077175A8AB213793CB06C4507EB6B84CADFBB2B2BBB00E2FF281729C2F76D0E75F41537491BEE6E5A3B0DB953FC0D2E85A92D057845ED893B784EA66253D7F9E5BD2B7B1F14F24CBE9445169A687E80697D14A39E4DD80EC8E50B0461568FF5364A54FBC7B57CF5399CBBB1774094B971471B99E4161CD7531B85F15CEC0AC7EC70AEF6A65FC445630229D46F93F9578640E604AE340029211B6424A5D6073E4241B050F239CF75F82C1A3862BC0F62490C6FC523D32C164F4F7A6A497E80B8D4F865E18DB3972B1310985F36A143C3B3E6253CC184BAE8DFA12FDD5ADA793705EFC8C4AE23E34C1BCF0DD2CAF2F3368EBF7345522C7C08C8136DFE04F90E5AE874970F9DD4A235103CA9E6035F3D3834F113F62DCBECE505B417BC046B980216009E5CB9F60010524E2AACD977FFF9B2F772233224737A2DF23EA71503BE86A2445E7D8169E7D1C591EFEA54D5EA9F41B6A8001B15C386081A60465461ED4C0AD25A1C3325F74371FDF5097D5B71F357055B3538073B372E9FABB4A815FC7015B303DCDC7F139E4DF6CCDB26C795D3A8DF45E1D341E1DDC8C7754302A990ABE75A951E950242C3B9D10122C5DB6B1214DE7B0E79F4F5465DAE91447AB8B904E5D6AB99474893C8D8A94462A5E964E656BC14E4AC472338C8C1E53018CF56E37B9D56B311BE6FBFE1E5D65129C61CDB135841E0E48916E4747075BBCCF15601C7F3546144E82BEA4AE411C0E049654001F08DBFA08B72819AAF6C6B4DAD5923403EB2A0F0EEC1EA51E561617D492AE55D9EED7771045D4F9562A8E3CCB33B15E32AB462AFC193DD803B27D0155965BD82FC08B57CF2B50D45BEED84D8AC0B7A3419B1B8A0E639E7D258C211CAF1097D26EE75BA3C0E2F534B45ED7BE1800AD1BC7D37B29F2083B12632024EDC0302565B422A6B21C52D0BE6A3F279907EDC652ABF0EC49FB13D80E939A9A71D417E7BBD394B4169770D522E49C1E875652360BE7176FE766B9F1E22F679CEB9D68CEE9FF1487CADBEC17BD424B99BF58D2CB50984FC9E330A7CA0AE16E3CE168CD70F666A92EBB03464C698B2A9E5CB36208B162F49DE197C146304D71EB4099513252A5F3E72E67E789BE098C7E931A3872D417724FC9E0E34E73DADD794174C8769E5AB9FF1F7AB5134989B2F7F872D1BE7869BEDEB1E9603CC4025EEACE72CF7F3A5DD0C21B54D4256C6C4AFD830364FF18E9EC8E7B199F66ECC18050072EEECB6C62E92738D61CC4F7D76FBCC807E150115A3943B5B5C3B414B80B5442AAD95B213E8E73CA02B2DF0D0DB20CEAC7AC5CA9B6CBF2280183E8DB008937AC1B82C42394AFF3A62B7BDA0F854068419955A7605A90F73DC819A46659FDE73FB9517E24945E0D6591078A1526EEB4324A567018ED72CAFC904F5D46B580F85DE7CCA6D537186419AC6AA1F50705CDA9B6F2F4D691F23A38649C90280268EE038330E06DD1BBF8C662F62DE01B8900FBE77FCAC7682A27227F02A09FDDB7B716C3971F01C21782C93719ED3CEA603A080EB7A04376F19F2B3B379569972C19463AFEDD06CDE8CC37861362F0C2515FDDDF4F1F858C9A1415C038A46943310556B4261F2E1C27B034F37B2498C92303F8066B24B023CF009FBA7FEA25C54CC15F0372491DEE041022F1C98E88057D74B501967DCEA70F80364CAD6B7732EEFC7E9E9D707F27C815C8FC4592C86EAD2D5683DD94C233718209EC30494D4736EA4BCF983F0C47AD40706CB8EDFA83B8C06ADA6E75BF438893E4040FD5A7C736AD2F44D127BF75A5ADB809F80499FDFBAD890AC95CCB892FB88999B717EB4F5E6F9C88B70801C09BC614DF31FE399F0C5A6B17C318163A0E5F257B667C04B118822B571F33069089B4740DD27C1404FD0729B4F304BAC38F1F09D4010BAD4A78E50DB7FC9AC4CBD1FBBFF32F63042CB626C7067E382360F84061967D4883AB104AB54CBDE0083F86801C565050114F96421A6841C2F3408E60F020441EFBFEDBB415925242D785F6E65E5011E279CE89362975FCE762BE0A7B4081799E60D3A6305B62B23468EE12C5E387EEF474E3E8E6883F96F9F732E5B57AACFE8C9AC56D1428A5E841F876D4D93D80E340C7A0E8A415CF1F27919F9F58C6CB8F6FEC922226258AE27B14AF63E9FBF7B184202AE89898CCC586D2EC40658B0B343CFB9213D02EFA6EE3B4235EDB103BEAC1524997CFB828A6D5E983E02376CE17E3CFD50EED86149729786D8CC5C08A41701D3A3DBB157D9C2EE57C36B03F824B7E091F15FD09EAAE2E64898997C4941F0313B2EC5C514FD3C5172DA7954B24F01735BF0DB45E4ECA8F5E21EA2ECDB91723A5BBFEA97E1FEEA048DC6459E1171929A6F4FD3B3B6A2C3EC0A7646A20601A53B638B47C60D2CF64C76CFFF1E1DF159CC850A7EF3007AD8E18BC45F4B5DC33E1A436541D7597F11729314EA99AFA93C270466C7D93C91784D0A40D715BAB92E695FE68F71A3D56702021671DCD73CFFD3FD2B03A346251D49750E01B7EFBEB2B2846EA528052C4A9831040F359E23127F2EE4EB6CDFF8FD152E6D4445ED03DC78DB35F9069F5C7CC9484B71BDE160407028140A0E24C86262A28E3E595D068998270F1268EDFBE43B8097B5FF183E390C5712D29810A076409BCD5E09CF49C65595BB228E6841DF69BAC1F44E3807E934367794D9EE378C856DD4D6DA06A9E8FD473CDE451DAE487423819A7D51470051C99CF8223AC8EDC59FFFF169CAE342B9B952C44EAAEFAAAA54F6E8856C4CCA275CA6DBC3A9E38C2C3776B76AB1B525E9F17661F9F29CA8F74117840F575E94AD6281D8438E39B0126DE8EE283C986230013052E337164969EDD45C4F64CB77C42517A2DECA4B6AC08BEF4FFE63AC39A4984DFC625217544912EA3F51A4EC29D3951C0066E9A46CB37393575156FB1816C29D9AB41C13A4329BF4AF1520D8360A0F9A8C64937A50FCB2478E935ECBBD99516C6A7A7A1ED29965FC8B7DDA72E7FE201E9C75FFF81AEA206D6C3A470DACD8106FB03166D7C857DE234469E992F3193A2A4F07A3B1FCB9317D6699F65173486476F5B00FBE29C66119419444BCDFB4CB242D5EC8AC8EA4B556E6B6178A2C2C95EAFE5EF5DF9A2FDD335FB9A4074F2F355A3508DB67EA126B689BC9CB0EFA4378901E0B9589401ADCB5F5A6667510A0C3FA71C539C7BE5F0FA8B5B662B2C882FE3D5DD344F51892AB5E7A0A9B69F9D6D9BBA6C00C95848B1D8E3F36CD61E887F4BF8230E3D6571FD9FB8A3E7135984A6108531F210DF5766653DB48F27553C36D87A5C94107189F6F4445A855163DAD0F29DEE8A4E368338BBFB8877C5FAE5D87E4AECC171805A113CF680C34BFBCF86255F6E2C91A7EDA0346264EFE74499EA55F1D4294B7537FC85CF84E63EFB4768565479335E3B8FFE4A67B1375BBF6C5AE794F12B4F690F03B954CE7BED76A61F04D60DA53BADCB1DB1930D552E4A2D4729F185BA55D4B377AF6A4548380E041C0CE1DF43932021DCE5DF6CDCE72DDEAB9A8BFD9B8A8DFFEA50A1098587295FDD1E1935BA57B2761B4A5B20D95709036862DB58489F481C05A164240E0FAA98B4CBAB65658326711A8E5F39514F26E290D9A79941F691E11F8831A1091E07DC1AF7A6DE6BE4D46F2BA7BAD4CCCF6F12FCD00471B3673C4C29AB4D9B32FBE8B7BCEB6F276F1D6D6832F5FE7197E514B594A1844A8C67F00A0F74898F0F2D05DCBF40998CF2E8DF69F5534DEC4BF8253CE597D104212A7E309E5B907FDEA86E3DAC9A79EEC32F1C5B6852FA59A8409E415F04D61C4F3C92C5ACA4A4253D014D7086CAB9900B7FC34FBABF625217FD2934819BDD8326ACDF3D8EBC0BAE1AEA7F2736414F4E25D1974BC3A1899E3E9F91F79BB887FD3E6EE92F74B73BD5DE976168025372DC3759C866090B6B3C695D6F96A2CC373980265E5F82FF18B7BCF78C4B4539264CE500987C55E9D06444212827EDBB71D9839F2909DABFC8C1DE7C6E3A68796EB0D0F5211AA1D57FF4DC0A46EC1FF89BB0009A60B27647DAB0FCCFA6A2DE72A4EEA31D538A41638126CF92E9A5681E6E405E951235621F3F7726D1A75D68E29D76ECD9C213E9A24DA29C0C3C5AA7FD1279958226D932047F94604EEBB8E567E19431EB222CD6068FD0847197E3D1C06DD0420D692510CBE3BB8DD69F5F68D064EB6B4C598A519900F2C0BD005D8D191A15D16A1E34E1A767F85713CBB7D7A67A2E20E579392824885A0E4D3C306A3E1DD464AF6ACAA05EDF49631B61A26ECE0294463449FB8894EA3442E8C6637DF03F7C7C318473FFBA199A88CD68C59F2B86D26D0AA47751E185D6344BE1F4424B567C2BEAD59053ABD5E1C332BD8EF7BC3A1172247BA47E32B111848B473F47E1DE0FD18E3CB07D3E7C100C78442BBDE8B0B5EADD1A4DFFE419276298C87E208767FD459BFA6DC8716590710A503E8127EC547DF56591FD63A47AC8EF0C3758A245E73CF453BC8ACC40243B2B1A040281402050B770853033FEE56377EC839C07669B2C5244A706A9706D61B08263EDFF19BF561DCBDBCE82B8B9402F800A39A87E5ACDC4D5F7DEA5E1A9EFAA23FCACF85BBB9673E542C2E7783B922BB16789B26D257C26B6ADF44709575464798B018ABC232330915141412B967F45977453B89A1AC5F6573C486C1A072D303B6C73088BF9AEE0BF9630D2AC2D8B0C28A6F3A743C54A5E697F72EAB5BB343BEA52B16D6945CC4E06C266B8CC4647E47F00A6B740379BE9E5A7B3736A2FA9C263EFCE6DB3C62061E5C9B2F9BE57D05BA441374A15080E0402814020E99A7CA8DB705A31A335D0909626065DAA633E9A7D52B7D3512F096E90FEE1528D51E70AB8D5188EC6E73E874535DC145EF49CB25864F5B6B1DBBAC743C8A7F8866A3FB13FA2785AB9FBDA795BD978B8E1A804F2E01C1F8DCF69014D7A31682F6D6CD72EFA2FB7AFE241D4663D5D708EB72F82DA20C8CDF3E370479CFED328C168D5189FD3AF29B081CB5786A3DE1CFB551F7E128C318D5A62F3F5E83364858785F33989D36F2D1C4C2657D7429CBC017D22E4E1DB8E9FF1881843ED5F3DA243D2779B8156E26BA7A212F6DF52C588797920B190BAF5F8BF51D663D4DB6097BB1F0F6C11156870ED1112B7B22D2DC6D9807D6ED0D314F37F4E32ED43E72A4F089574B106F7681A8DABFB2FA6B17996FDFD7459002B1F9EC95F1905662799851C6A20DC140DE4B959AD527E73F5E4DF7C316511F1EF8E98842BE22C311AE575453AF7A936366AC35EE01C4FC05AAA3AE16EADA47B488FCFFD857998376CC1307A7937D7E3109578060B779E8935C1CBD047F01F81FCD677155237BC6C6F61D5EE42876B3C45BD278E2029C0D1BCC629331E125AE1633008EA06DBFEAAE9B387266B4C3D3FB38B67ACAD25B303C3DEA8FF27119946825AE3318F07D91C89F09ED1B3AA449C491804B3BDCF0619CF884AF644878B99EDA39BFF243D284AC1F5FDD2E6EEB5929E760C4626FD9963632ABB7FF68B358BB354FEFA29FB3FF79603EECE0A643F54414565D960C58AFA841D39DEBDB018F6F2BF463EB555CFEF9410A782D218B0B5C5CB4F1AFBDB1E55EAD73F49F9C2D9675BB4FA1B50B8B4B15C3EFA9331878C2C8850168437274AAB8420D4EC87235D02EB060F6BF70E307BE15EEACBADEE7CF4099CCF466511C5AADF3CC49C442BBFEFEE41D4D710B093C1FEC1AC9BD7A536FC36B3A5949416F84613E652F769A796A257F7E3C989D34866F6877D1B2D38025000BAABD433A3A0A576F9DD34298DF05C1A2D953D9972187C1C7714B84CEAFBB4F4E40827410D520D8330805830B2EE5154608141D6486C0831787517E37BC42ADBEB63F87F937D2FCF0B2A40F65FC4157E820C7A83B03DC2274064163DE8AAA0188980425C3BFC6452C42B1E795769865502A93FDB8490FC6D81521D72A68353336A78A2DA9C84BCC76B74C25C6C2977B9C1011C1452AF5F3EF1D7328C49D2D52CFE5C49A2483D121A10A0BB158BD96BA7FD4E5DA20B3885622DBBB35652FD837819DAA5FE837A1CF3C84D677619EF4DA3EC8A09F46774C3A7D4D89CC02198D42A93A3BE88BB5ABD534A966F02EF30C8188B7FD387EDC205EDDE4EF2C34F2E48BC8872BA71FE6E2F40E58DE2E9FA96893FDA747E9E13FBA5A251FF156DA70CF347252DCA82E63FB1464B7A80EF072BE5390BBBBF068958CB7FA769591B8320BF74D2298BEE0B8344839A511364782221CF771261E026DB27CAE6D077235CD9644F5155255CCEF8E8A7DD469C28F9EB21964526E50F119C2393076A4E4D6B908FADB3F2F50E53277F5F41ADA2471D6D196FFAECAC00DEED8630150EB7DB31E1DFDA86851F07BC3D47BFFB5D9430A41D825654751C8E78059C80CF82E3BE320AF9F804D65F91587265CB86FA5C9FC9C3A35BA5AFE87FB7C5F18D4375F5857543868FB40453A6A96A4F0424A8B811B28EB0DC09E8CC0B92FA1874F1116E03E5A1B50A3051527E8D2294222A42ABF922B49E082A3A7BD876A89A94ACBC608930080330B9496AE935B7D7CA56EA21E1E45FA3FCD6BFE39C6186BF7C19E7F529B5B77300D465377F3CE27DFB1B820B870F7D55C9CD3737C0F4E74DAFAD31DCFF917C1A633B15D4CDB98D49C4B9CEA960EFF3396D09FF8BF555B39D0F3A5B38FBBC3143AA128346E35EA37C2D7B955F50AC01E05F419DB13C0C3A8EA9CDC740D8648FF3AEFAABC369357E1A60D0CEFB377E96861F1722B166C2DDACFE0877DEB940782A658FE195D636AC1B2EE6791C1B28A86A122401829ED70505B9ACAE41399AD2E4005BC543F878F8B00A66A53C29789005056BCB969205E71DD620E6C523B0751EF13692B8E5BD075497A14548DF3F53814CD4DA7D4FEBCB7D116D19331121FCD069F9194F214B5D8C34ECB5D57D20F70CB69B2CEDBDA45CFDAA002236D5758C8B41180046C280966BCF63E56B69584298A645246C9362B5D9172954E6C6D2B645B74F002FCFD29824CC11EFC0036B48BA6FC61F9A034B235F8F1CFA3DD865088346043FFC90FE3B134BD7C228F8AB1A2FDF45CCDFB2BB611FB042AD2013D30B7019D69BC91FB57E7DC98E0763AD70BB0F82BA21B2BC9BDFB360AEDE612E02FC5D1F6C721844EDA00BD4ED048B2D31357FC2C6D1D7D6F0AA17C13C8D0295B3DD6D4D9501FB609582E3EE3D60374F89300803AA51677CBD86EA21D370E56E5746F00ED52843138144B1BF9D4463FD0A4C83E900DD41C3F25CB6C9E39460E1B1CEBE57F772CEC73EC7F8B15C7F72055963D28088F6CAF0E6605C9B67E51E8533350F2ADCB136CAB7B8DEB249754AFDEB371A1A27FC86F5FD028D44B30F213F5290BF2CEDF8DD6001E055B07D791148342FE02052CEA16B4109B6FA063787A83CF585AE67E2A2973F11A8CBC5E18128AF617EA17F5C251BA6F60FAAAAED209D278A17311D4FD844B325863A6381D760E1D2FD2FAAA81FA95CEA7A8825E0BA3B1CB8AE4183B9A274F7D638DB6063276AF81DD1CF3921ED3B8F172BAB5A5337440404070281402090F12EAF82404F63ECE8B3C972ADDAD9FFA63FBD459C08DDE831D1C4F316AF2C21B01892720D2C471FEB69A26A8A2033D8D0AEB7409496CB1DE3E147E32BE86D709EA3FBC94DA01AE280C6C6D324CA821C176E8E82DF28597A91110F79A1BD2EE683EE2E14BE9095D603004596340962DD6628146077967820E6ECFA4213B36DCBCC5C347BCBA09DCFA1079E9896DEEEC7C262D267D7CE1473749AEB1D7849BE62F46F25BB1F2FFD94D5AD6AC5EB33E68E152F206BC62445F26125E8FF3ECAB3D79C5B6F5D30560F84FEA2E2CD0D4680CF2680A629CF77A76871AD3716EF1971060B95EAB640514ABBA1FA2038100804028120B750C823E422AABC39F2061683847A3E184DE53C972DEDE247A26BCB891E0336836B5556D050B9A98558A75B57DD9E906C1E16684FC4FA743D575750D0419CE6975F6DBCF263759ADEB1B40A01A176A5A90C703DE0BF6765836FD2202800E40771DBA8CB3AD2EF9A28B4496FECE31AFF7E0865C612454F3E51158360208B5630EAF56A15450103AE388691E7069B2A6B9B6F3ACB224CB5E4652AA09E1660AB7D4E676D1E3A3B2711EC364C7C66BA9E689585FBEFD4DAAD776F536C5A8D0A6442771B724FD55DB29F768B063F734D60E231B0D8B8B187EA09F30B6AA384740C078626E12837072D866156C83A35FEFF6D350244FECE7D84116CF183C749D9F48A6A77EBFA03BC5AFF6F2FA59B1AF33741A92BA8BC7D9D18EEA927FA87023D0B6954BB6C724DCDB7BF5F5B40DF9CBFE5CCF298175803EC58E40AF3FB6CB6D68D2566F60403D33A92FF52B7801FBEEFB9036EAA6870E2443616AAADFAF04DD34DD5291354548D5AAF8AF9D80AA570B902C583FB591938FC7E707D9D49FFB94398C3363180802C6E2DB3E3FA0B7A80B8BD8A591F375F492906E0AB1B5059B46C108937F7C518349F0DFF4352D9FE87578D80CA97AB432B81AF5E57CB064DB55D89ECBF58A0827E33C475B493112BAB97ACA571107A098C05B2CEE5D04B1F6453E2AE2FC275BB30F6936E5AEC3D70F2C817B6ED4F222807DABAA23DA38B3E34087E84E0EA6371A414AAA0D9FAFE4FEFCC07848D0ECB47AE3E4BDACE2D9755665DDA5CCB8159B5685758B58D2D508A281428753441FA90E4046FC7F9CDCC26CA579B70397B6BC99E2C23BCD2D3F8BDB83182FE9541282F0A0EAF52776B14E99E17F7383F78ABD6AE1EB7FA5B582FF38D5B4E3EDD787A1F90C129B7703EED5169021AF9EA681BD3258331281A1EDA2E2DF4455A7418F7771D4F3D143B4C7ED9945F1D5135EFC597BF8E49C7BBE09B23C390C9DA3A980203E76B5F36D08B7C33DA752EC42527DADC604277F36E9E14F70883C2FF2E58D091000CBC4F79CA58B4623344ADCEEBD549021F9C2E06D63AFCF013F347625345FEE34641C1DDD06B105CD42C8C027BEEDE3F1ADC0AB331BC115E9AE4974B3FFD72100C3A17DD7AFEFA9D1E1623F67B11751006A4E70F9DF44D4E86181F650D1FB5DF245D60CB1F92E404E7F4CB5A2D1277E43D017A68248303447ED93008CDA28C9D5FA8B11DE64E51BF963E675CA8D67A9278010844DE7596518B0AC66881495B75398A29330726E92845FE83F102E145F5EF84FA6C1516B5200A6C5371D9A25CFD35666A9CE4077377CBBED6E0ACEF79649146C4BD5685C709BD63767880ACBABDEEC1AD4B0F7AD19A48FA42D3F8D7E72FF4F37BB5BCAC7ACDED953D1D15B46A821FA08FE01B92AC6778EA515EF3CB2E164F3DC84B6E36433101AD304BAF1987E7A5044E179A08A3E17F43F7DDDDAB9C5B392554AD145B6850F0A781E2AAB6203943E9C3CB8BB4B2BAF7DF65E221D5B74875C2168A18BF5BA8381C37569C007FA1D23556F73A40152E545C79C97DB2C8FB680B033782D679B6B64E946FC4BF03B56D718FB4AC3832A37EF028D351767F11AFF6E7D3E6B1A1160A509FE783A77DACAE1981DF22E0A067A5BE1100D7C3487AAFCB6719279AF5D63F01C58E5DDB0E696E3766159D73BF47BDA10F1EB0989619735034620955F6D5EA3093DF7F7FF5D5E5CF3C25DA7835C046536C022A69CA70EFCC3A66D304E52FCC2EEDB7DF425C143AD69E8B472F071C8125A407FF95CF7F77C530CB2C104D0077ECA2FB62D1D7C9B582F440721B5D2734838B199D9E51873DE7EE9F7A83F3ABFE89A150C8C3486FB5E1FB9A0F8F5253D85989FAE2693F3BE732958062565DB4E5076180E9C637725AE371C8FFE12ABD06AF7005EF006137AF5E4712D959BEB9ECEF313C8035CEC52C380B4ADF84EB3CF2663D37B6C86DEAE7A0CB9EC725CF8531463F630B5EEA6DE0D9CE7929A9F051C1C5E46C32A3646F6E6393823DE4C5A8A3F66E9DE08A67C6124FFDF5ACA9F35C886EDA75367C3F6E4078E314303276A6531A7977C7BD8FB56F353A1DE7D5BFD0B41062E856DA972BC75E1648EE86AFA8BB6BBDB35CCE221B2E6F9D62C042EDB50AD6D835561720F8189F1929D7D0DD45085690959115193C10D7F15A321C7A6F7456CD9228FF0C720194B60144E836DE9E88C8867B7046EFF8B7B2F8312F3E9D0EB02B15E248503C829816A425DECDC2E2FA3A2CA35CDCB6764A02EFF0B57400DE0FFF48A62335A66ED8CFBC0C655464A4EF573A202AE73D44EC5C10FBC860040A034F0460779AD994AC2176C403D555E20EEFA0F82E103FEB16CA200E178B3C64549C8292813E62C89AC014E237B6C85A386006E89D50945E407BE6CB8C380D7C2FDE66525BB1562142957AC4D1F67334EAC7525CAC100A79C88B92579695F6DC7AF0DD7D35EA322F1BE71B22BA2854D3FDFE827B98A7641B840180D8FD24AFE08A801C72DF7F6F6C04762C6E7AC6DC54C23F2D56DD8CE79CB4A100929186261C1FA24A3AE1D172B24E66934EA071F1013EDE69851FC154D6BFE4D66E701F080A79047744954FD740C4F8867F64ADFC765BF469FAC3A415CA4295E4B3694701B7FFABF92EE40A6B5778B2B424253122C8056968DA77DA64D722B479B1200FDD3C60BE7B74CB32ACA6A738B1E0E6EE0006FABF6EA5EBFF8F4A9B52A50EBA1A17C8C8A58DB65B45B80EFACDEF330770EE11013A010B4471F1DFB0B77C2765445DE71757FE1C92D3542E005037E1B9FCDA89EBA63DD66C4BFAC228D4030DC40F6AE895D9D9730B72BDBFA2BEA7E6BB96BF8623C6899D3CB4C0CA3BDA2D8C7A9F6C9021BBE0C21C94A84118D0E4C8C19D7159BD4CFBD3FB7AA94BA6E34BA5D817B1B125E4DC7FC7812F28D32240806D2286724EB343B015DB90C5546401D6EA9A41EE9E9DF2196F7DBF7677D8E76EF8843B9F6BDCA10F2E8A2BB79D1431B06C6495117747FC59390BBDF242BC6B0CEC68F6D457584C24F1A05DF64DF9D5EA731B8044B67AA1D875674F8657E7C0515922CDD92E31956CF30075F07301104CA74154B2ACF073A9CBD18AAEF7D7C8E8960E83E3715D5534816F72D91B9103DC3377C1FE97552001E280BC05D5EF6BEAA4F797BF7AB3C8EDCA87B5ADAFBE6F7092D7EEFC5C234E9C967905DC9EBC0788A9CD99A295C3E0E27C0FB64BB37217F7084758FE47E5B28A0A27B646436D5951A28A0A26AE4DB77CBAD2B3D7C1AADBF312AD8783D0E0C37E95B7396F4483C5A9E7FBF50EE0069DF225010B5C1FFE6A132477D3F599237390E6B5D2C3FC19134FFCB02F4529CC216080ED3E58E8CFD7DD08056F8BF6DAD50D0A655DB2BCE4B492FC4876FE6346C30A513E0E9F5960AC2BA32092C7D381C2C8D5CCEE59AF8D1E2D14A9F665FFFC09D988F52C264F101DD6553E37FC4D08E968D5A53C07C6D459FF9946A37D245E4A8D5B67BC817AC5ACED1E2728BA8330E0E55F0FB888D087474A76BE17656A7956CD5F844177695C8144CDBFFBFEA1ED1640361896FB61C15355DE24F2473FDD2F7CF24A216AD89501B15CCA015D684A4407BCE97262E0C293F45BDF8F6EA40970BD0DB874D9B01FD14B0948AB91EDCCF040830B7FCDAA7F529C11AC827FC28C117CE8FF1D1BE6A07C36C42BB58423455DFAE6DA4B295921DDA8195D500F6E5A2354B8A42002DADA3A51BE11EFA86D4B220CC20055701805A4E778C0F9FDA785CD479A3CF2AEC19283D6A86A55FB7FFE948ED2E3002EAC91670B42C0C1B27ABCD4EDA47125DDD688A51B4F6C72C6F4B36873C5B5D5064ADE0C7C5450484B4719C50A6642CC455F3E3D17FAA40A8A11FE6AD60EC47C2FEE9FAB21D52F8E6B20392AC69178EB9CA5EB97F36AA307E4B8940CB393E243D6C754361F2E901006E3999131D053D265A011A26662CA70DDE02B101C0804028140438DE6A4DD267B5B39C8798E84FB2F3DC4C4B21BCF7F0A43917EF19AD90443CE45B5887998EA07DA977582C4D1F0F9739FC0C351CE588EB71A0EFBC8B672674F0782B07E809C3F9E636FD6EBAE0D5EE1CA65DA6B7823677622CEEE22F6B19C99A09798362250F4D9D8C20A9C665B2B5FBC16A89F0B6451007620F537F5E76F1CF9D414B66CE1BF17FC1C5AA7EA4D3AF0B52E8D76D47FC58080060904259CCA622B00EE987F0168CA4C50CA94F284918A96A68BA01853642AA70DBCAE075EF27E5AC1B567E8A282B1C331A540BA3C3594F5754A0A694E7A44E9E7DFE57AD39F2D0BFD1807C6A9860DA8032E50295E9D0F1D5FD3FF5EF6292816BFFFE20F422285629F54DCE874AEA16F006A02C108E5861273B110772DD3B464C6DCBCB22A6CEDB114BFA845DAA106F2BB6EB860101C0804028140AD485855BC7D88E84B05B058267F272FF0F38B65F9BFA86853B3F54DE62205A3B203715BDB0FB8215BFC32772CC38040FA95724B0833EA81AA4D8BA28347B4F38B925943CAC9460FC8B156FAF2AD029C4DFC66110FA444A99E588F481DDD0F76C98C8C566E7B9771580C1D1913CEEA9D1AE2802E12D4D77C37EF0A3FD53A740DCD2F7D94046D87D64CEE0D18A252342385BC1900DBCF83C0B6EAF6585C9D3769BB524DB31D342C5AD1B2E1F0453EDADE3FFDC003AC9B96BFB5799E6B7F6F89F30F61B6721BF586762B363B4496158A3EBFE673D068D31E0FAFCA5E913133D80DB61D363B6174338117BAFB78FCB9E94C93D4F3BC7393D4B9CAE5DE51D521213BDF1E460E7980AE09F42AE2AC0FD4E3364827EB1A0135AEEF4237033913B48EBAD41DFE781ECF374A0C5D067126BB8CB8AD0C27B9A36BC0E38FE8BAE24B0FA0201106C1804D9F3D765F4D9E7947CE0D9FFFF587FA77170C8CE8D3A5F6F847D2A25192CC1020C2E306A7DF512D03A72B7E6EFC9FCC3E6B00E54CF2DDFF511403EA349370BCFD844E7A3951B628307E50BB0779F800BFF3718BF9BA70A1DBE285389E0BAEA9B7435012F10406DE914AD0AB414EF18C05808F19BE1203D9BADBC027F5BD807C0DA227D30D877040E547361335B5CB5ACB5C8253B7A02B141B9A7D263850B0F1B879411033D5018D82037743F64070447D1DDB3751D7BEC76735C864E7453C85CE8D19F4A7FAA216A18F62861576F2E0FD08DA9714F478DC64F50C359D8D54A08258009E6FFB63CED9324436774E449656064B407F82F28B9B746B83C7D1D49ECABB39A08777B2FC7133F0475B28AE752A4E3EAB6C705E283845503D2E6ABFF7997CF49EDE0F1E4C88CBEB1DCB5302FEA148D7105D0CF67766D996485DB6E1DFFBEAC626382B1D3FD86C5FB38E867421565FBB13BED3EF00F8C09128409B2A82DF07A0A39D92D92AE9C7A974F85C48E6FF2BDA796E6C83DEB13BD02A1A6F27E5FC8CA6AC569CA00C35F46061223A8FFDDED4C355EB2F3B43733A08F0A213F9FC52835C60DE35C56E30EAC62557BEBC42411F19F4BEAECB45BE2F647465DD805AD2AA23E3535934907438CFF39BC2C28080FAC35A8CA17A732016F96A461D79D375C59242666D97E6047601317888D97E827031F253FF1C46D15DACA4C1F67DE43C21C800C070FC66A54565A9278AC6A336F1E9DA3F2513DE7F156D2A5BD7E37CEA1C55C8EA866F487F3C1DF246000486B6EB3ADB9EB4316E06DA9DDC1F019D21947C78BAA9116E575A698FE757F10F1C7DCDB73447A171216375C41390446E10E5D37F82762E84A36E73C72B9968B9E430F89F5078D045B81EC61716C750F8828F003DEAEF453A3F7797A949290625D60D3229A68277DAF110B2F34E09DDB77F31150365A098E0A8A08077943CC28ECB0FA2D32BEFACFD0915CBE9CEBB69DABB1BDD4C08BDD303999F60ED3A193A41734BFB013B05C0D399F072FD2DDE237FB9C2FBB356F3CAFF2DF172D44166595CC9477AB83F79C7799F26174232CA974F816A3A71A9E6B9560ACF88B71BEFD4B2850CC67880014FE1C8ADFFFF708EB62019AE6B54D145645CA36FB9D0D3A05C5908F90498DF5303569AFD4BDE272B20891CA2D2885591D5494C4CBFC08821CFAEB05FB799D31F69BD1FF2A772ABE5B70F234AA5D0BC4C9AA3FDD709B1A55AA9D7952F12C74D6DCCDF938154D2392D3C36B7B71C9F8D0DD179886810A81208430EB2E842263894AAC9AC5D5B664C7841DFBC148EA7D0F50EC4DA38E67B485B7A69CFA9BED1AEF80D0932BE345559145DAE4ED2F4949ABF304C9EBC7BDB669DDBBFA2595A92C9A443DBEA51BE807D81860359E07D4F1804032D451D7C929AB5B74984D9C5B6AC6D745D7AB96D925F5F8DE890D53243355A8501F6AF4DF4221395F96A86D9E61A5D66162DD1FEE82EC6DD43262E6ACD32359B333DB50238AAF3B6CFF538DF5AD186BFD97B86E0A43F4C6219CF11BA963BAA92040FA4917E716D1DBA1848BF59C2D75CFE9A5AC3DA0ADE8EB40A7C28DE5197E980D6DF5079C52116606FD524F3781155D6A02CEB1E31A887EAB8075E73CF670346C8D39C9C3215932B16B686F703BF9CAD0E39B94A22093580015ED471F9D440D138A5EC301F323D9F14A49E3BA4905BEDA1FD24FF40C46F952340607CC88B17A56B88726BD369CF5C57015B6276E78F80F2AA7E11829F0A368C39B07459DA568F82A8DD21A51CB2747036AA0745A5444EFEFB4178A37E795D48F1FAB3F337E3381A5A91FBFDBDF172AAFAAA6A1EFDB88A7F8109BA7524D40003A00FEC85A5A59DC73E1D73DF980C2EFBC2B9BA49D97E2064663256A085127B3B01C8DB122FBFB4A31DFF97A3ABA8D08A7EB8DE6CA50A307295842BC962E6F6F86102DEBC9732333D2601C8B38F1F7D9DAF460D4AD1DB1C9A106F9E6C0885CCBFE0A9619AE829193B3DA6E2BA04010378B29393F0E9FD1575CFEC0BE5E9A721CA2CEA95376D2B4530BEB2D9CDA05639C0954FEC9EE53EC764BED7F51A63DF84B3385E3B81A224906F40E8739695559A40379C3390A5DBC7C89CB6C4830A3899E1E284046309382C4F770AC7FB22E53B2CFAA225B68735255AFBC6C7940BD02826F15C7C51B21943C8712EEC110A3801881E47F2C9F9715D4C7DAB772CDA83F802F9F4732AC9DB214FBE77ED5C8C7E984777AD3991B6E7E974DF97C80A36C4AB167393227589E5F9826B1D1F7A06A12C56AD7718732986BAA87B9B971D53EEFD0797C973B6FCB3DFC9B7542ACCAC5182BE489BA71980253DC6AFC73486F652D613CC7DA9064BF9AF5361157D33EF0390EC3835EFE762039E642776D8FB728963FCD60EAD9635133FBFE9FEFBFDE68BF3594A95EF3273A6E8195EDE0F5511323FB59E3F3B36332910B53FE9F1B1AE436D721354001C7F11CDD87CE1FE9CD569E5F0C3B734E44AA765DD29959A32B13C565C72809214A822664E70B7F07098983EE7B2B7EFE1666E7DCE62665766D07CC6DB0DBD02845AEE0CEEFE5906B7E7295763E7AFF07641DA7D46EF29B4D9447D21C43D8C2F471CC617EE38802CBC276EECB73779109FB5C4DC710745E2420FBFEBE696F1B1D413BDCED3D24019DA847049DB625A4AFE17DAE99F89CFF0BAD5401C52831DFBBD2B81FCB832AB73A0326805EF7C65DA172C16DCCA721AE79D2A203B0F9B9E2CF2989F32EA12D57A4F009FCAA71BD00A9C2F8CBE92F869C5226461A5E9EED2EE2B19677D7449DC33F21534E6F6E77B242CF1E01D0DFF17FE69D60E7FA8CF7EAEEBF26BDF9EE34C7A1570C41F514044EDF3304D40D7FE72786009C2AF0425FF10D9DC31759C3FC9FD7347F771A224A51009A356AF828EBE60D584A108FDF25780DCABD727AE5603B56BA233585CE9A541805ABE4BFCEC1135DB4F96629884061B3CD1DD7CA8A22E4585E8A597BABE506F2A18EDE4206B4B25E0B82C47DA34AACC7A8A8BB4C1C17287CF53B757D2C707CD294A1483CE35F7DD8543DFBEA14504301ED1F159BA65A954E1FB108B7BAD2327F813B5C83DDC6EEC115C7328DA97BF357DEEB72C44DFD1A785FCF28A84D85FA7666A3DB3EE0A3CE3CEAFC55143832C74D0B1ED18E1026C5AFBE000B846D257A7B5AB34C74F65F783430EFE7269AC41113BBEA510413B8A08DCE704F8C146D163D15D3DCAFA62B272FA1B29C9A7EC865817415F3417E09BC2ECEF5C89C412ACF3C41C58D71E4A0F42DA4682F29419E9FF230AD94354455085A88AA822A8824C63CCF31C9F0D12643ADA5895B46E752D23A1E6516049F328B0657814D8503F162C0202A34947FD00B119471649476B4000D318B37EB424BA483005240A021824CAE03B2804C96FF6A6D2E580A62A4429EDADE4B41FF8A6CF0548527180AEBFCB70CC220689323F36E50A280475DC1413DD08CFF117E6314E612C2250451008040281C24419040363831C6F459CEFE167AD84F5486E58C96F2B238DD161E146EF292F7C15D89F630164617F134BD342020A150AD73EC70D3FDBDCBE4D97B12CC264A788B2B8F15AE36EA42F093013DEE4491EE1F5A3CA9BE7A352025D276C88F0BFB569E3AE3CBE8F2CEB03BDD57D72CE48205A41B3EFFA480FC9208DEC06E707B41BBFC8F347322BDF31F8F3946B6D7A7C1CD64118B5316DC8ACEA72CFA8F9671EBC840773F074C52D2F41093015B6DA9FC9707A9DC1861EFE3DEA26E0CA7E712F909E1F3020F053E6C6632AE5851F47F7659C1AC0C0D8F3EC0CE64D5CB317E3023C61932866EF1C7D8BA497F3F39684AD670195B723A02DB346E2C4EE29736A119DC44825376AE425B3F1B98008D7151A5C9C26D98542D49B83CDBF3052DDD5EAD578C64A4517078AAB541E297088CAC499EFFD3708067671BC5A0D1C5B7E85360B3067C9954486A07EF8E7BED07E891631D5BDCF301602A82CD79CCC3CB4E26DC3D637352FC3ACA87FA98E3837C5A91B096E7E125F363DB8FCE02F57596BCEE2702631E45376A07FE1E67B5584D9F469E7CC72FB48C349DE627099E562EC938153F19DC921141B9D3809E705925D456D9BD3E4CB6058685C289AF82F2B5555EB026F2E9DF12B3F645B3BE4C53BF6802FE055031850E168A9991449D07B3DEAB5B6ACAECA8F30831C9C56FCEB0649FC38A4EE2F420602D650A787DEDE9C309265923DA975C64160B13069A59E6BF5BFEB96AA39830CF0CC9D65BE13F75B76C29C4196DDA5299DDFEBD629F2045180E778C30E74465F83945567B8FDA5A10B6F5098AFE1747B422C909739BFD12DCB335F91FA4525819B6D2954806364FAD1C2B09187C5B121E7E72DE099922F30B742CA8ACE5086CBCD28CD7760D16839F093380A9EA67B3BD4CADBBCC06AF91D8273D899979245826F042225E845085A6CA9CE72E4B5B1ABF959E21871C395609947007FFF7144DA3D6C431F91B14E161632ADE0E5015046B0E419731A0B2FBC61C3CBD30B7F6ED8F347EC1C7FC476F72076345E5758710CEE694BD2F98C6103C259B1064FF44294BC9D39E22A15CA374F7B44523AA8023A077AC6EE2665125B775EC0F57958E7A7249232784575E039A78BF98F7ACC143111E5E47DACEDBDFC53C202012B59830FC331A8F80D76AC9EBCA2630047885792C93FED2F8C8FD2816822B3ED0AA7926A8BD15EFFFB67EDD00F934FEE9178ED4218FDA860B2FBB7E8D2555D78ACA85E0996BAE950B2E9AA90523266D69A717C1C74DD52388F77F6775B3B198FD0DAAA70A702E6D99AC84366F10B69DF3333E97F54AD8BBA7BFF2401792106241B92FBD3A3AAE1543BCFB7C5BFD11269E9176F5AF6FF33ABC12E15B97982248EAF6D7B94AE56BEBFAED5B0FC25C4454DC19064F5403AA78C4F590F8037A4C240105CCFA4A4EBB89CA1E85FF7F8EFE7187E43671DCEB80016BBD595EA8EE0287E2F805D31A106EB1788081C25CA9278CF4E1DAFAC5B5D88EFCC8A46DD4FE5EA1788EF469E3A66345788974B36FAE7FE25F5A29177F7B2131963AFC5367658B81AEE35AF62B75388A068120958978F52DFB61393C2518CEEB52310AD1096F654A9FDFD38F89B4175E5877ED94CE621EB5C3E8FF15B40E38697E8D4A05F0D29E64BB27CD33EBABDEB7B026EACEE4E1E6FF70EDE7612E9156E4AD3C8BF32DCAD0F1E3B6D5EA2A6E6941F1C60E9B6B47FFA68740EF1988C0A0A237B6D535D31F2F906D2C60DF85DBEC3FE93223DC24722EDBE126F1F6529ADCF78842AE6A5558B72193E4995DDCDF1CDEAC31F119D27C72788A6580F92B36E98F35770D800926ECE245EE1F84A89CD2C9A2A456DB7C07409CC05168EB05E8FBE00B6868F371FDC54BC2C00FF9A28C5DC5EC985966C3CA4C5567A77B8E926BA8C49380D969DFAF0CF06F10896A69E5E9654412C604161F2DCB3A06D934F98AC71D48D937ECD4C1CD5432B03DDA621CD1FE0E741074C1637DDAA9C3FE532DD6C0E71165B8619FC5E63FD561C592AEF152A35EE5DD1B51EAF60C3279C80A242442F4C4398E1DFDC65BE36923FFD1337ADD51A8DFBC185D3180E85A2FC2BC133A3C7C10EAC93E9FBAC6D87EA6BF867E4BB3D6CB8E880DA5FBBF678C8FD192788430B47BF40697AF449F814553EB0FAC73EEBBFE14D9CCA94FA777DCBBF08BC836080FD0A6E2022C5EBAD96284C4D19F56906E7C9114F6082D571807641BAD8CD5E176091AF4E2A63D4237F74FDDFD4264AE7EB2F16832AD9B32787AB75C0823EF3450F9CC525C620B7146EEBAF69462910BE7E4EB14D928232D5A74ECDDA83CF777EA898F12D1AE4AFB83192983A9A49824FFD20953F958BF2A97CB7B50C1F88A93373C2F4C3FD930307AD968066EA760922C8C6D0017E9A1A2D74B398F15E6BB467791C09FE91F0FA16DA9C0453669BE404C698E16B40197146BC059128C9BB54533E2492CB9909F5EB336DB259DEFF5B4052524503DB873187DE7B103F26A583091D609F84CD627DFEBD9D3BED6E44E52E3CDFA2BB2095FDA35957408953D8D87F5880DE5975BA320A625B2D5C02E1F3F8BC23BF4D1FC6BC2CC2D986363D8BAE4AB9E9B03221C365B9C950F844CB2557F9F3BC3C276D214E2C48704396C3291C3657E8D1E2FFB146F8B91967FF4872D94C7FDCFE39C3EE1C28EE6E5679BEC719B063F69FA26143B6BE94DCD3F1A2F1021810D5FE562E27CFF317D09A8045E057741AA2B6B2ACF77FA6C05733632164631ED890661D2AABFEDCDB23941F4C14CF3E5C2B0D70BFB58A258895DDACA92C605DD57B4A108E4E048F225D902DEB24DE9C5F2ABAF442C56C18DD8FB09AF73981CD1AB9872905E7ECC81F672BDDEE052013AC2D0A3BCFA8961AC0805393EEA3C0889080240AAB740887E67F934C4A7A4EDDC90FFF8E729AD6E41E4E00020746D9413D624E8F2C23492D12DB1EA9FAEA42A6BFD7F8FE5ECB3551BC8CD7F0CE808C0D3734CDEE3A3CC4530E80E44F2273D31B26D45C144F89C050082B08E99D3B8D9534148770703E3A5BD3E1F64AC36E08D435D97432A91C2379ABDEAA3EAACC03A8F42495091D1693B6C772558D02FBBB754A34ECB49200135C62F5B17DDD3FD66B7B6F3216BFC5D9581577D4E2F6A8690F994A0D907651370203080E04028140A03B1D86B6556419B66CAB7D9B428DDA780003F738D6098D4291FF52CEEDE605D535A1624BF44CDF1018B87B83AE4D0DF67A5501ECF0BF51821A92453F91FD17DDD1999507CF4A214BEE38BADF75E23F65166868F00A88AE6F0AD1906CAAC7A4B129D988AC760F99CD65893A451F4957B3191BA5AA9AEFB936F772AED3E4666B3C70E7D5010B1E35817C310D4EB5C5C642EFBFCCB19500D438BE738E23254F36EF3DC48B7031838C1DFFA1ADFF2BA1F8A9CB86FDE6810EFB97E388199FF598D5076C2408D6560E4EDE56A060068272F3F0F3828E7EA57295385A3C2CA35EB0FFB90DFB50C45533D8101A8866FC1F36886DB5668883C9D96FCB4FBF7E8FB565FDD58EF114DB1A2DB1FDE945FD7D4D87EBF327BC8CBD454649F494FFC4F2BB1177B03DB8223694C8E9002BD03B98EF2F0A76BCC8188FEB311A9D0B07E01C8E9808263B4A7A66E0D3DE44BD563AD9AE4041280A6801F35D9265A5C1BAC009543C073A52AD30E5E8AC06B33F578648A35588F17275A36993AC0A10D9A7EA4BD3902205DE8CD565E1DCC1070EB23BBF9BE9A3325631930547E5E90A797EE89E0790BFF4A6DB8CC47E58108E55B8B793D9AC0A78B5A2F8766E950648194278F8977B1740F71F2929735F7FA2137F489BCE21D94B556742866AC5FEF135DFA10F2F5190EF756E7F0C856EBC91FD8E2FF2B51BFD383561E8FFE1964F085CC541B718ACEBE36BE5D07F89A30F5306E566A41C0994D36D3E9B59395C9DBB5341FBFFB85C646B423145108D1969106EB31259D4C804F4ACA6E241CA2FA893E3472869293CCF6C64B694CC7410A653EE3F518D4AB26127AA6789C25BBCE97C869BC70B067D197B71E1A242F9CF9A21E179EC985E273CCADC568E6AE06F035052906EAB6748BDC9D0E3A3DF11A05581F7DCF4E9E7E7419EDCF1143DC5863B5288CD16CA21C6865B36B2DB93DA28B879EC5A00FEF5EBB24B8BBAA243DFDCEBE3F72650BCE283C3A713243B86D80CE10D90CAE5DB065B4524A986582061B2DCA9B62D7E6E7E51EAB63C0EE3BE7B6B3CAE692B57639A58643F7D84E52BE0E6437ECEE2ADAFBD5C422FAB742BC0F31ED5C7EBA19DC83B761E704EAEB9460B5E4737F698F8726B5EA3F0781DA9BEFE4CED662C1C9AB34446E53D290C80EFB060991F2BD6FBCFAE57EB8D95B69E9E25D2E6BDC875D1CEC2F5921252760538A4E4B8CED3B0666D914A20C80F4077F7071EEA3F0195657498C306886D0811DDD054101C08043AE5DA603F3B92CEA34FFE1FC6F92FAFF05F6577D774C56F67F8E92AB4B973EC377DCA7744860E17A20C4FF298D8507072BA8AA060834105B9797978F449CED87254F6F71DA45A63ADC34A437F74D83BC65266B27999DE386889DDA55268D2451575C6B5A7ABB70DD70C327AF3B682AC08B2289321D20B4C7F99F6A7972685F2744F4249FB16E79ABFA52DD0FB6DFD2946B11923462AA1DEC1290C144DD394AA00B643201B7799B8DEAC90C74037BB98AD5D62E6CCE752387A1B6602C5ACB8F860A08C888D3AECEE6BF6BD230D3DB44978FDFB52D26BDF4127A9722ADFA58AC65FECC55686863FF4647416BEE3A5AE8C20544DB3479125D1FCFA69CF0AA08D1B430A97E3DB4F2D4E443F36C827912F574C0C46B4AA517BEE3DA5AA62CBC0F25B356E4DB777F7B23B7EFF4EAC6A614EF8366ECF53C752E8566BB92855D8E42ACC7252797B144CB394FFD2E1A23C805B29E0443C44F0BADBA59634777FDFA3D7825AA809D09F18F41E64C8D694BCECCF33AFC4B5D8F8F62BDED3B1A395A12ECF22DA33ECC1739E1C331915EBB8EA92466C910E293F01A4F3362FE97B3F39987F40700E9AA5D55681F88B2C5312874E49071581D022A090C795CD757E11F03C69AFD051C3CC480EF2A91A34DA39F1DAF30D85BAF1FF2E2EBB6B5CD589AA6C18DFA4075448965BC22EC2BA72A9BED6600CE72F73F2276B0E8F95847258F05B34DE3EBC4361EAB0B2F7163760DA4D161E703525493F774E1118CACFF3E2E42FD40355705DE27B0BD139FCF83DE41AC1E43157F3D3509ECEAB3E5C804E56CADC5EE7078A03FF064DFF274F29C62E1F10F4C103E1B18AABCACF8B55A1C9B371991A196DEFE2EE457AEB1F14D275A82248979B49C148658908D7ED3290441A86C93DE56669BCAC1A5E8B377E19CD956E1A881DD10BF8D73244D4D5DE96C7AF997D4549BE8C9D61D43E587F46B8FDE7BF1DDCB144ECD10D39CBF05BAE2C674C98146CF44CCDC3A788B1F824489012953B4AEF5D647757494DD443FD9FAD21D1A3BC16AEAB085D0C46EEBC7B6EBD5402090EF424771EFC5D677D33D9D922652BFA472BA2E46C7A66AD49DA865C8D04EFE34D4D6DF7F249FA84E1AE0171BBCB81BCF03379CDED5F932A160EF2DA799916FF2C5EEF739051270519F6E79009B69CFF083679E8383E1B7C99C7FA76F577076ACF22DC8718A493DFF09B21B844B758FFBADF415057FFFE925A7EBDDDBA13188811C3C2851EB90BDB1D31D4BCCDA19633A30AD536360E2761AF33E61775D0F16467EAC59859AE5EADB67744EE59178655270B328386D13D33355507C0AE78735680AB1D30DD40A26AF6BA63BDB35B1C64D5D2DA0DFF0265D85F16BCA27A7B372E9CD8976CCC2F193B030A18D047309A69EBA4B74C994B9E3E6EBEB8926F59FF5ECCB1F9F55BA5710BDC530126C02E1488DD3D75A322F58312B656ADB425F8F60ADAA06922FC220C18519A7CA8E9060B83E0402010685AB872E86DCF7017E71E1A1782684DCE6D928CA157AC4725356DBCAA35CD62ED20D4100BD8B636E6C63F679254D9C5DA80E427E4FB7362427B8B832F69D7CC4FB94C05B801BDDF94A4F61F442B5288F6AF082CA2317548F2EA3B238DED6A1AD53E221DAD1FD37B7960C6FB0C68A0D1ECB9BE579798FF81731B261D250E27BDE766F0220893669137E4B70DFD348C50D331D9FBC73ACFFD675B1809E6C37E1F0C14054FD7642BFA58771D14147793C63F20361C03E447EB907D8974036790FA9D71DF3F5603E4CEAA81B7AF743C23DC9868F23CFB27D90C7F4E04E91CFABF2D6D6A06A55A7F85437EED8A3D0FDC3A1CBECD6ABD24600E7CF532951BBEE55ED139C6A70F57EB3253DD5FEF237F9785E7D7A24411B8CF32547B4627EB9B3AABA901CEFFC465CD77ECBB176EA3AF496423F4ACABF7593D32071F5EC94350E81634E6BA213FDA773517EE7B8A85B1ACC1274FCC1FD2782F31ECCBED4E43F9E0C031585A81BBC70D6785C53F8480BD28A9230BBBA119AA0523646F7017D1AC4F69626F59991EBFE017FB0A9477E33765559DE4E0D52E44B45FF56AAEAFA038C16C384C107F235546E8C70E5506DC16B1E6563D1C8F56E9E556B1F0E24336BFBE99C58ADB6DA6BC442D32B67C5780F771DE5CB0D7111CB66F365B6724F5C567D628DA4CC04031457454C3833020C2D49894D28B9E799B51F8FE729049BAA4787F3C67104ED3B6EDD6D109BA0F015C033738D48D20B6042461E5B288EC5726B4EAECF93209669B1EAE7A08D059A3B5F03E0C5DC9080E6DCCA84E59F038C8637773527D63B16A72663349E1F1606D9CCE559FFDF241E22A0692F815269E2854263C350B189077541727510942FFAB64B9B8612DDBDF67C4718696DAA3F2313EBEE9CA7CEFF203411FBCA2216706310968073C63F14CE7F039B90663EC5DB8029A97C3CDCFC8E295EFF4B37F9C7506C971C08747F857B2333F61D1C2624BE672E5762F4ADE52F58F705AA7FEE58B9FC54DCB0126097E745C9D513EEDC378A17FDDB528A7FE33C899553807CB59E39673519659DDE0B742BD2A929E5E52ED0F28BBC8EF81394D2ED95F88C9339731213709318FD8842919C98F2E1A5E57FEA7B1C381BAA6BD77A7928B949FEF9A78C56BEF2D06FC5FD249F90F2CE9497557ED8C021B0413B589E90F49371C953F9F44135BF1737144F8E22E00E6A1B3B9EDFAE6F192C3F79A5E519D13B1A28305AE8EF278F36EA6AF62B49285C8028B4C08E68F8068596516F4A718BE865F224E49C7F6457B7CCBE7EAB48F5B0CD7EAF1F19688E1003A074E9443AC7806267640D0321C7172D3EB3249050E7E8BEE27D4E132A11D8CDAA07E74BC0A3BA8C696927365100CE4EA44E559C8104A26E0F1D68EC2E13E763DF225FC2E11DBC2AA4CCBFCEB9C490B30443D0DB254A5C42A34039EB65F3FD07ADDE80FA2BF4172A4155B36FF9E6DDA0F04EFCAD4CF69C42F3A880A163A619E58574A66EE53C7423E74912F4A44273D753D16D8E8A96349997613EBE886BDAE407BDFC058707496C9F529542AB024C844A8CB64434A6C5C6852D3FAC8D34DD9F0211DC0330A43BCDB1FABFCD9EE1B82C030E6626B0A1DEC31181B5A0A772DF1CEE8CAAD73E31AD0C795D8AB233FEE7A294C5EBE8D1F47149C2C74054E6A70F0449A97C99A30E14FAC14717784EC6E2666E60D83CE423F6D5174A58583E744A63FBE88170B7C0E79FA18C7192DB25094839F6F80A8031BA9A94932F90349E59A4C272EC16B8F40D74BB2F671E855380B5D27FEC290ED104614285F4E9FD8A397C21139581E8401CC330D09EB5B5C56DFBA250CA8B8C1CEC5536A01AD1973B35AF338F52BA3D5A1801FD31BEBC646FF41AEA0D02445F2824233B795A6139A2FFDB521372DE921D972373CFC55C7A725E9725450D79FB5041343917EE5738F36D5FE9059DF275D84AD49178FCED4CE6FBF7B456BF89A6E154EB0FFB4B1046C50BDD873D7F806666FEAF1C3EF4648FF54CF111D10FBB99AF27C9332700ADF8325C112730B4543E8713E640AD9844A55CD512ABF5D0D66FA7BFD6E97D9B2DF31C2273B2EBC4B39B004C7585213E2C70FB711F8EB8020C228C64D561F16A1EC095CF748824D4B3F67837FA679D67C686CD8FA152327DDAA0FBC8D818818DA21F91ED31259666F4D23EA239C9D8E77965F88EC66CF3C3F0A32A52022F5B89EFAACE4415B54860C905C47081050D270A6CFCDFBD8225B4A6642C6431C7064F9318BDAD9F89FF8037BB584A15B77767B5C88285B9A9BBE88F588DAB66F32E0F307461ADDD58FA9478ADEE4B6A857F7B473794C6FB11C54890BAAFC6426F8897E485701B3A57531F818441F23C97FE9B7A2C9E03E6653067096F531705B1E21F7124C93B8A40F3EB53AC3BA21B217D4C8FD09E7A2C2CFB38A80903957E993A9D90E62333E6F0B9D1A1F2EE064DD4DE77204532F632A7397AD3D64C7245716DB05F543296D2999DEDB0F1C4FDCB9D4049A6316E9E74D526BD04C1068D0AA1F040549A5AC97F9187DEDE865FEFA9720AE80915EDCE711F3BB7E70C67B787403FC17C3CFB4592161E9A707DD7530769B7A4B9F8A1FF68C1C254412E488661436C2E216AFC3B91F7E3AC1F89F9360BF7F5D452F57A33C8F184206EE0B019D7F8A7A882AEE6A2263C540C033F128923F7309C6E83F1F5E7FFF83F81FA977B667087C8E91513FD91702FC867560306959A2129BBF85F28ECFACBF618DA9B28C8D5300561BAC30BB29B6514702F513FC299D53964F47F6E101BFD095FC5163861416534DD7A03F8C34F049C735C31B755B8E7DD78965DEE86798DFD5049A02B7E885B1FA3D23A3C51B20B8FD21237060B7E50FD18903C4A6D33E7B1546C41C12E2AD13E925F96D875609DD811153647F97AFC5023C5A00E9FF17BEAB044922EA4235ABA75ED5F8D49CA25620D22E05F47512FE8F016772371817047D046344E124C520A405C0A2C591BB5CD235B650FE19794DE9B27D09C5AF55D9AD39A4FAAB189861F92BCCBB4807F74575351B79372D7E1E7569410C8A33ACD3DEEBAB1422AE84070E6F7C5E9D745FD7D56F360964616F14DF8830B13A01B8377693CEB18417C35D93BE327B66F5DF1D41CC399EE42FE6F1CAFAD73B132ADD50EE6BB10FE16834DF147A5C0F243324462CA8AFC00ACA3F05C5E90EDEED56DA52D9D50453F80A9907E025FE1FC87E5A6A74FDEF14664A0830687FAF7868950EFDDD144763B8ECC8FBB84FEFAB655B6395660254B58F7338217075FBA8A0A0D90C14C539CAB6FC88F902DBAF69E36C4891103AD1AE382D66C367FD060383C7057623ABA98E2139435F80DF09E8081BCFF636C270CB97078D3D1BCAE1BB4E5732B53EA401A3AAC9F31D150EEBC694F41E90A86BD165F172418AEB7384B7DC2CE5DCE5C1F038A75020DDD350EBAF5BB722C74223EAC218739C508071E70EA32A982634F9123E6628496475C1B729FD738110D4C0AE31E2B44AEE8694D7E9290396826B059E1FFC19960D9EFC561FE4792931F8E05D9C52D59F1D858693593C2CF1F1B96E75A2D24EE3E9E00CA4080CB316253554D01B0A55184C2053A3EC821AADE30061A74CFB569541FD7052325FB21979B129D7E456DFDB3624862AED1F201AED906E783D101C080402814070D7D047B8F3289C9DF2A2F0CAA0A423C13596EE648863F4263AE275081AC612429812FAC1203A3670A0B17E8381271B04D03AB241668302788F60C0323B4500B6F9C966B0487B073CD89A91ADCD66A05A3328E2638C280EDACD822C9B41BAC30273E508BFEA53608282D4546607333AE4E737ED8A9DE6F7977CA0E3F9B24350673BBA6CD96A474AE622631DDA7CC712D825E6D82DD5D78198DFAD833B337526744BFBF0D27C9AB374CEFA133AE61978E527FA682477D7C96501870F2DDA0824128D89EA47C72D5450B9EC0853DCF9FEDCB69389EEF47FC7248FBB79E2D39E1C8EA03CC6B06C51ECCC05552EFE77B0D08D99C32983A8D7FCBC6B9AB593D5BCB743EA1110486BFDA466F74928C9DF35B18ED5C1C0090D6398A8693186BE9C8BB9FA448908A8BB959CF0F829F4A8C12F7B573B24D333EE2E2F0808D7D78C15A5C8CFE73C68D3D2A58B2B1B33FF7ECCD5B275C7689C76B00050FF569D13CD8C4CFFBAA544331ADA2A60583CBDDB351C5639E1276F31F64D9460B4B4B19EE6CE1E78EB277094BF9E6168BBEB2EAEDF1FC2D70B0EAF8327EDB293C7C465C45E77B5FDA119FC850530637615FD56F77D0CF26868BC4472A7FE1349FE6F0577CD95E2E947650E74EB3270AB3E0BBE9A42783470F624BBD018AF3398F780CB0527C5BF359413781C9F40C93F37BFBB95EB500844AE64F3087562824CD40FD22F8E2700B14E8B4DE2D85F8685B228BF1A086B1394CF45EA09795CE747D2B930C5D53126BA2166F0CEFE6C363C71AB982B69D90A41938F9920500B5A79A48DC99A460BAC6839B7099E138B3F4EF0E1671BEE080D06989624B206D2C91600F75B417B639A1E7FB21F5EC20797939B1896FFFE6A15F4465A9CB953DAF844EDDE3B9929B9C88B486EF67D7593E380B41F395EF02302136F23CA4B0F85B208BDCE50FFBB204972EB25F93E7D1F325F071F9ADCC2BA0FB9596EE79727FFC2991005291418F00310EB7666A541D41DC320BA853C65A9B9318A7C3BFFBE6261A7B404BD4991B6806EC84BB27E0FE09B906A5A7A8649F987057D316D623C8A7E0A3421B018609EABA3B2374961A7EF53D4B264E0CD875402727F7F789DCF665B1CC532170B554A97E0563517064AE5DB3CA27880D3BB50A6E1878896B059047C4229430ABE5F8822976FA3E8FDBFCA59D778870DE55B0CA40F67DAE5657373D3316A90DF2784819804077FD7188BB6A34A0B9E93382D1BBFFCFF1AFAA4B3AA4F979A8DACABEF56F5936572AB68411065F93201487B1B44A5D863D188188B4E26453A45DED85A8D049A96E45B33713BD5D333B409116FD08C0B8F571C2B9EA1F71140EE6767666AC49E4F0279594477CBFD5BB2E5EB36852A6B3849A9DB74879D8D7783E393C0C78741210F41C55D8271F3DEFB1ED19B2480E3269DA754403FAA010C903CEFC9D96457FCC56E3CE571C5F88A5F3B98CC0C039CF2F0050B471DF90EEA00996FFC8E3556F54FBC05EDDA69858BBA2FCF51847A6875F8D9DFFF7A2242B6A5C1D3CB34F7D489AA883C238CF3E2F6F17CE4C1B73B71F6EC3F703411FDD6443F2CBC315E5DC4DDAD9F90981AC5780666799A4200857378AF88B6B15FB7BDE28B45F2A1FB8A017B40BAD3EDD12365A7699C87DB53C9DDBB01AD24EAE902859A7F30C402D191456952352633EFD3F40E143FA29132D66AC8081D8769B86EE588D1CD5BA400ABBA20D4DF5669A60E1139361E179F69FBDEEB87A7B2CEE5FCFAE7CB3B58A8DE91A1FBA49047B07A5479736D927E8A108123BBFF4419AA2B7F1BBDA6AF8A4213F1AA60C2937F01EBDAB36FAFDC5F6CC4456DAA03D9DF4149B540247A8D5F591DDE9B9F81F08773ECD74118404B47BC70D5C530A252F28A61CF93BA4377D98D5632C5A915D41C5414A056BD0780B1B197B4B67FDCF95DB51F5477DEFCD3FAF5F0A510E225A7D81387EFEB49AA7030BC1BF0F1E8EBF25735C781350E10E9C1FC4F88FD4817140CCF812EE4EDA3CE548EFBE99AAA1E9E47D6E2B6395A11609AFE8946CEB9B1ADA5D2CD5820654B164F5EFF447E3ED65842D4468C37E66ED30D3707820381402050ED38E694D6782BD82C1331C7815415DE14076CFDC416D2EC760615C506BDF7D0242E97709104A2BB5B0A13209E1191F8D30019F9B7C360C134F6F3DFE5C7658499867FCE4BC22287DF40E20262D14E38E6DD79F11A99DB198DAEC2AB176923EFEA0EDF08F6DF78361EFF4959FF4AA023DACA3BF74B356337686EC2DF42AD97A4CE33945ECDC67500FB8B781EDFBC47B2D4940D33CE89EAAFF498DD87876AD1627CFC5E2ADFFAE1B3E680BE03DF970926A9483501FBBADCA1512F1C3F6A654C6C8E8B1E8E3440AB34FE7A46CE003147F66BFC3678CACAD9A4EFB0FD96B55E75F495940D2FA492DCD05C4D18A84774FD6DF86E300820F8CB05DD1DC4F7BCD51C08A78D274BC5230EA89A64561C547EF08FFFF3A78EBAD5507ABD09271ED07E0B357908DB19F5CE86CDB62E9389EF33107C72A93D55033AA109CAC691F60C15D9EE168237D41055DA79115BDF60BBFBE0F8A3F1D949279BC051900C3C131B36E042EAE1C12044972F836040A8BF64B906E95B26C6C97D4DD1D095452208A5E370CB82D2BF278E634B90AD0040FF9F20B3924F211CA6406AEFF53FE2388EB012FCF7245CE4096A9F9B8FECEB0202814023AADB4256DC85F1916970327AF12D1473F318D83D1537E1357BF4D127382AFEFC94DFA0D0F04DFF11954B5345E2C5EF7A89BA23B235B4A7D3F16F29E1705FAD655AC6FFD4D68495D632ABB580EC86AA7401C539535B5E39E273CBA6E45B9DB5C34DBB0A7A04D3D4507B326D32BDAF784EEE4362F0F208DE0E8627848FAD2783598026479644C293EC947C3D59F4D95395EAAE782ADEB4697FACC7BC16B65E72BD4D692D78B17F576D8E94663BCDCAF2C189E33312258081B6F587AEF8BB0D769068AAD4D4947CB784D3E96773D1211C187D47FA0AF85EC90FEE4FE0CB760DCA1B317EC5D1A889DF6E7341618AE0F860E75BD7780B4749A08F54B69959AA189C1361A8CF1217C22A778D73E2249F7E1E7D2A911214FFB33A0B7A095009AAEF278638B180F8F2D710BB836BEC343179888E406372A9B22026273E07F5E9D8082960744E39EC660268A8AF3008568E7DB11A076CBF31AE44A98E0D15F17D3A58442A14517B1E3797D3E3D6F389E2384956F660157363BF9620112E6423261F3B5583815F9FC3B5E8563F5114F78A907439843356CD02A41D7B83DD38048F491430122FD8FC7376DE186A71763ADE7B8BDCE3A07FFCE8BF4895D2DF5A343AC7878E78B647D98313D909E54F3A4171B55975734EE6AE788F543CF581B2322940E5BF05997651B346FC146AC21AE9639BCE574757D1D24BB07703A3A25CE2267779006418A4FEBBD438A54BB144CA1DF82E8471F5D7B625984FDA847C29B43542A8361E757A61A32A0CC5C224FEF247BE00AF90AE928641EBC586F8BE2202BBDA77100C602C91CB46D9F5F8043DFB00146343BD25C6DC7FFDE11085A368C931B2AA82CA01E1BCD38768A3B0CDF1C73D8E6B53E2D60D9EBBBB246515B1D20FE532D6FDA9BADD9046EF9960E2D51FC1788F4AC363A2C9ABD63D2B4EDECD67EC2AEFFE565B71504B47695F23DF0B4EA991C2C3D547430312E17AC26B3DD5FA1CAE21E1FE758063A7FD83CA26D4FC9F6C5DC396C7DB96F5C0A7696C7D6B3893A2244D294FB5A6C4D6032D7C92B774F5F2054369148FC79E1D16C961BD25FE2934F57DDA6FED568360E0596AB1FA9B90E24F83DB26318D44495AFD9677CFFB7C0598CDEFC7737384E056209891C9447BC81E1BEA6F352845B6C16C28214756A9BEFE328726D1A14EBB378094B71947E1443A5E80C3E9E76FE9F05DF9B4426DAEF6ED433055DC43CB90D4B71E7CDFEF7FD4E617BBA18D53DB30AC780640C0FF7764D48313A63DF24D4CAF54F049B72B5513AF373FB6B2739C9938952D06AEF5823EB833B4987A5139D1B3A92B5995314A0439AA6F94B6C5AFF18594CAFAC7FB877537DF78F9FF7DC849C3CF6341E0D1D35AEEEC201CE52130EC931E82F25E379CE1A6FA0D98001C3003258568A5F32F9DD09807F51F8C88731049882D0AE1A457048954F93722052AF5E9748E4CABEE3976F8F360DE83C1D2201858C3437B7F11D1D640B9F8053D9978708C5389C960D86D211DA8A62C061FBBFC06B8896A150B2250256CECD95E931D3477C41EBB899319E0D4271FA469B6405899DDF011E7BF22B720E97F3CF8AD314E4C320F5473FA84A7CCBD892F6676BDDFF07E537922A9B3B52D48E4252028BCD770321EE280772DA6F8B44E9465B285968F2BB616A1AA0F65B70BB1B7C75AAA052E940EDB9B00F29CE0596C39A8235499FDE3C70CDA918F0169C16B54DF2DE77AEAAD6F9219DAC0FB64D22C8C824BA94F1CC2F7FDDF91F99500FCF01632523439BB72C9429856E60597556A7523059E4CBF74DC2C1B5FD0FA32FDC5B069438FB4B893C340ABC193920C6329C2DA1DD6811D951150BA3E99736885AFDB8F7A7CAF708ED106DD05BB787B9C1BF7CCF0E2EF7D5FC24267713787E1FB5072A486BA304B5E217241BDA5516587F2AE93E03EBB5A4A98E5E1E087DC1538565EBA6CF0B12492DC3EDB0B0CF718B0E1BDF820203451C5766163190C28205B8776AD509CFD77F4FF053A8822DDEE295D576C09314B4DC86C33600A095B20714CBA8E9E3870D5094A84EFFB8D6D3C79F8C97B59F0FFF050A22304FE08E5C8C4A191BEF0EA6DBABEFE00482590F48C5AB8A3CF3C4F1E52622E72BCD33ECBA4CB27F6CDCE527843DC7070BA91EECFC235A09FA09047A8651B184929349F8693C14887D2810DD72A8443F9311838820E73165BA0B708908C4073338CBD2413FB5BCB56BEFD1E14D09E48FF7C7D3FF62824EB397E3425944A607D5A7152FD7B3D47C778C781D3D97E760E27C00B637B3FECDF012F095A8AABBAE1DDA8029B89A646A0491B620700E5BCB8AEF993E3F6910CA085F2065957EEBE53C8AA7F7046FA9A7349481FEAEA663D6E7E8633629DA63C711017836060FD8BB1DCBE1A7D554CF5BACAE83EF3FEB3AE1639A99A4145B671C6EDB73F64F38039EB1AEC233ED66E397DEDD970184575947DC1F212D6FFC357D41ABED2B7F878F08A316D088512B2610816E2CC519CC5F07D81C31CED5A47FD44A2AF7D28700828F997020731161A8F2DF627509B164DA8030F1A4563B65AF489161542BF1B03C2DFF23BF5C62BE10A48DAA3BF42E8C75222F344C52BBE5F3F69B89CAB8A29BC82D898760661407D8AD75073ECED8C5E6BFF57D48B2C72B62FD3AB16C1093C6110237A6BEC365F006DE187B0CDB45CA008F3DC639616F25A919BF9C8A25BC7FC0A9E225EEA9FCE0CF03E96418CF60307320426800C4735D49827DB72432561FD71A2F17EF6D009460702BE0D6503B70EBA8ECEB925D57C4550F4F424D0191A70255A24572E4F35C080C81D3944982C1423C660E2FB9D9B20C3295FF7E64D1452EA3C8DCD28A395531820138B372C6F8BDEDC7E6CD9599859F7FF78EDD1ECBF9672B2342331A5D507C3035E16C8251E7CA3CA9B95537678C4448E0A3C9F361E3CF24DDB467282EC0EBF9E30E981F7356D481A3FBE6F521CC3B9FC18E8DD1057DA0B3956984A38E15508E02AD84F5CF14F621D63BCF48FC5196DBA634AFD77E239632B0BDD2B2E49C9E0BB699E4DD858BB41242A9F731EFE89057977A0A047F89157BE835DFF62C8F5EE7237ECC063AEA9F3CDECF6B22FDB02249C59C44B792D30B0BC70080FB0A90868DFA6416632F27F610C6ECB0E938A9CDACCC31F215DF9A4C5B607EDCD6379FE953BB8DEA2A3B2B73D483D7A280C2988D330CCFFA6534D0D8FE54FD36AFE35D52EA5F9F3BF55B92C1288F23F0B8BBBF4643CF3922A8F99D236F7958E0D7B2945D38B31F74F0B7F1654B56F002CE3F793D11CDDF1F49F4B032FAD68937F62C4F2803CA6149C78684EA233731091056EBF1CDC7E96798E0EA9706D6FEF14BA751172D880D1A7751D8BBAD177165BE2BADCA092502FE23A2E7D3DC6D7F820FD2816F37162B5B98A1E49EC6D9072092786396DA082E720BE0C48B031E613157BA075B06917455D6586C3EE0099D82EC737F7F2E4BFB05E6167B4327D98CDD1F7BAFDB277D141CC702426C0D66F1D7EB14AF97799B074DED1028E1BCDA348C62E429721854985594987587FA2F111B4D33775BBA10AFE4AEA7A8EC96FAD2B793A6FBAC48EF8FABFC05633AFD91174288E6CA7868E2C7586A300C1AE6FA7C083D4937257CCFF7FB27E9EBCD592CFFB460627F444566BEADA8D99DD1051101C08040281528CBB9D894F91CAFB669230D7211BF9E9E594D25BFE4647382BFB7BBAECF9963B7E595CC72861160A6869D9355844452B4C09A47DF7FABF3A7D00F26337CE0E8AA7C5D993F8A17916849AC1D047B07F24CCE88221100DCD239EE0336B04EC0EBBC097EAB3CA060D5D887126BD42FF1C377F8072AD149F0874A5C10644F61E282A9CEE9E201648EAA9815F8DC90AC4421D55FF4431F9E7DD43C9F8E9A7C8E01727F637CF45BC2780A42EE357AD00E1797743F60AC2D9CF1667A5EF81054B39B607F1BD661AEF1B871F4916D4E0C7E61AB6103FBB3B3493CC2569CCCFE80B1718DE741BA263B275AA585203344FA88EDBB57953DD92B5634B514ADD00C8AFF125F88D601623D7DFEF171E86BFA588EE3F13A2A06EFD2762A142B149CC06547D1C159D896A156DFE365BA07280442E7CB1CA637E26557740BEC5D116DBC23D56143EB0E3939359AC3DDD3C3623645767EA7B1701F0BF12F2737F9AF9B3D45F99A032B18AB576F0D93E02A9AD7958C0C02C0153B5FB28EF60864D11B72A46FD488388FF3DBBB31E2B8EA92BDEC391AF50031F93F730C2AC010E1653BA4F25370803242B43C49BB79AE2AEBCFF40FFC2CBD8F6DD9887FC66C0CE6A92F29671BF5966001C9A3D7373A424B14483E79347F979624EFE072D6DCEFDF5E10DE6E34085A1DD45C181BBE1574170201008041AD5312772B74E3EACB3DD1E74D238372ACF4DD7A47F95BB16B0C4DB8C78E089D4711CD99DC0C0836301DF09112A00E226B03510F64476B071E45DF66DD24FBEF2D51154E12701A89193DFD45804334D1BFCC60D8D925787282793784C4DB670E013374D58FA43402010080482D71D53AEB6C6BD4D78A6C85236346C3039BA039C3E90E9E9B662AE44501CE9FA0F5C76F879B24CE5F8112B322CDFA463687B5A3A5AA89B9082AE455669A90C1F3BFBF47C042E3603EA7C068BA4D6B5D4E53D96E66B3C22E6178A54C056254461B09E6820FEE1F4DD6D1E12EDB921FFC0C0F17BFE1ED3F539453AE4E5D96D9FB12723B6C95E7756154F74738FA0E3282D2463C593804B3C8C263B60BCB6087E7CD72CB1C3C2CF6540893CFC9F4E5B03924C475A8793C899B6795DFDB9FE4D7F096E8B21FAB9C50AE2B6CBE401B476834CD2F69C31FE4178A3BF80D6B5912AAFC5C7EA8CE31AD1D0FA6AC5195F4481601E0D03395E3C5BDE4306C613BAA268C0B2359ECE01CD42DB3270B8F021FF93538330608E08116ED6F1CE1FAE1853835ECEF928648545F06F724AC005DFB779A502367D008D97A7F657B07469D11579531C8EFD06625D96D238699393EA44DD059B117A7537921F08FA88E419C5FB1C839016008B813C5DC0B215FC1AD3CF1591DFB0BEC1C785B1C225A99850CBC3BA91A07234861F63867E8B6A29580F7EDD9382EA946A8E8EBD04E952C4596AD04E13EECD0C1347E6ED29BDB639E450074DFB416E4443A99DCC37B2A5AA3924E45CC88AA3DAB1031E373F827C1DD6C09692196B9966B03ABA0E802F671C10A35B2EC0E950CBFAAD4CEE919B0F3B6C6C3DBD7E9F0486C55E8892A3A1841ED3BEBA0CD62F1459D7D11B4479FEBEECBE230628B9B2013722783F17286F4E27CF0A4F187126F7B57CDBADF009C1DF74BB0BE8F4CB5A2F289DCDEEFFCFBD8998C279821AD116800C1A82C69391636CB06B94F45EE5C69C54A4DEBC44D47F0401F71EA1DBF91E6B6DB7F2B6F660A0D7D0443ABFA809D7BA252893FB7C5296FB536287755E21D249DE5C05152E3BED2AB548DB1711C69590FA75828F7F0E4CCEDE5C6CBA162E9B71181A25B32CEB55CC00B4452C5414AF71605D291F7D269EA210B40C172C8B9E4E8D6190E5AB700BED5B2A0A86A906E3D10A92989FEB0F1085C718ED3814A643231A0819848BAA40F122870B6F9858CAEB4D80DF546A07948E4169E0D8A35489D675CCC6640074B551A49CC3608A7930C4E9D29DDDBC3B0EFFD521F1786D1F9CC91A7DF50818FE08591132EE98D7FC2D692AFF4530F7381D6E5862CA2D8DFC51D80F830449957DF22D84467085EA68F4AD561EC6831234F3C41464296027529454C633844246FD79DF8BF17FFBCBEDBDD1D2BADD4AF87DC52AAF22B64081975B9026998E695F0751821F062955F270A128F09B5E81EB5E7104752FED61EB1437F1DBABC7E6FEEB0C3843FB038234D34226A643E92075170FA9FC4A7722A626B3D85768D4945DA3ABCCF3AD7B26298FBAF48F08F27731140E7156B7F07DCF727E6F026D52AB84F3BE361A116B3EB8427296E4CC0607C9CFDE12270A822FAB842CCDF615892DE91322BD881F78303F2E9B812B4B1A144717CE38213C6B7CFCFA1F675240EB5F729E9834CA840BFE9526B19BC99D7E5C3C6038BA03BB77D5A153FDE16C4430C544AAB373E685DC07F7CF5CFF58E183C0737C377875A0C1DA7CB59DA9967D7FB3F9CC60C3007B669EBFAFF151E7C2DA790F9CFEB0DBF90B493F7A2AE8A7D575C27A191523C0FAF3D5E99FAC558C9B672481696EAC1C206129AEA0C52862E4DA68E2B8C8760596071F8DA287582D577965EBD0F5783D07ACF908C68C0613BCAC7CB7B1F791B3FF1A7C7DC4B1CABFC4483334CFE2A05A9162F8CC8B29CA2B549F69A9CE373EB4020328009C19E6434A0A7CEFBF66F00B5A7AABABE40CBCC29C2E0DF7355F9D5DF3EF027D39044A1927769B6B0194658476516BC3BE8B4B1CDB4ED6582C48A154A4DD5A8EE37DA5735427E7C35AFD3FEB474B6AC322D65FED517C29DF3ADB8764115D0D93F7BB01F31A98F378017687A0BFB81EBF8FFF236F87BCF484A1814A9BF4F13FD28B2021F032542D5276A8B000702273DDAE7F4F3525EDD17612E01589C825E41075EDAE5D14365A78DA2775B7BBBCD7CBE2C688FD5189F88696EDAE5FF1A738C0048049EDC0B8FA02199AF912B76031E244DD388360E07FFC7B01C79262F3BBD3906E117A16DD28B99DFA9FFF5AEDFAD8A2FA481FD3DA0027FBA7D27FF0842FA76F7C21C433CE1EFA6778254E93659FC50F0D7FED5F5982A3A0E06EC81A080A79842C469537F3C162DE3C3CCD93BDA8EDAFADC7C3DDAAF0817F2E77436C1F8CB2D97A5ADB046EDBC3D664DA6F415C0460DC354E1C89AB27BA49E81E5138D4FAF5B645E4C167462251C3ECD4B660EDE2F5BC31D0F1C727558845C4EF4C6A5B7532995FD231CDAE5ACC969265F012A0919592030CAC4F407272BD2D4A250DDFD9580CD31B6A34B66A9645F578C9C28412983F28C901548E74C8A82A6EDFFBE5600EB16B24645662FC525D1FE5EA3BBB7347FF0C86BD75231B7A380B89280B09B736FFF97C81EC57AAA7BB814ED49F09AC1BB13C2FDFD6D6810E12ACD699E424CDCDC30CCD3B4D2878DA023F4B2E1F61324E40DB414D4A20D87A3E1413F3A3AC0902CE1ED4E3CF0886021C317092A03E9EA08804ED02D0321305193481318541EB40F78E83CE4C199B210D80389C0110D4DD358964DCA696E40194C81B4C7219EC8607F31EB00089AA71E5701E043D7563286794301A55E222A53ED8FCB5EF0A5EBF0B083F01276A1884017744EF360B47520A12844767962AB3FABC854946FE86C1C96129AF709BE4FC2680B353ED1602E2E67A28185503CCB162F747EB12FBD087A307A75315684591BCC6090C9D9C8BB3501A7734B9E6D76A3EEC9B32F35B96EA38210ED9C09CB71384A9A6437672BC90D666D850B82271D717A11E45185F6CB7EC68EE9A6F9E143D21F6CB1526285B5EBCBF8931C65BF6E102BE959D0B32EB62301E876CBF96FE2FEC65F3D7013304A5DD21250AE4E48F284A35AD96CBD732F32459D53A4979F5DD402122EEFB5A1E8EB077A37A5197283E6BC266011CBCCE98BAD0EF99FAE3802BE55DEE1A2B7B5E1274BA2EC2755386E7C74F2FF0E03C7D6873CD44A30E5302AEE5823E82D9CC49DB6DD260B6EC7E8B5E5106AC7959BE5D82ED9EDE02412DFD1007ACD1B0573A5D6DFD931A78192EEE0602DF3EE28F965C6C2E938D5AE55D1F6B154E2D4309293056BFB0D8B0F3957F6E9A0050812C89212F954A77094F73E1D20CEDC8EEE93456D0585D99F2EA2CFCAF3F4FDDD006BD19BFE74C12D6DC890A4636BA253A0C0111AC95724A34B21BC1ADBB62B9BC35FFEB477D2A1C1FC98AF910A1E64A45E41228D86AC6B9F109BB6FC8D1FB12EDE1B3717121648CA7A8721770FDBC11C99AFB73E4A815AD3DA1214B95D9DBF98306F6D316C384A2EFD259FE9A7A7BC260125B65FF6A946D855B27A5D37E66F9A44144C45F0FBEE2BB12B5F21ED034F832C8823CD1497AFAE9C1080F0249834DE44E096B76FEF2A82269882860D553FCDF4FBDB799C5612F2B8ABA22B925C7944757B0C6404C68697AB002C3C2F3EDB7DF106F6334B53588645C811F348477296FC1E9CD2B2B39A4E9CDC65022582FCBD58FDEEAD9AB4F11EB7BD643A94D7F49D36E04D8B1D404C48FDF7DE783017A49EBA6069F8BC9F178A3F2088CEFAB3561BA2DB3768D0F76921FB389B346F180F0C28105AB826E735CAEFFA394B69DED7B6B7FDA679DD288EFB3D2961043ADE253F309FA701F05BF394C5778A9702E31C86627DA39682A5D31909F2F0F5879C84848DF5A429B558FF923B24E3020FB492ADC7F313EA1C29D4BF202F7889C397AD7DF08FC3DE2AB41AF4A0323B9E315A7196AF325247CE3C845D6D2205A00DB09A649F0FEF3FFA889066F45CA1923AFD7F565A8ACBA9A3139CAEC51C1494837425DDD5D8F62DCADD2D57A660B0827A6F8E43732C89DF8364C9068BFFECAFF49DABFF97A083A8E9255C2E755CE15E8B572420DED3A94E41FD911541690BE021C7F2DC563BB77D836255E392E92DB2ABB980CFB020D068C75D298FFD575569EFC278443210FC16DC4828E1241FD1D39201A7E0D85C50318100AD6968EFECF1D05C66BFEE54124B0ECF24B8BE0E2F4C02F2E517A77F426E308C0B65724BAC7D2781C2E9BFD905E7C677F7D1A69D8630CD710C5A656B12D018B4426D8CFFF08EE29B33AF2175B8AB03C553688020D5CA009A43A5E32BEAE7D376BD5D83C8A6406C18020037A2B779539DA6ECA5C39A2FEB763556B9FC5514AFB6FC62A43B8E1E99F3E03145B4A565F56FE647C14E20DB8463BF163FF1E1394D81A49008958ED9893D15DF51E59DF2E4059D9649A1BB96C5E211E3B6628F52874A4A958E52AF49FEF9A341CA2D7E4EBA79A1AA82A0D68193DBFFC247FFA0909492F8DD2196BE84F827B1436D785BFED228102858C2062A9DF83F4A371A0DAB9D1D03E48059CE3322EF26325F582C3E042EE95ACCEC333855A9E5552069003E60F722A9FD6850F69FD1001A7CB89C3BFD86C04EBBB1914010F33A1FAD1FBEF0B7FE1D4A045A4F7306F427DC7936BC1C7F8616589364F87C8B5F16B43ECCFA5A28E2321AD047EA0404843F8339E604980EC5B07B495123A7842F44722405F5068CC4986DA0D33B445F65CFE1AD2B7DBE4D0B2288687271807E5F3F1323FB6354EA6CDDF32A4DC4C3BB7041848B04CCD94EA9B394B998D14E05901F875853624F235C9C375DDA334D0E45694E608CB6F82F8822BD7464AF07E7E7C40FD8F30B893023935B847750F2273AF2991CD92F02D368ADCED555DA4B009FC81DFAF8E17D2B0DDB359B76E695BD69AA21799F71BF8ADC85B98567AE73185BE3B03588250BAC40CA5AC3332E82F9556F7DC05E9D55EE50740AC43928BE25EF56EC158BE79F5670679C421EF7C523D7856A7AEA0F2D18E078D2C484D073826E92DA9ED38A93C24D1EA0DB30C019DBD705E5597068900A683F7F99AD367BA017E3D28804D5B889A78BA99D5B601CA78F069F5EF7C7E054F68A7A2871C565022E90787B47F5B0323684814095BBA97001635BC2633D7E7DBFDFCBD9FF6AB81A20EA37AB28296C1B84263110375FD8215EAC9E976F9DAC3D525B1AF0C11E234AAA9DE83DBA977873775B3CB8F8693FBF05F3FE6357E03D0503361198A2CA5ACDC70296363B772FD94585C139F3B22B331CEB04F67CD72E9FAF1D77B5ACCC25FAA8E7C6B58F27D749ABB3BD921AF5E1FFFBBE520F18C86B4E17C3D908216A6E6C71BCE9A135AC340DDF8B647E9324FEC4C56D04C5690DE899067A4CDDFEDDCC061E2D91412761EE4492EF1A3E651CD955F77C39E121D998F08DB0703048AB85C073DB104E964D30C24492E8BF11ABACC8D5CCD6AF5EF3F9A7E27F27FDC2F910A4CAE223E58035B4A2E1F1714C868EBC1FC5F86CD019B4336476C8ED99CB0396573C6E69CCD059B4B36576CAED9DCB0B96573C7E69ECD039B47364F6C9ED9BCB07965F326AADDAB8201930DE4B8366E091B2451C7350906D5B1416383CE06830D261B2C36D86C70D8E0B2C16383CF86800D211B2236C4A24915F30A5CFCA0CA951215E6FDFD6AC9B2DCA23C700784D7A057684B4320BE22984F964118302B612EA91B664EDEAE3F142951E48AA163FBF85BE5476933AD194CB872A0B800B0D20744BAC2E0A9BC94BDC466D0E642AECEFB8317BE4F1825D8F5E56355999776232415063C7D3314F250DFE1565490FB3A7BA8D673342BBEDAC1248AC6A19DB52FC633B4BD487FE3E45B5F3427D1FA40C5730DA59659AA338CDADE1EC6CABEB615742DC01E91CBB3ED9CB18A1464DF92AD8AA3A4548A4E69C69599BD16E7938722027BCEC6C8CDC8C2A9596E6E93069C25E89639690EFAE608DEAE816B528A2B6A92563FAD5292C694CEC14EBC1BE3A3E65700BAF0D590D14E36AE7795D74E3E83ABF1E83ABF6B751237014B909F62315E9F8D6014F3CB6673E5BED55FA7CDF2EBFAA5D56C0689492FE286306D224684301F5767436E40096B0EFBC672AB8B9EE57174770DFF591E6FB51FDCEEFDC5DE3802FFCF2A5FA508D4B5494EB46D5BE055D8F92F208AE1199F6A45C33AF971E7B73C4202F4805353690CD208F94D05118AEF1BC343AD3EF478A0C405712062B4BC700DE8E61BFE9C8B73DF6F1200E8637CA06987FD17ED869663A8FD2B94E8943F96ED3F4671C961FB1D0DF240C5C1EB97D007CFF0A41F3B6DE2EF72018DE18FD52F50405ADDD577DCE2B5C7BFFDA8799B8E93177A3FF5E199CA6B1801D2443FBDBA2A21850CC2CE5FF43A399B5C41B9816069D6DC3694B4A4FEDB35664B83FF1F118D8E1398B93EE804103950CDD80FCAB0C6EF93592AF124AAA6FFB92066D9CF5C900883602076F3DF37011D669EA782D464573453E9465E22CFDBFB19C196538ECA9443576E00F522C3A4A3F172A34448E4C93577BBCF1C471F26C6C957488F44ACACE95BDED4B0F2CF93C3DABF9BD4492157E351D618D3340BF4C089B222BB9219B1DE03E9CF7381CB487941CCF55D244387D367652F47FBB1EB21A2FB3526994424972ECFE633FF9A58B758E8CADF6AF3A577FEED24C5638881D4969245601006F03A88903BDB70B3811C6B885F76C9A718D0EB379F59C428384827E27B1E485A019CED61A6A2CB5C2238844821292CEB6FA6B99032A098FE33A6B8FCBD4852314137C4FB8274ED434314E4AC16D64A99CEFE4B57A95D54546AAEFF137B3BC6CD2B13FAC63026BF34603E786DF1B4AE8638406E5A06346CE23780169DB1AF6B5D5A9453975ACDEEDBF84A74119A777F68DD04581B8AAB1423F0DAE46E2CBDA0767C4DA4F4C1BD0CDCB041F001A07F94708C95803E916F551CBDF075D7E77FB6DF7719794C77099A1BE1CD47851DD3825FDE73071C272F451F16F338AFDCE468B0CC4FF4D1E4073BAFB68793A40862F17FA1955519A61D07796B01005875D5DCC3B5AD66D9A7C520D6165F3EA92CA6BB8C37D521B4EF0F29E21ECEB350544981816F31A4C12C89402B18730D6B2E07EE497E7DBE8EBC058CE35E4C5BF52E5278FE2C46F7D0322EE7397A5CC08D6BF68390193921EEEB9F715F80F32A861DE93A5DA91EEA3ED1EAADC7ADDE1CD13B8ED64584D0E332E047215FBE2E5430FD0DE11958D1882019822EBF670DC200CE008C4BBFDB19240CB6FD1B54C213C115CABD1B4F83F6339E19368906CB492140E1D4EC051ED95A8229E44BB8F46BA3942E2554E846AD5262ABD093824F3261A71B2E0804070281404AB95F0D790473F4D4CBC563ABD8746FD9E69C6A3758D730F794F6D8DE1DB5E0BECC6161C432278179B65C0F5B269B64500078CA53FC50EE1F6AF1D32F1904035FD32A11FE15795E25AF0CCC1A9C47D5FEC2253E5D145E362C8F80CC2B467BB103CC5ECFB564CD5BE58599AA49C646058C8E749E5954E9531F58982B90DF53175C50AB657893A130E715F2B3588AFD20B9661EC336E9FF484B05974C02FBA639F0C5FD4BC4A99FF21830B804B8DBDA8CC448FD38FB881E29FEC8DF217F9AF5B6610FFC30289A04CA43945583E1E9C071566A8A9540716340B7E2673458A034F09CB2DCE7EF737A95FC73E29F457651C786DF9EB8DDBC91A70E14151C7B3F862878B574852DB64BA2045612CA80E55C9387EBE1AA96F693ED7F5E0CF2180F20A2749DC2BC38FBA84DFC9EB5E6E65C18F3BB11B76D185EDAF247441FDBA22D5E2593D91806ADCE82E2654131D138DBE169535F8CA2F2577A58375CB906E6AC064B9FBBA516504C90C45A19359AC9BA79979533C98D69F3169CF9F6642C31377D2D32F68E484ED1533B273A5D25D6408198DB3085ED375C82EFD452EB4C481E4D65BB3DEF86D3313F44F39DF4CC1F1AC9315583B7668E8CCA3AB9A6BF08BC8E5433B76B6D49C37C93713108062ED90C045D9743E183560502034BCCF7A4A8641221150B95B24303D88D5581BC006E33F2BB97BE02E8EDBD880021D93558538C0A441EB3B49FAF7C6B326F40E5033F64ED86D5B2C4F885A72C25CFF4FF8B9104241D608E5B0C04EA3782F2C7C60334CC62306137382185671045B72801F5D7D0E52EC194EBED466DFB068A481036DFCDFE427D2C02A0132B44ECC0FD46C45CDCA489C118CBAC5A14B1F0184998975837730FBFCB10A1EDBB12F6A5DAFD283A800E57CCDFFC577C8B1DCC2D5E279408C096BADA695CD610C6CA0250E0B7A2AB19A37C541531574A5F72CF3FD82A9904EB7C230805F1D6784F8BE4DACB4F81BBF3F523C25F2667B69AF957BBF14F98B6E097CAD0ECB2DA5B56647D151B37001315716DE95F2E8E69696C6FD0ABA03CE3C302D6F479B2F46F782C995ED92F5F510937FCA115AE6964766F1752C8627F9805E3A50029EF36AD6302693B46E54889F258BBD1385399E44CB50A6EC425BA0270B32F016D4FF6A2E7FAF13A63CE95E2CE657D23159B12F08096C1058D09A34886E5A0E0E849754CDBEE497981943739D2004C12B5D7163C394C9F6355D80CB201E7C5F2D211A930F94493A2586621EE36BADA36CABE30229E7D7F736EB1E84AB8F529B875A2A28B51B6CF2FF4D135B2B1867AF41DC0B830D29FB173F9E7256AE841CD782216614CD4477672C878F23181298EEEAD1EDECF7BDD18CB8B6DD285251FED9A95443478AC9883D39AC19DF14BD402D9317BE83D3C33EDE57619CEF4FD4558D16BF9F5E1331A137D1951585ECD72FE4AC1DC7369E7ED8C70AE0C2B9539A13C68A297FBD55E80827603C3F1F5FE9821F853E525FAE7BD2EAD2B0CF943F0DB88E3E2A7513AFA8A6704FD5F84564E0C8AF99CEC2B0F587E25AAEC7D8C1A3B4A08658DB0944B0EF95D9008A7922BCE17760EB8349606F5F5703D6B1513CB282542A873F30E39FEB07F77FB964D0A5D01117775835B1BE13078620EBE515F50B008F5C66887F2BB003CF289B9A5AB1E992DD7740C09B6DFB7429C0CDDC7A6D543454B4523E4EF013386198B877F925DD1427614896852BAE0E66CC9870DFABF9BC2D4FE48AA44CFBE06E81CFA704273D10E0587C8E211C17619CBA140C9695A9AC2A941C7E76E2311D5E73E16ECDEB1684BF5E11D5CC14342CC0C28DFBA897F16F949302088CD592F4D900EDFF2A89F982E19E3793FA6402D0D30A48AED622DB9517C09313F759C57D099FEC1E1FF9C1F4F6A9531999331BC2ADB4D50B0E732E1EFE73FC25FB599F5C58CCB2B25853148D7E8110D1F3B91837F1923198A8250685080EA6CB19406492E7179E34315B7AA42A9CB7DE8E5698CD3CC841105E708503C9A8A22EF8721CDD0C1DF9768CF321080F86F70EE57FD8F0081C9647890827B6A0B9635E9AB5B339D14478AB77DC6041FB4FDA58F44F65AF5016BAB3FF8EB6632CD31FE08ED20E0B9730A0136AD34D82B1CF680A66DBD64625DAB2DF7F29771DE7C3B0A565136A6499D644B07C834E5117EE86FF6FF58F67F486C0D659C02B8A81A4E89685A2921B5A495B61B36CCFFAA090FECB46B35BCF40AC2B151EBC5C1FB80AD200D7DC313BCAF98B8EBF93A01F1A808A03633FA0C6DA525838426CE1BA4F8C77C25FB874D6F556F5EFBFC00D615F110F5695B19838E43DC383E4E31DD2268BD9C8C35FCD262DF0D42732FEF3525EF2AFE22E8DB02F6CF8462AAF05B8110B29895487B40798C19FA76F29B417A39D5E81F2E71F273EAE608A9F3A360ED0E64E2BCF95AB2349C01F4114E270AEEA3B25B1268B0CAD45468E06E4B47F7C9881DDDF971EEEA263FEFE7DBA0D852A4A064359C43132A19FC93453DFBBADEE75A5CD7EB8D58A3D14A4FE8A95C5515EB44063966DD45F8D7EF9F7D2919FD0E9A25AD017B5082F8F5694D1078DCBF70489F5CF360FAB1600910188BC18CF029804A153D0745B290CFEBACD154F71B04B66301962AB90A81314E74EA55A97C4AC86EA320E0EAC9C53E7B561261A7756C416E78E324AE625F8D8857EDB8E405DC7F281E14BA49213F831405BC4835872ACC840877B099A49FBE8D1A9174A2385D865D00B2E094606E7AAB211B0B15CAAA47D29CACA3827D9A131367FC935EC2034B65BDD03E35AA3E14F288AA9589AD0E727FFADA6D27A5906C02E20D1717AA53EA60C3194CC1EE3FA1FE366F139CCE50F6A6665BCC3001A8570D07E00150D3E456413E2878C346A52C0EDEF97102ADB98AE8C1638CEB23F348B916CCB27480046F2F1F72D1203AACD9CF91FE853081B99AC72122541FF92A0B2297589786830AB76CAC38BFD03590DD3184BB63169659B43F17FA2AB82B0C404D17412583620E5A1E0CE435D840D8C0B181FB61A02029FC0DAA1F9E5E66062F61768FC261E8EBD6D77E24B0A84F82DFC9FCF1FEC8ED5B84B97C2F22D2C38CCF27B474E9CC15B82066ADED0C7645B6151B19AB284D722B1B0DE198E723C10F33FF27524121CA571DAC5B61B68F5E83D4E599C276B34EE47FF0579D6D7847352401FB450A16993B3CA7A3C6E628915BBE727D9438810C5F5231DE7D108EBD4AA984483AD3D308DB6ADA7AD1420F9E283E041BD6FDE88F622A30BBE4AE12FC88CD20E45E3E9A5165FECF1DF308F12371C2C1DAC0DA337D75D1A7527C8583206CC57538F6E9357919C8C5F18D52E8006D76953FC16821FFC5E6832AAB56748EC3309A5C769DB9A31EDD3F56D7EFC0C4BAAEA528F96F7FEA037D97E932EA5655C6A0F607F413521C735D2C9C6AEC90D5407FFF17079F1E037A2CB3108D8B8F5E3E6A8C8B54326BEBE463A2A67FF990507DFCF1DB1F77BD42B20549BFEE7FEE8346A26DA118EA5D83D43FE3E098EBEA386B5DE31F9CA5839954711AA09CE306D2F8CF9AF9D3C1BCAC98F273C81906D6B71C11C2F0DFCDAC630F6A822B802B1E3BFD9237290719195F54F5D73BA7481CF36CA545CAB72D704614B4EF552E824154DEE55629640EE5F3AE853006DF0462AEDD38C47B9CBFF6BFC992C3E2B159813EAE7B9BB19AA086906CB88461640B831D2C83E734A123C182E33D7BE278112A1A13A87CB72AFE3E220B4D18B9F8B731B16CF3CEEB766357012FFEFF9369BAD044EFA6E4DB88DE6FBD531E0B5AA1928D030D3FB52B68128FF6B06E5690D62C29FEEAEEACA073B3485821E434C901BB0BD4B76DE113F24FCFE7B14454A813F42341931CE5355F4502BEB6B9C061A3585175D7EFC10773D024F7702EC15748F8D019065FD94E1680FA2D2061109A7CB1B7958CC14A22FD215230A5B9B828A1839CDA014DBEA43CFDD6FAD0BAB05B6CA43D6699966B223E728E97802F3F1933704FDF46554D99FD5FA24966B47DCF919A142C80DC49DF03CDEA0D9DCE9749D8A4754D0BF3A14995286FC18706C681CDD04EF642102AD24BE2276468F2ADF42EF9B1DE724DEC99EC1CEA83D1F9448F47474D469527BA06CB246F6367907E6993DBCEE94979554393DF38EB7C4B466108EFB90F66ACD9D12B0BF72BDAD064162DFA830CFC36BC886D9F4F8A1E5CE44D2474029A5CAFE0FC7F2642993AE2AE60FCBC60BE939BD48D084D6EF0298E9F480BE2D73F8ED1891035F79CA710E14293DBFA08C1A883CA90F7D2CF8EEA8CBF8B270349B761287787122D0976A9FF760EA31E0B59059369720AF149D074BC53B82A73DAC446F99E3ACBDC17C024A63761DDDDD786BA83E81CBE6D49C412CE447C7DD7492290A4E2ACBCF7DC65CA87F47DC4551E9F8147B67CD80DEF6823182F986DCAA3E5279902A1F4062574AF83A95529BEA6F4F1340D8DFC749DC3692FC103F534BF8FC822750653FA4FDFF6146AA2CB453A0B4C4C14B7995641CA25BC5F2705B7BBE10357C25FCBE23B696EF05C606BA222A008AC7C2460284EAE6DDA1BBF3A471C4E7DEF66E0D41FCB9557A8ED761F4E2DEB506D7910AECE7CC5CDF30FB02C1F962C29A4DACDF6FF2F9D6433DBCD72DB8657D23BD552129BE0304C565527333B2BFFE34CFD17F6F8B03A5CD93ED243D4CE8B545FD14D84523BE569FC37450B59CE26007BFE0EBEBD997D7D55382A9348C57136EEDFDD4F69746FC2B57631AD9B00C74CEFB609418EC91D926EAA539CC38C85D518E025D94ADF70AD7E17F38A2788B12CFA44054632C851047F683F58547B66A9125B9FC1D3A8C5EFBAA9E78B15565D1B7F6A56FDE401386EEEB1F0C4963B0906D1F67CD4AC4DB96135C492EBF70ACB3B4468729634FAD00DB1247726987FDE23982B875F8D7C524A2101D7F9CCE248277CD70FF908E24A1F622E621932F229AB30434A45D77B2B27194BCA34D159E963EBBCEA1849D9D4871306C09A0293F46143D3BCF9F99CD2D5127B832D2C694E48FC33A5545616E54A2CF64580F781ED6390BB8D32F19AAD4BC0E1F5387BB03E3118A65B90A6D03D39267585C81A08BE7C144B5D0523B2BFC65808E3CC4AFFAE30F9A071983385978268524125B221F92D30C77BF4EB3D80F7A9C9E8D1E6C888F1EB4144DE329E2DE60EB4EEB0B5BD2F3F69D9DE13EB3A04DEEADA8C76B75129ECB3FD7B247EDED67F23331CA788D3A4E1E10E3FF2DE40441E55E626157B1C1C77BD7B9B7E68B8D2053A1C382184860D2DA39A210E2121F0E0C321975CA9EF8F8E6040FFE538FF21CD4BFD18E821DC6722EB57B6F6DE21396B1506589E439E93DC62A4CC1C2BECB615FB9C042A5DD7B80FD1E9F6703014BE10AA0B499D09EBAAFD724FF1CBF7203C8FA7157FF22089716A8803A652B01036F29CB49E9F7F0A4F1CB41304A30C3934C80A7FDE75C6E9CDFB368800909A182FE50BDFE076B1D0F1F4B340ED171E553F50F906F58D4447EBFF0DCE15007A9C367C1D043F78FB86840E3D5689C383627FEC3BAA85CEE954E0360D2658C3EACDE9E5BEC0A2BC4AF9FD71FBA864391005E08B2E1DE4830C134C9A49771C83BEA1113987A19791478C7EFB4A3A9872AB78DF0DFDFA34D0CE30FA13C85F41C511D5B3A7D7DD53B26011639CC6BC2972078801727F91377817C4A19BA3FF56130161610272E59584D059255E8DCFBD0A34976218AA3C3B148687FFAE91E52AA1A986D7288CA17955065927EFEC2F4F4C69A057AD1822BE9A64FEC41C74BFDC9D07EC3AE87205311FFCB8BB25D732D6850B978D9026AB44AD021261100C280EF2E2AA945D597F47178460DF38AF51291A5538CE2432445310B84B0BE245033A3C0D89B99F6CA4BC89C7AE18CBEF4ED2A51CD7DC8B0D664A68EA4B0282E08F439E86830CEEE98BDADF65139E0A2A3F528B108370A5A748E415579766CB6FE4ED814EEF27D323B6A3887257BB19480310E184BABFC8172C5E6C0BF60E867ABEE05207A9F4A05EC4162B8DDAD3286093E25A77E8838B501B04A0C12BF608BEAB00BE96E836F286C20D821E543F52948F96124CDD8905BE528A3CD8A27FA9014B7B5C2E3EC192DFF1FB4C25137F6EE34A4C52C8241F223DDB79E8AC068D91C3BAE108D423B06231D19228D8A3A4691AEEE538998940CC9251C03A940A6364A8E961197C5B891FA12FF5DFD543BA4CBC6EDBAA856633618F38A2ECA0384A96411840A15B25D559FD10C44C419DC6DB61A902427F70D015C02D9D38DDE16EFA79A00A101BE81A1644B6258F05ACE95096A9C42922708DAE5946B2FFE52F553A964293EB06AF64BFBDF2ECD899D710943F0110C85FB2308764C3850CACBFD9D763F3963D0C874A54EEF0BF503DC5D95D54DA7A7EC33D112D8823A877A0DA30EA4E0275FA745A6B4D4583AB8518AA372CB8057F72B443F87514D572F35E67687D0B03337FED3B6B4D3725E4E74F095F5F2EB7275331FFD095A9F99AB87AF614CABD5A71751E49A3DDE764730968B60A30251FF0073D1D39C8306D0D8B4DA2B075DFE6AA57821454653193B5D4C03BDC6643D6A282DC175F4693BEB30B7F696080B0EF1ABA6FA19C8083800CCF117FD7EBCD3BC9DB61744B7D510E222B1DD190068271A8C6F7C607E4F9241425DC1063B0900583E926F182D26F7C61980B42571AED7036290249F46827DD9C186F88E8929F8DE4E7DE3D07C44118A0B05EB9C8964C92E0207C9B616BA6B2F5C3717EAF2E8C8A336DB678C277BD021760C6413614ED508B3CA44E5D201964F926CC89B5D057487DF7BC889E3B103D52DC5799C0CAAF30A1D4EDD707094BCC78F8AECE3451F9E86F499FCFD7713072BA4C2BDBE1BA19794787CC64C79970467F11EF5F7444CC024A025ADF176BBB3EA622176B3D5B3E8F4B1F9D7A709ED49C1A0D9677736A69BE819E0A6CDE21EBF7E35CA5E6C17800031457B6C28A5D0E874EBDC9C14C1D9D23C773061895E5DF78A6FE670EF5C20F6703683F25500F32FA7F8937046AB2DDD73863EDD52057FE3F667491561510FA73C90B414F6FF2FDC855CB854402C9034E671A37D86937728640A4F8623A885E9EFB8606C2F388ED46D6CF189E44A1B14882F284637B82E30CFF271146E831AFDB7D61602746F9F7D6BFDF62E6D2C89680ED1A421D6695D31351FF72C0C5309C6EB3DDB7C799CC53FD9D337692A43950DE6F64BDC5BF875288219B25BF1B7D1E04070281402010120914F288841F55DE1C05668F41273B07C5A0939D83A2B94860D91B975E6F8ABFC1F8CDCBA8096B69B546841E6706B06EC4F21AF5C073100804028140D306A35AD48094043F0D2473751E38226E3C9536428BED3553CBC857E48349DA50F51E30B287801F1F1C646DE7DD0E60F1FD79C1A03D2108C492C5064619E61E6423202369AF301053519A3CA262A35E8B4013312FA70258EA9F5A03A034A2A8D56008E7D1107CCD4785F4A647E98A2C6EC6D72327EDDAE63ED7A0D118752AD6A0A006F27013D0E5682E38AC3B13D61F1460CB088AA060DE06085D9F0108EB643AAE8872D19B1E8A2A5878704AC50A22348E3F39BBA4985D967AAB8226F769F7F15C90B3CA6DE42B313EE88D51B7C378893B24A385E6A2567DB01B407BDFA3753B65346AE7771F693BCD0AEE87757B65775104BDA958CFBC7F83625C0CC200B62DE43E0EB3017F1FC6B43953327DA1197316975C8F0AEF7BDA662F1035FD07403571C56342C265FEFA42DEC336D23DE3F7BC1B59B38E765EADCC9AA5DE43F74CBC29981BFA08668F4287080C100A94B81DBEE50EF38C32243EB5F6D35C7740BBD957DA8F24AC161CF3F6CDC83B2412B811C7D7543A2794CB5FECD6DD36DC2E6EBA627C45E2CAF69C38D171D985FC8E5649F0BA4C984BE4A0094814F1859F2A40C3EA80A0FEEEDF99099B62C5EE52BCBA2652BB6E486E741BE87169082EF411821985DAB3F224E16F4CB4B0D5C8E50A5D5896F9359A841B66C51F09AA928A531CBA78A53FE37F33F7D3C671C22D6BE984BC43085BF0EA38B9ED6F9551F517356A04F5FB3D38CA0F24EB1B73C808759490AEB2C2F4EF8A9264B6EF5AAD59C926F4C75E9C9A981300330910FB7322ADB685F3DCA4E1955703C2E573AFF016E31FDA21F2816ED7D380B8344407FA08D1881210D93D7A1C8C03CA561867900A72D5DB9F01B2B7CF0BE091F2090647F041DFD3E13164236CA8A4BC5277EEE4FB947803743B445CBE4F3784C0185BB0133E1B304C1420C007379288CB8DD788D3504B7BA2CD7E8E1ABB714FDBBB9D6252726D7864BA2D03D904B5D6C43D9D4B0AB1ACECDF9C1C017E1523BE276B93D7D7BE1CDF7466C4A0E778765A915151D5CB007E5D6473BA1103A3E38CB2B52759D3EC8C738A2F7A4F397610F9FE4E980CE14B37F2DF3B3BEBE279B3BEB9148A56C539F5B29B3F9C09AC1BC936E982F7399D2437808C2C1D73EDB1A46477AD86971EC82A0BFA6E02480099020892A61149C01D60D93A21F308130046F841D1A51C9A7C92E101F3C08D04711E73E659DE80A8CF8958675452FF5985AA663A088242C67909CB9506FA20C20A1D1CC7260D0777558623E83D20EB0870A09B0C5B4AF66F0D077757404DCD429E9027306C1F73C7E10CA6A973B66C20C999202B5F06D8C6A06D206A6B68B48FB1A24E82A088B0BBAA7CE4F92AC05721343A1E7EDE36763422342E69690B68D8681C2AE5C55072D7D391A511A1E1E6E0E2E1E313E017E6F9DFBF59C3CFF7C75DCD2D28CC2FC4C3CBCF2720C8CD2BCC4BC346A36D676FE7ED6DE54A234243C34623EF6AE5E04323C2CB46A3E4EE6BE7E0EDE41BA4E46EEF41231242A36217A4F44E9F170D1B8D8E9383BB95AF9FF7FCFCDB9F8C9C32B75C90379F0C9FAF9F82B1A1A280B26680360F1FBFBC9D0DAF92BF1F0FB78C7550A0A7B0B793AAB5A197B29AB49096178F8C9E83AE802EA79EBC208F822AB7B192AC4AA0ADAC80A78EBDB4BF9096A2062BB78E93AC8390B38FBBA78333B79DADB3A6AEA026AFAFB49A91BB95A190BA9D1B9FB4ACB12AB786BE8E2FBF81907E90AE94AE83BA2FABA1B0819290AB2B979DBAA39C938C9FBEB5B1B7AABC8F5180BDADB2BE120FAF9CAF8BAF1BAB8B9A879FB0BDAF6E8066A07080BC9381B09B869A9E8CAFBEA18C974E90B157806A30ABB1BA81A2AEAB90AFAEBA80BD8B869EBEB6BBB6979192928EB0BAB79767A082958B0B8FAA80AB4280B5A6958E8A920E92DBCF2EC0CDDA9ACBC6D94DD6415FD84E59CA2A58CBC9DD49DB9DC7C1CE47432BD0C351495B884B4B505138C0CDCB575BCF3B80CB4B433DC85BD9CBDDC95646C0534F4148DE8957C5C6D64349585A4FD043C04F4A5C9C262C0C04028140D34418840138ABF7B0FCA7720CAEA5CCDE4BCA549CD07464CD193BEBEFF639B20C33E41D6A80F907A8C332D5DF2EE4A517CD3F9771E7E17152AB06F9B6B52FAC0CDC77F9D132AF79A409C8F7EAFEC7F9265193E83BEADF17199D0E4E3FC9D7933B9D12A9312B6C7482C0C836C53B546A0485F61E4EEE01B1007985942F1BE6ADBE7FA3D976A0925CB7E6693D35AA5A0DB0074AA72871875706D8123E500BB1AF04367118DE7D95628E26CE06CF0FF38A587AA158B079E7A3387FEC1310A4D306D1431CD61EEF140E83C538721014731A41940A1F8661CDBCF9BFE192926511F5450CB1034D34321E64675EEBF3B06F8068E97D9753A06059C07E622111AA2A91A1A0000E609BDC90E1E6DCC985A97934407210D596F2C5CE56513720D93ECC890BBA12397ADC67DFFEB8BDCA3C3CCCF866233CC9F3E7885E57E554C5200C902AEB39F81B9BB0A37CE16A1B4FD51BD9E285E59B079FDA61B174592757B55E06E8D01C70B08A7A46510861766F40E0B788EC1AE0450A7E4AC8547FDC05B01569C953270B331B15DC981C174AC756BC2C36638E974D5822115875BC56702019EC29792E2BCA19D7279B1E7A8A68C273F8F1FB18C0A0D517F5A725F9F7AA24BDC8CC9FAF0F022295C5683FABAB11B5913A49BFEA6A82D2FD19F959D28214F2878E90CD7FFACD9766A67F7C3903735F7B63625221FFCFF4A59BA2147BBC9EF308F0F3697BF8CD9D08615C944DA9E7E75DF30DF3903E864B8315208FB5E48C66DF448F5A8EAAE1063BC0996AF312D91A9F1F7F58CD47D8EA3B6D66FFD3A2545CE4B2DD116EE9AC6E6A2D7580BCE45DA2AB174C597F5EE3E54C8235136F00523452FE88793518CBE0FBC0539A6FCE99E2BC114718C1700F21F7276C7DDFB2D666AD13E08368F724817E39AFC7CEB077100164628A776DCFA8B1DB9C647E0B22E817E3419EE219EDD37E0126C4CF1F98B9567EEE9E37FD31D2B5C03987DAFD3FBBEF72DA04919469166E66BD2A1986AB272A2D007E95550075CFB0D6C7AA2C362FB78F690AFEEBA6565DCEDFED498F7E5B99D20682A73366AF359AC3E355855973F9361FDF5CDAC7F1F3073D4CEFFA3F217FDF735B1EF4B9C5680EF9F77936469D2D9E2F4516CA0AF5C4346B6A2EEB52019557A2D6CDCDC5E76F6A7280015A99BD0DA2C79F2CB1EA051FE595B7CDAAA2C0B4D0D01D81C4537E1C9C0D330180F860A535A1F7DFDF31D3F4A333DF2D598F9BD0DA9883C0D0964384EB965246E66EF0E35F6F2E6786AE05915E552AA4563ED4248DF88149B346B74450CAC2C59D2519E91267CDCD6D66253FFA947ADBC40AE035ECAF90F9FB757550EEFF130A49AEB218F5C7DC3E3528DC767A0DFDE657C64258FC9B7A47F9E625996EABDE0D384855DF84BE8C59F9C97CEDAAC8ED20FD23967D8A9C5FFEB5B31419DCB687232B287B1EEA2ED8E7FB00E10BF2488B0D416BF1E587127E25F9EB3B47E4BB45EB29B210EDD97815FADA57A0AC1D0C3E2D4763D6E5CE22FFE47334A04C5D67E88DE587BB25CAEF94092C42C0B38331A9422F779F7BEFFE1DF6ABF378ED90F7E8032B853C83543F2B45C344E902573362013BEAE5F88DAF2D6ABBEBBE4C7F4EBE97687FC85049904AE92ED0B2C9D4FCEDD7D88DD005820381402010A8B31936C450FED51E08030BCE61087C58BEE9F367E088BEBA3B1D2851944DF94AD6129B251FC504188401DBF6510EDACEFC477EB02E5C7D3879DB2F244B28777A1F31B65957BF3C01271380C33DBCA6DCEDFA0DCE018444C62E2128E33F85FE561CB50A0A752336F1414BE43CB5D4DA1427C27DD9D3B78A21C0533316E0BAB0611E42BEC6AB45BADF7F3CEE0B7BFE914EE54A7BC42018D8D27FC438755CBED82AA1E89B38F917243E8A7437A855ECBFD776F37221BD220F88251D5E61A558ADE1D5D933509C10B618D5DB73457EED4BD67F50A16F54C173057AAC948D09F7336311867FAF185F9FF3CA52D0A98F3C099A012EE7D8279DBB3274CC381BEB4B92A60D8ADEF770520D71C02EEC270664F8AA845798461D5535384D4CAFF6F7AAD0CF97451FA94BEF6B847DC0DA50BE8735E7334DCA85388F7A62B1C78729657359C3F6B4DB389F0F9B3485DB11DD92D5C630336454307CE13D5606EB90D204BC9137AF037F4A5F8EE2CE9D547AB0C0BC4B691201FBAF44B6D45CE6947D89570B93713323BD09F5E365A582BF01DF0FA11A8983A1B732AF3F283FBABDE9F8337A596D1E9DB534175E46D379F16E7743E040702010080402B5B6549BAE8EDAAD4443F89E8D4AFD7B80A6DD07131E8D315EF04B94CDCB14A30B2C06EF266C92F2E350A535EECC94BEE030F835FC8A37488F8EB848004F5516369F5AF2EF38404E0167A5E9E2B9CB176D509887D8F231DA47F502E636ED53B92967C9EB4E1F83A84EF02E4D7D58DC7A7CD9D36CC1C7060E8C4A5FD6827AE3BE67973E3EBFD638D604B0CAFFD6BF9ECEBB2C61E75B50D897FB39E02CD7F3A3F9F95778184E7479E327A026D9F68769A5444D53ADDEB546734294FA4EC274C38BCDEF8C34904DD0A290BDA6DDE5648D048D9A8AB78DB3A564757EF9278D1247D5A4DEFEC32838B888B5A673E140FD256703C14415A26C3D1925FED60984088C54B0F5EC5B13A99FE96CB1F8F6FE8C6B3C909F1A9F87CBBA1BA28FA4F6EB7D0772DAECA86369161BA91CD99311CAC3AFD50E83CB7DF4AFA73A91F5FF2CD701C54EDA073C6C81E07937D62BECE5148C442022969569B669E2AF7AA6389DB27C38656786073587A981D640ACDCE36383B1A9D88055A49DAE0EAB4B9EDD9BEA7583955766BF94A2F8D4F0414A8347A526B9E413227123B12C86676E353553B84D34F5D1B0915431F875450A38793BDA1463D0100554B0899F8E81EFB10DA01E5FF730E71E0E4FDA0350BEFAD6A31AE5CDAF4EC2AA6E64446421C966217DA8EDA8CDA0F002F641953C7DF204E6523A923B369E56DD8863262D03E5030551973E6A4FDEDCFAFB243A9275AEE57446DDC478CEE1002D0A293F3860615BB6D313188CFA207C8DAF048106047F0382FF0A02721B66E1110A02DC1C7F23C28782A07C20C84710D0DF914DBDA5A8AD5D576833A541FECE6B4286305443950981D4DFC92067EEDAEDBE6D40CFE66E68E46F733D20CC3E284AD7A6007E1D4F015708367A0BBC86B0DE0A18FF6FAA181A1A52F0835DAA1DD4679CE05F47A2499D5337153923A791FFE7772C85FE64E3AF32D05CE1C020589B2E7EDB8008D320993E52219405C9DFDDA647EE3EF7F108CA638560C3EF8E3F029863AF2C9D395C8C03CCFC6BBACCC02BDE491AB5B3C93BFB1DDB5001D56777CED31B7F9561C6D2ACBFD1F134C7566A731F325AD96B4207AD555D1754D77103A227E1F9756E086E6191929CE6F1E3DC9CA55F4E4D098BE4ECE99732F0990BDE16F0968FEE31B05A4D6D706AC7EFB4B421CAA9D502819D815F54E0FCD8694179DEB80AED689684782660E1B6907DAEC44F308F24F128EC646B1DF7536A0D3E935FAF390C6F6F4C12620808FF6E3E46DFFBA660A5D7239CD5849DA55154F06E6A631AA9E5E483CFF7FC3A0FCF7E45AE19CC10A74B76D8D9D35411DD9AF1F088ADF491EC23EC5139C7F8F7DDAB6C39BD68641A2E7230A3B9784439A4C532D31BB97526E0505FD32291ED9ECD3AA40BF97A7845FBEE12D130F88DBA632F7897DE863F20167DFD5D397F36508CB1A0119C7C7981B156B6C9F1F8C37E0ED41870324B5C220D704BCDE72A2E759173E809084E72859B9AD2BB194037327B5C1011FD5F61D4FFBA11044BFDA71C0AAA4FF673715F2B13B717ED2DA3E95FAE0EC34243296A17E8087E738E46EDFBA7FB435A92D0B2CF7639C87A42632D85249743800756547EE2A9BCABD8F76F079875A0B0342B9662976C365ED17CC2C95EF3BF0EEDF0120E64C4B3800D490B8BABF2C571463B665EF1DD6E4606C5DF7A39D99B5EB337784D77059FDCB05408F411121005F6F1A584F064CD637F7DF204F83FB4237A5FF94AB71B022DFA0F4A2310B5939A86A06516EA877C4930606C1346D72553AFAA0267D713421A4F205ADD24E1E19526CFD2B574560DEB1722804AC5D9BA93FB14C5FC4BE3F6FBB3D789DAE408E4A291EF7738BBF6BA0BD5EE42B4844791C110D5B30E60914AFBC2FA6D76EC9B76B5F76C1A0D1E8A9751632474985F939D116AA6BB7960A7A471BFB7E18B428A015CFC0E8001B8A4AC15E9FF57117131701BB7688AF5108A3A83B7784AAC6F1BFF14B17A1D2BE0B7F1319C1E0E0FF9FC09EF330EDCBD425E71D0176B4FC76698CFD29149A8DA43C355DCA1A70918AFED68EC981810ADD6FE27D3EE9C5B1B439BDB6B7640FED8FBCE7C787BCF15D7F8AD425983758779B12379F5B01E3AD5152D1CEE07B1FF807A7ED28BE6B82FDD1979B273FDA7186CB11CC96CE9A7A1C2CEA2A3AF8C1BF1F28167EB721BF5C488423F94E53D153158FE2EAF7464DB3F037B02185850406599E0FE34FF9F6A98B7C4597FAEFB03CA936F5C0585E9E7274A14F9503800C355A7507990089ABA3E7D9388945078A1566AF8F34DC30DF7286E027C9E78A310A6FA059E40A282A970FF584897F73156E1F7FE5DA4BFF9B95B57CCBB5A9EB6521B4335D84BF56C8360607CE9FF571B96AF9FEFA14A9ED697A84DADBB68681E91C418B5DF7E1B5248DE6603A454BBDC1C79CD962DF14205E86D948B0E45E28E9316780443E5E53711D16BF6F45619E3D3AD7DF6551A9474528628CB937B392A894B11647D58417A085D0C4E8F172C00661EE8F66B662004037364B168C774EF918ADF7EB77F89A0DCFCC4F753FA43CDF321AE27FF474FCBC44AC03E5300C47637FD51D202393A322B1EE74A5DF3ADF59376A6008E1FC79FB4FE7C650F6264653C2D51C6BE761A639CC8AED76BCCE3D917A0BF52FB8D46E6A4E1F714EEB1C331B47C65782D2EDF842E535FDA2B1901C42AC4FBF759184CD611C7F7470DC185F6FDC2DC30BF76DA8A700B037E55F23AFA282FE8837BCAA0EBA4B933A92CBF770271D11292BC4EE533FC40316BA2F355F110D6EBBF5DF99D98535C11E7E31F65A22485B8F74FFA65EE4A7EF7138219185FC935289915195DD8AC22001A61901DFED8AF5ACC0FA284720EE792154A342919CCE74F6CCBB39F6E2D3A1E36224F349E552039A588A2FD1598F23CA74C4DFE087F9C1BD3FF0F7D5E603EFC20C28FDF2196C84BD5F5998D36196221689CBF831AE200CED564375F7E92EC6AC622D037620D92742A06E66014A3D9EF6D081CE953735F01BA66D22469F302592B34C065FE8DE775E823078135B2A21C976D64A793DC833B78351B344570CD9F271A4B495DDA78319DE51FCA7CFD876D28994B95FE55CC0DCC65D810FFB8DD349D6729983C868D0CB0439D202E06C1C0C0EB84F985F441E8B7A547A2994B74087C7347E9687849F4E7FD3B827FF77B1B80330A261164DA13822575BA45202B6E545F3488E02A63B4530726487BF5B0A10E9E0FC0BEA6571743B814038A364985ADFC5227C0AD9E959266C356723A03F331F254E51802F19C566B80476D103626160FAAF1A7B8097DC41F28B40251EA4A6174DF6C27028915D5687C8795FAB927DADDAD0AAACA8A439D4D49CA5FB5E819D706A64E3E40FE1B52A39BA1F2480E726864588404CDFD4FB76868B339B3CFC2106B5A3D3E4637B4137CD92233E6DEF4E2B0EEA2A8CA840274B4E69C32124BBB09806EB6D9E867E4A8D26CE7E732BDB865E6E17762812F65D9ABBCEFAC67D50661406DD0375B1484221A7D3044168D8FC16455372DE18909F63DA6BFE661E4F53332E0BFFD617CF580ACAF3B04B9BDF89D3397F59A92084528BD6C3811EBF63668F5EEC79BB3351BAE56125AB3827B412C2FDA61DC358963350BEE527B799E55CD3F6E73D6273C791FF000D5BA3C1621C0793346F9578BBABE573F83E9A0D9645BEF1D2429FA477A9326D49B5654D34D1F269A5AC501CB51838EECDF6829DD5F8D42B3F8FF553990B17DC7153AB50DEE3E86BED451D681A7861E1BDECF8E7CDAE8937FD75F17CBAC110828DAB3BB937188097B83B32DC17E33B2883284B0649EC6C4F259003314BC4390A7A7D3638D8F4F88F7A8EF9FD46BC7FEED626EDE62DD5BC6D92F8A4AEBFBB82A3399D6FA54B0AF27D9E90B97E3CBDF278F9CE54F4C1809E5FFFC74078D18EC4EE2D922A72FF24B0D975DEA901C606037F7308EED820A75BFD176F6358463B62DD7BC492028FF1CFE65E10943A0370AE036631A980D5438FE84A45A7102C0BF2CF6FF22D9DC6D097FAE08F6F3A8EC88EC46ECE337CA60C34047EC71104E6634381141B8944098C4DE77B9160F4155BD879303402CE0D50292E0CD0FBD6854E1E221DD6D4ACE53F17D4E442D654D6B1E1BC9FBE12C0D081E322622765911D577A88CE5088D4C23F6081FD417B2C08A7AC3ADF8936AF535E8F1CAC6DA1DA960785B5EBE3D8EF0B452765CC5731727674AFCCB7A2109B4E2BB6EDFCCBC38BE6903D2B00D4D26AC68D8B3721A40ACD1B777FD551F5F3C93E47DED5258DD01832F3041E0CE71A42DBFB0E3A7DA62FA21D4073F0BD9EA51840DB9635E6C925ADB6CE4FBF024DC8D2FFC55B4584C44E1C50BAB492CBF94DFBE3EE0F266E972A56C418E74EF2BF7130CE4909814267F4608AD4F6B843E26BFCC100E55DE0FD3FE1AD89BBA8D4F3103DEC0F3566369C4586F9E5529E644388FD8B3685C0CC280EA1FA69B09F5B3CEDD6489105709C61E1FD92A957353B2A1645D5FAD97D7B812C0F06EB40361D354B4B8448EBD96E80B7BA4C8A49B7E6D6F35EF26E5F71E2A0D157E45E076E823B8391ABCF3184BA8E87FD045AF97AA877A5A8F1A6F44BC72BB6F60DD8F5F26756BC4E3B06EB02C217FE047680392F822B915B6CF89BF57CBDE028FA0C734E319CA077AB993DA7181B9A1280E34C165EE4C0F0107FB38AB3159FFC6A9912733BF1455F0908C368884F7FBED3D2B514AC0FC70F9157EB7D852051E27178942EC3BBBE695A92C5AA3B3767F84EC372B61048F639AC04DC6DC12CD901F66E417FDDE1C8F7BDD8F9C4F9054A514AE1D66B3D6ACB20842CCE25E12A61D2B697603C293667E0EA170A577ABA7D315EC5DE01DA21AF068285D9B69C7098E69EAE8A381273BAC0F9FD127B247D087976BE26A8296283C2C832D440B632FDEF8603732D0E5250977B9D22ECAAEE3E84DAD6114AF15065E0975F2A6EE580A8EC2D6977E2E815125FF6D8085B466CDF3A2F21C49EFCBDDA7A0CAE8469CD92ED3F9E557C917784CB1A71FE3B184D73D71BEFA1727CC36396320F7FA351BD77BCDF0265A57A3FDA90F41E61ED638E8111C828CECF3A1E5BF165E15A28AFDF53288A78AABE3C7D2B6348FE1BD8C9EB3F8A11B7010A338C81E08D20162D38F857C0481FDD9FBC69234D8DC169160558428191E22D318DE68C1487A55848848B009A34524601149A50AFE24C3F50DA5EAECB65B639B5C0DC57BA09039810E7FB7D73486D7EF0AE53B54ABE1FDF49CE122612C10A879480018206B07E7C5BC9C0A872049ECD20045A82324B1988CB53489A3176C985AF435DD02489A3C9AF6285F67C3AC92C73A2E58AFBE7B1CB5B0ED2245FC4D8209AFE4FBD5328D0A283062E15135154C3FE26444D30DCAF6FE07ADDDAD07235959E644D0CFD17782186E5E3B90E60B2B9EEC664A36E5CEF148C876BF7CE80BCAF3A5F12E825D3E5F79A57597430B888DEE8F5F5AD412E619637F7E016BD2109102F6BC93C285BDCC1E93C65923BF8E5BB845F6B67DDB6ED34589DDE16D72B1624B83D7DBBA98E24982C6806A08817B6EE7562FFBA25506A537CED80900F11EB73E1C1D7A3DF24D513DBB0757178A0B6E4731FA65C2698EC1D5CB2A786D93E4F3EF38E47D1EFE0D78202FAF8CFBAD442C1BFAF61C3B7F4324C4F9EA5C8DAD810431E875C1C836058161681505AD38FB6C8D232D13FE5C1F1A3D86962DB91F31C17B45B13BFFBECF9F62B89D3F8DDFA2470DC9682CCBFE7E0FB09AE48070FEB2AA0D09045C982FE74EEA765E2FBBF6D858DAF9F68534DF69EB793146C83FF148DA29323B7443BB3ED805AD2F87AB914E27CDC54914B1977FD1BC01700595DFDB7903A5082A31BBFCE7493EB71A23EB0CCF25F82DD6B669ECF7F7EAF77FE819A054DC88CB94A1FED3F20F3E631629C39C8BF147B93906AABADEA277020FA2A10CF20A03F3B4AED752287F7EA5D40707623CC000594AE5B8532924687932064DE11A4A5A543A6E154C159AA9937A45B6A37EAA064855E17D64099E8E78A7A20D5E7211B1C4DF8393D671178DA0B47C0EA74E2AFA06EF8593BD9FD21227E4463FAF912C67E9CB1EFD30EC87727CDFAC2F2837A734E4BE63D85AD54325CA6F8CE82C874E5C0A76A66C0597755F747F2704C71FC7289E14F92B661E9A6D97A13D7C41F4E1610C81E06F9D899E20F0F60C6F6F430D7180E6AB12B8A1FDF5CACC6D5EC42EAE9E583C6F729E6B72353CB521EDAD4F774F1440404E972262660F92CB382BF3DCCCA2BA35D0462CAF1AF82E597B65BD5851714E744E61FC7A8CA6B992ED63CD26506645F63598E685596AFABF19A1D1D5121E9BC31120C6BD8BE6ED676DE76E67EBC761E56D1D06CB8360A06DDA5642E8924693D5D6F69C12B41AABFC37DEC7F7FEC9ACBA85FBA95C058E1FD081BE48739B33240B558D5BE3109FB374D89F77E32386A4F28402B2FF1D4E12BBC17ACF9E6DA894ACD4AA2B71032DD232DE1F37FEC7D951E1B8940DDA550A166371B0F1E552B2E1F0226CE9BB9C78581CFC8FA9C72B0972BCD9B2FC539B72AB14487166BA438C4C88E7237F5B59A66A9A5BFE724C36C3514B265FDBADC561770DAAFC83FE29B92BBAA71C59BC6742E54BED4B4F32DA30EE11D351494062088708EC4E0F98B2F9C848263E9D258F12552D1B839DA5160A3E3A8076CB12E3D44AA09D39065741D0CC1BF4D53FDED1045452345EDB94515CA056DE8D10263CFC2CF612F251C1145958ADBAE241BD73AEE8AEC082B4FBC85B8660FBCB7AEEB7059684FBE5754BF9D3305789FC9C05CBA98DCFB5DB34CAE77F274438D97DE0E8D51AC27FBB7B7C11A8BBD070C5039412F114D78CF87E1336BAA1A87E58D2FA15F3A75EF8DE137DE4E3F4FDFB70160BB2E0FB9AC2778A23D72CDA5FE65834B15D2DCDC0FB663C0E9032D3926B6DA5B90F48F6CE441968C75AC98239D47FFE3C82C27AF873552C2BD4E3B253C148E24B0192919B9225FEA6F7B357AF26F60430E0F4F7EF906BC8DFF1D0EB5D71DD416B2E03AEC3A1A9D5D7D81F7863A50589D65600F6E32189A3E1993F1EDE9FB8457EF84FBCDC76F1E9BEE71A4C975C4C3F67435B2C19827A2F381C5ED0CF21EDD9E97C8FA012A7F0DBD9DC0974FB64F1D95D504065E0E77DC4E754684153CAC735B22139E5F18688DBF93E3EFFB2F1F0F475C25919EB6278DF1122BE8C964BAC84DB6AED771D268A73E85AD3D9F5F6C66771A8A990E196F74F49E69C587A76941D752B02EBDFD6779CE90D301C31A4A4A0BD0E853C238D61FDF844992FA1E457382E9B7DDB27582D4E598F63AE53E24F217F3BA6075ABDBC1624C7944786F7C0C946F1ADD3CCF86E1438ECC975645832754F9F66A9072C393E51153E788EE57C024765FBFBFF6A33D88B56C1D3C4231FBFDC04B0A509732D58601B6F4B6719BA6ED19DD2CA0E75EFC8A8DD9B34455D7A6335131E18EBE9E05A0869F034843B1BD79B03173E0D8DBBF4C5777598954ACFA438E69A31A8F66BD51A052988E05F4F2B841B714A53DCBC783E2C5C94E6CA9725B9E6C40CBFA6860ED72942401C8FB2BBEDE0B3CB9F3BBEB90574F3B69124AE123E787A1C7DBF95332459BF3DCD782AA2522C77330ED27DF848BC1209999685E2B6FFA8272882ACF376F06E22909269BCDBC3A77918FE1E4E3DF1782015282C1AE292D5B08D21434228C2E5FEF2DBB439A15E0E933D0F90564DF6855954A7B1A9D58CEE0A446B2AFE01FC703A3373486541CA95F37B17E52A7625FB0C63B6DB66B96BDBF9F3CCCC5AD3DDC81B106828C0279A41F5FE4A259847C7984F4F11C0003DECA24C47DAF0F3115CA41CE48FBCD4D0BF40915E88DF2C9D4E31FFB44116BC89913A12C3D4C05B2B8EF970645C74EEE3D2C2AA8A448D113B64BF6AEFEFB8E51C1E87A6C051A20292A27B77A7FFEE430ACE59E883004D4E6B60BD28E073F8AC6CF08D4469660A9E751417833080E866887E246E5568945F9943ECA4E4D787B61F7CB1410D5954F1AAD3A90A554680A8CDCBABCE4620FED3FE920C988E458A81099D18F561ECED24123613C936CD0DAF18668D6F35E41EF2D503D4532C317BA2658270E60F2E6C11E4E14992E3190CC9A84BCE68F52A4AFBD7822580140D515F2316CB18EE116BFC42A6596C5A5D816F0403E728A312261E21B0596C863DAA11996955BD2646EB401C4D874237ED20FA8BBD4198376E37E22116B819D509BBE223988DD519DC29A9CE34FAE866CEDEFE0F7B05D31404D79EAAA604B0A31F809433FE8F1A7B7CFFC4E71A6048DAA47E1E421D13BE54C8C4439171B10B8CAD028B430872998E65123CB047F3D39A0591BB7509A5C4CA39991F3501D43C423E5F264DB0AE2E4DBB9CF58D9175940B232AA4EC8B2441F3E5A4AA70DA70254AD353A5D6203A0B84B1E5A2586068B6DD96C099D404BD03CD123C2280916A39259B65C2F1CB26E112038EB8C14A2F9A4FC482FA5A5D5D338D926FCBBF1B1A04820381402010A80CC49C04D9EBBBE810A5903BAB3948E41E51739A82D4CC8D89F563DFE5D7051A5532CA9586D4DEE0255521DD048273EF8D11BFEC3F616098D76544E53B3CC830166E638579000517BBC58811AA3B5BAAF5DF4FA6B764AEEE474B5D7780EF2DDAD76FBD296861DC37B6E46EB1D4DAFE036AD075D49DA4740EBFCFED6FA1815ED3AA9F866EC96F449BCAB22047FEDB176496A552F1F0F9D37FAC4C5FFF8FA84BF42A7DF8A0155CFCD39139BD3D020CA86C7CFAD79DBE9F3A1A707BFA01A3FDB23284ED6060EF60D95E03ABFA7D4C04178CD5CA412131983B252925DD1C177A788027BF5E036E8080B73C01F7941AA6F4E6D4C989049120F1E06AA6CC7BA52173A62A3DE0C2A3BBE9748531454959D6D9BA5BF541A046D128E9AD7DFECE688AA088FB44043CED0533EAAD126D8D64DB89C045A9D459E9DD632A33824D1A9416CE8EC15FE2FD7213794050D289F0BF18CA1428A30665B4CDCE1DAD943500FFDFBCFF87C9D220DCC3B146DB1390F6275038939B61AE84875B4F6BDC78175B3EF5272B502A4A5BF52F7BC2EC2796F01FA1073C9A1369711F0D32C3E0CB04AA7AE4491108ACBDFE9791473D00FA2C0738861A7A1FFA2B2AA33FC49288C5A013F1FC7FFDB8943A74F6B0EF4F96DE0D71D2E5A70499B73759712854C45F8A10DBE455615C5B5D1C829EF7B793B40AFE5EAFE771C66872F89CB916AE9F3E99385E55EF87FC8C274A46A7E820AA69FFB63FAC01AFC1B11161845D0AE5272C179CA8D602A27DBB00B9B50D2D4C2F7600F6739658FCB5A7034A8FEFA7A1687726C81B05F70430F00AF8985DD6A0E466DFEF7D54025521AFE5A958CD6BB3ED5FFC9115FBDC77B200F8C218DD504E219244FC6006B22B348AFA9F491F7EFE786DCFECCFD0F90AAA033DB7993D757AF5AA29D147987A2281C07895BF2110A4011F60C59AEED6283EA6D997E2612A9D4D0D8240BB2F891A6E089FA3CA1DA19F07C2989569D691D5CA6931B62A50A9122EA24118A0DAB72C640F4DF6496BA3341FA9E311B8F8EC23228C9C6E50E848ACB256E8440404D2FEA855C2A4EF2B56FC8A8ECB07E10AB92FEF74EC877C951F4B7D5F7180978A7C15173782A4063FF52C7F1CA9C6D2B76D18FE8B75E9536BDA1CC9C1BFCAE117B7D92D2B83B37EA99047F66BE2C7A765A764B2F2AF2D764CA06C36BAF47E9D62D72FBD19997963097F270153D9E89E07E1FED0755E7602DE85F920D522E0CEECA6D5ED7F3F5AF96A741E2B32C13CDF84C01C5175A631C3DF6524A36D380053AE47AFEB78C189C20D25F78198373B88B2BA4C5AF081DA8DD616BEEE9B2A579D3D68D21CB8259E0789391112CF6D8BDB870717C227AFDA21F5C1EA0099DF8558C30694E9309794114529C0C1CF3FFBD3FF99BACC4A9AA152D66A1DE7A286770686D8AD0C996A76C70E875B00CFDA3BD99BC11170C87960E533C591F7BF6C3B07FFE94C50125241D8416FFDC2CC0C19CF395D6673FBB7B9FD039029FB556DFC70FCBB778AF24497530EE75B8F46A4C400FF96F68DB1269B3F875CF0662F66924F5B544D9D9CD35B2DC545147EE5854C51B80CCDBE02FF016E9FB01595946F9AE8C64BFBA23BD730207FE4B74D2F6CA5A5606AA94CE832383DB6DB6215DCFC830FEDC868FA579CE3575B4031B3A324091AEEC6D3489AB4DC10EFE71C08690A1367FA376911453527415906B4639CECCDE108FCE7F3E0E4777391D7FF8BFE23814C5951C4B2CAC7E6DC0433BC1BF190998430356C80FFF113805F3944F1689A916FD5F21A39237C88D875D47046FB1A519CBC2F2FD9B391A505B4F64EF6167014EAAD8638E071F2CE75AA875BF4AC23FB5C42A0478B56531F93F3B3E3EFD960199FD89F0B0B80C1AEB4A0C7B6F4F29E1CE651659D2BF6AFEADC819E8BEA78A7A4D6E87036D4C7C8D355F5F86A77E00BF976192F160B621B87226A4874ABA0BEEBDE4C3CFCDAD7F46D280FDB724F228339A286B0306357AFC574D5980A5F6B19541ADD1C97923FB8DE0E01F8B90D0E220F38EA62DFBF499E1D3F40C2CEFF654054BAB8683F3FDF86EE6B72059EC3338CAF7DBB2AA83188B24D3BA9B44B5C9585E8A7BAF0AC5ECD13C0E796F2E54378B3A18A5405F6FBDB12D374AF17061731AC1FAD78784EB28F605B5326F6C83B8500417EC076DD2E704E64B48F754EEDD706A3EC62CA7D5074F5CC9B6CB81C55C7955A807C5708681DD4C48E85EBAE0340FF4438621638257F5E5EC684A03506E2E30A885FA519D1B1D3A7996AA3A1ABDC31FAF791EB0A4323D8A4F730407C3CD5686A8860DE2EDCF4F20ADB7B535576217733A9E26C56192E8BF36A59AE2B1AD414CDCA8149FB2F5236A5873563203839B4FA9558BD5E1E3D8D18A0B81DDF7CC0C6562199EAF9EDC7F0A855B8FB5753209CD241046E35D5E04446429F1FF5EFB645A1285206F7599618CFDF6FBD15D0B76E881C45BC3B66C6CB70D17C6AB341D5D270490EF2047735E1D60F60EC0A8180A8289D45B9EEF9411367507E2775B74A37B54D1F3C8BC5974CDFF897FC6C859370153FE47D247665EA9D5C0050FAD2536DFA153739A3BA1D364D5C3846D7113ABDEA7CA4DA037F79189F94160E4F4D2FB3F06B476B093C56C212636544DE3FC24AF0EBC31942826789548305AE21E0922DE19F93113AF8A050F0C4485DF8C47CE85244A131CF606B8103913B8CF4BE129759298332C9431DF582DCE1326C5ACDDBF3CF170EC23848E75B9E657E353D80AE3ABF5B983ED85FF280BF261DF09A1D94993C0DAE5C202BA53E6A36743D7CB929B810BA2550B9D3F8A47660F3F345EBD993CDCBC7464FD293785A02D7B644C7788A5E6A6C75C8EFFEAD7EC21A39C17D095934EDF564B9074045F44A4B6A46FC53ECB5FB5557E71DE0FACBFFFF6909472CC177F563E5EDDFA6B71B782584C3574043E70656DFFFD408AF25A9D9631DF4D45383A7CA0AEB1ABA6E5AE8039358350D51691B7E7C9ED04094B71BF6670233E2C1991A1485AF3AC20AE23DE56A4614932F94BF645065E3FD46203098EB36AF35C64FE6B8EDE86CF17796941C521A17E7FBBA33A05C8E44A9C0C9C19FB317DF825B014E4F2F33CA0B255B357C9F55F494B23310A51F229E7461119A1B0596DE4B02F1086D3FE7FF710225AACA64016188A386105644E7595CA2586EF15ECFD45B29570A6545321C5FE352E7D7259E2A78A4C8F7859C71F84A430D60E0BF968A686AEEA59D33666DB465A7508BD2EBD2101193DCCC6DF0F74F50148F3D806E345A39A834F019CC686C94C41628C3C2898B9063D9F348E6DBFFC975F8B896DE0B74262AE5309ABBB359AE8F803DB7E9B8AF9122257C67F4E42E259E6665FF0C652AEF4C4984B02DB9FEC94BA1D71596998F90F38DC1F13049C000EA552C4E64D5CA9B8E885E62E3C2F4A7B0D482B1E3C6888DA362B14FFABFBF8C011A8404C5FF200444368C09CA93D58A4B1A0DAFBDFC291065043DE859E8DB67E16E389E740FCF316602A31952B34B8FBA1305C2E6EF02183CFF195826088F94394DFCAB6D1AA8AB2D14F24916C2109EBB6105633E9E7AC6C670567C1F28EA68FD23E0A3DAADA7C98FD3D06A6F49E6EC2FBFCE529500F586022C0784F9408DCD1D8BBFF609C1EA732E93F99CA623B929D4E17D893C69169EE154918394869A857579917C346B5CB9CFDC594BF4BF13B77A572B528605B8AADE5C549C498664BA0AB38358BD9A64F52F861712FD59F370B391D8FAA340828885BF243BE07F311F4AC4ECB924144A8DBE4E8AB37DA64563C2443B2A39D7697389D3987726471BFE025B2E88C19E47FD5D2B86BA4561F1532BE8101DFE7CFD06D5C9CB0F41DAF2B72320C261A5A666CA6632DCFC2C823FF96203D7AC01027D3A4D02E45C2B4E9E6112C12FCD7C89A06DD60B20E2565D6E2FD804A29AD11D267BD281B49359205739D82B351CAE9F6507CA24EF86D619CAEBFD0C83101E9F23B9479E2E4A7AE621BBB42C3F780CAECF8848D61E6D1DA130D6C224A75B4D981407C2FFA2CB9381ED5970BF656E0362DC875F382A4972653223B926B6945C4651D48C01C2A0892059F8C8325CF17D96084B695A17E3FBF62D272248FA19ABBC4ABE1F932F7CD5FA07C3E04CB91D49ABF4B9CD5D848EF2F089FB37683AF65D0EE07A367DE612123736626E1DED25A3408A5CF54ECBFC5E1881A0C1415956694106542ECFC5A85DCCC2D22F75E51570534A879F217FB72E99183CA856C70EF44385771C173829BF56956D16F34E49C8BDCF968CDB79F270CDA083D1B8A054134A72DD589A6DED27C093C9E3737DF91B4588B690FED189C7449CCF487DA84CC0AED940A1E64A15F33004FD7CB1135E3698B77616ABD1EB68FB1A7BABCB9C3C7AC3F451F6A84FA704AE67682FD191D4F9F672436C08C9398EE2C58D802A6A3418AFDF529946DFF20AD7B94608EFE8CF656189653E919BB1A3CB0A44F92BBA0F3F4D6C3CCE39A4F6F61D7597DAFFCB6D697EA9AC494BA3A29694E9A213B12BB50E955A235DD9D029D86D3A9549120788262BFC14BAE32402C58317BED172F80B7E81D47A78AC88375E1F1A79F8C42E02F05FFB8DFF2A248124146702E1701EDA58511A319EC2C9D2F6AFC54A53724AE0BBA12CF4D602570DA956D44E54D046DD1B8134847071891F52036ECB3CBC2F3953703DAAF7749DAC7054A156FEBF4A6BF80442A474149B8F751E49C77F5F9674252BE8D2554C7DD9AB51966C4B0191565A83EAE7552A05A31F57B5E207968C3231F8DB5D14C7A83AB9E886FD36DAF09E9A6AFDDC3F48AD673E6A6BF5E79F245B336709677E0C5D0FC7F9B9F4CABAA0AD10E672ABFF21721CC2DAB65C80AC9945F907031EC9D0EEE7FDE0FF2A19CE22B7DD21701B32F0D3A648F4F5303BE5E913C901027DC2153A375DE2242EC1858842D104C5D116F53BAC173CBF7B23E61396340980AE477290D1A8C35A97F564F734E2A878A27C72E1B24B135D934709528F70159C82E82095F7CC246872F6A13A1972594A6DCF2A219E8DA026C7D5112CFD5AFAB3D3282B7918D090ADCC3719BF093993F211DB5629A4DC3C9D7FAD5D5F8FB0F5242F16BEB5CF8CA88681DA3A6DDBA51CDA4A42761A6A4A72F7AA52B9FDE7EB8ADE24AE345F45EA3918D963A8A727DD39FAFCFF60243A3D63F90E9A6FEDCE4EE10CF257C939105E1EFAB1EBA2DCE8145CC7A0FF41D6BF0BA4AC0AE12478EAD06590F902106122FAA68F3C5B5962DE05D284B449FC3DE5A57B88143F079D33A751739E30C35B16DA06A633EAAA7A74E1A048F9C9B170E671BAC109EAD7F7A9B837830BBB5E6741B6F17DDBEB0C0FDD6396B46D763FFE36B3DC0737B22D83173304C5F3D80E60AE2CC1F10DBEACDCE057929085D04649B50F8A31613C6679D0D3733A46EB1A547B333694379ECF6C5DF96D757FCECFC2C1701F87FC98F0A6BC928B4AE5772466016DDAFF477BBA8C1BA039703CAEC2E532A37E3D91800141AE0166EDDE1EF740EB871471E205E1E8B4F9614B54B840C7A3C29F69A56BF09EF8C648436CC03FEA6E439C32415B0FB9923CC19905B115A2AEDC4038EFAEA98BB24382768E2D2F81CAC1502C70B2E8646089EF80AD301C3C543D9F4252B090AFDACCB843F1A9E0D0FC6213B10070BB7EB02D59816396B65BD1DF40B73A77B9335AC6F6E72FDED9B085457B0F757336BCCADEE838B199184C8A5AEAD47F52BAF7774154B1AE302C8FC69B99CB14FCD37370E258EE5B5D5C7F1420C90B0C8FB1EB25542257A685E3954147E8A93B57255388F75C71E153F62228BAC1DDF0A8A93A87E1CEA066A4EEF80A0BB41EA8E664909397BFF768A59DC5E3FE63FD320082FC6D31B2575C8D9494447B365C8808DB2D4177F597B2E38785B475FC0976CF65CD80B0FD51894256D8D8A93CE63F6A9665BDD5C3EBBF61E55B38595B63B4DF1D438981F6BCDA76C987A4B6451FF5F7769F48EDC0D998767D287016EA3ABB2CE394AFED46F60B358509A1CC64FC662F0C8A63E719401761949E3696E4CA270E113EA448047FBF545FFA17200A8F739917BB033A8477FAA49EA20A66776173EC5414B659CD3B8269E9E11D5D3C6CEF48C3C94CDD90F71A3A18D594C348DBCE9617C69D2F9B9FCBB40FD3E9E231354AEB4A15C5801E7DE1DB74CAD3DABE953D2EF6B80A1733375B02ADC4EB43F0B57627330F2DBE517E5C8464A15FB8DBEAB2AFD112285739D5D9A6A249CBE99C6EC92FD606C847F69880F7F321571CB60075277703DC56A1B10939D7284581ADAF4A488B9D0F8969723E786AC164D82590743DA47DFEE30394B058A99EA8134CDCA095677189E816C58FD4D2176585E2803CCA8342FD6A596838A71956DBD811EE155529F8BBC76753A8D1E11789AC6E3584E67253BC94D6B20A1DC5E75A664E362D01A2734ADEE8E7865D70320376B70B52E75D37237A92851F3D1EBB39F67ED950B175635CD7F7ED3BCB15D552C4C25F58A07F0634189CCCD6E51A11FBE525FDC935966E85442AEF2FF1EF9F20BF0DC1686B9D6A25C22D99E986AFD5484CD364DBAA66CDF8969009C06B7FBEF0B8A856BA96B7A503310A88361C1646AED25793C9CCAE6C6D38382E8535D792555B5A088F5689A579B2A5EB6837583798EE86D02BFFE183816472C020A328E1851DD5C152123D5B4A569D309A8DAED40CF9DB0BFC6B2BAB6987E961BF9C5E52275D8D4F10771C19DA730C98A2A7D57E11CE015284197AAEB2FF73B90FBB31B79AAF1018BDCF52E4A5C7593E97BA29A1334C2C2213B97301722BEA47E365939CA5F6D9F32A277BE9FCBB4E86D032DDAEABB8A4AAEEFAE8386314D1052E5037B2AC7CF9FB601DB9F590F6645DA205D7480BFBA02AB0D62B78578C75539DA6F42EA1F9F14C36885B1A9A34EBA97B75412690029DEB85584E47802E2A9048D94F29BC46CC1A11561A22C8FD02286E67F87A16B550232482DCE83440E3C8E99DA6FE0A53CC11DADF10C90734FA5D9DE5355EBC3FA089A8DD860350BA2D05F0595F235B8588B0F7F9F50AA0B90F6C94761A35A2300B2F01F71C6003056DE35C10AC7191C8B94A2150373605BD06B48C669DDC7AFABB41FD04C164FBB878BC247D24553F7DEB5AEA02FA7EB109E202098318F140A0A72A9D668AC50F39B0D1E0BF1F46D6F117719C1D6C70B1B455719D79604E14F53FA02F4D2625E565309439E15A04DCB3F2A682F86EC9C47BE47E0BAB83151CF3930C5406F5E1EC8E399C87A2D5207E9770F02631E2D5AE5CAC20C03B3F1E2294241007291D594D6A7ACB6F0A709964A999B34D1A603B5D1A5EE0DAB50B8B1BB51E23450BDC6DBEFCDBAAADE47B43FA1DFB0977CCFEE446C8EB1878C5B41D309850114B618F4DD10700530523F50885C9E11FA1815CBAEBA2E1AEC409F3978D7F1EB10C8A542CA1C701C16BFC61F621073D02F56CAD7F827F4D8B964FEB39BF45611ECF36AFC91F2E60F6EB3D2FD80E075FE3B8F1302AE627CA1F6CE47E7D9BD53971E3801AFC1338492E89F89546BAD2BD671A87635AE001E8FA9EFDA849451796CCC99F3753AAE323C3081C7BF062906F96C20E93ABA1BC3F4635B33258B41C0FD710BCFEF95B10F20B8FC33B317F0FE64C71842C7E378063DDD615DCE52BE74CAAD4C54AD9931BB22569680D95522BAF5EEB9B1ABA511746EFE44155B600AD4153F8CC8EE6679D1C3332C3C746A4D602626556D7B8FEBC37AA67469B697DB6BC0E1C05D2872D7BD85B9109668523A9010614EC5884E027862961DB350FB3598F8F60FD1FB2C24065FCDBF78EA7BB66C80901D4539A3AD9DDD1248D74B463962DEA1F82F0EC2AA0BAC6F8DC19CF4EE2BA54A8E00D583BF7AA766522C6AABAB86602743F14591AF3C798A361068C96E78D5164E312937B96A2E5469627FF922124304FFC82E0FFA99C8717503D59A43C59EBA36F6C5FD6239281D0792CDAF9F33004F0A39D9F09F42996B637514978075A1BC77C1C1270A533077310B175437886BB27E2C3345598D414E5067D0954F3FB2C14691006BC087F4C95A8D8E26B8D26926355DCB28B7C3A3FB946FBF3490085CAB62D6C8409D0A8C129D8EA847B5AF2FCB335502B153824F924144069F8AEA1F87A1675C6A3C9CBAEE97F384F1C61860E30FA934F363193F85CF410E9F547CC601D94B26A12C68F6BDAB0AE18314211311375A9E760E9838D50D2ADCD3D63FEFFF9F2CC8041A31ACC049CCAE065CC13446724E24E9948C6CD0DC20CBF3E5DE9C70CA308A8380E0A927B0D562683602057D17DF40F822FF38D1D3A5C1FAB863C6B30AE776F81867DDDE9D05E16C3E10C20E08832D044C6351213F14E2BF05D8BEC67C7DCE207820F843CBD6D92EE1CD7D5DD6013EAF87057C1E98C9A69E63BBD31D79C6D98F7A8A9BA3148E520AF5BA5DEBA74FB9CF897C866C547B918A339375D17A076ABF9CFD8F38CD3E4518D237CC926F5FD229A9CE88E887F53DE35CA1BA7F4DAD823605ABED7F43F1ECC4C27ED316F0ABBBAA715686BF7791A588B0D858CFA0C998DE6E6126E87AAE2080AEF3D38DE0320ED08CD6449B2D818DA997C282CAB0B49AB40ABAE1D5553C278082E4B75A56B052893D64E4CD4BA29F1AEEC6562B668D33EB4730D508E2D7B5C13478EC38E2DD6BB9CAFCE4E7A2873FEDCBA7BDE15885FB93FDFBC2573F82C849057A50F165FFC549F46FD2A6A6D83769CC428F4E70D50E12408420B6CCC59FA34A49F32CE84D39D5518B51DE378945F9A89F451223AACEB1A1BFC3C1AD1826C1BF45FF6B3F7A08E5C1E4C73FDB662891ABBDB0F4189C23F38985A20E8886974124DD64400BD87937B421CA0964640B4D819675E0B78165F1E3811AF5C0BEF729BA0552273E91056781B1802AE347A06D986343214E984AF66430F338541EEF6D80237019B54DD45C213220C2798B1BCAEB663AB28FB34B183E8D91939454DD41B211A8FF981EE6F42BA92BB266FCAF1D0FFF855F65D2B503EEEDC47F48CF647368A1D2106AA84534C2BC120B8DA93DEB48BE8A92E23C18112E07B5FC1EEE992DEE03833FD45C68688C82D7AC80E7290EABAF6D42942AD747822AF01D3A247F46CE784E6B8E6BDC3708B21E2157EA521784F875A90FD2DFBE5249062E988F5509B261C2E8742E3A213631CE6C5FC6728D6AF98795EAC79FC5D4AF99F5B910C76F27E433EF78E7EC75EE5B25183CA80C235C1B75792C106B3798606CAB6A0E58F73055AA4A51FE62766FE350BE8D4DC16A14327B2126C54508A8C0437C7D6054ECC71904CDC8F315FA2F7228CF394306DE8D988A9A032667FD0B6E713FE9D4031B3CC2AB9F754D80E18607199AC1BF7FCAD1B3A4A7754A9351147155BA225F5098955EBA13F347E295C82F564C26D3A20497AA253150CE0B271E87C2393E9E3743CDF8FA72511EDAEC295C4CB9F28B2762A4552C34F7284AC78FA6CC135FA5BF80035A4F733FDA1E7420E86266D40155BAD9C5C9B1D77735066EC5A4332B29017D9245F7E895497E82DC0452F313BB33232F6EFA9DC19A6811075F3FE77C9D773CAF154432CD0CAFDE4DD6D99BD20F28532E66D84F81CCFE99F003F63E4467AF903A6961A6C1B90F6D6A8E585BC35322E2C3415E40EABC24D4194FEAFFF41BC4DF48BF73BA1A402BAE83F01608554B79A641E695A59ECA26F2F9E5AE7E35E05338773407423E299316F2189B2D344B11594B7035F2CF720A0ECDD3FDA8A7F194697FE495BE6EBE8FDBD34F3B3609541208F31E08100C54578783446414A38ADF20C0DF6A9BF6D28631CBB49C99355FC79E3BC1F87D2D26D35D10924E968C3DBF473BC42F612C64416F6302754189541134946B4E25EE33E1403CA8936451E959E2CBB7F8D3F9F4B48F439E4BBAE0C917E50AE973ADB43A4EB4F74002DCE3DCF3A77AC96760F4CE0E2B93F6154B0DD162755349F6B572C9192674F1B050577CD83A09087E92849D12609BA6DA8A1ACAC3879AAF8C7BE0CB9C438BD103B75F86A629881ADCFDD0F4D960E9577AF659612C2AA5F700EBA0A57AADE673E4F6C4179337D9F8444C4EF80D8B051D806171F55F8EFA28FDA1F94966B8448A4D9923A96947FFEF94A4DA9F42C4452DA85BA6D913D4F44A1ADC3AB2BFCEB611FB71453C8FE21C2094762088179189CA1F74D69E3DC3E847D01A7718745AD8E5AD415EF63C4C7979D266AE699627B289C5803EE1F163A33CDFF355B8A6A331EDD5F626C5D3B10CDA262670E16F8E97589AB049CFE9707EE55F91CFE494D1A4785811EC85DAC2BB327D8C773D3AAC723F8297502CF9EABAD59734A58129CCD85ABACAC9A62A2FCD507453FE1B9D081D9EBAD3DCC19432463A9A07BA526FA2FE2A4AF7B98648EBF01062AB843F524FA4AF0B26A3CCD4650F25EF6C1B9292ED568A956FFA30F96306774B5AA31CBFF723F2A74537BB97074859A8A86B10F9FD15D724128B12FFA5F81D8E477EAF0EE831E111FCA64459476F7889A74DBCD5CE60D11D7FBCCB73A1394419A3A2B88C599BDA9DD4BAD1647497E1C80684DAA8C84C4C4592FA3B7E4F9B94C8BF4812B43F18BCCD0C47FD502CF1D64976E68CEF0DBB3A4FB1C7799FB2DADD599A6564F99A4007B7E4F9723B8031F45CA45FEC8C3C0C62DE4F9AB703FB9F3A74B637CE5EF11409A1A7D16C6AF836FB3DDB84D1569E2B71F4C1F78EF3F5D30B5BC106507781D799D26BE50BBA37AECA5767AABC85C93A22CD9505BD7B986771EA691E8A6A81694837080DF6F86BA3269D13A70C6DE7F66CD295015E9978A07AFE1CBF32DC177D4B137B5C922FAEE939708539DE33500A81511E2270B1CB536C2310D96CC3121E403794BB7A0236EF2F77F1338CFD790FC813EA8BED06BBBD7A8258974EE7038294D21BBB122C44233EFC3BA930879FD89A3342D7DD338359451B1E98017245DC6C6DE2C7035692E8AA607637B4E5F5AAC8EB73020FAB694EC95D7F2F9AF10B28D3ED04647025F9DB9DF6370966AC99785C111BE458CF5EF17A312593A46742E7A541BDA6264A383C775B1C2944C2A7F1DD3AB553191283422868F46D9AF68040661807A345595FBAF104316F6A554CDBD7ED3E6C9B85EAFC4D2ADD854490AB3D92103009E07F2339C84C6E8BFA2CF086906B1ED32D51E22C0AF8DD14ACF935BDECC1BD50DBF038283272529FFBFF65B66E909447932BA8DD64A9F52C11B93B3FF64511D24F6447ED43F242329322C9D00F41E4E26401CB0DF96485461E0D521F64B34F8D3E057B56DC465B1C0C30F7D7CECCF30B59387334019071D637DDE6C093FFFE708BA4FD41FD1678D2890D9C3E795458D635EAE898EE6A35CEF0CA4C5102D4325CBACE091EF87D7439C88CAF5FD751224B5F565DFD4608356EC4CEF14C29F997BDAD0ACC202A87569E1ADC6607ED077D08E934A824D1F2FF8A58AD548E37BE06C430AC8D2BFCC1C43392990353B7A3413CCF14DB5FE94E7B39FF88A69FA60DA675CD06F284F3AE39F17C586AA8B704B12E73FBD377FFEBBCC68504D035FE22D28A8B78B7D15F0E51A7148C1DD895E09021F2FA28D6BC9D1FA49974493C609A3D665982ED97F82BB7CC6E2326D310834F9ECD235F548B066C3B3C347EDA542266719813C1B7B2513511825167A36107579E265D92CA5AA9E82CC23EA4EEB097F57E47C26846F06669A9E919F2941DA86DDE847B5F991DFA53B99EDF6E0335A2AAB9997021D8469418D74450300EB022336326F1F2FCC97FAAFEBC54768508917BE113E84C606B1657BCAE46D2113FCBCFA23F86E834BC0AD0F3526C10CCB84DA7EA8B381DE8A8868C08F91F0C15B4B8E9A4B48EB0527B3422442E12018888854176FD11A518F9A68D1E6ED917580131D4E48F9F8ADB4154D137D6C816DB19895F980BD5655987D357A3ADEABA6FCC708E83D2A6F7B4A4CAC5B4B617CBD08084AFBC929F822912B927506B1413862136E19E4B1F6456313E09E2C77E2A2F294FA2C8393D9D1D56268F753E315CB6787F4D690A599CCAD69A20E03254EEC4120DCC5BBD9FA1B9BFA61152ECDBA6EFA122637CA170D8B97A5CE6FFBB5F9FE67FCBCC607FAE019987B3E3C95B1988D5A9E0D2C113A0DED725FB4DE1F88D7719F7B28759BD209C82F88F3112D9F700E91436FDA3E171AF99889F94917B049378CBB573EF908B9361952F9E34DBD964EBED2D71B3461283AE06430140CBE69BB1072B2143808FA08F68B2C6956363CDE679B0CB0B785F833247ACA6B986E0A0A440B9D53163916D1284652112DA322CCDC429274C2120E93469E7A7DA055C151F13AACAB5BD48039F10E5C8AED775AB004D2B8FBA4FF1F840FF6A933F0157AFDEF80F14C7462D807D71DC1BCC3480A4A3B2C74D82B5229C21F122A9683543ADDD6EA4AFC60ABC390C574F528B0FE3553783E24CD74EBAE4A000F52F039125B82C60A267C22A49E0ED9EF641A656BC235089FA431CC5CAD3F73D3E141061C4FFCFD9B3892188E66507CD4E4A9EE8E3C59B442CCF993D33EA2DF200C30FC296B2C54E97788FF7D80B0D1AF31EF0410D630D8368AF594534DD8EF20E60002F4344A170CCCAA881254DAFD98EFDFBD9BEAE01246C1F448B98D10F71D33B16EF8FE3867C12D9E0F375B8570E72C854153C0B39C8A1ACE96CDD68908C56BC890B671B0F6461316F013D391841D09D54B3C1A39FBDA74A3601D1AD2A7D1B54205096B120A61C75F714C7047A73B4409EBE83B1C03BD1C1D6816982E4C5A88E8D7181D2D945129A251D2AF32290D2B1388CAB202EC1A84F3115FDA03438970362ADC36062D831A06C18096837EE95A7D7CB201654D3CBEBB778D4AC23156A5AF79CE776EA24ED11E501DE0605EFB3011B7E09D84325252A377D614807BE6CC1E65765BCAA96C7D71AFFB39E2D5C1CDD04B627D6E51F2152BD936D38C7DB40FB718230AEF23D3B9E65C847577FA84F566F9CC595B37C9C5ECF0EE4378051D611FB01B9C18C5480FFFBE9953EAC586132333D9BA73A422E53BE7C0B1B39E1FDC0467013EC7121ED78C0025D0FEB6AF5C803D6CF5D7B1E19B196AEEB62F55C3CE85922D1B3CA6DE33359D1514FCE09E8D68697FAA28F8B8048490CCFF7AD3576082BCD14B40A4887712961F558C5B96AC0BC6ADE1D426ECB13EF8F037190A14FD6ED4DE42B5AFEFB5ACAFE7F341D9CBA96D05F2F3DB1D4F3A9F6CC106937B2E84F77BEBFEAF9DF562FFBDB73B60EF5243E7A418774DEE6E167DDCA3B1D272B61DF39B969BB09A649CDF4ABFBAC6D2871CE4FB957DC9604C02C4FC5123704E2426BA8FB863F9BE84D9C07079545CAF838D5EC19536A22620F5730340F2F4374A819F6FAD537A8083EBE04C4AF35C1EF2FD866AE5861F6F65F32AF84135BA5165B02969A1B2477F7FD75892E839DB73116B3C759EED23D923B24DE3F0CBD8AC3EA1D5C0AE507878213A05DD09FF32F985E0F5D5A8623EF639C956271511406CBF36A2454280B60C4453AA2F7E607258D71DC7DA69247C2F4E99959BD96F78B4C2D045058544BB5101AACAA55DD4F2A441C6DE3FA37E3F2FA46DADCFFA4BF4A583C670CABD8C2077059679EA22F99E6E6BB1BF0804CBDAC15430CCEF5E74D94BAD62C92EB477C9A89BD3346F8880F8CBEF8EE1BCF12941C853647E96B42087FC329BFC0CD95EE5FC2B7FE1FB6CDCEC7A4DAF73CE57A2247F5ED4583825FCC2BF03C42D98D16361D746F399C8160B5517DEBFABFE0C1E7DB86A47FA40DDD2D07C370B9ECEDB3947EDE63661B7719EC9B3EDD8EDDFA893427961C961CE611D15EA9CC5CA5A98A2BA2B5563439377D9213C4AE59D9BF504E7B7F928F24627394A3E180911D730C5E991061641C2E55717368E4741943F928E372AB1EA13B90210AEBC8C87FD17EB43DB99A3DA97B6B6AFF0491E0DC8D379CA675380C8241596B84FDD551320E36A6B7B2F737C4EC290A76D80C6D0B36840142BC475708C734BDAEFC77487334606B320784D219839182451C4990E06A8462D37445009B0C93C12AD4EDACF0C3CCD357C641D3FAB90567AD2F03D6405551F523F5436CBE231FDFBE1D8D414325A7439C3EC65C1F623E13043CC95B0A17E9A8E98174959702D599D28DF11BF8A5253212185EFF06B7C96CDA1BA0EC491C25F9468BE08E57FE0CFACC0A556C5200CA8694003097F28FDC0BA699B958127B0F980D46EDB401334799FFCE8B62B6DF617A087DCCB6A7E6126BBC9FEF59EDB9C31C2DE196DABB14F2041CCB26A1531C5141C5122476D3871DEB64964E58F8335CF62419481AABC229ED5522CF5CE87F82F989E81F5738C4C0884A43F9E92A39B6BC6A166AF1FCF93103C52556AFC17C9FEEE4C231B41746C6601FA2883FDDCF82FADEDC658C3A99502CA6C8F9D32822E7B03373F25D08D6FFB79BA119976D02F00AA0B7D846A462336591FC1245D2CCDB58BC6762FFF9C2322DC5694E95FCC3E038002FB9B736F40D2F920E7425202A7515138F137850663B06DEDA74DFA6E595C5CF0E1926B20D12DDDD4D476049349B11CB9E08F6806887C1D9FD6933537C4DAFF9916C9CE4B9F099A82B7E797E7FA82FFAE657AEE81C5F02736989D82E84F3D2E4761D546ADDC24F4DAA77F2624CB83064857155C0A9AFC9FB8BA8E87BF0B3C67B7F713253ED2E144953F16852A5FB14EA769649F33A16901E8413078FFC43AE3812046BB3A85EEEBE12F3955D168D9767052A1D5489AD1D3F0E639AC32D20A0CA5BEB08AC123AEA6711C4691A41A06FE7F891175191F75826ABC33BFAF3D2CC6152FD14EEFB3D5806E13F63FE3434D9C88E60C81FA48E9451ED84295D1175294FEA56CBCACE8FFAE0A615FEA1EF5FC33624F25D366C91141ADA522E70DD57355FE07E523EFBFFFBFAB8F1BE8EE24E49DE70367C7FEC92A5C4DB451EE42F8395B76208E0098CD23DD186E5677056B7AE6E77BEC0686273E6692173D8B7B359DA6473E544D045EB5E24CE12A43A51E2E3B602A4F734514775FECEEAFE775E9A24047E1BF2AF306CDEAA51374418AB827490ABC0374F7B1453845085C1B93A934DD057E5A51DE8F5C87A3698DA9EBAABD380493BF47AFC08DCC5454303FA96643D215A2F9F63AA572B2AA4AF0C476842C77351F4A470D785DBB4D103010ECF949BAE0C468BF496B12BADBE7EDC689B0E91544D14E09E20C69EB5968B90550E3BF4EAAFE138CB6D3F160CA26D361F35D452F7F1BAE9861DEB9F9B1F2F5C6AFCB1F24A057CEEB17CB778D6118A121399DA439316E0D25A2BBE89D71D26400AE5CBBBB5CA523473662BAFDC5AED9AC0799A14086514228B40CBF842DE95679F75A2710D0DEF046689D9B310EA23A99B8870F78D7D4435EAB2265917E3EC613CFE4F52DCEBD655B1558D9FCA42F852CB2C723BEF1734542183B2B058261ADDB569F80744395B4FF08F423772AE207C801D6C00280539E9598B283FD28B7916284F941ED8EE8505E85CD713A3ECDF322D79E92CAB499D9F0242987BC879BADC3F09FF236EBE4C7EFE0897F6F0686ECEEBEBF2F0F36BAA26E7AABB1618E23788011FFD2A3671655848B38CDA44BD9114A6A35B2F1FB30080638A547111E33B87EDB22119BEE1BA6A3EC0F2E22D2ADE4046CBDC05966BEC2BF00ACF558B546A9D1FE6CBF97BDFE030A1ABEF91C760CD91DBB287C1C9B09289592DD083369DF5578FE54C6204822DE2E56C5D278CB41370920351E058C6BE344856F3A3E377F7E140B97D223D1D41C5A3E454A613D0D1D9A6A3F0072A241B6AA18840179AE7DF78CB7EBC2EB7CC9F4E5162899863332DF680AD641E0744C45BFCD9FB780FED2A8702065E0FC7A4B291C076561186693D2F3ACC8F907E3DAC8BF5D78128B40D71128D9AA555AF8FD6C5BF03B438B9A1E078EBC2AD7DCDFD9C768DB2D059B4B826CA853B4643FE27060B63FCAB3C2FF90C45BC6DBFE81E2B2019C81F6C146A4E5A63A8F8DC58FEF5F47283B9F4DF83AC5ABD9859A14C41A1CA7CE9351E724595BDC28E6B67F6BAAACE4B3F68B6C25C96A96CCC70D5D43267EE32ED8686004FF41CB11D200C4490490952C5FDCB962323A2FA9C9CEFA1BF64E5456AED0AA2B7F9E83E535E513B6DEB94D75C0E0458794636BFC8351F34E43D41F6371C2D4B8F18576DE64E7D2E29153E7DF56E4C547DB1CF58F33256C7DDEFC29D6D0A5CE7F60848A7EB12B922BAC2ABDC7315FA48CEA71A025AB13E53B625791E871503C88EDB3855C2BE21186B76981FFD8DD50B2F051A2ED1B1AAF9BDD9C531606F10F4016D7D1F98F6F63D0F9CAB6A2ABDCA463AC933EAABE4D9B5B6FFD3C8153A1334D37F8A29426B20CCDCA4121751656EC6321E8E5BFF268D804D5488B59E05B83E55B44159EC5EBAC0F1C95317D45665C6209389F8E57019E23D3F786DF79D93ECBFA16797CCE633ACDB3CBFD48C1AEE61F0706B4076C97E0CA6F3E8B59BED9A8A090DACF3847EA9E05ACBC27D8AF3E7FFAC322A956F3B68B1A6FAB03A3144D20974CFE22BDA92DD1668F2600161A729D7C87D6E9787C8DB60F6726E7FD717A2CFB7CA24A47FED37107DE589F9E3E9BE7A4DE1E88A17A3AFB41DAFF872F770F3F0182D0ED1D19BC785C1602038D650C08B100FA076676E7F360BBE86AEC634B135159D14D831E7D6D1ACEF123E2286A06E479C042A25B7A6DE8FF815A05B4C26D35384586EC7384E03EE424FBE95BA4C172B45DB7F6DE05CA1B1D06548613FF20B36391B6E25E6208A5E7F5868208CDA3CE4DEC947A1A70DD876B82C7BDD914F7C0706786F2A5FDCE1607A90E7822A2B704EBAD8C3967D79411EAEB4A5C54F8ED9ED201159680D1B0FA9113BDD93334EF2CF39B4085907308ED7669F7C83DB2FCE7B59182310BB8F527CFDD6E470579D78CBAA23EB7F631C86F46F07BFF0DA60E0B22CF7EE9D61BDE31DC2EF247F2E7A85D9FB599AEF6C13D10E4FFA31A9B8AC8B9E93EEC2CCD426EB6DA920E778B5D69561DF0C4E036D6BE399F120EEF2D84EBD40F2F691D938426F666572E10F0960EA8D1DDE8D8483CFDED0F7ECAFF02C608C6BC81365F8E20FF71205D41E74E19B9C852DFE8F07BB02A9EDA4C69B7EF7B987E05E0A27F154CA7E97723EACBDBC148203432F0519EAABE72D5487EDEA75ECAF2EB1642EE8ABF0C66174742F8203B903649FB5BC1EFC148059349AA8B1F4847B04E23EB54A2A057DFB0A4C5EB574B8A117E3C35FFD2951789D80C58908643391CA2E1D2BD2EB1BB8B4DDE32799B951718A8ED1A6C507F582AB9E875C31982E040201008E494E13E5F59DD7F3E430687F5BA598ECEA229F7FAF6665F369ECE5793F0B3F4EDA68A9B74C0CE034519E53D41F9EE5ECB05E41105D66BC56F02D5DBEB46085DC82536270D61561F77830C9FC8BD8130F7C1AC5530C6C558C71FE7DFD791113D2FC2E22D711E43E40E621C5FDD3BDCC853C500631E0D6401BE24B51E498DE554FDE8434494464F5169ABFB55C6E9FFA50287DFB0729F01A4D40B0553D63BB9C024A36A25EC4D99C38B3FB6377A3FE3940C110468CC59177435210DDB47067DDA6309B4A5A424B70C795781E8BD599AACE6CDF13F7BB681CD6D65F66480B39E445357D2B9670DD0DD66E4C99B37923692DAD2A45DAAB59070FE6F3C290310A35371E14D7A8EA4186FF52CCE93E8414F7DCA1E36724587FBD3C7069EF73BBB318421CE42B2C84232F6592C4378FEFFCA2EC8F467329EA945A443F7F4AC1BF14037CBA08B657ACF1F3D5F8A38807C68185A944754A55DB1A07200BAD5A8F0F3D86092AF016D2361806E83131C34029372814DD6B8FC10650380F6F1E313CDF0191EDA241169065F518249249D191A313FB1E9890C149025C0DC52E986D26898B88C8AE9C2A47962FEF075C6DA20E1AC1B8EF71D3C8109740C139DBA8254F6A39A7877237842483528CAA9759A6C664F10BFF6D6AF92506D4066861F8401CDFF04E369A8A2BB6AD80E2E91139898F54E164209284F54CA8D6ECA912DBECE0344D2BF07758F0D4858E622F059ADB2C9F9F3D146B68858912590BF74C9963FA1824020100804C987421E219FA246B894041287AED1F83A1D8C1960CFFE4B1A36CED0F593355D2553EC187F6FC278BFAF210B232ABF65A8D90C65E534D7574E4AC742614625868D7224A71CD15D6F8128E67BB828FF164D0A66604964D0CBE963DAC26E25742040B4951A719078D86065330BAB271C6099717E537653E7FA2BFB89CB27B74F8DB9F3EA558B44F874E7D24CCEAB3A3307997065F31FE18A2C20C61FFC912BFECBDA13A95F4EC5435318853541A06E38A61F4455E591AE455244466F16BCAE27F0BAD07EEB0FCD8D6AC99180675188C2C6C7F1BFCE619E85C41A343177CC43D1AF05C34060EDBC23B57D0F04CAE9BACF0AD1A8FEEF8B95FC63AAB03606C20DFC6DEF54E8AA4432552F37D2590FF6EF7A8326E1A9FFE29C08DC1D5A32850E8DDCDDFCA1A66EA7F7C26979978A6B52BDB5D4FCD2F00CD9EF367D52D2D391678C43AA85C2861C2310F792199B68B321A66CEC13333F1B3F7F53CFE27FE8AA0789211621108A3A622F60B28F4ED585841E91582DF7CCA6ABB5762A7B19A1538B1A011D088E820377858184D8618DEBC95081782FC6B04982DB825BB8357B98F0C848A9BD44428DAC9DEA638AD757FFFF3EE2AE7F6D01D301FB7BBF6D7A1AADB5BC7391D73F0320A3F3D85F2183F2638BC341E9DBC983DDF0B920E8237C5614443B06FE761B141D7D83958D8D8D8D333C2C47383C13022493612DE72308A08B351075E547F4FFCF7ED12DB33E3AFD8433E43922012806FEE808E1AD2753448B483B40FEA52C3AE88642C8A43E70CBE08713AACD2664C8D7C3C75E84C481C0CE20B0A616D5E326FCF6080E3ADE264927CF67886719C97FAE34E409DAAAB42E0DDD6192D10F7E01ED95F823DFB3A45AECFF16F87F29F7858BDBCBEE0BF1169DA2A6A0B81D7B5A31E3730F3ECBDC4FB088F73D03D2B32B0A2254E38E0CAE6A8DB9A4E2C31FEFE24E54B990F75FB24CC8E10173F9C833DC16FEB9E8E9F05883E983E960F22AE033B85BED36F6EE4F269278720449EA118A6416B877914DABBB36DE58E14AB32F4FC313E5CB069E081ACCE93ABDC1FDCDD128ADE19788A55074A1B1FB9901CFC5E588EAF147ED56146D4E231DFF76B89B46A976BB4598B0A0F0E64B15833060DBA1373D66FD0915B0AB2DDA4E460CD909FC646EFDF58FDC8572537C427B9216F0C16B91F41155EBD09003F3F7E68FDB0D0BC5C042E2AA4DCC01B4A2E9A8EA715CB87BBD348BE0016DCAD1D3BA66F36AFAC6184991E3A51514B1B5AEB5B6F5FF44FEF5A85017FAC95940E2367E1A557EA7B7F61852E5089F1217C0D3311DC7A468B8FC33D3BD8646D4947A884C1CB619C823364551A3D926E13BF6904DA24A6F0688CCF970F0DC8F7EDB20B29C0CEE64D8B370B24649AEE18D48BB0213C9FFF3C0EB064FEF235E41899E4934D84234664C24A6943755F17E745C6BB0E4621FA011C8EF312FAD44095D7FB062D0D046A85D481933670C50CF595D391268E7A1C0E7945CDE2A1637ABFD2EABF49123732C474B2CDA56668176043AB78C95D7C135D3F8404E74A0C2E4801292A2D5713508064297476236641A0776DB468ECB87AAD16D6E7F40C84F2FF2EC435E2D86F1666000DDA1DED605A946BFC4B644EACC1F1FE85DCAFE8B89854754B7EFC3AEE30C9C007966B8B293D3180EBF70DBDE78E777A7166B5FE4B8A0F3A5B90ED1F314E8574CD785F737BA2E8955D3EE672BE63303445DDA120B86A01B6F8B256D479265D68FA15FAC92CF586D1FEE9DC243BFA6DE591CCE63B2E094C31475C8765BB1F989F563EEA2D07CBD2D6D43EE6DC6E65880BA726A2EBF1E57C75F1D30F4CBA17A6BB1D07C8CBE0AEF1AB216DE7DE5D0FFFDCBC01C07900E5D5A9527C60D45DFBC18418CA51436E976FCE9F5267CD78FCAB910632C820152B706253867056B875CF88F8BB6728B89F96F125BD0387DAECDA1FA70C5C8F16ED442101C0804028140702150C8239C7F6DBA12C89226FB0BFBCB74B0FE22E7DE645E371C146C847FE6C2A1CA3B0913162098AD004AC0CB1BC4B3290001765D4AF622900BE250980791FB138BBF4D1CF20691F24C5CB9F295B6B2FC3D9EBA06E0E229E6B21018976F06F61789D30E46D0AE16D0E9E269D9014865623245B0B63816F26646C04BA53FAB220B33BA4DDF1DCAC6118DB89E56B2DF0F25A863D3823D370AEC329F5278A2855B886C6CB801DA5A60EBE1ACF210F5D9D884BF6EBA30D1F79A17D4F1F929A4333FE42738EF28C579DB3E2D7FF25612FAB59BE9DF882DF7767BFF1E17E33B0AB80829508B9007BF08E5298BD098B908DD798B304ADCA14FFAAA1884015F3983A7332DDF5E3592F327444E78A7CD046FBD9D58A87DFB63351CBFC177A603A63D9AC1EDFA30D2B951B46FB131DE8CF30521EEA5DDF2657BE68B5196EE1246C13DD813C7884E0A64DDD8CDA29F64347D139B26041D106CA1ABCEDE2179C32521D683808CEB856E1FDBCCD1D48FAFC4FF1FD13C31778DB68FBB292661D0FCDEDA64006C27EE5824A6F5BD50F0B85023134C5A1528EC968A4FCF8FE5FDA3EE30A64B7F9570B73856B8D5A3E0C4B29BF51BB4C9F6D9D57B841B73BFD0EFB4FFFBFD1857B31A50CCA716827543F64EE431B8D91CA4DA28A6061A602A3E0802293607EEE4356C4E595C388238C7669ECD028BC5E6A07E8BC120910DE454060CD7B54152741FF30DB631DE3A0E6B39777D09BAEE3DD98C83E34F9D8F3847AF5E6C0DB7D90620155E1EA7690DFC91B44BE802B86C6FEE23E22C1BE42CCB5FA6D31B8B04B969BA2104778A9C4DFAC7A85F5C8465E8052234CF292BD7A40EF7E6481D27489D8BC270C267DEA636AA07D1E7774930A0E7845ED855EA57F919477149F54D6976FEA8A6506F5303A7E4B8EF1C53BCD75788D44359508D073FC0837AD059ED7025F98A56B272285B0DAEC40367D0FBFC9DBFE5FB6A6C4090CF1078D9FD1AB6BC9A196C4DF34EFE2095C0632D0459F73454B5CACA8C4E4A2EAB82285253FCE6B7CFBF2D1A64CE00437480A3F6DEBD4ACCC44F4F708252A492C78644EC582DB0769D87F6F94F03223A124F375C16080E0402814020301EF4118C158DF0D7C2451FAD1597C1F1378219C14CC9FF0C63A0500D96E3A830F7083865BAADCE90B3198C21C23EFA2148E37B9660862B46ACCA29B017F35F2D82E347CB9D6B1022EB3F6E8C02B72650AF2215679A1CA487A57E16042DA025EED20EE42EAFAFF2119D4EC268D21733945355017764C41F7F83A6AC1293A4F1221550A1A2D392BFC6BED32B5947A3FE27FFF0111DD60E4BF39551C8F61BB045D8440B6AE96A13D80EE8FBDFCF6F9AE42A62E2CBD7A2FE4C2BD7AF15824CA6AC5DE585C3EFB47896A43A62AC6A71C2CC006F1DB9048001B8A3D6829E5148A393FF3E507C743130CE9EE77AD6F9D26E62B68DFFEB7FDF1A26A03ACE8F2385203D752CD32E9B97209DBBC1F1BF25502345D9BFC2B43D3013AEA631B7A3F67247BD5699A4F1B2DB3F70867570D7FB60070ADE66100461B34C6251066C08E605CC3D9C6F06DC74A9F132633D21FB9D5E0ACA6F0FF53BCDDA57C7F992FDDF9643BD06DC2FA96EC24577F31766FFEA0065C08EA49C4C3AD0AD47C51C7F76F133BC1A2CF0BF6BD3433E9B06B9FDB1C4782CAB73BE9033523F558F3B4941D97FB09FEA63F7198C50BED3EF7EB8640921413141E3A7B30E5B703E737E36219585EF2B7F18D5B70276CD136CAD433D22D7C14599D12ECF62F974C36B9B2591BBBDCFF8F80C5720103208FFDB1FBB1DCF87C51EEB7610DA5C18BE457B8367EFA45C3564C51A928FD0EF3726D31546B70AF750428DAB5E6750518017C93481D3645C1C430970034F770C4AA3D2AEFCEA43AC8FDED468F7EE75261BC21ACF42E25E4A972EAD67B9758F3007B3548F41AE75734E210894810142448765106480E69A323A22D0B034E10C6A880318F0A37F75D7341F46349F07DC5BC3466FD766EBA7E9F0B7D77F76A0AD3D696102813E2B325664B6F972FF55A37EA2151BE1479C1AE9FE9C3F9390D72FC792EB3380A5C25AF2866704F05CD3267797E098F1D045A47F773B8584EA790F146C0AF3DEB00E8DCE4773E60E0308088CD163F0A9712DE56D49A26348AA63FAD1C59FA52D0104BE59A444180403EFE238E23B228565CDBAC7E64FB2BE6489A9B2BEFC20A1FAA06D82DE8AAFD7A800A23646ECD64F4E63532BB1132E1BE5A3A7CF4113AFB2C77715E8FC1DF64F83753677D13FE8C34E34C25FCBF38F35E06D40C06010C32D76760936D6B30433AC33622D06767B7FB5088A23B0D6331012D87EFFB7B6543FB0750EFF068205D7DB7323266BF1C3D691FF3091737FE4494D3F666AEB0A9B01689A892F80AF1DD61EFBFFF33F1991CFA7085A745CCE5D962E96F3CD9E5B72FD1C6766DE32167CE66B777F0E78AE701A27C5DC26E351A066A3FC0F53F46FC068FF2C39B6FCD9349FEA9CF8B920044CF40535E7A10916FEB7270127593C5CB2932A4AE504FC5830660434219ABF7C679BB59B2A7284F34FEC22AB58378EAB01D6F9CA05D404044FAF87FDF8FD4FCC7586455990412A6759ED0134B11151FBB7B2004FC5EAE46A1AB92B93F6EF91D117A065D0643C92A7F180C130E6132EA763FA4ED0CF3FA2835AD8240F6AF4CE327F77C7EB2B342297CC8DA8CB390D8BE620644713BEF939E58CFC5FD96CA1351790D7FC17A626EF8FCCD0DD6B92D014FF4D0B7091FBE237FA337CF43B815E5585C3A80AF80B84699FC921F9A9882DBE06E9F89E98C182FFC081742F0DA29EBACD4640C5AED230B3BDF9D009415E15B693C3006E1E74FD48FD8B52D1F5024A50AACA6FF75D1333A98BF75726000CA8544280CFFE513027125F17FDC526B8ACF2F00B33B2CA47608C9EFE2942D5830E808BD76AB2CB72C2756D294728CBE5EE7B1E37BE2B21E8D19641890F4B6BAFB8E5E74B9D652F7C467F8202703656FD65414C247806F64130B08D7764E275151F27E9CACD56D55463BC466AE86CC42516DC89FCF8F569422303F07F54409BB2F07044CAF9BE6FF8338AFD222C24AEC5E14BC2ACB2F3B3EED1BC6A37E41A742CB486D4F6579DC3F712296260D928C551AAF0551A06C13ACE49680EDCD1D5DE9B37F170D2D83D5AF5906E30B481EB2EC3F03AC2F12467AB7E5E3ACA4FA0E6DC968CA61F87C25C217D32E1E8E09CC971FF9DD4D5DD8F562789937ABA1FA85E433B04B5F5BB2A06C1C0D47A07A236D820454226299F1F9B6B933D037A3F13ED479B54B0F294793AF519B066CC4B4F2FBC7F2674F7CAA9BF9E9B15F9793281F867BF6481D99DD9F455612DBAAE917F2D4A0C4A4F4E54B0EA2CCAC7EA8AF8ECAC8958E062DDAB5FA9EE81C1AF7FDDEF285778C7FD7D525B7CC95C315FE5DBF4634911F5FC3FCE883B14811C3E129ED3618EC7815BF9CE55D47AE14A03B00E66D4C7CFE27FCCAD8A5F646F4004ABAD5D7E9CC4A9D410DF70C6101AAD7A56E79A751B789801F85C20FA5A837B6FA2B69902180863814A1229E88119D597D980F9F5869D5E732ACF9C0C1FFD2086CCDE4E9E40854FD5809F2EBBC7EC6DDB4CEC71085E528DFEEB164FC5C0FAC8CF8203693FFC2CB4D21547FCC8047D7EFC435699F0C5586244023725FFE120117D55D997EDC133EA9D652C83AEF76DA61742E9A55B05B8A5C0CAA12EB6F6E9F158E440355038DAF441304020656029D233116C3AE928753127F68846241FAB9ED5CB91E420AE60D4A1F41750916EC2AEA864A8BCDE460159DCD5CB5E257CF78CF078E824358A7830AE284D002720D16AF07F11CA1CEFCC2D8B3BE89FDC96DECF81C8D151F5AF99F7637C95F1CAFEC47ECB17947F6170E27DA84197A193F69065C3B1AD63E69EE173094BD847076EFF2B6E66775F40268F9BFF341D58E914BF3F1B27C81EFAFD291363FA3E105CE1C92E3C915E89878F84F873FE23C4EBE208B965CBFD966801D989904F4594312D4044F45DA3B71C7F49838807F1D0A7E41E274FEF767997CC319B5B1D476E754FC652DB40CCD52E8FD1F43F7F9096A0F33CA8DFFA137F1809E658458D283B3EBDCA2FBE23EF00386580054186D68D9FE7C0BB32C0BB2092B7FE5DF4E76F52A162225BC27F5EA93D4B68421FC1AA86ADC777577F38BB06E15AE81775A4699FCA58F07491E358F8C3F2251EE0EC7175A64E73076CE5931A65B66043FE5B653EC80F1F28D9153A4812E0E9F550E66C5E4A50F049B60400C3D8B98C42CCC68E9D749E909CC23FDF5AC8851F2FAE7A5D2BFE054F96119D84C1230A5BC3928F705C1D436329C5FA197AA2BF5254FEEA6465D0C790E2DAF101BCD057F9FF84AE889220D290F6796773DE30B1CED9C6768CE614E508E8292D0F2283A53CA08F5A01C798C754C1FC15FD5031C86470EA70CB231B91910C9097AE35448DD20C3C9DB5D8E60A652E1EBB1B8B4B358001E6D4E386420FD6313F5C0B973CE452F76FA54CACD9EB8735FE77DC47313D2B9700976AD1EDA71DF3F7256D224B3622BDFAA6F47FFBA86905F98E7BC2F9B1EE63F74062BED526AFB73EE530BCD4B2A54D995DEA6E57158D1DE85950EB8622ADF0EB0969845776F80B8A1C6C9C738278F977953A7F15B25B5DF2BE82CA07D90D078BED4F905F867559A74A04CA4B279CC91FA63CBA853ED150FC9EC1E403E0952724A99863959F07A982713F663612F879085369C2B163345078645646840055A63336C22EA5D81EA1C3A80630D04B31E48FC5C5789497FF4F319FE9E7804AD8E9EE7CCDD730E5F2452B9CCE3709C0890ADDB96E2B632B6C00999106367276205C50BBC120394EF5EC33F2800DE34040771F1353092815BCE3C59FF03DF24877DA736DA75D7EF048FABC5AC7DC2BCA46466AA9D7E9C8B8ECB002E67C177C1679ADAC215445A28E301D0A0A79F1205204ED240B70757FCD122B3916763D82ECFCDB94DD75A7E831BEF048B62E76A2A2F43ED6F0CCDDA92A2D7B65A2246676094B4F74FDAA767122348482268F03F30FC87E0D326A7B0345EE5F8EA34151CB0479EE9A209D161343356B8BCC701A2D9C7BC09761DBB917BF85FE59340581E94FE199CCC428BE1A8F385D9629A908ED8D6F86DDE0DECB338F7068398C76267480E19838F31509E7B8D9E01E0BBBEC5DBEDF2A5E61E817C81F06E56158ADFC127B74DF96979A8EA090F7355AEB0EE5F249EA4B0275F562F843BD1B8026F82A27379AF255A6F5B34AE4884276C68E29C38BCF0FD0BDCDDA573F494B44F0D49A980DEE8F0A9EEC92EAAFD2CAC00D749B1B7F7C3B63C3CFEF4CD2B1BD54A2E46FC847B0037176FED89A6A7E92411143DA1AA7E036D18403691E0D250A6A015D3166BA713443F4D9D0576F8D03C43602C7E343E102D5F28510BB51833BD2BF69615BE219E27FE77A734D75D849EA46B04A5AF36AA7CE07AD0FB4827699338424FB9ED4A5D84AD5DAC634A7F470FBCFC63C7F3CE1C8DF9F773C699FE9A147C5786DB6E73FACAE8A0672186279BFAFE7739E20721D31553CB5162BFD22A21323CD0D2ACF049C437C725AC0207C164EDE0B6B7CC80B0387F8D83B3CE4E76130D1B072170FB0D33C18B237EA503B8321CB0A04909D578F37587ED0FFA00A7836D8EEEF280F456FA9E4E5CCAAA6E32FCD1D11EE42FD215D3160F20721FF7EF8C1A2AB671901A1035F642C6FC4EC2A5C9D5EAFF512F8F9E826CE1FEB846C6AC2E7C92AA079C6AE615DF405C1950C45965942D64DE31FF165C0190D96DEAF22B3E13A13804AFC0423CBEFC5B070050A0ACAD871F1F1CA0A0AC9F00809C8F10ADB0A71F10BCB090809D9DAF0F0F2C8D9F0F109C8710996F4888B41302032377FBB9F6AD2F1416DC3914119A077CCDD17AC500BA21787B27DB06AC2BB06C4D0599A7BE0365655029C66FE5A7F7CC120E990F4FA00EF7530BFDD5BFEA67BC14AB8D5D8144E4011D1E1A9071EDBE17A6D2A9EE48391343E2B613764D8C973297AEB8D9893DB1C81B6F1396553F861191CB5393542B34FBDA4D6B8ACAB68C674F01581F18A469E4C590BDF9636758611514740768DF713DA81CA6C624FBDA6CCB49426DCC24BB8EC6132820D15F716F269F077E7CB441CAFF6C76E6B4AD5E320DD18EC557415A8987388C47E5162731EFF8BE5E71A7EA32AD3C99CE2117EAA0B4FC2B3C5059C7B7569BC2A478CC1B367B3F636744935D62046F4021E1C83825B87A22E832A06C1C09736AEF5CC67E58B31A76AB2269D3AB9FCF56F5BAD15C233BB2C0F5A0BEC97FA80A34EC7D651134EF82725CD1BF25F1F4A69EADFE52EDD8D9769B15D63ADCDFE6D025D76E62435EB88421F27B2BD68DEFB1F06837ABF5897A69867089C906D8A55EC5FF676972619162F3C331C8F5F5958026CE0BB55FBA65F3F46321FB68FC3B70C3F2389E80FEAF24C69A61FF7F1B291A000, afterDelayedMessagesRead=692571, gasRefunder=0xe64a54E2533Fd126C2E452c5fAb544d80E2E4eb5, prevMessageCount=51384750, newMessageCount=51384995 )
TransparentUpgradeableProxy.STATICCALL( )
-
Bridge.DELEGATECALL( )
-
TransparentUpgradeableProxy.86598a56( )
-
Bridge.enqueueSequencerMessage( dataHash=66653C8669E2E090297F73A4C844ADB9B506FEEE82971881A69C5E5BB59343B4, afterDelayedMessagesRead=692571, prevMessageCount=51384750, newMessageCount=51384995 ) => ( seqMessageIndex=117750, beforeAcc=A92ADF543B5B428211652F7A9C7EC682D13F0B02FC44EA45E3CC3A651C19DA04, delayedAcc=540EE91EED6386657F901EEA3F6D2BE2F1E69DCC2BDA93C553D4C8F90B9E47B4, acc=EF682736DD2471124DD036EED7D486791FA66D7D852590C82C18C85676DA5BC9 )
-
TransparentUpgradeableProxy.7a88b107( )
-
Bridge.submitBatchSpendingReport( sender=0xC1b634853Cb333D3aD8663715b08f41A3Aec47cc, messageDataHash=86C9604FE406F17AB98AD81DE321E1DC23B9091CF7CC08CD432208340AA8A3D6 ) => ( 692619 )
-
GasRefunder.onGasSpent( refundee=0xC1b634853Cb333D3aD8663715b08f41A3Aec47cc, gasUsed=205614, calldataSize=97220 ) => ( success=True )
- ETH 0.042462801423434859
Arbitrum: Batch Submitter.CALL( )
- ETH 0.042462801423434859
addSequencerL2BatchFromOrigin[SequencerInbox (ln:154)]
NotOrigin[SequencerInbox (ln:161)]
NotBatchPoster[SequencerInbox (ln:162)]
formDataHash[SequencerInbox (ln:163)]
packHeader[SequencerInbox (ln:318)]
getTimeBounds[SequencerInbox (ln:300)]
concat[SequencerInbox (ln:319)]
addSequencerL2BatchImpl[SequencerInbox (ln:172)]
DelayedBackwards[SequencerInbox (ln:345)]
delayedMessageCount[SequencerInbox (ln:346)]
DelayedTooFar[SequencerInbox (ln:346)]
enqueueSequencerMessage[SequencerInbox (ln:347)]
submitBatchSpendingReport[SequencerInbox (ln:365)]
InboxMessageDelivered[SequencerInbox (ln:370)]
BadSequencerNumber[SequencerInbox (ln:174)]
SequencerBatchDelivered[SequencerInbox (ln:175)]
File 1 of 5: TransparentUpgradeableProxy
File 2 of 5: TransparentUpgradeableProxy
File 3 of 5: GasRefunder
File 4 of 5: SequencerInbox
File 5 of 5: Bridge
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol) pragma solidity ^0.8.0; import "../ERC1967/ERC1967Proxy.sol"; /** * @dev This contract implements a proxy that is upgradeable by an admin. * * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector * clashing], which can potentially be used in an attack, this contract uses the * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two * things that go hand in hand: * * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if * that call matches one of the admin functions exposed by the proxy itself. * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the * implementation. If the admin tries to call a function on the implementation it will fail with an error that says * "admin cannot fallback to proxy target". * * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due * to sudden errors when trying to call a function from the proxy implementation. * * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy. */ contract TransparentUpgradeableProxy is ERC1967Proxy { /** * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. */ constructor( address _logic, address admin_, bytes memory _data ) payable ERC1967Proxy(_logic, _data) { assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)); _changeAdmin(admin_); } /** * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. */ modifier ifAdmin() { if (msg.sender == _getAdmin()) { _; } else { _fallback(); } } /** * @dev Returns the current admin. * * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` */ function admin() external ifAdmin returns (address admin_) { admin_ = _getAdmin(); } /** * @dev Returns the current implementation. * * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` */ function implementation() external ifAdmin returns (address implementation_) { implementation_ = _implementation(); } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. * * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}. */ function changeAdmin(address newAdmin) external virtual ifAdmin { _changeAdmin(newAdmin); } /** * @dev Upgrade the implementation of the proxy. * * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}. */ function upgradeTo(address newImplementation) external ifAdmin { _upgradeToAndCall(newImplementation, bytes(""), false); } /** * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the * proxied contract. * * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}. */ function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin { _upgradeToAndCall(newImplementation, data, true); } /** * @dev Returns the current admin. */ function _admin() internal view virtual returns (address) { return _getAdmin(); } /** * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}. */ function _beforeFallback() internal virtual override { require(msg.sender != _getAdmin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target"); super._beforeFallback(); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol) pragma solidity ^0.8.0; import "../Proxy.sol"; import "./ERC1967Upgrade.sol"; /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. */ contract ERC1967Proxy is Proxy, ERC1967Upgrade { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. * * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded * function call, and allows initializating the storage of the proxy like a Solidity constructor. */ constructor(address _logic, bytes memory _data) payable { assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)); _upgradeToAndCall(_logic, _data, false); } /** * @dev Returns the current implementation address. */ function _implementation() internal view virtual override returns (address impl) { return ERC1967Upgrade._getImplementation(); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overriden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967Upgrade { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly { r.slot := slot } } }
File 2 of 5: TransparentUpgradeableProxy
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol) pragma solidity ^0.8.0; import "../ERC1967/ERC1967Proxy.sol"; /** * @dev This contract implements a proxy that is upgradeable by an admin. * * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector * clashing], which can potentially be used in an attack, this contract uses the * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two * things that go hand in hand: * * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if * that call matches one of the admin functions exposed by the proxy itself. * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the * implementation. If the admin tries to call a function on the implementation it will fail with an error that says * "admin cannot fallback to proxy target". * * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due * to sudden errors when trying to call a function from the proxy implementation. * * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy. */ contract TransparentUpgradeableProxy is ERC1967Proxy { /** * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. */ constructor( address _logic, address admin_, bytes memory _data ) payable ERC1967Proxy(_logic, _data) { assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)); _changeAdmin(admin_); } /** * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. */ modifier ifAdmin() { if (msg.sender == _getAdmin()) { _; } else { _fallback(); } } /** * @dev Returns the current admin. * * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` */ function admin() external ifAdmin returns (address admin_) { admin_ = _getAdmin(); } /** * @dev Returns the current implementation. * * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` */ function implementation() external ifAdmin returns (address implementation_) { implementation_ = _implementation(); } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. * * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}. */ function changeAdmin(address newAdmin) external virtual ifAdmin { _changeAdmin(newAdmin); } /** * @dev Upgrade the implementation of the proxy. * * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}. */ function upgradeTo(address newImplementation) external ifAdmin { _upgradeToAndCall(newImplementation, bytes(""), false); } /** * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the * proxied contract. * * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}. */ function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin { _upgradeToAndCall(newImplementation, data, true); } /** * @dev Returns the current admin. */ function _admin() internal view virtual returns (address) { return _getAdmin(); } /** * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}. */ function _beforeFallback() internal virtual override { require(msg.sender != _getAdmin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target"); super._beforeFallback(); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol) pragma solidity ^0.8.0; import "../Proxy.sol"; import "./ERC1967Upgrade.sol"; /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. */ contract ERC1967Proxy is Proxy, ERC1967Upgrade { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. * * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded * function call, and allows initializating the storage of the proxy like a Solidity constructor. */ constructor(address _logic, bytes memory _data) payable { assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)); _upgradeToAndCall(_logic, _data, false); } /** * @dev Returns the current implementation address. */ function _implementation() internal view virtual override returns (address impl) { return ERC1967Upgrade._getImplementation(); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overriden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967Upgrade { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly { r.slot := slot } } }
File 3 of 5: GasRefunder
// SPDX-License-Identifier: Apache-2.0 /* * Copyright 2021, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ pragma solidity ^0.8.7; import "./IGasRefunder.sol"; import "@openzeppelin/contracts-0.8/access/Ownable.sol"; contract GasRefunder is IGasRefunder, Ownable { mapping(address => bool) public allowedContracts; mapping(address => bool) public allowedRefundees; address public disallower; struct CommonParameters { uint128 maxRefundeeBalance; uint32 extraGasMargin; uint8 calldataCost; uint64 maxGasTip; uint64 maxGasCost; uint32 maxSingleGasUsage; } CommonParameters public commonParams; enum CommonParameterKey { MAX_REFUNDEE_BALANCE, EXTRA_GAS_MARGIN, CALLDATA_COST, MAX_GAS_TIP, MAX_GAS_COST, MAX_SINGLE_GAS_USAGE } enum RefundDenyReason { CONTRACT_NOT_ALLOWED, REFUNDEE_NOT_ALLOWED, REFUNDEE_ABOVE_MAX_BALANCE, OUT_OF_FUNDS } event RefundedGasCosts( address indexed refundee, address indexed contractAddress, bool indexed success, uint256 gas, uint256 gasPrice, uint256 amountPaid ); event RefundGasCostsDenied( address indexed refundee, address indexed contractAddress, RefundDenyReason indexed reason, uint256 gas ); event Deposited(address sender, uint256 amount); event Withdrawn(address initiator, address destination, uint256 amount); event ContractAllowedSet(address indexed addr, bool indexed allowed); event RefundeeAllowedSet(address indexed addr, bool indexed allowed); event DisallowerSet(address indexed addr); event CommonParameterSet(CommonParameterKey indexed parameter, uint256 value); constructor() Ownable() { commonParams = CommonParameters({ maxRefundeeBalance: 0, // no limit extraGasMargin: 4000, // 4k gas calldataCost: 12, // Between 4 for zero bytes and 16 for non-zero bytes maxGasTip: 2 gwei, maxGasCost: 120 gwei, maxSingleGasUsage: 2e6 // 2 million gas }); } function setDisallower(address addr) external onlyOwner { disallower = addr; emit DisallowerSet(addr); } function allowContracts(address[] calldata addresses) external onlyOwner { setContractsAllowedImpl(addresses, true); } function disallowContracts(address[] calldata addresses) external { require(msg.sender == owner() || msg.sender == disallower, "NOT_AUTHORIZED"); setContractsAllowedImpl(addresses, false); } function setContractsAllowedImpl(address[] calldata addresses, bool allow) internal { for (uint256 i = 0; i < addresses.length; i++) { address addr = addresses[i]; allowedContracts[addr] = allow; emit ContractAllowedSet(addr, allow); } } function allowRefundees(address[] calldata addresses) external onlyOwner { setRefundeesAllowedImpl(addresses, true); } function disallowRefundees(address[] calldata addresses) external { require(msg.sender == owner() || msg.sender == disallower, "NOT_AUTHORIZED"); setRefundeesAllowedImpl(addresses, false); } function setRefundeesAllowedImpl(address[] calldata addresses, bool allow) internal { for (uint256 i = 0; i < addresses.length; i++) { address addr = addresses[i]; allowedRefundees[addr] = allow; emit RefundeeAllowedSet(addr, allow); } } function setMaxRefundeeBalance(uint128 newValue) external onlyOwner { commonParams.maxRefundeeBalance = newValue; emit CommonParameterSet(CommonParameterKey.MAX_REFUNDEE_BALANCE, newValue); } function setExtraGasMargin(uint32 newValue) external onlyOwner { commonParams.extraGasMargin = newValue; emit CommonParameterSet(CommonParameterKey.EXTRA_GAS_MARGIN, newValue); } function setCalldataCost(uint8 newValue) external onlyOwner { commonParams.calldataCost = newValue; emit CommonParameterSet(CommonParameterKey.CALLDATA_COST, newValue); } function setMaxGasTip(uint64 newValue) external onlyOwner { commonParams.maxGasTip = newValue; emit CommonParameterSet(CommonParameterKey.MAX_GAS_TIP, newValue); } function setMaxGasCost(uint64 newValue) external onlyOwner { commonParams.maxGasCost = newValue; emit CommonParameterSet(CommonParameterKey.MAX_GAS_COST, newValue); } function setMaxSingleGasUsage(uint32 newValue) external onlyOwner { commonParams.maxSingleGasUsage = newValue; emit CommonParameterSet(CommonParameterKey.MAX_SINGLE_GAS_USAGE, newValue); } receive() external payable { emit Deposited(msg.sender, msg.value); } function withdraw(address payable destination, uint256 amount) external onlyOwner { // It's expected that destination is an EOA (bool success, ) = destination.call{ value: amount }(""); require(success, "WITHDRAW_FAILED"); emit Withdrawn(msg.sender, destination, amount); } function onGasSpent( address payable refundee, uint256 gasUsed, uint256 calldataSize ) external override returns (bool success) { uint256 startGasLeft = gasleft(); uint256 ownBalance = address(this).balance; if (ownBalance == 0) { emit RefundGasCostsDenied(refundee, msg.sender, RefundDenyReason.OUT_OF_FUNDS, gasUsed); return false; } if (!allowedContracts[msg.sender]) { emit RefundGasCostsDenied( refundee, msg.sender, RefundDenyReason.CONTRACT_NOT_ALLOWED, gasUsed ); return false; } if (!allowedRefundees[refundee]) { emit RefundGasCostsDenied( refundee, msg.sender, RefundDenyReason.REFUNDEE_NOT_ALLOWED, gasUsed ); return false; } uint256 estGasPrice = block.basefee + commonParams.maxGasTip; if (tx.gasprice < estGasPrice) { estGasPrice = tx.gasprice; } if (commonParams.maxGasCost != 0 && estGasPrice > commonParams.maxGasCost) { estGasPrice = commonParams.maxGasCost; } // Retrieve these variables before measuring gasleft() uint256 refundeeBalance = refundee.balance; uint256 maxRefundeeBalance = commonParams.maxRefundeeBalance; uint256 maxSingleGasUsage = commonParams.maxSingleGasUsage; // Add in a bit of a buffer for the tx costs not measured with gasleft gasUsed += startGasLeft + commonParams.extraGasMargin + (calldataSize * commonParams.calldataCost); // Split this up into two statements so that gasleft() comes after the storage loads gasUsed -= gasleft(); if (maxSingleGasUsage != 0 && gasUsed > maxSingleGasUsage) { gasUsed = maxSingleGasUsage; } uint256 refundAmount = estGasPrice * gasUsed; if (maxRefundeeBalance != 0 && refundeeBalance + refundAmount > maxRefundeeBalance) { if (refundeeBalance > maxRefundeeBalance) { // The refundee is already above their max balance emit RefundGasCostsDenied( refundee, msg.sender, RefundDenyReason.REFUNDEE_ABOVE_MAX_BALANCE, gasUsed ); return false; } else { refundAmount = maxRefundeeBalance - refundeeBalance; } } if (refundAmount > ownBalance) { refundAmount = ownBalance; } // It's expected that refundee is an EOA (success, ) = refundee.call{ value: refundAmount }(""); emit RefundedGasCosts(refundee, msg.sender, success, gasUsed, estGasPrice, refundAmount); } } // SPDX-License-Identifier: Apache-2.0 /* * Copyright 2021, Offchain Labs, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ pragma solidity >=0.6.11 <0.7.0 || >=0.8.7 <0.9.0; interface IGasRefunder { function onGasSpent( address payable spender, uint256 gasUsed, uint256 calldataSize ) external returns (bool success); } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
File 4 of 5: SequencerInbox
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import { AlreadyInit, HadZeroInit, NotOrigin, DataTooLarge, NotRollup, DelayedBackwards, DelayedTooFar, ForceIncludeBlockTooSoon, ForceIncludeTimeTooSoon, IncorrectMessagePreimage, NotBatchPoster, BadSequencerNumber, DataNotAuthenticated, AlreadyValidDASKeyset, NoSuchKeyset, NotForked } from "../libraries/Error.sol"; import "./IBridge.sol"; import "./IInbox.sol"; import "./ISequencerInbox.sol"; import "../rollup/IRollupLogic.sol"; import "./Messages.sol"; import {L1MessageType_batchPostingReport} from "../libraries/MessageTypes.sol"; import {GasRefundEnabled, IGasRefunder} from "../libraries/IGasRefunder.sol"; import "../libraries/DelegateCallAware.sol"; import {MAX_DATA_SIZE} from "../libraries/Constants.sol"; /** * @title Accepts batches from the sequencer and adds them to the rollup inbox. * @notice Contains the inbox accumulator which is the ordering of all data and transactions to be processed by the rollup. * As part of submitting a batch the sequencer is also expected to include items enqueued * in the delayed inbox (Bridge.sol). If items in the delayed inbox are not included by a * sequencer within a time limit they can be force included into the rollup inbox by anyone. */ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox { uint256 public totalDelayedMessagesRead; IBridge public bridge; /// @inheritdoc ISequencerInbox uint256 public constant HEADER_LENGTH = 40; /// @inheritdoc ISequencerInbox bytes1 public constant DATA_AUTHENTICATED_FLAG = 0x40; IOwnable public rollup; mapping(address => bool) public isBatchPoster; ISequencerInbox.MaxTimeVariation public maxTimeVariation; mapping(bytes32 => DasKeySetInfo) public dasKeySetInfo; modifier onlyRollupOwner() { if (msg.sender != rollup.owner()) revert NotOwner(msg.sender, address(rollup)); _; } uint256 internal immutable deployTimeChainId = block.chainid; function _chainIdChanged() internal view returns (bool) { return deployTimeChainId != block.chainid; } function initialize( IBridge bridge_, ISequencerInbox.MaxTimeVariation calldata maxTimeVariation_ ) external onlyDelegated { if (bridge != IBridge(address(0))) revert AlreadyInit(); if (bridge_ == IBridge(address(0))) revert HadZeroInit(); bridge = bridge_; rollup = bridge_.rollup(); maxTimeVariation = maxTimeVariation_; } function getTimeBounds() internal view virtual returns (TimeBounds memory) { TimeBounds memory bounds; if (block.timestamp > maxTimeVariation.delaySeconds) { bounds.minTimestamp = uint64(block.timestamp - maxTimeVariation.delaySeconds); } bounds.maxTimestamp = uint64(block.timestamp + maxTimeVariation.futureSeconds); if (block.number > maxTimeVariation.delayBlocks) { bounds.minBlockNumber = uint64(block.number - maxTimeVariation.delayBlocks); } bounds.maxBlockNumber = uint64(block.number + maxTimeVariation.futureBlocks); return bounds; } /// @inheritdoc ISequencerInbox function removeDelayAfterFork() external { if (!_chainIdChanged()) revert NotForked(); maxTimeVariation = ISequencerInbox.MaxTimeVariation({ delayBlocks: 1, futureBlocks: 1, delaySeconds: 1, futureSeconds: 1 }); } /// @inheritdoc ISequencerInbox function forceInclusion( uint256 _totalDelayedMessagesRead, uint8 kind, uint64[2] calldata l1BlockAndTime, uint256 baseFeeL1, address sender, bytes32 messageDataHash ) external { if (_totalDelayedMessagesRead <= totalDelayedMessagesRead) revert DelayedBackwards(); bytes32 messageHash = Messages.messageHash( kind, sender, l1BlockAndTime[0], l1BlockAndTime[1], _totalDelayedMessagesRead - 1, baseFeeL1, messageDataHash ); // Can only force-include after the Sequencer-only window has expired. if (l1BlockAndTime[0] + maxTimeVariation.delayBlocks >= block.number) revert ForceIncludeBlockTooSoon(); if (l1BlockAndTime[1] + maxTimeVariation.delaySeconds >= block.timestamp) revert ForceIncludeTimeTooSoon(); // Verify that message hash represents the last message sequence of delayed message to be included bytes32 prevDelayedAcc = 0; if (_totalDelayedMessagesRead > 1) { prevDelayedAcc = bridge.delayedInboxAccs(_totalDelayedMessagesRead - 2); } if ( bridge.delayedInboxAccs(_totalDelayedMessagesRead - 1) != Messages.accumulateInboxMessage(prevDelayedAcc, messageHash) ) revert IncorrectMessagePreimage(); (bytes32 dataHash, TimeBounds memory timeBounds) = formEmptyDataHash( _totalDelayedMessagesRead ); uint256 __totalDelayedMessagesRead = _totalDelayedMessagesRead; uint256 prevSeqMsgCount = bridge.sequencerReportedSubMessageCount(); uint256 newSeqMsgCount = prevSeqMsgCount + _totalDelayedMessagesRead - totalDelayedMessagesRead; ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc ) = addSequencerL2BatchImpl( dataHash, __totalDelayedMessagesRead, 0, prevSeqMsgCount, newSeqMsgCount ); emit SequencerBatchDelivered( seqMessageIndex, beforeAcc, afterAcc, delayedAcc, totalDelayedMessagesRead, timeBounds, BatchDataLocation.NoData ); } /// @dev Deprecated in favor of the variant specifying message counts for consistency function addSequencerL2BatchFromOrigin( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder ) external refundsGas(gasRefunder) { // solhint-disable-next-line avoid-tx-origin if (msg.sender != tx.origin) revert NotOrigin(); if (!isBatchPoster[msg.sender]) revert NotBatchPoster(); (bytes32 dataHash, TimeBounds memory timeBounds) = formDataHash( data, afterDelayedMessagesRead ); ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc ) = addSequencerL2BatchImpl(dataHash, afterDelayedMessagesRead, data.length, 0, 0); if (seqMessageIndex != sequenceNumber) revert BadSequencerNumber(seqMessageIndex, sequenceNumber); emit SequencerBatchDelivered( sequenceNumber, beforeAcc, afterAcc, delayedAcc, totalDelayedMessagesRead, timeBounds, BatchDataLocation.TxInput ); } function addSequencerL2BatchFromOrigin( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder, uint256 prevMessageCount, uint256 newMessageCount ) external refundsGas(gasRefunder) { // solhint-disable-next-line avoid-tx-origin if (msg.sender != tx.origin) revert NotOrigin(); if (!isBatchPoster[msg.sender]) revert NotBatchPoster(); (bytes32 dataHash, TimeBounds memory timeBounds) = formDataHash( data, afterDelayedMessagesRead ); // Reformat the stack to prevent "Stack too deep" uint256 sequenceNumber_ = sequenceNumber; TimeBounds memory timeBounds_ = timeBounds; bytes32 dataHash_ = dataHash; uint256 dataLength = data.length; uint256 afterDelayedMessagesRead_ = afterDelayedMessagesRead; uint256 prevMessageCount_ = prevMessageCount; uint256 newMessageCount_ = newMessageCount; ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc ) = addSequencerL2BatchImpl( dataHash_, afterDelayedMessagesRead_, dataLength, prevMessageCount_, newMessageCount_ ); if (seqMessageIndex != sequenceNumber_ && sequenceNumber_ != ~uint256(0)) revert BadSequencerNumber(seqMessageIndex, sequenceNumber_); emit SequencerBatchDelivered( seqMessageIndex, beforeAcc, afterAcc, delayedAcc, totalDelayedMessagesRead, timeBounds_, BatchDataLocation.TxInput ); } function addSequencerL2Batch( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder, uint256 prevMessageCount, uint256 newMessageCount ) external override refundsGas(gasRefunder) { if (!isBatchPoster[msg.sender] && msg.sender != address(rollup)) revert NotBatchPoster(); (bytes32 dataHash, TimeBounds memory timeBounds) = formDataHash( data, afterDelayedMessagesRead ); uint256 seqMessageIndex; { // Reformat the stack to prevent "Stack too deep" uint256 sequenceNumber_ = sequenceNumber; TimeBounds memory timeBounds_ = timeBounds; bytes32 dataHash_ = dataHash; uint256 afterDelayedMessagesRead_ = afterDelayedMessagesRead; uint256 prevMessageCount_ = prevMessageCount; uint256 newMessageCount_ = newMessageCount; // we set the calldata length posted to 0 here since the caller isn't the origin // of the tx, so they might have not paid tx input cost for the calldata bytes32 beforeAcc; bytes32 delayedAcc; bytes32 afterAcc; (seqMessageIndex, beforeAcc, delayedAcc, afterAcc) = addSequencerL2BatchImpl( dataHash_, afterDelayedMessagesRead_, 0, prevMessageCount_, newMessageCount_ ); if (seqMessageIndex != sequenceNumber_ && sequenceNumber_ != ~uint256(0)) revert BadSequencerNumber(seqMessageIndex, sequenceNumber_); emit SequencerBatchDelivered( seqMessageIndex, beforeAcc, afterAcc, delayedAcc, totalDelayedMessagesRead, timeBounds_, BatchDataLocation.SeparateBatchEvent ); } emit SequencerBatchData(seqMessageIndex, data); } modifier validateBatchData(bytes calldata data) { uint256 fullDataLen = HEADER_LENGTH + data.length; if (fullDataLen > MAX_DATA_SIZE) revert DataTooLarge(fullDataLen, MAX_DATA_SIZE); if (data.length > 0 && (data[0] & DATA_AUTHENTICATED_FLAG) == DATA_AUTHENTICATED_FLAG) { revert DataNotAuthenticated(); } // the first byte is used to identify the type of batch data // das batches expect to have the type byte set, followed by the keyset (so they should have at least 33 bytes) if (data.length >= 33 && data[0] & 0x80 != 0) { // we skip the first byte, then read the next 32 bytes for the keyset bytes32 dasKeysetHash = bytes32(data[1:33]); if (!dasKeySetInfo[dasKeysetHash].isValidKeyset) revert NoSuchKeyset(dasKeysetHash); } _; } function packHeader(uint256 afterDelayedMessagesRead) internal view returns (bytes memory, TimeBounds memory) { TimeBounds memory timeBounds = getTimeBounds(); bytes memory header = abi.encodePacked( timeBounds.minTimestamp, timeBounds.maxTimestamp, timeBounds.minBlockNumber, timeBounds.maxBlockNumber, uint64(afterDelayedMessagesRead) ); // This must always be true from the packed encoding assert(header.length == HEADER_LENGTH); return (header, timeBounds); } function formDataHash(bytes calldata data, uint256 afterDelayedMessagesRead) internal view validateBatchData(data) returns (bytes32, TimeBounds memory) { (bytes memory header, TimeBounds memory timeBounds) = packHeader(afterDelayedMessagesRead); bytes32 dataHash = keccak256(bytes.concat(header, data)); return (dataHash, timeBounds); } function formEmptyDataHash(uint256 afterDelayedMessagesRead) internal view returns (bytes32, TimeBounds memory) { (bytes memory header, TimeBounds memory timeBounds) = packHeader(afterDelayedMessagesRead); return (keccak256(header), timeBounds); } function addSequencerL2BatchImpl( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 calldataLengthPosted, uint256 prevMessageCount, uint256 newMessageCount ) internal returns ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc ) { if (afterDelayedMessagesRead < totalDelayedMessagesRead) revert DelayedBackwards(); if (afterDelayedMessagesRead > bridge.delayedMessageCount()) revert DelayedTooFar(); (seqMessageIndex, beforeAcc, delayedAcc, acc) = bridge.enqueueSequencerMessage( dataHash, afterDelayedMessagesRead, prevMessageCount, newMessageCount ); totalDelayedMessagesRead = afterDelayedMessagesRead; if (calldataLengthPosted > 0) { // this msg isn't included in the current sequencer batch, but instead added to // the delayed messages queue that is yet to be included address batchPoster = msg.sender; bytes memory spendingReportMsg = abi.encodePacked( block.timestamp, batchPoster, dataHash, seqMessageIndex, block.basefee ); uint256 msgNum = bridge.submitBatchSpendingReport( batchPoster, keccak256(spendingReportMsg) ); // this is the same event used by Inbox.sol after including a message to the delayed message accumulator emit InboxMessageDelivered(msgNum, spendingReportMsg); } } function inboxAccs(uint256 index) external view returns (bytes32) { return bridge.sequencerInboxAccs(index); } function batchCount() external view returns (uint256) { return bridge.sequencerMessageCount(); } /// @inheritdoc ISequencerInbox function setMaxTimeVariation(ISequencerInbox.MaxTimeVariation memory maxTimeVariation_) external onlyRollupOwner { maxTimeVariation = maxTimeVariation_; emit OwnerFunctionCalled(0); } /// @inheritdoc ISequencerInbox function setIsBatchPoster(address addr, bool isBatchPoster_) external onlyRollupOwner { isBatchPoster[addr] = isBatchPoster_; emit OwnerFunctionCalled(1); } /// @inheritdoc ISequencerInbox function setValidKeyset(bytes calldata keysetBytes) external onlyRollupOwner { uint256 ksWord = uint256(keccak256(bytes.concat(hex"fe", keccak256(keysetBytes)))); bytes32 ksHash = bytes32(ksWord ^ (1 << 255)); require(keysetBytes.length < 64 * 1024, "keyset is too large"); if (dasKeySetInfo[ksHash].isValidKeyset) revert AlreadyValidDASKeyset(ksHash); dasKeySetInfo[ksHash] = DasKeySetInfo({ isValidKeyset: true, creationBlock: uint64(block.number) }); emit SetValidKeyset(ksHash, keysetBytes); emit OwnerFunctionCalled(2); } /// @inheritdoc ISequencerInbox function invalidateKeysetHash(bytes32 ksHash) external onlyRollupOwner { if (!dasKeySetInfo[ksHash].isValidKeyset) revert NoSuchKeyset(ksHash); // we don't delete the block creation value since its used to fetch the SetValidKeyset // event efficiently. The event provides the hash preimage of the key. // this is still needed when syncing the chain after a keyset is invalidated. dasKeySetInfo[ksHash].isValidKeyset = false; emit InvalidateKeyset(ksHash); emit OwnerFunctionCalled(3); } function isValidKeysetHash(bytes32 ksHash) external view returns (bool) { return dasKeySetInfo[ksHash].isValidKeyset; } /// @inheritdoc ISequencerInbox function getKeysetCreationBlock(bytes32 ksHash) external view returns (uint256) { DasKeySetInfo memory ksInfo = dasKeySetInfo[ksHash]; if (ksInfo.creationBlock == 0) revert NoSuchKeyset(ksHash); return uint256(ksInfo.creationBlock); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; /// @dev Init was already called error AlreadyInit(); /// Init was called with param set to zero that must be nonzero error HadZeroInit(); /// @dev Thrown when non owner tries to access an only-owner function /// @param sender The msg.sender who is not the owner /// @param owner The owner address error NotOwner(address sender, address owner); /// @dev Thrown when an address that is not the rollup tries to call an only-rollup function /// @param sender The sender who is not the rollup /// @param rollup The rollup address authorized to call this function error NotRollup(address sender, address rollup); /// @dev Thrown when the contract was not called directly from the origin ie msg.sender != tx.origin error NotOrigin(); /// @dev Provided data was too large /// @param dataLength The length of the data that is too large /// @param maxDataLength The max length the data can be error DataTooLarge(uint256 dataLength, uint256 maxDataLength); /// @dev The provided is not a contract and was expected to be /// @param addr The adddress in question error NotContract(address addr); /// @dev The merkle proof provided was too long /// @param actualLength The length of the merkle proof provided /// @param maxProofLength The max length a merkle proof can have error MerkleProofTooLong(uint256 actualLength, uint256 maxProofLength); /// @dev Thrown when an un-authorized address tries to access an admin function /// @param sender The un-authorized sender /// @param rollup The rollup, which would be authorized /// @param owner The rollup's owner, which would be authorized error NotRollupOrOwner(address sender, address rollup, address owner); // Bridge Errors /// @dev Thrown when an un-authorized address tries to access an only-inbox function /// @param sender The un-authorized sender error NotDelayedInbox(address sender); /// @dev Thrown when an un-authorized address tries to access an only-sequencer-inbox function /// @param sender The un-authorized sender error NotSequencerInbox(address sender); /// @dev Thrown when an un-authorized address tries to access an only-outbox function /// @param sender The un-authorized sender error NotOutbox(address sender); /// @dev the provided outbox address isn't valid /// @param outbox address of outbox being set error InvalidOutboxSet(address outbox); // Inbox Errors /// @dev The contract is paused, so cannot be paused error AlreadyPaused(); /// @dev The contract is unpaused, so cannot be unpaused error AlreadyUnpaused(); /// @dev The contract is paused error Paused(); /// @dev msg.value sent to the inbox isn't high enough error InsufficientValue(uint256 expected, uint256 actual); /// @dev submission cost provided isn't enough to create retryable ticket error InsufficientSubmissionCost(uint256 expected, uint256 actual); /// @dev address not allowed to interact with the given contract error NotAllowedOrigin(address origin); /// @dev used to convey retryable tx data in eth calls without requiring a tx trace /// this follows a pattern similar to EIP-3668 where reverts surface call information error RetryableData( address from, address to, uint256 l2CallValue, uint256 deposit, uint256 maxSubmissionCost, address excessFeeRefundAddress, address callValueRefundAddress, uint256 gasLimit, uint256 maxFeePerGas, bytes data ); /// @dev Thrown when a L1 chainId fork is detected error L1Forked(); /// @dev Thrown when a L1 chainId fork is not detected error NotForked(); // Outbox Errors /// @dev The provided proof was too long /// @param proofLength The length of the too-long proof error ProofTooLong(uint256 proofLength); /// @dev The output index was greater than the maximum /// @param index The output index /// @param maxIndex The max the index could be error PathNotMinimal(uint256 index, uint256 maxIndex); /// @dev The calculated root does not exist /// @param root The calculated root error UnknownRoot(bytes32 root); /// @dev The record has already been spent /// @param index The index of the spent record error AlreadySpent(uint256 index); /// @dev A call to the bridge failed with no return data error BridgeCallFailed(); // Sequencer Inbox Errors /// @dev Thrown when someone attempts to read fewer messages than have already been read error DelayedBackwards(); /// @dev Thrown when someone attempts to read more messages than exist error DelayedTooFar(); /// @dev Force include can only read messages more blocks old than the delay period error ForceIncludeBlockTooSoon(); /// @dev Force include can only read messages more seconds old than the delay period error ForceIncludeTimeTooSoon(); /// @dev The message provided did not match the hash in the delayed inbox error IncorrectMessagePreimage(); /// @dev This can only be called by the batch poster error NotBatchPoster(); /// @dev The sequence number provided to this message was inconsistent with the number of batches already included error BadSequencerNumber(uint256 stored, uint256 received); /// @dev The sequence message number provided to this message was inconsistent with the previous one error BadSequencerMessageNumber(uint256 stored, uint256 received); /// @dev The batch data has the inbox authenticated bit set, but the batch data was not authenticated by the inbox error DataNotAuthenticated(); /// @dev Tried to create an already valid Data Availability Service keyset error AlreadyValidDASKeyset(bytes32); /// @dev Tried to use or invalidate an already invalid Data Availability Service keyset error NoSuchKeyset(bytes32); // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IOwnable.sol"; interface IBridge { event MessageDelivered( uint256 indexed messageIndex, bytes32 indexed beforeInboxAcc, address inbox, uint8 kind, address sender, bytes32 messageDataHash, uint256 baseFeeL1, uint64 timestamp ); event BridgeCallTriggered( address indexed outbox, address indexed to, uint256 value, bytes data ); event InboxToggle(address indexed inbox, bool enabled); event OutboxToggle(address indexed outbox, bool enabled); event SequencerInboxUpdated(address newSequencerInbox); function allowedDelayedInboxList(uint256) external returns (address); function allowedOutboxList(uint256) external returns (address); /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function delayedInboxAccs(uint256) external view returns (bytes32); /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function sequencerInboxAccs(uint256) external view returns (bytes32); function rollup() external view returns (IOwnable); function sequencerInbox() external view returns (address); function activeOutbox() external view returns (address); function allowedDelayedInboxes(address inbox) external view returns (bool); function allowedOutboxes(address outbox) external view returns (bool); function sequencerReportedSubMessageCount() external view returns (uint256); /** * @dev Enqueue a message in the delayed inbox accumulator. * These messages are later sequenced in the SequencerInbox, either * by the sequencer as part of a normal batch, or by force inclusion. */ function enqueueDelayedMessage( uint8 kind, address sender, bytes32 messageDataHash ) external payable returns (uint256); function executeCall( address to, uint256 value, bytes calldata data ) external returns (bool success, bytes memory returnData); function delayedMessageCount() external view returns (uint256); function sequencerMessageCount() external view returns (uint256); // ---------- onlySequencerInbox functions ---------- function enqueueSequencerMessage( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 prevMessageCount, uint256 newMessageCount ) external returns ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc ); /** * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type * This is done through a separate function entrypoint instead of allowing the sequencer inbox * to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either * every delayed inbox or every sequencer inbox call. */ function submitBatchSpendingReport(address batchPoster, bytes32 dataHash) external returns (uint256 msgNum); // ---------- onlyRollupOrOwner functions ---------- function setSequencerInbox(address _sequencerInbox) external; function setDelayedInbox(address inbox, bool enabled) external; function setOutbox(address inbox, bool enabled) external; // ---------- initializer ---------- function initialize(IOwnable rollup_) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IBridge.sol"; import "./IDelayedMessageProvider.sol"; import "./ISequencerInbox.sol"; interface IInbox is IDelayedMessageProvider { function bridge() external view returns (IBridge); function sequencerInbox() external view returns (ISequencerInbox); /** * @notice Send a generic L2 message to the chain * @dev This method is an optimization to avoid having to emit the entirety of the messageData in a log. Instead validators are expected to be able to parse the data from the transaction's input * This method will be disabled upon L1 fork to prevent replay attacks on L2 * @param messageData Data of the message being sent */ function sendL2MessageFromOrigin(bytes calldata messageData) external returns (uint256); /** * @notice Send a generic L2 message to the chain * @dev This method can be used to send any type of message that doesn't require L1 validation * This method will be disabled upon L1 fork to prevent replay attacks on L2 * @param messageData Data of the message being sent */ function sendL2Message(bytes calldata messageData) external returns (uint256); function sendL1FundedUnsignedTransaction( uint256 gasLimit, uint256 maxFeePerGas, uint256 nonce, address to, bytes calldata data ) external payable returns (uint256); function sendL1FundedContractTransaction( uint256 gasLimit, uint256 maxFeePerGas, address to, bytes calldata data ) external payable returns (uint256); function sendUnsignedTransaction( uint256 gasLimit, uint256 maxFeePerGas, uint256 nonce, address to, uint256 value, bytes calldata data ) external returns (uint256); function sendContractTransaction( uint256 gasLimit, uint256 maxFeePerGas, address to, uint256 value, bytes calldata data ) external returns (uint256); /** * @dev This method can only be called upon L1 fork and will not alias the caller * This method will revert if not called from origin */ function sendL1FundedUnsignedTransactionToFork( uint256 gasLimit, uint256 maxFeePerGas, uint256 nonce, address to, bytes calldata data ) external payable returns (uint256); /** * @dev This method can only be called upon L1 fork and will not alias the caller * This method will revert if not called from origin */ function sendUnsignedTransactionToFork( uint256 gasLimit, uint256 maxFeePerGas, uint256 nonce, address to, uint256 value, bytes calldata data ) external returns (uint256); /** * @notice Send a message to initiate L2 withdrawal * @dev This method can only be called upon L1 fork and will not alias the caller * This method will revert if not called from origin */ function sendWithdrawEthToFork( uint256 gasLimit, uint256 maxFeePerGas, uint256 nonce, uint256 value, address withdrawTo ) external returns (uint256); /** * @notice Get the L1 fee for submitting a retryable * @dev This fee can be paid by funds already in the L2 aliased address or by the current message value * @dev This formula may change in the future, to future proof your code query this method instead of inlining!! * @param dataLength The length of the retryable's calldata, in bytes * @param baseFee The block basefee when the retryable is included in the chain, if 0 current block.basefee will be used */ function calculateRetryableSubmissionFee(uint256 dataLength, uint256 baseFee) external view returns (uint256); /** * @notice Deposit eth from L1 to L2 to address of the sender if sender is an EOA, and to its aliased address if the sender is a contract * @dev This does not trigger the fallback function when receiving in the L2 side. * Look into retryable tickets if you are interested in this functionality. * @dev This function should not be called inside contract constructors */ function depositEth() external payable returns (uint256); /** * @notice Put a message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts * @dev all msg.value will deposited to callValueRefundAddress on L2 * @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error * @param to destination L2 contract address * @param l2CallValue call value for retryable L2 message * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee * @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled * @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) * @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) * @param data ABI encoded data of L2 message * @return unique message number of the retryable transaction */ function createRetryableTicket( address to, uint256 l2CallValue, uint256 maxSubmissionCost, address excessFeeRefundAddress, address callValueRefundAddress, uint256 gasLimit, uint256 maxFeePerGas, bytes calldata data ) external payable returns (uint256); /** * @notice Put a message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts * @dev Same as createRetryableTicket, but does not guarantee that submission will succeed by requiring the needed funds * come from the deposit alone, rather than falling back on the user's L2 balance * @dev Advanced usage only (does not rewrite aliases for excessFeeRefundAddress and callValueRefundAddress). * createRetryableTicket method is the recommended standard. * @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error * @param to destination L2 contract address * @param l2CallValue call value for retryable L2 message * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee * @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled * @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) * @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error) * @param data ABI encoded data of L2 message * @return unique message number of the retryable transaction */ function unsafeCreateRetryableTicket( address to, uint256 l2CallValue, uint256 maxSubmissionCost, address excessFeeRefundAddress, address callValueRefundAddress, uint256 gasLimit, uint256 maxFeePerGas, bytes calldata data ) external payable returns (uint256); // ---------- onlyRollupOrOwner functions ---------- /// @notice pauses all inbox functionality function pause() external; /// @notice unpauses all inbox functionality function unpause() external; // ---------- initializer ---------- /** * @dev function to be called one time during the inbox upgrade process * this is used to fix the storage slots */ function postUpgradeInit(IBridge _bridge) external; function initialize(IBridge _bridge, ISequencerInbox _sequencerInbox) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; pragma experimental ABIEncoderV2; import "../libraries/IGasRefunder.sol"; import "./IDelayedMessageProvider.sol"; import "./IBridge.sol"; interface ISequencerInbox is IDelayedMessageProvider { struct MaxTimeVariation { uint256 delayBlocks; uint256 futureBlocks; uint256 delaySeconds; uint256 futureSeconds; } struct TimeBounds { uint64 minTimestamp; uint64 maxTimestamp; uint64 minBlockNumber; uint64 maxBlockNumber; } enum BatchDataLocation { TxInput, SeparateBatchEvent, NoData } event SequencerBatchDelivered( uint256 indexed batchSequenceNumber, bytes32 indexed beforeAcc, bytes32 indexed afterAcc, bytes32 delayedAcc, uint256 afterDelayedMessagesRead, TimeBounds timeBounds, BatchDataLocation dataLocation ); event OwnerFunctionCalled(uint256 indexed id); /// @dev a separate event that emits batch data when this isn't easily accessible in the tx.input event SequencerBatchData(uint256 indexed batchSequenceNumber, bytes data); /// @dev a valid keyset was added event SetValidKeyset(bytes32 indexed keysetHash, bytes keysetBytes); /// @dev a keyset was invalidated event InvalidateKeyset(bytes32 indexed keysetHash); function totalDelayedMessagesRead() external view returns (uint256); function bridge() external view returns (IBridge); /// @dev The size of the batch header // solhint-disable-next-line func-name-mixedcase function HEADER_LENGTH() external view returns (uint256); /// @dev If the first batch data byte after the header has this bit set, /// the sequencer inbox has authenticated the data. Currently not used. // solhint-disable-next-line func-name-mixedcase function DATA_AUTHENTICATED_FLAG() external view returns (bytes1); function rollup() external view returns (IOwnable); function isBatchPoster(address) external view returns (bool); struct DasKeySetInfo { bool isValidKeyset; uint64 creationBlock; } // https://github.com/ethereum/solidity/issues/11826 // function maxTimeVariation() external view returns (MaxTimeVariation calldata); // function dasKeySetInfo(bytes32) external view returns (DasKeySetInfo calldata); /// @notice Remove force inclusion delay after a L1 chainId fork function removeDelayAfterFork() external; /// @notice Force messages from the delayed inbox to be included in the chain /// Callable by any address, but message can only be force-included after maxTimeVariation.delayBlocks and /// maxTimeVariation.delaySeconds has elapsed. As part of normal behaviour the sequencer will include these /// messages so it's only necessary to call this if the sequencer is down, or not including any delayed messages. /// @param _totalDelayedMessagesRead The total number of messages to read up to /// @param kind The kind of the last message to be included /// @param l1BlockAndTime The l1 block and the l1 timestamp of the last message to be included /// @param baseFeeL1 The l1 gas price of the last message to be included /// @param sender The sender of the last message to be included /// @param messageDataHash The messageDataHash of the last message to be included function forceInclusion( uint256 _totalDelayedMessagesRead, uint8 kind, uint64[2] calldata l1BlockAndTime, uint256 baseFeeL1, address sender, bytes32 messageDataHash ) external; function inboxAccs(uint256 index) external view returns (bytes32); function batchCount() external view returns (uint256); function isValidKeysetHash(bytes32 ksHash) external view returns (bool); /// @notice the creation block is intended to still be available after a keyset is deleted function getKeysetCreationBlock(bytes32 ksHash) external view returns (uint256); // ---------- BatchPoster functions ---------- function addSequencerL2BatchFromOrigin( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder ) external; function addSequencerL2Batch( uint256 sequenceNumber, bytes calldata data, uint256 afterDelayedMessagesRead, IGasRefunder gasRefunder, uint256 prevMessageCount, uint256 newMessageCount ) external; // ---------- onlyRollupOrOwner functions ---------- /** * @notice Set max delay for sequencer inbox * @param maxTimeVariation_ the maximum time variation parameters */ function setMaxTimeVariation(MaxTimeVariation memory maxTimeVariation_) external; /** * @notice Updates whether an address is authorized to be a batch poster at the sequencer inbox * @param addr the address * @param isBatchPoster_ if the specified address should be authorized as a batch poster */ function setIsBatchPoster(address addr, bool isBatchPoster_) external; /** * @notice Makes Data Availability Service keyset valid * @param keysetBytes bytes of the serialized keyset */ function setValidKeyset(bytes calldata keysetBytes) external; /** * @notice Invalidates a Data Availability Service keyset * @param ksHash hash of the keyset */ function invalidateKeysetHash(bytes32 ksHash) external; // ---------- initializer ---------- function initialize(IBridge bridge_, MaxTimeVariation calldata maxTimeVariation_) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./RollupLib.sol"; import "./IRollupCore.sol"; import "../bridge/ISequencerInbox.sol"; import "../bridge/IOutbox.sol"; import "../bridge/IOwnable.sol"; interface IRollupUserAbs is IRollupCore, IOwnable { /// @dev the user logic just validated configuration and shouldn't write to state during init /// this allows the admin logic to ensure consistency on parameters. function initialize(address stakeToken) external view; function removeWhitelistAfterFork() external; function removeWhitelistAfterValidatorAfk() external; function isERC20Enabled() external view returns (bool); function rejectNextNode(address stakerAddress) external; function confirmNextNode(bytes32 blockHash, bytes32 sendRoot) external; function stakeOnExistingNode(uint64 nodeNum, bytes32 nodeHash) external; function stakeOnNewNode( RollupLib.Assertion memory assertion, bytes32 expectedNodeHash, uint256 prevNodeInboxMaxCount ) external; function returnOldDeposit(address stakerAddress) external; function reduceDeposit(uint256 target) external; function removeZombie(uint256 zombieNum, uint256 maxNodes) external; function removeOldZombies(uint256 startIndex) external; function requiredStake( uint256 blockNumber, uint64 firstUnresolvedNodeNum, uint64 latestCreatedNode ) external view returns (uint256); function currentRequiredStake() external view returns (uint256); function countStakedZombies(uint64 nodeNum) external view returns (uint256); function countZombiesStakedOnChildren(uint64 nodeNum) external view returns (uint256); function requireUnresolvedExists() external view; function requireUnresolved(uint256 nodeNum) external view; function withdrawStakerFunds() external returns (uint256); function createChallenge( address[2] calldata stakers, uint64[2] calldata nodeNums, MachineStatus[2] calldata machineStatuses, GlobalState[2] calldata globalStates, uint64 numBlocks, bytes32 secondExecutionHash, uint256[2] calldata proposedTimes, bytes32[2] calldata wasmModuleRoots ) external; } interface IRollupUser is IRollupUserAbs { function newStakeOnExistingNode(uint64 nodeNum, bytes32 nodeHash) external payable; function newStakeOnNewNode( RollupLib.Assertion calldata assertion, bytes32 expectedNodeHash, uint256 prevNodeInboxMaxCount ) external payable; function addToDeposit(address stakerAddress) external payable; } interface IRollupUserERC20 is IRollupUserAbs { function newStakeOnExistingNode( uint256 tokenAmount, uint64 nodeNum, bytes32 nodeHash ) external; function newStakeOnNewNode( uint256 tokenAmount, RollupLib.Assertion calldata assertion, bytes32 expectedNodeHash, uint256 prevNodeInboxMaxCount ) external; function addToDeposit(address stakerAddress, uint256 tokenAmount) external; } interface IRollupAdmin { event OwnerFunctionCalled(uint256 indexed id); function initialize(Config calldata config, ContractDependencies calldata connectedContracts) external; /** * @notice Add a contract authorized to put messages into this rollup's inbox * @param _outbox Outbox contract to add */ function setOutbox(IOutbox _outbox) external; /** * @notice Disable an old outbox from interacting with the bridge * @param _outbox Outbox contract to remove */ function removeOldOutbox(address _outbox) external; /** * @notice Enable or disable an inbox contract * @param _inbox Inbox contract to add or remove * @param _enabled New status of inbox */ function setDelayedInbox(address _inbox, bool _enabled) external; /** * @notice Pause interaction with the rollup contract */ function pause() external; /** * @notice Resume interaction with the rollup contract */ function resume() external; /** * @notice Set the addresses of the validator whitelist * @dev It is expected that both arrays are same length, and validator at * position i corresponds to the value at position i * @param _validator addresses to set in the whitelist * @param _val value to set in the whitelist for corresponding address */ function setValidator(address[] memory _validator, bool[] memory _val) external; /** * @notice Set a new owner address for the rollup proxy * @param newOwner address of new rollup owner */ function setOwner(address newOwner) external; /** * @notice Set minimum assertion period for the rollup * @param newPeriod new minimum period for assertions */ function setMinimumAssertionPeriod(uint256 newPeriod) external; /** * @notice Set number of blocks until a node is considered confirmed * @param newConfirmPeriod new number of blocks until a node is confirmed */ function setConfirmPeriodBlocks(uint64 newConfirmPeriod) external; /** * @notice Set number of extra blocks after a challenge * @param newExtraTimeBlocks new number of blocks */ function setExtraChallengeTimeBlocks(uint64 newExtraTimeBlocks) external; /** * @notice Set base stake required for an assertion * @param newBaseStake maximum avmgas to be used per block */ function setBaseStake(uint256 newBaseStake) external; /** * @notice Set the token used for stake, where address(0) == eth * @dev Before changing the base stake token, you might need to change the * implementation of the Rollup User logic! * @param newStakeToken address of token used for staking */ function setStakeToken(address newStakeToken) external; /** * @notice Upgrades the implementation of a beacon controlled by the rollup * @param beacon address of beacon to be upgraded * @param newImplementation new address of implementation */ function upgradeBeacon(address beacon, address newImplementation) external; function forceResolveChallenge(address[] memory stackerA, address[] memory stackerB) external; function forceRefundStaker(address[] memory stacker) external; function forceCreateNode( uint64 prevNode, uint256 prevNodeInboxMaxCount, RollupLib.Assertion memory assertion, bytes32 expectedNodeHash ) external; function forceConfirmNode( uint64 nodeNum, bytes32 blockHash, bytes32 sendRoot ) external; function setLoserStakeEscrow(address newLoserStakerEscrow) external; /** * @notice Set the proving WASM module root * @param newWasmModuleRoot new module root */ function setWasmModuleRoot(bytes32 newWasmModuleRoot) external; /** * @notice set a new sequencer inbox contract * @param _sequencerInbox new address of sequencer inbox */ function setSequencerInbox(address _sequencerInbox) external; /** * @notice set the validatorWhitelistDisabled flag * @param _validatorWhitelistDisabled new value of validatorWhitelistDisabled, i.e. true = disabled */ function setValidatorWhitelistDisabled(bool _validatorWhitelistDisabled) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library Messages { function messageHash( uint8 kind, address sender, uint64 blockNumber, uint64 timestamp, uint256 inboxSeqNum, uint256 baseFeeL1, bytes32 messageDataHash ) internal pure returns (bytes32) { return keccak256( abi.encodePacked( kind, sender, blockNumber, timestamp, inboxSeqNum, baseFeeL1, messageDataHash ) ); } function accumulateInboxMessage(bytes32 prevAcc, bytes32 message) internal pure returns (bytes32) { return keccak256(abi.encodePacked(prevAcc, message)); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; uint8 constant L2_MSG = 3; uint8 constant L1MessageType_L2FundedByL1 = 7; uint8 constant L1MessageType_submitRetryableTx = 9; uint8 constant L1MessageType_ethDeposit = 12; uint8 constant L1MessageType_batchPostingReport = 13; uint8 constant L2MessageType_unsignedEOATx = 0; uint8 constant L2MessageType_unsignedContractTx = 1; uint8 constant ROLLUP_PROTOCOL_EVENT_TYPE = 8; uint8 constant INITIALIZATION_MSG_TYPE = 11; // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; interface IGasRefunder { function onGasSpent( address payable spender, uint256 gasUsed, uint256 calldataSize ) external returns (bool success); } abstract contract GasRefundEnabled { /// @dev this refunds the sender for execution costs of the tx /// calldata costs are only refunded if `msg.sender == tx.origin` to guarantee the value refunded relates to charging /// for the `tx.input`. this avoids a possible attack where you generate large calldata from a contract and get over-refunded modifier refundsGas(IGasRefunder gasRefunder) { uint256 startGasLeft = gasleft(); _; if (address(gasRefunder) != address(0)) { uint256 calldataSize; assembly { calldataSize := calldatasize() } uint256 calldataWords = (calldataSize + 31) / 32; // account for the CALLDATACOPY cost of the proxy contract, including the memory expansion cost startGasLeft += calldataWords * 6 + (calldataWords**2) / 512; // if triggered in a contract call, the spender may be overrefunded by appending dummy data to the call // so we check if it is a top level call, which would mean the sender paid calldata as part of tx.input // solhint-disable-next-line avoid-tx-origin if (msg.sender != tx.origin) { // We can't be sure if this calldata came from the top level tx, // so to be safe we tell the gas refunder there was no calldata. calldataSize = 0; } gasRefunder.onGasSpent(payable(msg.sender), startGasLeft - gasleft(), calldataSize); } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {NotOwner} from "./Error.sol"; /// @dev A stateless contract that allows you to infer if the current call has been delegated or not /// Pattern used here is from UUPS implementation by the OpenZeppelin team abstract contract DelegateCallAware { address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegate call. This allows a function to be * callable on the proxy contract but not on the logic contract. */ modifier onlyDelegated() { require(address(this) != __self, "Function must be called through delegatecall"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "Function must not be called through delegatecall"); _; } /// @dev Check that msg.sender is the current EIP 1967 proxy admin modifier onlyProxyOwner() { // Storage slot with the admin of the proxy contract // This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1 bytes32 slot = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; address admin; assembly { admin := sload(slot) } if (msg.sender != admin) revert NotOwner(msg.sender, admin); _; } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; // 90% of Geth's 128KB tx size limit, leaving ~13KB for proving uint256 constant MAX_DATA_SIZE = 117964; uint64 constant NO_CHAL_INDEX = 0; // Expected seconds per block in Ethereum PoS uint256 constant ETH_POS_BLOCK_TIME = 12; // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.4.21 <0.9.0; interface IOwnable { function owner() external view returns (address); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; interface IDelayedMessageProvider { /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator event InboxMessageDelivered(uint256 indexed messageNum, bytes data); /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator /// same as InboxMessageDelivered but the batch data is available in tx.input event InboxMessageDeliveredFromOrigin(uint256 indexed messageNum); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../challenge/IChallengeManager.sol"; import "../challenge/ChallengeLib.sol"; import "../state/GlobalState.sol"; import "../bridge/ISequencerInbox.sol"; import "../bridge/IBridge.sol"; import "../bridge/IOutbox.sol"; import "../bridge/IInbox.sol"; import "./IRollupEventInbox.sol"; import "./IRollupLogic.sol"; struct Config { uint64 confirmPeriodBlocks; uint64 extraChallengeTimeBlocks; address stakeToken; uint256 baseStake; bytes32 wasmModuleRoot; address owner; address loserStakeEscrow; uint256 chainId; uint64 genesisBlockNum; ISequencerInbox.MaxTimeVariation sequencerInboxMaxTimeVariation; } struct ContractDependencies { IBridge bridge; ISequencerInbox sequencerInbox; IInbox inbox; IOutbox outbox; IRollupEventInbox rollupEventInbox; IChallengeManager challengeManager; IRollupAdmin rollupAdminLogic; IRollupUser rollupUserLogic; // misc contracts that are useful when interacting with the rollup address validatorUtils; address validatorWalletCreator; } library RollupLib { using GlobalStateLib for GlobalState; struct ExecutionState { GlobalState globalState; MachineStatus machineStatus; } function stateHash(ExecutionState calldata execState, uint256 inboxMaxCount) internal pure returns (bytes32) { return keccak256( abi.encodePacked( execState.globalState.hash(), inboxMaxCount, execState.machineStatus ) ); } /// @dev same as stateHash but expects execState in memory instead of calldata function stateHashMem(ExecutionState memory execState, uint256 inboxMaxCount) internal pure returns (bytes32) { return keccak256( abi.encodePacked( execState.globalState.hash(), inboxMaxCount, execState.machineStatus ) ); } struct Assertion { ExecutionState beforeState; ExecutionState afterState; uint64 numBlocks; } function executionHash(Assertion memory assertion) internal pure returns (bytes32) { MachineStatus[2] memory statuses; statuses[0] = assertion.beforeState.machineStatus; statuses[1] = assertion.afterState.machineStatus; GlobalState[2] memory globalStates; globalStates[0] = assertion.beforeState.globalState; globalStates[1] = assertion.afterState.globalState; // TODO: benchmark how much this abstraction adds of gas overhead return executionHash(statuses, globalStates, assertion.numBlocks); } function executionHash( MachineStatus[2] memory statuses, GlobalState[2] memory globalStates, uint64 numBlocks ) internal pure returns (bytes32) { bytes32[] memory segments = new bytes32[](2); segments[0] = ChallengeLib.blockStateHash(statuses[0], globalStates[0].hash()); segments[1] = ChallengeLib.blockStateHash(statuses[1], globalStates[1].hash()); return ChallengeLib.hashChallengeState(0, numBlocks, segments); } function challengeRootHash( bytes32 execution, uint256 proposedTime, bytes32 wasmModuleRoot ) internal pure returns (bytes32) { return keccak256(abi.encodePacked(execution, proposedTime, wasmModuleRoot)); } function confirmHash(Assertion memory assertion) internal pure returns (bytes32) { return confirmHash( assertion.afterState.globalState.getBlockHash(), assertion.afterState.globalState.getSendRoot() ); } function confirmHash(bytes32 blockHash, bytes32 sendRoot) internal pure returns (bytes32) { return keccak256(abi.encodePacked(blockHash, sendRoot)); } function nodeHash( bool hasSibling, bytes32 lastHash, bytes32 assertionExecHash, bytes32 inboxAcc, bytes32 wasmModuleRoot ) internal pure returns (bytes32) { uint8 hasSiblingInt = hasSibling ? 1 : 0; return keccak256( abi.encodePacked( hasSiblingInt, lastHash, assertionExecHash, inboxAcc, wasmModuleRoot ) ); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Node.sol"; import "./RollupLib.sol"; interface IRollupCore { struct Staker { uint256 amountStaked; uint64 index; uint64 latestStakedNode; // currentChallenge is 0 if staker is not in a challenge uint64 currentChallenge; bool isStaked; } event RollupInitialized(bytes32 machineHash, uint256 chainId); event NodeCreated( uint64 indexed nodeNum, bytes32 indexed parentNodeHash, bytes32 indexed nodeHash, bytes32 executionHash, RollupLib.Assertion assertion, bytes32 afterInboxBatchAcc, bytes32 wasmModuleRoot, uint256 inboxMaxCount ); event NodeConfirmed(uint64 indexed nodeNum, bytes32 blockHash, bytes32 sendRoot); event NodeRejected(uint64 indexed nodeNum); event RollupChallengeStarted( uint64 indexed challengeIndex, address asserter, address challenger, uint64 challengedNode ); event UserStakeUpdated(address indexed user, uint256 initialBalance, uint256 finalBalance); event UserWithdrawableFundsUpdated( address indexed user, uint256 initialBalance, uint256 finalBalance ); function confirmPeriodBlocks() external view returns (uint64); function extraChallengeTimeBlocks() external view returns (uint64); function chainId() external view returns (uint256); function baseStake() external view returns (uint256); function wasmModuleRoot() external view returns (bytes32); function bridge() external view returns (IBridge); function sequencerInbox() external view returns (ISequencerInbox); function outbox() external view returns (IOutbox); function rollupEventInbox() external view returns (IRollupEventInbox); function challengeManager() external view returns (IChallengeManager); function loserStakeEscrow() external view returns (address); function stakeToken() external view returns (address); function minimumAssertionPeriod() external view returns (uint256); function isValidator(address) external view returns (bool); function validatorWhitelistDisabled() external view returns (bool); /** * @notice Get the Node for the given index. */ function getNode(uint64 nodeNum) external view returns (Node memory); /** * @notice Check if the specified node has been staked on by the provided staker. * Only accurate at the latest confirmed node and afterwards. */ function nodeHasStaker(uint64 nodeNum, address staker) external view returns (bool); /** * @notice Get the address of the staker at the given index * @param stakerNum Index of the staker * @return Address of the staker */ function getStakerAddress(uint64 stakerNum) external view returns (address); /** * @notice Check whether the given staker is staked * @param staker Staker address to check * @return True or False for whether the staker was staked */ function isStaked(address staker) external view returns (bool); /** * @notice Get the latest staked node of the given staker * @param staker Staker address to lookup * @return Latest node staked of the staker */ function latestStakedNode(address staker) external view returns (uint64); /** * @notice Get the current challenge of the given staker * @param staker Staker address to lookup * @return Current challenge of the staker */ function currentChallenge(address staker) external view returns (uint64); /** * @notice Get the amount staked of the given staker * @param staker Staker address to lookup * @return Amount staked of the staker */ function amountStaked(address staker) external view returns (uint256); /** * @notice Retrieves stored information about a requested staker * @param staker Staker address to retrieve * @return A structure with information about the requested staker */ function getStaker(address staker) external view returns (Staker memory); /** * @notice Get the original staker address of the zombie at the given index * @param zombieNum Index of the zombie to lookup * @return Original staker address of the zombie */ function zombieAddress(uint256 zombieNum) external view returns (address); /** * @notice Get Latest node that the given zombie at the given index is staked on * @param zombieNum Index of the zombie to lookup * @return Latest node that the given zombie is staked on */ function zombieLatestStakedNode(uint256 zombieNum) external view returns (uint64); /// @return Current number of un-removed zombies function zombieCount() external view returns (uint256); function isZombie(address staker) external view returns (bool); /** * @notice Get the amount of funds withdrawable by the given address * @param owner Address to check the funds of * @return Amount of funds withdrawable by owner */ function withdrawableFunds(address owner) external view returns (uint256); /** * @return Index of the first unresolved node * @dev If all nodes have been resolved, this will be latestNodeCreated + 1 */ function firstUnresolvedNode() external view returns (uint64); /// @return Index of the latest confirmed node function latestConfirmed() external view returns (uint64); /// @return Index of the latest rollup node created function latestNodeCreated() external view returns (uint64); /// @return Ethereum block that the most recent stake was created function lastStakeBlock() external view returns (uint64); /// @return Number of active stakers currently staked function stakerCount() external view returns (uint64); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IBridge.sol"; interface IOutbox { event SendRootUpdated(bytes32 indexed outputRoot, bytes32 indexed l2BlockHash); event OutBoxTransactionExecuted( address indexed to, address indexed l2Sender, uint256 indexed zero, uint256 transactionIndex ); function rollup() external view returns (address); // the rollup contract function bridge() external view returns (IBridge); // the bridge contract function spent(uint256) external view returns (bytes32); // packed spent bitmap function roots(bytes32) external view returns (bytes32); // maps root hashes => L2 block hash // solhint-disable-next-line func-name-mixedcase function OUTBOX_VERSION() external view returns (uint128); // the outbox version function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external; /// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account /// When the return value is zero, that means this is a system message /// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies function l2ToL1Sender() external view returns (address); /// @return l2Block return L2 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1Block() external view returns (uint256); /// @return l1Block return L1 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1EthBlock() external view returns (uint256); /// @return timestamp return L2 timestamp when the L2 tx was initiated or 0 if no L2 to L1 transaction is active function l2ToL1Timestamp() external view returns (uint256); /// @return outputId returns the unique output identifier of the L2 to L1 tx or 0 if no L2 to L1 transaction is active function l2ToL1OutputId() external view returns (bytes32); /** * @notice Executes a messages in an Outbox entry. * @dev Reverts if dispute period hasn't expired, since the outbox entry * is only created once the rollup confirms the respective assertion. * @dev it is not possible to execute any L2-to-L1 transaction which contains data * to a contract address without any code (as enforced by the Bridge contract). * @param proof Merkle proof of message inclusion in send root * @param index Merkle path to message * @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1) * @param to destination address for L1 contract call * @param l2Block l2 block number at which sendTxToL1 call was made * @param l1Block l1 block number at which sendTxToL1 call was made * @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made * @param value wei in L1 message * @param data abi-encoded L1 message data */ function executeTransaction( bytes32[] calldata proof, uint256 index, address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external; /** * @dev function used to simulate the result of a particular function call from the outbox * it is useful for things such as gas estimates. This function includes all costs except for * proof validation (which can be considered offchain as a somewhat of a fixed cost - it's * not really a fixed cost, but can be treated as so with a fixed overhead for gas estimation). * We can't include the cost of proof validation since this is intended to be used to simulate txs * that are included in yet-to-be confirmed merkle roots. The simulation entrypoint could instead pretend * to confirm a pending merkle root, but that would be less practical for integrating with tooling. * It is only possible to trigger it when the msg sender is address zero, which should be impossible * unless under simulation in an eth_call or eth_estimateGas */ function executeTransactionSimulation( uint256 index, address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external; /** * @param index Merkle path to message * @return true if the message has been spent */ function isSpent(uint256 index) external view returns (bool); function calculateItemHash( address l2Sender, address to, uint256 l2Block, uint256 l1Block, uint256 l2Timestamp, uint256 value, bytes calldata data ) external pure returns (bytes32); function calculateMerkleRoot( bytes32[] memory proof, uint256 path, bytes32 item ) external pure returns (bytes32); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../state/Machine.sol"; import "../bridge/IBridge.sol"; import "../bridge/ISequencerInbox.sol"; import "../osp/IOneStepProofEntry.sol"; import "./IChallengeResultReceiver.sol"; import "./ChallengeLib.sol"; interface IChallengeManager { enum ChallengeTerminationType { TIMEOUT, BLOCK_PROOF, EXECUTION_PROOF, CLEARED } event InitiatedChallenge( uint64 indexed challengeIndex, GlobalState startState, GlobalState endState ); event Bisected( uint64 indexed challengeIndex, bytes32 indexed challengeRoot, uint256 challengedSegmentStart, uint256 challengedSegmentLength, bytes32[] chainHashes ); event ExecutionChallengeBegun(uint64 indexed challengeIndex, uint256 blockSteps); event OneStepProofCompleted(uint64 indexed challengeIndex); event ChallengeEnded(uint64 indexed challengeIndex, ChallengeTerminationType kind); function initialize( IChallengeResultReceiver resultReceiver_, ISequencerInbox sequencerInbox_, IBridge bridge_, IOneStepProofEntry osp_ ) external; function createChallenge( bytes32 wasmModuleRoot_, MachineStatus[2] calldata startAndEndMachineStatuses_, GlobalState[2] calldata startAndEndGlobalStates_, uint64 numBlocks, address asserter_, address challenger_, uint256 asserterTimeLeft_, uint256 challengerTimeLeft_ ) external returns (uint64); function challengeInfo(uint64 challengeIndex_) external view returns (ChallengeLib.Challenge memory); function currentResponder(uint64 challengeIndex) external view returns (address); function isTimedOut(uint64 challengeIndex) external view returns (bool); function clearChallenge(uint64 challengeIndex_) external; function timeout(uint64 challengeIndex_) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../state/Machine.sol"; import "../state/GlobalState.sol"; library ChallengeLib { using MachineLib for Machine; using ChallengeLib for Challenge; /// @dev It's assumed that that uninitialzed challenges have mode NONE enum ChallengeMode { NONE, BLOCK, EXECUTION } struct Participant { address addr; uint256 timeLeft; } struct Challenge { Participant current; Participant next; uint256 lastMoveTimestamp; bytes32 wasmModuleRoot; bytes32 challengeStateHash; uint64 maxInboxMessages; ChallengeMode mode; } struct SegmentSelection { uint256 oldSegmentsStart; uint256 oldSegmentsLength; bytes32[] oldSegments; uint256 challengePosition; } function timeUsedSinceLastMove(Challenge storage challenge) internal view returns (uint256) { return block.timestamp - challenge.lastMoveTimestamp; } function isTimedOut(Challenge storage challenge) internal view returns (bool) { return challenge.timeUsedSinceLastMove() > challenge.current.timeLeft; } function getStartMachineHash(bytes32 globalStateHash, bytes32 wasmModuleRoot) internal pure returns (bytes32) { // Start the value stack with the function call ABI for the entrypoint Value[] memory startingValues = new Value[](3); startingValues[0] = ValueLib.newRefNull(); startingValues[1] = ValueLib.newI32(0); startingValues[2] = ValueLib.newI32(0); ValueArray memory valuesArray = ValueArray({inner: startingValues}); ValueStack memory values = ValueStack({proved: valuesArray, remainingHash: 0}); ValueStack memory internalStack; StackFrameWindow memory frameStack; Machine memory mach = Machine({ status: MachineStatus.RUNNING, valueStack: values, internalStack: internalStack, frameStack: frameStack, globalStateHash: globalStateHash, moduleIdx: 0, functionIdx: 0, functionPc: 0, modulesRoot: wasmModuleRoot }); return mach.hash(); } function getEndMachineHash(MachineStatus status, bytes32 globalStateHash) internal pure returns (bytes32) { if (status == MachineStatus.FINISHED) { return keccak256(abi.encodePacked("Machine finished:", globalStateHash)); } else if (status == MachineStatus.ERRORED) { return keccak256(abi.encodePacked("Machine errored:")); } else if (status == MachineStatus.TOO_FAR) { return keccak256(abi.encodePacked("Machine too far:")); } else { revert("BAD_BLOCK_STATUS"); } } function extractChallengeSegment(SegmentSelection calldata selection) internal pure returns (uint256 segmentStart, uint256 segmentLength) { uint256 oldChallengeDegree = selection.oldSegments.length - 1; segmentLength = selection.oldSegmentsLength / oldChallengeDegree; // Intentionally done before challengeLength is potentially added to for the final segment segmentStart = selection.oldSegmentsStart + segmentLength * selection.challengePosition; if (selection.challengePosition == selection.oldSegments.length - 2) { segmentLength += selection.oldSegmentsLength % oldChallengeDegree; } } function hashChallengeState( uint256 segmentsStart, uint256 segmentsLength, bytes32[] memory segments ) internal pure returns (bytes32) { return keccak256(abi.encodePacked(segmentsStart, segmentsLength, segments)); } function blockStateHash(MachineStatus status, bytes32 globalStateHash) internal pure returns (bytes32) { if (status == MachineStatus.FINISHED) { return keccak256(abi.encodePacked("Block state:", globalStateHash)); } else if (status == MachineStatus.ERRORED) { return keccak256(abi.encodePacked("Block state, errored:", globalStateHash)); } else if (status == MachineStatus.TOO_FAR) { return keccak256(abi.encodePacked("Block state, too far:")); } else { revert("BAD_BLOCK_STATUS"); } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct GlobalState { bytes32[2] bytes32Vals; uint64[2] u64Vals; } library GlobalStateLib { uint16 internal constant BYTES32_VALS_NUM = 2; uint16 internal constant U64_VALS_NUM = 2; function hash(GlobalState memory state) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "Global state:", state.bytes32Vals[0], state.bytes32Vals[1], state.u64Vals[0], state.u64Vals[1] ) ); } function getBlockHash(GlobalState memory state) internal pure returns (bytes32) { return state.bytes32Vals[0]; } function getSendRoot(GlobalState memory state) internal pure returns (bytes32) { return state.bytes32Vals[1]; } function getInboxPosition(GlobalState memory state) internal pure returns (uint64) { return state.u64Vals[0]; } function getPositionInMessage(GlobalState memory state) internal pure returns (uint64) { return state.u64Vals[1]; } function isEmpty(GlobalState calldata state) internal pure returns (bool) { return (state.bytes32Vals[0] == bytes32(0) && state.bytes32Vals[1] == bytes32(0) && state.u64Vals[0] == 0 && state.u64Vals[1] == 0); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../bridge/IBridge.sol"; interface IRollupEventInbox { function bridge() external view returns (IBridge); function initialize(IBridge _bridge) external; function rollup() external view returns (address); function rollupInitialized(uint256 chainId) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./ValueStack.sol"; import "./Instructions.sol"; import "./StackFrame.sol"; enum MachineStatus { RUNNING, FINISHED, ERRORED, TOO_FAR } struct Machine { MachineStatus status; ValueStack valueStack; ValueStack internalStack; StackFrameWindow frameStack; bytes32 globalStateHash; uint32 moduleIdx; uint32 functionIdx; uint32 functionPc; bytes32 modulesRoot; } library MachineLib { using StackFrameLib for StackFrameWindow; using ValueStackLib for ValueStack; function hash(Machine memory mach) internal pure returns (bytes32) { // Warning: the non-running hashes are replicated in Challenge if (mach.status == MachineStatus.RUNNING) { return keccak256( abi.encodePacked( "Machine running:", mach.valueStack.hash(), mach.internalStack.hash(), mach.frameStack.hash(), mach.globalStateHash, mach.moduleIdx, mach.functionIdx, mach.functionPc, mach.modulesRoot ) ); } else if (mach.status == MachineStatus.FINISHED) { return keccak256(abi.encodePacked("Machine finished:", mach.globalStateHash)); } else if (mach.status == MachineStatus.ERRORED) { return keccak256(abi.encodePacked("Machine errored:")); } else if (mach.status == MachineStatus.TOO_FAR) { return keccak256(abi.encodePacked("Machine too far:")); } else { revert("BAD_MACH_STATUS"); } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./IOneStepProver.sol"; library OneStepProofEntryLib { uint256 internal constant MAX_STEPS = 1 << 43; } interface IOneStepProofEntry { function proveOneStep( ExecutionContext calldata execCtx, uint256 machineStep, bytes32 beforeHash, bytes calldata proof ) external view returns (bytes32 afterHash); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; interface IChallengeResultReceiver { function completeChallenge( uint256 challengeIndex, address winner, address loser ) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; import "./ValueArray.sol"; struct ValueStack { ValueArray proved; bytes32 remainingHash; } library ValueStackLib { using ValueLib for Value; using ValueArrayLib for ValueArray; function hash(ValueStack memory stack) internal pure returns (bytes32 h) { h = stack.remainingHash; uint256 len = stack.proved.length(); for (uint256 i = 0; i < len; i++) { h = keccak256(abi.encodePacked("Value stack:", stack.proved.get(i).hash(), h)); } } function peek(ValueStack memory stack) internal pure returns (Value memory) { uint256 len = stack.proved.length(); return stack.proved.get(len - 1); } function pop(ValueStack memory stack) internal pure returns (Value memory) { return stack.proved.pop(); } function push(ValueStack memory stack, Value memory val) internal pure { return stack.proved.push(val); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct Instruction { uint16 opcode; uint256 argumentData; } library Instructions { uint16 internal constant UNREACHABLE = 0x00; uint16 internal constant NOP = 0x01; uint16 internal constant RETURN = 0x0F; uint16 internal constant CALL = 0x10; uint16 internal constant CALL_INDIRECT = 0x11; uint16 internal constant LOCAL_GET = 0x20; uint16 internal constant LOCAL_SET = 0x21; uint16 internal constant GLOBAL_GET = 0x23; uint16 internal constant GLOBAL_SET = 0x24; uint16 internal constant I32_LOAD = 0x28; uint16 internal constant I64_LOAD = 0x29; uint16 internal constant F32_LOAD = 0x2A; uint16 internal constant F64_LOAD = 0x2B; uint16 internal constant I32_LOAD8_S = 0x2C; uint16 internal constant I32_LOAD8_U = 0x2D; uint16 internal constant I32_LOAD16_S = 0x2E; uint16 internal constant I32_LOAD16_U = 0x2F; uint16 internal constant I64_LOAD8_S = 0x30; uint16 internal constant I64_LOAD8_U = 0x31; uint16 internal constant I64_LOAD16_S = 0x32; uint16 internal constant I64_LOAD16_U = 0x33; uint16 internal constant I64_LOAD32_S = 0x34; uint16 internal constant I64_LOAD32_U = 0x35; uint16 internal constant I32_STORE = 0x36; uint16 internal constant I64_STORE = 0x37; uint16 internal constant F32_STORE = 0x38; uint16 internal constant F64_STORE = 0x39; uint16 internal constant I32_STORE8 = 0x3A; uint16 internal constant I32_STORE16 = 0x3B; uint16 internal constant I64_STORE8 = 0x3C; uint16 internal constant I64_STORE16 = 0x3D; uint16 internal constant I64_STORE32 = 0x3E; uint16 internal constant MEMORY_SIZE = 0x3F; uint16 internal constant MEMORY_GROW = 0x40; uint16 internal constant DROP = 0x1A; uint16 internal constant SELECT = 0x1B; uint16 internal constant I32_CONST = 0x41; uint16 internal constant I64_CONST = 0x42; uint16 internal constant F32_CONST = 0x43; uint16 internal constant F64_CONST = 0x44; uint16 internal constant I32_EQZ = 0x45; uint16 internal constant I32_RELOP_BASE = 0x46; uint16 internal constant IRELOP_EQ = 0; uint16 internal constant IRELOP_NE = 1; uint16 internal constant IRELOP_LT_S = 2; uint16 internal constant IRELOP_LT_U = 3; uint16 internal constant IRELOP_GT_S = 4; uint16 internal constant IRELOP_GT_U = 5; uint16 internal constant IRELOP_LE_S = 6; uint16 internal constant IRELOP_LE_U = 7; uint16 internal constant IRELOP_GE_S = 8; uint16 internal constant IRELOP_GE_U = 9; uint16 internal constant IRELOP_LAST = IRELOP_GE_U; uint16 internal constant I64_EQZ = 0x50; uint16 internal constant I64_RELOP_BASE = 0x51; uint16 internal constant I32_UNOP_BASE = 0x67; uint16 internal constant IUNOP_CLZ = 0; uint16 internal constant IUNOP_CTZ = 1; uint16 internal constant IUNOP_POPCNT = 2; uint16 internal constant IUNOP_LAST = IUNOP_POPCNT; uint16 internal constant I32_ADD = 0x6A; uint16 internal constant I32_SUB = 0x6B; uint16 internal constant I32_MUL = 0x6C; uint16 internal constant I32_DIV_S = 0x6D; uint16 internal constant I32_DIV_U = 0x6E; uint16 internal constant I32_REM_S = 0x6F; uint16 internal constant I32_REM_U = 0x70; uint16 internal constant I32_AND = 0x71; uint16 internal constant I32_OR = 0x72; uint16 internal constant I32_XOR = 0x73; uint16 internal constant I32_SHL = 0x74; uint16 internal constant I32_SHR_S = 0x75; uint16 internal constant I32_SHR_U = 0x76; uint16 internal constant I32_ROTL = 0x77; uint16 internal constant I32_ROTR = 0x78; uint16 internal constant I64_UNOP_BASE = 0x79; uint16 internal constant I64_ADD = 0x7C; uint16 internal constant I64_SUB = 0x7D; uint16 internal constant I64_MUL = 0x7E; uint16 internal constant I64_DIV_S = 0x7F; uint16 internal constant I64_DIV_U = 0x80; uint16 internal constant I64_REM_S = 0x81; uint16 internal constant I64_REM_U = 0x82; uint16 internal constant I64_AND = 0x83; uint16 internal constant I64_OR = 0x84; uint16 internal constant I64_XOR = 0x85; uint16 internal constant I64_SHL = 0x86; uint16 internal constant I64_SHR_S = 0x87; uint16 internal constant I64_SHR_U = 0x88; uint16 internal constant I64_ROTL = 0x89; uint16 internal constant I64_ROTR = 0x8A; uint16 internal constant I32_WRAP_I64 = 0xA7; uint16 internal constant I64_EXTEND_I32_S = 0xAC; uint16 internal constant I64_EXTEND_I32_U = 0xAD; uint16 internal constant I32_REINTERPRET_F32 = 0xBC; uint16 internal constant I64_REINTERPRET_F64 = 0xBD; uint16 internal constant F32_REINTERPRET_I32 = 0xBE; uint16 internal constant F64_REINTERPRET_I64 = 0xBF; uint16 internal constant I32_EXTEND_8S = 0xC0; uint16 internal constant I32_EXTEND_16S = 0xC1; uint16 internal constant I64_EXTEND_8S = 0xC2; uint16 internal constant I64_EXTEND_16S = 0xC3; uint16 internal constant I64_EXTEND_32S = 0xC4; uint16 internal constant INIT_FRAME = 0x8002; uint16 internal constant ARBITRARY_JUMP = 0x8003; uint16 internal constant ARBITRARY_JUMP_IF = 0x8004; uint16 internal constant MOVE_FROM_STACK_TO_INTERNAL = 0x8005; uint16 internal constant MOVE_FROM_INTERNAL_TO_STACK = 0x8006; uint16 internal constant DUP = 0x8008; uint16 internal constant CROSS_MODULE_CALL = 0x8009; uint16 internal constant CALLER_MODULE_INTERNAL_CALL = 0x800A; uint16 internal constant GET_GLOBAL_STATE_BYTES32 = 0x8010; uint16 internal constant SET_GLOBAL_STATE_BYTES32 = 0x8011; uint16 internal constant GET_GLOBAL_STATE_U64 = 0x8012; uint16 internal constant SET_GLOBAL_STATE_U64 = 0x8013; uint16 internal constant READ_PRE_IMAGE = 0x8020; uint16 internal constant READ_INBOX_MESSAGE = 0x8021; uint16 internal constant HALT_AND_SET_FINISHED = 0x8022; uint256 internal constant INBOX_INDEX_SEQUENCER = 0; uint256 internal constant INBOX_INDEX_DELAYED = 1; function hash(Instruction memory inst) internal pure returns (bytes32) { return keccak256(abi.encodePacked("Instruction:", inst.opcode, inst.argumentData)); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; struct StackFrame { Value returnPc; bytes32 localsMerkleRoot; uint32 callerModule; uint32 callerModuleInternals; } struct StackFrameWindow { StackFrame[] proved; bytes32 remainingHash; } library StackFrameLib { using ValueLib for Value; function hash(StackFrame memory frame) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "Stack frame:", frame.returnPc.hash(), frame.localsMerkleRoot, frame.callerModule, frame.callerModuleInternals ) ); } function hash(StackFrameWindow memory window) internal pure returns (bytes32 h) { h = window.remainingHash; for (uint256 i = 0; i < window.proved.length; i++) { h = keccak256(abi.encodePacked("Stack frame stack:", hash(window.proved[i]), h)); } } function peek(StackFrameWindow memory window) internal pure returns (StackFrame memory) { require(window.proved.length == 1, "BAD_WINDOW_LENGTH"); return window.proved[0]; } function pop(StackFrameWindow memory window) internal pure returns (StackFrame memory frame) { require(window.proved.length == 1, "BAD_WINDOW_LENGTH"); frame = window.proved[0]; window.proved = new StackFrame[](0); } function push(StackFrameWindow memory window, StackFrame memory frame) internal pure { StackFrame[] memory newProved = new StackFrame[](window.proved.length + 1); for (uint256 i = 0; i < window.proved.length; i++) { newProved[i] = window.proved[i]; } newProved[window.proved.length] = frame; window.proved = newProved; } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; enum ValueType { I32, I64, F32, F64, REF_NULL, FUNC_REF, INTERNAL_REF } struct Value { ValueType valueType; uint256 contents; } library ValueLib { function hash(Value memory val) internal pure returns (bytes32) { return keccak256(abi.encodePacked("Value:", val.valueType, val.contents)); } function maxValueType() internal pure returns (ValueType) { return ValueType.INTERNAL_REF; } function assumeI32(Value memory val) internal pure returns (uint32) { uint256 uintval = uint256(val.contents); require(val.valueType == ValueType.I32, "NOT_I32"); require(uintval < (1 << 32), "BAD_I32"); return uint32(uintval); } function assumeI64(Value memory val) internal pure returns (uint64) { uint256 uintval = uint256(val.contents); require(val.valueType == ValueType.I64, "NOT_I64"); require(uintval < (1 << 64), "BAD_I64"); return uint64(uintval); } function newRefNull() internal pure returns (Value memory) { return Value({valueType: ValueType.REF_NULL, contents: 0}); } function newI32(uint32 x) internal pure returns (Value memory) { return Value({valueType: ValueType.I32, contents: uint256(x)}); } function newI64(uint64 x) internal pure returns (Value memory) { return Value({valueType: ValueType.I64, contents: uint256(x)}); } function newBoolean(bool x) internal pure returns (Value memory) { if (x) { return newI32(uint32(1)); } else { return newI32(uint32(0)); } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; struct ValueArray { Value[] inner; } library ValueArrayLib { function get(ValueArray memory arr, uint256 index) internal pure returns (Value memory) { return arr.inner[index]; } function set( ValueArray memory arr, uint256 index, Value memory val ) internal pure { arr.inner[index] = val; } function length(ValueArray memory arr) internal pure returns (uint256) { return arr.inner.length; } function push(ValueArray memory arr, Value memory val) internal pure { Value[] memory newInner = new Value[](arr.inner.length + 1); for (uint256 i = 0; i < arr.inner.length; i++) { newInner[i] = arr.inner[i]; } newInner[arr.inner.length] = val; arr.inner = newInner; } function pop(ValueArray memory arr) internal pure returns (Value memory popped) { popped = arr.inner[arr.inner.length - 1]; Value[] memory newInner = new Value[](arr.inner.length - 1); for (uint256 i = 0; i < newInner.length; i++) { newInner[i] = arr.inner[i]; } arr.inner = newInner; } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "../state/Machine.sol"; import "../state/Module.sol"; import "../state/Instructions.sol"; import "../bridge/ISequencerInbox.sol"; import "../bridge/IBridge.sol"; struct ExecutionContext { uint256 maxInboxMessagesRead; IBridge bridge; } abstract contract IOneStepProver { function executeOneStep( ExecutionContext memory execCtx, Machine calldata mach, Module calldata mod, Instruction calldata instruction, bytes calldata proof ) external view virtual returns (Machine memory result, Module memory resultMod); } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./ModuleMemory.sol"; struct Module { bytes32 globalsMerkleRoot; ModuleMemory moduleMemory; bytes32 tablesMerkleRoot; bytes32 functionsMerkleRoot; uint32 internalsOffset; } library ModuleLib { using ModuleMemoryLib for ModuleMemory; function hash(Module memory mod) internal pure returns (bytes32) { return keccak256( abi.encodePacked( "Module:", mod.globalsMerkleRoot, mod.moduleMemory.hash(), mod.tablesMerkleRoot, mod.functionsMerkleRoot, mod.internalsOffset ) ); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./MerkleProof.sol"; import "./Deserialize.sol"; struct ModuleMemory { uint64 size; uint64 maxSize; bytes32 merkleRoot; } library ModuleMemoryLib { using MerkleProofLib for MerkleProof; function hash(ModuleMemory memory mem) internal pure returns (bytes32) { return keccak256(abi.encodePacked("Memory:", mem.size, mem.maxSize, mem.merkleRoot)); } function proveLeaf( ModuleMemory memory mem, uint256 leafIdx, bytes calldata proof, uint256 startOffset ) internal pure returns ( bytes32 contents, uint256 offset, MerkleProof memory merkle ) { offset = startOffset; (contents, offset) = Deserialize.b32(proof, offset); (merkle, offset) = Deserialize.merkleProof(proof, offset); bytes32 recomputedRoot = merkle.computeRootFromMemory(leafIdx, contents); require(recomputedRoot == mem.merkleRoot, "WRONG_MEM_ROOT"); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; import "./Instructions.sol"; import "./Module.sol"; struct MerkleProof { bytes32[] counterparts; } library MerkleProofLib { using ModuleLib for Module; using ValueLib for Value; function computeRootFromValue( MerkleProof memory proof, uint256 index, Value memory leaf ) internal pure returns (bytes32) { return computeRootUnsafe(proof, index, leaf.hash(), "Value merkle tree:"); } function computeRootFromInstruction( MerkleProof memory proof, uint256 index, Instruction memory inst ) internal pure returns (bytes32) { return computeRootUnsafe(proof, index, Instructions.hash(inst), "Instruction merkle tree:"); } function computeRootFromFunction( MerkleProof memory proof, uint256 index, bytes32 codeRoot ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Function:", codeRoot)); return computeRootUnsafe(proof, index, h, "Function merkle tree:"); } function computeRootFromMemory( MerkleProof memory proof, uint256 index, bytes32 contents ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Memory leaf:", contents)); return computeRootUnsafe(proof, index, h, "Memory merkle tree:"); } function computeRootFromElement( MerkleProof memory proof, uint256 index, bytes32 funcTypeHash, Value memory val ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Table element:", funcTypeHash, val.hash())); return computeRootUnsafe(proof, index, h, "Table element merkle tree:"); } function computeRootFromTable( MerkleProof memory proof, uint256 index, uint8 tableType, uint64 tableSize, bytes32 elementsRoot ) internal pure returns (bytes32) { bytes32 h = keccak256(abi.encodePacked("Table:", tableType, tableSize, elementsRoot)); return computeRootUnsafe(proof, index, h, "Table merkle tree:"); } function computeRootFromModule( MerkleProof memory proof, uint256 index, Module memory mod ) internal pure returns (bytes32) { return computeRootUnsafe(proof, index, mod.hash(), "Module merkle tree:"); } // WARNING: leafHash must be computed in such a way that it cannot be a non-leaf hash. function computeRootUnsafe( MerkleProof memory proof, uint256 index, bytes32 leafHash, string memory prefix ) internal pure returns (bytes32 h) { h = leafHash; for (uint256 layer = 0; layer < proof.counterparts.length; layer++) { if (index & 1 == 0) { h = keccak256(abi.encodePacked(prefix, h, proof.counterparts[layer])); } else { h = keccak256(abi.encodePacked(prefix, proof.counterparts[layer], h)); } index >>= 1; } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import "./Value.sol"; import "./ValueStack.sol"; import "./Machine.sol"; import "./Instructions.sol"; import "./StackFrame.sol"; import "./MerkleProof.sol"; import "./ModuleMemory.sol"; import "./Module.sol"; import "./GlobalState.sol"; library Deserialize { function u8(bytes calldata proof, uint256 startOffset) internal pure returns (uint8 ret, uint256 offset) { offset = startOffset; ret = uint8(proof[offset]); offset++; } function u16(bytes calldata proof, uint256 startOffset) internal pure returns (uint16 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 16 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function u32(bytes calldata proof, uint256 startOffset) internal pure returns (uint32 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 32 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function u64(bytes calldata proof, uint256 startOffset) internal pure returns (uint64 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 64 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function u256(bytes calldata proof, uint256 startOffset) internal pure returns (uint256 ret, uint256 offset) { offset = startOffset; for (uint256 i = 0; i < 256 / 8; i++) { ret <<= 8; ret |= uint8(proof[offset]); offset++; } } function b32(bytes calldata proof, uint256 startOffset) internal pure returns (bytes32 ret, uint256 offset) { offset = startOffset; uint256 retInt; (retInt, offset) = u256(proof, offset); ret = bytes32(retInt); } function value(bytes calldata proof, uint256 startOffset) internal pure returns (Value memory val, uint256 offset) { offset = startOffset; uint8 typeInt = uint8(proof[offset]); offset++; require(typeInt <= uint8(ValueLib.maxValueType()), "BAD_VALUE_TYPE"); uint256 contents; (contents, offset) = u256(proof, offset); val = Value({valueType: ValueType(typeInt), contents: contents}); } function valueStack(bytes calldata proof, uint256 startOffset) internal pure returns (ValueStack memory stack, uint256 offset) { offset = startOffset; bytes32 remainingHash; (remainingHash, offset) = b32(proof, offset); uint256 provedLength; (provedLength, offset) = u256(proof, offset); Value[] memory proved = new Value[](provedLength); for (uint256 i = 0; i < proved.length; i++) { (proved[i], offset) = value(proof, offset); } stack = ValueStack({proved: ValueArray(proved), remainingHash: remainingHash}); } function instruction(bytes calldata proof, uint256 startOffset) internal pure returns (Instruction memory inst, uint256 offset) { offset = startOffset; uint16 opcode; uint256 data; (opcode, offset) = u16(proof, offset); (data, offset) = u256(proof, offset); inst = Instruction({opcode: opcode, argumentData: data}); } function stackFrame(bytes calldata proof, uint256 startOffset) internal pure returns (StackFrame memory window, uint256 offset) { offset = startOffset; Value memory returnPc; bytes32 localsMerkleRoot; uint32 callerModule; uint32 callerModuleInternals; (returnPc, offset) = value(proof, offset); (localsMerkleRoot, offset) = b32(proof, offset); (callerModule, offset) = u32(proof, offset); (callerModuleInternals, offset) = u32(proof, offset); window = StackFrame({ returnPc: returnPc, localsMerkleRoot: localsMerkleRoot, callerModule: callerModule, callerModuleInternals: callerModuleInternals }); } function stackFrameWindow(bytes calldata proof, uint256 startOffset) internal pure returns (StackFrameWindow memory window, uint256 offset) { offset = startOffset; bytes32 remainingHash; (remainingHash, offset) = b32(proof, offset); StackFrame[] memory proved; if (proof[offset] != 0) { offset++; proved = new StackFrame[](1); (proved[0], offset) = stackFrame(proof, offset); } else { offset++; proved = new StackFrame[](0); } window = StackFrameWindow({proved: proved, remainingHash: remainingHash}); } function moduleMemory(bytes calldata proof, uint256 startOffset) internal pure returns (ModuleMemory memory mem, uint256 offset) { offset = startOffset; uint64 size; uint64 maxSize; bytes32 root; (size, offset) = u64(proof, offset); (maxSize, offset) = u64(proof, offset); (root, offset) = b32(proof, offset); mem = ModuleMemory({size: size, maxSize: maxSize, merkleRoot: root}); } function module(bytes calldata proof, uint256 startOffset) internal pure returns (Module memory mod, uint256 offset) { offset = startOffset; bytes32 globalsMerkleRoot; ModuleMemory memory mem; bytes32 tablesMerkleRoot; bytes32 functionsMerkleRoot; uint32 internalsOffset; (globalsMerkleRoot, offset) = b32(proof, offset); (mem, offset) = moduleMemory(proof, offset); (tablesMerkleRoot, offset) = b32(proof, offset); (functionsMerkleRoot, offset) = b32(proof, offset); (internalsOffset, offset) = u32(proof, offset); mod = Module({ globalsMerkleRoot: globalsMerkleRoot, moduleMemory: mem, tablesMerkleRoot: tablesMerkleRoot, functionsMerkleRoot: functionsMerkleRoot, internalsOffset: internalsOffset }); } function globalState(bytes calldata proof, uint256 startOffset) internal pure returns (GlobalState memory state, uint256 offset) { offset = startOffset; // using constant ints for array size requires newer solidity bytes32[2] memory bytes32Vals; uint64[2] memory u64Vals; for (uint8 i = 0; i < GlobalStateLib.BYTES32_VALS_NUM; i++) { (bytes32Vals[i], offset) = b32(proof, offset); } for (uint8 i = 0; i < GlobalStateLib.U64_VALS_NUM; i++) { (u64Vals[i], offset) = u64(proof, offset); } state = GlobalState({bytes32Vals: bytes32Vals, u64Vals: u64Vals}); } function machine(bytes calldata proof, uint256 startOffset) internal pure returns (Machine memory mach, uint256 offset) { offset = startOffset; MachineStatus status; { uint8 statusU8; (statusU8, offset) = u8(proof, offset); if (statusU8 == 0) { status = MachineStatus.RUNNING; } else if (statusU8 == 1) { status = MachineStatus.FINISHED; } else if (statusU8 == 2) { status = MachineStatus.ERRORED; } else if (statusU8 == 3) { status = MachineStatus.TOO_FAR; } else { revert("UNKNOWN_MACH_STATUS"); } } ValueStack memory values; ValueStack memory internalStack; bytes32 globalStateHash; uint32 moduleIdx; uint32 functionIdx; uint32 functionPc; StackFrameWindow memory frameStack; bytes32 modulesRoot; (values, offset) = valueStack(proof, offset); (internalStack, offset) = valueStack(proof, offset); (frameStack, offset) = stackFrameWindow(proof, offset); (globalStateHash, offset) = b32(proof, offset); (moduleIdx, offset) = u32(proof, offset); (functionIdx, offset) = u32(proof, offset); (functionPc, offset) = u32(proof, offset); (modulesRoot, offset) = b32(proof, offset); mach = Machine({ status: status, valueStack: values, internalStack: internalStack, frameStack: frameStack, globalStateHash: globalStateHash, moduleIdx: moduleIdx, functionIdx: functionIdx, functionPc: functionPc, modulesRoot: modulesRoot }); } function merkleProof(bytes calldata proof, uint256 startOffset) internal pure returns (MerkleProof memory merkle, uint256 offset) { offset = startOffset; uint8 length; (length, offset) = u8(proof, offset); bytes32[] memory counterparts = new bytes32[](length); for (uint8 i = 0; i < length; i++) { (counterparts[i], offset) = b32(proof, offset); } merkle = MerkleProof(counterparts); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; struct Node { // Hash of the state of the chain as of this node bytes32 stateHash; // Hash of the data that can be challenged bytes32 challengeHash; // Hash of the data that will be committed if this node is confirmed bytes32 confirmData; // Index of the node previous to this one uint64 prevNum; // Deadline at which this node can be confirmed uint64 deadlineBlock; // Deadline at which a child of this node can be confirmed uint64 noChildConfirmedBeforeBlock; // Number of stakers staked on this node. This includes real stakers and zombies uint64 stakerCount; // Number of stakers staked on a child node. This includes real stakers and zombies uint64 childStakerCount; // This value starts at zero and is set to a value when the first child is created. After that it is constant until the node is destroyed or the owner destroys pending nodes uint64 firstChildBlock; // The number of the latest child of this node to be created uint64 latestChildNumber; // The block number when this node was created uint64 createdAtBlock; // A hash of all the data needed to determine this node's validity, to protect against reorgs bytes32 nodeHash; } /** * @notice Utility functions for Node */ library NodeLib { /** * @notice Initialize a Node * @param _stateHash Initial value of stateHash * @param _challengeHash Initial value of challengeHash * @param _confirmData Initial value of confirmData * @param _prevNum Initial value of prevNum * @param _deadlineBlock Initial value of deadlineBlock * @param _nodeHash Initial value of nodeHash */ function createNode( bytes32 _stateHash, bytes32 _challengeHash, bytes32 _confirmData, uint64 _prevNum, uint64 _deadlineBlock, bytes32 _nodeHash ) internal view returns (Node memory) { Node memory node; node.stateHash = _stateHash; node.challengeHash = _challengeHash; node.confirmData = _confirmData; node.prevNum = _prevNum; node.deadlineBlock = _deadlineBlock; node.noChildConfirmedBeforeBlock = _deadlineBlock; node.createdAtBlock = uint64(block.number); node.nodeHash = _nodeHash; return node; } /** * @notice Update child properties * @param number The child number to set */ function childCreated(Node storage self, uint64 number) internal { if (self.firstChildBlock == 0) { self.firstChildBlock = uint64(block.number); } self.latestChildNumber = number; } /** * @notice Update the child confirmed deadline * @param deadline The new deadline to set */ function newChildConfirmDeadline(Node storage self, uint64 deadline) internal { self.noChildConfirmedBeforeBlock = deadline; } /** * @notice Check whether the current block number has met or passed the node's deadline */ function requirePastDeadline(Node memory self) internal view { require(block.number >= self.deadlineBlock, "BEFORE_DEADLINE"); } /** * @notice Check whether the current block number has met or passed deadline for children of this node to be confirmed */ function requirePastChildConfirmDeadline(Node memory self) internal view { require(block.number >= self.noChildConfirmedBeforeBlock, "CHILD_TOO_RECENT"); } }
File 5 of 5: Bridge
// Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import { NotContract, NotRollupOrOwner, NotDelayedInbox, NotSequencerInbox, NotOutbox, InvalidOutboxSet, BadSequencerMessageNumber } from "../libraries/Error.sol"; import "./IBridge.sol"; import "./Messages.sol"; import "../libraries/DelegateCallAware.sol"; import {L1MessageType_batchPostingReport} from "../libraries/MessageTypes.sol"; /** * @title Staging ground for incoming and outgoing messages * @notice Holds the inbox accumulator for sequenced and delayed messages. * It is also the ETH escrow for value sent with these messages. * Since the escrow is held here, this contract also contains a list of allowed * outboxes that can make calls from here and withdraw this escrow. */ contract Bridge is Initializable, DelegateCallAware, IBridge { using AddressUpgradeable for address; struct InOutInfo { uint256 index; bool allowed; } mapping(address => InOutInfo) private allowedDelayedInboxesMap; mapping(address => InOutInfo) private allowedOutboxesMap; address[] public allowedDelayedInboxList; address[] public allowedOutboxList; address private _activeOutbox; /// @inheritdoc IBridge bytes32[] public delayedInboxAccs; /// @inheritdoc IBridge bytes32[] public sequencerInboxAccs; IOwnable public rollup; address public sequencerInbox; uint256 public override sequencerReportedSubMessageCount; address private constant EMPTY_ACTIVEOUTBOX = address(type(uint160).max); function initialize(IOwnable rollup_) external initializer onlyDelegated { _activeOutbox = EMPTY_ACTIVEOUTBOX; rollup = rollup_; } modifier onlyRollupOrOwner() { if (msg.sender != address(rollup)) { address rollupOwner = rollup.owner(); if (msg.sender != rollupOwner) { revert NotRollupOrOwner(msg.sender, address(rollup), rollupOwner); } } _; } /// @dev returns the address of current active Outbox, or zero if no outbox is active function activeOutbox() public view returns (address) { address outbox = _activeOutbox; // address zero is returned if no outbox is set, but the value used in storage // is non-zero to save users some gas (as storage refunds are usually maxed out) // EIP-1153 would help here. // we don't return `EMPTY_ACTIVEOUTBOX` to avoid a breaking change on the current api if (outbox == EMPTY_ACTIVEOUTBOX) return address(0); return outbox; } function allowedDelayedInboxes(address inbox) external view returns (bool) { return allowedDelayedInboxesMap[inbox].allowed; } function allowedOutboxes(address outbox) external view returns (bool) { return allowedOutboxesMap[outbox].allowed; } modifier onlySequencerInbox() { if (msg.sender != sequencerInbox) revert NotSequencerInbox(msg.sender); _; } function enqueueSequencerMessage( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 prevMessageCount, uint256 newMessageCount ) external onlySequencerInbox returns ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc ) { if ( sequencerReportedSubMessageCount != prevMessageCount && prevMessageCount != 0 && sequencerReportedSubMessageCount != 0 ) { revert BadSequencerMessageNumber(sequencerReportedSubMessageCount, prevMessageCount); } sequencerReportedSubMessageCount = newMessageCount; seqMessageIndex = sequencerInboxAccs.length; if (sequencerInboxAccs.length > 0) { beforeAcc = sequencerInboxAccs[sequencerInboxAccs.length - 1]; } if (afterDelayedMessagesRead > 0) { delayedAcc = delayedInboxAccs[afterDelayedMessagesRead - 1]; } acc = keccak256(abi.encodePacked(beforeAcc, dataHash, delayedAcc)); sequencerInboxAccs.push(acc); } /// @inheritdoc IBridge function submitBatchSpendingReport(address sender, bytes32 messageDataHash) external onlySequencerInbox returns (uint256) { return addMessageToDelayedAccumulator( L1MessageType_batchPostingReport, sender, uint64(block.number), uint64(block.timestamp), // solhint-disable-line not-rely-on-time, block.basefee, messageDataHash ); } /// @inheritdoc IBridge function enqueueDelayedMessage( uint8 kind, address sender, bytes32 messageDataHash ) external payable returns (uint256) { if (!allowedDelayedInboxesMap[msg.sender].allowed) revert NotDelayedInbox(msg.sender); return addMessageToDelayedAccumulator( kind, sender, uint64(block.number), uint64(block.timestamp), // solhint-disable-line not-rely-on-time block.basefee, messageDataHash ); } function addMessageToDelayedAccumulator( uint8 kind, address sender, uint64 blockNumber, uint64 blockTimestamp, uint256 baseFeeL1, bytes32 messageDataHash ) internal returns (uint256) { uint256 count = delayedInboxAccs.length; bytes32 messageHash = Messages.messageHash( kind, sender, blockNumber, blockTimestamp, count, baseFeeL1, messageDataHash ); bytes32 prevAcc = 0; if (count > 0) { prevAcc = delayedInboxAccs[count - 1]; } delayedInboxAccs.push(Messages.accumulateInboxMessage(prevAcc, messageHash)); emit MessageDelivered( count, prevAcc, msg.sender, kind, sender, messageDataHash, baseFeeL1, blockTimestamp ); return count; } function executeCall( address to, uint256 value, bytes calldata data ) external returns (bool success, bytes memory returnData) { if (!allowedOutboxesMap[msg.sender].allowed) revert NotOutbox(msg.sender); if (data.length > 0 && !to.isContract()) revert NotContract(to); address prevOutbox = _activeOutbox; _activeOutbox = msg.sender; // We set and reset active outbox around external call so activeOutbox remains valid during call // We use a low level call here since we want to bubble up whether it succeeded or failed to the caller // rather than reverting on failure as well as allow contract and non-contract calls // solhint-disable-next-line avoid-low-level-calls (success, returnData) = to.call{value: value}(data); _activeOutbox = prevOutbox; emit BridgeCallTriggered(msg.sender, to, value, data); } function setSequencerInbox(address _sequencerInbox) external onlyRollupOrOwner { sequencerInbox = _sequencerInbox; emit SequencerInboxUpdated(_sequencerInbox); } function setDelayedInbox(address inbox, bool enabled) external onlyRollupOrOwner { InOutInfo storage info = allowedDelayedInboxesMap[inbox]; bool alreadyEnabled = info.allowed; emit InboxToggle(inbox, enabled); if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) { return; } if (enabled) { allowedDelayedInboxesMap[inbox] = InOutInfo(allowedDelayedInboxList.length, true); allowedDelayedInboxList.push(inbox); } else { allowedDelayedInboxList[info.index] = allowedDelayedInboxList[ allowedDelayedInboxList.length - 1 ]; allowedDelayedInboxesMap[allowedDelayedInboxList[info.index]].index = info.index; allowedDelayedInboxList.pop(); delete allowedDelayedInboxesMap[inbox]; } } function setOutbox(address outbox, bool enabled) external onlyRollupOrOwner { if (outbox == EMPTY_ACTIVEOUTBOX) revert InvalidOutboxSet(outbox); InOutInfo storage info = allowedOutboxesMap[outbox]; bool alreadyEnabled = info.allowed; emit OutboxToggle(outbox, enabled); if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) { return; } if (enabled) { allowedOutboxesMap[outbox] = InOutInfo(allowedOutboxList.length, true); allowedOutboxList.push(outbox); } else { allowedOutboxList[info.index] = allowedOutboxList[allowedOutboxList.length - 1]; allowedOutboxesMap[allowedOutboxList[info.index]].index = info.index; allowedOutboxList.pop(); delete allowedOutboxesMap[outbox]; } } function setSequencerReportedSubMessageCount(uint256 newMsgCount) external onlyRollupOrOwner { sequencerReportedSubMessageCount = newMsgCount; } function delayedMessageCount() external view override returns (uint256) { return delayedInboxAccs.length; } function sequencerMessageCount() external view returns (uint256) { return sequencerInboxAccs.length; } /// @dev For the classic -> nitro migration. TODO: remove post-migration. function acceptFundsFromOldBridge() external payable {} } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; /// @dev Init was already called error AlreadyInit(); /// Init was called with param set to zero that must be nonzero error HadZeroInit(); /// @dev Thrown when non owner tries to access an only-owner function /// @param sender The msg.sender who is not the owner /// @param owner The owner address error NotOwner(address sender, address owner); /// @dev Thrown when an address that is not the rollup tries to call an only-rollup function /// @param sender The sender who is not the rollup /// @param rollup The rollup address authorized to call this function error NotRollup(address sender, address rollup); /// @dev Thrown when the contract was not called directly from the origin ie msg.sender != tx.origin error NotOrigin(); /// @dev Provided data was too large /// @param dataLength The length of the data that is too large /// @param maxDataLength The max length the data can be error DataTooLarge(uint256 dataLength, uint256 maxDataLength); /// @dev The provided is not a contract and was expected to be /// @param addr The adddress in question error NotContract(address addr); /// @dev The merkle proof provided was too long /// @param actualLength The length of the merkle proof provided /// @param maxProofLength The max length a merkle proof can have error MerkleProofTooLong(uint256 actualLength, uint256 maxProofLength); /// @dev Thrown when an un-authorized address tries to access an admin function /// @param sender The un-authorized sender /// @param rollup The rollup, which would be authorized /// @param owner The rollup's owner, which would be authorized error NotRollupOrOwner(address sender, address rollup, address owner); // Bridge Errors /// @dev Thrown when an un-authorized address tries to access an only-inbox function /// @param sender The un-authorized sender error NotDelayedInbox(address sender); /// @dev Thrown when an un-authorized address tries to access an only-sequencer-inbox function /// @param sender The un-authorized sender error NotSequencerInbox(address sender); /// @dev Thrown when an un-authorized address tries to access an only-outbox function /// @param sender The un-authorized sender error NotOutbox(address sender); /// @dev the provided outbox address isn't valid /// @param outbox address of outbox being set error InvalidOutboxSet(address outbox); // Inbox Errors /// @dev The contract is paused, so cannot be paused error AlreadyPaused(); /// @dev The contract is unpaused, so cannot be unpaused error AlreadyUnpaused(); /// @dev The contract is paused error Paused(); /// @dev msg.value sent to the inbox isn't high enough error InsufficientValue(uint256 expected, uint256 actual); /// @dev submission cost provided isn't enough to create retryable ticket error InsufficientSubmissionCost(uint256 expected, uint256 actual); /// @dev address not allowed to interact with the given contract error NotAllowedOrigin(address origin); /// @dev used to convey retryable tx data in eth calls without requiring a tx trace /// this follows a pattern similar to EIP-3668 where reverts surface call information error RetryableData( address from, address to, uint256 l2CallValue, uint256 deposit, uint256 maxSubmissionCost, address excessFeeRefundAddress, address callValueRefundAddress, uint256 gasLimit, uint256 maxFeePerGas, bytes data ); // Outbox Errors /// @dev The provided proof was too long /// @param proofLength The length of the too-long proof error ProofTooLong(uint256 proofLength); /// @dev The output index was greater than the maximum /// @param index The output index /// @param maxIndex The max the index could be error PathNotMinimal(uint256 index, uint256 maxIndex); /// @dev The calculated root does not exist /// @param root The calculated root error UnknownRoot(bytes32 root); /// @dev The record has already been spent /// @param index The index of the spent record error AlreadySpent(uint256 index); /// @dev A call to the bridge failed with no return data error BridgeCallFailed(); // Sequencer Inbox Errors /// @dev Thrown when someone attempts to read fewer messages than have already been read error DelayedBackwards(); /// @dev Thrown when someone attempts to read more messages than exist error DelayedTooFar(); /// @dev Force include can only read messages more blocks old than the delay period error ForceIncludeBlockTooSoon(); /// @dev Force include can only read messages more seconds old than the delay period error ForceIncludeTimeTooSoon(); /// @dev The message provided did not match the hash in the delayed inbox error IncorrectMessagePreimage(); /// @dev This can only be called by the batch poster error NotBatchPoster(); /// @dev The sequence number provided to this message was inconsistent with the number of batches already included error BadSequencerNumber(uint256 stored, uint256 received); /// @dev The sequence message number provided to this message was inconsistent with the previous one error BadSequencerMessageNumber(uint256 stored, uint256 received); /// @dev The batch data has the inbox authenticated bit set, but the batch data was not authenticated by the inbox error DataNotAuthenticated(); /// @dev Tried to create an already valid Data Availability Service keyset error AlreadyValidDASKeyset(bytes32); /// @dev Tried to use or invalidate an already invalid Data Availability Service keyset error NoSuchKeyset(bytes32); // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.6.9 <0.9.0; import "./IOwnable.sol"; interface IBridge { event MessageDelivered( uint256 indexed messageIndex, bytes32 indexed beforeInboxAcc, address inbox, uint8 kind, address sender, bytes32 messageDataHash, uint256 baseFeeL1, uint64 timestamp ); event BridgeCallTriggered( address indexed outbox, address indexed to, uint256 value, bytes data ); event InboxToggle(address indexed inbox, bool enabled); event OutboxToggle(address indexed outbox, bool enabled); event SequencerInboxUpdated(address newSequencerInbox); function allowedDelayedInboxList(uint256) external returns (address); function allowedOutboxList(uint256) external returns (address); /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function delayedInboxAccs(uint256) external view returns (bytes32); /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message. function sequencerInboxAccs(uint256) external view returns (bytes32); function rollup() external view returns (IOwnable); function sequencerInbox() external view returns (address); function activeOutbox() external view returns (address); function allowedDelayedInboxes(address inbox) external view returns (bool); function allowedOutboxes(address outbox) external view returns (bool); function sequencerReportedSubMessageCount() external view returns (uint256); /** * @dev Enqueue a message in the delayed inbox accumulator. * These messages are later sequenced in the SequencerInbox, either * by the sequencer as part of a normal batch, or by force inclusion. */ function enqueueDelayedMessage( uint8 kind, address sender, bytes32 messageDataHash ) external payable returns (uint256); function executeCall( address to, uint256 value, bytes calldata data ) external returns (bool success, bytes memory returnData); function delayedMessageCount() external view returns (uint256); function sequencerMessageCount() external view returns (uint256); // ---------- onlySequencerInbox functions ---------- function enqueueSequencerMessage( bytes32 dataHash, uint256 afterDelayedMessagesRead, uint256 prevMessageCount, uint256 newMessageCount ) external returns ( uint256 seqMessageIndex, bytes32 beforeAcc, bytes32 delayedAcc, bytes32 acc ); /** * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type * This is done through a separate function entrypoint instead of allowing the sequencer inbox * to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either * every delayed inbox or every sequencer inbox call. */ function submitBatchSpendingReport(address batchPoster, bytes32 dataHash) external returns (uint256 msgNum); // ---------- onlyRollupOrOwner functions ---------- function setSequencerInbox(address _sequencerInbox) external; function setDelayedInbox(address inbox, bool enabled) external; function setOutbox(address inbox, bool enabled) external; // ---------- initializer ---------- function initialize(IOwnable rollup_) external; } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library Messages { function messageHash( uint8 kind, address sender, uint64 blockNumber, uint64 timestamp, uint256 inboxSeqNum, uint256 baseFeeL1, bytes32 messageDataHash ) internal pure returns (bytes32) { return keccak256( abi.encodePacked( kind, sender, blockNumber, timestamp, inboxSeqNum, baseFeeL1, messageDataHash ) ); } function accumulateInboxMessage(bytes32 prevAcc, bytes32 message) internal pure returns (bytes32) { return keccak256(abi.encodePacked(prevAcc, message)); } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; import {NotOwner} from "./Error.sol"; /// @dev A stateless contract that allows you to infer if the current call has been delegated or not /// Pattern used here is from UUPS implementation by the OpenZeppelin team abstract contract DelegateCallAware { address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegate call. This allows a function to be * callable on the proxy contract but not on the logic contract. */ modifier onlyDelegated() { require(address(this) != __self, "Function must be called through delegatecall"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "Function must not be called through delegatecall"); _; } /// @dev Check that msg.sender is the current EIP 1967 proxy admin modifier onlyProxyOwner() { // Storage slot with the admin of the proxy contract // This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1 bytes32 slot = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; address admin; assembly { admin := sload(slot) } if (msg.sender != admin) revert NotOwner(msg.sender, admin); _; } } // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.4; uint8 constant L2_MSG = 3; uint8 constant L1MessageType_L2FundedByL1 = 7; uint8 constant L1MessageType_submitRetryableTx = 9; uint8 constant L1MessageType_ethDeposit = 12; uint8 constant L1MessageType_batchPostingReport = 13; uint8 constant L2MessageType_unsignedEOATx = 0; uint8 constant L2MessageType_unsignedContractTx = 1; uint8 constant ROLLUP_PROTOCOL_EVENT_TYPE = 8; uint8 constant INITIALIZATION_MSG_TYPE = 11; // Copyright 2021-2022, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE // SPDX-License-Identifier: BUSL-1.1 // solhint-disable-next-line compiler-version pragma solidity >=0.4.21 <0.9.0; interface IOwnable { function owner() external view returns (address); }