Transaction Hash:
Block:
16697428 at Feb-24-2023 09:52:11 AM +UTC
Transaction Fee:
0.0477774747875235 ETH
$121.23
Gas Used:
1,843,525 Gas / 25.91636934 Gwei
Emitted Events:
310 |
TransparentUpgradeableProxy.0x5e3c1311ea442664e8b1611bfabef659120ea7a0a2cfc0667700bebc69cbffe1( 0x5e3c1311ea442664e8b1611bfabef659120ea7a0a2cfc0667700bebc69cbffe1, 0x00000000000000000000000000000000000000000000000000000000000839cd, 0x9a6418516efef3495a18fab91f13e9c796aa4bb153fd018491c37ee157713271, 0000000000000000000000001c479675ad559dc151f6ec7ed3fbf8cee79582b6, 000000000000000000000000000000000000000000000000000000000000000d, 000000000000000000000000c1b634853cb333d3ad8663715b08f41a3aec47cc, 51980f433989d6049b0341deb9f062c3081052e13c30a95a27f1aafe4e433c7c, 0000000000000000000000000000000000000000000000000000000602c688bc, 0000000000000000000000000000000000000000000000000000000063f888cb )
|
311 |
TransparentUpgradeableProxy.0xff64905f73a67fb594e0f940a8075a860db489ad991e032f48c81123eb52d60b( 0xff64905f73a67fb594e0f940a8075a860db489ad991e032f48c81123eb52d60b, 0x00000000000000000000000000000000000000000000000000000000000839cd, 0000000000000000000000000000000000000000000000000000000000000020, 0000000000000000000000000000000000000000000000000000000000000094, 0000000000000000000000000000000000000000000000000000000063f888cb, c1b634853cb333d3ad8663715b08f41a3aec47cc56601a59dd91835689a75f3e, a61cc0b0c02342ed012e23fa03865f7153b2914b000000000000000000000000, 000000000000000000000000000000000001412b000000000000000000000000, 0000000000000000000000000000000602c688bc000000000000000000000000 )
|
312 |
TransparentUpgradeableProxy.0x7394f4a19a13c7b92b5bb71033245305946ef78452f7b4986ac1390b5df4ebd7( 0x7394f4a19a13c7b92b5bb71033245305946ef78452f7b4986ac1390b5df4ebd7, 0x000000000000000000000000000000000000000000000000000000000001412b, 0xe70f35f6f5d053c3068915fa5bed191cca7922eaf4ecbd104a22e2db632acbe3, 0xcf8100a83974dc56a8925ee44cf1730a9e68c56856da8cfcaf9d2f13faff5e04, b8032a83cfe68789d99d3c3eeef311cef79dcee74e6ba5dc873dec109025d901, 0000000000000000000000000000000000000000000000000000000000083967, 0000000000000000000000000000000000000000000000000000000063f7374b, 0000000000000000000000000000000000000000000000000000000063f896db, 0000000000000000000000000000000000000000000000000000000000feb1d4, 0000000000000000000000000000000000000000000000000000000000fec860, 0000000000000000000000000000000000000000000000000000000000000000 )
|
313 |
GasRefunder.RefundedGasCosts( refundee=[Sender] 0xc1b634853cb333d3ad8663715b08f41a3aec47cc, contractAddress=[Receiver] TransparentUpgradeableProxy, success=True, gas=1881021, gasPrice=25916369340, amountPaid=47731221118650256 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x3C02F840...8e04Ac273
Miner
| (Fee Recipient: 0x3c02...273) | 5.633239512985069838 Eth | 5.633423865485069838 Eth | 0.0001843525 | |
0x8315177a...4DBd7ed3a | (Arbitrum: Bridge) | ||||
0xC1b63485...A3Aec47cc | (Arbitrum: Batch Submitter) |
5.001303689992880704 Eth
Nonce: 30950
|
5.00125743632400746 Eth
Nonce: 30951
| 0.000046253668873244 | |
0xe64a54E2...80E2E4eb5 | 299.796433929119052868 Eth | 299.748702708000402612 Eth | 0.047731221118650256 |
Execution Trace
TransparentUpgradeableProxy.8f111f3c( )
SequencerInbox.addSequencerL2BatchFromOrigin( sequenceNumber=82219, data=0x005B97C5340A696A6FF6C317401455B51F363368D2597F085047EAC29F3FFFFE1938AEC73AEF019CDB7F4E44844854089EA81ED122B4B420952A5D8284D0520374CDFF282C50FF015CD25AF0F2A545AC0F5EADA5C5252D692DAFFE7F36F543C4EAC6C49C99034B497BE87ADE8DD5D2A49D290F92DF7E7F4CCCF4FFEF6D665B3ECD2F8127C4B04A8B0DE5C3AF42A70BE1502A1F8E8243E41CBE3C81968BFFAB7E2921CF4152CB29845FF5FE7D1F240A3A80844D81C60770941CC1EA3356CB491332B43AABE510D5F07FF5315498907AD452CF6431FC070EC2218BE90038A55FA5F6395F62740E92933493B5B2BD12ED76DE4E58E5E5AABDD8C93D2BB1588D26A4C5CAE9EC67FEA7A6E655637BE45140DA72540038DC4CA028055765940B648FA45157929DAE4C417452525C0A8E34F367E4C4728894F8F585089D2C0048C982E1F5B648CE6A9E4BB4C04E4A347269D214BC29D2E14474B81C367BEBE1B8977B2D86CBFF99E59BD027698E20BAC8D56A68F57D26BAF3DF28F6CDA865001910A628687FEFCF7AAE9EFDDA57AC332940622C15A16A69FF65C1DFEB864EF31C72C8611B2D4F345CA4F563AC5B1434E26D5CB50B990A0407FAE3C7477C82429E106FC32B9AC3A223E1EF76417F3F174630299C655AEB54BAD46D6852D0CFB8F8E660563B947369D8C0BA102353A54978402443FB6ABE65E56F0D89ED0B40474952F9A196664F09043F2C2E19093CB04EDF73502C0155B25225BE0AC90F07BA127DEB66E358B7203485B0A3015AEDC0BFE29A9AC3DBE278AFAB168480B951D3C9C397883043E2F2258C42AAE9FE9ED01F22BAE520204C19292E316E2E77F570BCB5AE5F0F85C6D2E42B90C51CC82A022111F8622E4B0A04F44265191252306895CB18C650756FB100C15220F1078E90302C07848AA50AE74659C900960D18FAB5BB78B04B47C8CC6BB6D5B4FE66565A8F3D90BF1148C74EC8495FF108773AF207E0DC59D34EB9E04E924CDCB32061980DC826DE89220AF4E01AC12F46893A96D2F343BE7542E221987CDAD4FF17C088051CE938660D288E5F584549B41E0D3462F803FE319F0485D3562C07B260F168BCFDB4C3CCC35B9600FD519A84C4000C581A491CA6A7A215BE12EFC44D0F4A1B8B5768398F3B0F598834BF92DB9E9E6802B08673A324365DD11399A33B7FEBBD7CD5654E6CB18911C68BFC14048097F0BEE193A7607CE813183B02EE9F75242223062822080794B9F5534374C6CC2A9F50BC4CB44A6967D12D483C1BD65985CDA73304070283181E18B1E273359D27FFA20F5424D1F1F73CB8759CFD1B710B6F54960B8947DCEFCBEA4337B8D191D691EC6E0681C00C0F8C5866E2C1144C65BD961C85E9FEA1CD7283FDDCDAC7DEE70E9D7C0752D967AAA76E5B0D7089998634FFF0C020F02D23D61085DE588D63D74BFF349E80D81DD6CF61CA0AD92CEDC7433074C3B3120421411ADE2C4A4882B3C5A7B108B07214800E3B2E7AB68EB0E4CA2513C669B1C4776B360BDA1E560A77B6C14FF50E4EC001C0358EB89D86A57005232C0D0D290869BA59FF8C4D0984105B89D7B2771729A4BAA09820381008843B0567409FC029E1CB1DD5A346137A5F6646B9B40F4DF5177350338BD8A8943E09885D609F201B301DB7657839A8FAE29BE7959B1D41868B1353FDC7D133CC568EBE1C901B7C5E62FF6F699055AC1D6990839D7A9A20CDD2F9020902C5FD62A10ADCDB73338D5AA24BA8F55A3CCECCFFFD89BDBEF6A4AE9EFE123BF43E723F303D02AC1C0DF4E511FEDA42B2119553E49DCD5122BAA6A6C86D22E9F9EF3799BB528CDBEE6C0458E48C9264A17D647749F896FD7A415E69D6C8F90FE564C3A416EDAF3BC9228E2A9E77E7A08FD3C49188DEC65211B82F9E99ED17D401AE4C23DD9676F85A3199BE39CE1E1E79B04E1B9816FAB3932550C5923FC941DE58337383BC89859ED55409AFE1DD7871B9620A679FCB85D4D01CE0547D5BBD782DB46BEC97A29EF29FE6BFD699EFE953DB6C6775D091E38EF8D6CA7D4525372FB1D2AE102C67CB1002A065961D8B4F96E5444A1DB9A4AE141E3C533EC622CEB9DD3A16F955308FB18CD770C7BACF585A1C9C9FE690058CDC53768EB45A9957036EBE3360E1BCF106436276D22013B5132B8C7304AF7A250F426AD597C2C587D2FF6B9A3781EB104DBABFD0F8F9F1B1F0D1109F12181EA84156674A8529AA367ED1779EF812AB977271319B33BEAF38DCBD587B9A0CF8E137D6B4C7D1F8451E073297140E6CC1978E2C26731D1F8C3338261B4D9CFA86C381BB90574170201008040241F1A04F50AC08C8CD7D24FCDD2E28827B8033F33BD9E2946F4932F544BCAC7D87EDADB845686C14AC0BAE6202E62B0C028140201B5220F903A97497125C69C2D3BBD1F5ECBE7E9F606521AA40569A0225B67B7ED620087C838280088103212043E1C148843C43D9412852055869D3359959696FC5DC0C545964A03A3103354A19F84A5E9E161FF3A9E050BBF7209EAE9BE1B55845EA9C1349932F4FE30C436D130F15D59DFE27BC589A6295A56B227FFD7EE07D95090E0950384915EEBF5041AA717D3C33702F77764E6047616A1976BFE65B15112FFB319C5EB73A999671206799DEF435C26651302BA7095EB49AEFF60BBD285550C5D2227279B1AA064903911ACDA604B36553CDB4821D0864FFFC877E825AE9F9914FFB56460DB437BACAE6E84AEA778EAC4DFF7A5362D57CA536B7671457E2D5E6C8CBDBB8931510D5A79266F2D08C73037B4EC17D08D84E6DFC8AE55BD6A0FF76412A7F111E1648E0E36950766A9547753B014DDDA7FCD03D2CEFA5C5E798A0CF4AF73F280C3E792DE009A19A70BEB691647AA760DD6258C1EAB5270B573D9E697A5005DC23F1D11CDD3D2840C1445DFC8D0E7F641CB60E332E472A1EFC0B50170DF4642458117F0CB98D8A5CE50CB236160D1EC976B3BBA2D54B6B18778BC9DF0717C02BC1F9807F7B51C5340996A966018F1BD9C72E06FE3E2E3FF75155AEB7BFE830C6688927C54B0AE88283F26718A8F911280DA519187BEBC7F891C50B04824305A3812C393B0D32001AC80878878954DA20EEA0001096C34ABF28408867A11BE16E8035F84122A143A00CE0DB6A3B6682C200E6897C39ADFCFA93FF30B3CEDEEB2CA2B8D8E25BC876F42493BA31CCEBC3164D61269C6F4A05E09A6E5A0EC7F796D1DC99F1D4AEB3723BC229A7267113F286D3D980A1A29DBECC53EC601328E409AC1F5ED1CC018B4442BD1C88103C8DCE243826C57DB3086CE3A6B27E38A1F4FB69DBC0D310839D9B2313A0D1D079F0F9C6A99DA3F1C946CF4739AEC9B29D8DC78633B1FBE13DD62993B37FF8656EA5365107EBC7EC4FF4118F4181870CF3B0180003EA8A315727EFD53239FB784367FA7FB115F87B041AA28CFFA69FDCB85A3720CD038820C6DBAE9C8F7B6B80E7EAE02AEBC3E0C14E145964BD00CCDCAC94A120B71EB7F613FA381B8E5C475DEFA359706532C0784636861DD7265C61B84EB4AE3E3D77093058A78D7FD50F13905536518D2BB2853EA91C35C2968B301C2F81A659EEF1277E4713B30863F59D3FC374F48908A38BD1EFBA6E143FAF3CB491C6A35D3756DEDAFEEE8414CB40E193DF7B1F3C4201156F169CB779B49BE55FFE453F26D695636142426E52BEF49D7ECC4362D876455D089F72B202305F1CA23867856DFFFA8CC20A51CF44CE75D6A03715D3834997A370ECE3BC11DA73FF80750EE349C2EF3A930479182DC982D1C65D22CC0BEEB794481BD6049B3508FBE1985FA4A6A0FAA7691E1FA4090259F76043EEB8249F92AE5BB0851ED2C7EB1C88175F2D13CB9DDB730F273300039237E7D5A4AA4212C4E98DB520EDE80393957EBCC8AA5F8D2E9CE55633F3FBC801315D54E240AFA8CFD7CEA7FE49ABD0359E66C4880ACCD689B6E7CC31FC21291D1008040281E005A0902778EEF08AE670C432582412EAE54004534457A67768231E02E5510AF45DAD86CA644E374AFF651CD6051DC6BE10FB070211D48890B3FCC900186002C988980BA8FC03E58FA509B906F41A4C38AC096620901106365DFB21C802DDA3346D04247EF073302B8A0294C664F5E3D26414901B40711C64815EA375700EC00007AC0FA731988D5A910244AA7BC131EE0A27FB81C1DC31E6F35B2F582711A70980667F6ECE17A658EEFD9F212DEF8902B955ECB939EB2E02679A38A7DB0772F4893D0C57019B822A2F349F1DC2EE01EC626E30D6A106093BCC83228828A18A28CBB67C242C2B7497557E72C5BCDECCEE49307A08C24AB3FF2B5C1583C1BA18A1FCC0F6B07A87B1CEE3DAD7D8F2FE9FCAE5368291EB2980811FFA93216666DBC26A269114FEFEB3F752454F2CFB7D3E217C2B9DB2FBCFB9CEDF2028E47136BCA299C67F9F51A8092C99C686469C103870D9034F0361557ECB4A8B0F8E34ACD386296835DF6164A8DA537EEF24BBBF8E6FA21EEACBB182448CF17E04598098DB8620EE5F0760C022F94E0365A83553315DCE6F2C8D62244D7C378A57D1FF4BF621C429BFD0C4B800DD57F39F91D7B33F3FFB9C1A45BA18AC2B2D33B649BDADE614B5C82A4E6565227581F3A30D9579C0B09931FC46E325CB6716BB3D3C98AC2469ACABE5D14FA8FA159AA25B85A101C0741CEAFD29EE1F49C24C937F3B53375A97A307DCCD690EF1AF133BBCAA65BD73E111E67BB040968FD74011D4E47905807417AA8197BFC2915152B2F256C7371284E9ABCC11D6FF66BD342FF342CB14284506DC3DE6681B31A5C18992175E308207A7C148773385BAA62DE5FEC7C2E9EB03329902AA2E470255C84C8F73FE491A39114780C1C79FC9B6499E5C270F8977D3FF0B19F263D281505E12A69291CEC76DAE0C1C457A547DE38C396CF8A4B21291D2530295D3F0ED2E78A9FCF316E146A09027B8819AD19520DCB060BA265D4D71E605DD848B90CED4A504D2C936539AE3F961580CF650A0E00E0CD405A7F68C29B16B60152499245B6CED096BC5A6CE953718D990E053B2B4D088E9D850D43C7EB4A47511C8D274C5B68B0285238499D543611422EA02B97F0B6786323A482A26F215B0636DDDE7CB51259BBA215E5490009A5BFFB7CB5976C8A2A75F315A9160082D28ADFA1C4C0BF27A003981D42D6A168EC98D0BC2A0F4989783AE912C103F280F444A40A94DEA6BDC37CFC685DCF91F7FC465CEA0C1AB6D10174818C48887AAFCAF26E62B02A56B1CC542D104FE64D583DEE6C7D08E7E3FFCFDC48632F0C54E27DF1A55D9F54D8897FF072AE7965023BEFCF41B51010FBD4875F24F819B59F4D6582478BBE7A4035290C58553580C80012F221559ED78BB993FC2AC42A9B11EF8A31C5BBA902F10A67C93D6263954575A80211675DDA07932E23BA2151B5BD2B8167606F3E7A11DECE4557CDE9942D861ACDC650B14F2F835BCA219AE3069EC1B59E62B92F3D88C9912F97461D4D94140E94047C95417EEBB1CB27975AB137FDBD02C78C36162BB6EFDB96F13194B287FB7C262000C300E94786AA8959F3F5263ED1789D3242F0CED9CAFA99BF54C7DF2A2105F795907508ECD9FED798D8D8BAD86A923DCFE1EEFD9A46F7D220E3BE0102F7E9F89F883FAEAF7D6087DFC02E99BD4ABC3F93ED50D4FAA4A90A6D0B83E950C330B44240DF91556AB91B53DB4FD6BF802DBB56C521400E87748E7303FFBD275CB1BD36E566E7A541B25B8FF2EB8EDACDB147AFBDCFE43B45A64E2B6214A905D6C782F350692278705E89112050C46D5520C18BB210EA69AA9F034DAD30F955A83D143D1FCD4620D6E5A0FBB0DCE64D98C03299FFC8CF1525DAB8793C9F16432FFB3F71D6F006E5F245B996922BEED2666DFC1BEBE347931916B08B639A47C9EF914596B60FAA5DE391BD2D1F3712B5AD027B09A530C69B4646751A63C759AA357B5ABE97FDB67DDC207E0873195D617D4FB41C472C019C82A7E7E77F2589709369A8F191C1220B54640EA3828DF08AA330EDAD54194B5D53515DCADA4FCEDAC0FA664A3399F27C21F8D55D9203A159D006AE81617E7F19800AEF4E7681940A4BF8F97C125D3BF15EE88E7E305524D8CF0AA0B0CD694FE97B1B22BE0D870950560BD584C69CE0A7BFDB5BB21AA7DC8CC4BBFB7C00D0C1C9CFC9C805DF8D3DAD25843200CD679A081C5D4ED4250B18FAF4DD72EA142B5BF260ABFDEF11E2EA59FC7B31DB4051C460119FF40E91F229C024B5488E75FAA3DC839FDA89EC5F5643753EDC8F1608369C8964640C43A50FEE5DAB003F2DE9ED9ECAF1C7B4B58F6ECE1D1C96C4BC764275F875878EB57707F90B6E4FDE9421CA860250615F6CD942B2763271C77D9F547E3BDCA5334E0FCF296695C22A6818242A7ACB5C90D569013C16E9059CEE9E0C28610882A212126B4CBB1C71916D11A847BA10F42ED44380C8001EDE592347C4DE685C84F701D7B35B4A37F481DA748BF9B95F333378A9FB6AE0602DC55296E0684056C5DC8E9A89CFFF6A4834A85FB52D12CCC941D4FB46BCE65D2D11468A77922341F29159E7F3A05B83FEFB02EB8E1F4C7247CC1415040963F1042C2C72F30BDFD005953F322D66CF8FE6543852F0222322C25731CAC1F5364FC02E52FAF0A26DD1A79A6AFFFC26CBF6C52B3A5D6828D1E57770B0C7B0308E3110D3A145C39ED4EDD455F838DD548FADF3F67B6944BFE303710463B909F59FFEFFED4D9A743A2420AB24A0F5CCCD696E4970F4CEA84F77952330EC9D532E3CDDC65E28D94215F8D67C4B2E0685ACD3797F0FBA90DE735FC0B8281737A1A0FAE186F13D292271AF6EC7C1D5693D4B8B69ABBE4DDD8DEE2146AF8A62B31D4F0ECDB412100B550E7C49B0D26CF9AF1F4F111508AC6F261A5471422AB6AD6D39DFD6FAF1EAB0BDC5EC1A71A69F900885EB5FBE52E7517584E5B70B99A0C206215ED8D0315CE92AFE54A5063818FBA7DFE9007C85B3994B55C982BF427D630C23F34373F7FB7DD9D80ACB9FCE74980A86A9F4661A2D0A221EA06CBEADCAF0EC339C15BC4B785E5FB1B5E71FFB2400B1C76D2AB4673D037F8F7227C1D4DB7250A527587DB19DDFD333B0F8042456A7D2B40CAAD3DE3590B56B76D6A5CEF3309B2F058EFA925E3FF8C7D61D830A379ED10A22A63935E3E201C35F361BC8111833F13653F37839175E0FDF34E23663F95D9E5020DFDA71D18FB335A030C70A0D9888CDBA16FBE0924EB9F92D428E99A4B191BFC3D62A657F3B1F97DB8910760337563BE7D722395FBF3999F38419C6DDB97B2D2A1DD197304A34336F258671F9F09F6FF15823AA090C796F08A66CC0EDE0E87B2A990692FF5A59365645424E89770E8EEFFF34F01291F139BEF448A96C8C6FAB33394EB3AEDDE32C36B8EBD9212F21161310003F0E4693E9DE64FFEDDA125312D7C25F67C9640D0C8A4EE4B2AD4FA13406C97DE0538D4FD4BFAD1C95C1697246B2EA942501D7C00D25BF9E61215E013B44B8013D247AECF21151CD2DF5024AAEEF708910F2EEA6BB1298E3FD862276E0C2A08F0D04AA281CFBF6D9E8A92B395C7E9F074E9796311E26E0DA1D74D05D642EC3DCE5F113F3101C4C5758679E5C292A3864A668BCF953115AB4FA8F4A6CD5DCDCE2E56FFC139045D901CA440D2F60F070FC404423A9757A119EC103A3049CD443018740B265432B649AB40110963393462AF91B9C0ECE80434DFED8F0E7D82C3A2DD773AB5036AC53E47EF8318B1502ED4CE2A199A5151356A5086BB3C12D7E1E65D48462F145F885050C2499E88CFABF2AE1CFEAA8605C0CF5617EA976751DE33E0F874245BEB733D8F334A671AA9B308FC59916F0EA3ED428DCB17A84EAAAD623884FFF70E87F1D32953593E07E3ED6FEEEF8CB6AEC0AE7E061391BDF80410EDDA167F5189838DF397205EC17D95EE9A6266EB3C42010CD027319E290692CD92444670A3DF13FEE3231911FBCC77AD5EDF078D97102CF4003CC9716C11913F4E18FA4835745EB8BB96755AE30002210B9CD68B45243AF108F895A27C87429E50BAC32B9AB11FA172960E9C59A71F49C5C09D78B64B0D80BA50E4269FCEEDC2F262A70C4B588C2AC7EC9F7FB93697672F3666A0D58CFD1A34ADB6E44101A73F538179E5CF09AFC61E0807F63E03B75748622E215E28DC0EB2BFBF2E5D4890F10711BC025A908935328107E96AFA634106031980EE9823E8A235CF1312C66E014D5C3B13059DDF476F025978272742FD79E38E207FDA2DA980C686A82B75365878DBE870B82246AC11423DCF58B660FEF74D226F1F4161E502B3F90FC87F719743316BF04E9E069573D888BD1C8A6B04F9D1461F41FE84AF2E24B34485904DF5AF8F23606E22A33F311F6770E9405A80644464C6C11CB92BC6807E1A31C006CEFDD2BB513875DAEAF1542786339E4F9D6DEB9FE49A6542542950D746CDDA0581AB8F53398919DF2CD230D2D881F3B36D75FFAD9F91AE7E64B2D8A8F5629AA04BEAA4FF1EADDF7627983057FB04ABA0AA23F5C3B061B0D2C70506C0002132C7A0CDCBC03485D17B7EB48D055F3E70F8DAC3139FE540326EB339A3860A90F9794ACE5B224469EAA007D67C9F50EA7EC914B6F6F5DBF9E9A646DCF36535158A664398D86D18106517E7F7C296FEAD8DC3A288A6897287194FF67FA190828883C4EE8FE44767BBBB7B77181D86E60F1A73C0FC389BDE8224C102231E60FC142FE91725BF941F5BDC8285FAAEFF3A0BD0B594699118942EC2E271B66D96BF10F7EC60EC7AF756ECE8E5771658FDFD9BD159F359706982628809B3A971DC9978F9B3D923D9C2DBA4117387233E7345A43139A6A875C89905BD5994CF45A02C901516033080916754FCBA2C29CA51EDFEAEC378F2C57B7F7178964DAB9F954705F58895A715C05A3E1357B4956F113361CF52E648A5FBD502C36AD4A25AB08F9F6768F87BF48982EB69F10E877C5791691CB8DCAEB09F2CAD199A4BA3AD7A205B0183676E4C1275DCFB6DEAB7DE5DA51BE818AB0BE3968ABC452E09CA232063A4B1EA5D7598DDCDEFA5254DFB8B2292A1C8F2B2ED4E48BED989D1D9F501CA021C3E4F394A8DCB81513825E16633AE0B0AF0DC460AFBA4E9415F02F39A239002364E01EB550C07CBFDFE9C2D05E569662DC28DD014759859AFEA78D06CB1C378E8E3CA3F58E701D73795F9F8764D580CC080FB22F133E1C7BA8F69D5DA754766D76A3F3CC3D22F53DE46A95B51556FFFC8AA03A2C1A6A9ADEC88D7BB28DB4842714EB6F936C335341DF6143CF5FD66A3DF5DE628440F9AA0C928E9A999838488822AB3BC6F8900389888993D5C4BB4B40775922391F0701DCA3CF2FDE9978F55726B4AABCC55F42FF257C0D5BF62B25EAFB4F916C24E1C9B0567987909175AE044E0768F5C7491531CB522101C9DD3E678D736AAE81997CD13CDC98735C2412ADA4338ACCB106A101C9942DE05F104C18140201008042684429EC038E115CD60582412EAE540049E1067E6FFFDE2811CAE494C3C06166B57F64FFAC2FC823AB0CE9ACE24CD2D10080402A15D9A8C6F5A3ACB3F316714FD2DD89D57482590EE10A436FF4B450D541B2CD4263B16E0CF1374D28185AA1E801838DCE768020B57972E5B7F080674621B934131C78F457EC1CF2DCF9131EC8C09EB4C678632B4946AF4D617BC100204721A55386996EBBA85AF719F23E6BB8399A4F7277E3942FFA3F55330F4AD6C80C6AC161422C76E5AA2095BBF4F6CDFCAFEA8D5A46E665E608EA3E0F94BC47080010B9F5B3EB8612B39CD3EF22A171D59118B786A3446DF58FE3C0BB392A9E29A4104D82E63353A9E7E6C1909BCC571DE356DB0C5CC15B9D639A2F25E042874283E8E2021F9D3132CBA17C452AACCD3A2421CB4F7B7703E8D07DD56B8D0696EE4BA5B5885C59B62937C061CA3AADAAAA77DFE27A56AD7F97DD5755AF0CBE724D0D99C7681EC37A93E6E71EA493243AE4940D95531E452A8195B86EE1405751AA3940CDDD422A4A4E2E57ED7A8E72E961A0197CD290BB855290A41BBBD91FDD979B260625A28267EF1179C9794BB54939E65CAA56373E83331CE4948B48EEC245C411636120AD100EF2A4D66475DCA4856B5A0D4CCE4119AB1D0BF50C6FF5A05084B22E66C92AAB4004A725BFFA71CBBAD1AC527343B16CA6D96D3669FDEFE9FBFB2F7EA7F6038515CC1331661069B276FD16A8472302AA28B12AAF43068A0DF2BF96DA26BD3C984283A4092E69B1F236345383646857401020B5B1BEB977E8708EABBAC4E75821FBDB45ADB21847A1511048241EA8F57285D709639C2AD18409FC03A08CEEF6EC5914199A490B5C4A6F99CB324C352DFCEC49004C53C5F8468F8D4BFAE58A09A10D0F22611E886046A03ADD71D873EC5FB75F656487C3A1895C1A0690CC772B56F4922345AADC8C4273CB4496154B0FCDAE9D54D00CA7B1191D434817DAC3651FCB7EBB9B97DC686F438BA62340BC068BB57CADD085C006FE341A5B0A56E9BCB9865C6C2BFE0EB7BE732012A2C5AA1EF1662C90AC4B8A3AF21AA6DD2DC768818F7B18B9DFA818CE2EF81C33EB11011C5AB56F3197D394236D8B73E129A9E1E324B5752076387211C6040DC75688BB959B5CB97573BDF3BE165AE0065399396A78356C19237191F51B231C0C72EF0CB6293BE4F3E9B881EF2326A0B0392C0F7D12CFF0341F62E491FE3106A8A9A1B66469976F8AB2DC080149DA35F1CA370B3FF963653032E7A450CEDFFF32BB7382B45B2AB639BAD86B402540B03E3D65B635A33BEBDFCFA53F65876482D1CD6F1D28261459F6E7483CFDE472D47D853E554C95F6E11606616F8487FFE4C500445242CB3BCB716C3C42B3613C5C878B13691A7A192857802D6AAF9EDC9FC9D0B0486801BFDC5231963A6486953F6C7D79698D984B1DA7F81DC792AB633AAF955CC784752DBC9DF3392E80A0B06C000164EED009ACB98E082CE2926DDD6725BDFBE728F0397D02E44D88BAD3FA7971560225FDBDF509C989F8EAC33DE91C746698248A59F74B025916A7A3553D97F4303512804F3C1D3323A1C2A8A4126F64C1B2B469B6BD6536AFFA64256D5FE7F38E50012B51B878686862629A1423E2BDE17F0503770BE1E4744ECDD81A56CB4FBCB358FBB528561CE83A75FD81C267888BD3C55AEDF0CCD79F100331AB5291B0AE8F54A98BBE8802AA927A1CDE00166738A4663CC4D2F8418AFAD0BEEBB6F27439EAFF004B9CF9885C1CA7DA7E43DBB1E83B4DB5B702505EA82448E593249C94408AA9C0A58B0314399941BDD5EAD4F425EE3033412FBAF7FFEF1207C4AD124EAD0FF3FC7C19AFE1DA9505905920D35C5E07BFD7BB842580C8001DC34F556484BAFA83E37FD7772B55B1C20465D0AF720F6FECB6C1D217FE0AF1A20D858E7F16EAB7A456B23C5DA8708FFA81D46D32896997579F96F5B3E919C2D91422A9E8EDF7EED683BDB998264A1A32B70250F19222C65C99D8CEFBB779C88202AC715A40EA5C38FD4E934C9BA68A68E6AB9C02F911161F87016F27E2173B68D7DB282C8F7EFE12F9FBB08BF16691C34A55AE42AF71339C036337E49966DF99D6B592FAA73DA49964451C83EE44DAA23C1B789560DA3B7B40B63022968FD29685D85CDAB56957372988C864E8B566DDDB674A1FDD529AB8A9C810FD4D6C38EB98E6556A1206350A863A783965E6018A0AE79D00E5F63165FB14DFEDA90ED3654840768F8D61FBCE9EA8F957AEF88FE2119BC633B9B64DBD5A96102650283B82103083B45917E443F839D300DED8D1E0EC1D003ED6A5902941CB4AB154548408206E4F56D819EF1C26CCE0CE85741E180ACF84158226083FBFEB25AA07C645186757AFA99C56C47D60151DD0DA8828AF5753A4A799B92B9021E9CFD3F0B8943D2CE69FF2B7715FB41D3CDBC098A43A0B21237615A237291098489DC36CA0664E11D0C07851F3662AF87C43542E3F7C61D41FE84B12E2CA784021888DDCC6929FCC9DB5D6077626C32C9701D46A17062CD572D95397BEE3E191FEC07C8EDBFDD75E31744A23A87F1A6468C664BFB592B1FDFE63670AC274C692F747A480158A2FB8F12BE9B7088D43A24072FECDD96395151270B9558A0CEE15ED8BF1A6AEAF8D1F86E372786ADA33AEA2EE9F2E839FE36E90FC3DF49A2C546FD2D61AC732D08148ADE4DA14F2831EF1D8DCA8CC526CE44E62D4DCEF337D6FDFA9030000678046FD8C6A628F8850A7A62E8206C6C94AF8EA1BC075CA9BE68AD58731FD5A7010E798562DFDEFA0CB79404582E8E8061DCE4CF03F62864A462B1A56C0F447A6F100804028140AD50C86363784573D8062C1209F572200279A733D35E661D8324E4F3A4C9AFA92FAF7DD95460CB8FC4B04E39E4F62CD1E6D454279879FF2C2EC14918A37F3D15A79702A1A12F00036717DED63AE777114867F1778EAC87D538FE9BDD4A295D84B28335507949393C20E0339E7263C04EC5F3632F4FF17F8C2A74571F319AC928B270A5B780FA7F62B2D341681E3B04CC1ED824581A7440AEC0186FA0521F7BA2FC959D5A768CB3E15D60A0F79E75B10D5BABDDA585D1C3D1F2E2E2B2052ED73DC9DF253029385CDE6D247FCEDBC302BE27ECCCB1A203064288804DCFC04FF6D2AF631B147953492FFC2A8EAABA5B934F6421B8574DBFD98CA8E23082939B5051B2F00B38107DC846A6AD42872306376FC633A86F45B11EFB2D164197E482B4AEFE76375CA5468945517EB1E4E1BB25C6FC65BEFDF7F603C92713323D808B2323BB5382BDAB323C6B2316AB1614609023EAD5A058FB3093E514EB1D99BE17C50DFAE86C395E77C34857B523B131ABBFC62D9B3612CBC69B7D1835CB421E7D284FF0099CBCC79AE517E2ADD31B76974790818FB9D0A139F167C9DD35532D5B031A135123C47261004E16CA587988FB874CB0D31B047D74878F84BF3BFC1D81F06B21F343EBEF539465A9BE5DAFDC0369AE5A65481D0435969E325C7794150682458095A3004A9FBF4704342B3FFED0FBC69364818DB2A2871C8B5AADB618BF7FF465A422A107EC063C2F44C8BACC1E7A10A0B43ECCED7209680D172556C9758638DD4C56D2CF5D9053D050D3944F8982F29F1516F7EB8B2AF8219D99BCB32DC1C2BF7A42382C1F0CD4C5AF33E42050C218DA121D3037654417187A012CB788198A168EE4189487C3D64D3A4C1C0A42D151C9E4AE9F7B56DD2F258D390746BE47A28968CD691AF3B950D1C2B8B1B301FFB8C8691AFD0DC9CFBA77DC3DB8D16DC5975649E10D9D663D833657E1E4C9D2BC33B8DA4D6D351487BFF3C6E5E807D8019E5FD0A4BF767832D3CD196FD704FBDEBB0849870C83152FF0F86C948DECDC7FA0006C160E94E195C3C15BBF564E74F6B6EEC28730314870DC65D5BFEB965F40663DF23242C0408BFBFC07B3319DEF31A8816EDD482F637901C6E153EE7CAD9E783381E104C41180EDE4C6A661799464B7FBA1894BA1FEB78CA957F20C038B32F6E4DCD37E2EA7F42E680552C0F933C0599E5D64BFF89F6F35934B9059539F098555F54F7D71406F401719FD37E7FC4AD04FF2E568F55525AEAD921A7BC4A87D5D4AF251F7820D965BDDA069F2CDBD074267748BB91A68D4BC10F827630944F97CBAF6018114A1000312EF2D68B756AA0A76E56F5D238342AA5AC86AF59B863E80DFFB8F54C3CAA5EC016CDFB3ECB2CDFC02842F8F1D3F446671CF844D53643E93353E8BC1597B708B621B9416A00D1258ECA26F7EA45C30D27398155C3451589228FF2A7A9DCB4C2C5E896FE216EB4ADC73BBC0E811507DC1DCF4B2FE555BA8C5DC23DBFE600A3708035D34B21682B75E91E27277F4E20790F18A16EAD353B77D63FBFA1410B7203E7751585C6B71F7A147BEFCB28D5337C3280067FB323F6BF03320BF6A649AC7C8D48FE3D2C0D8E9D4A9D1D41FCA37F6442DA1753914D0C8B2A8C0FBDB20ABC800BB5646012F786AEEFECB338A72CDACD3CBB777A0462210C6C5FA3189D23B84DA453C0FF1A9DCA10145BBDFE2614D34672E13397C05C810CC63CB077C0E0D0F75501FB75416FDF451D24BA3F1819AD236E7729BB4FD81B0CB1ECB0DA01460C4FF2B48E8BB8D4C0B21E6AFE77F914A9C83EF4B1DECC7763DA89D9513D4D19C5BC8C43933814A5FE9321DA1132ACFA3D3F3D3E4BB0D97A44D5C3D1789BC9FE17915786FC136E9D6BD5CEC07613C0D80B3F231B67C9501AEAF515CF39E7E0D4DEC53C699D13801F5D0E039D4E4E37A17C42B09D17F7754125A45580C845E0E45925944EEDE73C83A4362000C085FBCD787438707A5A579B6E315CCCB7EB346D5CAC79EB87EE5A82DE562DADC06388FED25752120A71D7BA1B4CFF23FE851649BD628F2D9CDCA8E36FFA0CD585DE24EC086D027B06E5864B4086026093A0477F2037E4EA76202751E381B5D5F812CD79D24B241E09789F86230E95D4891611133A6CBA557697793EAFB56254D308A172A4615483C01BCDCA2AE70528FA122C41AF7FB02F1A85E3A0FB0071B656E3DF7FAF8D342840483BBFA64173C674981BCFB4FF510C5ACF60184E16F5B7C9AF602DF438CA5800095AC440D4BC1DAE2B81914C5A9AB817BED23B1F3178963DEF4CB7F533EB9769D4D98B75F102681CBD16E71F2682F39A458CBE25A8BA968FE4976515FF157E1CDB79C1B144EDD44DFAB10838B14C5D105480763E6CA1F6F7679943CAD760CBDB128BA070F9F2FA03254F68B29B74E4830BCD6134447D7DD2F3018E80118AC0BFC6A01B390D2E183E15B82B00C2D40B057532D4BF026CC1244650112B600DDBC5DF3C5165001AC4721606801E2B7D82183592B24DE229E2548D41066DDDEB9253C4B90A1A1E9E54F404B90BE0514260017064EB50469A5A55A82EA0C4C2D41BE06A620534BD0474B50A281A98594B625C8E5E7A7EEFDC0A386A5C1A5DE985A4228C22C41113F45BDDE02282C555F4BEB3B5F0BD34BD54A4D0EE35F9625A822CC129C6A609A9E76C5322CA8C223E170F02D41BDEEFD892D4096A0C9C8F028B02528CBC0344D4BEBE21FCE12B41166093634300DD7F9DC29E05B1ED2830528021C6909FA7DDB6B5A8291C2AFBFA5342D4B306EC477EB94AE15F639E08E3834023B1C1F9F00DF12AC66680956B5045B1A989A86874352DDC13DD749592B2D55CBC0F4B38652B067BC7E8416201D0B6C0BA88E059D058857B204E73DC08DC3F02CC115E1D20C066F65368E1E76DE46343854E5797E3D8305A6B5BEB8E15DD057028B8AC2453FB7275AC5522AC9A4ABED09B08DB7BB8BB5EC58E854DE66E2867728D99F784DDE915E6E6783EBC1354DF9D4AFCB65AFF5E7FB89BF139CDD7D6B1AA0A6259B681169AEB1F7414B5BC75BF413A23042D5F46FC9B447E7BE1F4038F3B7EE125AC00E61C61A76B1B21AC89A14461DE62B7E40146633C6D1E189287DF51F02584EFBDEF1BA346CAC307A248E7F676D5EF25CB466622C37233B34AD720F71FE08EF2F9F1A0E6F88F43F7EF6ADB50134CF4F2DC7D1978590DD36BFE87D1596D1D7655BE44F41D8E2A4602D54AC8C5D4041E7CD22CFD4051DD268FCC4C24C2A9EAE9A3F0FC7F60E93E99E207109D95D4B674A2C52E4C979EDB6DBA4F3BCC0D10059CCA03852CC1B8B02B0967E3235AB78C12397E25F20AB7719000344AC5F4FB9F6B3A2D99858DC3FD3F51C66B4E81A7C2BBA1CE05F42636BF837A50B18566088B7DD9CA245E7AD8E4DAFCEDEAE81FA66BB6AB8189C75FC931BDED089BBC0BF40D027F00C623E8BCC400F11D605B689E5B63120706929ACDE1238087C9BE003BFF62361C0E87147A60E606ECE856B6C677B1F0D2E57F1911C3D906AD5C505C935AD1FE3670BA2D764AA5F9F1BD5B40AA32EEF1D6C545E5ACB9AC60DA54C1683C9ECCF38E67E2F252F021FF2E838FA4D3B59B4E24996F4BB6D47E4F5647E7DD313B8E837BEEE2CB89BFE1E0E057741AE4170201008040281B1A04F6034C448041936A908CC83B94C9DD811CFD7A09F84FDB505F7983B912E1A914FBCB0CE8A6011B104B6CBDAE0E7AC248E43DA322A2B843CF99C41F1088A3168F20CE2FA06523F2D5E41E2109C688CB80ED3C14B37EA229D5A0FB2609318F8EC54797735B5687002F87B0DDA6F557E197372A710EB0308C4811D6D47019A31315D03C07D0935D5C21A559AA462656A686EB2148CD33389950EA3A370BFBD94F28663BF9FA8754B0BD921F245864D86B417445B0DD4F106C6AABD210AA5D5ED741E079DBF7DC37C8AD0F4A255BF52B73B8C1E85A0AB0F544ADB117D5BE46FDC4375FDE05142187216B559AB9E9DA7D1E971CB4B220528EF2992FB39CC4BFC43D0E5FC325FA824542495E9B2AA89F996DE80DF1B25A55CC375DF2691706ABC8DA221C475B49B3779A8AC1D59CD05B6C6CD6AED1E79CD30E201DBB06DF99796612CCA6E7D0E1F5DE556A9A4F64A44FA9895F395955E9A4964693E17C326800AF60BC7396783DCCB1F3E09A5FEE0B2A785E074A196CD9B3BE94BCDFFFB7ADD3EEFA91D2525D5342B2C5FCE3FF9F44F6E61B02C5BAB422C9A24AAF8D19D533A4A10A171E2BF9373E2877F655E6AC825240D31062A9ADDF75C0BE476C41AA0500FCCAE74FBF0F59FCC8A262BB1F85A6E0AEB07159D4A25CCC524474B70B955A14AD68F99EB5E80F8970BA9CC6381BACC24C2A79BBA7A084A3E49C3773A722B538B1A0D7E9D59060258028EA5C48489F3AF37A3E23AFE2864188B83B635DC995FC5A74665E21632CEB0ECCC0118F0537C1EC2E6A02F31461031F2A11C57F2E5FC97021CCAEE729A122DCF8AD5692120E2235B77FB2EF861F92BF5F11119FA6FA1E9C6CFCCA27EB4F795E8CD2834C4BF3A9B40D0C72FB0485DEA32CD9E0C5164A9852FECD16613CFAB392A73DEDF9DD17C4C2A098C35C25E354B206B26A26E4E1216FDAEF76622EC79DC7168FFABB92B0A551D7BA7C5424A07AC2F78685560D1519F008118C6A4BFDC1DAB3F7F6E510F95B27E3EEC3055CDD81FE5DAFCB9E696BE18F4B3B315A4404AA3560B0AD187560AFEC98F1102039E85C0511615668426782A23A6B674D827C82DD0EEEA34C65DA74F5E34E0EE28009FEE99A461E8E0DF5855BA750922F698DF477BE594E8CC1F1108F2BBC077C79F5D08DE920CBA9DF178D5FD9AAFFD108160E33BEE6A7161911FB305093A4493C6D2FBE17D756981E262758AEC68662A855C014E6651AD4BA53F5F66847FFDA86B122A10F7B2013000BBBC44FE389C1DB45076809156FDC58CF709BC4610502DE84C2B898EC2808D07887D4D9CCE8F09CA8677494D25D1DA2991236CBFB0D31922116EFE8F12F775C713A2FC9F96B14330D3944D5C28196AE9EFFAF1068A76031105BD2175A8E18EA6B42B59AA6F273EB5BB3813750AC68E4638C0002BF08F66966CD5498B8CA8C4F805FCBB38F54A945E0D76A232E110180AF9610C60E9BF601F284F953765515801CD6EC0180B1EAD4C909F1E39FEFFF6A1175DC20E37B881421E2F7362BAB75AB0261E235887B851FD4764468C5ECF347DD583FA8B9D9BC6FB5702D644025A764964D50C7CC53529300153E5CAEFA6F988FE9C60840EC6A00D50F2C6517D97635494B61FBBBF15729CFD2C940B01102A6C2CCDBDC4D6A3AAF427EB87474CC73A21FDB246F29BBF228F06AF841D3C9002D14B8168D2906E871468CD4464B57D4C6B2E8FD32D4E275DCF646C94AE6E7E8075810FB26E92FD8DACBA924C00B39D76A1CF6EC7617A45E14DE7F96ADBB2FDE7CBE5B9FA013AE4DFED0777F1625CCC40138743B4CDC3528A113D36AC612F97E81ABBC6F20FBDCBA71D58ABA32A597A79056AB9FBF8D87A6131827271717181AC537FD2A2A185C839949A9E2659F6CB9641D1087E54F54CA5700808A395B9F38E8CF0C3A2248D190F411D19834D5974B6547072A0811237213752F81075B1B9019F98FD1D61C201067CD8A67F7F9F36F9D663F8331853EC4B3BAADF32386CEA16E088A2F678EACCD30368065D09991C6F51AC6E8B18852C7BB9D20255193FABCFF0CE383EC6A87A8517C935DAA090C70ACE55C2C10BAA1EF3E4AD683C5F8E29F72DEF6844336BE6062FFEB942FDC17B5A995A6B105EE0D77B0D3E4775A8F53F385C2140E9C7996EAD52FB9DEB932E2EEEC4740D761F759D2D0599C4E8D06E313F234E47E56C9FA0449FC207BDE8EB3B027CBD4C666B0A8715520C4825E29D4A6026E464AEAA6205D60586124D35AE169C6B4CE603B147C4ECACECB0F6ED8CFE61F8E09D3EB4F578D1F8207828A2F97CC131B853CCD94325CB73106455C5FA3169B8D047B68C3CB58017D1C3194E7ECC17D4CA926980383314B7B70AE67C97F8BC9BA12AF907ABA03428ED969FF91F9C05600D9A3912D1A219E57D63A45591F36D0F8D43C4CA5A34CD3CFF19142D23591ADEE903823E7A4480B3592345F3274111389AB0CCAF3C1F3BC6273BD38E88F34F7E8D8C765E03376D311A4C7BCC9820102C02AC1C05D07D174041BFF752DB6FEFA86B1AFA2B36985035C5BF425D3B384A2D2A2A5C1D5F128C82AB57D360769FAE8CA3EAAF8E7A29B033508E55B6131CBB7BF483FCD756175C2008FA04E703EB5F404F301B0AD83B54BB6A180436331E98CEC31D14BAA5CF99E7DE84BB4166A2BBAEE2C5CAFABC4485500CBB192416BDDD53EDA7F83382E76427F2E47BBDA2213B3B13FD2BE503811320359A2C5A5E7A58BBA0785FF72E2144F3CF8DB0D9FB9E25013AE1E9AD24873DD905398A8E37EA82421EDB27D532629DD9A9F46B8D907A38F0412A5EDB00E30A27339691EE52273882A6CEEFFD0DC96F5994C0E34CC40F2CC5FE7B03435505DCD98A29725C62B703602004FABBEB854CED73A3D76AE159D1BF7037558782CBB83BCFC774A52557AEE25F00267A0FC290A323A5F6B0868EB6FA845E6D79C6477F7FB8C941B1AD9C67E33177D0434CA72EF55E44F803C91CD861A9FC80B51FABBF2B6A53B32B1404752001C5C02585568CC2409D728736960D20AB8890E9E5CC7C17F95B86A38238EBBC1AF5BEA0FC37A74B5A1E80012D75A4959239EE0B16B7417B31B91983BC2DD4F6F6D8EEF3250E4DA1F2334B64809E0F430FA37B1AF2DBC644E7295D5A6E738B4A95E69185C56474A9A2915D712908040281402D0E9ACF0E815F15EC629D2F6A5AA96B38CCBF01852870C49033ECE2AF299CC99168BFD2E57E386ED8D7C0D831680D6080501F87AC52BF98428A4E4F3CB71AD72F6E6F9B212305FCAC6CEA45C945040E04DC7201195CCAA1A5EA5EBB69C755848BE3CC063EAB7226BD102A4070F8933363F5623682CDB4E644620AEF96C3862223B872A5BEB1DE8A20528CCA0C7EF54C3F76CD42E2190B6EC3A93B9186162515C0BAC015AE98B70B26350C98353BB2D287768FDED130A65980E5EB66549A1C31B71584F7829ED0B73DD9289C518BC2FF737D1C55B27E4C7103682E863F78E20F26CDE0903368BD284764097A8403A305BD709525A7EDE80FD196F4C4A118441C550D1747D71FC71C63747C2D00FA7F03A5C627D47983EF80113283667C9E84E8F2355425D9E20BBDC61D2E75F3F94E7CA18F5E11C829AB95214EC773A5E897A8BE0628AE7F9B5D4B58B4FA2ED67A65426F150BE57DB0914F3F80EA5DF79538D4DFC9F65B29589C85B8800E7181F812D4E1D4BD3EFE0BE6EE7E3D51801BA3652A42BDBFF467BBED919F9AE79FA6EFD2BDAEE6FCD82323EC61C8A265FA0A0570BD9B0D51DFF2619D5D0F0383E41A0CD605673106BCFA782D40304B3008254C2FCCFBDDBADF106282D4889F3D710410C2547D2D4B3810CC126431C6EC1A561E21F9259E67014294DC9724554E991E51534398F52AE1563B9E2528DA1066BD97CB468D67094A1D6CE6DD486B5DCE1264CC849969A09F1A617F6D0F4BB0C9A03315321284FCA6A0644B70E8278E282CF46D147B4A0B273B721678F85689C3A91BEFC00204B300A5EAA5FA511952A11E511FA95A1620AE542D0FBC18082C915EC21F01776A183E24D5424ADB02C74A4A1B16011716151BFB2F434B4B4B0B1F866F09D63714B700C124C4078A2FAB35622ED9354B22CCC094CF026C01E2BD44CA27DE50C7820A9CFAAD2B5880A806E7EFC0C0D4026C41A5031BAB2E90B2D01EB88534AD542DBD3057A0EF332B9C60F8FB07B300594210C32DC11B06A63FFAE05B4208C32CC12FC3F39F0EE14907C1E0B40C6642143EE52661789610ED01714145201962BD2F10F14707F96C680909B5840819983A636A929A407A889E6888FE21B184D4865942B25D450FD3807818FE31968F259E4D9D5360DBF153DFFEAFB24A7B7E12995922BF831E73F6E45FCB16838104EC577F0360E038C7921917F5CBC8F3AF957307D5E10571CABF0CCF8452E2AF75DDE8B6934E488077B8629BFE9030D7DB6444C04DC208A60D58C156788EEB6FE2AC4B675D72ED6517B81704853C813BC22B9AC3111E239D957F81A2C02E6313EF11B84D72999DD1A90AE4EBF5EED0ED86907B677FFA4CCEB3425817582EAE54771A0442BBE435D3FE1426DA87EA79483620BB8117B6E2C693A45DD03607D548163646A8A7540F7147F4F487BE7BFF05DEA1D505171263704DB940159561993644CAF96A79C2EDE1C1C92BC0E5146E771C0D559692CBF454324834B9768B0777F976BE5670723FB590311512368966798900E7F6DE980F86FDFAE9C1D092674466B31F2A3A2052D585D6880C5B333E523CF62E7826CDE344DDC21A7AAD7FF420BA1B5187BBF8390EF53E232BBFF9D089E4DF7681C421A239BCBEACA139F38B648B82CA27A2628AF56C400F7D05081185A3196667DE2B71DF735BA886430CF37ADAA3640894321905D36935D9E6A1006EA8982BDCBF9F5E00747A365B15BF8B97AA620ACD20DB3C91B05A66A053F6205BF55D245A38C1A9F982E41E2E356826EEDF2A345562DA28F416D2BE839263BFF4648FAA20BEB7EB8FF90C062DDC587C78DAFD18927841B17EF142FBB0C945DAA5118EBD383BB245C24A4A29DF21D22FF6F3311EB1C49EC5CB4A54A8D8285173ABA0114E7B8A862C410D61BF86926EF34489560221AAF9F72EA4CDE606A7296051B26BBC51967653AE0F1A9D8DF29BE2CE41CD49E32DA2B20D27684ED736F20B2D944DFDFFC810157C63C7FC175B4A174875E36B4158FC7B07625C860205FD0218772ED33753C85E00C70FD232843F3704515D37C2923EDBC5AF709E754FE2EA18142FA78A8FDFFF0677C17B649777F21BFA049E0B0767D7590322ADA2EAB0BD301BEAAC3C33508727C6C22C4726FE5F7BA4E7E436B4988EBCCABEBE1A250BED81408426775F6CF799114474E5338BC457FB7E950D77E1614215AC1F9374908056CB9356107038DCA7D37DC1B46E4376569B8C9ADAB03A16D81FFE64777552D3625814678EB6F71E3424451D60609B11A764C59D323AA156F93D997580E69630C08348AE45A2BE3F4E37A1F793F7FB23EA7BB19B4E1AEF7EDFDB14190BC91D3510C01E5F37F715D0A7EBECF8B9FE4BF90A435DA7B4F21FE32255FE99BB8FC2F9C9BD2C92A531119D2CC31DFAE82214056681BF9E5DD7A8E229653E3449E65D6D2F39C39CF0CE8E8CA796045CB3EAFAABC84BAB5F18303E7EA5CEBC63D5BC616D3924D1FB8BF0577CD09CF3B1C0B7F68AA3D8201140149CA9B4815EE8936E74179BDF826CF75DB12CE86707A96F20632ADCF395E42B3CA3189F0131AD164CA690217F4DFE8A7970D84A441ED3939F8F81C87CF98A86D175812B60DBA79570410FFA1DF78D19172D54A70CE78E3CCB0FEFF38A8D16AB1247F1BF9B144E3C72E39F801BF8174E481E84B68ADE67E8D9C89F51DDAC5F36F9AF75EF2FE2CA1266719B56F4A47B3ED0C7EBF08A66AC418C67141D527266D787F666FB65735728CDA7F7FF9608194ABF3CEF609D91021AB4D82EC27DA4AF528199904A03C35BBECE26C206C040C213F49ABBF7EA38BCA95903764661E5BA4E33ACE6AA95275EE5869E1794A408A87DA86FF7479BE9536460E697163A245912E71D13E651ACD9DA6024280EDFAE82A82B8BE6B14338E11BBB84839717905C1A87555FAF13C59567F389AD9FAA39DD65CA2E30C3D2F9B3E4A767183D16CDDFC6B18B55A44BF9F74D7B4DCF4CA7C839B8A3E8705FD69FB6748CEADFED6CF03220812A5AC18CAF8B6B11F497B58EB361DE8E35BD3C686294CAB3CF2282B8E5F8169F09158B378740DAD2E51722200AF0BD396DAF4CCCD64616AE41AC81F8C8C6BB7C98D4B30B26DCF1FEF0F7B06B330690FBE7F9B52157FFB5BA50F56A77E8D722DB756B3946DFD723AE133485B5D9CAF246BCB827D6D5AD916A2E30460818A8A1AFD1A8830C9FBDC35AB59893FF946293256FE6779372BED594DD575B534503F6363CB42C868944FC4654A8B4CF26E3A076EE853B7E05C4AD5FE8A84E12A9845D08772605812F058193D67B8631758032F565F5D16DC3C428ABAD64683EF50065F1CCFE9EB02EF8618463431AB627E10B8855C1EDAFD4DA89E08BEAE16860C6669F5EAAA668BF60DA59287154F3721DE05D2EC362B12B3F97610D805FAA44AFA2864AF4822C4909F8C141E8E8C3535C55BE8428C2A0F2A630DBD2641931D3DC9C47E142E5CD402FEAF9943F3E8EA44994E4F8BEBB0D660BC3E37444E3B358662E495D7F228012C0C532AC39F7F7A7DB9F41B7D1D1497840F104B3FEBFC82211A10C8346C5F42B26FD6FAC9E78B4F496B34F548BF5413C2087C174971FEA45EA82E02C084F50650C54C8E0F363901FE2CE79216EA80EF02DC88AAD303AB3717CFFD2C925B0025018E0CA277108E02485DC8A31AA1FC5D77A12A7C15F4D89748DF7CE1CA844D00FF771EC55628E1C6D788A16F003164D58CBE5498E8677E35B7EC87C23E597061BA965481362950E8328612AA9A6E4568A998119396164B703F24E67E63A9AFBC40ED9AA79F3EF9EAF7671D9EC077133C1DA6579D21B4603E71930B176749C412B4DE348EF8DFAC50603A78DCF34A424C324429374FD7EF600833CD31CDE144B524F92F313F20982F05E36A9F0AB2263953D17BD45665D8E95B683784589F450708D349AB19933B0398E85CBE057DC25875478F43B2DF83B757617F97E02150E8C365FDCB4330334790110DBE3B2B483196A127A640DF8F0EE9777A5735CAC1FE3E7BC634FBBF84CF7EB3E042359B3ED4CA5FDAE94FFEE9C8C1C08EC75B63C515FD556DB1985743561986224A8D2F51E78465A71A6544E6EC13F7B6E44D169BB02FC287671F53E2DD150549F1F54C604A98E9C0DB74533C246F33DCD0E6D2015E5481429CCAFCF51396D316CB5835F470C22A43FFAAF2E61E7F00DFC323190DB0B49338B0F1C6FB88D9FA2CC35D9213C8D48531D336A395C9406B36B91F0EBCF3309A2D8D0BAE8FC3591F4194DD68F49F40330808C9E0DEF631637C5FE8449DC4FEEA86BE3C993DE92B9701A76616E2DFCEAFE0C005FF793669C8B65CC61F53DBE7CE89EACE34FBA2F677DDA378FA38DEC88743B075D90C7CA4CFEAFE328D1A44DC6BC2CCC2CA8B22330B2FF437011FABBFCAB0BB1B41967DF261661C306650264C93B8611120360C0CFD53BBCB7E63038AD60C2A260812F401DD68D13A665903F7D3D98E94F5F860AE06C20BEBDBCEB775C5D5CE7B7F259170AA762BAD3FC72DF8F6CF3E04717287783A89FC1246C034A24BB58C8AF3DE470EC0EF3B432260A8AB0D6715EAADBFB261FEF11D63DCB8D593E82388C1D8770800128BC98DCAD111F56CE56F03F79A833C9049B11F77F9B191EB80AACF3EB59FFAA04186B7B140EAEFDA80A4B466C77FD65CCCDE4F4AF5370C589E5A8E9AFB71209D73F0AED1B0BC3907B92C1D81660809D859D62A9682191E2140135BFFAF0DE57D9B38E54AEE6585F7B542FC181490F802E5B30DCBA80A33A48BCD0B3583D8A5942815C75443CB5F1A804B16645BF215B875874E0031AC131A4C25A18A615E8949DEA89E7F4484C70FD1EE4CE6E2897EF2B0D54A30082B53C26070DA59393977F5F225633BF64247F72ADB86A9B0496893C5A2BBFC88D2375446805426BF09BE5E6FFB542C9F385ABBA23EC050E69E47C10F5CACE53AF8650A6ED6C38630DF065BBF1F8F9322A6E5FEE7357FC444AD4A58D46DB879F57EF05D67685196ECC740ECC94A27AF60F07C7BACA316C2F164E7914318AE807DBE12050A7D202DD59A2B322673405A9FC470DF1FE56D0A4905A60B863EB2CD9FC8120FADC1FD243E25FAC1F637D066040DE73587AA5D340B19D7798EC78BC203D0195CD1CB5E44110D1797D1AD296CA38C0BFFABCB03A5331AC8ADDB130DF0763FDFD8F5830C7E2D3C74267DD798AFF52365DD0B565F462E30C44A1100DC0378B8ABB948C73C38DBBB2EFEB3D62C2AD348449B46F3E3CB67061DEEEE22A0352017A42345CADEC650725B691799C3AFF67353E6485498ECDFF1956FBC1F5B0C4D9E0BC737E99CD669ABD91354D98F059D5E454AFB6579AF16F01563903F963F277CCDEE9EF1D1C22FB68A7B160F6264CFD3C291328CD2A9EA50BAA53F945D6EE0BC6BE5FA330C7D6676AD48ACC85340ECAFE45E285B694078654AE27CD05545B62A295BE311E6E29FCDEFB689B77B4A45EB283D09B479E0068FAE33CF8912D2FE36F91E1FF77172BE06FB061DB48A176729CAD888BEAEA6EC24D2001D02788AEFC8B2A54438C9987E93241287FFFB0EF9F5F5012EDE07F828FC6B789910D87A522600C7741A05FB2B556C0844AD6F5D9416BFC3E40A1EB12D4B906401FCD564DC66A8E076BAFFEB1A7CF1363C68969D8C87FCA6620A8725D3BF02AFC00DDC1615090557B280E35C6394AF84C221AAEF8E211611478EF1F7CD97C2CE01FC9D6EFCD191A88560D497A3DA4C4654C07009E695521894DD323789DE349EAD0799FCCAF7496A87F4C35004864808362FD4317D2518844D52F9AC10E21DC7D7629434D142D4C481DB655764814F479498DC59C68C1A30EF554E21F9FDC38E36DB561F47828FFE38D05DE9B5B3F47135B8EBA31D25A719E1BDDEB36A97B8BF7A939C0FE1AC318400217590E107510107EC556F2B8EC8858429FEFF1CDEE386FFFD849FD149F47822988930369443EBDD7C8CC7491B978FF6520AC0BE120D374760274BA8AA2F08684E9B10AD679423FA4383830B766AC501C060A5F7433C494F51E08161F2123AA8BF563C931F57C2204D051E5FD81701DC3016354CBA91B1656D5FFB2C01BF13DCF5CD2231C55B1B634E1244DE0434528DA359FF242FE44600347EB8439E1D99183C3CF0CBC55EFAE54A743F90F15B6FE0C9909FE9826C86528F157380BBF0C3AA475326D5B83332BC4D2855C4A21ABFEDDB755936CA40818FB0551D44F2B02C97562094026585DAF15DD26A07EF75F336F39AEFEE9BCF20284FC005952E3E0628AF26CC280BF67D649AB544773B9147194589329FBD145CA2B6A1C8004D0E93F616944DF6100A1772B0EB93920366917283AC54696E34277CB4F9D980D134DAC3B27834EE0530E75314DD025A5C3177C7755FDF9D7BB751979F7CB0439BBDA1BD42606C040789B92D5DC9E09045F66516328F7F331BBFC50397BDA7E5742DD4E58C0BC7410105A353B203A59934334DB61A59304AD42ECCE94ED50859D5B3E77E9E03C7E339A056452BD31C813FAE856C2AE38C2D850266CD487C7D6D5184FEDF2C9EAE4FF63BA6D5EEF630C9E6B2EAF6F8410AC1E15743DDEF0F5E6C8C60923D31D0EC210E1F12A9194771E1035D68F84AF696785B515801B0AF5747297D36D32C9A7A0180A0D32CA568144E5AF5D79D7E56B2CF806DE95881B5D40218FA753ED98B12585D4080243A1F512BFE00B076484EAD8E0B4A41E0EAC80E4D8C7838D0F2763C1969D5BD82D33F9426200064091FD64BF469A4EC029A41A2F0FC6D592E6B7B1983A1BAF6739091D977BECB100885C023BBF1BFD7191DB719C2225E642ABBEDAD031D75068BAC029D8C3270C4E710D02E3419FC0581170FF6C4E80BF4F650251322316F211914CC04B46ED443E1C3A493D0B83410CF78C5865C38F465821F25F889CB01DDC4A372279CD5CB9E5D1DB542651BC8110C197FC388F931DCD7CAC509E9611D91AD3E082B03F8A647BFCFF5821EA7E3ADB379639B49BA616532972494D808127986778416E506DC679B671ED7FC0DFC48E2C5891FDD5394D23E19566143392212F77F30479D86373DF850D3E28C4826F368F530E077E1D909543F06A5D12F41A1FF418F577FC26CFED3FF060513B4FF82381FD2118B04876DEB6668041D9DCAFE28FA453854ADB4A1F4EC8AE36372CAEC8F83319B60C843C857C2725DD1FBB389A508FE9958C754A8D826DBE25307D61275A325D2A5E474C68D338D997D4E00A36949272969516623718D9E61D0B177EE286661D91D4D760EA300DD40B03DCC8B17E73733C999B3FBD63BE92F160E3887EB8CF60F7FED11A18962EC25632D105E101C181402010E834CF86DF41A6B0D05EDAA3EF74B456DBA85FF3A9B14DFD6F1FBA7E0FE2D67BF1A00797E16704F37F69441791DEF1F7F0BFE3016B43BC0456A246E8A6464B5E5E1AC9BAE69FA2BE42DA1BB4FD712F04BAD05605E1748C2D221C0ED140B8277A61F26BE27B0E47194BE956E4680109173D1AD24BA11519BC58FAAEB213205D2388A409CE36BEB13C1B7F2F895C6D9FA3C5DBDFF07422023B22631876C140F916F6CC78B9799E8D624F70AE0E610B602F7A1388F2561345F9F4935B9B37632D1FF0211EC4D634000652354238A29F325EF145E647F2D4BBA7A2B85BFF4C7C99EB0BECEF635C8C0DB10218D3AFCF6FEB8E7E2FC7B18F81E822A8B5B20DEE5582E12F6137C7D2B7496AC45DD00A101C08C402B8F2793089C5E21ED7E715525350263636368EDE458B9E7F474AA7F92AF38348367C78CC22F3D7E26810A80B8E09A74EAC11ED62E3172F42A7FBEF64AB58F60FBBED8BC0C1440C3B415BAB82BAD540AFA1695EEA042BDFFEB8ED4034E38749C82DA34B151A1BE87E14C9AC12FC96F4E2D210CBC8E06D236D00877F35D8060416A894444A3A7BE5462CB45D96878157FC1B69F8DE36EFCF416C234554EFFD5F1EBA6927027EA99D184447D74A820650B8E0B62497698B020641FC2A045424995121FDE82184012E1A938C311299288A0FB2C266CF39CF7F0006181387BD953A8E6646D999874519BC05782F4A3F1E3173C8155A815EA31142BB01B3A30884B28ACFB4ECADD23C20C92B38D6429B4607B4EA20CDA09FD03965F13673A34BE8E35FE944BAFD8854612D80B706219ADA4F2046A705A05B1DE8D43F50C5E38A10F77A1DD79709EA1492CA1DD63C7EFFA67E5CB9896DF3D54F71CD13D458745AD73E7364C088880398C608913EB24BE2A2383F20F5BA48A1F7F7314E4855E879614F23CE38967F60E88268F5F9D23C76888892B2C98AB971BD826D31DEC05C4E5144D12D47A43E33E9B52ED6A93EDA575BEBCA9E47D687B113100E60C09ED417A56225D76843AF84D80C8B596F6781C00B3BCE97BE60E81BAE876F671320EED252DE7986BEF9E7B3E0B7B070CB8FD1B601B21BA377817BF09CEB759B41CA3C940EA08FBB1170FF6CDB47897E9684B8DF1D4B875C3013F171A2013BB38C7961F50D4E6DB1925C1CF1A740D09544C6A8022182CF15B019AB1B3C6D210AF847125E9E51756E3A5D90A7C4256A56E7F6E5B64F67F47AC5C3F7FB8F39FDBE1B8099F546AAD5CAAA6138B927A1DE77861E51CEBF63EC60A949810BEB21EC97FFC849608B9A0E93C6C6B1EDC2210A68ED00E7FFD0977073A33DAC67093E6430A51D399F0B7C79C162AFF8ED9224B309287BFA1BF287B03FA5E5CB7CBA58619A12FE57E5FAF3AFD91E8B9F4404395EDD1945EA63E92182F651234D663151DC1C0255B175A12E9F67720DAC6CEE6320AA76952B582C647A037BC6FEF5099619C75F052274971E34E6B2319F0160B9CBA8264B21369A414E05A47A41C9ABE2E8F721477BC5CBE0668EF4090330E09DDA533621B265DE7A5D0456FECDFB6BC9679F5F95A1C998BE842A905DEEA3604090771D655A5A769E19B808B17A4C2250D5AC8AFBBA6A9A78BCD8C74E0D2D9057FF3041470D431386E54A75CA4EF5DA94612272672D3E594F9BD3019DEC751CAA711CD6F2E8E6E32ED2CD6B652E36589D70EA350D28E11EF9721A03582658F867AEC091FD84A4B1B014A2C24E99D349AAD10C241B00B70537DD89C79FDB435AE75886108D81EAD844D17B0248D1BBA6F321316C0B3AC9BA335C78E69A6DF2EAAE27132A422DB7932CFC3A48BBE024AAC5897C14673E7920369AF0852333012F577D67F3D70E6CC5BEE46CEF6E4235C7E4118B04199E9089D598F5878A69361A2D94EE2C330BA2B8F5D6CA1DF4A92D485E6FB670886D8AD82F9522427A202F48942FABCB76CA7B44006F0BB7C6BE3C5313DD32AA30407A73A3D43060011C1DBE089D1889078C8C237DC20018900CE72BFFD61431E4557989C57F7FC7BFA18CF896E37F8E3C4AD13F1C5E45990DE8B9914AC6CF87680D104851BFE3399D306F9B259F8168D2D6DBDEA99A3707DFB6FDA045EC1031BF66179B7FADD1B545D16181758444717DBB3077AC0E781C6288A925F84A2F0CF10FF908A327E2F8EF03A6B219A420619CE4F6C4827742DA4FC385EB2C346672115F919ABD3329920164533B8716FE63B34AC8E8AC7027650295427A03FBE3D2B6B288C0E59FE294215CA10BF2E6C92990C72B87435C7E0F80242960D2E5908048F2AA9C04EAA81D9095201FE4D5BA24EC358646848FC665122F35C4A3E29EC7FF5127673DF928EB47BC48BC66F1D7BACF071946172245937F79E2FF6E0DC2F31304FF05D4ADD62CC50BF88A85299B879DAB72311BAAF82131F9DE139B861B4A1949C6449DF320E8E3343412FE6EF7C8494DC2E7095DA7CE02C81BFFBBA753F6960A36114619A055450130C8CCF9C9DD0EED69783BF5C1B0B8733B6E42C3333A46D4CC429B71DB8D8F2EC0EE4D7AF2BD206BEA57685688D0806E7D9569B3752EB3A267E47D9A94BDD1AA7417240F04853C4132346DC495F946E3B38764767F1E76410A33603A3637E4F7DD8AFDF1A7C4E50DF709A173F2C389919A36C75456EF15C5915498307897B34370AD3DA2A10FF7BA9300EAA8CC8E3396BCC7B5E803C2E1741EE8E5D5984F3CC4DBE2C6AE8A3E547F5360944702BACE17A88913FE93DAF384132D6B3E3EDBFC808825C9A71B242641229470C4E9458B4AF6EE19C4A5AD49812F10DD02C954A26500067CD1F7100996620E1ED98A48B9A68BC7F295B4304D9374302DA5B39ED81E4AAD034C8E360D1FF3007A5343790F7CDA4499CCBA048D0413CD00ED3BA41DD879C56C17E4A003263180F22EA21551E7FD49C07AD80B2D18BE365B74D4D787363179764C24060E1285486620776345299ACF4E1863D0AFEF532BF14F29181D0FCA3F67F265A8FCCDCAA164645EBA3AE5DC32C90B1AB1BCC62116CFEA643867B6B806B47A51AE286B9F49462F3F62A55A60EBEE7E1975504C1E0247E4987FC9EC669E236259563B84B62ED845DFB0DBBC59E17598E54B0251FEAD4D06FF4BD4BA1529CD59B2F28125D4FAF055C0E84968FECB7012939AC08D660CDF92CB786267216AF68A8CAC87572ECE1F92DFD07F2B4600F6727E8EC49E3A1CBFF1904EC88F4137A21BC9085FCE75DB5475585EA57CDA2C3003FC507BA5FE5D391C62E6CD01F1859BEF6C5BDBC82F42194BADD59AA07798228E3F94E1FF3B91311B1482E1E70EFE5397B79EBF2E0B29C431973D16FDB2B333884C98CCE041453D2800DB734D1B6CEA3D8BFD10846DDADC590D2D866CFEED1102B59B903BEB721B7CB706788C7D66CA0B23FBC0959595AA32843F1E59948DF99DF2BAE49E55E10E4DCE00B99B761557455C0BED30AC93C4129C73DB6BD117407C62804609CA99994DC1EA428285FE019182E6EA3CAFD086DD646EFD1BD85AED1FFB576A8F441CC12375C5D862FE1E83543F6D24F7A3B10B09495ADFB689B20E6F79D3FD52C50659F35594AFD22BEBA97B185065003AE00FFC3530379698144161E42DE03070D28AB87EC13D03BE6504F536630124A508BAA69810C110061082DC006B95F9346B1044D7D7DBC151D7DFD243E069382330242630EF348E3CDF1D84F81ABD3A8B63F2F65B832C7F30296B1E8A6F2632663F2AAA7A0D5164CBAAA96690B11DD1E860BEB765F9E6FE040F46648205F2036BEEC8EAC7F8E220BE3CDE6DF99CB4A92962FB5E015BD6B1BA6CC2CAB31AB1EE02A678CF06F81A8AFFF8E59694BFF2D1E5D4A90A2D6E4DEBC50F928BC04CDBA7C06EBCD4094C389F9FE37FDE9936B70075B58A0B8579A6AB22CE9F843F4102A6C37FADE09814166A1611BD1BF5D14AF7B6138C95D38E6C786737A83358A427CC242E6215D7081AE91D5C78B29FC60F787ED01CF729CB1E680052E1186532F29A0DADAAEBBF0CECDFDA1193CD94668A05CA52DF554A1DEA55D43A7B697E3B04879BD8C517DBFA9E2AE9E6B06C9A2CA2E4448C2592459C230DD535830F6A7A6C2BD717D361EC643C2D8081AC899EC1BFD2B2F660D14A481A0B639CB83D864895609B6FE338D3E07B350232C0A714848E3C95DB8AE46B41EF6CF157E4B829F24A4FA2AAB77222A3A904A4B002D11B78A2259ACC3E3A9069355217EE7F5020D120BB612F2F31413E1A6E03872C3A74826C44E21884056F18F3153ED35099D76FB7E00AAF9AC4BA5D2A79A5386EFFE6551E65B501E7591A1BFB07BC446C565C429735D737E55384F0296B6234C187EB1CA03D556E4216CBF6C5DF3DFEF174AC80F070EAE062E8146219284D91104524C38944B2D73D08C31104221192FD611104E6E999EFF822755DE86749B143C77F76BC83E12A4FBAC4609D0D5A821B60D3BFB5DD2146D2C9446EA2A118D596F295A3A5CF3D92BD30756612651C2F8557E5FFFBE4C6F534AE86AB05239F88550BD30C421AF57ED91B3547EC9392593FC69640D82365AFB067F40B5600058477A9C6C9422FFBCD49DA4EAF24A89EC3B7FFEAEB8B2926EFF9E29B08AE35C534B1AD765C6169BB39619239304DE8FE0796C4F2E25DAAB144ECD6D9A20AA88C2708FFBB0FE2AB9FAE39BA4E582F7D92149FF6030E2A59DD85385D82D52C263B9ED6B939F26D38A336A53F98AFFDE10710A5E8E1EF4AFCECEF7812654E7CFC90B7105F18C2228C79A3938B0A19BF60D4785112D42E3CD345C59F53210C077DCC7C871E25ED6B0A0FA381EDF7B870F9FF86CB4D987826612B3F0C0C7DE54CD309E26983123631ED97B392B3345725CDEA633D677A45823E8594A046B6BEDC9983EC3979FE2DA57EEF036ADA0FCD9064ED2AF541DA58581FA8279B5C6FEA8C9917DC6736C53C66829BB32CFFDC8CB058DE8E7E39159FB9907D4A348071717F9B9545B61A64A6008893A939702632CE5B6C1521F115720D6D92953B03AA675328DEF036650265CCAFDF9037CDBB10E0897CCBF5CA18AF9EA9E82EEA99BA20122038100804EA10A145EC100E286017AB981D7A50B5E730DFC039A254C4A48CF5AD4F87435310672ABB7B93A3A230A661F414A8FF5B54CD125238F1FB72B50E313BF99F819DCDD070CE98791E7C9E5BF60F4E8B1EE043B6D5843423E2A7AB4C10CBBADDD50BDC374371AA84DB2AD2C7076C29677C150A8BB6D0426541BB5ABEC2C92C115277CA442A06750C496335B0E646B6F6D9C46CC9A36BB6E5BB5E325B0D02AA98C3000CA878CEFB405B4B760B47E7D4514F22798A1440CCFBD588B8FEEC38064E895317099054D8D08F355746249B7030230E34FAF2D4ADA4F3EC1E7F82ADFF9ACA8B27629FB5C6D4191D56BD97E15F0E2CDC2637A7B47B6DBB656B6C47EB6451C5D9F8A724A7936CE3E0760780C4D3166072741254CFFFE87F3EBFDD4FAAEDA46428F4C365C024D9E4565A3A1E73C9DC09205F72CE5093894ADD32EB7B3FE6591716384F19E9A96F432FAB609C52361C1776D5AAEA34C3C60EEEFCB528DB4476F7A0317B2DAC517F30971561ACF367C28B1D15214DC69F6E7AAF8B2E4BDE45E4F28CFA7396A257CD3C343F4964A91D289DF8BF20A0A4D2A61F34841F2E56F1E576F2C6031FBF30BE2195B6EAD5D3B649638B0618B20C156C1FECFAAC73D191982F56933750D0FCDF14A0EBCC440018E895964AE42D8CCACAFB57707A254F0E16CC31B068892B4CB5A02FF2ABF1992F05641AB2759ACA39693C8F23420780B4F8F5041D5AB37677C92104C40234E8C1B976F93D82EE043A058982E8A11ECCE23A52DCBD427E97B5FBFDBB069031C9290142D59393D9F1604E7A9768205D3A646E07DDF70FDA473F1DD9193BBB816E63AB8FEE0C9BF87ED604E4C10F3680D0540FCAC5D0AF76ED15642AEB6D870DA5532414FDC64482DE0E9AD7EB4F8C1C5D70412028E409CE277C47E9CAC938FE0F450F015146068DFCD6EF4368801A87A9A0A0D027EB401B7DEDDEA90D7583CCA249BFFFAD594D3E87068FEA52FE9BBDBFC563A684FBFDF626628F51020368D2145BE743ADA350EB72CA5E0662EA79BE61B3FFC61A0F169B44CD61C2A4E401503FB75B0928B099A2D54699EBB94D36F813F41A5A06F3703D7F61F6DEFD10B1D905918B8C375881421E17062E0E48E6764EDA6714EA87F54C683B3633D3B76FE66324ABA9055787BDC38C59ACB04E1BD646962974E6BE9A5072A3CFEB7ED3D9CC0E00E1304744E6131E03106542033C00035EE578596310DAF212F18A22071A740385F5491687B73E09063218ECC05DA3CF03C6E3945F42A8D258E30E2E099A33EF10D321C65BC501807441A9F55C12B47808A2DA1ECD6987E0A339BB78531F6D2CD666FCCA7897913E4814F1FD8E932ADF7FF687199CCADC51242D3558CCDC30762ADA020CA8CA258317377354B929184F1471E05A7A8FB1C0DCFCA17868C8532D6566D6F8047061C0A6B60824A97EDFE7B262FD64649B999AA187E367D3A374CE8D9D2F90711BFA4AE07D744F608E702AB1488CA316D85191BB214EFB9A5FEE82A8E9ACDCCD7963992E128B6258A3B0CEE1CEB3C5A3B07B3F1A891CE993287EA360187BE631534F19C6748D95A5BE7FBE12A31184551EB845990A69AC45C5D21612EB1A014F5BDC4A9714C9E09D11F0D41D14CAEEBC1CCEB090A94848D60CD0965773A4EEA6B9FE6D3A3533B15292D90B0F14FAC2654FEE173473A622AC35DE8528A82B3A3DB02434816DF07F7917F89FDAC4E080816A2AF8A0D027810A365037C82CC8C992F1E3DD7885020C409823E4C732152B6F545BD0B52AAA2B9B0D36BBEABF56719BD341A2E1CC5F9407485BAD628472BFCA070A124B111AB9A2FCE22496B2AFC6F5D7E2E9168D774F77450A442805C23B157BE20AFF8D5A4470B1746765D9758187F3AB070E4914112FA5BD905E4EF88420D35ABF3E227C95E9B3D48CAC87D890240D0169DF6F24688E952AED3BFAA7119055EC6C7917DD3D34C102B16E1093395185EDB0180003D4C676297AA3F5E8753B5B53DE9A0AEA222C4A2EC0C2977902869F67297BF5AC80D63EBD908E35FBC855C8C427A586CF23F6AD293049851A9424A5580996AC2FDF20B4FE689E6A417EABED83C73E0FA85F3400030EFC6DE1F5F097D1D36E8AA3154E7A7A2CDAE5240AF6B553BAB65F1ABF22F5D300B4BD991F7E5E26E382C2BFFFE73865C08DDCEBCA9795269A0EDB326053303AB070BDC9BBA3ED3B64AAF04F469BF40F53E9712191CD3C385862207CEF0551711B328CAF720907BDFE1DA08689064BCF0BDA9D232A9236B641457FE8B9035CC57B5C09F2177E90E2D405320FA794F45565877253D8005474B8BC488F275D1F0D5DC016274F2D07BE18E797AEC154552EC7D28B5F9845BAC0EB3D1A7F10F1F3283F48755508F759DBF0E2722711D6E4EF5167337604777E3C4C25A64B35BDF8D0FA53E2FD13C8604485035C286B036427628B29C7FF4B9C25798479E57BB9E363D1FD1D4B08B51BEAE01E1B193209DB22B0C3B2F6580675E8C128EB30240A22FD895CC79505E3586A7C7FDF5C0E55D067F969183D0DC7FFEFE882F1E86F267D8183B3CD656AC45D45D88F3916A279E9F9BD7AFCBF7F7C7507D0EEBF0C68C2393445CF18054615D09DC6DE7451E8617C2775488C944BF6D23AC115BAC07C55F66B734680C316766DB4AE9E58E665E427F5808C61E3145A05A1D97EFAB689539E56BC5036ACD2F433956A86C80FC937DAE937EDC4FBF2A889A42FF88CAAD5A4F89D7FF7BD512767FEB453DF0D1CE2E092181A60A3F5B3FFC6D26656864ED397EA7984D3885FB976DFA9650DA3DEDEA46433B6D68F718D378443EA98B5889BABBE9672E9668DA9F2248A040414DDFB7EE38C92FF75952264D02C8FED94D56D930120FEE95D6B347C6CEF74E6FD95CBC9972517EAD743FFBCBD979558D2CCCCA5428FCB3EE73CF9BC7E9874718459371933AFF70E18A9877DAA3B04B6152D455014127757B031ECCBAEF8102F26C623283FD7466D284BD916BB9984D609DF6E9FDFB9E2C6B49082149FF7D5F14AFD4BED89F75ED0D90C4D5BA09E699F4B9CAF710C92E8971CBC54D6E87C34478B31C0A2B69249A86C3F64FCA59D9CBA60E52323224DC68B462CEB57BCC9E4C51371570AEF8A20357C87C3F889952993FFF9BF9F3C4F4437B79DF8891E9E74C70D190444FB099F3F3CEA2E049670DE6A9C13CF140BA02AAF40548001879E4FDBE8B41384BEB5411681773232448CB686491EF1B358DAECF5E4A4F6CB80763305CB88E6CE4F8EA697E817BBDD3EDCEF7283AC3CA2B144FB422F453F67CA3ABF8C05B1F8055458AE82F3D7D2F2A9EBB6050E43DB92AC4AE47E34169FC08908E76BC632EC74A7BF5A7DFFC7FE108AAC0C69B98D7F6D3297BD00CD87F6D851D40266F93E8C848CC173461E5DFF03B3A9763AC45692B76855F9513CB29D6C85F32CBB30169FAF00E9499191BA3D6058611805C2BC78FBA50D39F7481F9541F4C964FEBD0A0DCA7666AA88D382A3EF9EF8D78176997C59F99058DD4041E61E7EAFFD1F7F5FE4723E1820371241EB99D9769E09CC1FC718CCA1C34D887F1323158462C255F6730E53A60D668E1B7AE60CD389A589BF1A5F6455F3F40720480D34A667923081F93EB430289E12E1F25A547517995497CA9CFFA671A6D033FC3B97154709DC09E6FBCB6B81FCE812361CF2032E1C948E65A3BFA07C007930E9CD14C882C5519F07B306F93136E2C8C7E227A17170E38E207FC25C96CA25E1000350B88CBACA93A78289D4AC425F306AE8FAD3FE6FA5620CAB62D154C578D820E1036E1E5BF6A253F8F33498CBD0500BDD1101A33BA815E15EB4D0923DF3B4B99309127BA88E7CDAE667E578DAAF6A2B0F530C186B95DB6D00B4FA06EEB7BE0EB24A0C22B859C2D04F5BDDDA4AE151FEB9452D8C213B58CDE0C7AD475802449E2DFF92470512616F2E9B87FE782CFF8EFEF0000C10799899652AE73EB487A260E2DF87FDD8FA68FF4DB27F8810F444D6BCCE515301F01BAE8D9BBE737F7A684FE18BF0596B5A123EFDDE6FFAC68E4AA3D45B9F97F0A56CA0F9EC10301C63970E752091EF6FADC3DE7E321320CA45BDD2DAE18E17838E5EEFEF174403FCE09D0DF268F474A8AF6B5D48E533B07FB8DCCF278130A5B9AF535E90F92347984B68BDA843775C10133068680F407447C2404CC7C503376A649C302DCC2DCE342B96C81FE03C4806ED22A1F95A5FC3F77C0E94D268F9569DCCC3D9ECB7CF7F856EF5996862784B569711588C48797F93930FF4DA72BA4FEB9A568259F3ED1CD50D26E0B39A53E1539B58D666414B6BDA45852F29BF2478C16D58560DC84ED7228058AC7BDE6CC2C17611DA18465863DF751BA7D15D6C235B598DC20DD20912FF71BE84B6FB013EB7F47D1CA1DD99FFD9DF5E1FA08F37761D7FCDB1FFFBF0E56660D8DF3CC51173272F7ABD6D759524CA2AF5A0B6CE29FAB65B76F4C7575C7F16CAC451AA3F291AB46F3DF76129F55BAEAE70BDFF92610E8DBC380BF910AFC6D7243E7F346F4091DE6FE3D365F88553CFC53F9DE802476E9ACA8D45BB12C53DC7A0D47A2D6E30F8709FF96CB7CA7387C3455AC9CCA511FE1D7F870A7658E3E5738D7AC6492F5443DCBE5E13D0825175523B688D2FED232434513DE7777F1667E1CE2066F686A959825C4B12373F2EA3B6F9D7063EE2E7A75C878EC54065927C0B898B62D20637A143AF3E71382BC0142D153213DF2A4B2557BCB62B5F182960BF87DACC9F6D9FAFC28ED850EA6FD8DD351BB1AEE97E0D7F28E471F671C57030FA3299C7E623546A9A78CEA47797504F6B89F382BEA578C32416321A7FD58387508001394B92A89F1B875D9BA9D7DD7BF05D5CDB7AC420ED2C38C6EA15DB3714333FEB016E45F66A167319DEE875AE207FA26260A3FCDC51FF869EBEEE22837DC3328A8042F44B17AE798430CB21CAB8330AA3414A88642177204ED9821C460CBB3B1E6CB11EACCF8988FABBB5DB16EAA7F055042F38CE696A521E29C2BD0D22BB8A508802F083189947F6BE6AC472E8503A738BCD8BFC1C5AA5F57926BB451E1D53481AB500C403DD33EF0E95EB397EEEAD92CF0317834916D378216AA71BFE53AE3E1283A210BC2F5DA4D68FECC787D150CCE5338DACA48F899350F78B0474FEB03B168B23D58F7859859B1282BF630E59BA30F56A178B703DEEFE24FD3CD331441445384403E88FE0BE2FFEC169B4550F97CA0AEB0B21457AA0CA9A6CA4C5A4C8F744B7CB6520288676975453B2599B62847627C994EF01DF54E4788EBFA4B61DFF7CC4AC8A089441BECE7924A5BD81A77736E499531C2210E5354F46A603D1AB567A8F3B03C7AAF02CB505350586C904F2BD03F0543F666A608AF294EC58C5EB34F58C40E2920E2738C7E8E1D69E3313017AEC1F2409841088BDDAEE55CAE5051E4EBCADCCBE0DDBA23C5A58120EF220366A5F433ECC42E80AF61FAE2B7DBD8578A5B7CE48A9995D2F09D209D201CBD466E8495CCEF9270BA1D3E49EB105A160A805615560B6AF32E2EB40FB8E9026E59D1AE179CA570E44C2067F67103C9ABE735AFDE58ED9A5B3B6DE4C9A34C12EED05E803A8B2B656C37CA848F3EC0339FB508EE2C3D3BA16295FFE6F9CB1AB4ACDF9527C3667D3DBD63AF60CAB82B1F5E74A61D0671DB604CF9F4B07E299757389BCEF5A843BA4F863F0D1966A35B611889C9C9D00E7DB3C5C3ACFDFD6292A811589EF713823FB3C0665B3A608A21AC6980FCF83A12874B3A776C4F5C6C3E4789F4EFDE2F69F05EA9B0DBA02171608E8A79A3464AA427932DD7CD725A60EEC3C4B67DD41804666FA6CF55203863C01523836BF69CC1D0E6731537862C38F666004C15BBFAE0B81659085F9E57AEF8FB5DE9663BAB7958C26C1CBBD94D6888DEFB69D0EA3FA0CCAF554F56DC2D092C47CEAFA3CBB4A21F5C5CF96BAE1AF2FB5F49585A1320C497D8CC7F31512BE2B8B61850764BFA76A03004BAC93192C6FE3839653985769F8A8E7442076CBF5E0C78F88BE9A876CAFCE4542F9501EFB878557758E656F4B265D7FA7BF9245F2BFCAF8BC7ACFA7CECF0125FE8BD195E1789417686B812B8FE0EFD53D8269CC4CA725A04B6D44C26CBB6137F3BC4D969E18E3513F594E270050C9176D555E3915AF95D98469E35109A4E605A34DFA08E913B488E7699BFC8D3542D01D206239533C42B15DD0A03089A2AB168CCB0DB33AD127539AE555ACB7D8AAAF331C2FD5A5ECE48FF351C767F00CA5F60511E396389429EF82BB53EBC5103FC61683EE4738777B73E1DC11E9F8B1F20F3539B4FC469C688B97C16EBF5093EDEE74D001A095463B534C90C3379ABA90E15B494C6F4D960A7EC4D3E99A9C4050443E5B29353D872D4F0F56AD164CBAE2590472507D7ACDF1E3D0DE913C9BBE916532571FCCA90BD6E28B7AA9C60495152E0DBF2845407663338ED83FE7E7E067A0C781AF83D4E48282CC48669E631F9997A6B57AFB0642F38A79EB7AEBBDBCA4B801919329633C88D6C9527A9A58803819D264BF96D96D2118532DC983D84FB59F63856D140A51403E050DDD779DB7C1703B96C92967A675BA45C398898E8F1F1EB0D8754322FFD10086BEB845170E904FFAA7FF055EF4632E17072DE385B0128F69C2E98E8BA937D3E04939A9348E104E6C5C6D2787BE0F98DA1FDE849F1B5D6B882404C3BED01AA37F682B68909871E2A1095BD023B8D46D9BF8EDBA7C29B6463EC87B66E6C4CC2AF8E3A545C5A2C6CC248B4BC4414871165C910FD5724D1B3C5AFB0F5D4656DA7ECFEE25534E80A36992DEFE4BA8DEC77EDD6135F6B80FA9D7354F1CA19DCBB6417681E80A212D5D705CAD3B57F334C9BE46CCCB8BCC2F3B138A9A2249F61B0D66F6D9B8E3650FCD8F0959B0BD2AD19BB7EC078F7EA8FFE0C208880258207E7B9A2536B830DC3537B48F5F228BC2B1B9FE7AF3EB0CC7670869ED89E0006A95B00FB0B80E0E3AA9F7318DF9D59D3E30546416AEFB2CD74D1EF6EA4973245777E0A70B153C425BAEC89D7884B37899E49EBB877227049D75A82A18F6A530ECF6A199BC973C66932C4DBF96489FC33095E40A40C592642EACA84064A781D02E54DFF8A01259A0445D70BA147CFCAC23AD644B20CDF9C1BB0CC1CFB88178EE696D05805F87FD8CFD6C3B38CDBE46EFEC2B06A634DFA019F8E7F261CC1EC234E23460098A87E260AEBDBEDC34B20F54BE28410EEB99CD55CF7D3BB2A5EA7282B34E55F88075D32EEBB9B7DD40DCC872A2C1AF5F79FB4E2022A1C402F7147E235220915759B01275D850E6B584D065335BB2643B5EE19BA7517BDE89B8E8EFD90BA245DBE12176DAB3556B9F5EF4C8C71F0B5D08AF75AC299D5570AAB53079811310C92FC6B5D87C1F1A19B496991773091D63A699D79F9222D716EC3453CCD975DFB23B5E3BDA8E546A2242104E3F43A7E75B86F39740053808B89CF5A79D18323389F0F827FB48E9A5772519671C502E67A71345542DFCBFEC871A018C5740D174F8637E59DCA7F0194C5D5DDD123C7F6A5AB89179A197A5D196CC62A1FC3B637CC64C75EB1228FF4AC543C1F19AFE7D76F37B4645B8351F2739FE8DBA66E97EDE4C0B3A96510F04D023A1AE144947362B087B0BB7627C321AFEF47886C2C46DE275D254125E8273C102B069185206B3C28E6A7A95131CEAB7F03D3B8C4BFF7B221BF47D18D09A235D2042325D9C9C6417576BC2A3C19F13AC15A14C8E307F0C9A947084ACDA4364BB5C3ED944682464EB2119D81D49177B1C00033C8C139B7E95304CCFFB3837928E1B9D884065F9C287D8CFB62EFEF39AA92BD68027E25ED1FB92FDB00D7C6001A3F137D1EEAF132BD0F51663CDF2019BCF46ECF7C65332FBBF529F5D6F61B73B792A983255792F722DFEF922A9B1459E8A94AB78A85C161B8D5FE7BEFD807891CB38A9FCFAAF6368AC025F3E2D9EBD543857B5A8BBC387EF0D1BD00801F3A84F37A63DDA80E8447CFDAC33C531ABE57C3D238DD0AC8E37527A2EC505DC265E94AE036E22263CDEE7BF66A566D85D1E2668D5F16ED69EE3136D6EB3A4CF2064020901BB2AA2BA3DCAF27CE08313019D541F9CFCBA4794D9649C8C6C7F57193A8E9E4C48AC2B4E46E185A7F74912215E0F155031628D93B773DB1D919F77EE6F838F64902F4D5EE3251A196AE9F39A476BFA4BC40E253664D1B24904916F0B3AF51B6FA0DA2E77A2301C0C61DF185E4D6BFA851B8E8C527DEBBD8A9883D133D0F2AD3FE6D56A6FCA7F35ECAE2C9BF08C84CE65A74F25CD1D73D27C08C99A24FF6A02609BBCBDB4CA0A693CA47D6F21DF18552EE8DEC01E0872FBA2356B70317ED346BEFAF51C03BA19CA1FAED5293FEC2BB297EAE2F71625FEF70EFFD7C5C85AC18F6217AA14A75118DDDD128AAF7D41CC14D278CF83F54F03CBCB0D638E50E7BEF3A210351FDCC2FC3749B940419F5269AFEA38F62360BFFD65CC3049CD64302963D8D8FD376AD19954B12BAA2B7D1DF399671C24AA18E50F15AABB0EBBBBA535632D06A69E973F36325CCFFDECC42F0B3308367CD56B8D38FA35F1D5F58D51120D986D55BCD604B09C76B3F8E30E5C9BB0D8B6A578FCDEA4E57D561663B342E6A9048C86CD6BF40DE3EA92A4A53F348B30A41A854E5EA176A5024FD70E4E62A7FFC4BB900AA7FCF167DD62028B9D33026FF9B209D565BEA6D696512787FD141D20AAD01477916770DED51A17EB76B96A54FA713693046048634E2EA749DD556093D2FFABA7E75A015CDB0A1B5C5D5DE77D28E38F698B32D169C569AAC34C124A9579CC11DEE1B5FC7B0F81E713A2D51FD8C7EF5393E91897BEBF2A8CBA3E79843F200B741A4D500878A7C076391FF321AB812FAF187B1A871392E3C6BC1BD3C4842631406906D2D612632FA9EF7E62B3B489D42AC6CCA0C1F6A682F134B10E2A0ECA21F0ADD38ACD8D21054A3C9340A96E221D800142083FB530B6F8B8832515650E475FE77A1CB753B0C19E23533A03DB1AAF3AF70025AF7E07859F31E94AB5748067BC0C6DA1CE976F3A8DB05BB961863FCBC5160F28004B55E228D18AE160AFF6F5B30C9EDB61E63C2EF16D8769208EBCF2965491C0B539B4F5503B0665A46A80F5B9968742FFE0CD85560E3555BB0A4CF54F2EB343F9B671FB98CA4C94C03C8169F609A686A16AE94B4D9C297B7A94C6B8896238DA1662D8A382C58BF957BE38FC91A1D5581D88F0F3F752FD30AA546F9626E6B48F58592148D63E7883F6EB465AA7B3A322DF68779ED9A8A0E39D01F5506B7427BA3C8557199E041BC7766C2813EFCAD9C5E02D21689C6A64F3718BA24268DAB535066F8104DDE93580CAFF18AC1368240E27E4A97C4917B282FB483A98B5BEFA2F93B97E940D680ADF6204E8BDD8A73DBB767DA70790DC6A3970AEBDD635A6DA256454EBEE375397B0DC5770A7A06BE8E36504029B7756E06E8393C6271398E6DD7457225EF0A6B1320C6479A3C5181AFD0CEB8C547814D502CDBA2DF73601292C03AFA35BA8FAF322E68A847F1E833477FC27A5625D1E352372A8AEBEEBFCC25B077F758C8AC14D33E156B4FD6F0EF8DD73BF355868EFAAFD92E5A115836F4F1E4DA80FA6FC40D0A53627F3964E8D2C4FE8D6DE42D6304B2AC312D75F84ABCDE8EF959F550917BB2024A7A2587A6A8BB067369C9AFA8E598E78E652483A052F7A8488492A3F22080E17B69F05A36A30914AC294C4E2006673730FE52DF251C9CCDCFBE85E25D72DC92355D4C0F828FDDDAAEEB007FF0370B974A6119E7B35E22A486766BFC9335F99D9EEB7F5E0915A3F668740DE676D0004F1365D08FD19A3A9F03724CF4EB38F585029AFB880BB0EA2F9A662380EAF14F385EE57EC4EBDE301F96DBE9192EC82A0AFE4DF5D27B8A4893EC52EF32BD9D14FE30C7AA58DFBD267A589C2CC9DAC8CA6B59360C80F52139DAAF065B2E97A720E176A4980F5F7C8CBD00893E83CA559D97A62B9D446AAA022E6C1C9CFECF9833F5823F4DEEC1A0150C8634111347C0088D12B42E5B8CB109812594B6BFF6A0006B0114E061D97511BBD1066C1AD6E18828E1C63C3D4309536678395FE97FD1D1D053CCCAAE5A157A6AB39F9C75741C44BB404654D9ECA9FD5E9BB1A0B17A3B53E1C8443215D605310145231930D103F7691E1532D2CAF8E1C2639BA4C14A311039550E46302A0A66671B2FB772A8D7D03058C9D89D600061E9C01E3F9407ED4E8C1CFFCB05D7DCCC3FC2F684328FFC13D5517F2E215791F0001BD845EB8A2C343C5CFF41117F981D36366C9D68AC0AC125C49C86BAA19AB2BE25179585BB6142142C040E5E1E448BE05C14E90090E92E9C31A544C73E98FA0B874291A7FC567BC2B5D4E40183E2FD75AF873E94BE17067D1C53BAC4822A4433BE293F97478F3ABA2A14759177C2B44AAF1A155ED208D8D1B0210D95E4555E8304005E0720A9D92631919B108DE0799890E12C40B6134F38CF25399E2BF40C39CBFABFC4DFC97B1CF8EEABCD2917356B9F43D1B4DB5959696A801092948C6940A9AD48C0C2C02A1EE42DE406A70546E326AB82D01B397CEE0BF2D7E1C500BF4B131025C351E89803646576C75A3046BB73C3ABCD55F2A65B35610C833B157D310857161728BDD5B8858F30E5E09FC21E9CDB4FAA8AEE0D64042D7F46DF6A9D5AFAF1178B2BA989F1F10A6BFB0DDCEA6C5C904BC032E33A4033AB63306864306B1D2D50CA3BF1FB6D4D1A0F2B148D1DE193A112453D3ADFE833E5E84C3953F7E361A475B33131FC5E8CFD177C7E933F26E933F9F085CC703E985B128911EB2048753F7E3E46BEE111E2EEA34B851E2A174B731C7CC9656AFD6AC6C8C35E45D3677BC9B808EE38C56ABFAA8C89A26685563CEB953B6D722ACBC9023B2ACC0C86B73C829DB6DA1AEB0A5A0E3B18E455A9963461BAC9A69A1418829E3F2D3FB6D1DFE45947E12FF7554891201E87CD93864E69269181A2A2819084BFFDDB5AD7DD9D02C54297F06AEDE8D57C916F6687DA08F9EE1EC75912DF3E6A0B656AC14831FC5AEE9C54F58B5F148AA77605755CAB6426B2CB8FD8A2CF41754C4F856319C24E5733577E7B6CE6A49E39D1BC46F23B962E0498605CC738A68F4A1665A02F443AA2322B48EDD7A484A99C6B3FF52949C2B00629F69B59A2DFB9EFB9194EDCE6B909D6F23C96B1015F13D589F586B12DA9A9EF8B0BA9EA856B652FC306ED0AB6784FE643F9C240486009FFDE1DD822219FEBBD2EF7075FCFD424BD59D71745FF8C78EAD5BFA0F76CA766517FA9FEB35EFE3B691504528AFB4BE2ABEA86F58D87AB09F59F78F58ED3FE517BD4F9D76B4010E572B2B44C199808545DBD3D1DEC7978598F120765A87F66CACDBCC6F2790D2E1C3DCBF23DABBE38837B2E26EF9B205F57326768BA92DBC33D3DFA3D43A922F432439724C6BA899B167D0A219EC54D844001AFEFF3DBDE6F707A46C944452C5930BF0B839F906EA881D750447F39CD871EAD079EB349AF497D545FE5C4135DEF66A8A2F5F3B12EB8F86F829945F315C2008EDD6BC2802C634499F770AC4BDF9534A860DE81EDBCB88D7E05ACC802020A3F72EA64076BDD827BFEBFDC3D8243646D13CE862CFF29FE025E753B32644656E9A50B76EB6FBD0F6962E05E8F153F3C33FEE6595494DBB83C1FD5E9C2FE3155F1BB79C72F42DD684158773427E009858A36B4F7EE2A51077AB1BDA66A1FC82858D81170FF83DE24D2DBE1F1CA58DD13209DAD0C1CC2EF617081E480CE2B04FE7D244596A332487565F8C5FD8EB297545B951CD9408DCC1D859080530E0D93CE010465729AA2AFB69C9F336DD477C383155C9AFC4E4F0B5B8B159FA3E19E0B2DBEA7D3474349C9FD86E1469544053B894E865DF3229EA2EDFDDACCAA6504332DC8F8A4F707D1512544EF75BA155024376347F2D04A5E96FD982F8B4B3B87E75CAFE84EDD556148697711E1E68188DEB88255931A683080F6B32C7AA0E3F8EF4375CC929316C9D87CA16473E353F3123297D566BEB6B214A5E506C76964B3E6C12175ADD6CD540978A6C41604397D52DDC7EE4B41F69A64446B88082C0245AF11C1AF1A4130969E7349AD3D9529CF73412A2AEF63B5E1EE86BC21E32CB8E09582B18335EC70C7DF93DB3B94906B3B33F636F27B7E0846D010680A730F18DC9E5706AFBE88EEAB5C979E6DAA015B44D629F5C9A4602475C18B301BF0FA8CFC6AA1F57DD93D4E4EEFF9B1EE56BBB8D0F584A20967EA6A96F28F58196D798107A4DC81338E0A5727EC9E91C003E074FEBA827EC0F3FFA1CB4B17C342DE326C4E6D44D75B8972691815620E3B7277C7B2EDC9B9287EC9831F39611C95DA7ED9D1D33EC8AFA6AA63DEA5D7DEB54896138F72FCA47319667BAF6B2463E7C919CFDACDF1B94B402E1C60A197F021F3F7E62742279FEFFEFACE73AC08A503CE404FD50DB8BFFFE3F95252EB22F16693CC33692DA0FABFE1E678AA2835163F22BA988B3D2B4F8C92817E20E8C1302D2F09BE3B62AA09D02FC9CCA3A82B23F2C28A0BAD0A2A88F270A13645CADBFD39C262FBFDD4E64F6A2C324F82B45CD85429E5033C22B9A7113343CC35461F29996DCEDFF778B2B9E566D4E07A492E5903AAC05DB615DA874F157BCCFD4327243C8E8F219D7014B6266E77A68D9899C8AA0C695DCF403467F200FA345917FD22E8C2B5B6A5CEF5B7C7FC295580EA12F9F6911282D89BBB05F7F2C286799783E1EA635455C96E9BB3F11012B55EBB79A961C119E2AD2872D2C69D481B44592F7F46E098E0BB2C51803831DA3421E04786306264AF660D6BD8D8878E0A72EB48E6E943D7F57EDF61B806ED4A54831F9856007A06598001037483B781CAC1F93F84719FC4E976290810F7DED48C60B87383D642C29C735A2346807703F0A754388C908D402443903CBA0C03068138B0F486A3ED0D20734F3E147406E08BA46828232B8AFF1B2CE20E7B05F8C950F30E1598CA42AE7BD5240C6FB1E852C51619D087CA70971FE92BD574FD1A397FEF7AFE3685AA66400B2E4E0949C814D36F08747B041FDD383F8F957D04CDF76B44E08932169DED2C194850983AEB3A3F739BD3C820A18096C04B2036CF7F80FBC60BEE184EF2F1F1641D309067E08A6D175F7F5B2B6A511A1B1B10DF0717777F1A661A3917675F775F35176D3D795A311A1E116E0E2E0E5E7E2E115E6E71610E0E6E7E35DECCA9ABE3E7FFFB6FC421CFC02823CDC822DC2CB252840C346A3636B67EBE565E942234243C346A3E06269EF4D23C2CB46A3ECE6636BEFE5E813A8EC66E74E23124CA36A1BA8BC9E4745C346A3EB68EF66E9E3EBB553FF87C158C3DDC957579ED3C9D1C5CB4940C5C5DF58C69ED5C7C84EC056875745864F438ED3DDC3D5D352DA5BD3DF52534F4E53805BD18BD3CA95D798C7444BC89FCB415746C6DF99DFD15ACEC54ED156D14D83D35527C8DEC4C327D0C52940DA905FD5CD55D8933BC0C98D9B554B5951514951D7965539C8C5C3D22DC8485F4746DA5880573150CDCE5BD7CA55C086DF9A5590CF9E53D056504FC0DACB93C720C8DE388855904FD952C9993548488FDF51DF4D4FC95D4E51DA4B31508FDB48D35A48963BC02920C0D088C7875F5E40D7D25AC7D1CA41584E43D398C7984B97CFC65D404ECECDC933404FD0C3C9CF4B57C6CB9F4F4E518F2F404EC55ADAD9DF43CF46CDCF59D19B574B589E57DE465BCBDE3D2050D34AC5C9D295C75B4EDD483BC8C7C9C15A5E873F88D5DA8AD5D5CFC8418B8F8B5FD9D8578547CB4E4F55D8D2CBDDD9C4D880CFDAD14BCDD050C08E95C743C35B8DCB5BDF5F5C9C2644E79B91300003F236DA63777A5C9EE71D0A67CD680446A8C28553E83BE33DEDD20F641F44BFC5011637640E931DB6A1D81A22305B3DA5845F1CD164670D35EF75B3CAAC5A5BB53967DCC955ADEFD36D8D08E75FE0294F4D3394739FFE4BDA6C83B42F55ACF65F84EC7F246BA15D327604681D3C83AED3B4114F3DB8A04BF32B9BF34F1742BE5F2C5C189686554750A1A2A6144D8237A081AC45B0E5C751817ECF3730C4D51135FADF0701795507E35D28B7B64DCD5594C81B6440218F2941E3648782A7042AC4D32582584224B311EFE90A6CF17ED34D522E76601678D6C0B1800FABF839FFAECC9F0FD68F9ECC7A99074233847F9A0DCEFC9793E78F1784C67C5306C040D5A88F5529AAEE37AF8C66D0CFB8B16A5501C5094A44F6A9F6E472E0A1457F07109424AF9BC06066422774BF3AF4D1A2264AC2F1B629170DE5BE72E6929DEF73EB82DB02C18140144AE249ADD064067A2073F116E1AC5868BF755FCBABA6DC1C7DDA9EA2661D55DAEB69AE8E1F5C2992EA1B33FA69BCF1A018CD1323F57F4E925EC9D6582AB7E279DB52ACB1DC7FFCD89F0114148F7CCCACB2EF247619175B79DFAFFEA5B1FF3756E34BA37E057F54C324F05BCB00B7419FC04D11E074C79D3FCC07BB0399EE1AC9DDEABC9F6354DA7D02BEFC9832FDB2413C913D3C0B217F407ABB04F2A5BDA904D35FEC20982BA9E88C01DB2B03ABD02489DAA67AFD1BCDE6D8708DBDD8D9AF2FD673A9C9C835E62AFCF7CA038FFBECA0B2D39C41D2AC5D43C0DE2EDA725CCEAF7166F4FF07DF4435F090AC0E6826CDF6EB9FF1E510C78035BE41374F0AEBA7D5978BB4B99E8257B35901B8BCF6A468C65593A0B4C1295D73840AAA79665EE74E4980941717FCFEA6ECFA44ADE8FBA3A3E153A8BE6F8C653259DC270DF8AA75EDB4EDB37E80CD65CD250A445CF1DF73C939B48F1369693FAD4929FE97ADD54868FB30D8EF89A208765AD60E81EC4FEC62AED2956ACE6E39CC03699B28C437C6CE02EBAC02482288170AFBF3AFB096F71B183B1B6D000694659E49D16F91B03FCB66914773C04C430F6CD7F0A9A44175BE89A2721DD01820C4A49CE816005F0D2C664DD75CA1199A8D55F37F5F941DBA76A7A434C05D687BE1C1C053D6DD173752ED6EE9920FE5FFD42A573EFBCD0BAA87800614FDDC0C03CC690BB32C0B4F97FC4B81B74D4E73006344E2F76FEE4BA7CD23AA6E650779B9A8F3E4F60F0A4B4EB53EB20E5C5606F24C0167A68053F2D14EC205C08CD6A146863CD60A792A8D8B1319F8A3995AA02DF38F2E65B6026D73DA4FD68503F20DEDE11D4C988A014F0B2C2684BF46F428810151A6CEDBB53F74CF4A08BCE1F58AC8DB523C44E54A7FFF25E36CF50A27B550F9080869A82FA47EB0A057717FF124730BEE7E259B69731502B359BE23556E3948F374419E2E14B1A43E51D51DC71DBF2D35F3A1AEAEC58A6CE129237196A99EBAB82F0323F5BBB3C11FB2EC01313FFC5167C88BD0B8349F96FE437099CAA08CF357D28562A9D1A10FA33DAA42DA89EA8434C31D35DB81E7E8325FF3152F9A3E37BC76A82309A5934197D7DC35C37CF53B6C2E8F74FE853D782621C1B81A86E9686E786B8D3C885EB1E0AA4F4E9D098CE4BF9066284C338AE7128D5AF908DA7D11779D00F4CAAB195E3496F18F68D905A7FCF5CCDBAF4AA75CAE753A9EE2FFE303588ECE84314BCDDE610969409914F74DB94AD728A1D3393CD17D9AFBFC4523ACEAD0A44F0E93974863840D3CF102048E4BFA6FFB162C475824F0CC9AE617D5AF6DECD2EB07D8DC40E0A92EB0A9336AF08729BF8DA0085E3DFBC9CA7FCB4FBC9C43F3C05A3379AA30A2C51F7761E4187771C32B1B527FCE5CCF8CD397BE2211D4C64A8D4F9E709C2343A7EDFAED789970000C5C0DD63028499B196A3B11974668114FAE93092D74194D108B81129B24DC7FB600ACF4AEE13D211CD1E8E8CA7FFA1F37152B39586C79019EDE2EB25F81BF6907736B57B443D8C09B4D7621E3B3ABD0BDF10696AC5F214A76FCE16866535DD5DECC84EAA7D3EE5A47CBDB20183D07CD4F1333FB21C0A861A74F07BDBAA44AEBE5B67D1FF867B1AE672D9A50B95E479100886DA3965705FFA11557EE3AB2925C6933DA33FAC14BF1B3C16E1DAD41A1DB4416B3A19737BF1B7843218FEE5114C9C662AF2D21C5EE2F4710E01F643A169AD3F207357FB74D986F85792C2BECFB79DEC0225FDB01890130F0F73C933E20B1A4BC3DC99669EC3B5B6F9E9169981A561466E6744800C8329103E0ECA5350E668B1C31AFD96970C9D3045222A22A056B5EC461323CC4A377DB939B2FEC5E08ECB1A98D298ED259B6843969BFDBA4BC94CF525E531047C7BAE47EB30041FDCDC829923D4C57DFCC8A5699A40CA9BC6C2BBCEF08F482F3824CF964654E636E800BF727C23B372B2FB22F8D0D78159A6925FF1526269EF91EEFA4CEF619B4552B782337E8A333D5550FAAFE00D5E3BCB266289D623259BDD073BE74DD6A09F078626EEAF730581CE3EF79D6FC5B06746DC3910345B791149E74B710B1A805C2D085947FB61F37B653AA541113B704EDE35092CE2D5D0AD116BE744ABBAD1F79106E359EF39908597F66A85A6B97CCB36ACD5BD8A2A3C5CA1F0268B221401FB3AFF87D7ECACC311B9F406F5F63FDACBE459BD9AAF38889C8E05017F891E7A0C0197A4EDB51F13641DA6C19D4DFA271EAD3D6B1EA93AF86E48B99CBBDFE13CFC76FDEB738FF3FDA5EE3EC26236B50225DCC409147E16A8DE0D73FF5BAF962B811FA207C38FB29973CC1A5B7CB7E3CE6481C4186A870FA4499E4C54FADDCD488EBD3E909B7857C9C7A351289F2958310B67D7011780760A8EBB2B88B0FF399E52D0DF254C665EA4FD1259282AF4D6129ADEAF5C4E6275DE0FE0BC5BD0542218FBE1282AF4C24985B493E13A5335F32029FB259EDCFE44E340AE762E07C905ECC09147191CD7FAE3F0EC080622BDE6193FAB2535CC83C7E445A52A46877CAC0088B137BF0A916814087472EF0E167EFBF98A841D3972E1B95800F49792B91734C82BA4DB3AFF439EF125FAF63412010080402170BC85C6B8FB305A7190FD3C2967A333B85A3CFFFF41C4F95CBED3355019B8658C78EA0344D16A4BD7DA6E550A1EE47FBD2BF0DC2479A010C8B4158046FF8AB4B6863A492D06928B092094236D72B6DF83C5851CB51536550B3FFA8289A37E4D9029456C23261A9BDD377B855CC0436965DD0B4B074ACC898AC7E09C996CC5EDD8B1AF5C228E94A8DE37F12F2A9C4C3C943334004565A532729017C3CBA3A664CF67EF4ABCBA65A524FE1F4F398783DCDDEA341920C1FBDF0556D84DBE9CBFFB9AD64F06163BC5518B1BD59D8126871E2365E7152899D12A81F48247C591184C518AEDE850239E3758E3D9FDAC45B84B609DEB028F7C159A03B029E656402DF3F3DB4C75237A2DF6EF0015E8039B5E01AE50A7777E9CD386DA5FD312CDBDD4458016348B028349BE33F83D022FC5F2D83748FF3D2CAEB1AB2EFB32CA7E7C4FBF7C69FA73A4EACBBD5084EE8E42BD487E09D911B80CF9A708802BEEEF73B8EBAB972674DA17EFB4C9CB9FE8B81AA48F677ACD4ECF3DFBD0A25CC72C059E3A39633CD71DEDF9D37F49467C0F927B17EB5AE24C969DEA991F3B3B38D00E76C2259980D8D6FEC1235FB7E19FBD2E1B0AF29BF08A02693523FF113B0AFAEFC5610FDFFBFE85BA18216F368F45CF43CFE3DDFA2F4E819AB8DC57521AFA9CB0FC1F51BE89D8AA3944B76084AA58C68D8008FE67297F6F34FAF36747E67772995AB5E09C6EBAB78B2CDA386433C0BC348F13AE49943D75B97E8266DFE8591D610BB398068E27765C81BA69B9E14EF948C192DA841E1E114B1EF3FAFF8B17587FD62A5E4D453F2CF74FD3954C562C5AC7B9B3DFC225E78DD711347E0317B6F155F0900CEC781845060F8367663D4BD470FF537019B0C46F1B46CB67A009B53C3B70E962E241930BF5A6FFDF7CD0C5AFFF7D9BCA4BCAEFD4FBE0C25A70BDF2ACB02E43A523B7FB0B467DC13F1E3FC56FF89857FAC49EDB347CC8F81C20DD2AF5AB85B5F6AE7B37143C83F1E4E5660A28903812ECEC764F79831B4F53692F4771D626D898705021CB72CD7977CB29E76351BE4333E673EB57FB745A4ED8DEDFCB9CFA0D5D91B1D7F62364B4DBA6C2597FB76F5346CE177CBED020C2B2C99B855FFB33AB5E68F161D2B52C5A4766AFF7FCAD6D3E071E48906B2BBEFF4E6087AE0509D81C5FE3135F62FDA3F0F19CDB5ADF4D6B4D07F8D765C0E6E72CEA1369700EA3F67A750B51F850C9D55D5DF8BDEDE6DBE22634E772E7FFC53F1E934EF8F75CA00FEE0B7917015087A78F0DBA0E0EAA00A5FB37802AB39071B20CDA73E2D759FF3973B1CEEADBF4312A0CA76325A577B0E7429BF89CECE3D15617CABA11837C80F0DC095252BAA182DEFDC7DC2943F54B8C4D9617724E7585A046C9DDD2593AC76C6E39FCC88877A5AA989B453EF5D52E286A99615E8E4D16EFAF0C59AFB4B92C2D2A1176A39E7BD5EBFBB1B54FEDC02BB36FBF0ECDB33951257769E472C0AA3349288D621FA437B2483474EE5CF904528AD498A031A5D54F11B7C3645A3463494F74C71DDF4F01A261C06C0C0091909C65AC9F64A70D5D088DE0E7E20ABED88D9051BBBB3FFA5349FA21F7A22E0FA18BFD9D835FC7305F4C584982A65261318A7EB6A639293F3306F5ABCD26D5962011C41B40E85FDBC1B8E75008B443DFB018AC8CD866506EBC3D0773814F31E9A50D8F2AC0DF56CE0259D605D900A2CFA9D0C7A5A3EFA76EDE89211D1705F408BE7635C8D3615E8162752274CF811394AE4C281A327BFE79F380D053F81B2050641C2E4FEEC187C712EED821E6BD7AD3672B89B5E2BF62BA0EECA6F819EF20C44F9466C4773378F10FDA24B8490F539BEE9021A320B390B3285A9DDECF447E98F4616BF3F5271A9AFBB2A4FBE91EAA94D11AB3B26AEADD0CA60BAC8C23FD3661180087A91EF2DBFF1AFE9669BFF47BCF9616A3A27EA97C4275EE262616CE766A1C0E2570482A42F57681D7052655A231C19EC6407CB891A760A0E36CE21F5A85F10FAF67484DF9D508E93A511E6A44A8A3687A34368F89EFD8AF95C4A3306E73C72CDB47F46DE934DBD22F3B91D21C2AF011392E4DF2AE813B3CDD3E20A54856BB4AFBFECFF262780F0D30029DAB7B78A75BA6789AE496E8D73939A50E3B5BD8A6921352ACA2FD8DD5A1CA35D109F4A4DABF2E823D2D890438A8532CF3B121583408D9A0EFABFBE5286944CEA00AA57667517101752E15DF5872CA38D169F414F192AD2C11A40927636B0A9ECFE67E2AC6D450805DC3B8F904063E1B68F24816726AEFC93CF947FAD3A1C9AAA5AB0F1EC1A1381A192ECDFCDA05BDFAE4278C575DEC40F57335941B3CB43DC9BA7A0DBC2B169CA9196894ECF71B856F056395569E8EC7FA01096B8ED754F08A05D55036CADC623B1A4D620A9B5C49691175699CB31F9929966324B7F7E7592F8FDF43B7C57D92B9B45A5BB713F210A285F92461AD70D7EE185E00CEEC6CF7F289AFE4A05457B7DF6307830410E43D004F808F34E1605EC782444EB6BBC331D89CDD50BBEBC687B0129D9D43F798F2E28BAE0724B9ED94692D73E8BF43C1E2004D4BDDFF2C30FD8809C32D0598F933E6D51837A6D8EE3FC5D9D60834E0BA06CF49D2D3BD98A0E9AC92A20439C5EE3EE9CB0223FB7BDFA2CEAD9DCB8FB5C8374913A52AB1D1A36964D622EFE28FD68663D4AF632AC99F725E07A71BBEECBFFC6D22E568B5ED2903AF2F1194EAA5FA65127529D771D8437381DA1D0FEC24D1563E6085D84FEE11AE4E8C84F8E69065C609C9FD7DF061EAD5519B31822D9541DA3B4E2582F33BB6698C2EC50ED271FE9BB660B3B848E71D9C5FA9B23E471CFE330FF0A14A2ACEF2C47250F25B9B2A18F36660E32F23FAFCD17C1D879781CC0808D1B8DF2604FCF8A937602EA52FB09A9D2AEC067D3B2ABB921DD8234E7DA541EACA8FF4CCA24DF8D85995D685625CD0A2ABC02B0A79F21F421A820F6F224A85018E7FE3773EDE1668273EB665AA4F3F827583E15EFF72F9A67039F3C8EFFC8433174FA72AC7B7A638EDC1E35E86902CD65E15F85BF91A7E498B30E448E5D3C53A323B45AA77F2F2D8C2D73D6ED00C81B31FDA5EB396BEE331697DAAC647BC51ECF9A6965602D2B4A7B9302F1E761E849BF59F03857AD12BD5923FA296BA69AD8EA09D669633F73DF5E8207078D338C1B95D0E1175AB4924993F59506E9E81BF062CAA58F0ABB68744CD77C077CF7345F5AAE91079E19D4CF63EBD20E4FA5887CC591C3F52E4CFDED586C46C57D3DC39A532EBD118A49EB0F3877B0EAB2C711A06907553F6E7F5B2D73954E7B835897F2070734337F8DBA15E121B6421F9B22C02757221EE2687DBC2693BA06BE5EA1DC91FEF9FC9C9194878938162EED862B916F9F86F9FB447424B16F33EBD5596EDED0B45DFAE2AC6A49B80319AF49B81F013EF4F3A72E65C0E7941CEE6168B29805C3DFCF036A7A017CD8E277BAC1EDCA22209DF1BC79799B2E384FB16B624C43A0CBC5FE71DDBBFEBBD677CAD10E17DBB7B757A3F4765C04FD8759ADA0DE8C173654D3FCC9506F8A2BC7BC9F0FDA800921990DDE1235B52705D00BAE9009EDF86CD7A252BF22863A09315D32AD806D973E18BE3F5D8183C37C9D2B03C736120BBEAC71E56574DC8A5F6A573DB3DD8FFC49DF803736EFEA9841CA057177C52AB0E905031C20CF6F4CA53AD00D3D4050145DF5BF11B9451F70B7D24CC8E2C7843C7DD4AF33A05801609F0926C9849EB79C02814018333422131904E7DC66A49645AC4BF991F0CFEF0E1C065AC7A9A7AB173C8A3A71C3D064588C5B8ED49B5121F46BF630D2966C41E41B220D918CAF118A27C3324C6BA829E8B7F8DAF1A3D33E20F9E5BD5452112E5FF24241EFDBB42CE1C283E7554BF45FA54F87C84B6D43C6F55DE01070C53A5E2B023A612349ECB14661ADCC8CE7D5DEEED6A701F9C5145E899694176053D5AAC7D086AC516B58C8F1848F06FC376C0B27D399B985C06E11167FB71207C77F35E69D3CB1ABE19D79A81EC2A201DE6C19B28E3D71BECFB4B18D58CCC912093DA8F0C934EA3FE29D488E4F18150475830728E4F1E6725CF8F8BDF2338AB89824D364FB075962DD3B4DFDE3E61027B1E2DE72786410AC33929BB1489C24F2806AD8A0070ED0409094C348FE2E8FD7049C76C90ABE57EA4D5210C6FD5DFEFB579A5D886E278F997172679228063E059C98A1AFF6CBD61FE5E6E15FC7BE7FE293F2F5D51F4AF2FF0A8F157A84B77EC6230548145EA3C977C9258656CA462488D8979A18EBC942B7537C936ED925055BE534BAA0C220381008040281207E50C813C433BCA2391C8E1D1689847A3910417E709739C4D1EA1EEB6E9DF2BE22B02D374887A8F6C61F09EB824017343DDA40A039E43041651360F4A67A991A14BE99E5B2B1464C91D488AF98C91EDB285294B022A11076988A66823B3DDF238ACDEC9617FCE8C8CED5CD8FA6D2FCD8E9F4CC3109DF437FA2DEBA4113D58DAF4CD3DFC3D181F611D399491B11FD06A3A385323C51345CE65536F1EBEA24A28A9CC0FB7FA4ECDAA1065FB48E9AF337C6A5387A59F7312406600035F6AC53B05A9D2A7D7DE9B6BE9735BEDD4F7A58F835254A5EBF0C3BB2BEE412C0D13BC43642E57DD66C604483595789644E03B8C091C5B665FFB24827CCBBB3C7AD829BA14FE00699936FBB35438F6C798E6140C03DE98D4B02B7B3BD1DDE8DA0B5DFE3FA6A27157FF96CF95A8150361E4C4124D94ED6375BA739358DD838C8899DE30F173AB8E81F8CEA2D80FA58ABC6CFBBDE998058E5146881FF0A53B743E1B16BCB859D1DB337B35AE5406060C4A327D86512B0C196965D1CF659A2E7B10987C1C2878832132788449441D8B78E9BDFDA030E29D48F76EA81D1F3A13E3DC24974FBBA7C6CA1C24D034975D7ED116294E1C2ADB26BE733ED60298C0E1D08F870B03D89B6CE53F1DAE6438478FA418187C8723F516E7BA8E6EA07CCFAB78E1122D813A8EF6928D46F30896F8956B4E676B34A3CD11B1BB568809C576E03E53E394204C08055ECFFED04B367DB8A0BD6E0DF4C12EF7756E52B1C417F3331762ABFC7282E59025483D3E36EA9016D7CC1C42AB1AD9FE764D2D37F1DD920955C06A84EB73DAF9F8D8268C6F9ECF5D00584F6D6CD2CDFDDBE7076C90E1B5DABFAFBD2E42B313B7B4F30128F05AD48BCC0D55CF4B81800039F39F0D3ADAB5436F9E6B61B7E64DB4ABA9321E751360C2A6F13D29B3BA175FCE31341699BD6EAA4E8FAD378B9FD2F68516A8306BBD95C5CDD203E2F479AED6A5F6D172424ED3DE57FE570387A7F5F39B1DB6D8061CD8AE6B99E35A8FBDE0581967CC70A37F8E36A4A0CBC8CA637EF88EBDEF7738DE16B6E7FC4310FF19498F362A1D49E93E28DFD18A157B05616602C92486F3359D3EF972C9EBDFA62B40CC000DC4FBB4479F3C418BF38789E0C3F57311ECAB661C4090F3CEBFDCD7783438A7F0124E1D5DACB3C23C51759E97CC4F72EFEF2BE44F3F4322C834883CC6BBFE518B174413B9F9E85E6F8A5C63A2E1C23F3C9632536A26099E0BE49DCBD000ABF24AD5888F94CF36539829D8FB0DA8471F14C3C11666ECEF84614287093A0076FB725C8CC55426C4CACED0FB87CEE7FD8F973F55F77ABC28D57ABF3FB1AFF037C553F3A6B4A288CA280B1FB14445558D0503BC8C05367D9814F24281BA384CB29F44BE9D711F03EC86CB0298C3DF6180E30001F3DB5EAB4AE653F319D761AEF4379521B8A2441F8A7A3BBE330421922C5152D4051E548B2EF3954E3EB1DEED4F53D01B82E133782DB762B79ECB7F8C0182DC53B6247E990FD8668406CA84DE070D9DAE45DC80B504E63741670D11FE3F0D880D7FD71AE2DB8426D031860C873F5B66FC3D9B0D0966721832E1FAC0B25EB1BFDAE5EFDDFA6D676A583C2E1C09DCF41FF0AE06C36B539AD8834D7831E224FC8FC5D59B59E6AE612CA37ABA5B918E3EC27BE643238A97EDC846DCE9F88CDD23D4A538BBCB9E13FCC153F088EE7F7564BC660298ED3FFCD01FDE887FA8BFCD2AF945F27E8AEB4C5C440900FEDFD179A47576C5FBE7DA90B95855B533DA9D656CA8B9CFEB23C84762349A8EC27974EABCC21DD6A412CFAF6F9D407332244C5B1077B1DF42117EA8B6DEAEAA49651E375393B6D64D28A59FA299F4A5330C516701BF3AF92618856C3E7F1C76889CF23C2EF0D8D47FE5BF2C4C682417AA1C37ADD0569B3817B4F83421E93DA711200128C45D981B5ACE020099172D95DF679380C8001B3A2212401A3494753B7CAF1D0938FB246231418399F5A695F6E9AAE9BDE8937011586FDE9AC96CB62813F37F26C450788693EA16D0E348CDF45B134927BF4808C8B082501D8213467C42E618714312ADBA8C3AA4B8E88D2B97C3827455D80C71EFB7A80AD62E89F6576FE03462F80FA76B64330BFD1E7936FA2723F110D0AF94BCEB1C4028C5D6D71B4B7232D158D8700C6ABCD0AC9DF5CB6189BCC60D351D7F8925C9F5CC6F996DA61E072D6FA640717DCA99B04AE16AA21C6A77964B3D5A12644A2004105D0A79999051EE7519B4FBDAB2D235E6A7E411F5E90119B724BFB27FC8FB300A526EEA4819F735FD818F450A33085BFF9B5D6841B9AFA3A593B0A351F422E8D3A6F4051C8D647E8B6DA679826B9C669CD5B59E0092D58DC7EAB81DA0EBE3A69DD1B202FD23237387A03B40E9ED140F4F97433659CF047118FCDED199C8567600664CBADDB7A83491BC39B78CB9F0B507B5E1B9658F880CF598A5BC096E7F4CD58C0578C884D96638987DFDD6E1CB0E882EB729E14C8DDB92057F4534024BC0A5AE7DFD4231F74161C04844659AB12F6C7C2300101F6A18C5C0BBF5F4C11F666DB307E75610B6827E354451C6E3B088B013090E39BE68CF380D3216B421D7ADF05F9D2DB32C2A7D6FCEFFB57DFD7936CB5E17480BE856091E237F6CCE528A3F463D7DD54E59D00A23D930E2CC81137E38EEC7E16EEDB65AAF5954A2FD61E4D0FF3BBF4468F97FF18C91FFEF92FB3732C445DE799D51086964FBB3D50D493F88663B1A258D90AF996EBEDF97E87CCABD789A4EC73625294E0022018EAC5E59F3B1170C79EC1AA36014BB8A4042A3A98B2B303C3122225B5AF623C93494654524261A7A8FA408876561BF88E593BB69D32512C73CDC6AF26598BA846CAFF7DA2AB4ACBA63121EB3A7CB21CD0B996A9B697F563C9233E6F39638A649AF4E2235569E4A92AF8F32C6D0EF3122330BA9254F85E0A5D5FB8675F39000620DAA8273B1FACABD2F918577CCCA86AE7A2AFD8D63F99582948716F37A91E7803CA9F7BFB288AEBBE4B49E1D57DB3D2F915CC3A19F19EFDE1EE77EE80BFE92BB55D174257EEA6D8684F8393CAD36B90EE168C26A4C0894A9843B0CDA53B31DED5C1FDD54CB97858D517A69F8300AF7A2481894361E5A56CEFCDAA3184D871BBEFDFD2E4D27B6F246F4D8D6392D33105FA1633094A470642D3C1770B1AEC503A3069DC61E15040E16C598BC6F5710B6B97164B2C9588D8A03FB4E9CF6687712573874A780640FA01C9BC7FD950E12A8366987B78235393B44FF74C90F8B3EF7D377EFC478D45F6DBAF7E5BAB6F359AE81FA1332DB8957B8F5E4171441F4E6B45EBE61B1BF2564F3132558DC373C24A73F9C53B49D2D475CC3E0F5403B4505A204B2E1ACE8E3AA9E0C05286BBE6B6B43F991E2237983BABBF89F97808B71DE4517988C9C87BB3D1AF9E9D1F2F0571AC76A928BF68C66B06FD2CA84D6C3CC9A9C8C800D774FB1A3EB489541A8A4C875ADE604E56D4333817FDE0D1BD3016D56AB1F9AF1005194DAC36EC04B349EF98F82391DA67BC819102FB8932492D38433FE9F93344B6F4833F71340E794C9B328C5E88A848C6D5BD771BF0ADE86C987771BBCE64BABD518D5A206E3C67381C491FB754FE0CA0B4090732918634150073E53E2BC6F616737EE3FA0B4C90A2377A1F3B2553D32EF88FD72BE135D0A64197C742F9A85CE373AC53099BAD26C6B477FFBD1B3539040FD7B394DE82801551575C383A003F3A295E56E5C63FD350C90ADF21FC8F2FED336C689D8BEAA3305E4B4A892922EE1C5A007D82E684433802BD07CF44503F5043C1BAA06CAF2514856ACB2A809DF73ABA76DF660B3AA7BF8ED5F84C8E03587B1A40F3D29F6DD04C56A526008E2170EB6BB5BB6F9D6C08051A29A9669F874BC8B7F0FD50B4FD989A7BE4A48FDB33516E9FF86F1939DC57C702E7400246F9D66D49FED5048996549AE065B6460868B6B0D0228557B84622228DCEFCB85C9CE024D89864D3060ED3167BCF67B238B191BD3BB2EFBFAAC5E2C1961100387FCC47F4B48A8703EADEB4224E692E9A24AEEF7F18D362E2BA2B90AB60F45E56AD5455493F4900455BBEC21CBC43D3540B55547885D15EB2C8043A2A890941DE78BEF1EF7B812A9DBEA088E8CF474ED9585984B1A1CC2170C8F777A32FD48D6981E37F1596D34BED2DA563A41519D78BD8D00F981EBD4CFD04DF569731103DE32A1E2E8986B44F9D7A3FA460A6AF0F079D6E290444DEE00A9ADE3BD46C1F420E9881CD71CDB0F17437A59DEA3035B6353C25BBC8F0FEA4A2A9ED1014FCC02E713F85671D70E6B0F6FF97441132C2B28BB19AD9B797113C68E27A129DF078AE86B18BD04A60C0D463F372BECE271472F5963D24534E3523DCCB4067399CAA3178E61F2870E5E1008DCBB26AABE6D051E553BF05697F001729E4F8C83504EAB864DAC42D7C5AE3DB0536CE3C3E4DAF5CC59A237829A9A4D6F288602AD976D76222D198568174CCA21B0620C2F72DB5047A0D914418EEF3D0550F5403FC71A51F8326AE1ECB450735E4A8CBF8646233AE7198F3FFAB1A6EB86078C8F4DFBF62C4D361259CF4DD51817D22A8C07E5C01754F5223CCFBD313DF0423C73884590510A57A9504A1A9F25A3723963B12A9E78E9EE1FAC9A8D431DC7A44BD1C7B58CA6B351499141CC2A4E368806656D28938EE75CD29A311B7C126745AB4A23EDBF0EA8739FA4B0BB666F10004832A8995CC53486351B84AF556B26A4515A0FCDE6F5C0E7C02626D16ACDA6E5DE0FBFBAFBBB0FFCDA26F847F4294EA67AF0124B758C2895BBA4938683C54305D9FECDD0FD5925BFFE1799B3E33A302B41A03B1E2AC89F1783F5C517E3F372ABDAA64EEE14F05B49F794C5E2259C49F53C86C482B38042BF22B86FEAEF1D1DF3310FA039EDA46FB000C2084A97FE1A75A25DA16B9D1711ABB996F06B398C45C057BAE5C6E976C5211D00118CF2A1351E1F02918CC736F5289ED226BDEB6FBFC166159A5F50AE0371EC2D6B8D639DDBAFF36110BB1A20727D5A7FB389DAE937F023D11380BC04852E47AA604773DB6DE1AAEEF069645F4287000E4141FDE6E967C1A7CBFA348F6F6821B9D9C383806E4D83658BFC1F7ADA1EFD0E246C9D0C704BDCB1A97CD95C825FED6BBC23A555FC65DDBC8EBE95C7CA791F4477AADE0D3C05ACA9B2411FFF5163C8C0DB1DBE4204B49F8FF793A79C8BE72F46FDFC7F03FE9EC5E10405D24B5C483E554980485E75CA085252A37B575881C575AD0F88B87D0DAA171FC8478216B8760551ABB5881C8A0FFAB2C0EF3F126248ABE28B522D5B58FFBDE24230ACC9928811A9EFC00C62E467F080CF0213C5ED9FE50776B2B97195211B757377CE32E0C222F73CB2696D6A3B6E20B025C04556744AF2BAAA8C34F9978290FEC59665696C77DEA2F7B7F5F30BD25FFDE508AA831EF3113D9B76C97FE30AD4ADB4D2F915DA762A5D81998EB1BA9B80FD24D0CDC33A9F682E2F9263DE547802A7B47BEEB2071934AE22F12B88999F84B2B6E2E01EDFFB5B92CAD5F297E30BECE816A3F52A371F9AD8870B53B4B2B7AB3AD497CE3342F9EFBFF8EA3644997FB1D1A03937DF1E152DD6B6F0006E8DCCFC9A75A1FFA57A4D5DC597812F3C9FC8F352540F0F783174631D53C46C3005D434DDF1DE7FFD4721C41976F41D7CE6188F660153A23FBA2FF4E0377BA540B6A1DA5093A1C722162667921E67EEAD7007B67067E7264EC6937134F9D2220BDBE3FA059AB18000354CDD6253629272B90A3B3AB0B24516B217C2CE7333714D39DF61499397A8E2040B4FA76366C19D74C9B127A2B2F9738F2A56676FCEA71D2CD4C94B8C1727EEDF532793070A3499E697E3B443EDCB38B55C2ADCA6124EC305FD82251202C019A688C86C1139292E95956715E1A8B84C630760942010C34B739E2902ECABB8C07A3951AFC9B568B765A5D5F9895AAF5926AD7ED617BCB0408A466C6F25DFA48EAF27549A322CC78458F808DDEB1DDA0C2C7328C12DAB33E4C81D87222A462381C811F0F8875A4435D000B75704B68B762160E5CA7FB41FC9DC41A02A773034D31403FF9E265CC0092A419AD50477766189197FF3501EF8B86AF1D31152F9C91F843ABC2951468065A0732EB11B66D800C48934E48132D0360C06A73BE0450AB02F74EB5C41C8CD2CA2173E8E9C2652FA09B530F615025C05F02EE5A73A38FBB3784654327B202D44E21979461EC0589D9D16E8B7997DFBED2B47621EC9FCC1E21ECEF211CE12952E180A3C6EE77BB543F1CBC25AB6DCEE439F649F6BEDB83D096B714D1A5C3AD489440911275F95759D26781C1A461852A780E90F85DA065F46AEA06C625F6AAF5CFC9BEA468000C20F2345B24654E1521E1E7360D587EB51C75CA4546977F54EA5975C6558BED06034107416174D2F5AF574B69D6917B1FBD999DB5DA42333A4846B507D044C76A244120100804D2EEB4E9F7A86F02E55ADAFF9C202E44C6D0A1F973FAA7CEF18967584C8CA848892B7797023A5662340B0904F01B6FD168CB50289FFBB0B9C7403D15F91E219D6BDA216D2462D2E5F1578F61049D47EF773645761B40988BF9CBFBB39AC5450DC2E1819C1E2958FF245AC4360E57D4ACC1747C3B697F0BF14600C12D5DFEA097880244626BCF3F90A3ACCF904874403D38FE2D746AEB39B1EF282B1C7C2FD7EBBA3203F475D7DBA09C177C146125B3577DB1A70E94B463DC88A483AEDC9E4C07FF6B8E3BBB41C2B56D3A1C7885496163DDE4D71220F2F023CB3FA86BD798857A48A57D950CA9E29CBE6ED443363B00F9CDA4B5E0D727C588809395C9E89DFEB59320F8E66AEE0A30EA7FDBD9A91FEF7407411F9DF543E3229DB4F77C9D31F8E49383481CBEABD86C3D88E44C871C8A9EEB240AC2FD498D31E79858F70077768674383F2D26D2839FFBCAC6379955CE510E5A8861BA5E7E21C90A69544684BC49D48601117631FFC07528E54939CC23E08128E211BC4457D7A9E31EF522A108EEE4BF5018F23EC1E800A221013C81F839594385EEDDC6CE8A33C97886CCF95C759BDE754228AECED8BDD00FB02D0A83F9316C3C3E5BA53218C609E82546325B14B266131B6FC081BF97FEDBE842E8D0E01468E601A129F98676589A5F24A999064CCDD05B5F9519390C568DDBFB10B51C89A5EF27DE96868C0E3FC22AB72C8DE5CFEB360A837A6CDB6A7AA250FD260EB2AF35E92B5EA4F2391F63DA42D658B47A833A2C9AC29EF9C87D515975004932F21C3B84B1D2D15DF5F58090E1C5021EE3D34DD36D0779467DA95B32AD5612F04C1F65F68E6A505BC5B51536288B8182A896415FA74CE9A335C0108E5A3C713934F0FC9FF9C9BCE93D311E925029328791777EA7D9288D677C8DC420CA371FA528D0CA897AA5948575E2A371B80A0FA5405D60A8B4EA8D2F05590DB2A3578A0F9A7CA9264EC303652218737AAC338F3427262EB69449BA13F3D48DA5F563FCB6EB5024B121A1DA54C176D1142975FBC930A069A93EB06045513FF596AFE7BFE7A263BA8317252093958DE09D80761475DF0B58F99E4BE027332255D65EA55D6A13C49BBE7C56DDB4DA389BCD0B866DD9033C5D90A2D44E26C83C218724D7C5CF508001CDF47992A6F965ED419F6F76F92216AB9D75EF73EEBA66001607E3743CD65FF680DE1941F95A99D9F93E93DCF9DE49F50AF94358C808850B41C4CB0FBF8E7C5A471480573D11B570C0B082A8AB1D91E48648AD9339222299E32AD69BDBE00F2DFF3F3FCF65896741294679240A6EF6158CB107F5B12ADFC890499EA950AA9BE507AC49F73706D98C2E7F9290AB3F428006E9EB482D8970CBDEE58F2F3DA8CC0B9D729CC806115051B9818A647A99A7F7F9BB1CEC9B117ABF413698DA9F6F3B7FD33EBE4B997F4E1C0003EE69A68CC3E5B7EA8B2A0336ED69F75A8746073D8DF1E573DD2E34CB110B3F1C00F12E21342E61579192904FE3461B5E367B55781F315CDFDD503E68E8B98FFF4CE84215883A12E97BCC2C766BF599AA8A665077D5E054EFF5B4B19EF0529F278C261478F1568F63AB4B47C45445B8CFFBFE9F2036339D185569AD59F3DF461519D433D0A230EAB538066DF7A847E8843DCBFF5E6598369F41C78CFB99F093168D7AA9BAF926ECA8E757513F0E3ACE852287E45D109F2662151E40A9A61F43781148EFC78437003EFD7EC98CD1DB76DE9194F2EB8D6B32D5BAC3B70AE54E08C925B757D4048AAEC404CC9CA43A5577CF2EC6E218BE3BEE6A99937AD8C4C0DB7063AF2FB5F82396448581B74E637E0EE8B9A61BFC19CEBFDCFDB6D01C801604ABB35A47CB3DB4591A6E44FCA5A1D6522A7DBC91486DCB9753282FC0CC2A990315A4F6FA5ED1CE02B3F073FA46E0F69074CE08A21ABD430C0D2900DC765AD77920B3D26A3702C67A2014F3A5C625B41BBD89E06FAD07F887731BF710856069FD1D9616CD1603A67AE82C2FCE60C68FA355D3F63A84F4ED76D07190B3F7D25FB6FBFFDF7247BD15C08BA550A35FE20AD6628A54BB57980706279E7DA96D6CFE9D73E6A5ACB9A32A97B57988DE30E9524FFDBE20FECE2509C6BD415875CC334EE27BCE1ECE06AFE78E2CE8B68348180003A2D451BFB819783FF3F5A79552B994BE58AFED58F3FDEA1B7B200E43AC6FBB490102AD7F4D21084ED81CF3B3EAEF1991F0F45D156BBC79FF1CC1210E3C31E3D4DF8F6B6441218F6FC30A233C98D6887B3190D994C98681558CDE07F481662F1F180003437F33873F967DEBBCCA58BF5E17FF31408D6F835EC3FBFD54EDFFCEF516B7751AA0FC9FDCD9D931883E8D02E37AD7FC3B2DB4F461FABF7380B57A7D497F19F11F8DF09E73B543A0EE139BF4F6D2A3A21EB5E30D8CE4E84C94E519CC6A59B300021CA450DDE36F1FB0C8C53F9FC2D8A5881218D071E29318BF6106A6F1FA0B2B402A323F178A175A6E9FCBF1A495923DB074AA046CE3A98FE05BCF2E70A8236B34AF5E55423547D9EB765C88831C7FFD56BAD3C6E80287874E3C6A2F49AD288B0AB8EB13A89B565CEAED3A8D27B47A2FC933F2F6451215C4543B78E3EC68F57495E4492A04A1B5F45A1B630BA13700038264E673579FD9F82891C534F4AABBC282CA4F44CA1BB839D394DE417F9D30AE00D24BA45654916D7AE11881E04121B6F6C08EF3B7500894F498CE8924B32DDDEB9D8B4E65556CD257DE7533F23F4F3103E0BB3F19DE06057AAF8BF4E8E737B3714A4D6E9EF9173FA83AB4C7FBB067A804FD0FDF2A1D5A902C1423F35C4706B40B27BC0988D563A58BDF5698670A22A578B0E6D7BC3313A0E95649FD5D1F46BAC01F4050C813D830BCA2392C121689847A391041284792490A594B4C349FF3E021EEDFFD81B0B51808FA835EA0727DC9D8104439CD3CBD7C4DEFB6106F92F6BDF356C8818F4C3783617A816EE7455B8001C4FD7CFAF9F9B8D3D6F270F1AB2F93E3711941B7FA5B3F1ADC955183385DA87F03387BBC903C3A45EC124DD999D468B517C10F817E04CC77725505E9B9AA6C67B014642310C47DB2915A2D302AC44A5528494EDFC4196E2552664B1B66E3AAD4E4B0294869EA52DA47DC6F168D0EEF505212A1555A8BE7197CF43C84195877E98FB84CAD3DAEB6BE1FFB61FED393DFC3815C2D6ACB17B7E02277F5B9CC1D4935E4210E3D0A80E30E096D95B68BA5C1E4070A5EA5FA7C30D0CECEE7DD0E96DBD69BFE4062A60A5AD00E11526C3691B6A3931D37BE8D379044D7365142AD115B87969972BDBAA702BA4C7EA5DA193DC1C3E86558F55D611447F8239385892FFA868CE36D465EF117E221F5BBF593467A5C43BFB16D00D963EB2D6B1148CA55F2ABF5062ED4FF067F61F5234995CEFCB82BDD9529B7324CC38B23D813FA0476A5B84FE5DAFCC7A203636357AE096DB7FA929E34579328B8DAC9A25FA771A62DC6D4A3B5502B82121069B4616851F02FBB837EA66B705B9FF44FBDF7BB6790B89C5C1FE9E634AFA5DE11F887FD1F7DACE5414B008F6CDE3AA55ECEA87992D537AD23D72F11C9761773F358C15114B61CB0B072245CE5F949C88D46D825CF3C9DCDB3FA2DF9C15088FFF3F77E96A337B284DF2CF8320DCF5576E5037F452AE014F0CB35D87F37B53BCEBA42D0C466D7F9B14E16B02F140BAFAE5801406E90A6E32AD21ECADAE5B922B678459C471A30290F3D2F16D716C22ABBA9251153CA7D0C3A6545FB77600AE1AC254CCC29FF6B552D3BE675377650AFD87F82039106390D7F4016CD2D33B9AC6822C3E64EA781FF898930FB9FB55B55E72C2E1A2E0A6ABDF85555486B9D1A5C2D18AFAFC7806CCE2E88BDC7000C70CCB7C669FD80487BA6269FB54074A67D1DEC9C6E4C38BEAB10A8EF5505637506087B5C44C2BFFCF8969B8D55D7F83D08D7EE5BFDA2E2780B268D16CEC43885ED05080402818A084DAD7094746E0AEDFFE50BF3F3FF15FAD9F86DEAE2A2762BA2FE2E8EC116151EC54C204E62F35CE6FDA678B48623059329FC68652C7CAB7E166969FB180A7C54510859FFEA1897E1F079DEFC55D55F02890D3A6E43E1DB21F811E3BEA52328C46F4452A7D448CAE394D9DF644822BBD15226E608686FB732E14FEEC367E0E8A7C152779DCE6B3F7B8828611B2DB4037C3F0C85C5317B722EF47660274BDBB02A77730B0815E8918DE6780A2FEF4B1C7271A39F35D0B9BE49732EB8F4FCBA17FDD4E92350BC433EDCB75B1D5C9C12CC50E3B4925586F50EA4AB4B781D77414D0B98B0EAB5FCBF77279B589CF61F3BBBCCECE770DBC5486550857E3AA2C5D5A68896CAEB078C41A4FF4D64660B88FBFF4C3A96EF528DF4F8B508E7D34427E7920A0FD71253C3647A27289DD02794B6B028070EE059C5A6773EEE27941A9DC0A8972075DD8E631041FD5F023218BBF7C365151267F50A97937C1FF6B24CDD8095B992B0BB8CDC58EF2548981B9F41CF7F96F0911ABE4E91DF62EE7B62AFFB8A78B3461B248C1020FB0111F77D287E12749FC3C618986288203BDAE823C89E64EBE618AC860FE4A97F9D7F8E34EB55E78624175ADBCD8F4BDE87511716B873DB5FDA2D46FEFAC58F0C4032123A40EF5B8B73EC8E283977D167B4A24FB52AA91AF1783988D76EB0F83903A128EE7CF9BC2A8D46B27BC814DC8BA0C06EF0260ADF0DBBFB535BD69EB0B6CEC2C7CB3FCDA9F1CE2A5AEFEC76BCFBBF5DFC2F65E0EBEC8E45A492AD71B6D39CE6D1774D8A1E7EF4AE65DF9AB5D3373FD68410719D774F64CACEE3E3CA9E3E4E6B9C2B79D7923AE59903DC86E9E9F1BA179F4067B98C5E29C6A7BF6E02A73A07B89504A4C6818EBB35CD7028B80B7A0582038140A02471343AAEFA5F883A2AF5EA5E504739AB744ED21FCEABBFC3EF66518BA3DDA470D763B0B7AAF098FE1F5C933427B6A4C2D38466167DC8BB9DC2CE8829348DE39AB9D6E5AA1BFD419E2C4F81CE40DEE5ECE795A8B27512FA5F256D60916D731DB70669863E411AC2FD92F4AEBAD3837541E414AEEA33B127F6AAF3B019AC3350FE26E966D72A43AA5F99CCE4838B4D4E594AF5136A1FB02A9C958FAF523ED8C3C9E4FA4E496AC8FDC9A538F5315B1A0F60C18F72C6FFF6F9BB0262B2EB7FC0D6925D46A28A304CF7390D2F28B157493BA4156FF8E6BA90126DC02079A4D419770EF6863E81DDC3C16B2F520F7E733B0A988BA0ACB5D039A1B0A915249F3B841399BCBEBE96A87101408444F15D6B19ED9F87644C91B2692F85D8F55D7707C0D8183E90D74676E0096FFD8A177EB094F9B0DABEECBD1454483B55598BB929F72FBBBF99EE801E513257EA4C13709D2AD2EB442025DFC7406FD4FD57EB04D6FA1A998B2C84F1DCD903A5CFF56B36DB5CEE33DAD3DC76084794B08BC757D9CCC7F6E8B0E4A500A2600E8DBADDEADB4A76BA99705A1DAFD54926AA3AC0D8E5781CC000D1712F85A53C91A515A766AFA9D10EC3C59EA699B699B1DB3FDE78FE749CCB70780C3BFCB748A0B49B6246914BE9E9B4A7480F2C7983B8A7F77EF27AF13D7D37FBC95576FBD5BC91D8BBE53B2A17D5B4828BA7C27922F5D3822AAE2EBF708D2D9B3E267BA11560986D3DBEBE28AB41D1450C091268FB428000F4C4C27517B3272159F6B29E0D7CD308806E2D2499E9EF461D907B301F876B3C1DF54517741A507F636516769E87413A463F247ECDC0CDE4670FB277D965E9154B69B3B044F8F0292C6652816100063CA125EBCA927F6503EA4828EA11AFEE1EA91CAB5583F6E5271F62A257F96CD300384DC615A722A19254C893DE4A066324ECBDCCD17019FC6391EB490B598DFCA50B690D047D425AD48642CD1162FE3A824FFF368A692EEBE5180181BA906CF628E7F3B37ABB8DDEE4E76500F805171703F13BA50A27FFB2F73E80E20235E1766C3E21CD27F9D0FF4FB26809492D71585D53224F4442B829F94C19B1DF675E209D4CA271B22AD68F891A1C2A1588FCCB8231301575243F72BB309351C457DFB037CF5F0C2E87BA797C7166208C07E8820972437CE64C5A338966363A00EF994EFCB8C018923F5CD37068BC13B41E390E03932875CB35EE03F7B4AB708DFB52288112CE511421C7B051277F78B9C17FE5477E08847838F878F86446FEAD25C4C5C1CF252424242CC0CB2B2820CC2BFC778B71FF3F45014D39355B3F65017F43774595404B39560F2503413E5E272F6B0F770F236B1B17353FDF20656B3F617F2B152E7956235F5E272E45565D566F5B5D237F0F01674F6779596F7E8720C18040195579455B4F6D454F5F7E234E434E61451F0347154B6B19550D65756B253957553E594E4F4B3B5B072B595F654B03177D3F275761054E655F7F2D777D2D574779172F1E5D6B673E176B69415E272D4F1B77197B151E2D45675B2F59EF40250739774303256F1F4B6D575E0D671F1E474F15037B1D57436119693D4B5B393D211B61134E5F2D7B6D2E254D3D0515674F1B654B4F5D2E5EF9403B4D7777EE403E7E6B1B4D1E5B351D37596E2F4107133F7E7B5F2F656B67236D7E416F375FDF004F37777765575D2F6D3B251E139E006B1E797F457E7D5E5B4B617B1F276B1F7F651D217F7B1F5D2F5B2B5F4E374F133D27157F5B79631D6517594F23652D3723EB407D563D7B07076D7B7188677C5C8BF2A1272A48335B07D1E5DFAE7D326F06821D46E8F5F1250A8CFC809AD2FBCE066F406433EDA48F5B257208D63436F2A1E0D10EDC19D4F92BA689260C2939EAF4C2BEA8B558E967E8687064C2859772FB5A542E1D2F14331DF32716A25AC77794F3F5CE2EDCA86AAF991070A5F61C7C66D890F85ECE9BC454E2F3797076D516F166C97E6DEB05155BA18DBD0B5E531D627DFAD35B01616C3A1F864F6AEAFF29EE49D412EDF13FDB8CAE54A3F5DD370A1E57081FB8837383EA0118003F8774D46D2159C34024BB2FF7EFDF428C7328B9F0EC18AD61D5C8E46C30372320092DC8B3D4724B56706237BCC36778EC4274A3D258A9CBEB300D28E66BC7C0C33D78431F3D54AD745C908546B99161140774224A419DEAEF653D1546C5B1F494B6C2DC7155F784413440C260C6BFAD0A4A95C2B7BD4D9F1831AE268C9B65690CF79BD50AB8D3619A0E0574E4B22C7E7C5EC47A97A5D047E58F0B505F11721A2BFCCDE2AB869FCC8AD31D20166596A0213B2CCD57310C987A01EAEA4BDC347202AC9AB1D7E55808B98F67D589DE7C41AFC78BBCFB741B33F93822A2E03352AE62260FDCE134B6CCBA6569CC57DAEC045B1EABEF076EC98DF78FA0DD2F8360948FEE027E6A2E59FD730D89F3F45E1B5497B9AB469A370DACC24806DADFC43CDD7690C796E75A665BA02D0943F840BA07A0AD10DAEDBB05D7AE872B8C37ED46B6D636A139012AFFCE5BEF332FABFDB50D82F041FDA653893AF47F042591E73E06DEABE9BEC3A7C69DB34F5E739ABDC321176665367F381B1FB96CB61672F477ACD1CD35637EED4C87263D31F0236348047A7414DB7C34C7911848169BF8377D33E6323A927BB63C06BDF0907A8E953DF94EA0D3A484FE57755BFA3741C3E10C6BE3EF3695057F66FEE4029AAA6F0FE18E0E287437EC4EAD3AC5C7128CE4D392630C26F40C47AD6A3E1CD9515DE3FB61D35AC272F536F3FE7EB59CF97F1E20927FA541C38801449CA2C72FEFE492A8EC1FFF2C5C56DD19AC113377DCE7B9844F30F9A3582BF60C913EEF1E60F82258DCF44D87E2AB526DA6E55A428A5A25F790B1054D30933CB9904DE4F70E113671D870FFDAC3EA25FCE0099B52AE5459251B8453181AF28CB32D36377834BB1211356545927409A720EC0A140018D0808DE56E9CF0D375117474FC40151E78AAAD9D5E742DF81D6E58F4B804694206F04A35B30C79EE8877A6D3ABFD968999AC558BD89774FEB256587B7A76F126969D40A781AD80704522C8B11886F6B8BD373D456C9A42B96C99C13B728842120538A4AAD26F32B17BFF67EA5403B156E98A29925F6144B9D963629D4F22CEDCC003F8A5CD6193969E15E5C789E0BD1306B54843C47E620DCF4DCCC4E241ACBE61F82E48E1A9A797583505E2ECD0EB8D44CF95D934F9FD0F970DCBEFE3AD9931E958F544C9D05E0FCAC589BA70F635A55554985010071DE3F22814DCA68D23F66F2E0FA9F2F1E63F4C65400038C1C7810D7C9632BA1B8D68B62D2C83AFBD749CC672A616663CE09FFD94F0EED277928A8C1042E8130497E5D4D9DB8453A0CCCE2059E78CF73FCB6666FF83BFBC3FD97035E53AF4E3E898802B828F7FB6F4C7C6AD9707D7CB390DF75D5A2269E1B4A3F4B66B7DE9BC2C89EF914C9472F35D8763EB8EBBA6CD2859FEEF0BE69E45B51507AA4AAD991688054B21A74B783F81B29A0CC5DAD04B1C7DF5B3310EEF76CF3C653D0481FB6D4D30919D2C36F31D0F731692D87FCF1A0A73D203841FBAC8155F6336D83DDCF7CAC7754CA627F5D1BCDB621CB63E2C737F5F725190245AD4D46503EC0C61E271DF935B09090A2F25CD3FCA6189776E3799846E2DF6D42ED050295C9BEAFCDAE4626BF7E7C593DA6C11C283589D24F5D588EC5D429E2370C76B0919528F01E4AC008A563F71EB6715FE00BBD3DD3D8260D3586C2EBD0E656C2EC4EF357BF366FFDF5B19822F9FF67E03A8C109A6B648DDDFEB7221BDF4BAC0D0B670D6FD290447C222E13F93182D10C0A8F2EE411C12EBC724D9C598BBBE52AB65318EEED74108F7BD7FE6E1F48385598EA8F12163F7A07BECD80CBE255B88F0B5680A0501FE76C5B9B6B18FC18B697EDACC6F130AAB8DACA4930F96EA811055FCBBD5612FE8C38B15C1FABC1E7B0871FCB26DD7EF03E538576716A74A57394DEE91E7CD59D927B515DC49ECA86AA1C5B23B5D00F5087DE426EE94220A73B4F02A1F7A605CC7F0F115596BE419FBB9DB47E4F37317B60108FA84AD1D81A0351889C888018A842CD83E66128608ACEF3192A8AFB3AC70A9875B2577512FA7C2BAB00EE83983C120100834B74E460DEAB01CDB6680282261CDD701354FC701D00C928614A64FA85058540E26006A7E0F9BE91940C7782481741FB581869A47C350158F3F0C5AD0BB71BAEEC51C956BC2EC6B71737E36904DC047B620D8ECA0034D0D2BF9DC3FB41722FF6039BFEA18B0ADFFE2AFFB9767CFD76EC0ECE91115C2B42C63B793BD8441FF8441C3DD85410179C220014720AAD27681AFF62815EE0C55A57A4EFEDD2148202C87A98A75734885823E9A2A25D52BAE094CBF33522D69C25A6F573068405AB7B401F6E744D8EAB5EB334236315E292408949AE9E970A1102A30480A040141C020E84E11CB13A6010C8A05D97C1D18888B469CD51AC047D3920A848515691A6181A8A4F63A014BE13C06E8F15CBD9FD0311F0B32DD22ABA8DDAAD6A63D2F929D514CBD692E7A31371FAD81CD6B9D06D2BDF102C71F4D0E2F82497559ACD5FFAC874B0998EE4CD4EF685B2F3D5D91DA98100D32AC0922372BB6DDCEE8AAAC837F8F7B2C44D9B3B6B4BCEDEC04E3272B20E3CE83403BF81177A2E9EEE1D9DF10D39F9A9E32211491379B7078030F2DCC14A65428E363435DF4A073053C43DF4E3DBBEEFF72BEBF3FF6647EF672D1A30C90D3BB41BE5C1F7E99C1841C712D2E4CF256613DCF2BB9F9B3C2D22FA36BFAED149832779EF094D6408F438AC1FF3F4316753ED82ECC65292FC6349DFEB9866161C03A98F3975EB5835E6A7BFAD975C747A3CC190E019A8588B18DA88F5E87A7FF3716FDBF04B4ED02DBD4C3F8DF927FE9B34DE4E028EFB3C08BF41E2105A1EC3CDF3C24B513AAF065AC7D5FFEDE4BC5B8FB9CF8B89AA9EEDDF08D75685320CEEE7CFEAA052F125C1AB0870F5D4DA33C771F294845D9C4C36F290E3C9DDB0630313F44CE340E4A1B9176FA066976EE38ABE5ED3842B314AC33F9BBFF6822E5DF67393ECA00ED473B14814F38F61B846D47DCEA1FD4E18CC5D92E769EDB74BE69F5799C9A3C0183BFFE0CBEF0E1DB4522023987B7AC7FBDBF92B744BCCBE5EF21F9D19D3FE63B0961463C16649928F5309BEBE24823524689423348C865F898CB1F6DBC33E53E5AD323E930A580C886FF494AD2ED5D32FC69CA7AA661AE43224849D64E3DC115EDE147CCBB1990A6A7900C8CD05B4F9C34B1B3C264F63F0B386563810CB35284A2EEEA44C822EC6D27F1BF108252584E9315D2B2798AA0D9859D85F6C88A6C5989BCE118443D88E5555A38A55D0CA342720AA1BD70885A0F6708E97CE08F5C2B82400E6EDE766E1EBE76728E502777155B12677757276B6FA87790A19DB78F93873BD8C3C6C3DDD71B6AE32B636BEB6DE7E3A31FD12BC2DD6C3CDCED9DBCDDA0BE4E1EEE3E188ED6AE1E362E9A7E6E4E3C81BCA24276F6D6B6A0C6209FC0AF59EA73B9E8511658F97D3E1A81C9F8AC3703EF7D2326E3F6252D38ECEFCA42DFEFC2BB373FDD423B40763D0703AB312881D3AA28559857EAF1478DCD63622E75FF71356FBE1CB60B68CA5CE2EF482CEDC8DBC67730FC1FFD745F7FEB8AAC51BFBEDDD9E1DBCE11A938D9094FF74C183573F39B932FE3C9A125BCE4608AFA21EFA4EFC28AA18228454BFC4E13C4FA394F9C4ED8B9E1B3F1F8668DD727FDC9D3280A0D8D9FC5A069B040CE8177CC3D4A94256ABCBE7300775044A77B8DED7C79EC310658A19EE8D2E515B8808A785EC015413D27BF897DFDDACB4B9E6FCB94F852F42F5F720C16A260257F32F4253C961AAC9EA6597B7B7B277CE7BEF8B77151E1AD65A0E955BB8EF87A69DBD7F2286ADF9045D4DFAB3CD85F199016FA4CC44B3925DBB8C738F67DCE45AAFF9FBAAAD7725442225CEE5C633111DB46CD62716FBCB6C48D529EE3A44C1E699A69FAC566EB01B6F3AD348ACA20D71B0813B47B903A76737F17AA2C50C37A1F4B3D63D0DB1E773A4420D26598BEF90D50F845857E15DE09392A44E64D23A4FCEF5A91202AC4381A989DBDDF9E673BBC49148F3C300662058EEAA593F39371F89EAAB25B617A4E59EAED4E76802D1978B1B4313F165188281A55B492D02BA944846A2D187E15D2B5202D0E27F7DA0D89409D029C243EE2FC9E674055E7DCBC7B0344EB3FC55836E4CD3BB3BEF5EE7D961C768D8DBB905D3DA7259B97B304DCF2EC6170E6EB2B333C36458355BF2AD140B121CE5A36EDD1A7461BE2F45554E10B0DEFA184BE5D22E6B8DF20A889A54AAA24EEEF19880898C4AD7F9525C38923293239A8B42D9078842C85E8FE9E3945A2892307201C508A03ABEC014BF6CD0CC9B27F1A81406632A42DBE682AF61A0D17A5E82B257EB96EFF40A837D5C13E2AD39D5774BDAFF2B517F9B38BC3EC5DF44BEE9C689663B6BB5D325A8F2C2B6DB2A3500BD7290B9D989BF1C5D5BEA7E22E3D9B94ECA75EAE35B84A9171BCA9762928DB6C9CA5209D1CC080EBD099C5DABF9EE962C663BB4DA4008B711EEC5275C127CA00DB908FE7B6EF06807B48C22F85FF86726426A16EDB66738703178817B302EAE19ECC0228B262BA1CA763D42856D85679E4AA092DD4177CEF7808E9F28AD35C06DC68F4C121DD85080702F994C807678F6E665ACB9DC338831AB23AAE395C120C539D8087A4FD2AB3FAB57B2600F8FB96827F82F927277F3F3227FCC2ED98B864A21472B9EDB76B837CF86221FB0186967B2CEE80473943EDDE7B302DFCC0FF743025A82DB30626A53BD707DB04A74CE0A5A6311B248E32E690B13FBA0B016851772CB4BD1F92EBF329EEBF7D9960B90B3159A09CDA3061A910FB2E5D3FD93CF2ECC564E9279A660F50755F6221EC4DBBAFAC3784CCE9873E9B271F28C3A74BA1BF46FEE95F328CD820DD4B98F368F04C05BB3424ADF73FE46E51639CE0AF5B2FE532D30D571DDC137BAFE28335FE579682CDCE7AAC2B6692389724D6A67DFB090497D880000F464240464105C121D253CD90224CF35433E45AEE0C0143BEB7E16714FFCEF3842BC590783CCA30A5AB9C94EF007D7DFD89FF0BB61C3A576F62F693DDF21C40FBECBC9A389FE456EC204E1CAAD762B71351A2CA62650E6F81AA6DF66348F6760CBE07B1FDF0BBA9B4B47FFAD7642BBE905B4625953F5420655AFEC5E5F55FF3BF67F82EF7F81925163E09B575E6B555B68C7DAA0BBA220F6EE1C4C912607EC3C61CAAA6D773C8102302E8B59DF40DE0CC8DE2ECA740201088DEE369DD8EDC3FD1278DC0F76EB4B389F7CD78371ED694F656052FC2DE754F3E35B19923EEC17B8F17068EC2CD5B4EE2B89BC3CAC611F9F73E1956467F5FFF1138CE6032FF2228BB29749EA9AE6F3EC3C8C932274D7C9D1D2EB92106CF7412B85D4FEFA0FB98EFCABCBAD12183FE43DD873D28CBF8A373DE61859C4AE9EEE92FE7093FCA0B71C0203D2BDAF5C5EECC18FE9503D8216CCE3E00F403F2FCB1AF56AA3B55AE61520160B1749F1DDD5208AC182AA8D901C708B23E8031079DF98CA033D206FF860AE20843F875390A612A0A092506F1C1018866E6E5CA2A2E6406FFFAD9F6C1F37A7F6A8451E17F5DF0DFC5081882ED404BE12A26760E04FF1A41DC353E60A28ADE08045724E2BDC936F2DDB3F8EA7CFCD3564ADABED12F2C67C4094564C5FE7641F3DB5F96337EBA4F38448675F7A512BB7BE3801AD67E708A8B7815EA278A80F386A268C866F30105940CF73381B25F9CC74317495AFE6DAB12C8A3959EA64CDCB987A2270C714D6C7F6705466574766B4B43980DB232BCA1DE28B0C8C4380053086786BD933FE0867E159D15403A6A138365F398300B481CF432BAFED394B5FE0E75A061AD27200177C163740EFC8361105856CA3DA504D4FA8FD24583FB75EBC5A5A50F64BEFBCC75BFFDFD1B4D257611B3F8B701655A24A10FBDEC8822155CEF5A77CFD83552FB81D3DF1C71D2C7AD43C06ED4DD4F7911057BD5FB324499C7B6E866561D9A33FCF42B1E07562BAEA6C3C2BE07CDC68CCFCABAECF175C2665E402F539F1228008569B21AB810AC9EDB7F435BB19ACA9CB1259D639DA9C4A80AA44C1335764D8600FC66CA657B72A335A7DE472D769DE9719AF99218D7ED9E63DE9F905F1BC5DCF0B76C27BE4885FBFFE4CB53238BAE1A2DFA14E63F15090898B63EB7CED821EB2082D5BC04D88FDF3F8AAF386EE835E0BBE325C66393D7D170B1DFDDE89F6FAC4CFA526E2207BE8CF414A35592EBC48A19C70716A07D0698624950DC6F084A173EBAB6713EFC114ED479180BE5D545C2B47074FF9EE2FDC499F40B8850FE1888BADDAB972C50DAD2425E51653D54E59C924E88715E103025DF63E6556DE1F5B576253B168F84FD95F20318283490B8CE8DEBADEEF0C64DE93F6D19D858992AB10C8A096FD88F59A2311A850758CB445FD69FA0EE754FEA2EFED84AC24347E2F9379F5D6D337CFFF39B0DBBB8577A735613F678E83FCB70EF967F8909268C00FCBEB6A962F4AA9794998F818A958E2D7650E44E59DA6FA1D5FF327B725FE4BABE71926024A9C422609A15FE599DC332BAC6627B80F160E9665FEF320806E48A358B6D4BABB579DD9960CF17E7F0C519AA0A6D8AA9250D661DB87F96728F011BE9BDC75BA416DD8FE74E13E71395913E95A182E9CA0386F6C85D0C234278E817B42006F792ED3603F7535A4C914EF5904282130DDFB7805B3F31972CF81C6D082E488D6E6774C4708D5FFF4348F56BB02339F1FAD86F5486F50458CF5B4C979DBC9845B815D594AEC3330F8585763E55B3BA96E7A75B75BE769C3CBFE5C21107A8CFA3464D171367D37C642C679C8C95B296E11EB1F06216FC653A1BD7765DED08209D17B6F4DA8927F63D029415A77773B67A4D142A2F1860C9FF4720499A630086F416BC905E651454D319C69842DB7B050D0FCA0641FB51DB6EE4049F2950C76182C868C4C34F536CE694C81ED54EE64AC892EB58E73B277EAD2057A4BE6AC5EAB18FACC145FBD42797282CB706E7BC41ED667DDFEF91DD0DB6570C8DF4E81FB060318755B6F8089213E834B6C5C383D6ED1FAC019B9C3361C9C289A6CEA9DA93ED2FA006A858C0CC92254EA9AFAB2164A7C0216FC821F2338CE4FC105B5D8CFA35108F9F65B4542879A54872B0CAF7C75F787DF856D3E2250535497EDB1AA451F6FE7F3F42600D801EE6189F494C9D2F062300CBE08F1C7DD7665CF3A97D120306E428E9EBD6461316358260DECB606D2B1316C0F3E399B80FE95DE41036135999AE20BA26E2BF02131D92B53A89BBD7C933754522F6F942436E36415F35CA5AC30115F659206F629C8F41A1AF99BF274098A55751E6FA90BC8C349B040AC25D38D54FCFA3DBE38239356ABCD0CF3A798353FEC28197C9809B68EF618BB27263224839EFBDF265FFB264A9E96053715B77B63EE06A2C5C89CCE0CE293DD252270AAC3B47B173F43CB958EE5D620E23FC11B82D69675F2F1C991D08C73631216AED04B296AD8DCF9C2206C140773469E1DFE937D297843DAC11075ACE725CD9D0E6321BCA56D559CE7404DE58C0EB3F93D81CC39FC1C66F9C6D79FE262610B9752961C6131095F26B622685FAC77D0EC5E69FF0C082084F60DE6870F3D758AEB48B5FA018302F27280B77990579ED180FB831C29353447F9263BC13FF16D1356AA43974C5501839D599985A0144CAFC15ECB26C4C836FF39890573B8FE8B055F714BCF6FB9802A99298714B009B7CC2E02B5ABCD99BE7A8632AD6F21941D5F816A1720D5EBAA38B807F960207CA24A020E7AA3E793C1FA3CBE58DF6CD312888C06DFE4FC2F378CDBBC3AFBA5CC7888D44F48776120FE57659240BF1A8FE423C80F909AFD88D875DF9F34AE9CE0F627A1A400F043399117424578781C1EEA513CFD58CC3F6D25315ED129249C9D970BD70E2A091E3A753792B21EEB7FB4263CDD4ECC3FFCD98B5D2DD294D72BFB6F6FB00F391DDFCDD486C3123BBA45DD30B8F58D9791CCAB236FBB84195CF060EE8494835694E08655144984CBD04B6C980EDC685CAD258F13925755084E35369BE0E72AA987B45FFE32F61426555127615159008A0D9DE7BF15ADC2E2D1424C3AF92A39E0E5CB7E1C59CD16582382CB9165F527A808F721FB836914FC723C4FE05DD5F807FBA8C7CECA4E94AA25FDB08146B8D800DC1D0EC93D86941B641807B42B68CAA68215E23D80345DC0F47FE6C146C0451D48D9286211D137353519D57F49193A89E7135AB47207004045018BCF4E1C783795C9A82E1529AB78201199452E0411A2D3DC1F45C00AFF1F5F5C37FF728712071042DCFB5C1BA1F683FB27D103B8551322FE85E7D71FF7CC5912CD7C3F85CEB86B8EB308438C88010CA35726204B84F8F310C2E8CD2D1663106092AC0C746ECBCFBA1A2F49E8FD635B711EA35A0A6EA4B3C610A38E3899B71A929711690EDB623F85DAA22EC142FF3A89D87AA2963AEFF726EB32D035FCB3D2ACB2CE770DC53FE57E061C3A7C1F5926238E68DE09DF31D803F944A51BE08A0700BC014CEF75792622634D9C27E14D7C832F1026BEF8F8E531D70078201ADD1BE5F8C640B80A1D5F8303BC72640B669B6F199F86AABD2DFB17EFBD7CF744AA3E7F72F882894372B422413228F55D4477C3929F3C9791E50FAA83BDBDB38BDF42CA3F1C9894E3DDD5700DE4AF8FD6DADFFB05CB4A4CAB31886E80F820781402010E86C664C1D8F9DD21837F0CAF548179B386ACED845A3AB377899CDB448F4A5ED11C6986AC6BCC9727781273FFF0021CA6386ACDEF64AF28D06CB1F045AA983B54639EE7B25E0F11C88EC137F7D54250382F2F92024D0DD48C42081A997AC3B8498FA2260080A5646064F2294D14B99CA51F0C7A55D99B908DFC3DD4EC5DDC6D15050D1CE4E3EC81DEAE674AFAD5655247808280E94CB8A68E3A901074570CF21B006EF33FF9E3E62C12EE4348F016F805BBC3B6DC7D8B486756924EB7F451D5058737F2F45220535B217CE6042ACF2B12819397E93587C1B71CC37C2C959EA0855702403F4CCA3A3B1E8BFF4157CB8F7205EF48E397ACC836967F210500E8E74013273C36B8309F538281667A80388C6F900195704C4C408309029FBFFE899C264621EAC3A95F4B7BAC0A00D4600B2860BB5BAD14DEBC8CFBCC7641A9791BB5F1696D9709F409CA8BE6007850FB2000B89771E03D7CE67C15AF5CC91F6C5DF652871812B3F7E50DABFAE3CF199A696C1684D32DF0349AB8500F744AB1A55D1C211930DF7048A012E7B40D11D3EEF1111309A2B23EC8E3310040D02B2ECAEC674BA82D03513AF844623E8321998FE9E09EC9E0CB80870CF2637EA03DC04DBDE3848E0C3EB8F9A820D80F4CA370625E891A34AC7F1315412043CF963FCA974462D232898CDD0CC553901140E563F5192E618C85EFDA475B6672098F25254431C44445E5D4BCE9BA8FF7D4BB1BF6C03B850902F781D0709F86F25970B83AF7BC0F140EE6371F28098C943F9A21290387924E9A05D6293538F82268EA645000573CB69CC0BC711E3FAACA89C5840ACE51CE2AF2848925C7815DED7D4F9FDF10841C16C46208BF84AC1E26960432BF64AC03A12A20F1842707B203328180245AC347CAF14EC2E0327A68263BE968674FC61FFDC46001485C01EBE667003EC63A0F9EB3F6CB7E9AE78250585CC019FD320BBC5EF323832191CA1DF54B470CC323889C60A5054BAAA93BA014D837380C813654142A32416F0CFB06B0896A11ABBB723095593B5F787FB06459B90C27D97C1ED48E1D6A5181A52B8CBFBC23D40310F24F0085191E048E149DF084F07C5C2AC7CB803AAD785C2EBFA2A81D79090644AB1F8A5F090FBC13B41092882F7F74FB2FBEA2E522A21B54E21907520F836FF1F8DE7A0049175F05BFE7F45AF7E55DD4540159D14812A0D41345832048184F6BA938A484330C3EB6DE1F7374A042F981985698CC902FFCF999E008A88620491D6094719099A3D5E66A42E04010C45784F8392E18548F47F1C812320A068830DEB73791324174E2224CC71B310F1FDA324BC5ABB313DF31FE16463B2E07186D97C3F9375F804F98C1D7A9CEE05A366611D3C445A27780E97599C984976290B893F4A24B6C10329A5695BB7D81025710B24CB3428994DE009931ACBE34D6F325A978C80802209A0480581B8422D5D1B424D0A91920413458121D2BA9251BA921010842606FC018A04189A4120E9DA66DADA69DA1150A4834023EB014785A6CD466521FB478DEC7693818055EEFD6E7AFE044666982E290CF2232ABC2A85B097BBFCE121B27DD025656FF12C7A302213A2919169A68A45D8A0C2DDD443A475226D06D584EC904736050211F9CCC4993E13461042519C6DA79CAE0D91D691947B39EA28BCFC61D0CE5D24282918B97DB7B4DD3CEB54FAD006105014AE07BB8D1869D788C435D32D9DD993D9E5ACDEC6CC699077632A1B1138E2189C019A0516A969CA42DD881A75E1F0338B8A4AD38EC42184A28D1A4140D1D1D191913850D4772328EA1B941C66686696A60DA1810343682491824630F1DC59A569E7886D464440D17AD3A014C456656E0445DD36B4CA734328DA3C7FD9656041D1711987A1A344A4A8AB01459728B343E4AD2962D581A22BBC0F072DCD20A811FAEC9660A8AE01821A15A91F890345773182A23BFF584240BA101A08884B405B4603758EC6982DC5C61CF7773604411F82A80F418AB589DE57718448EBC425D6530DC540C8CECACC484F8352B1E5D4E910507C8478E24DC428032499DE0CEA185F5AC6251101435682AECCB324A02C8CF5A831E6B312C9A699F304A2787920D23A519C49C5242AA874842633530226BF04D308A3CAA367876A83CDBEAB13C91F0D91D6890E80314B26F663BFF1D00AA15760B68501F98D5193D78662EE48512B1AA8D68D719AA119043EA3AB0DC592486DCAC20A890ACB7B21F11084C83403ED38086267EBB1B110A4F43428563E273042D261A81D0D419E77AE11150529E1A6615D38FB048C80A0E06E40B88433923D6F5A80204810500E8261D7281DBBBA0128324D9B85A0F086231C9D4CDD60B3B0199A8BC1DEF605AAA4520EA7275AEA6825E0AC55C47973545BEBE944B3E9618528A2B0305C5DE5E2EA34822041C06E2019619C4EC1A2F2B86B9DA8CFC79480FB20C123C7A84F595D7445C74ADD8E124D62698C1947F050021C23A9DD63624C2F07C347A842F8F018BE7C15C7978B1AFFB35EA995805F5716F067FF6AA7F09A86D64168B9370929922B09044B29AD38D293E9DA4E388EE2910954C8D24EAA12507D0D87D15023BF4354847E549481F31F0CD222C119518450C26AA374080D5C14D82C2A1297104A58651425E84C678C12C606A64368C0E9691030380D4A286A6866A69DA60D25EC989621308B344333B388A84058CE1B4140911050926B09064309BB3FA02B996A3AA83DB28F32153946841E8170072322C78840238D24801231D97E1C23128986080F23D2BF2F911E9470B93C91B50244AC185158D4442E1588F2BA20F2F3A46E2421E13791F6604AD0D98075E428B6F10C25FA0725BA8E89E80850A22543B328CF1802821263444189B6878AA864C4E089871273454289F17DAF40AC12819891C47C6DC7DE8E8650C780F1A0C4BE4650621F28B196A1995994609AB6833470556A9D38DD084A9C0625D667E04269A2C1E9DAD1109A28B868F078A441548F98D4CAD0CE08647A0484263A96F518F1A494F8673FA2C1826E2327F26328E1FA7CA0C4FF62A3E2C050624BBC31433B435BDBC15A50123491DB8A5F0512C60824E07E40498478839128464DC25E81042A2591AC0525F194FA482309A024218A859124472071B08B68D5184C4C8A2B46D2262569DD475092A1A4A8CF60284998A1D9176D6D080D94647E2092DB2DE9446E60247F2B92DC2691BC7F01C76E39DA392D20102829DE605C674559DD8444B88191F25724E593914ADD26533B5304F8EBE23A6FCEFED2EE3B2D33279D60A48132D280F2A47178B8C9A81515A5CB49EDC0CB2DE15AEEAE41341E01EE76DE343650771A1BA8AB2B8DAFA3930F8DBD9FBB8DAF9307041405D60D77B7F413EEAC49578EAD91BE42E8A2A1A4A93E5B40C990A3A0A4CBDB0CD2FF8825299A30D4888C8497E47475A164EC9150D2AB2492181940ADA395C83420A00A647C22E32432C9C890600925738F8292497F88489C5B52788093AFA3AD373440C1D791C61EEAE46A671B6A7FD013913542F044300959604869449B11C94AB3E29603B60A25478E84921DA86624723C440723678840F6D6319BEF8BE42A90B305AD2982744D2EA6D60D2090983855C0C8C365E461F7244F8E8B8AC7C809717D6A4A03252F1E886488A4FD9A4C3ACA82379978BD2DFCF9987C1B2E5A8180A0147451A9B6E7D2B58BEA0B8D828752E81B4129F4A0E4C711AB0A164F7238F40890FB80C6CDCFC797C6C99D26C0DBC9D7CED5C9C7D76BBDA8EF41910D21C52880CAA0B0C22846235224A445EAF7DA4A4A1AC5AD1A3941D749B11B9488FDD0E5AF35282571743494E275D399A23F5F1702A2583BEC9EDA3AA50D94D2321A4A49BF954C3CB796F153FA47E94329B57F4CB62E7C99F4EC2828C5E4472D4A2263A114CBBE622550CADA6828C591A159040464161DC9B410CA3D2328E5401494D279E9079A48888252A223B9A2C564CA509F6306475E8C5BA16C3434D38EEDCB7AAABBE323511140A9B0A1546852CA2BDCD5751C3F948A21124AF97485F705CA51491913EED435A054EAD6658CFF01EE383ED2965496917150CA4F6BAB01A5722B6BCB187B2F4987520543226E0E1815795A4EF6B3A6F6B4E90655E69D80B87462544D32AAC6F2547D91A962B417B11A50AAF5FD23B66838A66F4C5266C6FFD582523D3E478C3492004A0D7FE262D484DDA1BADA0B8C9A5746CD539E5AAAFBD4480F38F84267A41B94DA114A6D1303A556B65C8C3A3422B5AEF60022527FA9405D29A3F6252D1C68C86F06FF819EDA43CAC2C1F3DA1E3420FABF57A0C10AB044EE73FBF79B9CB326AE4D96D342C6BB171DBC5D679294C71972C9D1867869A74976064E4D169CF0E35D5AFA4549F568D62B1065BCFFD11F5BF8F2DF15BA02737AB3323AC4F7042301C95E11C274AA5222DAABD1BD7B08B34B41EF17DC8F86F39D928A99CA5BED552C799432FF4EDBE62DBD4DE3FA8BDA729B1D9C9244BE0BA16A8F6F5D78FF431D43B9EDEDEF0F348FEE8947F7DA01BB40D7E391422CB7C7A2C82B2C3071C08C3F6F819277BAB76EBAD0B56FF08238A9FA3458014C6FF562FBB9BCC315A9AACC4D698453DA7C4D491C6A986E11A2C3932B590716DF436B5A21EC6AE4053080AC381087F624462AC45211C2F59B9DFF234C928EAF0CC641BE8395C4CAFABE0A58D576055EA866FAA05058D097DB90862C06E3B06221BFECF9835112538F5160E817B81DA16B807F66C9EE41100C08BBC4427AFF1F265F14042BAF5CDCDA7FFCFD9319C6B587338190F8DF9699CB7E77D5242CA1FFFBC45FAE43E139DB675CF54AF9E78FE69663624F10051555B414AB9A6CD311B4212D2466BAF9D353F5F0250062F00CDE17BE48F7EEE69C2F3C9F998AF7E12CDC9C66136C9864B0DF238AE8C90B284019738D59399D356173159A1B3689F68D32DA5CBD65C0279CE5170E9E44E9E88AC1933178AABEABD85AF0D999FA6FBB4987C1CD29AE154D6B496EFE154D65F1074F113B5AB0A64591369CBC2B3F163D1FE881871FA6C3B84A781F4C7D7C60B10A6C0F503F5D91E2461C091C68453AA83FE567607BED73693D8F5F739B666314D8162BC0C056F2E821265663C6E9638488202E0BF521EC13FE56BE60153D0E0B4958C9D2FA27B6C97830CEAA1BEA2750D7C190EBD627507608916D9E3EACA7B2AB6ADE995ABF6E50CA07C168A256E667675584362D64CE474AECF435AFE2B34E36E0C1084069A1ACFF71120F7278F122F76DF8CF16F237BBF94E8F82E52E05539A3AE41364801551E0EB3243804CAD3C4EDE2E076462AA3F73567E5393E55B209ACF8593F45F185C9F2D770BEE5B075A3E6E2A4D920947C0E0947F207EED85E922396A9E41647AD9CF49132C55983871A2D428A2754591A4C5F773A753F5AE2036CF0CA348FDFF395D74850C7ED96F56838B756905574C4635737A1FF1838DE79B996C465480E2E13F5D9E03B2B5794CD8BCDBCD1650323908A54965F7FD1A25D66ED41326050D166DD38ABFC769BB8DB2890C2E067D84631F11897FEEFE7275BB4C7A0E1BA2686F4FFB96B16997628BA84BA05C5581764076C8787272DA1C209BA7B5761F9CF0E4FDED090B9E81CFCA91AE59F3367718698996243F7953DEC7F2D9169F129394E242A7F4DFF4E855F3B82E829B8F7FDDE04CEF1DD5DE4EFCC33A93AE53AAC4E8CAE859CA93031800476D8AF9D41DF3FF584FAD1C1C27F887CD8025D221DDFBC1634EC3075A29A00230046AE051F94C8DB062492A57F12729F0AAC611FD30392FAB98A0C71726516E7A6E91218CA57F43807B6CCB50615FE29F0789BAD39FA59477AA27184EC2E3DDEAFCE75B7C3FE32457E657BA70A4ECA1D9883C311801C8E11D925FE1DE45A17396759B841ABBD532CEE5A39ECEE95D3AC4D2FB48645E0070539FFAD01784BEFC3A1E855647CEDE8C9C7A636B8E2A94EB0700F02B8857F5864A61050A1095AB1797C59FCBC30F4F65416A349CE2F51BBEA7EAC7227C317D65DC670B48627D448622845D83BC0006281AEB2CA1FC89BC9B4C9CCE526F76EE8AB619169AD4689FA99C62C8114993EA012C3F34251D1748CD76BF37ED280D4226594A08FA8DD3F2CB242EB3E8758ABB1ACD7005173CFB9C62A8FA4F5C7C5F00FB59351E7CD79937E9C408836368AC7368ECB30D6E198F2CE3BD3957F7D315B1E56D502EC0DAB2EC23E085C2982321D23F2311FFBB7F09C520ABC5ECB3CBE00818CBEC94AD04F66E73F629C3600480F36D8344F7AF803622CD4F6D5926214BBD5CE6DF91E95BBBFE156287A2EE94FA000E71DF2C7721516E73FE2C5693DB43900B052CA5FB49EC78C289493A8C3C700A062703923520C13B8BCECD26D858A459F80D3A175AE46145438E2B0046DBDDE68AE533A49DDF6E577589AEB9A5A86FCE3A742A95F2844F39839F65A48B7B3D9230DAF8EF17C9250E849FB37C7629D0D9F2D38ACE643C705C2D3A0F5EFAC4F98F2E8C42023F9DA7CC2790AA1F45214E1036AC298E307613FF066A1FDCB23C9A33EC045E2787A57180C5E27155F55CEA7D27AA19BA4DD1E44B8D64615664534F1D44F9AAF4D993988A8DE0AB83284BDD5FFFAD4832825F180446E60A53710671C5EB9BBD14DCE885DC4A68993CC8FECCDBC9DE45C996C856013A5EF42A87713579D40F2836DA4C4311183C942DE9068FA31A3EB77C737F519560B81D53FF8D894E8AA1AC480342DFBF6E0FFA35EB69E46391D633D697219E5C1174655C9CAEFB250BBBCFA924F84D84C815D02ECB53086D0DFE7FF559DBA7884F0FF73351BC3B214563C2891F9F0DE8F3D2B5AEAA6249188550C813464E784533F649E60C1B4B5B430AC31D83CD32254052F865465E47F12EF9B6202B97E486AF5FC1E22D4256403AD62ACC1F3463B72186F439F8D6F7E8267C82903C98FC4B6EDD55BB57502433402008171887CBFCF986172647279194D262DF501A305B728C3FCBE0D8726E977098FA408F1EF77FE8806578E6C7D962AC046B4518A451313B6C08793A9BEAD0E9A92DEBA54C91DC31B07A685D9BC2BE3A9DDB04D7D0A53A87930BA394BD069549CC3EFCD7D4E24D084F16C68E08A6BA33385CDC030B96221C9B123A5DF53B2C2D38D5A1B98B4A750CF0EB0C9649AC74FCD7D400AC6CC3C0AE781553DDCE550DEF2D174B118E4DAEAFB2EF572C2D38D5A11ECD56BF5B901675E399C2FDCADB61CE99BD1B878752CBED24D2EC338C03D7AE96BA633BE6C825B5853F9F4A8080C8D3D0D690ABC60E49BBB8C1129EE47631DC8F9DCEFB4B6A394EC16BC633A7244AD8453FFDCCA291AB242388A7FBF38D2E36158429D9E4B0CD541A70AB2795CEAF4869CC2E4279FC8FADE31E8FB600F49BAFEBFB1F5DFA4DBF84FCB5AFAD5E084E295246BFA7B899C5FF4865C73C793D9144B71073F5D0F5E5404A7BBA6D2EEEB6E44A01A2F371EB422AF26BB49849D8127C5BEEADA7060B95D5459A2551D25546075A4BADF49B4BBFBB09627BAAA187593886EF5153DE2802C018EB0DEE0A1D6143495615E16A97F5E6E64C7179FB052F492768FD5DC68C34BB0BFC1704070281402090F5A3842A41FE8DCE46B30ADDCF06F9A7384CB3ACC25E75EBD34EC2FE7DF7E118F0D657F4336A57AA99E99C64060229FB53B42AEEA610CBA303FCFBA9E992263F52D10FF90D44D78738C5AB3E06F28D6ED04767DA9790403DAEB9FFDBF83B01672EB293A31932A9199D55C9B75A22F40F4CFFF0730D5BC74F04EC8901F74455E5D1C088BB3FB083AB325184B4A0A21DDA49E988DF7068BA10B7281206127686C20F148C4DE3DA0F3D32650D17DDAF623141ED3D240BFD4A96F3D52BE318D427F33302F39A0FB362FE145C0D68D7F1CCD0F805E7C30B8197DDBD97A3618CB81DF58342CAC500B22AFD4794F2DF32062C4F07E40D10A79167F82CA6EC07E6D7B61B36CD5129AFA614109ED509E1D717AA159F05F77AE9E4E906CA2AB2E5942004EE81BFAC3D1199E564DAF10481557EDFE60E20F43A1CFB88AF462F20A5E1A85752CA6039A1ACEC4FCED86E30F813A3BCC259168C36255D40246A4A8AF8589A59FA20F2CBF83F33498A1FBDF70B71313B537F7ABE6B56CA826014B261842713496DA53DD02E23B2F6889DC3105FB2B103C260E18A2F65089E8F4957F253071F91EB31C1D17343E51E65EBF5C835394666957C33E44D2E7E06F38A650B234E12643C25593F26E10E8081A72523579F4DBD74F07023064DE9395793B4F68A203123924B98517395A00105402A62FAA82A8C3ED351E057EFC15B7A386DFF0155B9CBA83B7A4E275FBE9A2FBF0B6C647D1DD319337EBFBC516CF90DF4B76D2130A0D1F20B7AF89420129CCBA38C2489B3D64965562732EE685CCCF4F6491DC5C91F6096013F7A6EA713714B0B2670BB7DCFB9F4B12F0B90FC34FBD4CED0E7F25BDEF4D44785622038DEA65E92534C69C4687395F5CBE2734AA9D4DF412135071748091C5F7EA35821DCC4BC1A845E8F7C11005784D4C6E29D416DDD38E3AC0077F9630270AC2DC35EB7831F0DC421D7FA0A603C30B339537E3BF77DE56C7AB23129885841CBCCBC5D80FD767AA07167A5B9E96C03152EAE933A6A1223C11343B04C19AFE2CDD3E075E13D0613807B77300B9514F62A12574BBF83EA3E5DDE67DF342FBD9BFA76F5A15D313FFA4DEA5204DC5420E823F0D0BE481656370490A009E4F159B979E245BECCF296256D505B8ED23577617483E04020100804926197E85FDF4122A52B6416B33906B00AF5A9B17A56AB43F64C27D7170D472E8ED43EDF3255CC05487BF5CFFF155C39CF46CB5CA9C18A70FB7145CB07045570B2EE05C77BCE09FC8C73CBD41EE03CCC41D46923362141B09970406B272469FCA3A178312029FBF32781F9F2CBE9F90076CC0AA1B36A7E12BA8DDF3F3053903419AB032D8EAE4F37F7B067CC90E56C4BCA405AD63F39475ADD56FB8D482C1ED4D8461D61D9380A781EC7AF727D99F9D442FEDC362D4378B7C4CF59578CD130EE4E4AE6FD4B981E0DE4B6AC46C4ED573D33DE1FDC3C755012F2C0A92D2DE61B3873838F9C72FDCC37CC2359705B39A0B9E7FF641BBB79C8ED8E30FBC7BB6AAAAD085A07ABE3A91744C605FFCA170330206B219AEB8659C1D4C09F6E318E05554055218637B44244856BBCEC8C3B70B80620D2777D9CC47641CBD3FBD7145D9A659429DF7777DE5D488FDF548AAB43F6AF1844A3A5C5FA656818573B5AE7C468819A044F8BA52954615244EA5CAF1465EEB61DBE2D3D57D56ADBCB5A5957D9ADD1AFE84D661028C14730C9A1E50948536E785CC434707AC371F2FCFB8EA45EF92359FABF546183E5FD7E5666AADA19CD909EF3CBBE23E4BB8F09F03833BB6092589F2C2193B38B70A956DB09E9DA53F9993D28F5222072BCDB8319C5414BFCE24FCD57367E65846B7DED3BFC8CF58ED49D47350010F726C2125F416C9A478297521876137751D8D159081A5DDEAAF20ED7FE7DBDCD3EE009E006B6C6FD12D333D83D303F0C80015219A5EFEFD233B6BAB8F415E6AE47143AABB218FB0DBCD46D6C041131B915638063C9185A8A9EF4BE1C7CBD807EC243D97F4D81A7B818C8BC1FEDC0FEFDE37F7730837D9FED118F94B0777FDC7F22399CB6CA83DA4202D345626C43C27A9BCA9D0573C2C013D14E461EAF68DBC1B790422AF3D706BE33762A2D0E061A5103B4DAEBE3726207FD0F10D24511BFF3E9E5644421587817E3CDE27934F51D0B9702F30F4EC0BB28CCDA853A757BA57A1707C30484B4C267F4068E797427DAC1952F9E7E736269D33ED9EF7DB943A190542AE6EA0ED25C1D752F14F7C4AA4BE329FA632C73B61694F013C664D747C300587333BE7520FDD7BACB1230D1E2C7ADF8711174F20941889A6B73164E8260C7B6D307A4B34C9178258435B897BDEA04642A480C6AD34778003EDC0809AD7D130926CEA5292809600027ABB138156519D368F6ADC0F9D802C709F4BF3EC2CF008D67AEAE359A8D5A6B000BE6A5FE35AE17C423D253A1FBB2D406D7B34FDA675AD083FA9D56B89B7E58334B148AE40CC6FB17C1B7D9930DFB51484986BFE9406DB14E70F6FD98230C77B970B6FC6E536D040A3B293CE273EEA122F6540AA5779FBA9948C06ED0B673537C62474076FFC8DB639A5658E00879CA2EA14787FD982D18994A0DB452E806490F26819C7F38C927C5D38088E7AAB8D30210D193888C2277C0981760C09D041F0B095E7FB4FE59F8D43E9AA0D133F74B09964D1B8FC4FAA542E24CC924E0A09778BD6FB65E76B126CD2B560AFCCD46B1AD0F0FFEA5300A6330CB66D54B9EA87A655A012B42F512E13A94DEDD7E52591D8F34A738118B609CCEC5FE1EF58C546A53A241DB75FBFD0BC2FE820200033C7326E1622F345538F4B657F00293BECE162BA9D8B7A33BE892AD49B6937BD60090DD1ABC3691B64F7B026F8FA6C5F5941D02C32670FC140BCE5C8F1D01F163C1727D96A4803103059326E3951C65FB69E8F3369832529B5C1613C0DA6C0257A9168DF786D15BBD14378EB87C7A9F8176B323FDC76E7E54038CD773FFF30DED6D30215BF10B1C1C6B435C91FBFB1AAAA52B2A73F261FC28CEAC1DDD0B9A06231F4C827D8BCC021B2AA1806B8DA6993BB344F7EAF90460CEFF3086A5F4B24B433850D77F8B38F2183021E5C719A612C764A45670FD998A976F3554712382BC7FDBD9A501A05E3BFBB170D1ED298167AA244704ED18128E7AC945874E9C5D11A34B85C66C6AA4F623B9ACA25D6B651E62D6B68EB83FE31736BD54519A15F96284315916656F08424D418902DE3122A428021FEFFD1271BE1F617ED83B44BC1FEEFB4EDD36C09677AC576DF108A82985B88B772CC9F3A0DC29F30F5A984C285EC5E22F250AA055882AE73C13D774415E40B19B625C05F647FF6A83DA8CB1DF63073AABE627C1DBF84577B692C44D2F0962715620E1F5D9B00DB6A450CAD71798B03F3F8237D05E8793237FD7C1B804B8D493477FBF0C4BB1B42CD442FDC0DCBBDC2BA88A044F060069F2D5456BA6E2B0532A3D1A22FABD2FF7B8E6F375237A3691F8A05668C8FF4FD3CC2DA3345F44DDCD9DC82344E5D697900E610AA05191D4F8D7C4E8F6FED81D9351B95B99C2136E0DE78D6F65E1FC1BC4BB7CE4F14618158C81C072833A1970327CA79C469E6E60743A194E49B6EE163F76774DFD8349567D7D16663FA0257F016137E0E4010676B69DE29A8E317F4FE937E7B7D05F9B9C7E13B7BEB90489F888D088CD4429FE079C04A2E2EC78B1609FDCADE3A2D0CEF7E9C222F20B67C70B2D05A04B48FF38A83AD381247566D737AAB781B3FD55A2F81C7C68B451F0886ABCEF74A92CBD383B32EBB990D86EB38FB448F4F48946C80542E78ADFB0B34A63F72878E8E06D933FF6892BE8C712BC5D068BB85309F767537541A24170201008040229AD8028D6E3E71D6F1CD46B80DB191C40BD02C82FBA3F96C21435394D2EEE9808052D6B689D8EB99C72F82A5ECB8EF11FD19DD9CC9415208286244596658F3C659891F5694D9A250D175E47B8DB74BEF07725C9BAC1C1F944F469833069902BFD77EF2A41CC679AAB959EC31F18E87968630EF4383958397F38BA4C4BD5563C302CCF6E28E4772BD9BE0D80439B10FFD64F118EEAA700A85470758B3AE075997FD610310965D2DBCCBCDFCC38DE154CFE1BBAE6428634DEB9788220F3A9E1E0C280BC7C64AC1CFFFE010331D3E80FEE0FE419C261083B5F7DE3C9B7F623CB4D2DB317EE6F11A478006E9F9817A9E4C5C0ED00BFF3D4A8E15680391D5F80556BAFF4A5EB00A5FEDFC185B5DB108AF494283847506FDA078AE593C017757AE7EA675DB04B4593610DE71483D1CD4C75B826E7511C5D3F8E708BF4542DB6CFE21A0F0E54AE8924EE42ACA6177E5991545966E9A5996403B04F443E64F366EACD3F654748C7A1D85834DF8A838966B768A9910802AD7135400AE1A3923110F139562FE6B7DF04F71DB22A732727E194835DCBBE20564F26D141EC6E625DAE4DABB5935008FB2B4A4430403BA9D2BFC696F2325DB46C9ED0361A2B851007BD4CA347FEB3B1C2E13A372301A0B9C59D6075E36FBE760573FC217B97CC33CFB05C8FCDC15D5EC6378E0037A677C9F2E74D6D19743D3115EDD425D63F77928B4B16E3ED776CDA9102AE0EF8FC4A2AE862D3458E1205E0AECE994D01BCAD990A1F5AE09C22BEF4D765E4C41199D97E3AD06DB9FFEFE20452FBD609DD6BF49FC9A249589829168D4CA4E10548081DDB4088375F4A3E94DDA26EE3E2BBF28772A3C27D98256D7F2FEBE525AD7A204EF8E1EB89605B7AC06F92F6E29B82AFED7B51C51AA70070AD7CE44251801078B60208492A2753E47F4935356CB8BFE4643C3F3F69DC37A07A1DE95AC3AA50BED6D61D610B5A35976FC74E989CF28EFF0516DF7E9C777F2A11492B556B684FF91A90A954FDC767FDF5E50858C33B6131A5FFED773BCF24A5ADB095D3E2AA62E439491EDBB3B990E488E5BD817C8E6D62B447026A78DD0581D008E7E6AF4552CD0CA3F9C78888FB87C6DBDF5E39A346820161F81BE02C098179BBB0C158A259E2C4D7D7156B5CE27171F6032FF96D015351179CF0AD219B89938D7BE489110BE44D1B310E5BFB1349DFAAC2C41FF95B5F20873F2A1E70FDC40F5DEA6A5DAB65D34B72CB82AAE9D31A34B81A8409069D41C511BA6377B155804BC44AE6E9C64A08C98A3391685A172428140C9BF1C7C1D9DE87694725CB545102F135425E34A3DD4E112370AAAF4BE85084A60376E78710B40E47A8D8BB40A085060F9C66A2CA29249437386E99191B017A6206ED24BB01E2BC30000636889E3D49AC882ED6D33BB2B9854CCDDD934432CB8E97FBAD058B1816F83EA0025C3FC49FF43AC22B993F18F91C62BDFF96B14B764832876817E4607FB8526C2A5E54BC43D557960ADCC0D48BCB8716CE5D54A7B298010B4E11CBB2E5BB49E9907DFC4052B0BB4096CFA94C81076137222FC080A396D60826C418C1274DC153D7E10AD9BEDC4DB7C399DF65B63ACA853B890D7B809F1AAAD2EC8CF5625F2A7E6773F15FED8748CA51AB49FEF3288CAF8912A7D8913083BB6D1969EF2B1CFF350B43AF893252670865796856DC0210CBB7539BB84F62918E4AF264976318383332B33217E3A21B46C7EC2CA3215BEA0C997C60E7D42FE94C9766CA54A34E782CA429B140140FC08004230A315B062D544AF37946B46F665C324484C3F6B2EB66149F4D8EE0CDBC6F0007F4C9869053E84C5B4511C6774B9928812F99777B92D07D97D43D34440FA5B4F2C46D06A51D242A8A41663A19AA274CCAFE4C04117FB75818BE8997877FFC6187D28D95A859ADC0D418AC1BD762832C3DAFBFC9B8A65E360108FC76D0D7F5114223FAAF99F0CC5E82BA7B4EFF2CBEBD009469F27C875BCD7FEE420D3DCDC972EAA019AA21D62E663A391E7FC8F48C8267FBD01CA0A665FDF3FF475C1718660FF482DD55DA34EACBA56A2516E7049AFFF2CAD98D40AE0FA3EB27E097CEF01AC9E290D65EB9B0B1853D84FBADA405286A5B72F812538AF06D0D00623679EA2859A5D48D85703FD6504457B3ADD0A1C2558C6B88BF62A194EA7313CDE02517F4F95911E2E314BE2BF1B0DE1A3C9B671EB2441293F3F54F8D4AFB88145F3651BEE237F13F6E58FF84134E5A23D3427FD9622248B97DFA1CB359748584B94CC752336BB0C94010C687ED567E188001020A082153BA75DBAB89AD9EF7E1CD4A706F1752B3656D1432EF720F267AB83F00530E419A9DB3FC50B3DE2186E0BF3F29F116CC7F422B7F156F95A630109F70A60A3CB5503328E4096A185ED10CBD3D3843D5CF57EA6B99823BA9FE1F94B8823F6325249E43007F38CBC7CAC1100A4768F6414A7D051D23DF182ABCEB1D82B649090EB7E0E1697CA552ECC8E44804E7A38F953150060F9ADFCD9F885E67E99A0B63117ADB927503AC4F4E3D09D50DC49CFF5C7064BED2D51A813D3F1B466CA207C10EBFF6FC2A2030992C175250777DE18A167D4D6B9AA3D268C9AEF7B8A03490BFFBF04B61E7233EC4DADC2CF3FE1A677DF9F3C549CB2656F94316B98E756E123DA9039A1A529E578C51572AAFFB55A6FEFB4CF4490FF5AD08B90482A83AC69067D6F942A48AC08383DA4FC97094004399356B284356D96EF9D2096CEF38AA5AFFE1074F7E412A628A630F17471A97C1D38FD8216A73F0403D160517466B1A157CD7ADA186C7F2A36935AF938A891B4D9BF9B93E40D70B1D8E04F92CDADDFE08A41FFE1C1EE93EB982E172288A1D6142D6B2A5AB4F8D066860FA81433AAF9EFD684017F24451C15B98EB28EED01CFEA3B0B0C72A3DF32792F29A897114E811FB93C0BACC421723851DB322E8AC9A9F846EE30F1D98FFAA89B7FE1A1E85D3F9BEE5D2F0A91ACF45A12A092B5A7EBCF47B6129D3A0447FD347D3233940C588E68F91020E4D5301ABA43FD2E4E0091DAA73ABFBA85B434A61B619519B6CFBBAF2866A551DB6D992E8FD547728F20416814DB442A75B66B4D25CA1DF0592A364E47F80FECF7803078D3BA1F7B6A2AB272656A2848E7FA0DD3FC2FDE4DA2F7F3196B8F2BBC03EA01656FAE538871F1DD4FC73BA9CEDD05162548B919FCFB7FAA146BB79F8834C0F5AAC6C1323E31AFED058FDF10F5B8F621EED94B8082FEA4B2BB98F33FAC5746922AE98FB9FD3E711117124D10520D5D478A2424221F5F257700AFDC3D591FD8BA11AF84975AF2FC6A5BD5180A86E64D0401F1F7BF700670E10C971663E79E9F1AB384F0DFCC78A6D68C4210F900E314E28649A64618F32310CE27C025A7F1530DEAF001328DB297928003020267FAAED6FB66194EC48DC1E5B1BAD56C662704C6DE5980573A35891E918A806F050627DB7FE9B594F83FA6F36CBD54ED1DA6088F1C13FF3CFD77BF53308DEC7E0963E3E0C158D81901FA05E4C29B0EB78C68CCA9C67313985AB8A21FBF608DC405C6C31F2E26C9F5518E0F41FC26E427E0003702B42B1D4AE78D02ACBD5583411C3E84266B75764B9D2FF1E946CE470F1E418006E26AFC8B29EB0E0E9F5E74683EE9D5A2A67DA04F615C1F67E0575954AC2A16A6448833E8193B04659D3C0676A97D208D1AB0D51FC9165DB0B18886D29B2A709ECA121C5CAAA9EFA8D812AFEBF1F6FFF499F619824902AF3A623CC5428479B13889A4B504910E6867896907EA601E097F5F5B3D4AD3BAD080DCAA40F3021F0577E0F0D72BB00F0A1395428195B94FEE7E79B556EDCFFD8B8AFC9D7DDD23C8427945962ED1CFF7781B5CCA5D5AC77F8077CC86ACA8ADC2CAEF7B574CEC432FEA2A92D0AA75158445455BFBD72BFB488C5206987FD3C24EDF0C1B21454772CF1CCF5947C9EB383EE7BB621567AED5A899F9508431FC6D6300AF8D7EFA5C146674C95D2695FEF6218DFAE7DD3E52E3C59049E71D27951069D89026A27E69BF1BDCDFBEFFF583A97C3C13E6BDC5898FD0A083ABFB9F38D45C965A2F11DB2F2E04B8206663F6D04832A3286009F1C531EF104E89DBAE57F7371349C8ECF7655BCAAA180ACDE657789DC9E2B89EAB484CC9C09D3FFB9C4FFCF57440A7FB299B380FDC09B2EB0CA33B59D392C705F244B65873136796B2119C1D6655192687860FAF7644368ED94C8FBCFB9A7515A7BA12EFCE92947405D38414E928268598FD8B1474C9433DBB28BE21D71A9335D439510C37DF66F963C8DD3ED24A1CAD88A4AF5AB21491BA008AAF4378051F228C39CBB37C54C3631878D8AE08C209C303780ED0E83B9C47C8B7F13E9CA9EE3876ABDC3F7007190968CE7BC319C5B9CCB257D17440B040702814005A4A10A3F6BC8DB5372AE3E2A18CB86B1C2D1FADBAF4DBEFA05E0CC6415F11EED015D3F7AD17DA40BE3C88E7268D95995F682D36DB8DA049816B74E4DBFD9EA1E630A564D878F9F4E0F45BC908712C4E66FADF9C6BF5AD4AFA671BD9D22791D0A403410E5C31162E52092654D32BB7BF977837C18B9534A747A2859F57B479E03D5EF73C000E9A806082D5472B90D6C1575C0D6F8BAB49B83C76126B31909828D5915756A20512E4C38BBDD06CE16FED6FF46232A9B7F81D0FB7F3342153694BC27CC080A4128DB554D1EC5FB510CEB702B00037C08E4BCE1FE309B02E52182B9EAABCAC9F79229BB7AB574183909B83767BC410CB9AA93C913B7ABB384A4D4DBD360F36D9BD4EABA5C605B300A288B2EB7A56BFBFC371D11A38FFE332ED1B64D7AD4DADBEA77B718D6932DEDEF9D00DFFEDE8DC744CBD91C2799062C0B3DFCE740D1F1DC33FF2932733DF534332F0750AE1808ACD4A9974AEA4BCDE78FE72ADB7F1FE3946BDB5B2C88E7FCFD374A8BA230BBED298901EF7C08BB1905040C5006E58EA60693C633DCFCD9F46DE6599F4C3EB6F8C5602244E77C50180E89DE01F8FD0EB21D6ACB87FD9815B77ABB7ACDCBC9C9760E288424CA2475708AEA637CBAE0BF83A47B5831A6023C1B7F02583820C6A543D841ED84D629F849D8381600EF03CBBC45C98B09895B935FD95803C239CD047AA827067F030A5C4F5F91EB7A1A513BFD18E6B984FAFBCFEA1763F3C8929D95B270E66F5CB7285A11800ABFE17CC4F279B1DE75D5CDED26192DEBDBC07C8AD1DE24550917A1AF4E891EACF42A2D5E540C3400187E22711C4C10F40585B1AC48F8B3CA604FB1D2722AAF869EF9418820FFDCD37364F4D3F40C9C1DB24D95A0575E74521B6E7222136FC2CB3FD00D4A7A3CEFB5AB3E0382DE8F38614321027172CB4B907EB250C028C9C87E6D1E3D26BFC39DB858E52EFCED6F4799B970A404857CD0ACB9EBEB7E12DA60B16717956CBD91BCAB329F92A43E61D3B7B9C9BEC8FD51F6E943CAF0D6F0E393A088A268E6AA5FD46BB23832283CC4686A1EE92A431CB1BBB501858A02678DEAF4304DBA5C3945E75AF09226C7B1D76EA775EEF5122F91A018F90B18A01E79766B5FBEC5BE4DBA347760606F1650C56738CCEE99FF3B28F769ECC3F7A42EA43E101C0804028140E91D5022A61401C769C2F45C6FC8AFF95E89762F2AD9646594944383E288A3DB1DBD129EE6FB9EDE5C7E2E68B35CE9ED9EE82362329CBFCE3D7E15A43700918603B8E0BEEA002FA17CE29A0544B154E5084E4C6B8FF5B0FBAF213F5C0EF1779A9E5DC95FC8854045CA21877975CFD5EFD224314569544CF8F75ADDC537E6E697BE4C93CBE28AD1458A5A8FB92E5DE3AFD5900AFA903F91A903ACA65837239351E208B99796859BE3B33567CA9CD9AF3E852D7FC4F479C48A019D325F7F1074E08C9189F3B8F424D4637C7D47903D7953CFCD6F0DFC201C79B494F1DA74FF5F679666088D3F0C4BFA3783E073C8C469286C613D50002A81987AB17AEC674926D0EFFE8260186B72692AD09339BBD4762578F5C46E148520D1B58D41A5A5C0D3DD5F4603C6CA8B540BE4C129E6C6998D7AFF94362BC83556C1940DFECE7DFD1808F1630CE195C475CEE1CD2C00B100FA4BAEEE25B66ED90BFE1ECAE7DC8FE4ADBC74BE676F77A736B8BC0A6D3437D380AFBE5E667923F98382D9AEEFC8796F635A8BE8DDB063B00DA72DDC7DC42876DA2D42D155A854163987DCC8EFECEACF0B3CD467857D1DE4F17FD96EC4EDE3D10197A09B10879517B1BBDFB0BE681BA35F42F2E7D3B5A5F02C39C0725ACC79C9877F884875088A38FDCB31A0C060EB23B5CD9A793C53B675AA62115128454DA14ADCA3C094FD9F043E0593820C0876CC9AA0B36A7E12BA8D3F6C601BFB51E68308E0166398D6873887C03E596078D1BEF768FDFF5F566233D14BC7E8CB9B7D1A9A7580FE66D85461B66256EE8310E2BCCEC53382E4DAEF85BD9D3A32DC86ABE4F00F9A8431802B7FF501A3544E70F10C37F1E29190F8360495657BEA42CAA031438D3D469987C5CA33FC5C6359DF33D4ABF8A5B6BD3714163A5F3C69844623CCE0194F809C270623807BD5CFF19C5FE3E5D5C5DDD89FD9095B37FF89FCDC0FD04E4E3A514D1ECDB46700D4C62760E7E27CE2FAA0F4AF2BEF2C4C2569A0A471786EB48865452CEEE0BB55500CEF92988820A6AA153DAFE3355742655E6E6A9C42A13000DB76D6B95DCE5D61EDEEFD7D7B75CBD806A1B7C2F5D761F88446EBAC9F8FC56C6594827ABC3404644F6A7AFAF4B85B521DFF11635E016E5173B6A68BA56C38AA27E0A678ED6613DB22078B61A247D24E4B0C9D75DC5718E0EB18EF12DE5F06112728544037833F05249DFFEA72AEF322FD774C7BA1730A5E72B4E1088E053EEB7508BE0F5FEF986D653050FBD8925353371FC083FB9BBB2A66686525B71F46FBC57A1FEE1DD05BEC6D4803A88FFB05F3B6B612437F7CF8996E7C215DF87EB362E49188EC2C575B7E5E9F160883EB05095C1138B9BB515971DA54E43489DA3DCB43A2DB1FBB12BE6B28F8D25C8D522A2EC80F60A0F960F9C3062A3E3EB7AE1DFB4785194FDFA1ACC290482215DD09A566CA66632E003376E5D12FDF7F27CC689C837E67E454D7437AFD873D8BD601E73A8911BEC22F240AD7F114102ED7D865D5594D4CCEBC028EC8B2F5A27DF81E670648902A3E7FD81C73D6949D1B6FBD0C87D058EB6EE271A06C2ADFA3B4678E8CB4B55216DED23B918827B03770BF5E8E20769782F69F7867E6A9EAFCB23B5DE250284D406583B8597167D209DF3F80F1EA838D397E90CAFD3F9E8BE6BA0C87C87F25E75300ADB63ED8DE59180F146348522AA03E3FCB68A8F6D826F6ADD6D6DFF142F6973778C40771E347C51BB8F7B8C437AA646AB993EA44D58D00E2CAA895BEBA5F2A7F54A1B6910A1C067DA3AACA483588D47D89CE183FD9E93983219CD79613CE1E7905DE3865300250EF6F064D6BEA366EC4CB3C664D96A78EF936B69EBF29F54B18CDE12C30FCB000424A073E7593C3FD7E1AE3D72A2BD643C262C8A199001387A85A626AE54009BE43025EEC123C3B3456070E45B4AD0007BC0BA8D3E780BC9E9C2F032A920F300369A21E445BEBF0C8990A262E72DCF2D25DB5BB169D5E4C148715E3EEA861F3989837DBFD22B5D3E9359F880E7E596BD293C748D0EDE8C06CAA5C7934DB7EB1C6D1541552027E5E45F3BF29A4FD73FD204BA8535F605742CBA4BC0601192D4E356F68F01B7F266FD2D2BADBD1297ECD2B29B0E3C37DFBB9634FB9251616AF82628C81364042E546C8E9CF990058C226D849276FF83E73AE79F16CE9D68ACB3CEF7FC8A861A3F24595302912CF7B6A95A317D5FAC5480E800605D42E311DAE0FEDDE4B920F94CD8C1C5D1BD38CD3882727B800101A125DD2BEBA56A160302E9C8F63050B138D089170F6FC9B1D699F7E7BE38BC522B0DC674FA480FC3F4F0BC758BF44D6E1A714048F9353E43C178D10FFBBF5CC02DA88F41FF70F29AC7F9FA2249E207C9B3997ACCE80267B906CC35E02B7D82AD061E01E103C0804028140A06E04B8C7CEA88A96C8E7881814F4ABC168D4E3FBACC11DB64A8BE2C662354ADC44923F28DF6E9DB66E604AD175F09170F58A834EB594CAD8D106C180F7A4D5C6B5ACCB0A52108F3EFF9906664B7A5B8E5EBBA70AA325AE4D1F93170C0884192388AF7D31E6BF497CE68D7807FF39E5794E44044AFE9815CBD8ED1C594C2DAF101ECFE5CE9F9F57B1CAB4E1830598C5D11776C20BAA82CA54560B3B630E643FC83E7DB1FDE1D81EFA701C5E495DD13B7A9F525D0A100BD950C34E95461745907BF0CA7FB3FEF6543F659B0C684F7F59804A79DC8765D4100F48E0F22470595D466E3CB40C924A842FABB486291501836368444F4FCC0809382848A97239051C17B5541001FED241E7910F60A406347AC449B83F9811BAA7205BE086F1E63A285EAF4A254F6C4654DB981509723642979B086E496CA14C96BF36EB7DC6B76FB59347B0C1A34B4BD461762013FABF36211DBF29BF5F5388390646E863F08072F5EE42194603997904D9C6DADBC9D6C16E43170496AF37D4DDC7DECEDBD7832B3028187815676E673C226DC4239A7D7D3FECCA29A76EFB9D6ED9F22480068EA30E54F7C5C32304540FCC2B295FE5D2EB1B915E613724C31B2BFF616D117A194517568FBC32439113919203A5E2B9B216DDAFBD18F12332C0BBBFAB7E22CC6489471BA7738447936C2A273AA12CA85E1D3110807209ECB22A4371E6E957CF6058033149D1616F2B96582852610907259741BBB0DD6B0D31106DD0562F21C125FB93324C65D9C8639C42D3F664D1ADBCE05E1E5775FF98501B2FC3C4600761B7A190800126EA9F9D2F1AFEC2D3DD17432429CA5CAFDFBE2FF7375016B96ECF111216352302AA472E45395BF6546F747D7AD9194E0BDF2A8D3AEE400A69BE7A4DA768A4796B3024D7AB98CF00D26D35A87BF7B1BA9A74D60858A6D3E88ED65A77C3A489EBE37A517CC66EB36E0AC6084EBE42ADA786D240345C1489C189458E2F2C85D74244B7D4403E39CEF533A6386489F021E7048A40E0D1E89A66BAD92020B2DAAC48E6AE855E770C7962100CB48690AB05AE7413EDA77CD449C4A7E2FE5E695FDCDF2A1926317D6518A2B5D20C606769B8AC8C957D42DA741423F9DA4337C697F1106821FE3455F5F3FF6F64761298E10BE220ED730A06DDD78CC1695987879DFE4FAAD6C8096C13EC1082F2747F8F1AF778F894908F5FAEBD38D4181C4D245A24C1F80C644DA119FCFA6D60BD3CDDB40B8A078B65AB5C0E4A142744DD4A4EBC6FFF148BF2FFFF0F6504701F4A5132674724168691C3F1003D583677D751C7776E7EA37B2E52D3BFBA619F2E9E1AECCE365D17148170C1D8073CF1A29E9B51DF953D3FB94611DA6C8198A65016A5548AA7B0AC76361856B20C0C63F6F61893F0B3E4D90B8A888061F88FFDDFF592D681621089C047403188A24523C110E9C8345D1C4CEE742868D8D00C0A12E18782BC0DCD20E0087D0818028600E4F0A4447F754464A5651165A66512A7651840E00C200811FA907752A27442C2F4B474E234032898C8503A6FE23369D1911FBF66268D268A248E318048EBA4A765106544A78727ED2017EA119910E0CB4F53FFAAB88D215509CFA52B5F6BDA6F27F170B135DA494F2B176A3419F4FB5052A375D69D31922892000ABAFCD59E85D0C4827520D271609DF42CED0CED0842C2480228187D01BB08A946A70C14ED26020A661C20C1FEEDF78C0CA198C74DF632FACB38A6812D07B6A804EC50BF04C1D8D5209FE59D1D568C4889FCB0361D82B4CA6FFFEF27257CDF9DF9D82018C8CB1140413023CA494D003864A9121759A886048C2BD7ECB46B4298E47A19FF291051B99736C9D7AA86C333B8E630044E6EF864691DA9D8C94D47D820D02B14B42F044180A2CA1A9A41102134BA10D08235A4D3685C293D2D1DAC1FF5E916113A19D1BAF2E0AE2A2D5D170C054D199A41C10C5030F5FF1ABC7F625A696B4453062858E01718BC615B10047D2858310D22F0700B699D3442C23DD1AFA8267CBEE18EFAC25705790E03D127881FF4232D9DE89349E0FC2DF9E42534FED8AE61E3C803024EF34D5B6542E492890BC75C1D8A68CC35822271A170602388B48EB522F934E48F2CCCE3053FA641513B650437F1DB8EC69ECE07E9341A083812AC2F8B430885D3FBFCFEA581204481752118108628B0AE0BC5269919390A39F9CADAAA09A48C1C22FF7B83ED26CE84866611FA51B8845038DFEDBF014E9F169169B250D4BB43DAB828B041847E545A541A04940685CB4F8B4983A261C858BADAC8B43CCC6431D2218D2CDB40BB5EFDE5BB1035936511659B5A3899BD1149723E9B1AEDE2782B632A40781B3692C5064150274A06F7C83A7D645DE2473562B800E61B8D63C796F7B976F5947F5EA7B0BF6C27A21B93E793CE0D090CBF30FBEBE1A6506569878E2E95F581867927AF05E872C170F668CD989CFB1F9D18F363CF26FC7A7379C8F16AD7EB7CDEFC644C0A89605BEC4FDF58797B6C97A71D1FD6F7FD262B32CEFD9BEFBC85806E05D280B19620FEB569D3BA759720919C81E004A2669E08FB7F6C7B5BD7CF5D2695A7DABAF7FBDF74AE7387B3EF47EEFFBDEC64E4C4066D632F6F3DD56D3B3541F7BF0F9E64F43B1EF46D1CDA376A8B28494ACA49B971AD7FEA91A4E49C2B59D393B2D108D7D67834C5F4FD6DFAAF376B6DA01FEEF646E9D41B2ED306FA293EDAA251FD2018472EA271E356CCFCC97FD1FD5553B86EA50E93BCF9C1558EACBF1559FFCE8EF558128319DF250D495EB19CA182FE97471E623819F38DC8D8BBBF7F1C18D746BF31FBC3B9697FFFF05ED33F17C35A773171FB98DA393947236758B2A8472D3020D7D25FAFFB0F868316EE5B75C963FB0EF581C3EB6E49FBDC43A5115E74C1407A50BE9B1EE11EE0A7C1F24D6E596FD3D19914E4FABC29E0160DC1700AFB928EB0579B51358A05DD8A0D3F364CF8464EF07AFF55D3E71FF45FCD6ED872713EDDE1D218E95AB884208E4795158A0FC46FD62CC94E6E909D76CD44A5308F0244A588CA231A531F15DDD9BBF1CE4A5B06DC44775212080FC68B2448C0785D10859E6D00A6FAB2F768133114627809D1D7DB8D1BDB0F3CEECE7CC786F55BD25EFFD03A5EF710B7D71674621237C53C1BB4C78C605A47C6A944A4F00D174489232A1B07A6957649423445384C1130F5B93C892AE1BFA37467BF9AE48D6BFED882F697B8076866A015DA55E0A27DD3E9539072D39C7A33EBCAD5EC6CB4CEADB5872642D5F606026C2708A6A3823861FC11CF6624778D8C03734D8FA6D314411CF76C816FE0608FA7C059E0F60DA21DE0059FD34D7BFC782552CB13AF8829E85C53A491FEB01973B0EC81CA6CEE72EC3DE6155AA1513966456A2EBF14545665C13CB54C51CAC0BC4010274F92927C9D4889034B8C5DE69046079650BBCF498A6FF523AA830E2A4DE3C46F3FC84FFBFCBE3A7A33C0432B569E3C9DC560DAEB90CBD9AB28988B034B753BE6240583A07E8AD2750E3FFE4CE552DF265B6C579EAE7193A7B40A9622928CB9C467FC02496C13A175B58F6D150CA7C88B262E5FF5E10696220C96BF0511D192CCA37022537C71B238738A989C6D4E14C59BE24C342E0531C775FA228A08A2B34FB791A5E84E8AE8C96639E936BD50ABC90E5613586E0922FB09FCB2D876641C58D3ED604DFF55573AB2D315AC4DBAC0DCDEE844266ECD2ADA31A63865F31B495360ED28880A8E8A03E3453BCB228D4AF1DB983F07D6313880E8320AAC0C1AAB44A564E7C5CFCF061A9993FC46873C581763C404A9852D5106853292E23FC3C37717319404BD8FF1233566E8A5C59F376DE8C9766E1FA2FFF67B6F2D57A1E6A71E4E7D608ACB720B70E0088D7698345D9A56CFF4AED683E87DBD0A12ED95AA17779CDF321BA3656929F1EF048EF5CCEFB727D187278DFBF9A6FB18B8FA2578C3F445708E9C9C9523549AFFF4E3B6D62FB08F5BCF916D7307BE7A14B5ECEFEF98B9C8393E34FF7D77FB399FFFFF529C71CE88442CA48B8F71C6CDC809AF66BEA8167DE211376823C42550BB6D5B67543E52A625233E0A572B60ECFF5A11BFEDBC1C3E47BBCC5EEF6E516BDCF1EFCE2E97EBCE3E2C65E52F5F130ED09B64D03A7CCEAA640C3D90B1CD9FDA13288A808F05DAEBEB44DD8DD59B38A553DD26B8ECFA8B39CACFE742BD9B797F5F6E3BFDBDF39882E7B479A704DC0602A07FF77758893AE988BA3DBC2E2BAAACD6B3C2E6D5CCB60299062BB6640C2EB5FC6F47B000414934B9FC2A8EAFB4395672ED229EE948FEBCE941EC3CAD00F9C70940EC146FF5E5AA05A3C1FB761FC35EC53E7E6F80641E71FF3AB23C538E81FA43695BA48B2B9390DA8609E890C0C3B074D85F8D81592BDC56AD4F42B7B1B303EB5BF031E8094EF728315FBFE75F4E827E427D5C72B4A07B8B7F3A8C77A8274A145292BB1A00AFD58E88CCC3D74187604C537B5892A08BE792F979B308055F077FE839966529CB426E099A24202CC2B0FEB6CA52993FB689B7BD8476A18636DF22F8D62D9569C4F3E894278E7945F8F3CD7DED586635FCB5F405B727E1FB76A0F8474EF65C42A9E473047B80D592BFF1F024FD36A8B41EA734780AEF44DD1B99BEBE61E580147924F8FA3209A25759B4881D22010CECE21934E4F81F593B2CB2D08C28ADCDFC05B1F5CE03176B5BB553986CD15FE8404730763BC2210278B26E7FFFEBAF22A97FF0C5D7A0E0D5E5BBDF6F3E0A14DD7830C8690430C6EF0042D2E47437A6382F08E0E3168496815BA388E1DBB4E2B0B84C643FAAAECC50CECE21A800CEE12CD776653ED5AD15A8ABFF42A3B9B3353195E20BE38DA4D88FC78C20F0668C60AB88A57D701C4E2A1ADCF2C6A3C9C1E52BC63D47979A51485E9E39B4410175CD46021CD3BE141FB6F0255DF2E73B5D237FECB425A08C43FC643774B77FB8E43BECBFC3C0864564E6EB48F2296D2C9DBC1BA02B4A18EF1A08FB86E904B27C468E2D5F2296EA313597221AA1527D84E168FAECFD6FC8AEEF7110398279FF81C89C310360C343EFFF64DC7B7765A3FCBA7805035C7CFAF31D0634A073577CF6D254B02F9592980C3CA374E5560D63C1DC2F0BA03F1DFE68141071D6B5B82E211D2A8713284913114B7C31B7906A0A49259A6131080658B93EAFB7F4398E5EECF185D66B7AFCBD9194A5C77978C0ADC268AC53FABA110D90194F3CD87BF1771EBA0953FE17710D2F6BD238B5B461413F8F502AEC21239A993CE9296761F89FBDDB1DE66BA680D6DF1AE43BB4376A9DA1BA227FD20CB424DBA19792504ED5C1725326224642830061D42122565C26606201F059CAD63F5EBBC4803C8F9C0816FE298FFCFAC6FCE1860557858897C92C82241D946BACA730217F378050EBB27000C37C839481DA1F017180FAA67A3F26EBAE97F9D29FD1494C5CAC8042E982EB1CCCB651BE7041D7EA951100E7D5BBC9A8E2420B44F7BF9B5A8BC2CF50AF78CA7D45FBC4E1C10628EB932BAB56485741FBD6C8E45C9635008AF218D05CED554506FB8D4DD0EA55DD0C3B891EE7375E263862CDEE81B8C2A7C18F18E940ACA4BEFFC1B1C6E03346B13BBD9627F521223701D004C87A060BC5ADBF8B55460E1BF2313CC41D93E386295A0600F7D9DBCD4AFE30E4B7CA7E4C9236846BB38BE38D176CD21BE8305F993AA2FCEFC5FA05FF7A28092FADF29B745C27EC89412A0FC6EE403880817D51E2B489DE6823CD9C190DAD7AED8764E8ADA55CE800C3E020FA17063D017F406C3EA1D08CC1B91F2E3630076B3BAF8063CF4AB28F2643277977C138FC9772B91115CA675A9F270B92411350353F3E67578747E31B9C94FF25BAC535A1ECAF7769A2F7774DD9899A68EEB45CA3D21FA5F835FFD775DC97130067510B7BB1803A51877C113747FDB37DFE95C7A70C4860E20D1A0DDA6E20ED20A620D634B20FE26780D51BCD0939C952F99E765FB6DDFC887ACC5ECCFE9030B849C1FB84F98D689B6F5AD6D23940353D30D87910E00AEA24A5221285A6AF9100DFAE4449C6C33F5F8D194145B1378F1E90ED54C5EACBFB8C01E85417C5F5C4FAC40606D3FCF9076B8924632A38D50DD681407D2E1E957C152C6C2717C5703027337EB210FF6E6ADDB771FC94E71301E38119C9FF9C02FDB4CB5D5E2481757C95B221FD0384B2E69501851725CFEE8E2DB5BDA66A8950D9F05D592B2FF7E5611111566B5DB592103DA28091ACBEE0B603A96691E01062EF14C37BDE6ED0291BC4B74BDF1632C46D5160B74AA0DFBA2FF9FB35761914CD007C09101A044E02426432EDC6D980111898C6A264DD4E670E8136E2F937C27F821ACE4D76FAF6FE90EFB86E7255F964956C1E13BB34C5DB9FE24B3205B72789B328198C008E296BABB2981641C03B9E3CC26C1A751168B2FCEC866CD7DABA069817E2EB01F0875DDCFEEE18358631E9FC39F6D134406428F6452FEB596118C7BFA46B409E87A1B4C4FA8C0939A491E59742E8127A43F92EE74D837349AA3F82CD2897B7F6E534EA67DA885D15EDF4D1EAD28D225C6A6C00012632CD68ACF376102E0E796FECBA4B8796C3CEBEE28A1CE60F5C00EBE70E2153E0C12970AF15A3C056293A2BA775A04D922E1ECE7BE3F29CA68E97B6C19C03A3DEA313728DE73412628B70ADBE78ED6C9ED6480C8E75741BD15950EECF0D3A613FD864436BF40DC5E6F7EE707E30081AD850709F2BAB76FFA5BC29DFF16590D1B48FC6536D5CDDD198E89002F549292E046DD65921031F0E7CFA9E160CBCA387D03D18180A11C0C7D8B119DC489D28CC1A9A60CB9C3C82EDAD8AB0881A084ED256C4EAC295060660794C2A8DC836ED8D3E5C93142C1E3672E521F2916EE46BB5DC9688D6ECA3CC2D4425D09A106DC01CFE0B81F0C5B77A14650D507BE1728A1825781F64E6393A580A4A3D29B8513E5F3F3FB679EA2AF25374558B224AC0C03F161CE734328139C1345DFFD82443B45B31228A520A5ED60DE54F012CE66170804AED5235265AF50E7F999E32C55F7A1ED1A403A9905E333BF22A1DC90E6E3E2E18FCD7975B22257B988E6DC8E616341912031C908D0283C24B6422781B3B3BE471770606FD06B5B8F9BD4997E26DD85124C053B675777BB774A56DD4424A8B9BA835120315F0B0B55023B6A46DDDDC6BB6415D53EE3889B563328EA2E42DE3ECD9C827049FC69E2F1DC448DD94A4BBEECCD2A91F82C330977071B28239E5FAA1BCB1DBFE25C0178390D9115F4B040341023ABC96D54E93FD4210881C764DD3866E83EC394E10B85FD619C91CF9351E107B3F3C44EA5F714B26D2258CEE0B2F9219EA0E8F9758E3FC730256B45846898D8207C3C0101002DC13D834AAA2452E06FD6C1814837E360C8A260467668D49FFF7D04DEA6FA1047044A8C663D8A7B8AE8317F175C1A21A105EBA769E5CFC79C1FB4835F9E5DFE917D7E8FEC880E05C2BACBCEFEA2492F3E5A64A368FC99DB4842F56B049455DA518E1879831A28190B6262E4737ADB4E16FE853C85670ACDF876BB6A924F60F9F44982BE873908BEADEC8C466F57F133690D3B602162D9F17399CB90FD83C2269C6F8B5EFBB5FD23F90FB6CA1EBFED73B5E8173FF0A439C06C183402010083498422CC26D0BA8ECF11797E3DD52344E705CCC49C8214B319AD1696DE1041A6B2F88C9CD9DDB71288650D2AD15879A7C3EE482F294CBA3CC3FD02E42275FC3F37ACA8E37190825145CBF50CCC06E320DF673BF2503C2C2E97A4650D7E10FCF07AA9E4136343388CA571CC46AE841B3448B22AEF6412800BFC71E53CF859943189593F1962AEAEE66E3052B2DBBC807C90238C62CE178CC87DC853AB829AED5315095CA6907F1FFC208AED4C2DF27751D540142646A05CADAB70FCBC2356D27EB4CF697AEC136C7EFD2648C66CA4CF85CFB610FFE20C5D72D80A2DB7010B9BF6F5F5762FDBB1880C5890F85FEF6F8495C888A20E8D6F7AF3D73C98FA633436FF4C2DD4B7EA1E33C5092A3DA90EF36245072339FFC13C0C0AC056EABD627C1DBF8C36E460FCC97FE9EF5E82AFF4F282E618113DAD14A84CCF0D4D1F51ECDEAF8CE8FD854AFC5C673008F4C0589FC0D0EB7F2CF618DA7BABB319DDE54A0B73FF17BC8086934E74D50F3379704A50D431BD63CD8A5F981F5B633F2C76147BDC344211C76955BFED77A60C8FD2BC19933281F9FE5F1338CDD89080003DC75AB6909238956832235201995FE12F478B4D411E2133C218B7A2E9B83EB71C010493DF28F7D920136BDEE24809BDFEBA8D64A532955F0FFAB7B19A92254D19E44CF4F665499F667AC778800163CE0D9BD91149804BB377ED8B11D548BA13489234607E687B7358959FBBD0000B4D62B06CF9E7659968DDE1992EBE23EC6982849C8DA51D3F7589312AC6F860683577393A7DFD94DCEA31ACC56BFF0A7FBF8585339232D6D29432CD7B85B5BB0E86797920E71D0F1ACD7B3F01B0F0BFDC0F56FF5FE56153658CC0039329CA0549E533418B39963AC6751928520EA8ED3DCFCDA1D014E7B6652F22884E6C15CA310D0D94DBB529FB35F7D871DF8083253BDD8C1B7E4421012B0701FF9E7E0FC6DAA275191629B0778189B04E11001B8DA9639A07259491CD6A68FE52F886DA48C0C540C76C4AFEA8C885B45EAA20F01A211E0E272D6A5951A1DD53F85F9A7581AE3EA8667D07159FC267A9151C5B45D08891D68A10E87BE569175797966644B23DD2F4B62A5F29D3BAC40E4F1F2F24D36595A6E688C3EF925FECF14E235D77858AA5C05FB54BFCFF2D8F21732F28EE89A385F91CA0DCE87C5A7BF15D984B91085E4098A099A7E96A178BE0020353D42311B888BA37823A0E5A3202FA595ADB5BFFBCD74B326882D0F4C7ADC65B48C2848A4A1C82B46C1E57883ED8974CF40B98CF0F68CC1B8B684EAD3F2206459F823542EA04374A905485BAAFBFD220ACDFDE96784B77C784FDDC6B3E399B7F028C9B57B31E9FAC6340C08483B0E8B4130E02CBAC25C2CD28ADE4AF2B8B6E8C18F5AAEDE944A91231F45B2BBEE8211B02D023086BB1FDA775FA8B00908E6C4FCB936623FA7CA59782AD51AE18B3CDED08566E34629088F4986FE43B6CE254A81AB0B873860F7690B0245069BB730FC7436C50F422FCFFEC48CF9B682EF950357F982309E0B30A48E880DE5A15AA7F46888F8E49241FB15111ACA75B53D29430A85C3F38E88F1D90B08606AA61043D11CE84A82EA1106B62D4535ACE51912070A1E3AA73EEF2E98D5A4E1239CD7291BB168E8D4C63B37CAD173598DD35C0910EBF51D35A0A713A21C16D82545B3B540AF02ACDA396D2F47D44BCC78276F4FF7BFFDC09DA86036F3150B33059F51DA8857D69CB87F751A8C0092DA245EDD9FB7D772CAF476EE8A67C1C3ECFA81985AFCB8492A5805628FB7FB809CCD80AE1514AF6877B937C06F928D43CAB45E73F6949927712E3ABD2A37200B061F04427882176DF66D5D92C0E80BE28022FD45DB342FF1B9A279D1796DBD5F37FEFE56637F2C84D150DC8698E1425F2700FA77B978F7E265263244162D4D3E2F3C296F342BB504EFD089B00BB1368E7D09E9FC68193BC44A9AD8C49FC3C9FBB6AA3CDE409F895488129ED912BD8B20BB35BA39A38515999938B573D10D6377E165A308A01E4F41EBE6AC57B98E4DE65A95B1257A9D747EB298F9F8532885872278138F1910FEE67C91EA4D9FA12EAB41E621C894E599BB6FD94F04329F422495A5E6247B86C18FA45E3A2800A292883169E456C322C44C68925FA6199D29588972FC6C06BDFE28EDD129AC2F662FC6C94AFB78FBC718A612C8A4F27946795C4FD58D603D86EBE0F204BB7B5E4A5059A9869FE747D1F5CF4702BFF0D47E370366C14BDE3E6CF1AE2F0194525DD464D9FF94C04902BBA822CB0D2DF74D75BFD6E0292DD7DA9E29D68AEA5798FB09189A2E1809E9FF6C0184E11E3826DF9D9EC238C4A6F811C12C39525600DA3A58B189A0554AC56D363B2D12CEF06BECB59CDB6D17AEE4BF3C2A21BB6521887BEDC8FC79D4F46877CABA70266D763E37F972AEA472E1C137B78BD1FD715A06DFB56B61C93BB111A5825E20C3535651976C43DD62C745D080B4BBA3BF6D940C8201E5EF48BF1463DEA6D0192D6DA5AE59E89F0EC83F2FBF76ADCED7A52CCABC3F7F079098FE70F94537692D0ED0AA68A712A580BF16E264A971789BB486878EDC18E6BD179AB37F3590F92C0F2C3AEFD3BA9ECFCA62DC25E8C0AA8B8A9E3FB2CBCBBC2C64FC7A579B0761EC2739AF1C6B25CE27C0D130ED4A030B8B3CA9A530A9BE69FE369A8ECD88DED62E35FF9CAD88E4EFB4D2DEE723F4144CB5603314A5C1266AF8CD5467D27A958C1DB6016D921E6A92400DFF1F1315AA42BB74B1FEC7EFFC1C3FC813F572E587C57E64FC60EBBB27AC73623349FAF40A682C4D9FB5C5768E0419C4C8A1D0FC32AA176131DBC5411036F040FDCC2917610E43E00ABA264A53E2078CACFE5BE5C447DEA2242FD5F188FA920FAC832089923B65B813BEC4F068CE9EE4E6BEB1AF4179D92C78FA6890751DDE640761887876880EBBC47087CC85AC337C43EDD9ED1410035C280CC040DBA35EC842CF674A9391017A52B86F52C7D820E49AAA5DAC90B7BE6AA4C8B94340CE87E64FE43E5AC534954C7D4B33A09C3B1A066D7DAB67ACF884ACBE2330ADF1C402F0C6F5B8F06F35FF564E66E3D26DBC27DB09704C750DA3DC112018D8B6FB789980D283915F2155B62E7A145979B973FA95716DC603F523F1F6C3696E8DA04995F95476C99820CDB527F1E5F212DE83A62C419523D6E0E58B4547BBA4E8C338B9DA416B5B1E4373E3CBAE37A93A5912EEBB266F9572CEC5E90A3ADC492B858712FAC82D3299FE5B617AC85285DBC768198C004A56C69032F6C91AD136299018031D8BC2D66E19A92716CF5BCCD159CD45469F00F23D0E1A4D7F4C1645E6D736CCFE0FDEB1A33FD74788F44192F3A6C72B7C47FD3084CDABF5A2B8233CBA18C561085D72140EB14095C40E656820F5102B1A52A57C068E034C79B159E9CBB3997D4FCE7F438AA84AE063135787C8F03F866A31FDEACBCBB405A113F7AF9C42FD0C5DE08BC86997DA1C9BF0BC0CA4FDED20B7B61E0A76686CD936D9CE30309B84DBAAF549C0363EF8211891F94BEBEAB8CE51A39871C2150D90AF8D7783E789E83382F1D006CDCB9965A07AC84988F31ABD4FE087CA35BDB8B21ACAC2DA2331EFDD9BAFA4A73FDE96223576805049763534520DAD140DBF796E5957C98408F0B1DF1BB210F6D1B8E8EE2F8C62C945811DFA4320A245C72D446535B5AFEE6067D3611F19718912182E3437BCBB2638997AD93DFC9198928DF7100FC686C1C97F7DA73E0CB6A85071FEE5DBE9ED99F087E3DE2444D1137B3A360CD39809775667473D00AAEE2EB0C781F87C4EF5BFC20085966FD87D8250C670B85A022F4E5ECB94CE5194E5B7754982C3D18F03E6DEAC6A17FDFD6C2990F7CE6B4494C3459A8EBE194992406C41CC72F22FFFB0C2360EF97A5EA77704F3CDE06409E762C37A0E9A2BFD97697696F0FF35627237ED4810E235A2958955F309CAC92C8A19D972675267CD6D26600A27A262810DE5182703CAE403250BEE17631FC3CB56751669A89677E977F1DB100F02C33E4019833BF2E70BFF275684DE0A84FA10239F320F14EFE64FEBC7DED2413FF47A1760607D103C080402495533132924C15FB5E099DDF6611D52B477C9E4B7C11D81FADEAB25CF58213FF11DAF867ADE689496E908504114BF33278856A779CBD4AB77009798728C99389EEC8887B8E0FC187BB62DBC0E5D9F97164BB71138C1AE560C7D0A514CD6F64AB182FFFDBF8A62AAE647D0CDAACF479B8E80FA973A59BED8299EBA257AB9B227470AFDDFC88058E5A38DF9B83F7759B2098018175E767A5D84B453F25FB13442D24580C917E39B6C66C30A1BBBF83417B4CBE02187C58B1213459033DF071523EE6FA93928B2A03BBE5AE2F87D0C46EF46F36B676B0B48CC444B803F84638B6115D099A7EB138F94A51050D44430A1578A9D007CF5CADDB569CCE87369F86579D5940EE24200DCCB7A1B655E77AF6C54FAC7481BF659F8C63446351BBBFE24F10524DF00B4B0188C006ABB4F567318EDAB1DB416585C79EA221686F2704AD9DB11A9944383F4D6194F01ECEA16656D9ECF4338DF5B5E764C5D9CB9A47CC367DE8AD1AFA62564189DB96E289407448B0784F1C9BD7B907CD69C0C4A0ED6A1A203A5D1FE778B0E44C3C41A3DEF7ECAA9397B5873195E5E93C6C1AF86A650489A8A139E3F17BAB65683B2E5FAD8D37986B67E7CB1A50A2D3EE79DA4ADA5EABDA6DEFE072099B07ED3D3F1E9D1F13BA9805C4ADE76936C28AD4F3E48DBE1E744ACF1EF048E14CC58914C3822FCDDA26650E1A24D51BE28C05F3868DCBBEF094D1EF9AB7D3246444626F97F730D181B0B05448DCA551772501D1C360E838DF7F6B1DDB260A3E379A46431D16E9A30A45E5E152E07E13B9D450BEEB014622F18984CC13D4ABF001CD46015EC561AD73A1827D4C11A7E1CA3F45CC86DA391FB67DA0FD511534C10A8C8BF7E3F364C81479055E063CE2EC4336B777E7663F89041B63A3D0A8486792322FB808B3FD36F8A124D2009D7F97E33D35493305DBA10DD49AAAE28C15EF82619A65B5BFAA844C7A767B59316C944F7C82541F31C4A0E7E629A3C1804A4C8CC3D444907CF09F845C40A6EAB91D5AEC44EF020F8A622241022022A121C32189E4B089E846520C17B276ACB4B129E84152789DE589D67991C24657ACE9F83E49881F191C91B90733CF3E1F90A0E3439291C2186E19AFF2BC79651D483A7D272F283C52473B3C5608E9D78EDFFEC086C28294BE6B5C66B6DF329C1A69CAAC119882CDDFF5D9346D73C5EC4B911B7C387D983DBBE3C886FDA9778E0AF1E8F0FD536F6CC2C39E2F719F5F06739E3E8642725B1466CE1D869EDF2F716D91AB7E41A9CA7526D3A8568924769EAD5F4925366FBD5313046F904CD5392A4B2DB9C288A4288AC499415AF5A6DAB7FFD7D6DA74923E0C5C61C6A7F539EF58F03814020FCBC17C0FE222A34C9E16644177302EA439C6439A3CEFC3AA254D78916C660B544CA14BACC42BD9806DE1C08310FECD1E8437A7B27DF1FF6F2D788742AA0D5E681D093095ED3AEBC28B49D9161270B1E5C26F53DB68EFCCDAFFAF2F5EEA3D5CB2CB01A183903EA5BA5B968B25E52395648FAE04B22F9592E52A7CB45AA98A78C04FE065171276BE85AC17C946AEF78FEF11CEB309DE67A78D7E7BC86ABA7FD593566BC8C07309B5F5944C8BC11FAEF3932BA898CD1D6208A9CFA99ED9BD621E6336CE975F5060667F154E39269CDFA41DD5640C05C366B4D99B5DDAFE7B9C27FA1126B06F45D42B57143ECB4F4E7B438425738C66F546C5823C9D33F21A45F3E55BB1FDFD9FF0EB0873BFF159A842714FE3273084328C4011AF5096E84240A61E8810FAB81E7CF06FAC3EB665D30230C966FF6C5988F53C940E83EC56945D7D9E6DDF2A1B7F18BF648F9215C06BA4CD077729A8FE95B1714B140954068835E33BBF8E45D8F4621760E8B275021CAFED8A720C790E65CF1AAF0FE5131D25A46D2F57B18BB07D10106746A3CBCFE9541FE0AE7268466607C27825591A7876FBE25FD09C054DB1344F908F0B3A6564574DDCA3A08736D44174AA7FBEDA69B5D5ABE0B1F740E100DA436FD87A175F3763282D0159F10781F9168437B18D6ECF5FFFD5D1BC8FE80917361D592BD5FA92ED98A89327F736407DC1ED3836F273E0FE4C7685CD69ECEFF24EF3C4DDA24410307CF358DA1E6CCEB7473B3BA2E503C34B6C4AB716A95A157ECA7CFA484CC512020B079CA2E7CF0A3DFDA58568CA8E323A194546D4E82FA2E0BC5080003A44E028420A34EDBF37E951692D52595C575C1D1D2DB67F26E77A43C56BC280DC02A4F74A0C0EF9519BD9A648D695A7A1B83549DCD22F1583C3850533D57B4CD9F5F7B16E171AAC0C65819458E4DA2D4440E09CC26AD40F1A8BD3592BF695423274A4418C40232C9AB1C1525D4E7C8606CF47EE020092E3E71E693A5E5C7EA5EEE41F4A97B1860E4DA2635E6BEA5C515464351B59CFB231EB907BBFCE0E59144EF81C00C0BF7D03CFA142CE5AA18C484CF19D9F0B46643E94750FDB8752E617A476CCD01FAE6E46E050FB915DDADBA96A8337245017352DF988FDE806A1A5B5A15DA8C378F0220DE46BEFA5368CCC32BE3F766C5CF1D0110FB875B62702F7593A8A12D6F55BFCB47B048FB87ADDBA1F7FE89C24AA2765B97755EC01CE01CDBFDE77C63AC7C0D10EEE72F3430EE4AF0DE654A920878268BD96A4033ACD4A7FE09540C2587C77E812897F2810A5D467F6863350AB2384AB78D307E22D04E6B2D06C51097B5B9FA1C2BE0DAF2C4D116A77B326B5D3245523202E74C726AC74B666CCDC836DDE4FA29E8324113B470DB97F0231FE030C3A2D4A73D0D19BC172ECF8DB6382846EFD78C9A01E44117FA3494AB37FC2EF2AB8B2FD7690FE878BBF52D61257DADD61B544B0D777D9748819BC5BA87BD7E402CB046A7DA4F897B993442507E07A124FDF1F0C14064910A4B42E9C3CACF05D61A648059392C01EFDF61391A552B1226420BBC839BFE10263888AE4B0757454D957920326C26550F5E79EA02277C22116413D4617A38AFE6277C6B0D31FE279C07197C4EBBDEAC73BA750083134B5A3B46E927F70473E98CB02E768A4CA9248F2CC3CB69C5CC715847881C0AC0FC4FB985B9322407847DAAA2EABA0B5E7E5C70DD0502849ECB1653A858A7AC947146BD359A5F305FF7CFC8D64B5BEE5EC3AB39A141CF6D472C443F984073DF81F3476305330030DF8A4148DEF303EE167D312979FB37757277573B3D704D18506523F4DA3AAEA22429FF7BF38E464DDDEC36ECC7E41F0CF3AAF763162191E494661C7D9959A6ACA54C82820D83656E16FAC5025F06B92ED9531BC4C5C489F63435F7A1A918B37871B5F7CB32E1AE0C1AF125806357FB624B80C838412FCF628FDF0ABA3AA523AD748A60F643EEF06CD8A71D6A18BC4012C37C64D7D3F918F357DEA7B7D7BE5091C126DFA071763B14B63B4757C0D3D43641703F144EDBEAD6270C6895A9FD260A663988BFA1B6F8FC41D1D2BD89D6FAA770FD670717A71583CAD6578AABDFFF0C38A7C34C44D69F85858627333163AFB2B4001628CDEAFEC0800F8F88C0ADFBDFA32CB9BB23C0CC332C1CA3E56F258DB5096850D4DB86EB03C6D0EF82E395DD1897141621697FF88C3F60CA5A9F2DF7CCA57ECA724178FC4F55C415BBBBEC7713C7333B4177F144F13174A9C2C33BBBEE6917C08CAF396CC8D9E5BED95ADDFE263BE9025BD9FF75C20B0F292A00FC1F218B560782DF1BF141C7DF5A1327C389F18E515062EEF16EED8FF1952FC77F318DD545A7ADADB43EDD60AC2FB5BD5445802FAF6E45C321A94557EB86C359E61259774F7845B6542D35FD29E5A2559E1C3A0C831B040F028140A0CBFD3612FE2BD43F2973E0E4EA9B0A6ABFEAF49527D9697600EFB591B4BCBF5A43BE158004265D01C50CB60C6AC5AB628194FEC6E122DB1668F4152F29B6A74B75C55317E97F75040A8DE9A449707D594FE05A4E39B9055B62E569D058E3DDBB8EE3F270EEC946F9A850955F4B11127B6854BD375F5DCA4AB0D07E187F138DDDD44CF9E91F8D29FA1BC06BB738C9C3C92775093E60DF49C1A6082932FAD8320ABF273ECEB7A8E7D3EC09510DC734B54D1C7B67D9CA8E8914D464C304867CA3875B0F689A84F5146A37AA1A3AC68E591FE6B456F8F923961B60E35E05BC0F3273B7240AB6F305DFAB92C6929717E27AE5A91153AAE219F0D991C0088800DC8F2C0584681E4C4BE8B51BA411358AE74C4DDE27E41132D49B3AE147FD549901E4182679985797909D1DD3DE142341C317EF8DAAC8D9B63806E91554C9B0B887B658FAA2DEA93E2EFED06F16CB92677E7F96AA932072F70B5B4197CF13AFB7DCDBBE66D3AB010F809BFFB19F5E809D67C91367AF54FC2F03C3AC9799F6B1C0CAC6091FCA13BB51AC11A233CDEC10EA4E6397F0FE58DB3DDAD761050AF444313AC2B7F07F59D91696E91BC2F570B8F8B6E6E707A3F742F959C583B3C95F8ED3840CF733672D6445B12285AB4977E226BF0F1C73A45719D5009416788D5ECEF239C2E880E899A18DBAFCEC3C61AAAC2806E65613A8818E24D4A06AF8B261917348109DA3FC834F83815915DC56AD4F42B7B173037F19586018808190D6D2D5FD56254AAB96853E12B4007DCB9FF15FA3FBE9F08B7916C21528FAF981A0AA328B537E1AE979DB15699BE9F3B7C25D3329DD7F94183C25ECB312DCEBFE58E8AFA124EE6A272274EF4CB6DC426E7B18FB28CA4FAD3791A168557CCE97F12624CA08C6ADE1F6382FA998D65E3347E20009E1B967258CAE0F27D587455DBA647DA586F52EF6B3C55B587989D05282CF15C117DFC4B2286F5905D900EF7AE3C627C9E28F63646FC9A21A0DEC3B055ABC68A4D8F481C27708A544D903A395EAD3E1F19A8C2D2B9D9571FDE2ECDEFB7B84969E25527EBC6BFCE511428B71682B8BBE295A75C241BFB07102BF5B84D17F4F94C6C183CB6501E3D59EC942B128E93B0CBB6E11D5AB34F4359E9AFFABEB37F1FD49A521DFAC9AA40EFCD0566A4FBEE338546662C9A3E02E31F5A65E403F419135628CA102DDECB3BD806C33E365C77FA543E5DB847C6CF09B77E3D579CAD5D9687E19916F2282F00416F852D6D606ACABDBFEAD14AA49EFF207CAB7290A639749B9D62491BBE8174C5DB21F33136F9741E7A844834E34C64EFD28BF9AB8E64F8FD6B0AC90B254645FDFC4AEC6AA60A0FF00A8A9CB297D678FD46928DD553A16FCBC27710894F1BBD3EB65EE757E9113D569F1A71056A6999B8C2FA19B358CA8FA997F608665EBD35D93FE67E5747305737C54C9BB5F52D475EFD9DF4697C3C8B26EA30CADC1DAE0644B4885D8576E1EDEC108E01769893BD5FC8DAAE09DBCEAB5A9D183E4629C799E5E02F5C1DD9DB1A865173340CFC81994559E98DED2CF479358AE29509DEAA7E7159743DC50A2B0F48BF5C32C0804028140207F04B847EFA88A9628707D440CCAF55C4434D2F848560A61C352D10BC687E835BEC0212E9B2B070E05583CAE631CB3BD342862100CCC1126E74547C5401394A245A37F72225ED12E83744E2FF51EF4343AA82BBBB901E6105BDCEEBCCB351DBF42788B722ED07711ADE66D0521F9E9BFFDD8835DF7FF4020100804422441807B42C48FAA68418A8841FCB70B8A66218666E1E2E2E2E9BFB8CA770FF6CFC76AFA3F21C9A18646C010AA3FC2E9824020100804DC0DE200D5D45A3482907B00A8720BD03E6A7226C34B911A11ADF9069D68FA4D37E2C2B19FC31C02C3F4D5A8D0B0A1C0FB7DF32CB8E54DB5003505A51441B3B2C19D9BAF866B04C17D190BE43F83F33784F305C1893497449382274FC53F7D9BBEABCC1EBB883C5AD883882C66E1C340E096364C90DC062EB44D8E0F5763AFE9D5995F9F7FFD6461892C95B7D284FA8DDD8731C0BB5AB1FCDE282E03871D99DFF8E065C08F726546E01A720A6E1EEC20F4BA23F95392CEC74899BDFC88321801DC6BC668EEA8D97D79CCF53174D324A8E5DEE4787529497FB8227A7371C6AE5D047038E4F10639073ED46DD2F1D093C66C74CED1E733ED74BDF4C96886FC16F8AFAF28CFB0234EB07F38424EE2198D26F4BEFEAE54668A10772EC0E963653844E47A9F1DEE1EBDF85DFAC3950BB71D349B0C36CADBEF7BBE0F38DA183BDBF92374F99639B1DD46F327B8993024117EFB0696C86C04C2CC4E8D79D1E2CDCFC96443660694ABD4AEA2F44D2318C8A4CAA9B82FFE759D40D4C390663865C2CDEED23DC95C82700937B6FB8B093B27C284D65225D446A1064F94757074E12296D5BDB1CEE8D65B39B29BBDE8BB332DA603EA923E34FBC91100DAA49D66924881ECFC5641F7F1B3D8BA9D8C778789619ECCA7CD81E4263A4327C0CBC38DADFC9BE377F4E3D1FA102DBF0509AF176AEC3F6B6F540BE68B7C2D47B730B0541E8A8A5138DB2EC1D5C57994EA9BA625663F289CADD37AB6B88FC26FCCC2C7E18CF920F51F0E38463CBD9007CCF07FC4F3E76EC6C30FFFEF32E07ABBA66743D035B874D904820410F710EF94D294932DAD891ED193C2EC54201FF6D34A52EADE7EC5B9C8A940E812C1D43A35A26EDF677DE17051440E4A2928A322A9B3FBF23C8A15D92430F1433BD56FBFB58BE1BD600F448EC442F3944917923AC00A024FBE9214D17E9004923EB0731BE63CE0D1C56AF7C43B4F3259AEF3A72A83C1D9D8A267D07F981D9F53011691E54CC5D0E937A0B06C2652B84882B8F0791F6E111FA11001E47A25B7C98E57A1EA290470DB0F9526F3C475D0EC4A2E34E15F2188CCEDF5510048733EEB394309AFC8F5774C6E2B4A65C18421F7FE0ABF4AA4522CE044D9C6F70DA273BDEC100B6264171B2A97D6D9FDE43057181E5154D634131E3A4A3CB8BB007B765147D7FDABCE7F307A1F5EFA5D43FBB7D0E2D87A4D9DE44C735FC2070256C5ABDEE95558E97FE9B70E0E81B50151450F9C2CDD90659E9623CB1F58FD47D4325F8E33FFC7C2C7C0A788D14A250F7514B8E79D12CDB31DE18CBC2867E0E41864FB647B18C55FE5A10B4268540D828175D02D621B9FD08ADED71D8E6448C79339D03F1A73E2605494EA99121593B50C38C18CDDC81CD30725FDD48DE7DFC5D530144ADD92DA3277CA29275AF4B9D91EE109DDE57305523A0DE8B096AC57DD80C8C65CA948DE0DA6CD75B675140C0A6A93C168256D768B724C072EE1C810AACF545443A6C536DC0A17E0CDFB440012302CD32D83E2C15D2A448A740C6285D000F222851BBBC2A81823CA7A1A3A9E1D1416184D35CE13ADC23DFE9A83F2A17FE040E94CD7186CB795631F65A89DCBC93A1D447C34DC43502CAAAC6FB8403350D88489882BBBAFFA28BA4565BC7BF987E40FFD81FF9A22FB8F084BAC296D3239296376D914754AD8010DDD0605193FCB6792A258F367BA5BAB86EA8F24EADD8C1106B84D5FBCBF8DDF4EDC3B8C691183F6AE5A307B80C6336AF2EDFA288BDF91BFE6FA4A2E5FA92E410DB0D51C8BAB83B1E9A54C6B8805D46091D3650DC64892BA7C652A0498641AE4F7C90B15AEB509165197FFDF33B100BE781E9541A52B4177FB167B920E05ECF89BAEA93960C1D2D1A996012A3D511BDFF3994809A20E6D32C16FB57FB930601A03285E01378D5C04AB56EEED699B73777517F1A6ED9B47C7F77B5A6B5CB140A4EB83D7E2A4FF671247B26DD34CF1783863F17CC91A84E79CA3EB554F742EEC2D57BC5CE6219DBF170446F525E0A65AC9C4E235F10334AAA4B3F9FD29E701E252590A821D84C52018E84553F526EC6B437CDCCBDF0A22C26156DE410CDFA5A752EE995B09BC8EA9430310F79EB0706814A299E4278EB2C2D74AB7496F89358B932BCDB82CA8027D39231083AD29592EEFA8B1931D5B59AA00554CB7FF923E29D6703910041D6F0A7F9291FEE35DD8728711B9BFB467CBB7B7BB5E5609B94D921044BE6369214077625EE54BADA67ADE27FA815FBC6F0DE6F31720A5B2BBA7FB5322CE8E688A673DA198006B7BA7D8FA057DB535BD624BD6AF293E6ED0A0EAA8403730F1B49E50E52E4119F1F8CE5D76A80D10AEEABA3E81B9BA0B7BDC93E7B73FB4EFEDA37F766F5B1512D30A6618646D4FDFF9C0BC111E3DA2E07C47A0DF4AC030711CC718BE1B97F25C0512778558B1C4BB21C5F18D5291C1276D6C0BF05B12BBFE666247C6536C5D0D4A72157EC253F2D4072BBFB8BBBF3175712A21018CABCB3FB3E4D1EEE078BCAB7698C4D50DFF4A239137F1937EB78C7D34602DFE0E43FC1AB9EE83981A08842D225E1CC81711101914798015023C012F049B8E3F44BBAD14A25A45B38CBD3D99A99F8851491CCBB246E666E280B115869AC6213AC8C1DD84549CA97CFA91B7440A1CE64D318F86413530D0B243702613482710CFC3DADFC9C3CF87CBD7CEC6D1DDC3D5C3A149B9F70C369E409E99C541F8727A835A6F075A06F797174EDAACA152651D104FFFB82F2A67A3EBE7299C634B1341C7097AC5F07BA0AA0397D41B71626A68E8174AFB58ED7E2F7D176A63939000664F707F1EDB4A264ECB484265426A92DE22918038C7062DD0DBB82D00E96872C73C97D4E5575AA0565C053C7853B40C82012E19C12D49F50F2578F78F6ED659BC0DCECBC92909DD592F769ADB3A29094D6280A2B0F3D96058389481F596ECC397AD23B98E5138622CDFD86571B783480D0C5418B2C87B616AFEFBCD44B15556AA2025E1769D6C65E87D35536F4D1AC83A6C66E1186B9BC7844668C26E2611AF0091E947BB09D6638A470D20E78BF5C2951B35717ABA4611B65CCA2F3994F46E9C6925E14FA33CFE38643A40C6D59C4BECF601F41B71C1F4FBD7EB0563C6BFCB6A43EDE4E043B1C1264467D6E6975177B65ABC746BEFC9F3B46F747F63F7ED1B0AC9A1FFB4FE29FAA824F2B974D6A4161ECFB2766A59F79F2A738E6CF77A22F64285E59B71CEAEE829E21935AB3350EC5FFBF27F687A34A9885396C7A059E89BBEF962C2C962A8E16C7D75AA53D9AEC9523DD4DCAB6510CD656E93F4E5B2D1107CD89F05F5A1EF08298269DC1ED2939BB6385CB11AD55F6E4B6A043F90FFE62DB75306C512A3FF7FBD9C22F05A11329D2694219B1A7C05940E0F81D49B2FA1ED98CF3227F0D605060BA6A6AE1FABF716321C05EB59A486E91ED9075647E97E9C8595D5E67BFF2749D5BB89C69D0B06DDBE0F268D74442E6EB39793A30DC3405958710C6C58656D83B0C59C82982F0A934A518C7B531FC25379B7E121669BB6C076C807C7537E4412A2F1516F1AC30AB0518827ED7A32C79097FA158D84201FCF911DB3090F028CA8AD32ACB158C30C9B4DE7076CA19DC8F0D61595537F4F516F3FFB6F29BDDA4314E54973D82354DACA6A29D31B154B9EC3DC3FB61225224AA369BBB22986A0EED9014709850D29348801C6EE4728800112863A37F16DA34013E66CD8DF94D2E8C2C090D620F75E0439ECC37F1239D9D4009240916994C7B916BBFDBD81F1130B91546510FCB4824A7A4F281CA62BA70BB5116926A308DE18067B0B0563634C4B6FBF8EEB0076D883FE358CABB9AA7872CB5B2E3A69C1D1A69DCEC3FFD45BB17E40AF3C559EE157761BC00671ABB568BEF3008ABFB00D36E6310E0C8A37C370DA7DA1C55FEC2CB925300DE3A19172B7C9EE8AED02132954C28467C3AFE521411897ED19611003B36F705BB53E09DDC6CE0D1CAB85C7FF092B02885C0E42F13D6BA1F8B0B6F11EF69331CBE8DFDB2FD9835BA2B8EF38D168B8679480F673510E6946C1E08F8A93435F78198104653FF7A301302731B535DB671D4BC3B1D4DEFC5B0FC8FED65A7F1EB3A9CBE865D5ADCEA8E52AD709FB66D4420458473F63D3F103A8F7BF34D36A856B78C5D0A7E1BAEF5F35920B28FC60EAA6A21EDDADD927974927ADE83517F760B14DE4F0477F3016983A36DC1CEB0864C8AA990DE99BB2B40BA4A955910006053C703A064573C80201FBF2A07432E6958F4F25DBA3993F835297AEAD4E68B50D3E5D7E19FADE59B917094F653F36A0DCB14B3A1D74CCE79AE4B04EFB37A27841CCED372768E88A69652ABDE3D90A3788E48761F401A87F50AF9741E8F1E5ADB837D2D85414530B1D937E6D6D0E4B34116CF771E280510040A43E2FCABF7A3EFA272452269FB8E9C8A4F65E258F32867A1BBDCC5AF161D4CEDC200701EE3123CE2B754A8D78C89659ED0858D8888AF2B494204174698918EFA37F1D8C00427CD45B7C94E59302B338850D1D02A7E3308946261A544F3A781AB32B6AFA28015A6229FAA918CC5945371C45CEBFFCDB59AB934EDD18F77DDF8EF95732FE54F4C1C0CBA780104D69751F2A5B79C2FBFAE6ECD22FD86E36ADDB5ECB11DE2BF308EA1A878CF048C62A7077FDBE20C0F6013E65656A92D9005CEBDF73126C7067199975FBA90CEB3C07729AF4A8F90CCF88CE4AA523750C74ED7196DA95F8CFB862B590E5B624AA5B11A813CFBDA351CD20AAA43DB9B2095F94748FB46F7C5EC0BE721FC0E5FADCDA2AA2DFBFCA96AFAB18C0AB77B3AAF18EAA89294E1DD314FEA4413109C8D6B14564EE259B95C20A059630C4A09EA3BAAA3BA2DB7D8F126EC528D64CAC51E30D2B5DF49AD4B1B0B5C7B975B15D3F6D36DDF98CA1D636E84431086E294FDB6D4A9EF8A2F43BF9E3C9853FC0B6E7645F22C7E965B583FC16BDFF318133ABB570CAA4255FF99E2F5B9440533E7B15B3F70D10CA5F9E91A9EFC0FC3F46695037713E93F5ACE8FD4B469985B7759E54DC876A10864C048207814020907EEBE975C790ABAFE84D3B15F8D8298F70F1D4F8C8269756B3D7859C428DC7BC967D59CCA59F360723745F8EC6B499BF09A8DA203E5213B27868A8F6CE45387E94031684493764040F9EA73287A3102AFF2EEEDD69467C8643399D1DFCD56590DA86B52AF4C8B22844211203893B85FD15A0303F8C75AB8130B48F1CFE71CD9B626E22D3618A4EADA8CA012BBC8E13EF8FA1004CEA801441C528A42F17DE40B02B9D66E75E888BA7A23CF754BF6435DDEA03DF6D23B216873D1E576FDC0EB2C62294ED3F33FEE7750A84F44A2B2406C18092B8C638832323C952895395651ADFD3410348D5674912F261634E52BB653208E05913AB9E7C3C6C64A4FB295CCAE26D4AA04B96AA186CB242E3133DFB8577E493846D6BBA3031A9068235ECAEADE9E0988FEFB3F8A0837795259449282DB921FCD8EF802176777C72E369C051FDC058206726D477AD0E5C3BBD9091555E14D346AF9335E251ADCF7E40295C4D9D72730D1875A5FBEB7EFAA481F82F7A1ADF6820963AA656F833FDA98AD9899F450986BD2500E533B91D153D07AB57F627F739D5937B78F3E81EBD226BFD7882C86326C895338929FA9328CE4F28367F1C2BFFFD0070B3F00D671EF6E2A89C34DDFC4C8610A3B8B833FC98FEF8AA31A3CDDCB346F67BDC061C29C2131CA1FD080746F2D3B9A94A5D4DF251978A16D98A6D03E0BC7E16B0DE24860EF2873EF16052DCF79D6BEEB96BD43B65D7554BFE1E43385943C88D303E089559FAD76A1E813B28E5F4DEBF23F26FE417FFA8F84DD069E904423FEABD496F3474B514E9CCDF4E111DEAC2F4D2F62F8FED7F2305D4BBF789442E3B85FFD4F34C37E4B59CE99A6667979BC7CD85B3260BA70D66D5C0B09DAF0EB8371FE92211A51A32D8B0AFFAB694439E802FA49BA972C9BCBA0741870AE78CFF308939DC7428EA8CDF7D20BA623069B3D4470A2A304D444EDF51598B436E29138DB545FD60B15C088E8CAD2FADA39676840068E6AB03F82463470ED2C55828CCD5E4CD1B5B1AE788C146CE4BD3E68C3FDB1C24DC52389D5AF3E4BFFB98E0E31DE6BC02D5FF81E4FB8BFE4D0685946187BC468C122E2D6A1713F83C83FF840667149EF1B51870567BB7FFFBAFC97FD688A756C0695EFC447B2D4DEF76942BFDFECA8A2CCE1C2C61C627DD40AC2F6CD817E2E78BD4AC68DB36DDF4694CDAEB08B2B5029B9AAB0CD58C1FE9D6DC1239577812E2E2CAB7F95AF24C99B6305325D370FC0FB287EF7925CE15D3C6308C39CD25F4BAF23F0568E80B9CF732A5715F5DC09BC744596A38706F6EDF2C9EF9AB65B5FA71D76993948CB258F109653609A7403EB0FF3505C7C18E620BE4333E86520CA8BB554197AA51C2F7241E4AA00441CC063B74FAC4AA15DB37764F14BEBD375951C24C12AFAE1D4E4A7028EC41CE16872779A621EC27E08655F69195B36888F46D1B467A9E941CFCF35A2881BE07248C60A6DCC8C07094C143FC61EDCE593C822E633A104C7ABE201F43DD690BDA46814EFF6D6C986223647240F05377C8FEC05D82ACEDBC7D02A09EFFFDE6F1090872F10B8A0AF20BF2F30808F1F28BDAD2E26F2D3E7E512E5E017E5E3E3E7E7E4161611EC1BE91B514DF3F71982A7A39043808F0F1AAE8A93AD9733B0BDA79696AAAC8BA3805E9D904D85BB33BCA08196A288AE8B8FAD9EA06C838F32AF8390BC8F0DB7A7906782AF0FBDA2BF02BF1E979F2090443D58D440378345DE4D9D975358D449C8C04946CBD3C5CBD6D7D6DB51D45F5FC0C350CE482E403F89DBC78B4030CBC7C0D6D7C8505F46574DC0D4C05340DD4A1729E9A764EC1817C4A1E9E8E2AA29E01A2AE860EB2B2BA4281F2724E761EB606462E81A66A2AF6727E8E02A2327E7AEAFE7A013C502D0DD1201E0D1F6B671E674F5E39AF0025673D2D454D7E61656D657D256D455539A8B2868A2AD4C04BD6D43B5046D89BDDCD34501B1A2CE8ACA114AC2ACB27E8E4C3CB6E2210A826E41B18E42CAFEE1F14C8676C23EC0895D51011B6F7540F9637B01794E537B1E5E1375071F5577790D50E92D1B017D157F6F5F1B4D110D01094E571E097E5B7D6B20936525694D1F6719775D1D51656089094A40B0D05814044C2600410F6C72A68A978EEF5334AA927D7DDF77DAED2A00E63BFFCA8A8D7B0E289A81B2BE0E37AF306AF817241F34E4C1B55A298E226FCC955C965A5A5F683C95D2501FCF30B82C5D9A626385212EE5DCEE87DD6FD62838B1AF751C62EE14E682F39D83B150A11806943B37D5B7DAFC275216598B7E4D9AC3609084C4ADF3CB2F384098FBFB7AA0AC06B798D2C57958705A62FBC36374F9C72C9F0FFF9E9F1DF243D4826A2B690C81C94F992D88090C62EF6C1C7977DE95187791AD713E51A8527891DFE8DE4A2A8F73BDD2021D76AF1D521461F4479EA01AA4DEEBA0F5DE452B01D3EFFE783F9D21A01DC29F37A1D8EEAC4BEA59D3480A2FADD475E8892C78EA6A7C965716DE19F73F59EB4F8156CA30C92D42E5DA2400AD8FF5C60AFE9E0F8EB3D1D3F3421AB0FA11B4095419F91E1B5396FEF69709D5B51224AE529AEE6D8269435E3CC89805F584D860805CF0F8B558306F89E9439101599367F10C93F3952957BCE8D0AB6C50C5F9D840C69E6B87307266D0E0F77AA5501680DA6FF94964FB23056EE05AFFED83B1343EF34531ACF50FE0CEFC39BE43F35C1D08B2FCE501954CAF4C85EBB5D3FA11405647997308A62E60E4E061FB115B5564C0924593C4A47540853AF2C80B72C2826AF36A5E2BDFA2B2F688E86BD34FE978C23E2973B7D01F2B6F1ECAF671C816F925BBB97129A573FB0011D38B3C450E70AEF8D37E38006EF2F5B03AEE4A1E5A1BF50D410F39AB9191BAC494602AEF88454B0807855EBE8FC0B15DDAD5971A9023209F82630240671D0F19818819C107D09201C68EB52E21D5EED2D0137AAB5194DAE4ED151B9B847F6770BE6C8F347DCFB929FB7C2587923903499EB7B2393E3CDF9F71153D8F09DB207EAA2A8F218E3028FC637589A896202FE4089E2E30BF57680FADA019948BFA964ECE111133C8A8DD128D5AE45D14BBB730D685006EFE331B803FE4C5172C1FADEE1F7B10E53F21C51097C1D349A96EF542CC36D1E6CC2B2BABA0AB8C1E39051D07C84DB59077CECC8DA05531B9D3225E52F15ED441125ECABBC86D8369E275897E17101814060EF30EA9455EE4415D65FA4FE5FDC92907372357AF8FD35F0FD33ED328CCF89B84091AE1A3F06A5C0F1FD7486D091920AE86FF4E960CB18B4C8F60007EC6E6FA9BFC7D20687423445898EB24626226CE223126232374E4106ED6DC088EB327901FB0E60CC5F4857F32124062380BF27F76F16148EA4DF44C90F33B81C651C2EB8E22C81DB3D278CE9A43D185C09A061574636673A753D1D5D1262669A4379B8D0B9993D537A14408BBF99A691508C2859601ADE1E468EA7B36C7DBBEE92C9AE660263437423F0D9D1348BCDF4FE513C904663CB000A056912EF70684003C05AD8437F073D4A8FCF7EE20B23C1850318F01BB874ED7F2942993C62C12ADC784700E2FAB1DCC0AA9A75E9BF7C9B030E2601CF5CDF82EC03D2685EB148665DB77609B9EF7B66EB1ABE923528B23C9FB49CA6154B0D76DEFCFF6DBE9E0AE45B6A9C39334726465574592B5B30C55A8706301A52DC7898DE5903CAE56AC54800DD06C73B76A309DAD71499799FE3447A76A1D7DA614D785294B79B6C6623D35D149B6585503C48AFFA58564E70889F9E50C324205D9B992CB416E666622339E1E5AA4E6EFBB14714B2F841949EAB21E6379F2C2F81D68664EC699D0B6F183D90C90A71521DC3FCEDEA07BF65CAE6D6CF9FBF9D72D5F7753F3DA705223217DE1F8487DD5902084877AFF782D615581224FE13252F2319EE73ED79FF063E6C642322F85C4A6E7A91B577CF6922D11EE490FFD7897A9E6006D6CABA9EBA5693B1F3C634ADA114592B7A1A84310FA7297679CFE6169C34002510936E33744E253C3ADC21B7DA1880113D8EE25A332E361E95D8F5B34F52F974317A526D216E8F73F0A36C77DD08334F6A318AE17EFC13310E4FBB0CFED0906C1396AC3980843A47DA373E2F224A5B7D399D62DD9C5336D9FBA02E2D7E3539AE3D6EB38726A62A01DCDC13521A9AC40BC0A72DF63CB8AFEFDB576189EFC70D918FA8CB519F27B9205F44A7BAD453D4127D11D91A447AFC81EAA1DE8A1D7235A0F695D48BEA176DBBBC367CC57D40A6E550FA0B3DE33CCD1244AB7A701F7DB809DF4DDF9754ECCEF3FE2C5A31B77F658824210E82813B040FF820066A1535E387103B0DDF1B59059BA16C31CE35A1556D596F2D4D1E2080F6A6E0A7764CE969BFF931D8E2CFEF4464BE1D7C75D3FAC14FCD0394D216B914C0113CFD5018BB102DD54EF2D97C20ED79BA884DB2FEDCE0D0A2AD40840C2FF4B86D113CF4A87A6CAF8FFB49576BF87F6878CB260D957E620450697876341CECE6C7D81465C0967CABA8124409298BD4F9D6E76988F1CCF1691ED04D4F3AF9BEA69D8CE39B2C5076A9CBE0B1C1A86462C69F42ECDDF622F057B60A06FF78E748BA285DA9463637EC8BFD34543F5CAEA4F2F4DF11D71956520A51FAF534A3D4D79C8DD04A29B4837C09095B40F5177354459583E4B2D1B5135E992A183B1B720C683405C2EED640ED7222AE6D0900E14F75B4936D7A64FB8825D125F90D0AAC7289B507DBE9D0AF264CC55002BA436E2510E109EC8B5F46A30054CAA63AC3981D013E99590E8CCD894CAC46935406E7F5B94B69C91064C30D8CA6281BD9F8F776360C270F084662181390B661C3DFF9A4FC4836BFB3B9E78C3A6BFCEAAC50FC5153555F12A6FA12A78FC74A307EB264591C20364139B8F6A19AEB12BB3367B3EFA143FA4B8FE0A1D0A6098D33428C6746F69D1716DF74E11D520D3271D81DB0583A8318BF8992B2F44D08A5E75EC4BE8AFD8FCF9F5CDDE23170C7A3E5E0B49C3ABA5DF127A5244131336CD744EDDAAD79641529D105266E6EEEB4A1A369FE66833C2550418D174B980A9247A133F82E19C93F6BB5FE2AF23E37F65513DF33BA45E7FE8721ECADFE05709BFB076A65FF2854F32EAB9CDEAEA044ED1FA9C70FBD6DDDA62930C2E06C2B9ACF64C777E1DF4185ABC11CD1283B7A97ABC2DB01C767CA7447E1720DB9E4114C2C8B3BE59E1D52DC92435DAD3D76920AFCE4E51E54D78FF05F58FF6AA4E53A7329561E5FF5D45A5F6A9FB097FFF2DB30FF2F89D403C8E631B11B348155643F2406C180B1F40C79402AD66952FCC5DC48EC7B5CA664FADE6A554C6BA4C07BCDBD07B63EC009C57632CF75E25F43A6E336C4439E0FD80A8A8CFAD9503F286CB06BFAB823F6DD502D206FC3BE39BBD84147A9F391030E73731021CA9ED16B4678C5CA58306D40949862E5917B3CC200C61E24022280BD72C300693E087458BA019D2BA536F323021B3B860FCFBEE25A17651A8E3A0C08B253303BDD5D4A57AE4615D0D8253286E76AAB18295B8FA729699E7E7471799C4C784EC9DABEFD6987B5413050BA3586D5B652E83A49CD8015B7F2F11B4D534CCD355346CB6B81A404B2F8151B00D138C96E9143218FD6611DFD0B1565A731F4EB11649EAEFE10012F98D378E8128500EEEACDA991465C30E889922D2E57BEFE10FB86CA53CF07948B0AF41190B15C44E2141C145C6AD5EFFD846C1EDEA7CE9D20C5F8FFDE60011CE6F055195F0C47E7FB4F2536144F37931826678B5D2F12674443101BE49349DA8C4EB8A25F183C2AA656646FA5A05585839384F817E96862515937C39F0482787478F7B7E941A9CF7D7E82D6F19F2B8DE41BD5A19E3E8F3C8309F86BAFD73CB9BE553F9C7AF04F3AC0C1D39BCE085ED999C44DC832E757F53DC5B6C5CBA52A2A195138DF9EF1E6A1359EEE553503679A6B9715B532D2C56F55AD539F32F7A69FF822C964D735B0032E862FF517B6A36F4882CCFABF4CF36C0959809AE898F7943FB0A698577348B4AA0BF232B43C7F0F97CA83F621F208A64F4F29AC91D31B7C2D374D435285DB35FE7AE12DB618EAED1E2941AF9289A0AE5C86FD336253761AE0FC844FECD1E8E910C6A6E4F7BD5346DE569CCA77792757041DDFE46531A6441786318617CE90A8140332193A803E2D095DF9B3F2E8ED724D3E780E5B5EFA80F22D529B333673AC0719EA9E4ABC89AABF0C03009E8DF5B329DAFFF1E7524BDE9662A87E547B34BF8B37FD7DAF18FAE8F7CEBE7A52D0490E0A1DFF346620DCA6168D01B255A1558C0B62D052843E638ECB69FAF46719B0C09581F3645127B901FAE607730FEB0FCE3EECA5959CE3D6BAA3DA15BB6D18EE9F6A67411FB9B5198783099C3F889F2955A424C16415C4231A0BA44B37FEAEFCA7EAB0546DF4F746E9C8415B342D1E253ABE9633DDBDB91BD0EBD66001739C118D4BEE2D5C3879F3CE402CE744713DC19B67CBB5A1733E01335DDCFE135F932DE6A4C4C0D29DD0F3B65CF0C7BB8DB83E012D7FBE1BCB041428F884613F173F055D6836EE040A27BC712D195D54E015B83A698F9188ABDE2A48EC8808656D6358C9F75A9DCCD4E1D6D3FEE3E397032884EEA97802A6F1E58E689CFA67A82D3873BFB6671476DE6D9326E10CB5F8AAC210760F91296FCA7D7A6453F11C6514469EACC5F9D8847ACAE25BEF5AD64559CD0F6CF0814554FDBDAFBCD7CC0A9C80AE83CFA8D5D3C7172F33F3AC22594E88AD4A06F1DF671418E46C0030575EAC44A35BB30C7943B4A63E276966D770DA408C45E7358C352BA3AC561F0771BBBB1D22EB6CEC92EED011B1C4B43BACF37489285D6611D09FD9B6056F8BF0D9D73D28F68FD2093F30F630A110013CEADF9D4FBDFDD217596634663612989793CA31477839F628A9C88F65F1747602F48814D62E4DFC90922520EFFF95E385D00A98B71B21C881D451D41E2E0BF300A80C886DB8503DCB06BFF482D21A4B1B8DB8835A9F82FE8C9D1DD8D9384F1181933B07A75DD533AF15E5325DDCE6DFC48D8152BBB5239193282AC7A8B622220248EB274F05D843403C351491F08B9C1BAEFBDADB337E8E0A49DE30EA84B2002B1862F976EE56E149109EE009D8CF01544EBA2FD125A9BF9AF194B4EB4A2C1120185C45CFA4821E09C677B2C7FDA3E4F19C3BAF29D2550CA625E0EDF0DDCF1C5B231E104338C50F613EE10712C0E23CF89365EA7F5DCFBFC96A139889FB47D17289EA6CAF2E2CD0366C8D6AD178CF7342C93548045807C0A700F3BD475133289D281B30836BF75D99BACA50E194FF618844FBF46C7227406C75D4EEC7C3DDD16FE22D956CA75F80E7501C497C94AE4BBAB7BD9D61436477558503B7331BBF08BE072FF58DD5BEC329398D765956FDD905A105C6D61D069D1ABE1A38186B7BFD88BA1C2F0658B44C3C43C88EDA0A7A5D4591C0A0AF5CDC5BA65F4D30282DF55427CEF5014712C3A9E08A51442BC5DE39CA78B12459A5254B75AEC9B3CF6CAC5681953DAADFE56AFFEDD712A03B46D8F6EC2EFF856CBC6EBA51701679D9741BBFF14EFD6AFF30010F1FBB0395A25FFFA5EC8725D532D6BC3C7C026D60300258769B31EB78162299C38D76FBD4F75EBCCB07CF046F3DB33BEDD5430316E6D32E795907920293FE327C2BDFEEFA8B1EB267A3BA389FE0D5213DC539FB79B6CA682D3F1345981F3265A9C5D76902721ACDC4CEEB43129E8B8615135D54D5B14F02CAD7121934D90B4EF92FE9A3E524F4AD8719C97D9CA12B69FAA4FDCCE76FB3BA490120E716D00FCB1EF77C490C748DC35EC8E35D215BED8FBDBA1BFB6CE05E15D8AE8828AE44E3DB418E6F35243072371A6FF230306BC31DD4FA14F467ECECC0487F2215F4E1844AF862B254B5C4D8C27DCC5AEA11B799F6EF41BE8902A5F8B88CD70348168051837D4D41CF944A6DB32656368A66EB8CE7D6FA152132B9539D2AA1F498555AD23EDB7CAA463414AEAC4208C9596D49A1BE09795E791B04D1214D7C4D82FFE270838E01A852F3E77207DA08588E5836CF190279C8F4804E5DED37B7D285E475B4E7097D0FB76EF922D261BFF58FE424E7B78B4E60F03657009B201C49CEA4B0DC8171F93AA04B1BFFCD65D265FA97F9CCABD4F9B4B51F2A319088F0A38D87585F2C61FB4BF89A3CAF9F75576A59692983E6B308CBD5BAAADC2FE67B3E13219C2C9D79381DAE31345B1843503ECBDB89CBC9B8D8B1ECC0B2664A11EDF71FDFDB4A82DBC2AA2419BFB381B7E3100095E117E9173ABE7B92AEE0E30B134F77879C427C09BA4145FA2F2E1E73FC9A754C81BB909D0867C635F8B6F4CD98F72C3D70CE1CF86F679CFA19CFE446DB76373D767BD48F007B4818B18BEB3F02E0680A7D4A6DCD8B24AE3A874BF089694B78BE8E6CD1179C2489D185E7079138830D3AFAAA53DA8ECBD6DF14BC12490400877962D227616E23CEFED121C9776FA331377E3BA23E283C1661880BB3BF9D0FD0DFBB16DDF3B68F2F76A810380C9C51A7BA5AAB5EAFBD3F5908AA67E64F72D4EDF204213CBA4AC419FAC858801195CBBA87D723BF5975494020E946DDD7817C04D25716A3C88891523CE2F4039072A34A0DFF61A7A18FBF1C7C8E4B98BA83F8515C63137D9F449E2A13E7F2DE0206AF1E5FB190A4F297281109151FB8EF4ABE61B6A98128758695C49839F17545F0C28A1DA268BF6F021F96FFCB84C2740598F5169FB438E506D5B1F0121226BBEDD63234AE5BF5FC7871C5D7AF04A6CF5C152BC7C7EC8CACE6B9B1376E2E480C042C11A57A347190B267BDDF52E1F90C1FF23DFE3D71130F4DECF30F156CDA9FE28B099EB25A65466F3A775783C6936D5AAD011680778CBBF702D2E7E0BDE7D530ACEA53CAAAB780F3492F9E10297AE5CF9E6A444DA84B8BD8212CA5C32E357523C1C3FA81C33610C289C2B6716FAE7B675D9767337501C4C24C15E4FDD6D0FD39C3A0130E147765FAB7C9568E2522FBFF741A364BD7C6BFEE77F92E09C935E87DD7DC047CA7C5776BD01961EFF2C138348709EA7E2379C9CFB4FDFD91578FD0B6DEEA0C53B8C5DA221FA22416B827F931E7FC29E5CDA6536C0EA627507AA57CBEFCFD13036E14C05A7DFD79291CC0C43BB8FD9937BD9291C0A751F81E6C4CEBD1BF633D10510F564D6B2A78E7F684A121DF8923D899F326EC42AE29388D8124043A9B864A64F292DBD3AE69F603D94AAC8FBEE44A5B8F873576DCC92CAEB4ABCFA201ED6A32FAD7FF03DA28554E038E98DE64873B6AD92BC70122200E08615EA98F3F4B629EF763DDCA33E22D5B5D53A78A7E8364CDF31ED7B22A15E8013438C5F58C2C3AC8FA4D657AD513E1FE54919651F6989845EDB0C42C4FE5BAED92CFF6B73536EAC8CB567E309CD8EBF9492606FB2923D469DC3DEB13A069AF773CDFA3A572CA952FDB6E0484FF547CF7C63D99BD1320C45CCFFC7A32D549BD6F836B18D159F3ADD594FD845C2908040744C06EB3E5806889D10B6F69F40A060C3DE8CDD23D8C9C8655BFFC8B6762E7E786DFC94D6FDFB7B37B0DB77AA6DBFFB4F1A6ECDBE4BA4EE76BEDB5923473F6E710F7927970502D0E50F138BFB98D3E587DCF9BFD645B6DCE3A7BB615A681343504C204F9AEFBDC9D69E3EE880CD95E0E5BD98582BE4CD0317EC2697E76F0C6D45E36C9B9AAB45277D82B52BD4D1A3836DADB29D70B38368064A50BA94418C3149A386098339596E8E8EBADC75D6CD8DCA19793F5711B6E8F682129D555A08A4803D2CF24271F7B0953B76FBBB17E4ADF948E24CE706E7D939A33C6EB00D40D1E97EDFF581012510574C5223384BEB0EC63E609F86E87064D62582A06AC9E057077875C85AF860A5B2064FD399BA53850A7828D1263765C580FC48E22F127723E402392E7D2081E72D92B2E35649310066D62300238FCD1C0E7B81FA63B4B479F26ED561689C921DF20C5560437D6BE058E9E7CFE03206FC4692793BAFD81755BF3D970FB6410ADC4D55F749133AEDDDFB1CABF8CD9E6E95F583042E873A84B6E1B213674CA4B5C540E109F4D5E5120AB4B76B326A711290D954CFC9CB30EB9C9B5CEA7D5AB5B7823D01B717C21E25F9F348FAA63FE6A1E2C2177FACD0E201C2280D705197C9247CCBFB67E01C5B9F3CDEDE104DC0F4DED02FD0D0CDD32DDA681A580E5AF25E5655899A8DDE5EE6729CF2E5C16A68B3803B5768DA14E3ECCDCBF4896120627C174F812469441555EEECAED0A52BFE5CBE7F9E5BAFFA5A1346802288575DA0277722891A206AE8CC5D507C53F486601C3DF6F1BDF5F6B06F2B05226069859971DEBC610BF0D7EC03209AAA74469163B12B7E9B6887428C401D5740CDFE4D159DE67CE2CC61F050A364CBF2E0F7EC22D0EC858C91F0B0A5B810058BE15FF0CB9F8735F7C7C621887F40B5FFB6D3ADB655A2257CB27D67847D44888333D56003322F537FB501F1907E0866BE5AFB17C638EEEB0C16DF0CB4121E53AF2DAB12EFFB3965FB99BEC55C70EE09C160062B1D4C6D86ABE970DEEBADEBED96DF763A9FDD56F6E5304C9EB284B30B0D879398BC884432C70A4F9C459AA5366B6DF1DE8F65D47B151964AF0D9ACBE2120CF32F9E5F7ACDD28E0EECD08DA2D9C66B974FA9E58C54D4F2BF54C3F46246CE9E302B990C25188E544283CED749A63607D351B79931C3E26B9B168F600AC0D03DA573F506F2AD65C295CAF1275F35762FAD3289173507154A12416BEFE11799206AFECF5E4D9499D4EAAD857E083DCBBA912C7C069FDC2C54FFCAF22DA94DAFFE7C38900A4C89D530CCA985D5C18BC06081E04028140A04EFCA69FB737D4EDAAB6E4BC6590824D7A94FC5D74FDA5FFE536C650A5D841673333602AD07A4D7BF9587F1696A4CA297E93DE2C34A4560484C6FF3186671F1BC3C57E872A85C68CA2E71633DC603DEF3F8B4435115C8B226011D970880364E0FB4DA2E898E81F7226DB8A5908131149576264F2336C2484031DF7FEAEFD02D00FD18DD7C46C90CCBF0A8A5F1FA4338B28E1AE0DC145FC19ECF967AAF57D96575E96C239B89FEEE8F12D317FC7BEE771CC27112C4938B4D1E5E07976F4F9EF4107693672963EEBF71401C2412D4D513FEC8BDB1D08A2FA1F8081C11E0FF4874584787FB2503AD24F086DA24633DB216C17C22EA12BA681E19F6187E57A781025265298FEE5E0B545D28F0F7BC4F9D6E53D304701638FD2474600BD07CDC5D67772A6B902FF15FE3DE5374A63FDC10B93433BC9EA202B900B290201F6A7E12EEF614767DD7F2A8AEEF57FFF5D100D7A9931CBA4C4C250FAC8E822BB0403276E902C22170E7100841E4DA91B350A3FF9DF80E66A79A7DC3199FEB464F8456AA2D6DEB7623E0F1940C337BDBAA647D91102FFB2FAD8A50F38B360F6F4EF526B7A8FF0139203BDB8084F155BDD8F9A537F4A827FFBF2526D9BBD93CF6C22F17676B9F6DF49EBA8D04CA57D2F8BF5D7D72280DE7432C2DC455863236E0CF62056FACD4223D017AAE29672211912397006DFEFB830B1887C9F180BACDF4C4FDB9893093E52FCEA9F94F81A3FD66C497F55FDA8563A3CA5F077F67C0F90587B3F61592767934EA6F414D8BB43D530991549CAACE1700FF08A74A110F8136510B99E5CAE68B4ED02635AAC72111DEA5F87FBDF0FD7A91E5B46AD0FF9B161922F9AA5E52CE3035184ABEA30078D1312EA534E95939E98144DE1343F7D49EB996AF52FB65608BD23152DAA98301D368F84033C2D9C633F1945D14D1878A6D4FC7BF3ECD295B4BA81A3B80B0423377C8B713F71F7277784471785C00D76816B357136099EED792ABF90C63F0A09D4F19E03CA9BF4DC1C3E4DE62456AB8092215BEFBC94702139E249BC70DF2F4EAEC6E565FCFA522B1CD216AB480FD0A21DEE1F84309C995317CAD160BCB90DB6D6115D7E1B7F771D6F68A5ED95B8CDA1CDD0C6EA1306C1808FF31DB2A7EA1A52C53F5153071688C9599BCF70F3BE1917CC0F2C32794ED8031853E6CE52CF190D58060726BDCD34F5BC953EF61167946CECE8E10834DC19E495978AF22AEC96484300C8092FCFE8474C8C2DE506D72018D834976C0083ED7F98780473B75CAC3035FB09D6DFCDE12354C9EE47D76B1974026628CE20FF699223E9369C8B83F15641411469D6FF68EA4A1B271C792D35DC9B6A6EFF374DAD04C9D542151331D252900D8F0C57D0F70B3D6E10C1D9F75F297D87AE7D0A5508B255BB2F44523BC6FF312D385EFD090784E555FE38CCF6EE3D7F16526E1068CF12FB782CE1439A055FBDB5E1B6EB22B67008972B68956A412326DD776B39AD8B9A5ACDDF23526FC7B8055562DF18E6A4D7623870870179FE841EB2BECEA11D905E7371640BE9090CFAD538206663FEF518DD78C67EEE06F9432880F24BC763F5ED47E1B8869F5307116FCEFA8F598B5BCBABB01E0AC4D542D784BDB84DA84514A3240EB83F1C2AAE45B7677944E63CBC2BDED67E554D243E26D1A72A79ADBE629212F300C22433015EEB13B8F6BA57C16F9CE386147FE4EC095DDE0DF6CCE310E68973916048843751C717CB667B5B97242C42210E689737976E6772304935A6E2100F6434FABBFE8D38A35E7686748A113DCA4CEA1C60D03D4827AF50DC5490DE0993C38FA58A17D69164B2D7FB061CF829FFE73A12C7B3E5A25102C07FBCCC6BDBA92C23900B0AB2E8D3D52295A7AEC65B0D6BE347B42399BC9D2DF4BC4FF2A4FA657FA16560E2F6A744AF61B633013AC5BA594186B6FEC9889DDE3FC3F319BE990089432E1B75166ADDA1AB4A48DEC21742DBEC2F43CB0A03ECDCD3F451FC5F0DC310D1B6EC760857CEB08BBB82F53308E9BBC3C218E888E252E2ED385CEC14A27FA856DADD25F87BB4D5EA37C6FE4E0480810529CFF8AB80208FD913DFC3E5B8F1BC4D549972357B2B8A5FDF0313CFF89D5500F35FBBB412D60D499887665401CD8E9B4F7D853A72E9DC0AE5CC15CF21F0B831406EDF50424A5AF5124C9EEF96E1BCA273B5CED244E3564333053A3DE51FF2ACF2688C6D45BB66FF02DA917EA08BA7DF9E542EB6FE3952890DBDC86EDFDE689068A24C70A4FF2BBD7C54D1B7C31C0B29ABAF26E3B44E1E96F4521D5596F34556D4B29B53FBF1FDEF1FE66AF2B16D57850D3010FECC8190735803CE3D30CB68C80B8627BBEC79456F8A96B9DE76CA26D7B981F2409A111E1B22A3232038AAD6844B9C6E08A78FBEB7F8BBABAF19816268F025EC67BB7BAD9351025FD2982502E1475515666E0BC795AE85000FC067CECF4DF29A5F91BE321AE95FC170E87BAF751F4C9A50F9BF51DE9383285E28C2618809659E5CCB8F82B42ED98A3BB849364E55E457471962132D1903FBF7FF9A5C0124892AE5C1295107F40F4694B8D46D4542D396174A724F96A08CB9C27F88566D601BAE034028E66A48898116662593DDF25BCAD6B007172B2013D598A65334E0584639B91C51B32BD03A76906F280D01642D5FCA9A4618A04EE39A15FAD4C5AC5A6013A30CFE1D6456BC1BB85E41E7586DBEC586D3C0D8B6527CC676A480F6DA61B96D6727AE6D8BB624B8948692011AD26EBE46CB604782D25E330EC989AA01DE4264839139EE96C4E648BA1F7EBFBC50A4415AB8465C6683ACAA58E7A90EDFE6F5EAFC48288D9AA4DFD402BFEC913DCF9BF7D5C0482149E28B40FE3F09277825C9F3108053410FFAD0D73F76B1FCAD38D535D082FDC59195BE4024DC32F669C864555BA0BE970E201AF7C9D01D2D48FF10FDB3016617C80491AD4B194A71402D4A6B64FF63E0B086713B228BA8B48658A0C1DC91E944DFDBE8279EC14629E186DA977A0185777BA2FE6BE56D5D2F50EF3FC05E7EDA3FC8E6C99C92566CC16AE66F7FB6F43D358DA55872C272F6351B7CE7DAB9A5CFC41D1495B0C68CE02D95DDCF16E23E783D79D8619F2BE81857938E9B56D587207867C9A2A0C773C1F56FC6B0FFF94E0433B098BB96B9AF95EF3A659E1A0680D8C750CC28344C7CF5C87E257CF2E19FB0AF87169F6A4DC51BCB166914FABCE2F7C958EF577CC27AAE514261999369017C40A07EFB077C8842ACEC7F0C8261C5BCC4103A65F65902D88334DF0F61760E319265DBE0D619AA4E70BEBE04F8A090A81C4C56F4F243F9F11E9894B6E1919FB3DE1FF8CF640095A628DADFD025A20EE02EEF65E2859CA2F610CD90B9A40E3EB7393BD03C048B1538F96B5A5456EFBFB33D3B86C5A7A77EB7BC658AE8C53FEB15E149317C584EDAC583F032C3B87E6B40D0ED5B1D24A4D500C0F0D806B41CCBFA0236C01993078523389C2143EED0C684991785C071514BB788080E50775BA8ABBDAFA39DB5B74780BB43A05BA0BB138898C1030D71F09C3DD0D6944FFF94D9E0DD14167C898970B633217096914F1A51F0AF9ABA6E510C4792858BFFC45D1FB0ECD5AA76E4B5554049F1EB5A46912B612DF6B89E06F1EFCF9D3F165709DDB8D6A01DB313C83A807809264097A13336049A0F67386A9D8AA9BB3120749C11A46BCBEC50DBD0A045DD95CB61313B9007C5B5CEB072A0F9874DD8E3B1714DD0E57BE34EA070C2792C25A33BE12380D1C268FEEA9396B0987838BD71E7BFDB5687234E84EB03631BFB56671F133DE9019CAFC57E81C89EFF582B31A9359CCB4C134AF2329B557F35E5BEABDCCD620F6B45EE4C8E4554FBC971C071697A325E911EBB6438AF08AE57FE236BE5F5BAA5EB3F22B80F2C0F307C6E7640DDDDB7E160D630670F9E32338A632E0E1F3F9E2432253ABC6508014564C0620086109ED1014DAFF3567355DFC48F98B47DCB113281A4F5427AFC4F4FAABE03E517A3EEC3B57600F2D8350D06E04176A795B7FAD1265C70A6404356089D23D087BB41687A646135960D405B3B4364EB0FC6DFC32A0C97D6884E2957480EE100067CB63406F6ABE27A1817E3A4C4828FD9EAF2ACE48D6D36840D015E9D25B4AB178023C839B6DE2664CDD5404399BF6AC8895754F95E66B8843C0AC30A97CE1DBDCAF335B41DD470679792BE0E7C589ECAA3FED97ED83A6A09CD6FE3DBF72E65051D0B7C811882F65D5E09FDB1C671C2BBCB6D002EC1EB1FDEB39AE2D1D75DCF4BC35C67592A94E51CC7EAAFAF93CC7E87378A4E70AB8B85D4D4BFB009F959C312B7CB18BBDBDA2CBF9E9989C4451152D12E1BE8BE66DC0DDA3506D00337A5FCA782A7F2FD550A45CC1EDEE973265FFF62D2C90AF2DC9E9A5DAA724BB8B9D0DAFE29760FEA776434E29675EDA1B05D3FA6CD8FB631B0A5516E2C17C5D39AA7EADDDCA2147F02A8B8B63DBE89CAA0330CAC55EBB26EFBCBA7CCCAF7D3B6095C5912CBD4230A6220147B7D2AE3EC7C678F518AFB0C7A175FBCF46B567E6F714F83D1438DE20957064FDA32869B13A113519D1F72CA7B8076F704C0A441C165CC644F118C53C3F6D2F6C3A1F0D1FDA745E6833A9F56D9DF2F17A73F47AF1C3F5B2DA4AEFC7698AF4535B7B3DEECFF10F38A1D412634F9C76EC6A472BF235276E189BE1711C05AD9F2EDAD470257A4ECB610C83C042B3F66A3DFE35984B8355472B2F3E1AE83A8C3B61D2203576C4A6777FFF78ECE186FE01F293344C9FFA990757CAE61D0DE7E12E9A0ABFAD4EEA8F411638F112560408812878A07E6423725BF35EA5AF6FD7C8829964A0C0908637498730E88235B0630262B8DC2B32F64A652200E96982C0774F3FE2E0F080BFC037C9218CC0FE36E3030DF1CE66ED29C86726A779D238F886761F3CE081215DBEE048A599B9AA8533E5860099DD9F49FFACAA365E969BF66F30A821CB3CBFE632A764B49A3517F867536171A0A8689A98E0258C75A69495E8A0ED3648DF12748F017B13344444A6C9F9E4AF1DD766ABF1035E1B3E32971AD1644C3D127475E696052DA705D0EEE538737B268D883E2D4DE7789CE8A535A1EB7948A080796D9851EE81BF38BDBE58BA59DB9FD06AEBB2A158680FFA4094B345A5B65A7F4F4D9879AEA1F32F1D86156AFED4C1258721B58EA8DBF6BCBFBD2DF311CBBA1E3F1F2B0F785912AEFACF0748ABD738939EE1B6F6153A2FFF27F89004031CDD1E6330696E20AD5A5CD536B7F51A54D1DBEA0EBA1CFA4BA13B3F97183A5D56A794A95540829673DA94589DAE35CCA39EF7A9E29A9E3146E299E1212313723BA2909196E1E8C8A8F9ACCDCD29D27ED07570C5B04A47C13FAA5C11CEB354F982A94284FC96AADA7E7D6299876363FEB878A9B1BDBD5342091BC43662C5E550BBE215DBFB5510687F297DCA7931CAF4112A9D8D7771A5DE509BEA45B48819C867D49EAA37DF00FC2E6157B9E08E83A727E3AB9FD9E7F1735D9FCF3F9BA55187C2AA6CF8BF8E51974278FBB3C6C24EE3C94B91081868F6E94A1E763DCE15452F7C941538587A3CD1F01722443BCAFC28EC73CB26C6D43D9147057974F7E949BDB751AB6D85FBE9ED11DBB8BDE6400B4F6F683F393055FAD610B111370B40C0C46009142A2F605BF7F3CC4B459D708AFC5CCA87ECCA3784E1AC642FEF626D54647890D38DDFC404AA2FF232F54AFFBF7B71E7F319DB7E6AEB83C9BF1B3FF5A7A55E7053F0CF1710B513F32D35E7690A5AA4F08EAE932B9FBDBFD4CEC4A0CFC192DF7EF45B3E6946EDFF92E66E1BE8FF997E115CF6E67071BFCE27F38E52EF0F84B57122B04F1370C31BCE1E64B727E0FA742010CDC4B688CD5A77E6E46B3B6345B56A14ED28A4A4D9CE9600AFC55F999C72E64171BA0988E28BFC3B41347AD8954BD1861EFDDF0EA485F2E45A7590ACDCE729D39A0F48886A8B643740D8D5DBC2095D4B08C258745E56E11A55B4EF4B743F12F8B2B94563C636B6B673BE62F6B187D9CA3CD9CBC1D6E9FA649C0DEF6D1E24B0D66C1211C8BFD1EF1F607DED6A9AA831F93591CD7691A680D3A1457C3B775E66309CA216545B91E525E39DE16925F9390AC1435A24E74AA1845B49A9EEFF9C795C22BDD88947C4113F925EB7D666045C58896EB82F01FD9E750EA63DD7992ADFB79AE4F0A44A8AEE29A161BB971EA89B1806E6F437004198D46B2584E2546E54E2755F750513ED1DAA79E3B957EA6BCB57A18C2AF68106598AF1BE395D60279EF064827F161BF5AC84F3F8B39B28D6C38A73E302D3949080BA32DA6465898601D664F4124FDD08BF7A5F6C161E8BBC10F2E3A7A80C2D6E8AFF28F3451B8C2D711E7C99BC3AA23740238A88C95686A07E5ECD7DCCB249EE28332D7DDE32C245F5CF4E517056A03CFF8E2FB7FB9982981C9C7553DC2CEC0E6D696C56DB73DC03125A79477BA7517C26B6B1125A85A7EF688275CB15BF600C55C8BE8B2C6E8E2C5AD54F002BCE2E7F79F479F7090A2AE554274E5E693E1BE7508DBF65770CE0EBA0A9B05674808BEF2C7E8175761D85DAA7682B92BCECFCB38380E1C595F298C82074E141FF38D25E3CF328DA9B4AD3B8A805880C8C88A086CCA94AED1DA7677458111E52F90F993AAA6635173AAA635C49CF712104AFB8C14FCEF785C5DCC3DF3CB1B81AE8780CD29862430B0DA6CD445E4A69458AEBB30B99BC58044E29D6A79270696469B68794E1C95EBFD87ABD9CF11DB6AB8F664B1799C7E9D1C442A2E13806DC2CAD4FFF419DC6CD920AE297F2F89CB377FFA939188C9FB059F0EF07F639426299CA3F7C15DBAE875A9854F1DF6351ACAF98851228C8919477B848F8EE4099E17B94F488DDF74F300F7FD13FF6A2961DDEB793E722DA1FF15AF1CF31517C956424EB5765BF1C400A4430DD3520DC79D81D056C067513DDA28512E2CBE9FE98FA5FB256A737E0D7B4B639BD27CD996E287D59640CA1FDE99DBFCB03F1EDBD1BE9C35A723DB94C8FB2F6B2D881842176420379FD15FE87F76E24F8402B5E175AEFE5C1642098EBE1DAC6EDE602049D0A078A8AFECCC6B5B1EFE8C6F8FE8D00EA8FB6E98ACEE620504F416133F25B29E66FE31FEC086F16DE2CDBA74357661A483050EA6CF4AF0D5E8D1F413E3009DBDB9434B965052C2E5B62291AFD5F8F0DEE7CCE7CB95579B07FD545F42374801DC21F62A8B60AD5F2BC630F8867C36D1F24E9260DA732C9B5EC9CF068A9DC34330B8CBFFD385894B2DD3E9B0BFBD617218650A361594ABDD54EF038435537332E63B6495334F287E357D1D6558EA3FF42DAB098F2436C217D94B37F25973CF91800D4784090BFFF4B8CA2EDD7F9606341FC2B17DBA14C4396F3E6D11514EB7E7C5FF0C99B2CC7C70430172C24892CE25DC126E921F3C847927057E5743E5A50BC04C04624ADAB5D31AE2174193CBC3B98C3AF5E935E99AB34B0888CBAE8A6FD19AE64F07DDAF83A75FBB93D01D959242CD8571007A21F8D7EFF447948F5FEB7633082228AE3966F87D2838EDDEA96BE78ABC171E7125CCE1A9CE8C946B79B2E93B61A81A4C8A474A7CEF0D16D4602F4429CB1F6E8EF3388E40D16C3F967ACE7469727FDBA014E0CDFA5A0D0018150467C2873D53778DB2FDDA1997D532B9C6FF0E454224B415CBBE04630C6CC2E08DAB55D48AE39B82C5E548A77A7C799F4F385BB4627D1A9D97D05CB425EB7F7354067D821D78380ABF392B6808CE0102C1747C19475FB0DAF12E9F41FE4F53BF052F04EB24C988DA9CB0DA7DB4E0A7FD3C59BAD9F039955DBCA74EE3600F3E87C5D1B7138594604B43E7031FE9CDFFA04403AA4EE4B76026268CFE03E5C7EE476F84140E53FBD7E0D6C319F5B0252A16F31A58C4BF05ADC7EBD53546620134B89F2DCCBFB42D666E349D6C2C0F304CB1FC52B912FF1359844C2B3D5A59F71B718F84D285B2145E2E97E30265F09A19A517C61BC239E721E637F7C2604F2D55549CBF785C07E6FFB83156FF375273DB2829BB77E93E4D7BBEF3572B6CF573BD5D2AA08E25079BEA6FEA5E6248593F88027EC4C2EC919468A60964CD9373D2B378FA6188C2C452554F95CFDDCDC0852B2C00E6ACC45D06DAD9986CA9270F2FD92B1FF59F7B9B2E144383001C466CAADE7459833917D4BF5FD237A5043C73E317314723FAA75822CB27F8A5F05C0DA2896A44DD11CF4A591225A2A67DD6C85A5061F0B7A2DAA02BDD448DCEFD5EB488EA68259C4687DE9B736C7A54D9A467EC72EBF3252F0991FD21DF47A6C2F67F9667032ACD861356EAB2788C2071CC72D51FEB330B0B7ED92B32A3D56062C772B2B36CA2DF7CF38D31B0E1ABC04FB932FE8EFDA9C38A4BA46A7A5A0D1FF9E30C6AE5C8512439DCE3C456CE092804B8BE211EE17965A9A6A8CDDE65C9162DE414A45D97908EE2D564742DB5BC14DB3C5D949ED472F2EC71EE8EC8FEAEB2A346A73E55FA3DD0E6B47525EB5CDA8E931357204D1FDBFC457D100C11F988A0156324A58896B4EF419C0C087B89D52268C1189B19AD4BA35FA25E7784D3690794BBED22CBCB234E4906E8EEAC7131DB1AD5B4161FFA870677C7FB19BDC46F9961A88DEED65174109E5034A8B680DD54555F16B12BC56F887F8A5843069AECC27D4ABAECA7B88B0818F20147CDD1CB3D41CEFBE94B15B9DE09F25605DCCB23C3C2C0A009240C063912C37CF00BE943723E7321D7753F97BC97836F360392ED72E4397BBCA86A02D2A8540559FD9F2D014D40CB69DD4655EFA5C2A9BB7A7817ED3F6153AA4C84B19F3D2227E53B95AEAD765AD3CF3175549F1D1F55CDC7E71D658818044B52144216A1C36320F95748525258525252489247DFF44E322AE2439A643A84C4E8BFD95F3EBA9C3D29AEBBE430C780A41F66374C52BBC84E2DCD0CF2BB9513E4BF7D8C3FACF601C54FA4F4FEE2AD559B8EC5F8AD40D7A54B3B663D63002E5570B2EDB26EEBBC7F4697E6CB9A75DE9F5D6D867FE3EBB1FA621B9593D2BC930047C408D4C99B647A42692B0013D6EC3938A824D82E8B4E019BDB6D4139339F28B9E96DE27F35CB36E7199EB0F13BB9F736DED415560D1FA271E77657757306652DEB7FC0F27C4E89B6910EF0A35891298944DB27031C0822303ECC3364234E82CD3DF009FF07022E5FA6ABE1AB17A1515D4CAF8FF01AE55770EE884A8041E5355B3DCEC12471C3F33364B1853A5D720C5D9BD64917B726FC59A7A0FFBD4D30B902198FF1ACCBF5FF674747EB73892518FD198B0D99AADE7FDA929301344ADA8D7E0C904F9E95D88856A464582981E6727EA82324571EF2A3EBE56AF5EFBA704FAFB503C2C4A164300210FC72AF6F2FE68D0805308E2148B0367CB97121A2C7C8F764318D58A85F20296033C1EC80A49622A285C9851A5E82988F47B7D9AD64DCC51E5AF457232722380DE1909586EB7058E390AC83CDEDC3302FDBE637823D9215CCD1C1940DF0E4A93C4DEADA941E146C0C0D2EDD47FBF3AE6FB59C7625FF8F5BFA344E8F90787C113C225253C43E5E9007677B55260C6B4611C620F84E26921C3CC58714381999FDEC4104C88B66F15665CEC350A407B0489D47CE5BEF4454D81CE049C668479653A8D4D661F0AB3C10D03784C776A27FC7A66459CCCA2FEC86919BB386812A39A76AEA0BE16902432F4AD0A05F6AD00B96910769AC31F111CFA0A3874D3F9879E89487E0DE2491C8E5467FD47716AFBE64442DFED68926AC3F9E04A8FDE4A03A675893AE108ACBA1EFA217B52DEFA620BB85F154C2C7906917F1AEF8C2D96393E0E0A1E9E7B70BCA507FF392EDCF64C48B140226DB6B9880A911E5A3AA0B5D29D2CDBE533FD3D751C56D441DE6EB4595112E04BB75DFE72AF9AFAC027C7F612615895A121D39FF37A2E15E83B3C595B91D3FB4D574B87CABF0B5B2D90365AB1636A423B18B8F3B32C35DC8E0B0B8E92EA29C52C8C6931E829DE02C7B94509B97EE9B27831730FA04EA5FF09F97A0C8EF3ADDF8FC712A735C9448C8AE5F7E89E3F3EBAA905C429FBEFB09A0DFF5541F44D84852246AA44E884AF384FCD50E4B87114A25094415E8AD6E3B7BD1396E93DB3C69597A59C668DA8131F8D3228B44DA4BB83E644F5D9AE8913CD2CFDF3C6AA223E70E3CBCFB1F0E6DBFA22872F9297D101BD7EA53E0BDF8F2EAC0F6A375AFF3F42DB09E3F6F6C260808C5BCE6EA7A0A4E71050E34D69E2E6EA67F92F94C27ADB9E64968C2E156FA49C010084108704F08D851152DAC113188FF7641D1B45ACE59EA1044FC98ACC206B22B18B90EABB6ED7589B49338CF899F61E1883418C132EFB3CB6B24B88B6D69FA7D723B1AA71126DEE1BA0F71175E93BE58756C4AD26C5A2362AAC33752FF576DBB77892FDE37E787096CA42D73DFE00FB7AA1919D7162280825B4AED439F827E0A67B7B9360FF65B094F6C453384B874D607BFE00D676D36C038C643777C5FBA3A4E8F4CBD7ED08B263EE9C9E26BF45173A87FDBB7C01416ED34C64D162263DF32A1D930B42358B70540BCBFA7A16A3C10A84BD9DAD246FD296F46EB6265D10F293C87B297CBD311C33820E52A59D03DF7913EAB2A95108017CE7048CDB2E9883924CF8C77A125AE3F1ADDF56B242600CE3EFECF3130B2462C3B4D6C8FF76A9C1B1129DA392C150669AAA53962990F3773C7607D2B9B84252DFBFC8E1AEEE05F042B7AFB4BF9DF38C4B38C56150728B39438DFA13923D6FFBEE3BDAF59DD54C9E7F94654CCD9435D78DB83F431EA07E0A4F755DE5460056DDD1D4767C96454A7F93A215322C4C62E5BB72E067CBBEB0503E78010E09EC06917FEE8D680C898BD7B83AED80C5AD82F55AB5DBC7BA7A5CC8023C4262388334D44A981DE20507C69C364FC955A398B8541E629F6AD0A268D66F020AB24022D7352DAD1A35F0CF1FC64DBDCD415F0BF8DF43554390FDE93EF16CAF940CBE3FD3FD3CA0EBA220078878C2DF89AF7CD8E67B4389B7555373ECFF3511FDD8433DB6AAE10158825B4C3E0729E2036D90DBAED812E38BB45A9D48F2E2A7C249BAF1EFFC934EDC1E4FD3B554783F9811ECC7B827E8A2445CD1C2DFB9B04DB5CB9AA5D2260268DBA861021CEF4970FDBEFD3F967AA5B2AADD52F73EED709A40D448363BF3ADA81E6B6432C46975D226602F144E90D8715E6F913854B0F81874769EAAF9BAD5455AC3D61BDDFD7273A8CFE93A0C72DC01A09E76415F3E40F67994F41EF23B07DCBE7A6B326F31E9DD2EFFF7A5B018CE3CEC6BE3F98BF4BB1ED3B7DA0F7FE861797D86E6741CE7FB8D8FE552F6E66F073234F844737DC8D92B4D118FFAD093972CA36CAB9A32BB6A4E5AF88DD5CBF73D97FAF8BE34F592238F1A3AE3B29ACA9CE5B1E0F553F17A800F45B3F048BD3DF86F5E09741FDB4E48247E1355F3EBBDBE18BCBEEAEBA9AC974182239081E0402814020FBB29D1559378BB95FE397CD8627837DF3AF45FF82F453FCB4D8F6955ABBB7E2F88ED7FACACA04EC88C10820AB4BD6D9CE55FA5CFD00C988292F57CDB9B0DBA2A8043525BAC77885DC45E3130091772461ADDCB9102ED37D31C166BC852A919E1DFF4F10AED50BC31549F7FC0D028140201042B57C4D845B6D780203262DF4D66C3A46A6C4AA8C7BDD9E0520A8217117A98D492236CBCD4F3436EC6D8E7C88220FB9261BE723732052468AFB8B07FFCA0FD567062DBF9A20EC32688471777ECDFC7A708CF3F60715195781821023AF8DECA2C77603BA079614A7728C7385419E6B7166E3F7EEF0A46C9D2879FA21E0E0E967E8D8CDE4709E0FA5966D4D57DE4989180086B5575CA56A0E134C3B748B7735C97C76E99D37951D57AD917B7368B373B031CB2B22CC81AC1BEE3310FF6E8575D9BCE7FF7654B94C1C1CC176F5BF8F9621DB86307B70339FC4A6F12AFBDC1E71A60DF4D85C8AA544F1EE3CE06FF0CCA3535DBB9F992BB60B841C654C8FADE79EFD418E41A2E930D13853C50677DF6D09C45C9DAE8A255659FA99DC8584FF4DACAE4A288D5FF95AA221ECF416251F0AE8F665FCA9AEA6C3A6490477A457923990D78F2D05B874C6814F68BC39D531E8610D09F54BAE1633BA7F7F63E1BBCDEF3DF43690E76A5DFC5B26F1A025387DCA6F59C4C31339E27FC22207080DCD617D5C6A93FEAF1D2CA157C1D42F89FA1C255144475B21CB7E4E72476A0078F589C46E27A078FAB82035F4F37FA731C7EDB677310C4C4B7FE72E130FB6BE9A2A46C549A82D01A781A943F0A5161F6507A1FEB8193F7E7EAED3EA2AC9FF7395A8E87380F8DA9FFD3B07CCBE5EE0A09D080820892D4422ED9FF24D0C0ABF2FBD924AB98121A8927035F35CC0D4593B9CACA67E163CDD4CF72C35BD097EBFD48C747849A40DD7565245FF774B7F38F497C2F263F062296D7B1A251654330A826B853FB00F7AA8152A060A23EDA0A74C0427347B778C278C506A205DC12AA7D63EEB0B0BEB33007F564F75D3DACE94C93A4F0527B4C0F041F17712ECE2FB4D3B36AAF9A0A96FF96D45E38288FA309AF16819CAFF5BF59D346BBC2AE77A1CE0AC5772E39CC9E9B0DEE3E8674A46EDF1E4C3335B02841122B03F7CBCD4D30F6D356BBF37129C22476DFCA635FC6F0A539D4364A8CB0D44B55BED103E546217EF3606497702D161B1D7534471CD7E723B4B70D59CD765961BB13FDBB28CF4D7C0E893A8FFD3724BE2BC08C97F344B4DBBBCDD2E97BC6185E1C823A6E0B3E613BAC514BD394033751D29EA8A4896161F56E47636161A35B6F8131CCBE08A16E73F28B6C8B3269F1DD51C10EA9DC7CBA5C8E7654C4D121649DED7D7AC32371AC933BC354D3CC524137BE1F698AD6E4D25351D071574BD1BEA54EF24F6111E61FC04535BF9F64A9D000E6BD36F0F4876956264A2F73D0096A64DACD89E5B9BD0AC2C4CEA545C24A632CB449956A0F25FDE45A7B9E34DA6872E5B169CB7395C496369721FF2D92DD5CBFDC7426101C992E39747744E151471691CF06AFEDA7AC29CF268C41737EE9421F5462B6F38F1D3066282508E7166D34C9B368E3B80173A473BDE5CD28FC01C2D86256E0937B0F075E922EEB9AC38A841C5A000FF06, afterDelayedMessagesRead=538983, gasRefunder=0xe64a54E2533Fd126C2E452c5fAb544d80E2E4eb5, prevMessageCount=41860731, newMessageCount=41861043 )
TransparentUpgradeableProxy.STATICCALL( )
-
Bridge.DELEGATECALL( )
-
TransparentUpgradeableProxy.86598a56( )
-
Bridge.enqueueSequencerMessage( dataHash=56601A59DD91835689A75F3EA61CC0B0C02342ED012E23FA03865F7153B2914B, afterDelayedMessagesRead=538983, prevMessageCount=41860731, newMessageCount=41861043 ) => ( seqMessageIndex=82219, beforeAcc=E70F35F6F5D053C3068915FA5BED191CCA7922EAF4ECBD104A22E2DB632ACBE3, delayedAcc=B8032A83CFE68789D99D3C3EEEF311CEF79DCEE74E6BA5DC873DEC109025D901, acc=CF8100A83974DC56A8925EE44CF1730A9E68C56856DA8CFCAF9D2F13FAFF5E04 )
-
TransparentUpgradeableProxy.7a88b107( )
-
Bridge.submitBatchSpendingReport( sender=0xC1b634853Cb333D3aD8663715b08f41A3Aec47cc, messageDataHash=51980F433989D6049B0341DEB9F062C3081052E13C30A95A27F1AAFE4E433C7C ) => ( 539085 )
-
GasRefunder.onGasSpent( refundee=0xC1b634853Cb333D3aD8663715b08f41A3Aec47cc, gasUsed=208479, calldataSize=99396 ) => ( success=True )
- ETH 0.047731221118650256
Arbitrum: Batch Submitter.CALL( )
- ETH 0.047731221118650256
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); }