Transaction Hash:
Block:
18978629 at Jan-10-2024 07:26:59 PM +UTC
Transaction Fee:
0.082480868610328332 ETH
$197.95
Gas Used:
1,830,606 Gas / 45.056592522 Gwei
Emitted Events:
109 |
TransparentUpgradeableProxy.0x5e3c1311ea442664e8b1611bfabef659120ea7a0a2cfc0667700bebc69cbffe1( 0x5e3c1311ea442664e8b1611bfabef659120ea7a0a2cfc0667700bebc69cbffe1, 0x00000000000000000000000000000000000000000000000000000000001413f2, 0x4ebeed17c74cad06b3e00f6475c14e5f0afc03b306c1b694e592d9c9e5e01c52, 0000000000000000000000001c479675ad559dc151f6ec7ed3fbf8cee79582b6, 000000000000000000000000000000000000000000000000000000000000000d, 000000000000000000000000c1b634853cb333d3ad8663715b08f41a3aec47cc, c653ec6e125009968e68244ea465ed1a45c0b649494b5a8d6081d0f6d3e51ba6, 0000000000000000000000000000000000000000000000000000000a41fa408a, 00000000000000000000000000000000000000000000000000000000659eef83 )
|
110 |
TransparentUpgradeableProxy.0xff64905f73a67fb594e0f940a8075a860db489ad991e032f48c81123eb52d60b( 0xff64905f73a67fb594e0f940a8075a860db489ad991e032f48c81123eb52d60b, 0x00000000000000000000000000000000000000000000000000000000001413f2, 0000000000000000000000000000000000000000000000000000000000000020, 0000000000000000000000000000000000000000000000000000000000000094, 00000000000000000000000000000000000000000000000000000000659eef83, c1b634853cb333d3ad8663715b08f41a3aec47cc2049f8a19bea02af998da1d7, cd916f31326574c5e3036335cabc77cd292a10dd000000000000000000000000, 00000000000000000000000000000000000784ad000000000000000000000000, 0000000000000000000000000000000a41fa408a000000000000000000000000 )
|
111 |
TransparentUpgradeableProxy.0x7394f4a19a13c7b92b5bb71033245305946ef78452f7b4986ac1390b5df4ebd7( 0x7394f4a19a13c7b92b5bb71033245305946ef78452f7b4986ac1390b5df4ebd7, 0x00000000000000000000000000000000000000000000000000000000000784ad, 0x59b213a0d88b89eb81d23cc9eed6ca2347f0f5e4e05e5fe953fd53d49feeee3d, 0x55947571310de3a6bb5e928761009e1c3022d1cf72e913aaaa3ab022dc93c39a, bb28129e40d3b8610f0e31eafa090b9c82d21cda1312d0bd725a66b6d17880d7, 00000000000000000000000000000000000000000000000000000000001413d4, 00000000000000000000000000000000000000000000000000000000659d9e03, 00000000000000000000000000000000000000000000000000000000659efd93, 00000000000000000000000000000000000000000000000000000000012180c5, 0000000000000000000000000000000000000000000000000000000001219751, 0000000000000000000000000000000000000000000000000000000000000000 )
|
112 |
GasRefunder.RefundedGasCosts( refundee=[Sender] 0xc1b634853cb333d3ad8663715b08f41a3aec47cc, contractAddress=[Receiver] TransparentUpgradeableProxy, success=True, gas=1825124, gasPrice=45056592522, amountPaid=82233868370122728 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x8315177a...4DBd7ed3a | (Arbitrum: Bridge) | ||||
0x95222290...5CC4BAfe5
Miner
| (beaverbuild) | 15.594475023058680657 Eth | 15.596305629058680657 Eth | 0.001830606 | |
0xC1b63485...A3Aec47cc | (Arbitrum: Batch Submitter) |
5.187855724144219962 Eth
Nonce: 441503
|
5.187608723904014358 Eth
Nonce: 441504
| 0.000247000240205604 | |
0xe64a54E2...80E2E4eb5 | 658.725257524903914988 Eth | 658.64302365653379226 Eth | 0.082233868370122728 |
Execution Trace
TransparentUpgradeableProxy.8f111f3c( )
SequencerInbox.addSequencerL2BatchFromOrigin( sequenceNumber=492717, data=0x005BB5B65430855B07D74900C36FABAADBE39D7063E83D0E460C7B864451CD7ACBE3FF2AC13660E60D7D25842255D644BA2160070B74A952A1AA0D9A0BB7E3BCFDEFBD7499FCED3F43C8CD0B84CB610E86F8F0082D7D24FFF3FCDCFE9C7BEFABBD01638C1E1562146090A30DFC0A0698A8A08D459A93010698C9B47F28D65766626224D81818C5578C1AC66700E7B6072D92754A5AC938252D15D24AA684C825F3449F48035A528EA4B4B4087232A4841EA06BFE677A418B5C1016B478B5402D2C7399CB8BA743CC6F62F881F7E3B63EF59781DB9CD14E2C7D4F36D40777DEEA9F67CE5EA1BEFB7FB30479BB008F435C489BA62E7485200C08E5D911DB6940458A2490DEE6FF5F5DF6FB9E3C966D3CA59E03389D1F4F66C8F47F2BD193CD1E3DCA5919C25991CA16764548112720F1D00CC66646E094290DD2806D94A9F0A15C5D5D3C83AC99F5589EAC6DC81EEC9073C65EE62430DE8253ABE5C96C28DBCA8CAC17CE1A619F1C763BA4C204E277AD149CCE8E7515C7584E693AFB4C9A045BECED9DAD9E6DE5E3AFD6BF8F56BE60B6A6B4BF2DF5AF7FF5C2F33CF72A07C3F0EC5FCC22CE895182C170426BB7052C164B05AA684F3515DFD3FF6FAD4FBDABD6C8952BCC17EEB65BA600BF3A653A38E72D5BF7ABCE33230392785CD5A99031A865879D68084C802684D5E940CD1FD13F38FF34F15F37D0536DFCC00E3FA698581C269835934A44476F21E04023B84ABA73905EF47968CEEFEF9D214F7476F7ABCFB79EACD7B6E439F5D4531FAAC1B6941AAA490394144A8205F3209A10D45FA9201E20FF3BFCFF3747DEF767652146D4D7227C215B1E99F2C86C31AA27E5947864E4C89423978A78B68A21117685473E51D0081073165F1B76284041AA1BD0DB507023FD1556561F06B64544E00AD5BF0F7FCD5381943D5B6817DF5F4DAC171AEFC13DBFA18921FCFD15D10679EB75948106C0420FC0A86581A00C468255D5B2BFAB77999E7F626608947FFAEF5266B025D180EB2B627109EF66AA120D3D29744BD9F4214C1FB55168A70AB0587CC19891E414BF2D43801064E10EFC10B1A5AD519B5C3D91B5D3ABBF63135AFF728B4A3DF11C8723581584361E91B33DA7E6E5A4012143BFB35297C1C35884F7AD4D6F61A1571D32DECDCC6B6ED9DF2D3228ED2E1D51FD5FED5E76851427566DBEDD6871C1D9511DB5EBC75465FA40B7C19A01499B4CBAEA746F1AF9294CC7321FDD55E2FD3DB87AB1447364E4FFFE1C9DDDA133A06697CA97B7ACBBD7D9619D7135B0409B998A0287B618F97A37B8ED290F3D421E5B61DC1858B90339C18D44182382B28BD805073BA6B2BE41BF4D00FADE98AD26188FD0C71BA4B710EF3C5065CABDE5ABFFEA47DD499142EB38242051B7AA2DF7AB229ABC38E9E835C9D09886D6AD23339AF55ADE5391305505D821AD86ACF9E3B6CCC067E486E2CB592A45524A0B4170404546D9DD7736AA5FA37B59DDEF038993EBB3A5DB57A9AE18DFC66F432B93FBC5ECB4D8C04FD7A1369D81F6F38950270E7505CA5476C6C5217137B634CDE989CBE366B63FE9375ED27FD275BB77604D831A0EC578AB178E6BC068B750E021FBDBCF4ABA22B558FACC935E8C70AEA01B17CEBA25853786E66CBD62E18758FAABE9676B66DFEB3E44B5340B953E587BE2DDB7230DA65CBBFC488590F7135A59B69F51C3F93532E2CD7E33E36134CF72218A06A1E21929A4145E10E9ADDC927E2B1952EBC37D180C6BE8DAFEB86F2C11CB7F523C82D22A51631AEDA119CE2E912EF4D36B78FE04745F928065F11D21F361D7D6F6937C00F5916415F49AA47344E0749721C2AD7C669077391771B1BE659DA25B4FF9D4085AE739738E8AA24A9B2388E08009CC96C5A2F3705DA6B1168047604261FA8DEB323866AECA309A1FB9BF11508C6E291A6903242DDB73CE02001D815EC8B8740194AF0332836994491394EFED1486466B635A0F726BEE3ACEE453E76DFE6418AA1B646421ACEE0A60FFC8E227D812A1B3A7EADCF06BE7A8EC3D17CE3B077989603D09B3F63C50D964F2A003B1F218503E0238021FD4D50844BE3398A7578A2FC4676324C6E0F2D4B261B56161593D1AEF7500483418D6FFF0F491C32269FEAC39DB7FF8BF76749C8EB017442986146C7369A575201E844C92E2B05C6F400FD7B3610515F2895EC1613C1FEB6957E8A6741D9535DD73CF0391707FD055F5941E97A3C0686BEC4EFD2013A572A3A7B88767F8F64C88821A5B880BECA7973EF39A759B626BA2068836D407E22C80C2D19644C6843248638308944FF8B71F6CBF8487F4AE38351C3A32DFBAAEF6407814C33A703BBF899D9B7C670C9922D57C0273379FC5D47A844DAB104C0145A24239AE6251A3034D919E0DC3313DCE4A6CE762D2D10F0652EB38729F39832A59880941F1A847826DCE6CABC0FA674C15AA938A10785E7C801261AEBDE44A4D99DA8CFA9A7FD212EB6F2DFB1FA487FB6E2FBC5A3BA5F0F7BB164B401A57980A05370A7EBE786BF5E9B5133BFD7F4078F67D2F72D85FFBF1D9E692C1BE74B04D8B06DBB10D877D01D186031D108AF03DF8E6EA0E0879E75E16A21F2689283CB6B61B7D7D6560C12941D567F979D782BD98CF53CDDF8DC9397521FB68C6BC3E86382E7BA6F34ADE10F435932AFEF0A73B5A90C107A77B88F02A76D7ECEC380FAC2626936FA1DF56EE8767336AF9D8A6E055713AC732121F3EC6F3C3DF8D12FE489BCF437A9FC9B8A5687686FAA56FE9D81C7C0541B674993C7B1A90278167BD6594DA38BFE37AF90B716C289439135D3EF3D9BC623FC945154E17711112CA4BEC1EDCB9A55556B7F41E68F17BD5AB949F30DEF6FBD9FA26184AD0FACEDE1459777D3936A741504DE2FED97A417C99EE50EB721A51EAD15EA8A97D52E1419543D1B134435CF072DE9E49FF14CCB69613D1A6DFB80536A434D506F153E52F7C4C7A1696ED3A17981D1D2B9D4C772C45D4D3AA27068F2B2E4406172104A18D2484FA84B9C886822E701E6C0D0CCA3287DBCC9408DE1E533E9A22369520F1883120FA6A52D0699ECE3274670B94BD8B9A9DDE26F962AD489A78B87B872125BC1931FF85F7FEE2A22E0BB23AC8FE63571BA267D9203A35DCD5AC7E8C085E05466843B72D56885ABDA0A7EAE0E9F6EBD2D4CCF2252A21E8E3D78F1E418688E7CE2E174578B437C2CBBF8E1341EC55DAC063625C503DB2AEBECB230A793D817C5036484EF69AB5E5CA551D32AC139F48168D7A45859A1B27881025AFDB45187AFA64C76ABCBC92684F08E9C5C8F4B3874A61953888C97449B171E634606AB4E051F10905A45CAE32F6C7628FBDDE0F5ABFACD821F449B7EE60A94623988039C1F3B7FF5452B19234A5887B8EEA6DF8AD26E05A4EC07D42811AC7C1F844D0ADADFB75FB422D0246EE2B44FAD7ADBF344E1B5BA576236AB35C07A1778CFAE779E82832F7C65009E385B78E63FDAE5DE08E57BDC7B53407FD6B5478D23FC31523925A912525DF8B1651308A9E15EF47F652CF8F53C5B93B8D08767C988E774EE2F5F7D91439B801863F5F58384EF7F26F5017AFC689B59998E6A9FC4DDEB873901BC5674B2BFF744338A056C0A860B745E921517B2E23A52A4E68AC87FE437529A76B9D9CCBB40ECE0E6D75E28FFD5AB0AF104D63E7C586A3FEAE38157B5262074DE18789D321B0F6DD6EA6E50DA4C252CD71C3252F1796CA0A3D76DD6F41C0FADDF1DA8AB6A310C39EF31355339BCDF0CA8893DA25675F911A6ABA67EAD71C9B44F25547297AA0F19202F969478F2A18E34DAE44DB40358B5070427DE9AAF5A3909664112BDC2568B5C7AC7B0792CEF6E1FB30C204F3CB0E6ABED98C285B6A95EF14826AEAA2C5EDE5E6E7D53BA4E7E10BD832FFCAE5C1B0C0FFC0AFEFAA75D5F71973285B5EC409E219AB156A4516B7FC4288E7CA588A2B5DB177C284430316FFA6A3BDD880F04CC314047E6884D35905F0B9F14FEE3130B24803FB1EADAD8B4A60501FA069A83C412A3AC6D66D4F88EC14A105A6C773812E3586A3955670940CD707C23408A093193D2DF6A660FE0CFEFA7ABC1A74B8863FBE74C71CA82ABCFF6C1488569A2B08D0ABDAECFAD382DE1B81F384AB36C56F99E7FFF75787BE35FFB3A82DA25DCC3287ADCCC1C0F0AE1A6963C37F45EB1A6FE267588D545DD76D356282D4A0A629E54369DCCF6D6B6F90DB24E45FF1AC95C3D3E25604FF3E6509455E2F734E41EB48BCFD3FD51D566E142087E562D19D64DD58D725A3F6625237AE1ADDE9004EDE3E4690349F1C18DAE055FA8CC9644C3FD8A39911D89B9F554985B6E079C42DC835B4921795F5C84E042FFF86B694F675AF6284EDDEAE1B860B10A7742D27CE2469AB2B1F25B7675C8A0649CF02D229C323F41F3C9E18EC3CB9509B84FDCD338381B1BE9A29F7E5F69F413BEF36BD4F8FA623D036E1404AC1827D222FD98F4617464F23CA054742D61D82262688BB812813644940A0D5D0028C6719DB8DFDDEFA89F5B85CC3383F3608A0B3CD2EBF6B96FF5D5362049C6658FB38BFF99B137645F5DCDD6CD2A3311A86F58F070EE8A0CA458AFFD4CEC423B39CFDFF87271CF17C1064E8E1EC9796AAEA5370BB5405746E97B0AE4B27E3F3BE53A99F7A348C772E9B8D0366BC0E41C248F51B294FCCFF4FD3361C859C9E085026FB2996A1C4F0705060A06B30ACEB7F062AEF9B5E8C58338008D04C1A56F2C68DC83F8FA67734F583AB9B34E3EE6089AEAAC84B466F4BDF6FB64221C115F52076F50FF27789E1CE07087FF70049700A792207DDA5D6819B7B9CFBF79F49B59FEF98A04DC7A99542BC9954146F01F8CA074559878D6BAF510D03AC27CB7043613A7B3162B2AE35A8AC0094C3BDEEF60010039BF3428B1BC2B03A19C3A11F9F808AE462417790C1EAB4286DD63182E6DB80D6968C93EA111455FD6120D12A4C1494FC6086880B77703F1818F30E4F2066F3516BA0AC4F692FFB5BF93C6E7AB641E35C3A64B4B274A392BD0C38DD52B8336589300ADCF8C5E25E6856B9DE96B59E361690E356AD8D36D681AE99909A409493623AD40BFE0CC5318F2F3DD19895119C6625BC9C1B024FAF7CEDF9711CAC308C0DDD2CF827B8034CE54D63DA9D00B006C25076BB724FA0AC96827279A98058D8FD9EF41E64ED7B0D710DD1CE06548B5B33504BB6D9895B6915F856B178F4DED4BE1BA026803E3AF3075F26D97EC125D0BD217E7437C5DD8106EDEE0A256C514AF504ADEB6DA977C9C23ACFB83864F97AE2F9F76884DDC7483DFD3846132F894D91B659CB0032E9F4F85D5D71A66FD925BA0DF3A4EC926A8E1B9D0FBF065DFD8EE87EE606BEF00247460EF5C2D0C220D6F2C2E16E6E048719FC90481336DB17C9DC26453AC5DC305BCAA4A5182C3B780AEE802C1E0FF6E04F79668A587B51C810E1537635C4422B46FA130D01BD98B9388126B5BB58105BB38084E419270922605C1485A83428F2AEB6A4E095A96EF59DB3C7D91AA0AB6E279EA2BA872276223C2F3E947F9AE821BE58CF1C035F4C2ABCD0B1175C44AE297A030B6B5C9C7CE5B80B22D4739CCE61B53A08B6A12E5CA408AB32EC858F820245AC9449844FFDD80E91F71461E9A851421FDB3B2D3436CAC0BDDB94D2F294EA82CE7BA7E529D3C3AE50F1F54EFEFB59F708AAF7A39C4DDE8B607B6FC30F0B68BA33623F29BC48878F99D66F3DDD9973552924262A7CD578A93771D493BC4924F1AC32EF1E98A34179AB98B03494D32C2FE9A26FD8CCD55BB134163A126B90B2FBDEB522B23903E0CF42B2DA35763047ECAD9244DEDC6430DB59D22F67DA4712E78950431BB74F905039B14A089C45C4277667476F36EEC85348C7674F24BCE904C7EC4EEFF48FEB45D6C016E8B8D2EC74A2116D19485BE3DA051AAE7F31E8B00AF3A0348ABA84FDF6F1A8D8C2F0814EDEA3943D1BD547EC52CDC9BC01A8A71EE18A8D47414B47495FC3E9F80A43BA9909C2C5EC8FAB7ECB041FB0FB1221923F3D92BF0A99EDCE93AE20C8A087894EBBE7F024B216D46B247DDA29AF2956F61E60BE86476330E1ED48ACF07D6A211BC9F40E07E111946F0978F72B3C8FB8B3BAF1E96A61637B4C09084C6B9DFBB6B7D9683BCA08F6B9CC876044D6F8B4C8C2F7B0147F66D03AC5CCC81A918FD1E7C05841C80222D9109855C6B46EC43A81571C3CAB6547FEAF37B665F80377D33E8AB3EA6282405F397900D59B91CAECB9DEE1F4494AC3C19DB7F2B7D8E044853790E132433F34B548158192210D3A47111D03F38EC6C8DEE0FD0B5D84EF7E7E4EDB6C0A674A6E83A36AF5C26665CD91BFD499AE44656582B6E4AF0F902497CF98FC88CF4A2691F03A830FF6C192EA722B888B2E3B1F1A66C2F99F1A4FD623657FFA2C9275B941319B0A7F6E8818E2E64D6819F7476A8055F3A6ADF6C440797B0A23C0F4AA50679E3B597161CAC63DC960CBB6696A91391E38A42D3545EF4B82F948FFF963CDA0DECE4BAB8B9EB53CF68F1FA44CA5FD73D954CC4193A8CB1EDC2E056F5CD67490781ACD2599E37F37692BEDF04C888B9661AC449906802E991BE981D9A147DA0AF22BEFA7B4E58AE843BE9C0CF809AE531648700C559284A5562A220053AFBD4A611253F86C3BDFF24A344BB143E71AF4C33782864ED16C5B98F3776BBB13885D8D41F2C1026A0C07D3D478518F04BA77A6FBAC6960580B22F20EFD8F5682C347C800EA93581E0A7EF81D74FB359A8D799D7EBB414F388C0FD4FFC9DC382FDABA674DE7B641240C085D4710DD722CFE692E9E73B28419A0FE9BCFDE8E60C035FF03A6D332476112B7DDEF28D239A921057931965234C1CAB43E8A9BDBF0EE89339A84FBA8E28247CA847911B168B0B9B4B7512C080ADFFDD284ED0F06A8C096A5F509D7775440BB321B2A0F89039B52E34641706B6E018567DDD1DA3DA09F9B4CFEEC70025711307F4500FFB5BC6D7288C4C44538FB48DF3B3B6BC23ADE01F904EC9ADE1AC0ED286197332EC4006FB12CB86F85833B20C3C3FC75A76C383A418447386BD94C28098077B7C445D9E266DCF32D1058C5354F2947505C46598D152B41D10BE6463820F99513FD4397252D12BF6EC17E16D29FE52225F0343758C9E30A88CC93E8431606C8028FEE03786C4B012AADFE079059D3E335300A054E6581B80C813353C06B3B00E0962840D70353F500A1F3E38D3120653F1E513EBE523C3EBF03B41200405007B0B5053863069C92021EC500FBDA81FAADC7BD0CE01B1130320780A6EBD6C7FC21401E02C8AD41A29D40220ED0D318B8C3FCE82007286200007E35D07F1ED8FF16B07D01D82B01DB1281315D40892BB0D80D486401A0E91F35901AFC70037B546007A424FE4B733F37FC71CE00988C132019C6A4206161CC5AA6D63CFF7BD1EF0F1031189698706E6E24845DC08F4CD2700385C53E3E494ECB9925DC273F6543696B9D9F501BAFAED126A2F19B6B113FFA4B9C9CE71101065D30B630B059D4C573BAA1083F709A50AAF65190B3F4417908271A23D9CF42D1449B579B14DA2BE26807E006AF2451A884554FFC74DD59BAFBC1B9DA9EBD789EE80FD7954E49DAEBA3BD0726763394A5288766CEC79240D139B1A0DB7DBBF1472C496DEF2DA29BC0ABC5B0F35164418B7C1B98D64446F73B54FF639C81F18249311B07A49E6D8ECD7F7A7AF6B7FD352C62BCF56D3785EDB2514AA29AAFEB808A8D920DE5F408C1DF292C694D80AE14E5526418BF7562DFBABAD5BA3C55C8049585DBE5FACD48C4394315DA5845FC547779C5AF6C0B9FC37FF2979505C235DE17C86BEDB722A8DCBA16B60D24735934A4C3F5141CE9A6B05E8D6ABEFB12F1A39FDEFF75750F690B0099A98B805CB7832C111D9EF90A8DC65A1E18F6EE639BD9ED476BF07BBDD68A772A24C5F88322BCED6DAEA096C50D8F743728CF22DB6F9E39134CB99B1E2F9447612DC8E12061C4D8CD6E22BC802E25FD7A038CC26E358F03FE438C6CED5B16CD89F57AF67B2E6426BCD792FDEBE025FD26470C92CE6C2FFBBF3B14A2E9BA01E6708388050BBA2CC196B0029EEDE3B47B1D3AB9162DC6D7490C97F4BF52B9284A9421472F1FF2301B7F17056A2F5E42D3CB0DD8BD1DF505CF3EC420C78ACB01B8E9BD932EF2B0F2CA5ACFB24C1CE19C00CB5D6ECDD93118FCD172D8764538E88A46D0B7B12F58E472C7429CA45F2FE06E24DFA20BB862443B3440EB870A62B84D242B0469AB0754EF34267E8CB22BD8CC2FD3765A037D13FBAFAB79F465A5C5CE8AD32840E245A7F08A24795913A13D0DF516D7DB71E559157591613F6E70699378D8A8D9019DCE7A40360305D1C866428B1B3082C3E110DFF787FDD0994843A482C0526CB22AE598530CBB939ADFDD235CC80DEE80B218898AC0F71AC1A873857FF22246061B62F4FC3D2EAF8E8C610DEC5CCE436F98E69ED06ED85D7A2E7D047595D1A1314C89AEFE6142021100C7F8AD38FF4FB0B2DBBC67FFF70D8DEB7F38717883E36008150741C2DD8FB9B40DF372B61019D0D5B1131C2A641C82B2DD4B14A672C9AC4FD2111281F3159FA867AE23DDF57F9EAAC2787F1DC569875DBBC7C52ABD6A440C82213BE3271AF33D3C3DC0E8B984FFC5346D15D7187725A0696BA878BB6BE902686CC532B6F1B9A03B52B82F8F06E0EF85EA91048FD7A112E826AFA116CFD0ED251C10CB3DAE6998C61CC9F8096826DC72707974E593523B1500FE33D1CAD552AD4DF99C930D929988295CE2D5EA9B159C798E4C430B0C7E841D2B1EF7DF82FDCFD532C1B0C56C013E7575B052BE77E29B960601461BAF2692BAD5FDC59E06334C1DBABF3C615BD7A89ADE4647E28CFFE194E88934FC95BDAFCAF495D02EF743B6DF0FE86E028945CC81660D59FF4EFC7E96F6985318776CEB5EFEE3F75F5AD69DFC83193EFD456CB5D96281445B3A6EB46CCBF94FE2B254CE9799F65D0AAE93478FFBE4B14441032489A53FF9184DFC60B1F315C9BDD061737FFD6E7E91AF70BD742EFEF089DD2F2405C3AEE3529AE2CFB092831F50ABBCA97590279FD5338B1E1EAB4E395C8A60920F46788CD14B2B75F44F5CF8C38D65BF59478E84CBF82706B8DA7B6732A5502D0BEA418634F7EBC80CCAE357EE9F233CD24FD132B95411CD4AC7DF903725AB8FB7AC01A3ECF5BEA1A9D7149034F178B4CC3E2571088E3587AA4374C6634A296051FD3F356EE0613213F6084B18020D971AEE8333F9A7424332FEB59538FC02B07F0F475203A36E0EC4343490155A86B52F6FD4BF49D4235CC62D1338727729CA952AE2432AFB74ECBBB0AAAA92369C6E9BEACC76F554ED611699EAFBE14F435E55C61FB979D90E525D34A21BEB8BE2C3394BF4DA1EC9C2E43C6A7501EA47833BD1F8AA34F3859FAA8E2D1BC92F73560D3D5A0E2BBCD0446F3DE70505177660C783CF14AE7B51B001C85A20598E0CC1B068C2B6EBCC03265A1186A91274E3DD2EE3E13B196F8A60AC0A19CD231E93E926CCAA92311E21C58C82B9BC76070D0B54CDDB72A906BA49ACA30818839C21485E3093671CC8A0E34AB1A4BBFBED9414C79BC1A94715CA3B728A276D85834497A122E342035DACBC3CC96D1AEA9DD5AAAF1D7649FC62F98BBF071F1E0914F6FB8D561F89ACB6856BD8904D7E21B863ADC3EA25E6BB66D5221BE1EB9758109077167B5C41059232E37311A5EB66F5CA6060EA2A2D28C6BC4A839654A64646A05CA9167465C6BBEE05B0D42E07FE36641666EDBFE6C87114D3B8C9F0CFB787B3CFD8BD408149DD82B54FF79533C976956CD24107841CC591C3C12A0614B25B2DE1EF0EE537B0D99B3AD4EC09E4A4BF24849C1BCD91BEC18F192C9C88C6ACD1FA3D2B553BB606F7CB85D16F94CB441AD136D1F55FFCB669C8D2514CC134EFE3924CE3034B19311B218755D88B4643DCD576AA0E0880D1FFC7CA815D9C44264C0A9F46075BB1AC3F0292CC43F7309064D16AE4EE5F8E681396861889EB76B7B37264E1480B68D9E335351D74787F173DC96FA9A53B4F9BDD53EAECAD579776B6F4BCBD66CDC9D0CB4836AB7D9ACE1653C50AC8C5CCD1ACFE082BF12AD994E5190D4C0F09AD4038932F943BE2A83CFDAD1BE5FD05F0F201110B2B17601487C9CAE0485F9DA1EEF2B631274C0BE1209AEE548A5F602C6BD49FDA1F0AF47C2D25C4FEA4693DA33D95DE3F91958B2B735330149601DFF6F1306AB876C4FA969524080D50D80F7B5694BE594C05173899A3BCF75EB90E68355B50C92C3D9B1AF2122A965A506232ED220E35E853E0D828E8B53E8D7EDFDAA0951BF2A05842AF70A76A2B3149B3C66825265F2EA7521DE0A162CEA7C900C586C0D019B9D5772779A2E991D6BF2D1960C610952196319EBF84B6339E9B404563C4C342E0C5FA1A3CD20DCE23A1276B5401C8CA20A8D72CB0012BB4465E289D2E11FD60C062B07C35CE533B15398AD4166C858D3F521EED6FE826DC8B9BB2E0C72421DA050454F67EFC71F3A1902CD4A7BCB676D29A965A0A09E2E6E014AAF68CBA2A0D7846FA9707B058A87744A89C0BA846AF989E2B6EEE53342420BF6542B4228AFFDCB42E206E80808D664C97D9868C61FDE85BD13897F6B0BF8C68075C9F010D2B60C2B054AF724BC68545E7C8BB0FBB2526CD1AAB8291B21BED69CD101135AAA12A3CD5DAC720CCBB438B1B1482C361089E0FC330B132D27E07DEA059EE72C4A9956B68FFD3EBA8BCC477824ED71404D79C0809532F9D5142282DA98664A81A0F6D94014C28065887D19C8D3F8C2BC47E6B1064E6023F47AB6539CB671AC74351B13D1FF61E3746D39FF730A76FD20800362CDD9868FF1A89BFA2E941DBD7B713226B13F2887CE5F4BA58A9EEBA7CE8AD0E28277FE7759EC9397B2137068C0AE470585A1490E1E3146CDA92934A15E544C803BBCDCB8306FA39845FF6E86470074478832494A2598489BB4CA64797E853D3C638B4C5136375397BD388150E2EF4DE0BE6A76791C4621990C2144E94C439FCFB35CF04B8B6393905F33EEAC85C8704695132DF2DCD8AD10F61C840573B44B51084DC63B5CC3488A4BF135E10EBCA413B3353400DCDFDCD94E0475F20A18269DFE1EF2AF56C9CD6188EFB152F9327639E98DC2A8DEAAAB2D4CC3FB4B8CDB9F4FACFED06CE6C213FA14CCBEF3E88DE80D9F9254CCBCA2412078456539BF88D12B9CAC8CBC6A5C5502B9A59D51B680A2DA01265BBD1681754373A13A187EFDFE6965687CD277A5748375D3533733B2108FADBDAFBC8ECEAEB63DA372B12FF548CF28D718B9736893E8A17A82BC7CB9A88943D63C900FA4B71219F2AE9ABF482E240AF9A6EE5593376D5C1CD4F8A220A81043A15176A4464A6867DA16FA24858CAD703F97D96A3DC93C52F3A3D7836677B1F18AF013D6BBF86811B5D7C68A4578E702D0DE3A8D8A234471CA5757FCE4AE5B3BF55892CAD79A8202E2CBACA63CCD1953E7715F24494359AB7A98C09BA375B664237B40E990E084087FAA477CD905E6F1BF994033D8004EDFF2F0D49A942A111712B92771F8814E95FED1FAE71021CD74C9944AC03DFF3E3DDDBE6DA8AAAE87A360F066ABCA5417B26DACB2ACCE0D117A5024795BE811194C726CB1F37E9658F5D4181A45DBF1FA0E48840AFBAE8E90B6834847DD5765139029D610BB2F22488580A7D9B63824839F0777D39A161314B24D0CBB4871FF4E8CF4385880ACB691D649DD99D7E5BAF8150F55377126279563F377DF13FD39D46552D580F458FDD1C5468323DCC70D05E9DCE263B9E2F0DBBC08D73C8B8A895A801E6866CB781837E7F4E0253A05713C3085C3E5878E70934B28DBCC094D063B6EB1C1515AE6AB4E98C6CC5778C8608C62335E1805E23D79FF389E71AA4DDBE4E5F5EA1CC4DE9B8D7C36B9236280D272F79A91CEED16E4C85A2096EE5E7A8569BA71D559F08061EBE4AD3D8C6FFFA7F21AECD1C12A4FF278C861F510C87821B5122ACACDEC37CF6A4CAC26A89CC3D948CC9ACB2DAAD1AEEE7CD83F3E1F1D8E6F24743123F940D20808ABE901F903040BA420D707148B3C8FD66F379C53EB001004B839528C8F5CFBB45050D3D1EDF22DD77BCEF18353C28B275623F18C0209B40CCC735CE2232FF16CE85F7CE040E47D6E5184DB96E8C18F1BD78164F01C0B7A50B63BC42A45473A648F1D5BE5B34811BF718ADA6DD14846D289F950286B7D21488D765957AD72770AAF72C1AAD81B9A418470E7445E1AE4100963EF3F25E207F0FFD8B49F881501FCDFF14A5F7C10A3D2BC532B536B5CAD2D6DA0B34EA10A3E036B9718AF05165AFFF98C98809F96665828C806CA4BB124A1AA237CAF2F1E437FB82A0021AFA9AA7E8481B9E2A6A18C8D446880E987FA4963C081786418571842368A6CF8629298AA559D1F772E08EABB5F9958410DD5333FA2E93CF180517A775E06D43AB83320A6FEA4000E204E50B7CFF6B04647CB233742E9AFCB02326CFA5B639E2C272C796C6B6D96F2ACFBF22EC7D5A70BDD395F7B4D6E33DB68E43190062BE394625388A17672D7A697C5CFEC19D7ADD0587AFB07949C89A068B0D4DF580E3709EA3A9BC12BF8A653C648C021FBDB667AA0E9322694D4835CF9C34EFD7E134448B238751CB7FBF93F85785C618715E6218194487719F8AC3A4B0F0DDD3201E9DE10A671B0FCA51AA8E0550160726C4099DF1C11889DD3AFE8DAA70C48C609A5279FC9C1EFC702E24F439EE6FF220F3BF550D09A5EE0E1749EF0C8E80BACED702196C79B0037E415EF3C6283A2A81DDE8F9BCF3D6AE2DD3260AD26B1D470B05C3C555A95CEE1440DF68E02EA1B5E918FAC4A98BE382DF56EFA974FDAD0C2159394BEB601690CC5FC83B27D3DCE30D38086EA2DF59A687DAECE8C1030CDBC3969AC030F90588846546F3A222C6B1C1BC9DE157F6746D9101FAEE43F56497DDB4679711415C8B8AB19BD7143529EC38F808FDA0BAE07C022DF37178385C9A73F73F3C500D046EFA3CC973A6BD05200190F9F2FB830161A48941DF1E43478E62B5E961F641171AE22D50BF8182F73FB8E3B9DFE255EF01BED14A8CD231A61BBD5B68DF2FB358C72C8995E7C81A9902E12AE10A922DFA88B024AD3F4A355473E22ED3591E3BD4CC6E1C25DCFDE2FC813095582C6A93174FF6C646EF1C64B762DBCFCE8DAAE825641ABA0FCE7A1E93A72285FD867964B0624977183558747973DD9CF2CF7C1A0B6648B712EE056F50DE641A70822DEB04860AF46544E1AB3500C63CF4F733FFA754DE7A8E9C200F83FAD3B0FB5EAA10CE85F07216C1D2D55F14351E41A73E64C037D652E7E66AD557A5F1411B4B8353B74B5016A49CE92ECB70BD497F48549203F40C3AFF1D8421B33814AC5F7015744B9A17190A9D6C0B992D1E03F17D19538550BBD37B5634B4D0588A83921A8C6AD1EF2677B8C6CEE49D6A86F127FD789E89C6A8572B3A445ECB5D7C43F73886F2E0003CC2EE6C3F4864C2B7047F239A05D05B5A26801BE2561D68940D7115DCE0DD895379E727FFCBC3D0451FC205B3FF820CCFFFF5C75305B522A84E4382016B1C77B1C98F67BC4C98CA0BC21463F870C546E0B4F2EFF4DE466D8CB0BC39B72E9D37F1A0576E2566719DF21A9AFD7BD0E8F3DC1BBC0258DC63CFFBFBD6AD3ABBF5A259C77771508D16AECD063E05CAA77A4854EC739021FDCBC35E58FF4674D01B815D4659B0FEF2EA7E90BF0A03B78E060F7A7867815442F82189121DDFEFC29F431FEF9ED428A4DBEB384D89D000935FB938A06BFF47FEAE81BCEF66D4E07F35E169D5ED68EE5A0D2C825F38B5B9C1631BA149369D6279B1E08F325D81F2380716B1333574C2BF222E40096D16D10E7C9545457AF89800B3D756063A17E4210FB4ABB8B9CF4FB2BFED8C501EE55A4239E1025E22092CDC4C54214C9C3BB6138A927F654F21932B3DE394BA5F4753909F4EE68542824D704D1F4B4269DF29F5A36CAF2F1C579592E66F331A6967F14A6EF29C78F68F02F7AB2F8AB43C8A41B415B24A0C646250FF64A8AD162E650395571513C25F792B686DAFC34AD83EFE35259E1606A7FEE65CEDEA165B02771C1049458EF429F00B889F387086E8CFFCDC752C497199D95C8E2A485C40C232871FAD5CBE4E891B3C497816D93AF3AD43A9676220DA947C43D1D8266D5E397D998848D137FA66D67B6F304CFAB24939BB0B132460291ECD4EE9843F4BD5CC1A7BE48D2255E2860B0BF94C4371E780B582957BC9062D8FB1041E905438773BC7D1486C3AFAE2B689FC97052A6A904CD0D5957C63144E4092C79E94CECA3F403C27617647BFD2DB661C0134B0914A12084F326C3A4639749C91458EC8E011B52822EBBC563E9B1EB1FC9D97FEC94C08EA85B086923B84238D599984B10AADA52183A661FD789A59F772AA80D5F040C88E9EBFC50DEE000F379FF6454398EFBCD71FFD50A8F449BBEF26A615A92246C3D444F992727177452063F17EC2E2BFDDA95E7A858B060D9455E976ECC744461C7FBD75641C6E48A883BA061296313139B3BB4F2CA32C1A847E138D524D314D40FAC41DFF7D19DF08FB64DC9DC37F9D8EABD3C515D6BD41E6ADF3E05A84DAEE9BF15988838C4E6963CFF061F9A6BB35F37F298E53C3F87302610B3F6EF290A45EDC7EE8602963741614C23CD132977BD1F6BC1159A2316D6CED86415E6F2FF248EAE36772E2D818997D174E9467E7EFCCC9B6B1E0FE60805F203C85EAD1CF1A97E82EC0BB8D46450451AB4BDBD1971733D3403F4A8D6C1F40ADAE3A5D18149D45819B11D992B99DF21235E1C42B5120CD95CE6CCF94D7389629A7D8072C1CA9EE6A90AE5DFEED4333001E1490D0CE8F68BC40B48B02F99210A94173ABD1B67764CCEF35F9AE7146303A8736AB2836E78FE5F2342871BA013B7FDDAD5001DBFCDD4488F2E63A050DE1E33E21E0CFCAD30583A245EFC950EBCB80E46FF974B3C7A4B98E818104BDB422782EBA41A25A3B6E9F3E350B8CC6FDE63E40A9144708B17D542158027BF49F0D772F12D85ECB6AD1C8F17F5ADCDF8E0513F0898F2EC732E379BC0244BFB0BC3BB0841D380AF4DAC58AC0C3B5D7A76C907DBAC9990FF0CD8B54F0CB1D08C188E484C672ACA1186267A4E6DB77BD92961A42E282765C50E641E8405D91C6E9FB4DDF250508A20DDAA7C128550908F0E94FF03241BAC08991B09B6DC24F1BB22E64D4E247B3789B8D72AE755CF33E53FCA103B008EA4C937FC6CFCF879C1BD14FE78AB3469B72EAD14B36E412AECD18DDCDCB6C88F139E17473879BEF827BA5E51F8573227AE289EB7B325219FB6E59854A283FA452210AC2CD7E812528CB6A0F306CD831557EE7CFF9B0A3F1FE075212C2BF5C43AA840E59E800A1FE55A75034C19D35DBF07A9DBEF78899682794F2AFFDD385BE394D07039273E21786F912119254FD86B65E7809463BDE951549173713414497BB7229E319944A4F7ACD34AA77CDEF6DAB48D6FCD396589E2727B7F544BBA17DA0E64D58A6E5E2902729266AA1E6BDEE50A3FAFAB6658DF3FEBD89262C2AC8F7207F08154C342865E4BCFB444B05F5AEED29901802B12FF259C697DBEE355EA5DA5E12E799EF9E5632B3B909878070E7C02474C6032441ECFEF79CD7D79A1DF89FB6087D67D2060747570534CF919D9AA873AD6A12117CFC3B946B75E3BEDB36AE69EC856AA881F69780A04BA1F51F921E62123AA7CA7FFFC7236B1C6A7FB833F001B50A348989A805CFFE8FD3CAB3FEC67F97D2037D88C0BF2CED07B7CB2E814FE8ED5DC577F4EA32335B0D37876BBB5ADEB4EE6FDF4EA4E100C67A9D9D8E3E8A9139760EF9812E314F1DB3338635398E986F3FB7B1CDBA2B5B401FA0F71C160A6E7E98CE90283C262DCB1D149A09FAB87797338864CF96C73706BE3F6DD57F869DC21D6049E9777CD71F0C2CFDF53EA0487EE941DA9BB33575384AC4FF41BF1FC35B979D289821DB9EF1BA0290BBB05BD012629333203D2785ADEE98C0F5AA5C48FD44FABD19DFC5AECB44CBFE01BD9F2E4F0D49534D13A2C8994731960EEFB20F22DA793079F8FF3B1276F65C5D36EEF5D6366D60F897BD1F3EE47E37C6A66358176922A529B06E92468366117CF634EE9C8FADB87506F0C6BA63291086BC46A8977AEA2DFE12D9F3FB743714B9D3AFBC4BF365D36ADC71926AF6FF5A1804F64C43074FA809C38396ABC4BDB840D6666798F97150CA9F741BED8DB1B3C1ED16B956834676B704BD4318F4E03E8545232688D438EE31065DDCABFEFEE01005CC9D5899EB43081479E0F9EFFCC3C86D90C84155EA72AC997BD57602089F350EEF7815EC2B005355003DF1BE3C1017BA60A39A4204C221F3E95CBA6028B89C68F74035D5E67AFFC6894920F49AF087519245E81F0F2340027CC0F2570B230FD1BBB0FC449509671D42D5C526ABB4E72A2CCC7E5310A34C9FD97A7C7DA387BDF88244A593DF012CCE01168F496C2E37645017292A393ED3BF6B588BB97FEC22E0B1691A741B041E439BE80EE77D75163002EBA7C0AB81A7CE648C45F38825FE208A7FC30A72BBD9BF9EF611E05A72897FF2C65783D37F6BA1229E95B106631BE4EC6A28925A6C8377011AB0B00826720B379768D78D9B135F1608FFA7A9A0CB615FF958BCE3EE865EFDCD9F1688751B8F66F8D798E31C2369B7B00BBF2F489535E927D95D95C19F2E85C36FF51AF3E4BB5A3261F9053F21D6D14BEDA24AB63F44A4362673D2BD458833CD2FD8B8F96A609ACD74E21FBD6D44F106F326DFFC2A5FEFB2C3BAFE05B5413F795113478C877EA385264EB744129E99280C0C8946082A2946FAAD34A575987232A350BD3F68DFC7210ECB0D7608EE40D3AB56C429E0EA3672D7B4A219EE0F226B39DD906699A69B3B296B43E9D36C70FEC3E6D0C4C155FA6C7B70678A40F2F2EF8B222D0FD31E4FCF7875EF0169A23DD0AB5D1F0FCCEA19079E153E0511EB17042EE92884F799177AE8D8CE2E3EB179CD7CD249B9F1FFA834D8B7D08AEEE034D478FE35C34FB4AB16F3DED329F451A5EDB6F4EC8785220ABB80D39CCBBEF005CBA0D2A3BE544891E0CD3B50855B179B3DF9BC06BC2A90E1C1417F1E751C868DF7B54A2DDF4C8AEC7DABD054A6F73C9A2C67CC2BA86B41E513C9434CE11D244647F48511D14734E70014DE7904D8D9C2D9B5B6433CA926094E8688058B51836BBC679F827DC1AA99EBBE9ED171DDA6AC4FCB53F235E9EC60C61FEC6377B985AA006745FA0A777347B63F97FD974546511A73B705FFA260A9F9004E1AB13B7C87435F6B374589F334F9F60A4DE71A043265055B931C1528B58ED6DDBC917356E9F83D19A9AB5312DEC6EFC464F8584709C3CAB04EBEE1981C28D83C392236E5C5F38B79B244E446D65073E7301FFEC2977FE3FBBA71DD36229A4931B1061BB0619D0942993747B2C4C707BC7DC11EC78F94B1FFFB6BB76CE581E3C9FADECF2EC33B62060D1435699AFECCFA073E89363DAF445C9CACA20252A68225193A95880ADD863C4E581BB81FA0592EE94B947381852F3A3399AF7249C7966FEBF05AD447DEBB4112E6315CF03AA6AECF708DB72F49EC38A8577CF878C2E76DE7BFA6DD3C340CCCAA465E697AFE34AF4189804914F033039CCD7944FD6C5CEFA6B3BEACCDC717D6FDB1DD6A5D209728B6EECB706224857A4194821C453B447A3357897488A044EFB1CB7402AD5954660C23BD4834BA34B8AAE297D6536AAC9EFB1E2CEF9BBE27739E26FF78E0058FB3B9CC6F67240507126F51E61FBF4946D7FF2F3F9EBF2423A6FD488CB589B90C5BB37093C24254FE65B85950CFD55E4A4EE7DD17721F4F66F2AB2542DF1BE48FAEFE4A059351E240002ACA654E24758C597D8DECDF7454C1A5BAD0FD56BCCB2765C361F02CEBD294FF404D1A9B19066E137DC02EE45AC5FF6911B1A5EA0981B5281BBFE1E731C74EA579F5D7D082C3A55D415907E4FDDD1F5924EF00D3D30BF2FF0A44906F782443470DF09B47754A8C5BD7C5565C1DA0FC3753954A70B19E3C3B8E9F998BBAFC47983188BF1DCC1AC7BC058D27570B4282A783AB14DA34E1653C3EFEA7A2F4680843C84596629E01359C2F918FF0679C13B71ABAE62F350496BA1DD83F4158AC3032DC12C08D65E306D480EFF60BC6B69795A5211B914A951CD2DAC22DFA3ABAA670238C7AC6CB64C1E15F5959DB424F5CD08AFA502FA81A06D1531AEEC59D06320C48084EB36992D1E57CFB518632F510B17B30DA1369F92E1DDC7E0075A05FF7CA18E65A92391714B2ED50F8EDDA157927DC7E750C9F218025796D46DDDCFA5081CA3E2D1EF862CB62EF35E4F64A23CDAF53C30179E83350CC2FB9282A65ACB20820E0DA71D8516B0E3166EBF3789C704DFC93D3D5069437266C178588CCFFE4F27F1E8B6A39F45BDF384D4C9F8D071577902485E369169161CE2551BFFC0DFB9094A815651ED7FBC95BB8E179F71834FD27BF5B2CA78B288C1C9B9F161EF5341D12614D189618465915404A31A7D2D361C7E5D1C1ADBE30FC37C84ABCAD428FB892F44A5CBB57ACFD87722193432078B6121E630AA306564107EF60FD3E8F93DAC59DE199F88B8F75245A56E88EBF7A70816E8F409FDE0C4337BBFBBB7E10A8B56E899286C3FE8361D133CB5FAD1F0C385C3A97617EFC2014CBC8C03D2092B83E760F70833226942BB62EF2D5C61CB902E8057CC39F8785A2D7D40A060D45D6945120AB5CE8964C3ECBEF233515D1DCC16224FA9E09BA8481ED5D550E1DA648F8225C9C32EF5F5E91E2ED62FB4347625BB0C940D58A906729142B896A7F5F39D93C27756B8F0BE97AA50DA15291E628D7AD56FC1C257EE4EF0583E67C458EB573C47F35B30015C1FB92A55436DA56F8509BDB2A6209930D58F7D3B2C012E6AB72983FAA0BE73105608DCF200E1D4BFFD3018EF439F36ECEC0949E6E951E7239FEF027D541ACBD16C60BA04DCCFC2B34B7351CE6A70C5A18A9DE5E1AACDB65BF641CCBEDCF3FDC8DC408A33E184370FDC1ED2946D9336D998ACC7CD8E3711BFB16B2C60B5FF1BF59E3E0B1D4BFDE076D6347591844AC1EAF51FFA18C21A4FDA7AD87790F1308EFF9AE8DA3FF09BF0CD3009B8D4C68997F550AC112F6BFF75C9E2102E5BF8A9FE791E2D4FD9DB385ECAF28068EB1FD8FAB365B68311496EDC52DF2767AEAFFB08922BCB2070D350E151F0EE26B844FCE30E056D8B1D9DE9C59403FAFE74B41C6168C7FDFE904B01465FF1F2963A738FE71F5F43FD534CDDA1BC9F13A1BA120ECAF8A80853B7FE594FEADF683E219C7CCB8632A29BBC7B178C75096246C38E3B464661B56DC917DF208B473DE500C2520F8DDBE47DA7CDC6FCCDDBD44D15903B8B75F465C934DD5E54D3DDD07CF7D3095C6EA9B0516B5F7235C74F4DC2FBCCDA1506013B40B883634D8157491FB168981F44E5A69F5D0FD2EE7C8F596B018B089621913382FE47C7999654267470F0C7C378DCE9F69303EC84A20F6BA010CC1F14899240A807C20F8D89B4CF9CF6D1301B906C9E6113A1309F9351301ED1FC822CF9E45097AA64ED431E09582D0DFFB8AFCC3D818D9899E5149283A3A18CA103A8CDC90E01B9E92A70E1C5A1B33649AA84CA131D15ED693F5A4DE80E68CC64E9F4FF3B5067D78CF516700F4F3601D79537B17AFEB6A22398F9C0CE36FEA77CC28DFB4CE0815CF8FF5E2F2DB0AA03DB4B10825A598B03FAE42769CC89D1489B4E58BD9DE6BAB697CE4EE7725B1D45318066F9C166B6D875036309A573E7D50D40D374CE2120F5A78D44A9E83F9DC952DBEA7567590B3624D1F0E93C7920BD7B48E643F9B504F1FF4773FBC50BA5A4839A3CA230E275ED3936C31AEEE28C8DBAFEA441612B3CB042C97BF4C72E9BF5261906ADEE1B0EFAC5BBF6369AB4C905C61AD660858070F8DC1D4CC99373453C50DC8D750D72C62AEA6EABD9B206EA01AB069A3558BB461E51C91CF4C00B1F2BE4FAE08D8DAFD1DED2ED552E1B21AE7D284D2FB1507D05FE92F7ED8FBEB52A40B41A56F86094685A2F00787476B289BC9D134FF9F0DE98A957954F90C6A103907C4AE41B23541C1C5892C8E46454C9E230E1D0C1411F6BEBDF696BDC580C6A62E938E677A88C91B1F411B9C6B15FFD89E7BCBCA06ECE3FF1EC718C41FF57067B7FF1291E65A403B796A83FD9ADAF6CE44EC57F6EAAF008C859B55113E2C33592A53313DB6E152A55C0B176D5F88B224AE2891C0CA97598C788AC600EDCF7C9164933EF507DC2BEE0C1F191A8A98915982319D78E0DB7EC0EF044D71AF390F47D6171BB61A68766AF5726D9D6E3ADEB92F65554CAD0EC878108FBEC920CC15530F0B85E854AD6970A512D270F5D2B1738BFF73FA28453F47098A04353036B406B75B349BD4A5F15A65DA7A8AD8CD619C7863E9C8D4C845B46A56853B26FABF90FAF38A1D74B8F9B225A23F1898863D9AFF6F6A5285BC7BF6FACA849B13C96F6A5F489FB2B4F283C246F5E44803605439B14F63B4EB38FDBE851338E2BDB80BD73A63C7D05D81C1505ABC3B7221C1D1AB188479D9B71E1FAB241C06DA4BF40FE6350CC30129EDBED65DA61DA056AB412BA7AFA165766EDBD8AA0A2EE61E47E754AA1E83DA14AA36E2C46E15E7E3349EF35630E4C50ABEEC944DBE6ECE3F4B6BB85A3422E9EADA1535C1D7214439D7CD2675B9090170FB0937F4C7A7287907715433FE4FCE7C74218F20E6D14D61557F290AA2581778BB13925BE5DD77233026678CA97FB7BE4D0CED7AA91A0D0102464ECBC609F39E7377BE11BA7C98A1F8C504A9B9A8E708D3EBDE1C4C3DBF897001AC4A7DC8C400FB341B3CB2FE8D7843B7232ADB58832B44F532F26AE1478A1F14D60EB1C04885E8FF7E5739EDE879DA36898B722DA298FA097255A35D6B8D03060D3390E98897EDA38F81C5A68357B93AE613FBC529579A5E15CC2F49CFDA5F6B9A79E68D4474F2887F69EB79673BC7F064F05680781E1ED3C1B95E3C49630FC82B8451FEF9B8D2ECF7C1AFDC4329D245F40C7D0821407CCAE97CCB4F5D92FF759F4AA1ABD867DA3A1A68FD3123D82DA48B1153D3F7D4957190453104EDD5BE3A788C55E8898D271C9A44C4D685DCC5DD694CC02E17DBF4AB456C2B04F91FE904A374C8A226B4A8F24CA4DE46CFF1B973896D8FE08717E49ACB810023C09D80695D3719D98340B4B14E1E86881E17A617B54B60430452E9F2726FD55EA6032A9846EC29394377A78634725EE92476D204285F24F1B0E0CE86A9D0ED9EDB7C90D226324BA221724EC1E073EC6042B90EEAB1523A634E5AB5447EA71DC7A81A6EE139BE837D46660EEDD69A130461693FDDE8C73FDF15C062FAACAD2C7C972A0501650F02770888F2DEDDC071F835A78D1F61BF1ACD4EC1E2AC136B8D31116F174A1B44F7B85209064E945B7FDB52F10FC7D17A9C739C439FE09B103F13A556436B2FFBAA97ADCA1700DEBA76C27F68208F71A6A17BDE538632871D5DCD9DD69EA5E8D42F12720C36B769C4CB339C74EBE752ECF59B30985A6861943AF66985054B550E0933AF0CF4DFBD4BBA14FE48563EEE077780C36523A1BFCFEAD1CF3EC4FCA32DBEDFA0729B16D1CD8CAA8886444010B515688A14BA508F190CBABDD47A5B98BAB7F6836CFAE56EB309670CF87981689542E375623F188000828AE412AB4548CC48FF8DFFCDA18AA40D3A4C14F5584C654B7578C0BB48040C824EA40163F7ABD8067AB9DDC8C81007FBFEC4C786B46AB106E198D01A88DF0153FA8273B8B07E23A3660983F09827227C0B5D2C44FC96EECDB41FCEDF5E60C5C9D0CF0F58CCBCDB31AF06B74EB21D2759BF3FD0C87E0F3673AFBA6E070C7BBB575854A403E5DDF564662139327453B64B272FD078BE431FD3A4D53455A7B96D8BC8302E4140413412BFEBFA2E215887A743BC40A1F1AACBF4F2A4083DFE720A45723E0583FC69F73FD8114B9CBD8ECEC89623B287609089403544C52A8024608C0D6572472EC27DF83683880052D9D1CEAB7E8580FDA62DD178469EDCC3DA2ACB15CADE1A28D661160F81183FCBC1F7D947AB45F2C1E02DC3DB1E19534F851BF04C8347C1AA0C35CB0062A5AF06EF764A700BD007BBC51230D97148E355538AC6F33EAB7DE161C0D3410B987DB4CEEFD29B3CA391AD9812354B21208ADEF03253D922BFBB455C5D9CA00843DD22DF0AEC3E88445E94898447EC89A04F9F6C32973856A0A88D9E5B29013291DF68A4F145101D570B412FB33FE390276EAA3AE487219C8847771255DB8D63F48400511BD7F1BE26CCD9E24CC3042AEFDFDBF7A3E1D38328071C8C32DA65649DC29A3139F6D312F3170152A877465B61398BB0FFB8477C84571A76539A324843890531B2FC7C03759A6378EE0A02625D892407FA7AE9C40431260F263F07A2907D70833DEF69577A572B50112281AEAB3F42D006509708EB44B1F0627427DA8EEAE9477C74039830C368D6BA88F880F71146D8F7DE008CBF716D95B69A1FC0DCAF9DA78086BEE06FDFA311E256EDB5945C46D0FFF9A129D5E194FEA16B6142888669D60214966E289504AF59019237573207B1469270E1085829A3F1600820371F82412822B61D4BF07EEA25B238BB8465D94B1DC9BF088A761F3936D5B86A744A0CCE0A459BB523C28D80CC3F017002D4B830A87588B78A4C7BD33F7F996AE2D42C02024C5C0FBEF897E574EFC4439398435A90C0A743C20B829C3575291F845B4A76ACBBE0E39B196A618A0FFBFCEFE685607A4D0C8B3F878E3785C95EAB963E6B9ABCE01C91E2F670B2B5ACAEF2DF87A729DDC583A590472CCDC82749AB4C0A05ED7B80629A8D5FD0EC5B39F12BF9F0ACCE22575E4766683D7A5479FD76495F7B64339A69B9FB803511F4BC14AA83E1C7BC4D37460335B4CE2FFD68480C44D816EA0F06385BECE67CAFDA2C908FB3652B64F926002DD0B926F93F29704AE84F97B585E58067F4E21FB832D2436B1CA3BBC3A8ABEF8662DC8F244D76F8BF8A66F1467C49C31333922689583A8925153A107A8611A0E3F6A09DB3B64D9FC83F90EB5CD02355B29D9575168F6AFAB39E5AEBBD5E60B357B702810EFAB193FF3E608C2F67BCA2491C707EA74E946F7AFC5C6951676752EE0BE5A6F1D77D932564C5DB325590092D8E176317D5F19EE8DF2A4D808B1ABD2F510B256C90B35B39EDF81B5AE2D3448B844F87A6C9F44C12CA347A55B1B08A2DE06EA8726BE65474576A1794C395E1118DCDFF470AE3EC2703E2EE54BE4146165762C6BE90CD86512CC4B2434CAEA39792A5F37E77C8EA5350FD646A72C270BE8CAEB7625FD486952860FE031959CAB7641B0FFC7EA7A3DFA40CE53D20820C454381310A2C228670B357DE1BAE05B52588526967AE78E9F6792867AE693C2517DBEC0BA238D107EA059D43D97CCC0AB70A9DE27D4C0D39E88995794E2F6011329633E3DB7F2A1CDB60B99F3A399698FABB505DB97496B3C2C404BF50BBFFEFF47EA1BE8699846465FB3ADD1C68AE4F66AEED7F765ADF9A0518D450F8470423545800367CA1845FAB74B80A1203E4BCFA49A57F8D174E30197BB2BF59E1B62264C09F1647D91A2AACFB7034BB0AFABA7AF1715027D5305E83E4AC59C5A327E17AD062E4E2761E90B178D665B19CFB49F12115B5E967B63C841EDBC688D6CF03AC5D6CE6542980501C12CB1B6B6CBD94C1489FBF9901FF3E4126AADD0770A49D094A2EF339009442C31EED372E0C8E4690B04FDEA0AC1CC88DCAD4DFC83FB238656AFE8A20C775C0B425E4255234CF61A1306FAA2751B2BE7F6943ADF0DC1EFCBFB5DD26D50EFFAA960414F65DF845BE4156A0D288B50F4FF8AEB982A4CD82A7964D27349318D731902A1C0A996A534F351112DBD35E86489DBCFFA3DE8DE1D104AE055120150F746841F2DBEFB609C88E6E4B4EC4D2F24996F2C0CA3FF2A2A4EC0F068663DA32A69CE9CAB93AFFB248A42ACFB7D92D7A3A443CB8CD6B2735A9A579DC02AE924CB2255FBFA6B0CF57B95DBE711D1352A4E33DA47485A1E5675510C443B13E6D642A95AF9C924A7A3B033AEEC7B06A617EE8C21B441E8B8393D2919E37CCC5B251CC2A8511266667600F6DA7703E6B8E8D473ECD8F0BE09D46F9CD14FB1B41D5438CB876C0A9782A9E0C927E1EE9C4336F1E1387AD03E9555582D5942D1A7D444B131E0589E4E3B192D6AD960FC22681D111080EC4CBCBFA74F196E422F2A427CB90A23B67A70F8098C620343420B640442A31E403F2F467642C0C6A9BB1E126581843B330B96761D6CAC25C225356310C78119FA605852A5639E9E735526C464D5A5C6D08B0D17366A15E39C3537A3576D52FB2A2A3FC5D51E594618028ABFB22859C400C12C0AEFEF935DCD5A6FB5B3F829AE5D14FD2F2E64D5F44B47C065F2BFDA72A072FCE1EA5B2458F5C361EACF53F3F054BC1D22D7E5A1282067A5E548EEFA754CB99F07864526A505BCB6A34A31F6B58EA9DB2F965C8278504DD03E1E24508568F43BCFB0775A9D2E36BFEF1A0AB1B8955381D5917B3EF87A8FF0236CB55E17F16C2E60E5613E52D3A5B0E48A72DA3269207FDA145D683948871A993DD9A0B8471A52E5FBEC5FA7033C1251A9B509F7C7387F694F247E5CA72DC2F9E9BA6666BCF72C518BF1BD0659C86C2AE0D26B50AB742FD1FE7E688636469EE013BCD3E2ADEA2ED1B1F7D22122B451FF3802CB2009C75E02510E0032B9B2A442D6078C5749E8512F3DBCBABFEC7C5A1E42AB3663DF11DAB77C14B212CE8A617D8B56BFDCDFAD32AF77EA941D69A3F46356184A05FB4C61DDE3E0C503CE0D37B24E7BEC381D6B417B0156F25012D717C648E2024F61A3706EC0475FD964C47692133A26A44F831AE792EA70FB178BA0FDF63B8DB399CBC573B605CC8A5B8DFCF42CD8CC359EBE04006FBFBB4B4EFB3ED09AE325B967B7F4CEA8E8A7B5A96847EB50747808628F79A1F11F9C50298319CDC98EA72A12F08A28549B487F2DD67FE25CD51C149139E7BF69D0F037A850E558271D57A34B372C6F92113EE5B59F2DF47D8A00D09609C7AA6C71DCD4301993AE58DB722C4F642DAE449FB0117289D04F34309D7EF0D223B9349080661C6604D1A9F1F43C6E7F8650386D230DB70BEAE24AAF612004B1083FEFFC900C37C76ACA8570EDB66C910FA7C5BF11B8C53F75309E3F5BC21189136A4A7B16F390C9271A59E8435E52C458634EB10B05020F0E338E1D95FB663BA84B23CA61421B8BDB80F1734BE589EC67A6D5FC963E53526A21727F6FF73B446191DB736D8EE31FF198589751E4DF675C29456A6588E52F6113837B4C44A2CE546779C3DD487687D80A5D31AF3781178AC601EE38F315A22C733E95F4B11EBF00D28EFC05D609AF81C29539B7749AE0A0FCD2F76084B5A4DC772BCA9F043258FA0040E094628BABF5F7A5A34425DC6791EB28DE63797C26CFD6020A899580946AA7EBE3DE0A8AC4E99616412364C32F99FF645B95EC43EB2941B1300755A3754984A0D85F32B39369E8D1E0AEE712B5FC00CA54EBD8965D358E12F4DC3AB45527F58F83FF6D215B2C9AB9B6D7CFBB810A412D03B539240B48A9BFF6F9710A8D19FC0AE76F13E8D7CDDDF69829B870638883787D55F5C2391F75B860075BB4D001FFF50011F453CF8EA8FE7A73AE312D83A4EEE5D232CA76A463CF00DB4CE0825880F16A4ED535D1A6844AED20D965AAB4A2C03D969C37B1B89E9356470FB81457C536EB4B2438CD6AF2D1C8E82D2F842127955DB0F59C65C77343DAD4A770DBF7411C5478463F46AD8AB35139276AE9F1D3876ECD39BBADB123D42088AC85801E22524A890BA18394B4D88B507E4D700BCEFCBA354B67EF0AD847E12683AED1DFDACFF7EC869CB6E37E3415F34F7D7DAC28879B7339D91AC76B9AE2D31A03E2F5F3530C6B563BB9C4B36B2A67B3D9FD7B66D458E8B02A37F5A8AF3237780A90E75B5AD1E63A6EDDEE34084005E2CEA27F42EDDEF3F4FCE7835E2F74CDE5ECA125FCFD441CC1B408769326958BD3659722656CC44E295B8BE73289C9F119E99405F36B5FCB5A53378F945FACEAD496BD2C4A5271094B6DE45D1C3E7BBAB6BE28E717F622A247F77B6E51C0384C41530792EB35C05DE4AC7B59F88AAAEE35539183D06650BB5A9894FC1B6D81D30CAD65F5D41FD19DA22C1037B6095358FD754F2F740F13E44D610C198A90C140603082FEFFAF69BDF2535525F3B5B3034A817825005C49578C140A04805C6018F870277D22DE803896A1B97E195ABFD3D7A515E6DF3FD7231B5AD78FA416A5B8FFE6253DFD62B2C58E5FA3B406D071B6A9F7CF9C95F0E30E0E5DCFD572BB7E89C5DBC1BE367478759F282053CEDB131952099B75B72BA96D31B33CFCF37D2EB6F84AAE6859090B7D3F69E479256CECA539A0335170215FBA319EA639FA3E72CFFCC5AF3ED72C365386115F7D49A259222246FFBD01F0EF5FF3B6719172BF7C5CD9B1432D2AC5274C45E523C5FC19C235B91D3C3A29EAF3652AFC552EF9FFD08F7975112DA26CB70EAC5248047A45671BCE53A6367CFB07B16CF69060EA9775B164B35ADDF6E8AB23EFA212B0C53D6908EB609EAB1CDD04CAE93721E83396A98AB4193E08CBE09A7BE0712866B41D2EB9732FDF142F53E7BD67EDD17A63BF6EF95DA4D351AE5FF336D713F1BCEC83374E4DAB859F5D03AF13B9292E36A0277FEF58B492024242A75E73AC639D1399320CD7CB9A37D1E2C7236C70824A4201385010BC3E23DD38228013ACD7146D815E7C322F4CC3DAEE96E98127312397F8A1F81A40FD2FBCE4FC2C8CF4FC011E0CD653590E1102128475510066A3A3842EA76DED5ECFD7CC3A53C06F34F692AE3448C923A3E65D6442EA2E47DE5338D448F88ECA6DECFD839CC47B48D3BA1DAC460C47571CF5FCBBD65DC3A6F8028178ABACA684E776677BCA9A85B4AE907219CE0C88FAFD2D3989EAFBD9AB5E83AD8C64752BF0B0F60F4303358C42782D20DE712C5DD7A1EAD25BE504D7FD0127EE5F50C5E9804A36A8337A43FFAD3B76ABF4AE74CC7B182A5C537C8E6121BE6A5A753E37ECE4DA1FE8BAC29DCD82FDADA2DC02B6561E42F9C23F5EBE78FEA14B0187C2767F91916EB416C9F4CC4406901673BD31736618315EB5657A3717DDD82008DB2E6FB358A3BE499FDD6F6B2C2469C3FD4BA368D87A7FF023416FFEF12993F52A629EA3B867E99691399AB2FC1A97A0068CB4C40F91779A4643B2022F5E5C55308347BFED75428ACCDC551782E4779B69E8DBD2D58752258C8FE9788D432BB668AB2493BDFF2154AC364796648378ECC8B0ADEB5E8649D0F2E6E6DF94E5DC6F54454E9BC9C97727A39475CFB0DA7ED3BBF2C3EA3C8B7A4CA52057AE068795CFFB8FA2F3278B35A4F5641C5FD04045E16A40B3311184CA10DCFE22915BEB1416716E9F5B96776577C4CFBD629D99FECF425B00EC07A754AAE98699F744509399D4CE58FC14B195E5769540A33A127E8ACA8C38B56D1C8B877E47BFF0887858994FFDE9CDF16DBBB6459F4AE01CA12D7FCA0331266982FF7DC578FCA2692FCBA189EE29F5A9D82C617D3B53B961D90A91F49A869CC516160E8D605300755F076E842EDE8ADA2762ADD12DC551BE594F1A8DACEAD36215E5C3B1C1B04DA15BE7CBE43F0ABB9F857FAFB45C4F744148DBA68FBE70B9075A85108EFDE54B7C80F33339EACF62EF238849DB2BCB4D58B6E18DA71BB6A29AFCBC8595A26F06AD0526326538FFCF64C0210AB709D166F82ADA28DDC9EA1B0CD33B999AD8E2AFE76C3867FA944C4CE4E6906808ABD17940E0E4A6DF49A4DD2F38633A1847685930D650B13D89753A8D007432F14A8F6F7C60A0B3FCC0D78C78954A03FF78F4D18D1EF2A9CEACB0CE85DF031BAEE7E16009EC2244E7F8996DEB117C7F0731BB1B01797D7627E1EF722B8BC5D319C6638BB237D71730CB1B0A5EA51772CEFFBECFDCB66218A148CC2B512A52EA29598FA974F6F0E77A4999F3EA291D51E2DC5EC9D68BF558AC3A0BFB9D7BD3ED5E8756FB4031040A575C267E1DBDA7F231B85E8AF6076D20E46F311EED9C8F41F2D661C283F5BBEC142DFE05654E77D9FEDE76A97CBBE22CC7F0DC16FBE8866C21562F010B4A9AC8C2DB04BA4E594BE8685394C62EBAEE277D669A97026C866B1290A809DB8128C6A9DBCECDDEF4C6F978BF1E0973847DDAF9DA1F31966A89F38A8E1E840554694C2224AA17B5828C46FD5DAB273D841DA34CE53AA8706423DA6D7B45FF46367BCDCFF65ABA85D4DC96323B3CE0EF883703BC211FB4B60B1283EAE66885F0B0695F7B64A9031B166804A2BF2818AEA8F14229A618620A5A764AA56EAEF4E08C6A262D36B81870581DB8DA28378CFD0ED07094BE893B5F3B40AE0ABA73B039FC0998F07926C686C2D770EC1F3A396E8D1D9E716B3B611C43FA673F3B149D474617D7AA01A9E2F86D0600B1650C430E161EF8FFFB5BD49492C72FE20097D6F90D0EB1C86270DF9D5811655410A926C19A9352618A4F8ADD1EB9D65ADD5B0F05F9CB9C4F0A27C778166B9E5D24492AEB39806363A8174E0A3C67CBDCAB93CD5A4A82223A577D3560C1336D784872BB8D45F1F9BF5A7506AFB85CE349D29CC8E00117529CCCBB3BC44D125B85414D529BB6441E6A63248324EFBACCA254BA81A4F085DD2F6DAD471190486A49520F2BEA0FF4F40EE60CE41AF5D071CAAC7012ED9FBF3073726FB737A970A8FD4DD3C4D0F2D5A3DC17377DA03CC29612E9660C130640FF4BEBFD07531F186BA885FDDBA902E58FFAAE9A4B70CBC1D327FDB5B80A7F56F9C3CFE60312AC2684124556CB7428A6CC876BDDE7081095D4BB6A362CBD678A7884008AFB7CBCD52AD974A6E97829015E13B86B77CBB22F0FC7D5AD027C224FD4D0D5F5FF75B53B45386BABF6618A1BEEECF0D8748971F8038494D1455C96C9249F0C050960EF5DC5C9380D7E8C47B3371D2D767B0606AE552BCCFC6B7113C9F1674B97088EE05A2AE5785C9BA078603DFEAF60BE735F74794D07486E7338952FB8B887613C7BE6EF911218E9CE5095DDC6703E5E1A239F280B5E0A443746139FC372F00E2E145C14BC202E17BE79B2BB68520D3241DD36B844E96937E15017CA98EC8EFBC800355EC83A07856E0B082D99D4F16F2E8CD4C4B7AC6EE2C3528B0B7E6F82BE0172FDAEE75600430AFE08E6A10F8951309AB75C940C6ED173A3C668715DDC5D8759C388868997357F0E1B1D02A4CF768F9F4C721B97229BE4FC024E6EDE6D6BF698CBE61F99BD0B957FAA2180EB03EB3A52C3D6A67695DC2F18BF60B7D9D147E1C8111FC9F11D09EC6DF7535990684AAE4F3E447567DF1123461FEC46A8EF32E34F556C600888779D8ED54BB0B25387D44FF3D34C25B26E76AC395BB3E77EFE134856FAC35896B318BD8FFD290F67004D53F626142A249696E33130B0E882D3AAA2666B439269E7FF6C98BF7828B0B6996C1815B52CD49E69DA6AB16364BF4A36EB876CBD03F3124E8AECDD8808795DD470FDFF10CE3078737A0E9E23AD845405C44BF44EB9E33974E2C8DDECD32ACC13C367CE3A7063BC40323997F9E2199DF19E2CAAEE48668E1F83475725DC86A359B824B196C60C8EF3FDDDC311B50FD208405CF5B5DCD7F0293C028CFD01DA4611C8E4CAB7787A29A349D87414B36949C55F4CD14E03A0C84EE04239DD6ECCF1258C9B77F72A1C4B5A0403659DAEF1BE4430AE70E98753E8AEA827CB27AFC2FB8F6700D8CC6D8AB8B1FD96DA5AEA4161D3CD89FD397AD3A9ABC52584C39647F8F0D4A32D2E8B9CAFFF1611E769AD6AA1FD466F987DF9D3724EAFE13EA17BAE204759B83196A955F0246CEEBAF8101551A65423E9A5E69768681BA00447267BD5A28DBDB1039E48476DFEC797AD467A8B9772EBEF1519540B640E64550D3DD89C2596961C0EA393DE69E0A4FB5B850C6DFF0CAD9E826AA3D4F2B15435F05D6DDABE0FE51C4F6BF5242FFE6B8DB95CC49A7AE4FF28FB51EB62E5EF068F40DA232FC53C2F3D78D9064C4D5079477A88C06EBE51344FD2B78AAAA82B374EB93170347809FCF337778848A81317FB9979830431BA888E9785B09F008FDBF51CF17C9D8545BBEEC4FF517598B101EA16B664EE2AEB47E6B42220C4CB6EE7053C24AB33CF7FBFFC1E6C736618D0191A49AFD5E2E1E9AFE60A0D5C52E767ECC9F15DA75B081853CE7AE430269ECE17838A7777EDB2B75503E1C804269BB9001CC3C403BD76706A33583DFC5EE0CE92F45D4B56C1921F8AA6E3EA9741368B81F6794C9159862B25EC9AB52D27F2D622E88DD06341BD79ABB54B9CB804CBA98A7CEC5EBD787E774EC3053F68AB2DF83DE3F8D8379384DB5685E61FB326C476D36F2FB4B759C868E28A9A0CC4D961288AD07F5FA6BDF331236B3CA5C96FCF72D6DDC11C933FD4BF4C1EEE34C31766D989048834AA6E9FBEB4BACFBD8D19D23BDF25DF1CBD327A81DDAE5B7DC56D7E127D0745CCF4CFCCDA73B1B13295BEB160849C079E4B295F4CAD004EA7F4B4CFEBB47F15416DBB815DEA09337E47CF13E132E166830F92930E0FCD890EE17B78C391E6803F301D418A6D80B211AF492BBA0EE67C785BBD41B61E81EDB8BD2452374ACB85E68037C72AFFF331923AA74341EF854E7B5A041E18B06B929FF28433539BA32899B66BE9ED59A43F97D27B7C9FE1AD7D114C0E274F3B8BE2670ABECBDD7F8D6F609B17AD5A7AC47B2DA42B0E0D49425A9BA14CBFB3B8B713C09B434E8989CCC8A68FA8A3C7BF8163396CF69E8EEAD7FF0ADCED074358A13B255E5ED37877D2ABD40B9397BA3F08A547683EF010C5663F7B1F4C25D1A5B96F5F2F2486CA2E5C3B7D371D2DAE4166D222E2C722604A12BCFCD4BFBDD403BD7763245D25DFC05E7F0591EEC09FFB93C36662685EAC9BF4CF7848D8FB6F42F6A4D5B6E16A932C4C04C0F210567C127AAB22EFCFEBFD59C28070B0982FE47435A39FFBDD9DF63310F9AE89EA7AEC3F251AB255E835EDE68C1D661EC0BAECAC0C3C2EB3587BABD3FDD9617833571139896220873CE3AA2ED3D9708864506EDE96C4BBFD5129389113D7A7F033AF636F1EFC64A53C6C7D47DD5294C287CCA51A94F5D5F92890F3252BC8F6A83B25F7D42FDA03DFD1EEB3DA872FB25FD591BC1160CE722CE659574E5C50E24909595165F7DBEF6E263786310D991613B4242449872777AF8547B1FC3C70D4BC5EB66B25DC9C044BE277B2C54DDD7BEF7530B8C4AE06F64007474D5DB199C866E91A670B72F8E1340A0BFC7F077BD2D5594031353835FE466EE2FAF749D3CEA98E125E5AAD124FD159219DBBF5CAAA66C8C850DBAC2A6C46C9198A06A8983FF2394193FFC8D4AFBB72244BFFE7B113A9518F8F2AE832A97005CA672461B9CDC28EC40FC1260D9FB2030CF8043419428661DD4847DAA92A91EBBC6DEE3E2FA463FE3A63FE041E59277887CDD6469D065C0EBE063CC62F139EE9B589E4B93B0F416FC0F99E5FC95EB0770A2D722EEDBCFBAF2665F66AC65244EDBFB63EDE80B35E6E094175D047BAC74D75667F078036CB305F6AC6EF16D059908545DE726FCAF130BA99B1277C75522BBA80A3074D34718B7D9D0A47CD44FFD6F0F1AE034EE5C1646A350F7E64328037F63DE7EE15D51772253C5524F7361DFAD28B3309EF4765C6E92D003F1511D31E2B7BDDF8FA0341E3A886CFDC7A59CF9EDB5535FB7E53B6E9589692947DFE4AC007117E2089E40CB2F9F01B63FE8F71685BE36B20DB8F69E0AF32B6B5FC339AB947AAC4A2659CADFB83251197F8AAB772FC12E89FE3161C5713FF98E3FA8E318D6621058C6B8FF641D8818C2621368F07F51E967B0DED7C03D89C3DD656E2EE2C59E2082C3D243876270F57D22DDD359125018DE12797523AB227C2D16B8C4537C1E5A93E561EA76CAED9386428C45F96BCD09B3A0FF2785824DE20BEF7E0D2C651AEB08EE2967092D2695FF9E0EDB93AD1E5953EF673478357422872C1854732FFF1A3AF88442BE983D07388858D7587BBDC57ED57138B676FCED6A8F4846561CDD808AC1780AA5AE08044C961B5BE1657AAC462BA745342E5EB44EDC1F6108A4E4408CA96010E603DDC94C5A0D6A8F2C8C8F8CB7A6D0A8FAA47D8843A107EB1019F1129E09A7AB1D6A6B5AA36705B74B4576FDE4F562A1487313CADC0F06BAB6D4A4CD4A485329BE196E93CCC66ED061ABC2941A04C0624BFDB7009D8CC002787A39CD06104F93399EA031754838F0FA577E9337B16B33AC981C71CB044A7E60528E0CEA85432D40D28F863EC126F95B2E6DFBD6F5536E068CDDB08A18BD9958A587EB7CA513DC0155ACB57F4F98C2023E34D13980948BEE1A623216DCDF9597D99F9E8098EC14B91116CD3616F6B5277C7E6A62F5ADA4561CFA5A2A5E72D729109B80BD9519B2689535D69D8C3FEA58672537C997D955E66A097ADED69B15BE6ADA0B5E115879FF4950F11F3CA1269931F77DDD54AE6B681F9BD927C9B8311504FF36776D712D108B5EB9F0267FA01E9A100BB74CB4E9263AB09A5E34025541B1EF18FFD541B510A713B756C5E80C79D36F684B05D6FF0DF93E6D9FB507B0160B75254B8C9F9BAD8BE229EF2FF55428B38CF5E5E2177201763E22E41BFE9F06ECC1AE4916457ECB108B6BDAD716A7C3498AEFC2E0F7A6A39416160675749DF7582C4B862AA6BA88F0777D3230C517229A2F73BEF1FBBF6E1E8C0861B6D95BD58E437E4CDA68EAD0B2ACE5B702E1EC93CEAE7B5640CE88B79B8F5BB1CA707D8E6515F44D657AA869ED381F72ED210C70CBE4E80BCBFE662E6C47C1464D1E3B211CA4495226A4C4D4943AC8D9E78189412BE736A77037B2CD4ABA70710AB510C684332281CB4795FF9AD1AA1660C4C44D301197FF097681A88AD4E3CFAAF4D629137B47AE36B0E10A4AE777B36E5C903AA8FE2552F7FCB9D7FC91093A41EF39CF063E170FFA330EED2B503356B0A9E120536804A7E32FFA70E981A13A1762A613C0900E58D5D7969FC843FB3A84B2A8B454FB1282B56CEF274B4B38195891D84A03F4AB5335D14382F41D4A2EEAB6EC5847A8EC4FADB582E1F6D6C69B001B95DD19E335522D0E321308777203D3A1AA82EB9C246FF033C7274BEC2C3779463390B8F13F838A06C82A0C8DB665239EAA585FACBD1DF6CF14658BBC5782DE9804D7DE374AB091A2EBE6FC86B1F06414971D6D96B4EB99D80D389E3CB401E162F432DA4E18FB7A554981EE52BDC45FABBA9637D895D0D6922D7C0E56D9AE3B68B1F75905C69D9AA40D0624E4634D2DB949C3ED8DF57FF02E7AAFEE17FFB336B6D8A4B1694662585EB6CEFF5E14A5FC686F03F6B3AECD5642F49B9D0D46887BF5FDFACADABA0DF766097371B922ABEE2308DE1E7778F3A2B884B93D324665FD0773DDB116F35FCF372A40EF37DA028A7990FE3B349156122C4236EB3A18E2E88AD71AE4C5DBDF7DC409E66350CEBED10D417B1FA1F9A6A73B57E352455F3F2562714C5795DEE06BF255EE237FE9798290BF552A3CC6FC1318D5861D6ECBAEF4A238646277E47F163C832BE5524CF636CA7A57C2E3C7A2B489A4A8D6C50540D2C62EAEAF4D52EA1EFCC072EA40E22254072DAA2445D21F8E447501552260BCC09717E561714F59460CE36BEE3FE03A95F758E986AACC6E0D5FA36894722ECD2C3F92456EE0299018873EED0D61FB95A836D10F11FB32C9217F1656C6AD6BD0F7346C05974390A6E1BEB06AA3130BD22CA64C0CAFB77C19FCFD0BB4CE2C4A5C119EEE0166E10D010215BF5290F43183B1D305C2C0F151234B30A825B194FF1B06873D84564014D9398BC2B33A16EB9CBE9DB2297D673F5D7A2A1D594266FC72C2AF287EA477C73DFD4F72DC71C4615C1F1922F906161229841833E3CD82F2AACD957EE0A917617FCAD5828801ACC3898D49842955E4C9523AA36A51EE4EF5FB3156D212FB67A17B7B2AC3AA7BED83D340220BD550252BCA6C46527DB8BD9E43B1B88AA3CEA35BDE62D3EA9D708E02D6FFB31EA7B084A527A153A84AE13A877B0AC5844FAF0BDC2DF7F9D4297DF9FD81441A293FC3C13FCF9C821D2FA3D58DCA9FE744BC0A79C6CF84C4E4FAF4C5C034EE378A848A9DDF511ADD3A1364A48FAAEFA0BD3432635202BFB610C4076974643FBBD0865DC47C69E2E80550B0795E823A351F3F87EFC334DFC038F223D94F7606937B2A87BF76F31E744FBE895A51F3230A01008A9A19C0A61B9003286BEA9401601DB3BBAE61801E001D1A81EAF6E719252E9A2B327F6F20C72F03921B4507C2386557B174B1C04B4FFF8FE1A38CFF82A4D7A55CF259D27EAD6BDC6808B83F8535E2BFF34BE754B6DD5BB1117EDB4B6DDD5D46379F3E8CCCD7ABC6522AD3477E59A08A291FA020F86950FA2FAF07B0EF1E55D345B48194E20556518578A0CEB8089FBEB31749873030757A0A654E718602605CDE4C9E6CB9BFE8627720E1ACE35910406FF43FA9CB4EE42F19D2397397D793BB57DDD4765E1BA0CA1B5FA40C018FBB560A42ABFEED4618A214F682A683405C7FBEEB0D81091EC682690D0ECEAC408915F7EA0F74544B90E767F79378BA4268D225B10359E832F96D36EFF8B4753B4E06803F8C40B5B7B1F54641DF40A9562EEA6BA9DFC5C68EB2EC111454F6AAC62987892E7D6F41F9AAA72F4CE0D7981C2D4E365E6490A8806F5EBF78A6EBCF7A713562A8FEA128135D9AE2FA45E53B93FF8DB48823311DC99BD1F1DCB6CE12569F3FFA664528E14F1744817D816A8ED7D6284B9207C261A69BD1B3DF45522A19C799CA2AD5D1BF6A1889ABA8942203F3B42B716012B446BD0A2BEF7A129658E85E0369AF2978E9DBF26F769C4FC2BE9671AF708EC8197F36D9C40E0C8805C97405AFEDB965DEA2FD33E93930ACC4777510D321E5E252354992EFCE1D63CEF2B6B5D06E4E29FF7F92929F0F76C458502A09BE18D6A61131A9A13AC59683F90A363A12135EE282FA8FAA3DE0FDBB3273B727AE4CEE8F4F71235F98E99F80F64D432AC36E923B574C705546549B299D85336A5E38A0855217A3E7944D3008400A8042DF36F015820513CF5472FCC160406371509BDFE27E0B9D1FFDF813FE58187F66C3B350C2C38289C6707310CA900370DA4AD6248EF13D931E816EA89DC3FF9F9E7DA6F8E889EFCE63FFBEDA2C9EE72DED1E7277C1FAA2BA7784AE2D3CF19C450927B0FAAE1BA976089BECCC85CE19A0EFE5F267A5642B4F42E543E03AB4DB669BCAD3B2B2E27EC53C554469F525BD44A2280D7C85E82855A45B73DA71E5FD61EFFF8DCFD6E791660CCF8D87AFF80D9F11E3187914D282F5D9EC67DF45D210D89140B35891FCA1FF06393710D7C2F857A112E62FFF79806FF57A49DCEA488A7C39AA5099BD70EA2465D1F7B22BF4A7054AEE37F386589F272FCF0BE711A7EAD67F27765594EEA9A585C4B08192A34B88D7553BA4D68F94CC2578C2391F85A09FBD0864E95E928772F06336ACBCE7A62F52B0242A507CA073556F09974D123DCAD3165F5A74480F8C33F55D7E47BD5A7827D9E9DB97E56B9EA47DECDA6B98FD5FA30E68C9084843087C310EE5DFF84568102A4ADEDEA2F93C3806B2F208F73AC3857751FC16D6EA57C2FC66247D5C8841A8A12CFFBDE8425DD81D8EA79564C713ECE73CCF8220159B29373F4C34D86989DD673737B4E1F7865C171A0ABB5C9EDF63ECEFE8717BF704227E6830A3503016C2E99021FC6FD74F9C62DDA5FF0FB6597D24A16E24CC5D3CE3944C0BD89B4005E770DEEC07A79DB4C8C7D5CC8D32CE5EBC430E56665E2EB57C11B70CEE91686FA3530268638D098CB880155C9A804E3AE1CF7B24B31236DE5B1EE53CC2768DDE67D022959822EBE3A1A9DEEECDBDF74140DF2A21F3ABE5EDF09784244E707D831C25F6479A19E7326285AA50106A8727EB4BC28B112A6B24ECA4A78437512F80BC927861EE4F22E043403EF4A470C3C98A8A52886A2AE4E9D6E10A8DDC657710915875EB581C8ADF5C29D5213597E6EF5FFA7E6B9947B98894E14A72FB107C389C3CDF493E0AAD138362BE0227C4154BA7C77A002ECADAF6776317E35D4FB802549F5E447F93C53E80FF22B47DDD2AEA0E3ABE1831FBAF49D6C32C23BE3AF57BFA1713318913AB842416C449C7763680332A198D02F502175639FEE23754C967718EDFEC626AFE383AD677DC98A2ACC852386E1156715CC572E2110F155303C76335ED774E03E9224F4F7FCF6CB741C6633F82E987E3E8DCB101D307947D0A559D9D4B3F8ACCFB26643797E0FF21D2B7AA536F47D16053F9EAD21E39C4855D204313DA69BFE3E3C2F8BFDEF051A317CDE7BF639FA352684059EDC520B83EB53922C95AF16F5C5306362999CB9E2C0974D3779B6544C61DC96F2428BD1C33804CDDFF28BC20A9E508A94FF9233B4DC3BD4346DFDAEC5FF86EB87D9CAD8D75FF31BEDD261444A3DD4A98E814BBDD43B678167021FE446D4CE366B551E838F535272F14BA113065B7B7212E980FEEC0B148137056903E66A2890B8BD4DFC8E30EFB03945A5BF73FC8C246CCA620AA79A3692E57E554ED40660584D21C6D4BA08F0336845B41652141F4A1C01AA21526840965423F0787624052BA712165B5ECC01878C5E1FA9A9E6012AC8E8DF45D63BA0C5A0B333E96E253E4CDDFE328C5C425CC30F49FB33A2C8D75A7AA5916711F2698302602139989E5D3A2D41AC48B7D8B3D826E7725FBF2F84309E722EA735ED749E66BB99C097DE157DEDB0692DE146D9560C160CBBA60CD96E8E6FB6A1E987B75291F795F600D7E7E8A320D31AD7FEFB8231A4D95254D80A5A17AB3A62D56786B6A7D59F04E366F68647693940F48C88FBD77A75A7A4FCDF3E7E6378AC4DFD30AD4526E40954A1A3715A69D6D212F231FF1BD8ED1783C54915BAD6DBA7CCC8901BF78112AF3567214EC1BFADBDFB463B566D5ECE38A998CBD21C88CEE586D5022E2464BA82FCAC5AF7489632416DFB94F2E643DD0EFCCBB9BFBCB25C4441E2574FCC953269EB58ECE1C92AAA2453F834AE41D5BE37C1737B846D54F8B438BBA03978E8D220A2B9814195FDF5D5D20D94782DFC43DC320C6959FCC96B3706520171281CE4A34B4F0521DD27C9EEE8F734EC6291B46C8FAC66298DC169C04FDEA381F3C190C6A2893C0BFFE2FCD8E71122F8369CD22EEB60566D2893893FF4ED6C4F2AC252B799295C2E76B7631DDF21BE14A1B65892AD7EB880E0DFA0C21D996ADEFA18957345B4BF2E930F32055CC7D8EC37B20891EAD131658257A61F7225E88ABFCF5720D3FDE6EF04CC0DE22A670F5FEA0894D474D7DB640EDA34FC81EF3ACAB869B8A96CDDB8F2B1B180C58E380B0DDB44B580A4DC59367AB2051B1CE60307027F05FE886AEE4672F63878B03E4F5EB5D44A2EB0D161CD3CF9D60C5DCF04A07F077AE47904A9EF31666B6FE20F77A0586949FB05EC833E9CCF183DAA6A3E0D24A392AA823E0E5A86A945251D35373DA732DC95C1009659D791DBB6EA46061325BFC6770308AFC1FEA5698C5AC06630DCD52585FFA0AC644F8DEF7256D68B268D60BDC9A38045633DF4616648E63E037DC44EE822DE5854C07B649FFC3013732B794318757D62FEE988259BD0FDED8EEC373CD60D7A0B411FE921956711465CFCFB3396E388F7B043CB91B3112D78953D14264BCFF7FA4EDFC026FE4AE22CFEAF14A84DD3B5E77A494D9D28721CEA2E1D917B2356DC68B6458D872B47F8CF5F6ADD9E48D955C0B408EF1378DCACCFFACC751F55A5636F6D454471A736053AFE8712412593FCCE4506FA40E225CBBBAF6DFE0E51A2157E17FFFD6B75012E8BCA2ED10415312402E7D028D35BCE8090D320F3DE3C4E03CF4660AD336436A053D37A2ABF91864B5EA6ABA0958F0ACACEF42C527BAD2A948B195B93433C51B720F3A4FB06545E71A2B10869AEB294B53EE49764E515008E02E5B73C85838977F92161BCA805710E38DDB15D6E291CD252743712B2D6CE0F507C714F9ACFFE34DDB0484F29FBF260FFA994959AAEFDF484A2E5BB6FDBE21FD90D8A2EDB59A20AE41A7ED5243E2B355B3A7E7D52192885DC1799941CF09E922357AC5C076182D47F9DADAFB0B777761EC7BA2DC3A7FEFBFD99CB8735473DBEB04D3F6D9E0E95923186AED4D09401001CFA09A97CE967ADBE67BD5CE33B76CDA99413CC37EFBF2098E1CBF8FF53FA3BD47588BE2C446CC0CF4D0039F2D8615D5525C957D8976BB1DEA33B8E243B3B2B1719C42761D86EA8C43AF553AE2EA4FE05EB8F6B23C22595F09A5BC061D39F13285001257419C7F67DA6FCE50AF5B7C10DB148BA61254BE4D3E13694D40B3548731610D1F4DF826FC5930F87BE909A6E05CFFC93ABCB5C4D6784D1F3C2F6E4276538FCFE40A9E182242D638A8F2C59A0216A38F821F8F278E3E38646B021F17A06B4F622CE5F8FD5055C68820A7CF6C66A2E09B1380A83628595A2C3F90899220D63CFD92F8F9C305ECADFB99A74C3649FE89AF7F6B847CE1C1C9D7787E2D9346AEF7A460D2C7C827E0F56A6A6CA43A1BE9A6CB8D6771C64557C9D8C291E2748A0C03A99F41A543AB4F0CCFE4FFE2FC6D81AB6B302DA8B047A385186FCF918F40FF708C438DC912E93F61CAAE4E2489891B9CE7E2BC88E2FDDAADFD47CEB0FDE05BE4B58D7F0AC3981E75938F21048CEAAA28A641E6EA16E188EDEDE40A6500C2B6E075AC2BF29578963BFEC6EB1469AFEDC69E6DA14345FCBD51EC652E2709DEF5B2F4F371B2181117D2A2D11552B548A8DCFAA0C51569E4E66AF8F8E49C1882752E3BDE43C6ACA446A30D559599BDB07208DE23C0991E8D7C1DEC560C653F117843BDC5E4ECE8C9A3E1FED700C4BFDC04AFC1718FE461A49DA2EE86C9C2B67AFEF521A6668BC935794D6F0FC417FF4CA4FE60C05276D7400EDA2E87DF859092D976AD400A9F1BA0FC0A84B3F319D09ECD4DFF049067A756DF9AA35D3BD24D85E911811DD551619CB9173B9249638AA38A6D4B9DAADD51360EEBC848E02348B56579FDC617EF2551ABE6FA509E822B7B7344A57A443559E687400B9A3600FD32CF7A49406F5F1F627FFB0F356527B5DADEAFA08214E71EC77E6C1C51DDE20EE85A27B807D498B9B0C806A982970B508894322469B8013C1B7BB404CA1B0CAB6CCAA166891DE42B499FF40A35AB1F586602168298433D2AF77707C5940B6C9EA677C35B7A9BB682EA4C09F2B9228CD25561A88C6EEB7DBB85FCF8DC2C5F1F34C19320DDC51722A93A2EA9C9353FF1B0118D072E0C94792210E6B633B108460B515B33C1A76AE38AF650785AD4A471298AF77BEDB69AFE7E97570C74D01405B52BAF21FB5F343599462FAB064366201604F0F040139088412423BC8855D43C77E60257B4E448B69B5D428ABCA76DF18AD681F6B459DDF1A4DF29B68F44FFAFF47459986987AE53B19C864D6400AE87EA0BE3162BA915FDFFCF9C57FA670B5B6EA15127D150015BD56C00875799D5CF34825AB92D8874764ACE5AA1B6E5AAF783005C76B4AA0D3177E5407D5F12C0805B3F03374F2DCCA84C9657E74964E6B1156EDEAE07D155A93CDD0F286E8F906C80CA7D0987FD0FC8F5B8F22ADDFDCF8248BA7843D83B855A5F77E84BFDD887EB30E86C7A524AF0CBCA8F1DA78F9B7670D9E875403C965DEF597823FFF0FBBA0C74F475340DFD88000CCD024F703F18E080FA2A26C762B7596717D81EB517FFA1DDC493A12F37FB1DEACF4F31752AEE58400C2798E1DBCCBCEEB251ED78EBB8DA888380A30E37E20F17AEBD582F4C6C2217C746B11A66D8C011D0B5BD9C36F629D586D1CF1CAC316E864A12096005DDB4206D473B3EFF228ECC8CA61F9CD63064BBB7DD65DF54EB5C5BFEDA8C03F8396466F59396323810F05DD869524CCE6175FEF0D8A10C943586F8C39176CD744075F8E5F4D58887D6037B9AE792479BB41F91A89CA5CDEF969FD5E150BF3689929FDE7A0BA2D033D72B88D140B359198EC5B5953AC04C9466441614BE1D88AB9A912CCA16CFC2258C933A648587C107775504B4B92958CA568D5758780846EBB8F31CFFEE639106FE3DB1767FC82856D193E37DC40D36D303C758023F988AB979C8182D397406B18A0873C2ED55FD8AF68032C143862F3CC60A1A78C6FFAC58C524C086304E134B0F8692A30D0DBC7CD1E2FB21FBE443D1B155B301DFC6CB7691D91B6C368A98ACB721D07C8A1960CD55B44FB46EF0EB703C3B5D5D9A3E4CAA6E116DD46697D41F985966C987EFEACA2B5CABD3F2F126604E81F670C53F5C17E5137B17538B2029348A7757477CC87AF3466B242593DE459749F1D38272F64E69A8D420319F351949D2200EF469988BCD21A2E0A280D92F3E279CAED349A9C6D0B76B4CEDD7F71363173D9AFC2C8DEC7669F6FB4A1A68CFC6098838D96E9EA055E838B7B4C9904E2395E55D53E0C7F004BF9706764271F24432753911483A81ACE0E1E0C0EE6633E72D6606F6F57FEF7307E3CA281051BB32156747F15109561FA8E8478A6526EC7998DFEB4C4E83005C38D22106DE91BEF72DFF98FA173192D5A729F1614B231405E9C70B037CAF9C400DAB3F4A921442D180E05BEB0249D3D0DDFBAB92D2FF280F11C0FCCAF0D98FB8C8C7647CF7937E0C01063B2EAC94B15126E7A64C410877F93E56004AA32817652EF3E540CD2709D1A5DFF17E76F2755EF4EB6F771CEF5B4EAA4E6485D76D214E0DCE4ED2E0D9915AD71C86B16713960610E8A098D9C2C11E2FA1562EE4EDC2B7215FD9C7A7243E625663753A3BE3629848046F8A87CBE76C0AB2B5F42C00DC7352137C6DC6B1A6B3C161A9A11D4AFF63E398889196D50DC66AD17E0CEA7738EB17F90D4BDF2D0B8FCF353C380D52145F5074BA91410A25A62832F0E7151E76DA9A7D1E3F0BEDEFF84CA1BD6CFF832A11C09D903D63A0B3E69B19664D1538C1619447A58E844BD9376FF81469FA1541BD03B0A42622C3A6E86A9CC414EE5AE44E51101FB0E4C40FB3963201B8E4672FCEC8172345C9C5C08C0FAF08A2203B566CD966EF430F6AE8457C29F4DD7699CEFDD4C33A9323FE12EB0703A1F0DC338E3B3FCE678448C2D7BE75D229BDD7CAFA1D5610F644CD07CE60EBDA010E46AB9C302183FDE38B2E7F0E519CCD3590E2435E7DFDA5BF1D2574195872C3DD07C16ED88603473FF964420372F0EA7FA19562B664811A92F3D15F3BFB21A43EC2D299C160C5FC225CC02B4EDAD14585EF9C194B56D338B938A5A45B837FEAA1A720ED8F6ED8ACC5667F074C3B88160DEE2260668F3273B44A82D953A09F9D1C2E7D0C37EAC44FB254E3B29B2A30BF9D49FABF551699320403A897B0ACFDF2A6A55DFE4D01ABE6DF59F2A584FAA19AB7FB7151EAE0CA9E638C32C22DF17C002C5A8CC317E1D5B82FF48FC564492ED90E36E5441F9F40D62D1835D83D07E2B39B367DA58D0258987D7966C4FD99E477D54BDA4C3EA2D6101442D533A2793EF2B84ABD9DECD47726DAB8BB9872733C300FFD1126CD596F9A2BD2BC5A092BFA0D0DF8C4CADE25CCFE4216C55D224075CA9252A9E6827C0BB1E308C8FBBE43982FB6D7916E82549E2D2269CC20589091D025E66ED03B969D3AA8F9D21E8AA000F0F2AAB3214F68E7E0EF150FAF8D502D91144720E68F0AC124C253E40411309B99C8DCBC1648A6F67C1B77FF95EB8029D4A4B745E12E0DFDAF6CC8DA72766AA3945C90A9CB025BDD5F283182D99E6006BC98BC17E86FCDC4AA4EE6D5802C92B818749ACC282DDE2427EEE0E3BDEE3D5BF3250A4881FA91899F5303BBE1AD9A23CD44F1A8866044DB8DD8AF05D6F6C2EAAF006582C7719C2C6EC0FCDB4E469DBA6AEB20EEA68A5E8F723DED1CDE83E2EFCA6F7C5B4A89AD050F14FCF34586C33205F650F39D0DE19EF8CD42601C754B8B252CF5968CC5820B3F512ABB1F7D2546FF1867A18B56B029DB99F98598203379CB11205B53C477940527273F515B5690498970F683FAEA459B28DE2AC182C51D360793D60B49D706264966B54395091F7EFB2AD0E19D822C3BECCAE22369899736355B882AE2071A8DA4B690A266084CEFB6A4D64175A7BB8182FB6DAABFBE67AA4C123ED22AC44E1A7B9C117B15338BDEFF539975662FDC5E71EE85420C8321799B715F313A1A80527502497CBE15110BB3E62AB7B5B4AA905563705887B76E3A102C985FA849D501F682A129B0F3931FE1B070F382C3913EC704876152FF1D1A82A059A3A363685D356A79B5FE6C375EA37F16C8800EC573D2B9BDB8FD7D0D0655EA81F066613B97FF6AF0B00E5F3B151106CF3F1D76C346C5D40D0C79C4731BCC27ED0011EA0FEF3E50ACF4ED14CC501A2B3492D6205F7D0D6ABACFBC86261EAFCCCEA459602C6C2FB3462949BE25BC4C3822DADDEFC71A93FF5C4734733AF7B96AFF1815177A8EC2262D6D7BAE75DFA0679DB6A73E9C38A55CCDEACDDD332D030CD73E91016D72C4CEB50EEA596C7ED1725F7CC83D1FBA61F37DB76D1FDB55319CDC635422A110F2170C62A60F2A5324485F6B0E69ED4996B9A52EDB7C36570EE4CB56C17ED01264F990D0E1D7487D9BDC5D8A28603D7B92124183434375E827EE7A3F72C9016849FF3B5B2AC31FB478F4ECE8BA5E321BBDA690D1F6E7012E75E1A26BC1865CCEF230E406BEE51505E758FFCD8909C007197FF3C150DFF87B50C3A1DC9A1D25A5BD396DC9446B779B5B0BE9E99F03654432DD439932E690D873628E85363C4BE5210F3842D58485ACCF8E798E46186E8ABD1235478612C4F16045D1887C8C9E4CB0A90FBF125E51F0AC968D7018DB2CE8BB1027F127D96B543E35C12A484545B5EC9762E5FF6CD7EA4A0B39892B09FC93732F4B775A00D5AEC7C815DBAAFFCB47643DEEEE68A829384F9FE36722EB0C65AAA92479BCC276FC4CB27C4EEC2301D89655AC9052FE69D93666BC7E5468FADC0124CE233DFF4A843C76686332DAB542C3EAC06F2B637A8D72E2BDB1CDD0FD0FAE11EE7645C7E6F0E7793A73FA1329CD49F407D59A5DB623904BF673CA77344DB734D36729104BC81593059D38D4E9E0F5CCD3557666513D6E83D0E6E83C4CC0CB1EA474D0A9ACB3F10B786EB42DD4926140BB71F2B748C44BC23D5F5A790BCD908E109A8B56430E283745409000EEA1FDA9F2D4C1FBF5B4E80A0CB989223882587E3DD060226C5A5464C0A3E04481E79C4DA6BA9181ABEA1179933D2EF7A55FF57905219557D4EB5557BC83535F09812A2957AA1D4B0C78F9A3A47DE0A5E0C4A1A01C9343589FA9CBBFE46EAF17DFC1A856BADD63BF782F074BBF620615FEA70F111047B5B8501B5843B0F18CBDB9C4CBAA03AFFF46E50979CF2803280F06B2989B061C4171AFAB9522D2A2F30F533A22B8C7E7CA1B7E6425491696C3F284D8683039326814BECA63307F435C9D158594DDB785FBB8400360A97F29DA38D0DBF3C8D55ADC3415E44B4236F2808EDB988B5084F735E4920AAE7FE2E63FBCA84FDCD4CD55248D079BF44011D0506F3C6947D189CF4BAD90EDB454400AAC70E20735878DFC96FD5BC4B8CDE1E41CD7258EEDFAED1B7295962AFC8824BA986A1D6EB2C2741035747E4334EA74E19CB29774C50504579ABBD0D55107BD21E3F73E0962905640EC0EF0895B82BA16BAEA32FABCD25571356221916F0BDEE4C6E6A50101051C099DD49C567A5C908F5E1D9A5CFA92B4E6CC6886D117BF1D0B773C89F47AF830D4CF9CB74424523CC727A79AB4058519CAC200E53FD93FA342C589D33B8DC199DC76C54022208E86BB9ED059B48064CC163702B6C199738B570477083960043BFE1836C27CEA201C81618823F136A945C49978E4800DD1DF5A77945D83C1F74DC2C6FE33FCA148A0A358D4F32F8BBFF427D698E6DE4490C1DC82221C6384BAD11D335434511D631B40F0C69E9550714B413231ECEF847BCBD6D57C891AC2206750773BAD306D11385FEA372EF9C260B05AABA22BF48C2D4A839EBF4DA9FFADF5F7062F0A2F3EA7CF7217DE2F3C1058B74561C91AF95A63FE3F67BCBBB1D68DB84603A1DF9770F2378E8FD528C069ACE4D2BCBFF383609A8AFA0075D299FFD05BFF55A582EA57462FB828F87CA611D1658D74339CBAE8977298F0740C466FC683C170578C01E20C617874F86FA47534006EF88277A5068AF19EC059551FDEA08D01C49512A9BE4133D8AB7380A3D3EA33E8D9BE827215B64D3793C85A318DA8F6234246BCC3C888963F58472C187F34F4FF8850F5F312C7FADBAEE13A2AFDFE907E1898311702BDDCD250C0BE74DBD0190C2602B0169ED1CB73885AFCE6DFAD11DFC5EF58EDEFDA5A78743BDABFC819FE90D01F029E1A715F46E6F3A5C5F1565EE2A627905A4ABD7C3D9CDAFB526DF5C9D49DD5097DD28A3D59174EE1181FA85C2A35B529054523227B9FB0E3910361BFA427BBDBE9368779C0BDE953722A4254550D1EC71F7B752D375780D6FA19EDBBB07D265613136E1EC9CB87F390064A499E7FE377DC00EF1F50724A87179952B37D2354B7D284D952080965632012A0449C0D4BA30C7E3BD652B69210AD193416A9E40B628AE34C8559096CD2B867010CAFE792A53F138F399BDDAA4526020610CCBE1252B44EAC5B4A699367322E541AF10AC60260E9B4ABD668B96DC77BEF24168FD023DADC3069B1649D9B08A8970A449F71D756B15F15F2B621DDA6A5A762EBA0E6B43CDE1E208F2CC6861001E01152349E21C9EC5F8A9E62D19FD28EB0CE653D7D02C928677FE94726AE852740BF3E8B29A5905A19F4B6BD02D70F56972E0D7BDA3BF87CAD006ED96DC5020CCDFA50130FF99024C63302A6209756325186B4FD31C6DB9C394B0E82F12AB1C667A75AD3906291C52ED7789ED4CB2EC8923C9E105C09A65A8DFC8828AB2BB5AD5C43BF5E748BBF9A6D5CCB9D4F20BCCFC76900FFE116B5A9ECF6E2381D432871AB50F11F7AEA095F0D58DD3D87C4C802214082CB6C8A594F9EDC43E60E9F7F1FD11649A9F8D222E2E85C53F5A3BFAB1F9B9B559E79661D1DE5005C5392483889D341790E01DD875389F55F4A133E4B4216CBD75CDEEFE88116A87507B36755B68449003D85358C37A1A1B48C9708A7428B1C6569C64050E6051124E5C9CC57D9C562B77706AB91F0594D24B9C92FFBA3B760C3F0131F53ECB07B53C4E328EEABB54381921FEBA98BE4CFEB3CEA1CA00C1A452CB188F9880FFB8F2192D32BB4C27BEEEAEA265D5613A5EFFD82CC34BEDB34320DCA3BE045A82F261DF649DFD17E72B06CB0A1F727EC5C871D5EC27F236DC63D1534900DA4C0866626F744CDF81621B4E1DB7E28035843505359A4801310137B7FAD5516333A6339AB637B3908CC6D359FEE080A53DA314DE0FDC321AEB0D8A2918E422908F435411A540DD4FB06F4687AAA79DBF3F22CD2E9413B3D4F5A5DDD12388AD98BDF4CDC0F47F340D2EC0A6AA3333B9680B2102B9E8BE6DAC15986D33268212C9638113DADE4DF82B6DAD6F07EE7342D30265FF705EF23AC6083F83E05E7CE74FF7A40090B5176BC9C10C3DD784F3D66E967396AB2B8D4FEF94398B6D9E4309D11639FB513384054290F3062475B2736695896F2DECEDE9383F6DF2E0EC7CCA339B7920CEA21A93705520F3F79EEBB3D5F22FCC92C347296846D04342FE7F2089D0629F169D0375A785F2823EA02C8633AC499F3BB69F4BED79EA5C5938B5FCCE6CB26559FAEF2AC3907804C23806FAD433AB6347BC898855880B48013E36994433373C630ED3D0876A7635790B055E748284E28ED487BDA4D6A945AD15455943E210A72EAC1A5A3F76B6EE65A546D03F48FF27B2269EC1E7CD424A58B5B37F866363AC251CA7C473B80A5549FAD539FBF4A1F32C2CD938A7DADACE031C543D61BD0A9B8C8DBC8C6D570261E3C3C6F89E7DBE829C8F180236BAC02E803DEAAAFFAF7BB3911C3AA308B2FD48AE87F6F2D76EF46033BC96DA55A928F9F0CFF21B581E39CCB139C64ED06D0DA8CE26C570A3D171B2A29775592645D02507C039DD23A2AA7A3B7FBF4B5F9F513FC3B73ABA93561BA499E4F717F4ADAB0F300851355394CEAB534A58EB25AF9F8CB8996B3D33B1D9EDA0089F83CAB9C3C41DAEDF1F17B3B659B75FD09865290CEDC9B119079C1F19C071CAD55C64020FFC4DAD72142C1865A49033A4E0442BBD79371C5F6E96627661B16DA5D0DECC67A0061C62DB4E91ECDC896F6087AF6EDE72F362206C055456AB7A06BFAC6510528C698950CC2BCD4EF95E9563E7431428C6149C9EA3FA6B313F8E0FA4B70F21BBCFD7D8659C8F4F5F35F7A64DF9192D5CC1F79ECD87A8E2ECB3C8CA3C1CB8D83E2828CA4EC393CD423AE5F4956FA29D236B3BA904EEEE1C44704CF77BC32CCF1C98E962758A15EA521CCED946CCB5B0F870C56532AD3E9D50A0C3B2477D0A2F7EF2D4E4F5E673CDE6FA298FD08F04B0896FA504279DE1F77234989969D99780C10468239A02FBE7FA065B248B3044D5B93913CAD0E88ADF9E616FEE61038BFA8B6A23E93FF93C3C070DA86B14B4429424C9FE978DA9A2D94AD2C1A5DC25AD0F4AF9909C12441B8AED9935DD4F57E29A57FC3A4DBB2860B55706AACD7BCF089437B3FA7EDF2F7F04B3335C51E34C7002D618CAA542F0C2207C72CCC2496E757A92545B3740F84F519BBFF478259DC54619C042315ABF48BA57F83D4220F4C5533DFB931126242BD6B6B772AC893DFA158AB6C9C9FFBEC6193194CF3BEA7A8738619E390F87B6F3C28B8E066FF06F8AEA66EF7FB677ACD90E99E408B152578920C7A813FFA8D6D78915B8FCA52B3A9317906EB5C500E959440424D0542E3FF131802F52F742B3C7F87CD4AB57CBD48FEC60993E4AB8E8D1D84720E2F335DAF27489F98BCAF5D5E6CC7AF2CE8D1F83E04C0C5154134EC5A08BD670DCD7A81789E189347E06FC586C6A6385853C4BEBBC9334ED60C39A9018E288835125920C6483181C8D6513AAB11DAB54C11FB36FC96ED2DB4B3DF1FD0034D3AD248E87982D9FB4266934B5FBC65851821D9E8BFBE835AEED6871B73EBA8038A632339B71679E1CAFE97E34EAF59AABF4C3FA458336E986CCBA4019474E4C45B3D8EAD431FBD8D8F2BDF8B536ACEF05F8803A61293768876A13876FC3197EC0F470001B698065C674FA8FAF8FA9F033F7C3DBDA427B8F9B88288BD59FEA07478492C017AEA66922AC29A757BB0F417081AF93509C5C9B3C50C16BFD770CC48548A2DB562B6691B5D9B54C0410758B0A8A0BF630BF3A317D5B945DF47D422E6EDF94C097322C135DF41B1A4EA1A7B949368C4A871D4538520FB0CDD0048A0B013CBCF4CB920540B38CC821FA7FC3D92406F623B5389FF4D54C9794476D8F5AF785F6D95FB901FF61721C0DA881B8A7FA98C5E35BB3AF38AB2D0E50523D9990103F05D2BB82EFCA7844C49E2EF94C7A880C6AEFB41DC5AD5CF4F4BE5687A84200F732C85D2A9155DF1A07330C907FBEED1B193D0D058A70FDD8EF4C25E7E84451AE4CD4A7F872B2BDA59A5BB0595BBF07D6603AC0B5C68F746AA7A5391E2CF4242E07D422C8A973E5DA480FCE7319ABFA8B7849D8CC78B31D9DC69DDECFC6FF14B1380B1F5D81E6AB224FA6E2F04C9C20EB7DB0AF4288362EFC71D9907F652E512BD851961843CD17578E28730CA9A5F633D25767E2557CF209F36486A8FC69AD5B2FF6BBA4E54E801F9021684EF92452DCDBCB86942912DF9E0E561EF79C167C17FE0B4F6B0F52D949487C6993BCFCB2ABD7029FE9EB7F33DC1CEFB1B47DCC18D26DD228D4436F187C180AA56AF99BDE9AF510ACE9F784C823DC74A3D6A21DEF2E7729E24289FE6821A30402729CB1EFAF0B36DDAC9009797EE18B2E95AFF3229EBE7EDD2CEED7DB2ED0EFEDDDA3504F60A366788F2A7E1BCFA42D5A50BB385F58C5567CC9A937730DFFEC7A64E94B8E4BF7F2DFA9E6DA15C06427B99BDDD944DC66828A47EB7244E5445F9FFEEC2FC30632953325100720479C87A6980518EA0FF81A9DC23054BC7F3C98694553E45A64B6246741CA2D16F85B4EC1D81C40A51C42258EDF155A92FE49B4B15432230E69591FF27810545F462983013159CCBA9C95AA9459BADDE8CA4BC06CA8BC5A25933E43D40EB5EE3509882D38D8741E5EB55BFBBE8309B9FEF810D65655E3FF29A910CCF1EF4164959A221701392EA389EFEC5BEE4DDE3BF7D5CE74821348F683A6F81F8ED0DC4EC551626DA8FF2653FCF26DC7AA5395901EFFE6080806F082C19E8B136725D43921A11C36B95D18E0AD326CB0D3D5C774F90C6B705400C7CCEEA5F680DD528462EFC08799BDB8B4F33216AD503FF6EC9DAFF61B24D717B7446C76FFE2E4016FA04043697048FA941DF2721A070F4F5B2617F30100BC5FAB4EC26F1CDDA71C09A9A636E29AEDF59D8CFE2454AB6EA073B80A3EB0E049CD7400A499BFB3890F4DB25915F7A9FB2494C2593E2A0227ED2A7966912A374C023026D168575CEE148BC6B6CE1A53073A1DE78D7BED6A8599FA1528D039B7E3060E0C05D98682638F93A61F74388764E78C5CA9E65847C5C8859C08B7347B67A14B0916CCB2ED393E527A56BA85A8F695C4E17C923B4D91052E24C095CB97B9EBBE958687CA4CEE1C45396A03F981986999C1721E9A68E225E663173D7F2BFF151F7AD54AE96B935AA373AA24C335EA1CB1BEBEDD7444AC37A5D17CFCF9C2B803D90C2F63B378731FF0DCAD104CD7C4BB5F69E960D7A50E42B68C3364C9AAE61EC3FAF957D7118221E49383CB83F511846EDB734373595EA0650553F5319D38421987177AD091EB2E05C4910E47D2875660A8001C3935BB04A0E013050901EB28FE328009BDC727DC5578BF1462ABF45258C02DFFF79788E3E8AEB96CFF612C50CDE12F883B7307DC016E72787F25554DA8C76E1CF8943C21C7DD79F9D721A3A0EE9A8C21AA8F262781012A4877A41BC3030488E40B8B9BC12468157325C860F0635E05F29B8786B0310156BDFBC0642D31CD16E4ADECCFF6894D91957344A9B0A8F0B1DE819DF46F3B9CA7CD1FCB447D05A48B458A4BF7615BA6E84EFD93323CB5F26E2B6AC01491F71BE3D1BAB2E84C496208B0FD3C6C2AF49D3F474C24188DA533F04EAC14783B0FD0E62208C4421DDDF06261C068DDCD2EB4D6B6D43153ADB8392FB96FE2F6704BE4C8A7CDF5DCE65A72895933F8CAA4A0418B8133CB92A4A51EFD2F35FF8A6FE45AFEDE9B43A4A4EE4325125CE5BFCF994B4FB6D3FCE6DBBEBE2371E61258184FFD41BC6ED71711FC733D8AA41A02F73C39272FDD740748E5483D025C7C2935161D370E392EB57C344657E0BDDCEB03EC678E5D4A54C6692C8AD326DD4E24709557AB8F73E9C02EE5D2C57682651D0700E2F6970C84321C54FEF85A92D88CB477848D2BA7E30F44080900EEA0571436BDAC3E1885EE2C3280E046E58E71765B3FBFC4138182286FFA1E5F5CA0FEFEAC27F093B32C2772487F205B956D6924C994CC2FE0B4963B2B6F1496FB8221D076A27DFBAD5F3C455FD614B11FD7A43883384803F38531CDF2C00024D2CF6C6602EF457A8432BE634B177FA0CB6FD01F0E5613C53695434D9A44DB72FA041572F906FD53B50EABDF142106D3859A2C3C70E13F7154ED0A85124A7F8592B5732164E01C047887E80D2DCB184BAA4883F86082847A33FD82DB87D6EDD445B84F2BAE44571BD7154680455B0F14277E5CEFF54AA6248C256407139D3C2B11058DA164289E67F701C080168E2A82E0508D35E85FFB1428180F2265F550D18E19487C6F044DE69D7D4D4DDDB33F616698290E9D82A94E4307ADCA3CFACA2C4B98FDBE647D23B4D05035AE67C2AB6158C25ABD0EB7305504BEFC2A270285D7C0409CB16A67EF673D47A28FC9E7FF31CC9243903BAB1AA9F058FC27DC786221148F92DC6702BC34E261127F6A696FD63A569719B778D1A57BC7D4ECE79BF48AF4F0E9C616701DB4F0FBAE1DA082BCBE7F27A695D28AF82A5A7370D925DA318C6F60A6D96C733A5DDCC97D76B7BE4BE90B065DCF51DD0F386140989060D70D3198D148AE10AC693802B5EA3B459F986A330D1341A81B25A9CC23FD4BD79474AC5BBA3312546F8A951C27FFDA26CBC493672FAAD36A30A8A8D7E4BEE7E7A6E9577AF6028819F902F430D4862FA92F6C018E06DC9C77F5AD46F15C5FCE54C300E3108F302D0AC1D35EFCA04B106116020919FB4F57F374266BF33C2F91C1777AD27EBA42F7AF96BD0721DF839F5B6CC67C26F9E1467A23CB91569EDCC3E50B527743FB8C8FE08E8ACD5AB33E87BA1544C7FE74E27B09C58C117EBF14674DFF6F5E3039D5A29B8AF1BF155B86AD62AA4109CFB6665D5137085BEB72578BBFF8A3D92271D4268BAEB9B398E07AB4302550E47ED81A01381640A7E3E25334E9F55D993D634ED2E5F592DDC62B768FE8EFB2784CEEA7E441A7D94AE702C0CD1A2153A5C3CA90A6498EC72983604027BD0E3933BA4F20704E97E1C3B4B9C9D312A828402B419828750DA7906B6144D8197D8D6C651E3ECAC45D99786B8F9D256D42B49D8F4B9FDC140C675C342A11EDE5547528DC0EDCEC05A6BADB2900FE4AAE3999453D1766FF508E0A6002AD4F99226D8E48A3363F86ECE85BD2EB1FDB5F816D393A8B46337975ACF3B5FC4FE178481C3ECC26179D4C47AF2F13E5978BB94798B038FB77641F7A70A91A5855FB16D26380B8C0901024748B025C1E360388E127A190C77A2F755FC8B6E26FF63D4FE1C905DBDAE5468466E152867FE4E1E1BE314D7E6D1D7BB4CB30B10069D52867A7AA0EB68FE9F8FB9F171B83118953D8A0AF6F8652F64D81174048F622960FF67858123447FC75DD2C12846547A1D880E351C955EB55F014F652AA8CEE61EC987C93429CF7AD0C6AF524E3074DB6FE18ABD179573A10640FA4EB064357E973AD2F0127BC81E2157B1DB37F2F1CD92BF1DC341092D63CDE9664D5FA8CA8E5808A469347D5F7DD2D516AFF2305A331ED53E8E6543347B52F65FE4939E031ECB79676992C3E2BFD8826B78D7D3FB8A44E08843CBC3025B5D58004B29034DCA2C5BC59F7ECE97AB3F54B1C468CF0C6711052A045E610C8788EED8462424B537928EEEC8D0ADC9B077DCEBA3C7C613A481AA3EC3D1711E6794341DF4E83D59B03E284F6147B1F5DA1934B1D676404875A18E017A0EA152EE40515838072AF31666506E0CD64FDB3B8EC81D67B305F588BB4F9FA69B2DBDCF6C59EEF544284AF7B150A6568917FEF5315678C8045D9FC2A75F38B4E31B4E8BBCA744231586C9476AB824667C4F151E8A28D6E0520A8E6F86BB8575439607AC2DFB814854AB9FC4E986348E0427A0ABEE3AA14BEE6BA5640E417C724749D56604EA0F39BEAA0FD3EFEF093D3756097215D1D6DD5A1D2150100E5D33E6908DE97136649E2461D0D4203B5697DD6241FEF56C4EEF7A36B9775081A292295A685FBBDA22DB21BE58419F3DB4246B4C771BA05BFFE6832678DBECA0B3735CF8244318D27BE28DB42DA83A6E88FBBD4235BDD1089DA674641DCA47769DB4E464EE64730E97415D11DC80C83F70AF4F5E60C860708AF75869CDE5ECC7FA15F8FAC947F9C1A02B87BBCE70F60D905D72AC4AF406859674A7D0313B552EFA64AFAFF9AF7904F8B42193A5E011CC832A2CCCEC3070D2CB03F8D899602482E8FC21E5117EBF31180178DFA8D4C167AF14507008846F37E38C837779A0230BD4A68D9F0D59F3053FBF01947C90E17D4EBF6F41E55BD5DD8EBD86ED2F7CA60B43644D70F3D05926644A16620755EC3ACD2A8D0BB59FECCF5187A575B870D10EB8719AA41582B66510D2981975A0B1B39FFDE7DF4A75B587EF18CB185F70E2EA00A501740B589829CA8C3EC3256D2E49652BF3A899DD0AEDE642F536B2A64D79DA581759A4008BDEA1A7CE28F1291F443CD891EAF4965BCA58805005F2BECB6FAE24206A0BB203869B86428A54EDF635CEF9CA19E1C4DD8D8636238F9C97A5697832E31956ACFD6148146C8A3E93B1C802EF508EC97C1A75F45FDB4EC08B11EE7F09666485EAC0AE8DCA9A1B8C4CA5035A16EFB0F4B603F40FA4ED0ED5423117925EE1089DE92068A67D8F6FE78BF3E272228F596BD9C0181DE43885A4B82B8EFFA9C7463F5F71FAEFD0BD4B84CFCAB4463CAD0EEF838826F0735C41BDEE32EF090092DD01FDD2158B4A0547B65675F45F4C6B7ADEFA55474BA81A0BBFFCAA4B82085086C2E8C3C03F616FFCD367A0C34535DE1A289834A8C86F26D0BDB462E1BD8662D01AE5E2B2D8022DD85976525BD3A79D1828628D816D06402AC0DBC23237D6D34FDDDEF72FA5425225D13970E25B1BD7AE9A8CC46C0AEE8FB425EDDD70601480D8017239CBEC2796E5120977060848DE15F30038919A4EABB6F3D765D4D4A792BE50CDEF77B03D244D010581D8B5789F8000F7C50C3F1C8DB298560327FD461011FA6D0071048D58D51FB986EF8C1CDD90EC04AB5979E39C0831C6246367B663F750B6FF34CA2CDEDF3C4867A0FA109A1E411605AEC1FA70998DBD3F33C1F3C48C9CCAF082A093F80E708998D29725E44EE536E3529B92C96B4EDD6459968D7AD9D6597040E9B1DF5E3B0A2DE597AF7C2791DE6FF57FA851F18C9453A80299DA98520C30DB658B651BFF4C9D0FBD05C1BFE9DAE57A7200DB95DBDC7FBC39E231FC5CF431E2D0F94E32C4723B664A437F1D9D872ACCABBF122F589F57738524B5A32029D63C9A2BC0B3F25349A87FBC0135DFB31F2FB025D0BE80B4828D7B39ED27EB22F480560C64EC56243B89FE7FFC5F610BB087A04A987406C602376830153CF54802313009F69B5E2F61D34AB5D11F733CB967F11ED52AF7594D97A0758069A4F72DFF9FA4742A08FFC6F347F8C63105FB261B562666A7DD705F7C739A51385DC519207129AFA51675A96BC417A4BD9D097F70F8A540A5C0B622DFBFCB93AC8F9E8A3F0301A950840339CAF800D12EDF2451683AD58FCFBF79844A81237A84B58F4320023B16A434FB4B7B312C7F33E4FC5766E79285978F872C7312C0BF4A311CF0B88DAACF30C068088DF8E5A5C31313517988E08FEC848B99063B7D1B6AC3991833EE0DDCA1E0CEADD38595D5E35DB219B6D8BF478E5EE7BC40B4413F8777895D03F8004CAD7301C5C5A37F2522E27BF9C1C9E600CE220B614884B51B00DD4A4D767F702D3EBB91ABB636E145A5DD839ECDFE9FD4554AA8C16311C17F9EBA2400007A11E0FB8228FCD6B6714080244A928C75C8EBD3CF85C23A47C36E7D1568725F394AC5568218D13EA11420002902FAACCE2990EF6B7ED07BDBE2190198E310D0F7B8F219010478440C9F7FB777440BEDFA29B81AD0E29E3225079D09A0203903ECB00005CABC33004A0B649402304B4479E8AE230904AC02111300FEF8043C58130054774BEF02C1B249960EA875A4467A8324010E68C000CD646ADB20C0055B30406409ECC0802823D853038C32002B4790CC131C060E4FED1881A6D98B9B50196DA1B9E77FF1B3266C0FD7922FF78A17E693892842A0804E60C011FB4FD0CE347E6C50D383689E121CE5C20822EDB673838188DB79B080C0EDBCD840C0CD7C080191CFB6D804619A051AA7FFD6F3AF51F2429E905AA5FDB9855943255A9748C519B14694CE5174A61F4F3B4F48D24E8963686B290C44DD4572FB1154CBBCFEEF7DB014F921BAEA2DA4FAFD156467815B47471E714ED5DA19A4268D8F4523AAE496EBA8B0AC6C1BF5147CEC04C77678FD9D946F7626A73E6F8B28B57F527E91024B33BB1BF5EB5877F780080C943A37690C293072AE1647D3330E740630C2AE05F9492F3758BA2EF41E613A5D7F25AC80A319AA92615BDA6A87963D9DEE8A8B337771D71D92ACA44729B6FF578C1F935442B144279370587D3A976FE43F05DC30670B97BB648392DF344ED00D4D496DA3BDEE0FB389F8438E1277FBD2501B3A578781DF69DD9C6C24DD9EDA4F29946D46B9CFC35A5D52FB08BC3FC818AF7ECC88F45F6ECEEDA951C3BAD146DB796372C7C0B136CEAF6AC8FFA64C1859C1261D3E54FB1B4749A71FCBD19E4725D18C8504DD7CA3A8DA1EB273858A2332289B4C2B212D148A78888BBBEC8DBAD75F31AB836FF17178C12A33E120EB3C5528D09E8A85ED31EF2548F9591DB72C9E401FB92B44E1854A57B3A059861F73E1F7C27CB25580663B87A15E627B82208A982016F4EADFAF8149358EC9D04A4C23AA90D999B810F92D3EBD6F9B44C7BE8AC72E485376E42C9682B2DF9D59C5237861EAC65FEDECE38D6E8B7E28290F1324CD4575D486E8B078EF88846DB1D9E655401273D39B6AD1E60D64294FA5EEA734BCC8B8F971BEBFDDD7616E8E61420B064C0470CBD48F15C6CB4B67A27CBECD5A486DEEF0E9E8A5D117D88B8D53529E43D95F81D55DEE1EA7DA23D4138332D95C41920939EAA754F7B91056551DDE11C6FA5833C1D5789953BC8C3FD27404CC2BEFDC6B6965AFE534316BD42F550903F3066C5601A4A687AD55E35713DD6C18BDE177B5015AB3ACB51A97BEB01F9F9A37C137797C6E9CA18407F84D3ECD13F9BEA0C557F5173FD69A667516C9F5DC50E5A9A7B000CBBF58824C44061BA38E663925618895895F722C57A3AAE29A70197A6F3F7DCEFA03C89C5BC23EACFDD63FD450148DE3279B84927E5F890F79C9678353D59E3183710945823C7DD5B2A5D78B31EF4D66E5BE3DC2909044B2E9AC00C00CAA7A914D427E0E93CCFC4C59404CC382A90F6825B609F653F9E870A910D1CE831A8E3A8D30FE0163965EE9955FDCC915695D5B531A60BEE721ACD4978AF13DD0FF34FE4215B426CEFB0F60E55153A8AF2B6FD0833B8F34F7FD78E5068C0C85011DFA7F6BB689AC7DF41C5C961F16ABF57741AAB81BBC9F501E24C3C12BD12D33234F512462DB36888AE2BD352BA02D77B04F876A83BAEB7BC10A3152F074E53428AF4BD273095B2A9241EB936CA8A09FC3DB2AEF420A497E01A49EBFE5FDE23CE95DD27EDBEF5A23FE5FB7C0FAEF9E9B3F4418E7EAF6C8EAC5CEA576850C63A1B82AE950EFC63D193F5A5C4A6174548DB592F300431563C7F38B9DB9B9387F961BD7EE256959F7C4331074B459ADF7ACFF4397CD5387A013432004680C6FD306BA535A9D84B9E2B26F3938F00603D43E134F63904E0B0F666E67F33BA00A677E63E30F05C1BE839A6B449CD623E92E438393F98E01EAE32F87D061DAC93B4A04905261B77656DAF38113506A9131F0B58AC560CF8B94D7A8E280BF3363CC69911D5E1E4F8336AD69C28F885762DB25C4E6A5E189B7DE59059ACA283C5BC5258BBE4FBFE835B0388F94DA6428566B069DC8F7CF6D9ADCE7906DF4D9124693C3D34C36763CE7658246F20F3AC650DA53857EA8B9B13251660CE3775D5E25143E1A13F179F4AB8120CF573FA3B5FA21F9FF94D0D704495CC73DEE29F3B6B320632116B92A96FA704FEDEB2C713AD7054A8F7BA4448A5500E544597F757FCB03A1DBF7F16EF23DA2F90666F88B28573BEBE897898DF7B968EFE793A11251F3ED25CA93A67032DD3DE5421B8A58CE1EBDB322F477B6820E260A0E1C1410323864AF60D8D20D07F3F84AD8D524CD7A99069A3D414834DB8FA236A65064CBD085D91D9094F3BE00A14A94303256EC9BE450A90788837B8EA84A3D50EBC288F3EF0B71E0BFFFD372892D43EA16534E25C99FFC4BB1E4C79A83F3653680FE64B670E0BBDFA80EBA552C2623EB086F92259C06B991E3D95C797551C209EFD4CA60A16EFD8CAB9CC9764BA232FF71A423F6F74323A538444BE6156240BB598EE477EE38BB29F1C61E353FDE43A21C243E599071EC392BF5B0736A2220ACA9B8EAF02BB86DA2B560EE26C3215AC1726BC4398896C679A1D9C863E0A0AF03CDC1CF8D94F38E2B6786829F0B7157C22BFB7C0F3A17C056AA68B4BF6319F3FC2030C954152ADED7C12612078FB9DF6E1EB5641BFE999AABD8B4732D6C819A48CECCB7E86A997AA661C333E88C92F594FA8F4EEF5C390AC4B4D360D5230C1266C6EAB2964B498689D040E8177B3499EC8671C54B7905664B50E13D93A8D8E6A44DBB6A4C193B7F194C36AC8D83C8D6D1F10B832B2883500A9AB4501B0B29E5376DFCB6C1A875FFBF39CCE3058A4EBB964E886CFCD0984030EB631D36141C70EE327E68E85B7EA201912266614615DD1B483A59FF54351265039F4BBC448B5E00EF0024E26F4A4BD82FD8972D363508EABD26CFEB82993369F0A1AB02504026805385FCD32D114C010E3F78BD5663EBDF8A327E6E4B52CD97D11807DE80665A3ABEAAF9026098335C27D8C4BFCF1738E9BDE54EC4CEA71A4E255EB82A318A23254E5A52ACC50956B0FF4B430AB35966E876CE92365895E53E92E600CC46AE587C7DCD5FF892CCFBC58E766DADCB3D53B6B6E1DC3B5AE35A1A15AA5E855131A14E31FE32FCD88A7E0302A9B67298ABD193E56DBFBBA1315EDECF1FCE8AD62F97F417CC4146685A6FD43A9BB78DE22F6558F8C64012BA83174F1779B21F3F3388345A7EDEC8FEE1C719BBDA10C6F2E6932D833CA666AEACC5DC75E100ACA4539BB21D9622B305DE74D72B89B00E3C455C7E9493AC923CA7FAA2B95B9F9282D61C06F76E9830F6E52E87F1E09812871D34F288EA0E35FE2E3C2883187913E4AFBEAC462E865EAE1C361D41A3E820427693A30754DD7E6DFDAD2924C20D887A9598F2ED5243FCF10DFEEEBCFD222327F94D18A9C26951C8BE3F140954623468A58C0DD5E57A19A8BC8FFEE7579F615D94A10DBF4B964E5C6AF333150364AC6CD48D5D57312973D359ECD17327F469174295F424370778F1D2C5B0532EBA1CB741B71C4060EF4083AF755FF18F66F3081B0A30CDDEF58DE44F22FDBF52FD1C4A57007A17FE9FFFF7B7B91AE3002B3328D134F68B72ECE8AF72C0892C8143F6D00B41F83CEBAEF627A37F31C65C49DAE5F2813ACDCF565303EFB857F832D5CAA7F84548ED959F82EBF7B3E88D8AD6340A08F81FCCC97A5C99090B68593A7227D6FF8F7C3FD3E186D2C251AB79232E58DBACB507C0B034CD239F6FE4956DF05A6B5477D2D8AC63EF264F894C0CA0D0F89333C26B86F42F1F310256CE3A27AFA6A8A315342D6B28F4BE9D43CE018F2A083B2A17A5BD10B223F6A222FF9F6F9D5CF7978590A50918C6714293A9A9F64DFA8420FC806FF9DF5132D054644B5A65916658800CE1AB972CE2FF81B17568C3D40725D30D1DB0D940502E5F6CCEDC69E984539ADD5DAC997BFFC134AB9CCB19F8F937222C9EBCCEC2729E7DF508AE48E8D36919BDAB397AFF53FC66F52C14E190BA6EA6E4EC7F0774FBBA3E7EF663FEB0C0824F5B2CFC4E1D745F1C73936CC78B3B787B4E89C7003DED0D29952F43323E3D258882EC61AFA858717F8CFFC326724101D73D9C36EEBD168D8670031CD7FE60E0AD7A01FF23911461447009B8297F96DB387918722DB233F30BBF923472180F029C093EB879FF7037BADAE6797DBAEC380F7C91C423312474E1A00C63111C8C3E975E544834773AEE69E7B1492F1070F177C61BF5584210E0486AC94FD68DA19D87702A9B3C49A0BAA796B4171876AE7B5250133AB328819F8A76CD0358B1B0EB103FA693B217530D5E24D81FC1CDD770425E406B224C60346BCCF3D0DEE6325576B5E3188E56C7DA8FD0E3317645F2379E174CF6489ABD5473F1C267A6D034F0B1C7D2BF3923AA3ABD0A58593A97B601B4C3469603390C6602780F280C2B74CABB9C9A6CFAF73AFE626B5019293DEF6D394876E2C3983D9DF9808623A417A6D11AEF1BAF9618CDAB1A48021480FC1C0EE481F703DAFB4E3DF03E5D00F32F8EBE0788A13B17A30C2A4A4C05C7685269EF5D7D2CC0846EFAD81B753F4D4B2BB6CCC77C67C978B8E737F6D40BBDF00A7218F33C65500385CB587D38F94CEF5198704A3FE21CEE203CF1E10F44025B3249A3082CAE8F63B963D860BAD80F79B1B026E2DB8693868792526F6B263D8076E3AF9172245FE8BDC52824797304034FCD46A5F6E2FB4BBBC9B143954C89BB7D486A4B73684C8F61227994710E4738C5C63EBCAFC3A1110AEC4BAA2898309DFDECA3B50EEF70FEAACB5897F14741D6F61046BE0010744AB3EF65E0682CD461FD21BCDA2093874436A72A5D012A1B1DB147F062507D942253EAB61F255053BA28440A117DCA407E8BBBC27EE58A3F7F7065B8FCAC257915F24C267E67F176D39C30923B678CD2070010090A6B9FFAA2B64B9C8D528F6E2CE8CC18A8EF99ACFE612F429979F348966D37779AFA5A175866ED9A8654FB01D73EC2F5C51F15BEE7866EB1A103294D26C46E05938E9F73A2981526E3EBC94A5BEDCC114B778FB20800DBF2AFC093D1EADC0711D7E2D8F7B149B4E5203CC449B7B9C368B9A55BCB0AD7E4B8310040AD630DDAD27E550AFD9F1ACA8F24CF515FB6AE829E49DA7D96811E38C0A9531533A899D71BE6F462D5104650EB9F4CBD8E99AF05D32259DFEB349703D2AA1371EEE34BE71CC20FB1A93444DF8E2D26CAB6FEA362690445C963619A9576405D8168F51EF6F02AB34F17C3755859DCB19648487C17068F7C5A2A0E300CD7F633447F93949233E2FE8C0DFCA060B9F3369DDEAA8A3152BC75066CCA4F16AC72251E1E9A968C425A7F4310AE4639430FE3AB0590CADB61CF8857BF1CDEF84345B0EFA2E62ABF4522A9DF51FE35AA5FA582B744FA925309FB45681F99DF2C4CBAC5A1F510B70928B5C8786E0FECF0F3B4C260DB828ABCB19E7DDF2A2C2562B78A0CEEB8BC667F88F5F5CB3AD11BA35909F4BCEF173B15B32B42C9A40B3EBFE05D356B2779C330C13C8B98A5CE69FD69B34F575950CE04255276A16FF00D13D6804BC1A7EB71013D3DF1093BF7AF1FE4453ACB2C393C7C869521EA841A2CEFA45744F5EFBD69C5EBD01B6FCADF5A58174602309C40BBC5F4C8D09B59D8FD84579BD9679B0B4B5ADFF9B6688B7A523D1CBC0B6073DB711CA845EC0CD331A0D48B9D497BF30D913F3E8ABA217D518BB8CBCBC93F3190BE10A3DE16B4C2AB6BB8576AA212BF759D42A4C704D61D719849B13B59CE63CE6077D18715B26C5435CBB86DE294E6E0CFDA85395DA61C52E510FD0DEF3E48B11A4A9003DCCD60263C27655A6071DA1A993B1B06087B0CE3157F67714A08B251653EACCA8E95323D186C5E18EB493C38AE48524041EF4D97787C17EC9355D0DEF25918805E3B3C055A963D6343573ED7421035FF84CDCB0A30B194D65B5E09E1459155426B21982C8F76308AC9FB859FA7229D87BC11DB00B1145877A62BE30B6D7A1117D8F5EF2B83147ABAF644A52823C63CD268B929153EC8FE5967771ED23B138D552B80530640C5B025E98D0050087F3AEF344C42F0B352B53A8FFB335D60368B1C1C50FA00DF62F0CBE94BC5DB644838E071B3030538121D011559EE9C82328BC82AB934471813C6135EA1DE8E6FCAC2B72C31E17CEAF40987A5ABEF2CFCAB55778952A9B47D8B92B8EF6A28CDABF17CCEEFF63D831DFC033FF2818A49AF5EF1B84B6EF454FE6E5E7122A434196949F9F6C6F661809E6440A56FFDE33BF61AEE7EB7633C16645A0F1332DD1DEC109A87806D2DC56E2F00D3533E7570D4B6484444EF70A69046A3DEC42C229804A2FCF4CF4202031ACE1ECDE60A2A6EDD366E3E3981019F2D5E502B7FD110C45ABD7744A71F28B801D7895B3728D1706972F6FBC55931C52150CC47CA7BF3B8AB76E673DF367175E22E160C1764F5AA51B4C185F7D3E75AFD33B4CAA49D673B01EF0CF40559EE8CBE2360C75757AF9C880E606198BCCD8BA123ABF3D5A2EA381ACE58204B272A34AED62BA69129F4B6F3677640CE3FAB657A944F348F90DA93551D89ED27BF8C2EF9D8261744FEF57E9F91EABFAAF2E6319C24C9655175B21EE89EDF170FCBA3340AA48EF2A15700499DC1FE57A5A0AAFEA877F04256C50E59B77738BD169BEA2A2D5C077839E5B00FE4C1B106A699E447EE268BF5848BB85CEF8A451EC785D1C369B457C38D3133E6FD2B1A62582A540D080B87B15FBF2464B88F225D086131532E53E9307B1F0A29FC76C1A24076C4743DED69CA128ECA5B5D8591F15D7BD742325BE185D88BAEF7303A410349C8BA87C0C6257193311F45C1AC46D5EF38C4CF91ABEE838F639AC291E09FA999165D5A00C31455A4AD24E25FFA1289C8641992A27CEC85F7AB7637846DE1C6A2378148C221232B5F0423B5B80CB4740CEADE8F0685C81C33E337C8FB1FA4FF1687F6B67E65F74DE79C436355A643A2A4797EA4C7BDE5EB736DD5AFE303DA06B1DB4E2C7F3D90365E8E7E59EABEAF361C8503E7AF1F6F9E0DE43B108C885DAC65141E09C6D8513732FCCF428A040A0EF4BFCF717E1AA8599BEF461F71954347933F84381B54F4057292FCE835F80E782B8EB249A3CD8841AB9D7BA6C81AE00083BB0B026DD001FFA64CEEA42FCBFEDFED9C738F7EA18985204CC3284E45FC1D51765D5B8DE4053BF37EA34888C4B5CAE7011783EE3800691172BDEA04818F8A348391C855B25FAD03C955EE716D9A59CEE34B42C289AC03C271AABCACE7C9932BE19676B6E7C4A876F7E93D373BAB3453D3F387FF5F4D66E54B6E53F3BC9855C67A31F80EFEE45E7A30A7B158C2579204BD6605B8001A9105D68765151BADCF3673A34C9180CA5288B3D1841368E93E0FE53D375E34D00BE9F9F90F839C95ABA568A7DBE74B771AC219E75A41CE2EE29B89974F62C368DD1F0CA011F148F3460E048A7BF4B5E25C4F8F7C6A9F955FEC68E7F74AA69DE23A900800523235354AECADDF71D33FC30B827085111C57372B28E434CC9D0F0321C90A2B0D04B1F560C269F96F2195335E1D76960D30B2987738E0B8D5FFC1B512D6B325F9514E66FB976215B11D57392D76F88D12FF21FA65C5EDEE3C4508FC48C079BFF7A69BD4537C8836AF5786C0A5E45F433D214C548979925C37C50A4C93C5C217A64D83E582F154FB9E2A7335B532ACA4BED04344BB56370A60C743DBEF1999C209076552F7C5E30DF831DCF688BD444165A959B24D9A487D0027C301E9B0AF833F3ECD2C5DBFB0970E772751D66737CE1363B4CF227798A26F0774C4932521C9BDEA98E809C37871A75447D663FAB9E0DD2449653C587C4E34B54D067740BB7C867A20B4C03C096CE54ED40E32BFDFEEC774B397A2EFBA3A20177DB79D69C39648D5DCD6E4961D72E341765302FAE483A962385A4D4D995BDC778A166F5B2268DEAD87495CABFC1BC7AED73BDEF01056E0E9499EA06959A4A9353A0C11FAAE99AC1B148581AF8F7F240165800133079D5EFF8F2180E85BA2E38D778FD60522F6D8C1B22844C5DF39B674BE318607E5EF0AC6FC13F3AF7E187D1B039106A979143EA8FFAB4217560FCC745ACEDE4B34912C8E2CC561746FEDB0E7188A22735BC7F46CD0052C558DCB070FD2ACF1FB447B077E5B113DFE5FBC586B04CB3D33131D23F99869949EC3DAF6B4AC1F4B42D9D5F229F37211A3CF8DE0B7A874E887014B7CCA74E609C489F848D349A4E7ED3E2F07108D2ABAEAD3D31D0FA11C326CBC5100B244CBFB39B654A714F2CC5575E98332A945E5083293FFBA3494224F54B24630D2D43C69ED9A685E7CFB72E665484DB17893E746BC8134D4EF316E006E664101921E95031B9B97FC4ED0E8478A40F8B704E62640200D22D3854FC6CD961A2E518ADCEAA7CA0F533FF53F8107DACE390572A53F551C73D6985C383CEC815DEED58408799DA3C2242E2A794D2BDB7293733F857E6F88BEBF6F4A198EB004F21D773F9F0525612F507FE36B497A91EFE65FF59E09FA5D634A472B496EE2E1000320F2DA4FFCEB869E489D10857A5AB15094AC75A5EFC844340D1FD7FD7981AA69F7AA71C36E0575DE1D52E1EABFA3669D3E6468BFC62ACB432420552281818FDB359FA0D428D0324150F8C7C9A85382ECAFAABFB0B57709856B336073AD8C1C503AD26F3C9C735612D5E729827EB69B3217738F21A391B4C1E2C195108DA6BD3744A458DFB0ECAC538DEFFDCA91B5CA314D4622FF9E18047C64321FCDB4972A987C8CA61C1EE742A574B15A01CB5F9890A41B05082C3F6D478A90FA65A61D1439427C9A25C49F5AA86F6212DA7D4574C06A53CC95D3D2B6B3C202A5EF0616C58F5321F6EBED72768C8BE48DD2483024CA11BCE7FAA741A0FCFD88F2C3DF92FF518F2D09B578A5BC04EDE728A0772ED2DE6DCC4D1B62E099F22D26EB822C8A3C4D75F62AD3F6D293881A41D52C36D43DC012825BADDD752D5DD51548E9EA2CD8A2AF130CD7932A7B5731E31ED43EA14BB5AB91C24FB2AF3D0F097955B70F5D4C9131232E38024ACC630F51BBDDE0DAA89814E3EBD9CE324926C9180BE2D0DECF2DF8EF892D1698849942BDB06F21A51AE6A03F2AC65C8D71D3F4F5D91B133D20771C5031F8CAB0ECDBEC273C9F34B14E8D12C7D606A38850134769069074E12CB6E9A79B3D4791095304A2E76699238F48A0D71C0C550379038C6BE789AAE12AE8A589A589BFBF452D2230D569F764CAE9375D0D205E99F358C62323FC938A3C0F78A75B2EC69C79AE5523B6198CDD62E97FFA6D8AB5CDB5447D3DD2976DC158802331953882DE79253EEEBFD819C4B0783FE70784B759EB0FFBADA09ABC521EC89A4D354C1A0E27B28E710FA140E9AD90045302B020C84B2E454566AF90D066650895C995C61D228018F3CC99576F8BE75AE5C266FB455007650ED41F66B61238AB953DDD2569F65FA803A5FE0A3FD3DF557AF07E10362A9C3F201DBDE2E1C7D6F4F9DEB6F716C87A85E9C010C5448C87294E299765ACCD497DF0DDD854EC8A0F2DA92228B6789ECEAEF6C3064527232FB576C20496BF334B415BEDCD7D25AC1EA200A625C6171C3A70E8F85D0B262ECB5325FEB585A58BBEE750CC6077E96BB26612BC906BFBD90AC32C40A94548165225068EBF9A099D72B3A56A08146C849E295C87AA40544F1AFB7091E1CCA66E8D7C91F2E0DC177F5209155FE0E374A4B594E130E68D7620830C07EC797113A64208FA165D81C1138C80562D544BE4D63C4A4815B34A3A6B5CB1A43FC9CC4B3E8F4D8C2DBB52A7C65F1DDE57244B4127D8008365D48AE25450A106CA6029336496CEA064962B69F9920525F1BA28171878275928BF167C3E29F254C8A30271BFA4EA0C1FEF7AA52625466B327C36497257A1D1A5F4F10A2C759046D97349EB38A461A02B0EE3039068AC9B447C13029C197AD80AB678DCAD44EEF98FB726C39055C2752C3AAF2EC026C93BBC3C676F075A8D76ABE7FC2C7247632002C832432DDAE54DCA97817B50F3AC76F8600778A6CD0D36E37557DFC11D9EDF6C033EC4DADC24B953718628111FDC8086AA717382C0322191A6A91CC960B280B0B32B700AB9E3BEBEFBF614B678067999B02693796E4583904070C04AE1EB0F061E4B1FA651A8656B97B7D450357E625DE4E217491B1B281718AA4C2E34327690024CB37422EEF8E16CD92E31098312745ED41D7CCD8BE296CE58FA81F591B039738C9491C646F9B093313FCD896D175E5C82352215B25E6DE4E9B7EE7A30B5643F42F0F45A34687E2DEC0FEA3513E3EDF72F52B6B0D52B591DABC5008CDA0A2952465F77B8791057E9F65F5B616501A263AB0425EC52686B0B1F46F650F0921CA57BE3F50B1858598C2FC951BB43D07DD1627C098EB856B3A3FBA298481E6C8ABA0962260FDF84848659AF3ECB9CE81B1B4A4572FB765B95519AB9752C5200CCC5A233E2450DF40ADB7B8CDA17F693398F1351F53C547166DC903C27AE312254E5A00DF8D01BF6BDE0F0C9627981AD6FAF99327AFA1D1FF31B74E2B340228147EF7DDD3494F1E4CC5BFCF677A8A166D74F5AD8715DC911E2F120FF4C35B94E40B3C5D3BF2C63667D838CFFECB61125EE38DB81F4653F1C873B01D188D191B504B2F2365811EAF62EA827ACFB014F71D8E557AF48DFD7F9823C17BDD1F2B299633B2712C98CBC5622B7B4BF170C4CF4B524CC291FE1032CEB94F875B210ADBA093370AAF2580EF7428A6B07AA1003A5FFFD7E4AF6C8898E2D2CDE535B65B819D9821D0998C52C7A04D4D76BBF47AC1DE50A1FD8C90DEF4AF36C35AB147624BFF20AA5301EECBF95DF023AAB16C65AD573D6CE30887924BBED7BD8A4D5FFFB172EE1118664DCE08D15891DFD050A61FE7066D79AF86C82C361DDF4C4C228A657D2E233B13F4A581F6AB76D425C39B67864BAFCC74483DBC3C7ADFD6A6362C8321FF312D54EF997E3BBD8919ED5453A9C10D7FF65EF9DE7B0628F58FCDF7F034AD52D0876FD75A49DC8461DD66549C1F6BB1F0CA8819275A824E91F95BAA83BD01904156AACC9C9A9DB8C093FDFD0DE94BEDE1030299EB117BC0E85D2726432E7C1959EE3E084D72A8CDB571BE4D9C57B1149E3AE4F2547CEDC12070468AA139B499BD389D8B7CE92854CE8FC27523F48625309FA1F2F7213743475B774231348120FCEBC5FA220FF07CE512FB47A4B45DB34EC6B02920CFB34F210530A8D801272F0745728E03A4FFAF8FDBD45C0FE8B9BFCB54F5B19E5E5CFA5130C8A270235520E6883E2989615137807572B2B294D096BEA5A99798FE9F56D98C93310C6F49380BEF018564E6948A997095F094E3072AFE890211628E89BEF539E372D3B29A9520D04AF810A0F21C9D86C2FF26B7FF03761CC6FF1101347203EF020B7EEE2836A7F5DA29B5D2B57A861722466411CA0D8DAC2430E4C857FEBF6BE6239FAF14D958F5ABD1A30BD8B3F0BD50C0EF042B3148D80B4C8843EE2581F1AA8B49B25CB08430E3BE396EA5C724B594F7F3812187B3651ABA6B434791866B41751C0E296ADB9AEB0A9299140C3CEFF26B3744E0EE8A6CE65AFEDD65F69F32923768695207FE3312CCDACED681161F452D567E8A3F54315D020D63C8705E0A6883B41DC0B4999D4BCF79A34F193F5C0278DB20DE2210186DC04310A6EBF0B6FA2E9740B6F62AEFFBC4E0178FE83BA1070FA053F9764A719808076E5B7B0DA5C2A70AF80FBE472F6ED5D0B7A0367AB59BD03D1742EF3145B0E8CEE21382548856504A059FDBFCDD01A772A14FFA97AEF54015593F3B4DBC5F7F04DD5C8250E7EC83B7E9494F0532D7AE7BBFA345C5F537D43D48DCA5DD8D3E701E4B7E8257EDCA8274B5A68F046C281261B69C089A5B89633DBCF6BFC7E735E5E6EF35951DA8E6BC15CF29D8A7E48A0828626BC14727A82603058F0CCE952837CA126427ED223F5FF8C8D12358142E9CF0FB86A66F48B0BB675554B687D462C230016604F92EA1B2DD391C6741DF079777EEDA26EC242546D55BE356A64603BA11EE6533AB84DFD11D29B41CC825CEF9AEAFDFEBC37290D748D118FE1B7DC108EE67B9CEE9AF4DD8B0C2E57342CC34926B575D0A8885DE01BF11EA1DB517811CDBC5381C0358F98DDEAE392DF2C0471BF04E93B087E123C1CCCDE1A8A8E84613B7D864E3481A688F6E9DEBA12B67D497F180C945669801E86E7B5BD63E954EA9CD7D6FE36E16CD0E80AC5CA41494554A55996052C5C47943B686F42A19B2336763B5A00BB84737A19062E35C22BC626B27BE4F6F1718B2B50AD7168F0BC6A50660E66F4635B46EC68D9C858D9F30379EDF22E8FD21B9E38B637C2B275F5ADFB9C741312447D4A420277B384CD0E9B6540A0740A1196DAA62B0BE1B52FFAC671676E99EB91409E3F2DB588BE8AD0E12BD7CA266CC7A7538BC02675AAFB037D89DFF98BB69CA2A8DD3AC0BE395620932423C4E9D0F69E34FA95D7AAFFD6AE1F22E40DB14B0E05377CB67E78CE482013ADE994F6643FE145C303C1FA49E037FE055E4DD47332E776ED4AA65CAA5B0A178DD94C216EDA39FDFF13AF5DAA08542AECA2A877DA5267DF5EEBE7A3660B80E06AC861C3CF16009A4AE27E210A30002044A211A86FB7C9C274CB47AB7B8769F12C349A46D93EEDC6A9AF69068738B5E186FCF939A8E773A1B749DB55FFB57F7F2284F80E7E70310E1854586D0BBDA43C9CFDF363CEB39E1CFBC5E3D6F672B7A943FF3737F5C97EE85BE14D320CE11DBF30F29172CBDFB4C82D9AF66853AB707DDBD6BDEB37B5B74405254EAD198428DE8760703600A1E1604B07AEF3BFBCB48D6D2C8E7ECF7DFB013FD89F071B372FA9AA1CB835AC9D768DC37B915A56E9327F35AA732DA7FC20A9EF340EC822AE4738AEF1DDD3D21C317B44DB59CA4A834E63FDDF68B08C7B0505CB4BC89A220B2D8E8580809B8A0859976B4D4BC47DEA7A971B3AE9710FA4B3AA3FDDD4E4EA2DE21B035E891DC7FCF8904D1FF670C65C336F0AD8E372BF4A6CB510D21BD15C50DBE9E369E2C16D375D45A0F2CA1C5C85EFAC655CFB09EA78A27EC301BC7C0AAAFD0CF7AB6A5647EE98C9773C812F48CCB79E8EF807E68CEFE93267BC1EEF37680D37978EAA712DC23F4D5A98BF2F5CADB37A70A59AEC1D101F0DC074B5CFC6D5E85A0CAB60A977D3F54A51289094CEC0431845A93A2EECB1964389F761113871BB62BF90210EE37EC4846B0FD1BBEE9D443DE3DAFF6FC03B574B90325A726DF1D3CBE4301EF40B18BD4F8833A8D3915574EBAC359A1C8443526771B5B36A9A55564115191BD56BCD051DD43974FD31620A9BC490E00B6F2D0C699291BDA3E06C266189E60B9D6CF6279F5CB47BA962BFFBFA87D4D7F80486ADAD01B2FFC2A4764B641099346DB10E1B01A03B9FD216FE4846181D1F52C391850ABF2D148E2D9D2815075D5682760E71B5A662770A5A8F7FE6D156202DF69BB1EA609425AA717CA1572CF796D449EA726524DDA529E42CC89EC40650F1B190E3D80DF71BA06B2275502D74124C26214D0C534614A82BC5E3DDB244E0C07BAC5DE3624198495C48173634A3B5B7E9B6A3E7A4A89F4898254042F324C3BE688922E1559E3268D0098EE4C9C0522559F1FA1692CA704DA686D781141EF9A667C6CE8645364897B9C9C9A77582810830060326097045F70DCB11150FB99BB1E5B47BC216FCC55CB986073788022543287402331EA096A69B5B3CB78814B84E509CEDCEEEDA011AD9959C318906957F6FEB324F84433A7A7FA410586CC20C9DA49860BD92600AD6F882BC351F2BF27E30B39A5E2F86F4CB292F87D0E3BDC088C23157EE17EDD913A6F8E3404757891FF90BD13140781381335B5154FBBA6CA3BD2A97403A9E1EDE6E8B314D55345483E58B03D36D5A6E3379168ADB259AB47430C02F6D62FEF764F1E36EFA21511CC48BEAB2F65B64EE4FE1A17464628D48B6411DBE8454D6AA1274C02B687B5A843A354C1A3803707378750A76B640D617E0FCC73E6884B600B562B5E79613C0CC03E9736B5E0C058A0DC6FA5DFBBA03D48F8BC90878E45C624208E3DFC9B3B7E0FD047764F7FAADD06F5D0ECFEE1467F6F9F972EC19DC936457046DE390FE0C953400F8EAD8BFCA490A2690B32090E2F95B94A809A7C9FECAA74D4C7F6BCC72383D92AD5180F1E08EDA39C90D6104406E7F7780DA3D20EB768D23157E5BB5EF00534F325ADC719A2FB35751D5B55B08E80D1E022DD5A938202DD365F77611D9D8FE33E4852B1F558EC4E781E91B74558BA6AC12FE27042351D27634D5F7C4A94A52EF9FDBD9AEE4A5C4AE684BB9988A19BDC9EE71104C5DAF9A86DF2FC8029A2D6F58623445DD96E55BEFE12CC159D2441D15967AF948B53859D4EA0E5EA8C99720ECE8A0998275E86EECF3E2C376C797C10CFC9CD835A6EB4F670757C8D3AA6C6DDFAA60E462F35F7F37C8A3106C44D8F2A1B48A38F26DF1F34CF7773E3B2047EBF5D9A30D5562E577B144A30087D930B4B5F84A50D9F6F39A3048D2E2BFF068FE42A30C7BA2D4A83EA64D910EC0541990C093086095EC59BF572F4ED22AE9BB4F919B3FA47B74FE296BFB2F5609F9783324FFE491F3A2FD29AD083E517153C1C05656C9E5F52DFCA129F5A83148B4809D1B57F8076FB9272D417F200278D1E3550C951F1275CE44178CC2BAF51ACAAADBDC913A6A1370F20F20879236060213B2207AB19AAFE4E48AED49A80F95C2C4035780383FC9DDF5F62FF5C71BD306162858CDC520998409EFED455C8EFCAD4CEAFCBB91C7100927A0E108DD20A4A96DA12C6226EACEC705AE27553F922F0DD4E7B0DEA608D06DFBA9D871E9BF3486A184C3350991DAAC2894A0CC6725DCF9EBDB538047E2784EA1442814B7711D9FDEE87C3D92B9B4B9DCFDD2A37F0D0D0B0A8F64B07F85BEAF5EF3FAB75044F1C0EED064D8ED8D9D4A068D24087289A31AEFC2C39EC95EDACDE3C69A829E67DF50A6DA979E8940DC46BDF2BEDA774A7472BEBE187EB583A6941BDBAF8F787689F1A90D66A73350DCE588D25AFD3935F57E32481C9C87EFBC71E97EB146C93FE05C4F16C35DB14D0F2FE5546634C9D5E4F1017EEF0A6CC80F130252532477A37F8D4AA04AE11FE7B6F0D41DEFED6F24264209412ABB08BAB8F014B70D962D091180527DC63EFF83CBBDF38F98F7532176C50D73042CCACD0BB85958C5215759C61C00DB5084758799D16364DFA327F3AB845B36F0512E2D7C9DF151148EF67BE3B130E8BBF4CD4342A1834397414F989ACE85F6571A5360A80529E4AB10141DC681498E10091184BD19DC6ED1EBF6F62B2688481AED6B31ADF635F4459F1FAA1C6D97A0AFC2FFC8159058B44F9E18BE73FEA3692BDBC5E7FA6E1E82EE0BA0C5FE8D7B16F7BB45A25D49E127A10683ECA7D5192DBB6C43C5E6BB842D8CB965BD40865C63E5A326A5D2A549E55612DA7E91A7388EF3D5A61E449EA431B8C1A6CDF8CBED0EF521441B58BFA59D3F79965FEDFCBD486A3B2E2E7EFE80FEA1DD65EEBE53682B5DBEE2AAE2A8F00A67D15CDCF1E01F84B91786FAB0C5EE5E68C5712855DF36808FC826313ADF446870C2EA8DC9BE2C8D8B0942604637285007C94A5CA4ED63CDD78EAB42916F8221E57AD8907A6770893F4E6AAC37DC253211BFEF02A6CD65A2A8221E51D9187FF5D96C55883FA0219648AB2BAD549A574C471651D2A50BD9A382B80A77F8FAF67C78C7B1BCD959CAA64407A54C468796104ADA3C073E371B9EB5DDC26582F7063AEC377D62180A37C6457EF314AD00E83EA77286ACD346C2D709CEF2EA4C3A827CF84498CD3F6E29C9032B4A7664AB3A20B605D8495648EB56B8E456CCB86806F532A84E51F31591E80743080E38B37CFD60E0652B6580437EA90F1389E2CE970DC037C03BE73E273C4369787CB97EAA449103D0CFE9EA2A3A997A5D12D67E75CC13B8D6AAD26E155DD3AA0A9F6F864A1DEB6962C5C885FECF0A43C4230B479091660F43B3E4AA041A152BDE76C09C3C41AFC7E4B7F28ACA3FE35D8E124EDD376B3F3BC3D6536DAE985167B08BC25673367A1D5B00881675F2DA1F4D75D99E6E0E280E6A3ED1FC58187E4B127825B80D7669CA825D149EA6D7DF53FE9922826F5FAC9509BEDC10021B56BF732EEF3F5A093661510E093DB7D3572EBFEBE457E686B4CC644CFB61A4353BD146F20A056810255195CC3DC7337A81F3DE18120AA6AEE658E423C6A0AB04AC5318CDA0B308EDB54CECFC6F11D804639D95AA9F39EF5DDDF059978FE72E8FCD43070A9F31913DF2BF582959CF9E3B7A1A222037D24401F0670BBE0179BF979FAA1EE35018A3E43ED40FDD6ED630DC0C316B0855FC6DA7E7B6AC07E37CBBD061F62A283E5BBB3C88A5AD12668CCC71DFC78A0D913908548A77D71CC59B100201FB3A5BCF273338F39829E74B250A3912AD255FC129EA0BE8FC83F08ED64C90E0F97702F5A525A896039DF698927E7DAC3086A3C7FAB3C1F03714D93186803EC75CF6EB940062C0964B575329E6306B48FBE2DBABD176AAF7EE8CF55B6C8B1767B827BB4758097A2BCC1D8F4FCE9C03DC12E8B02D4C1401686BF27F28E6C9A73C455FF5BAF089B224ED909CD238B2EC86E896F93C0B64865CA596A3C47CDD62DBDBF22A9EF80D372C5DDE171E7139717B6CFAA566F7BCFDA3336E33EB2B3B2755D23D4DD0300C07DC96535E8D84250CA04004485A6AFF860F65D03A9C97529F86242371725C8AE462A4FE9B8FD7DD6A29C93CE1712CFEE40568EB6A6864FCC671AC653E3003798C49F08C107F8BBA60869A01780CBA3C6F3BADEF4F013987C00B87F52863B1E8C0DAB73D7CF414607ADF71783CFC1A051B0849FDE2141C4CDFF369B98B83C69ED08DC1E88CFCDB04DD096239FBFB100253C40FE105BA67D0BE0D005B96FB13F5DC8F3C436D8CA7AE4655E694C515048F908D089F036B456E2F59E4D95E8C3F1B6076044A32C40175C7B0612582B84690C13D2B67273D4DF7E1A5ED3DA52774B1D6485D2E3E73D47AD12B1E1C0C2359B2A1272CDF1617A4D4E901F2E580C5792D445B43EF6C9A3B435A63C43037B23645C339D941B734874613D3DA203D603BDFCFEFA18E3F9F11AE72E6EE89370DB454CD7454E2996C4094D60353D95389E0AB8A458A4E558A50BB260BB7343CF48E09A499DFD47C660F4437B6E54DEA5B0BDBD7D3A74FE78B66AC1B2B63CBDE391A34BA25DCD5FB03F3BC698B3B2C4A54CDFED86129E9A40B548B9B094FCE7F371CE75F4EA85E69439A93DC3845F70FDBE5832D3DDBD25FF44629C553D405E48528BCDF5A47AA07A43518805BCEC96A155A511E171A33E66455EAD46F3CB0AFCABFE04C2FC04980BA0D015BA29733BD1A81B23032E70968A7296F391C42097ACD62A55E0D68422A90CD709BB94C275D17DBD707FE3AB37ED47493C89968E21365562429AB7BE3F9C22597A0311E3EDE4333D8F2D864E9D697DDE217FED2AAB2330DD37B01D26DB46FE29D3C0AC6827BCC4DFD589BC9A2E9395D9F522ED70FD4FD5A16C6FB3C7FD64FF28D1FEEC5C54BEAC2633AB0C37B06AAA877CE675DA338157B4070FF87075304F9CAED19F0AEC6D814F6F50A912CBA778FF07062E993EFD31326859636E2739BB22C206BEBCA3095A35EE7343A00F02F64B8013CFAFC29239CB985942D8213E814E6C1FC12A0ABFAC223AD71DD56286A0401C0199EA200514FE535530360E5AED40D00D7A5E9873500F061F9A96C65CAD905404D85ED010340D943294FEB750EAD62F2074F9BB4C004C55537C37E7F4AE87E02693A3B987D68A042478CBD979942F67BDD96296D0F8FB1BCAA6BE4F98F962EAD03F8426B2361D237C7E90E125D6C7EC015B0245F69A03FE652A253AFFC6A959784D8D91261D2FFF0849693EF300B1EB9225DF48D80DCFACA56D97474CC1D62DE529EC01BC8728F2DB45FF0964417762A36417FFDAB3DF8700C87B1B4CFD2E627B8774D9A3F8CD04F84BF0E4473A1EAD74F3AE8090BFFD80F0B6E2512FBED89903D2E9C2D8AAE4A0978F45316D3F013AE66F40703FF649BCF6505F5936AFA19F6AED2E3741127AA8C79BE34FF839BDF0794A937FE02AAA22C97712EAFB0574B43BB3F037FBDF2D034F6A8711D7370456141D6B660B1D80D6484D901746AF19B60A3C08A7FE3A7374E16723F383E44579A0D5FD45ABFCF70F4AC3B06479AF4BECA6C0EA058A89D5CB8BFA1A07D5FE0176A899F416B3C4F3F7CC5979453776F51A59C68EA80A5ABF771384BEFC10DF25E893F9576A7B16B8E14A1A32EF34331267745599F0475A1FF9BCB8CA1EC2D1C2CA6DCCD0EAD7066D101E4007ABAB13F18903C8ECDB061B18A9586D1F02504FFBA58E8AB7A3321F1FDDB005831FAA17CFD06C4A77E301D337212DC20B849AFE6DEB803D39F95FFC4E837C304026A7C86646B7967900AEA0531C3D0423E73A3F5B33E56A28D1AB4545E83EFBD4C7C7D185B30133AFC99BAD6DCA172742E8D214828400EB405D0C8098C2A3F3E9280218072A0855AA372B3996952B0C6E2E8DA36C65BB8658FB018F58CC4E0DF681943E4C30C7378F02DAC3D180E3AA203D4263154CC76857FED38181383AE0DB8567EB18CF6889AEABAF8BF0B25DF39D2854A1CDD8CAF2835001B6FA2D16B79E1D217112177191A6B9AB16F1E03D5ED500BA3522631868DAF72B8B31FA1FF1B4229D2C329876440192C4F54BD442C591BA1167E2839DBA7F1A14DFFFCC6EBE01DDC1EAE12D92904927AA322D1D606D47F7AB170C56CEF2EF183926C8E0AFF44504C77108CA318D132E2CCBFAE909D28993B16790819B6B5692D08AE7D0A1E0068959397873C211A50824858D385BC04F569906CBB490F7261715C461E9B741E46D73208F39D9690C21746E1216AA569FDFED43EF3A8D8517C6E212C2BDC5325BC2EA2225991DE4D16AC339235265EEE816830E09B9B5CF143478CC37A84E8AC9F578F3D27AE8F7FFEF33C32E40F8BF379EB4929E0C1D075A0790C679CCF0E510AC5136F706F6505596B4A0DBAB7AF54D3FD16510013932BF6421EC226052FE3D36FAF01E567EA51FFEB0B5164416022E13F060A93CACC10028AB951395B1AD5CA47B8D38FB2C6325BE07EBF75B656900E16D52F3C3EADE1E4E49BE7306428B77609C9CC16F6BC9FF536344D365F9AEDA7FEBF8CD18C03959220DB98E5BBFF37709A193485BCE363809F1B328A135F7B93A592FB2B37AE58E6A783CF5F42999FCD1E2E371549CDA289DD649A6F2CA47098F5C1FE300C94D6343FB891418ACCFEBA75A533E16D74147C1ED74A2D1E1E6B22F1FD115874089C7406BA72BCE0C3AC148BFA1A5442080BE52AB76B71E421729909A3ACBB37ECC6C254175A9BABAFDA8B00B1E6BFCE0A45BD1891E1BA0819D7BFA82FA17F4C98012FC81AACA129CD8E93C50E88A1BC03F49B51DF43C1C8E51972D09AC0C05998E1ED8F5E278BB362BB62821478DE2769CB66132E42685090CB55099A8478BF4617BCDA146A30499D42A0C62D4C41AB859998FD0D08372E1F14B96A192BE489BA7B58F9B3473C76971460B55B9ADA8818C7060C0204EBA7A173080381BF0578E84FB55F8A046A1E5A15CB0EBE4A116CC18B4B359D9A0AA94D32ADDDD472EB76240159A7C5E4CDD4E21206D70479A447CB0816AEC78FA5031C3A781F3E422AC2C16ADA745B61584D4CB0286D24B301889DE2FBC3930F3D6A680BB57AA4CC2A3FBADC39B8ED6A93D79BEBB33EC9F982BEE529205EA22EDD8EA16DD5C089B822680BED6701D68326EF9AFCFC848A14A3DDD7F8ED161E585350C3BCD375029E7814FAF1DDF0B0196335205498DD8FC2D74B518AE99C2EB339EDDF2941A23841750FD374281559C14B70DC1FAF4888DC6F156111268D8561E34DB6C17733B47F924BB55180E96718FE0F13927094745B89E6601D7ADFF553B6E744A1A2FC533B8C24D8FC01C01351FE6B0A734AD1453591293BF4B4D91CDBCA06D1366E20E110CA9FB25F6141089840E3E972EC51C07CFC7F900EB038F7F1BBC63CC9BF2200E024AF876429A13508B085FC438EFC7B5DCAA08F318FC1DE0C7AE943CF5A5F6538B33EFE9C7DDE7F4BE832B082F26EFAEBB827B0E02FC2FC2522A5F20F359FD73F519CA226F5089ED3C4FCCA416593AF4C93F20E3C61646F5ADAC3FEB0557520B641BF5FDCD356270C75BCFC5951836C8F6C71F1A37CEDDE0F4FC6178A3307DFD289F86BE027DB10CCF92D72A07C8AB4D48E3202DC4CD77BC7B3167B5A6AD2EA35BD0EA27F9B501ECE3FF16CF4400F2C865E2D088336FB096F1C9DE947E400298309864ECE3C663FCE9ECAF30F10A7272281284379F1394E275DF7DF8505FB5A49BC76482F5CDCBFA81682178A462AFAAD74E65572B66D77922C2BDC9297DA9A3771517D45E96E157E3C0A60320973FA21DC8EDF2FB1DD630B8B5FDE328C368AAFBE90B07AE15444E9ACF33E1C07E78D79E510DC5492E5AB8ED11A61529757ECED50C29668B6B56563C488EF3B4059531BFBB3761ACCCA8C5408147ADDE676E0A188FF7FEAA341BB358FAEE4E5BE3CA39019278A0EBBD9B520F08440EBEBAF1EF09D1DF7C043B479AC426643B8AF6186B0C995771BA81D608DD8FC56B2BE0D07701BF92C8BE324E69F3BED9EDE845956FD98FC62E9095F0C286AD4794C0300134809F3476E82D7F2CC325BE16E6F38D398C0071E7E5E9E94FCDE8A1B8F921219BA6F4A5BE3EFC48B18E920F9B11FAC523BDFB413D7F2DE80620B275143D927BB25E9105B8383A6A3A0FBA3D4870992B90A05D09741A5DFB8EFFFAF17DD0670DDAE5D4811F27F4CB29DE04FA3DF9FA7B746B977BE605A92AFAF25156A998AB0A0D4971EB048038F9B97C7D56D55DFB1F41BB6B6019DC04CD27996163D37433907327AD189DFD60333F827BEC730FAE0A93C9ED8E6920DCD0C58C2F7C2180C09C6C6302DB76CA43569A1ECBBB6C887EC0D9481ECC75FBD4C8B35E5F8AC3B3865FB5381CC4D814832DD68C279EECE0AF5D889E58FC328B976E6F45FF22AAF283590538BA7AA4BADE306F703295DC98A3EB9C4F2353662ED20DC4AFFF54C14EDA13788AB0EC77A9F9854FD0F4440F432D5901D47388D3BA4A41CB513AB6BAD1CDE6CB6CF489310ED209CAD1C14ABE6EDACADF3A13D363BCC8C79D4098CCBA860B20005D66850C34183017B84380001429C61010A5CE1E08E012F047803E08B123F5880820038B4C0404B6B69030408690B0408088441301A3A594B2810202002063AB4C458071888474057187447C31FD69004406F14F483432A06062260080C86A221DD1A4602301A05E3E09089814908C882410E1AF2AD613A003351301B0E060C145ACB1C2040C07C1894A26191352C0560390A56C060155A56C303B4AC810768580B87F5182843C066186C45CB3620B0869D00FC85825D7028C7C81EEB0003FB11701006156830C1E108068E23E0240C4EA3E59C7580812A6BB9080408B804C015945C870768A8B196DB4080807B30A845C3236B7802C03314BC84C36B0CFC878006187C40CB67EB00235FAC030C7C47C00F18FC42176FB2AE00090CC70ABE0C01652168712AB78B7C39DE1070CCD31110D50851DE1CB9F8DE1F72C0B9E382BBF2099615578648CBDADF5F12CD6A6D6BA6580AEFEB8C57C1BEFF9B6265CCB4F0FD108B8FFD719A153A43D4373F08CE184B3066DA123B946428361823FFAE718B39CDBCF58B158F14169550CD55A0E2F4EFB98FD48FD53A75E5A850218FE446D0878ED0C4195686BE2C8F2BA3F0F0306087092D4AAD939AC30A7DF7952A5693D3A087856684D5C499524BD578CF71BFEEADF2927E7AF2267DB0CB9F7F45F52499ADB5B9727F51722ED72895E2B32AFDB7F4A27DEEBD913FACEFBD0291E4BF7C6B101C3AC7254BE5CB3E7EB6028291920A0BCB92CBAF6F61C73B5AD077FF6E66AB270E654E3AD46A29D3E27BD7B2AC0FEB9B05F11BB2F6E3B98CE8D094796DA79AF1A623C2C0F0743AD4D1A0BBD7A544B3462F332687C87D3FE7441347F8E9D316676C06B82C7A1987D4C65B94278BBA96C6CAB7DADE23E01AA5039FF0BB85739AB5A8BDF7A0F694D2CA8C03B768C202D91B7A28AFA00854CF529132C7ABB9CF3A80FC3D9E32A9699AE4370AECDA66A66A5C114282871AD2BA58594CD136C5AC3646C9CF209C5311FCFE835B7A03E0FA91B1EC888068A746820F76F13A50A87B8912735C036777BF5615A12CAFB890E66F18D65BD759B79179495652153930B1FD2D3CC6CC734A3904B098A966146AAD25F7E52BD367D156E567B35B9F395E0C80595EE1B24856F4ECFD4261B4DECA2E057B8A3D851EFDE9A893F17556936E6D9EE472C52F44391B4BD07E6DFAF963AE4CBE75F4B094A76302431C31B24C62978BDD25B6360BD8167A0AA21A4A4176AFA965B6695CAA4D0F8BBDCC66851E10A5B00EF4811E1659D7ABA9B4A5CD22FE639700755ECA829FF192A9C7C0E46641AE03A9358ED7830D32EF4B6D0985E807DB0E5E29D3E2066B3E578741A754C91A5AFAA2DA2868BCE721AF2E7C225F547A0F14A72D70E6577CB27A1860B7A114AC2FDCF7D85C3CE0910866B74ED0E645180886A9A614F21C74A29ABAF2EE547B3600192E28BDD4181C3A112D21D3D75BB6F11F1A5ABF77D107FEFF136AA6409F03BDABD50CBB0D83B7A330E4E74770400FBFDBD8893D81C20752E8B946327EC2F924E984FC46D23F0524356C178E69D9728DD100865D5F1B761B4AC331DD6CA3EAE9D946AE0314B7945B915ED3901FF5796E16A459CA595735F15B63EB662074832EE21830ED38E1EFBE2FF23E44C851BA5E6FDC86095B0A905AAC9ECDCD4CC62975B2C64E2DB46E8ECE444F2FDD950EE3D522C32B8352FA2C4EAB3AD959B7A194DD9D3A70DB39A36ED7288D16AFCD4C236DB41E969EFE0A0D2627C677755815B09558BB580CDD68926AD9FBAC2ECA1B058A7FC6510862722EEEA4837C24D82DBE49DFC9D4CE7CD66D280DEF8102B6AB884E62B60ECC490F73D9AD7A58C410E37B386E2BAC126BB6C189411C36668B543C1977B6EA811136AB2B973D64107D96203853D6AF3B12A107D3CD0C06B96B3A32F42841765D1400AD382F8060E4BB163716B8BA05473148D3E705D8BDCD69D38713793F5293130417E7CF8F8F21D4952CD5ABA7DD4EC2E0539AAC837B56AC610F9C3EEF43679448E84B09F5E8FCAEEB8620DB40E52A1815FF506089167581911B6DFF05F1C83D36B7DA5C9E48010EA0AA78964F257B1AE73868A015167BEE1ED865C3273B708110CB9EB308703012AD208CC252D440D936C66CD3AF13A45E11BC7E7FDFADFC8AA6F97446FB2C97457812C3064D5850067B4B3A9FF7A3EE7F4A6A2CEF74F7DA40FC2CC29981960259E2F030A52EEFEEDE22B4032ED675A74D71F59374B256ECB059D10A75EE519F4588F5ACD17FDF522A7EEB4115552B36E7638A06B8BA3DB5B568751F34EA714D533FFB9CA3D73C7B0D6D9F9FFED799AE8321312EC2F1DA61B7ACE0E3D95E309954A063C53B1B557B70F367CC363C44DB5A8680E60478B431FE49811418BB4BAC7613283B35A08E073D5ABDFA2BC22C45699B9C1D28E397CC6E6DDD5659B160B49D8468A3C61A3DAC5B8626B9E46607DA3D4B3BC8EC617D5CACF9FA4D6A37CD902618359CCDF8AAA6E556650A87767AC1C68FF17A12775CFA563F514B75F983828F77754D5D13ED4CDA8A572FE7D9FAA3D014E9D974B0E0B05B56F0C96CDF06986A86482392995E596F70D8F37CA0D8F5A2B0678CD15366CDF75D5D169964D0B9FC5C92B74161FB4FBE95423DD7DCB4E65FD305A2659393A69A5FA484C1945F649933504FAD5451D93F17B62707828D1FA3180A1B9D1DEA5B9D45DCE46917631CE639553A400F30D53C85FA7A0175DD947ACBAF14884F8615D6D391661AAD92542AD0FE28FBB51399A39806FEF8C858229EAB1EC0D2F35FEF38FF8CBC4428E0A76511CB09B4098F3EFC4E70755FD9E24CF4AA38E17F5DF4431D00964D88288958D36601D0D343E15590120FEE87BC080AFD9059C0475DD264E678AF2EB1C974DEACC6E6C0DBC6083425E1DFEC0B74D114F55AE852A7F2E57B994836ED4C9BDD3AA4C363213677B82BA4092E74FA4E17AB66523098347E3601A23C11B7DE707888F57622DC6EEBD9BDE887BD4BADD4BAB7585D24C572A97F8A11B93EF86D0427D15B72DAAA9B6746E3B0E9CA15E7461CD0851710183D96AAEFD9F88B68EA778D3AB864137E426554DC563E0AF3FE4582908827A9BEA8DFD281A4CC9BC1E3107D33BC59C1B9D94FA4427C6A6168DCF6469A2D6B4A2CD2A3FF048D62AD8BF44AD65804304AC2EED2F6F6DFEDCF703D017CAB5D7477079E6B34ABEBAEC19F33EDC6DCDAB18ED0B3759166304E9E0368A5649EABDF8FA6FE85B87148C7C5405CD78B9EF22A945D67D3CCEE38C80AC68A518F1FF71696950493FA29209DA47166CB84C1DA2A7894E8F0C8CF5BE6B6CD886863F4C74092B21176CB0AF68AAD0A06D9447ED468106D8B53F95FCE245E3EE95CDC93158C1DF1FB14DCE0A2A0ACE0D3D90687172BA08E03697B52EFC064D51EFA4621DC33B8ABD0C5F06B59C9D526CA4462E8A2912EF92A9FD6BC57D40731B3E242C0DE5DC4EC24C8A5F550D66804DE266FE6AB825B5C5F0BA3001827C6294FC83CEC3694AA478E84A9CE46C4D83E9DB19360F58448A3AD9A2E935CDF118C13E33C024B0EB612B78ED9EE416CEF43DEE40570E6A15FBDE613E246E2B6A88BDF012800C54D92E1E9240E672FCCC148EA0E6106446DD855E1F35DFE13DD44EF5B38A3C62EEB4A82CBDB3E51BCD3775EA178693288D461ABA3296983FDC05B047CFE193C22467EB4E4EF53A9D7CF8E7747336B33111373090E5D71485071BE9E047F4753C681AF97C5007AF1DDC6C19402A4CA41F6FF2162ECA5D351F6D12D1D7AC16C9E45F699484F1AD021D37EF33C4A182C3DE9A09FE775FC95B5A39F068ADA9005C7BBD3173E9CA6008A8A172DB711951D6EE4E58C2EA8BDF9FF56DD894408BDF996D268A714DDD96D14FC7D1C3806ED28F01BFA6EBED14530783750C7A3464FD4FDA7F7BF925ED2DB86485A76BDB8D0272932E2D7419D8B6CEC96151AB070A6D51351CA89965571FD10E12474237D6FB1EAC9B9C236C626547C32D610FDA49E751B066F0FF9EDD125FE0607C69B8EBE4BE3E10314A11AD7C346ADEE83E96D6B7E62B21F33D1AF651EEFCE3FFB461524F4F15B4A1B01C06EA35AA97BCA4FFC40D5358906CF73FA8475CE367B4F2B9088D69FC3F190FAE4609D5092451613273FB849B534EAE2F2669366ECF8669F797BF4DA1085DF090D4991AE89CC9019761B9A373753640C24CFD0FBEF762EC61300BEE2830A67DA0263D8336BF9EBF5C7AFF28BF142408134E9CF719DD38A5C9AE6DFF1516C21D0876F1FD72B34F2A3FB4B395B8B231D9E73590D123A8C8273B6AC3DE64D900994B76DC3AA53B831CA88664738411BA5BA4661D5FCD8E7C5B6C37A7DC5FA59996D15E31198238D81C20D3914035467DD86D9E595DC8ED31CDFBB044235EF6ABEA451C7461E2DFF474972EAB2DAE0783ED453B19910D52DF6F7E78632FEC300D3E90634FC1A65A019675C11A8E559B799119FFFD0522F3D1E194CD966058014DA7A20FF15C218D9CD17E12F5D9AE57D4765252C21C61CEE72498F71DC1A074FEC169365124E291B89D3B3B71CA365ABB87E9070ABC820A082ABCF474F27279BB160EA183727F1FA60B7ACE08808A4853C62695AC59489AE821BFE7D2C8AC80D36D36474C16F9CB689AEE62A40774518C168DB5C7787F02353CD101945729827C87CAFDF190853EC7FC2C9642E81D0C8281907C2E692CA6EA9497F969A670CBE71DA3A82DA2D65FBC365F2275D554810E550CA759381905084DDF3E3B434F2C744C4D5E4BDC99E231A7FB508A54D91D91E8D63C5D96064DEB4BC60D9420243A352A3EF01680DF293C8967264F0ACAEA6CECDE36621DCD001DA429C0A2DF41FA5DA8A8F763FD14FBFDF14B7ACEAE98935C9F98989B6D70F27459E8F280002BB8592C48646AF3519A84FC01F5A9F7CA304FB45BA9A96EC7B671E9B4E51765B63998ADDA242A3E719234508215D80D88A3C0A726529C3B2C846795F95F2CEF9FFD77BCCC2CA88B559F3760C4A9F1EF34E1DF6582F7FD62D9BADA3310B0946B9E7A97346580711C61F9F0A6FD0E4B060C3118836C6037E2C4876CB6EC3105CC71F3906F1A62139A6B461AF7EE427EFFE5D4A1178FDEFD8E39AB3B5B16FAD028AF12105B729B0643BB3B116320CAA285062D2A5A35DB3B03CB5C60DA193B0AD03EEA06DC3CFEFB7B15B30438CDC3AE0FFB05B56706C04217070394D6B52DF448F48099D769386042D4A711D1CC464A370821FAD11A32B8862146BECD8CED635243509DF22DF9BB250C68459CC5270667BE11227B5CD934E003AA69A4724DB20D37EDA21FC79E19A1B3B68C9F7865823A1716932B6BC3130199C6959F35E3EE609B0BD7EF88B185ED64900A2D5B34227280C8713F6632CDBEC5EB20979F99448DB16849E2421A9F73B18753CB8F254E3CFC86552332811B41847B558D4EF1BB05B4A965A6BC34EBDAA95A2B5BF6FEFB09A74A1EE16262DF7590E4F23F67E707E85170F27474C9CCD88EA8B0BD00496427CF300CFFFD79A7A2C83B7652F66F773F571107F53111AC4699821E7EB104FDE34863CEB55561FF4DCB60C912F5815FC3436A273EC91C54DB43F03BF1CADBA858EA14F93845981722004ABFD8A87E69D9AB3229A708D32BD3EC9BF794B2F5A994903C1D4F17827D701935A58286C0BCBC307DA75C924C7518B4866E538DC687D4E7DD2659A3D6D95A47989B532304948D3E6C5D22C03008D5FC4C01C35E415A3D553A568441BC3C5FF4356F7473D6A295B0FF7AEAA54198C30A1A88E32A7C8AA4C8CD306BB658526CE5FA63CDFD0B2507B45D3AD0D55D4101C91D6C64289D749D81261E209D04A1D3542086CC280CA5F8FDCE1D9347A47A12CF38DD51C83D54C1D673BC176ADEF7DF7172D6EA1AC29B2661363BD1EC4B15B5668F29F99E9C8C6638F12077D134CA73FFA395F9E53221890B16FB17ABE0612A64EAFA21D09855EBDD0DA288D9644A0383D287E98E8A5FA7B0D0E9A3C60140FA8C97646CCD511EEA872CF3CB6097369982E71866C1563E9DDD1897846B2CFEF41B7853978CED3E9496FFC1DA9ADED40838EEF7ACD2943574A6ACAF55C19C64A398DD9CCE2601E28322F2A89FC508D42718831A1F973F558697FEF25AA2F03A95FB7594F67698E066766281A9FD0F09F008627659C48F8B1D041D2572BCD808EA7172BBC3623A8AFCB44821D518FE88DFF7AFABB01AE1F79A6F6DBEF2DEA4E8F6F0568CF1E7BC75F3DDD48F39A8B05D6C15136D203D92A26452F5E53F38B213FE9F75A613E8686945AE3B25F8E7B8C9FF57C37FAC0A8BA30DBEC2599701C44F4D5809487BC0C981B105AA836F75B258B13C5E76CA7F835FA2752A55A9AF82CF50F89DDD271210E5BB8E73774A83FC4ED8526388CA8BA78CA96F4BD170EC4557D620C33DB50BD3FF25CC5BAEC5673D3A889215E4AB6B460D9F6EF258EB823F5918C5C1C5D1424D4121052F4137FC1ED3302C3D71CF3BB27FD107F72FF0ABF0E1FABD3CC60FD2DAD8EB0ADC6A77ADF914D6641F28583A1C5B348EC940B812E1386939FEFEAC3E72C1D8F09F4527E5F185BB44C5BAAFC83DBE0DB26C5090451B0353E9AF4C5D8EA147EEF529CF7CE0FC54E964BC9B932E3FCBC48323926CF2DFAC1B6AAA1426B9D62AAA192EA70F9523EC09494EAE5C8E755AB4F1217B29B24523EB880FE4EB6C3EED0EFB0FA4EEE42C6A1135337838690EEC1A25184436A1C63902446FD737D9597DDA29741A2DB3FEA51841B57319DFFB494F4B36CE6B4A19D6B7A56744CD8F4CA669AA396A14557417CB95DE4D120FC8FD171FEDCE2EEB4F62DB85DE7C138B37550D4882F98817D1C0C572DC0C6D3FA148C4F26E675606A7C65409B49E850E98338699193B03380C19AD1C7F6229947A33345A395C61BCC9FC4E4342AD1E969C74519641A1F8C22D0BED4087A3B12162E5FF64E70A61714E42937CA83C19E42F1D2FF003E2A8C7EBFE6FFF07096C7508D6059F0EF6040C75867DE8E4B0DE7460FBDA31694DB99B70E2E18F8E1F270C70413C0BCADD1EF5945D2A8C954B10F8745D6FE66B4F6255FFD1BDB4886A5A83A2538E02398CFD085B7316D9D06E66972D3C5FC72433E7B0D140676225EDA2483B3CD7014ABBE6AE32E26378967E4F332C9026A31DE270888FEF44C84CA4556EB4DE80DF0FD59BC2A712E0D307B576837A3437E097F66381FC17F8E548B2A6F865369880689439A6B4527D90F9C6A4FFE24D5388EE0FD1611EC17C0F7FFA250730482C28FDDC9B935E6FE0EBFD5B07E6A19D5DE189BEA968659233DE849F4F864C5A5269BA1873357DA2F80EA5F06876F7F37B3E90703F9B382FEF99A28761C4D695BD7627F0EDA39F503A8D8DCC76B38B159C581E2390099AE699BF28D9B683A5DE3F7C3F929D002FDC7F971BDBA04BB874D93CA88ED0504B070441BEB10540B6AC7F0D775943AC71CBD598238B796E2FC4DD666A87691926438D01E36FA76193500532069AC940068521BD766E8A2EDDECF701D6FE7FCFE7326C1B7A48D52A326CA21EFE063BA618FBECE27CFC0ABF7F4A1B3FB94918F851FC2F14F8B7275A9DEE0CBFC04D4C2F3BF0B3F134EFB9F64ABDF0F382013D50228A10D2E71548AED0E6C5B73ED8EFF2D01F30632C302C0A283861C00D45FDD511C00CB438A3708001C72D35569CB7DF62B6B87A1D19CB88AC671C60570824CA2281A609C71FC0A0002FEDF9050FFA89BF3798DEB6022B66D7AFB2391D032E1423AD7F53734D1B7503F2A360E02953F6C545F1369194EDD23AF748B3D2C5CA863556FF00B031E21454C69B443AEFAAFE8206F8846CB376CBE9C7EB3F62849472ECC9745EBA49BEC4C1D7E621A6C7CFBB7372DC11A5013F9015F27567BF4E2AC1CE6A5B66AE8ACDD6ED71C954EE75A88A1142EDA5771BED609C983F2911D94C455BA605CC7633A4980850F605837997FA5BC7FA1E34CA5A9F1A65B8F3DE5A9A65B12B46CBC2B0E45D7BBDFCBBE25BD70007A490B315DD40ED2DADCF60171B70AF72343596A75ABC187B76141474CAAF5B0E817BB8D5D7A6CA461E8D6103FFD629D640E457E556BBAD5DEAD357DBE28FD124951E730D126D7EB157FC85DC5807A2028929772EA5A0BFF1A18577CC3E91C3E4F2B615574E62C6AE42A886DB64DFFEA405FFA713E1B7F6804FB0135D70424A6BB01F60AA3756B5A358973FF2D4297E92F5723898DB1D8F5EFA81825C01FA0568B4C7F0F743B2F5622C7527ADE4F96AE9C818CA100CC5BAE3CA30716D3FAE0C08DE41F4C8F725CFFFA14070A72FD39AB76DA4C6C3DBC41B9D1E4E2C35B02A1B53D1D7BE2A984CD8F4A7141B3A1DD4A568F99A01E74D304136B4AF8B1517515FDFCF63C05227FFDE63B8F5E0E56EF0EFDDF3396EA59A4839897FE519427A58B3C94688AFD3D8C26C2F554AD1CD56B5699B5388BB2D342168C63B1FEB2CBDE374F5363576893B048ABC3001711FC919DA51C59D5ED762D86D66E49B904AA03A1CB33D12EEC87A5EDBD8853A2040AA38036CB44E1E92F171790874BF36A7DD0179E814ABDEDA8CE723FCC6268A1A9CC0FEE8029FEFF1859106B16CCBA08621FC7235BD9F6B1088C42FBCB9B5B6E61B83CD2D5FD45856D286E783312E42A4503027E21FFB8E73C3AA19CB53139471434ED25D6CBB4658127F6283E6E269A0BE756A03D01C6991D7CDC4C0C73C64B48507F5C777D565DF652FCF453529A4650CAB775F67FDD51C253292D7F9E306F18E54517DC222C3A7B02D42F3FA39006AC77FD9E4A793635FDAAE8B054B88BE94C34CD024B859E3E6A8E31FD2A54D9DB7FB02F1D21A83F14F4FA3282FAC90DFB3A9EE908EBE5EFDCAAF4D237EB3AC4CA595FFC17951AF5FAA67EE2D45916ACD39AB86A222B886465DB52E28F7C9B919852B3ED02B8E9A2AAD2E52AFEF2344D8F6052486CA18D7445F666561FB6CA0939DFE6789888FB7E02D6F2FE56B09C2E7FEF8906C74977F16991A5D7D8F53685524A518D08787DB93C135BDF9F140CEE8BA7F7ABFAFE94371F78889604F3028C29611C6A6F37B95D16304F3690357AF35AE855F0BB220B29AD1572C4DC34A1187171C264E9A564886B27D97B97BA7E75B99528F2CB40B9016AAE036CC1824D19BFB0016866C345D42BF2CE790054B1A883CD2B1A828ACEC2EB0F1C4A2404FEDFB9F45B7267E3E0FA2FFDA4126AC2C5925A8E141247CC5C3B4E657FCF79E28B2BEE2834DF93267B1275C8DA487E1AA44BD61449DA49AAC182B1E90C7CD34852A76520ECD46425188DC704C7AA1A146CF1C7AAA0D01A675D4691764ECBF45B7A2A70F53DC6901D0879107883BD34F434F016C18844E2D82F0EC140DBE025DE3F924167ECB2D51C96F43463F8EFE1EAC625DE2710FE0132B3F71255802607FE36FDB43B29B9B4368BDD4DB3055A750939B1AA1B561BCA6574F7E5291E861F65426D6B0ED5FC2D4C789929EE7394E975431009A40A5C212466D4607A4E97C49D0FEA1C5DC3DAC2D7871DA699B9F6969C8155FB013BCF113BBB15214CABFA285E0FC565B62F41839237E5EA6A4891060AF941955196E5C986700A0CAFD430A12AF0FAA58014D5AEE30E11005228B3C7D0F997F772192CD2D0EAF22714FC8F07995FC61B25CBB41004196FAF8053535D6BFDB74525B7D146B6C098B39A99A5BF96E21972FFC7076B4424D0EDE930F919251B0385A8C516AE89735D29644C2DB7A9708AC9F37C0D10C167C84F29E67ABB9BB552467A501E39C28F984539F1512558D7654B418CE1E7C855E6C27A3202804C6EF74DDD275D3D1B93508B7A6A7B473C542C8A4DE8E0AC92DFCF66ED39FA5CA6DF6A35DED75AE50183EE52A96798C6AF1397BA292BDF6F9393DBF7DDFA1BECED6F2410456BA337BF977EEB2C860DFB86610CB0B719D55C9C1EDDC9F188578E885D9893201A12EBABF3096A7DB81172FC47B1EC80F2FE8E10C784302F082D6E20FE6A34D9B6D2A57D6DDD39145CDC9694F271837749A8D4034097CC3E2CA15BB7E9E775317B92C7EF36CE16C61B3AB22365E90B0A939F66B280B309822A43022D09AFD6904DDB370C4A7E490E611BD479C81FE617F0162A26C1F4CB81320A81DFAD9BBA215AE6070EAE17589C151B0AE3B2BAA31429F6D95874E1817D1FFB463C7FC83D7F6C5C4BF9F40058C7AA4936B2A0B207E38B9AA9F9C76885EB7A49DDFFD3CA3ACE539E6AA60B4DD6894923D40BA90B054FC4AEFFF08DA5AAD7FF3FF4E3F688608DB34895E30833EE2226513D0B7426CA395C6E5D6E60822C10635635BB87D2BB141F12FD5BDAA3A2D7E143502E3434FB52DE344389C13E7EE711350EA30C8456A89AB1EFE460F560053EBF1514FA1F95D1575D300D805809FBE1E8079DFD2E16446C57794931311697DD587366D6F6FF36797C9586F858F8E59B4CAC847FDD0074DFDEDC6B3E9650BD6288EC7C9CCB6A16DDBFCAB2511D2C9E8AC5597A2966EA3AC044A045328CFD95120E7BEBB1ADD4C498D3816F365E27941AAD59F2E97982E1ACD9A69B43BAE92D9AE90ED36D1222E5C72C38B515F70E6F6E1AB4B235D823F9D6CD307BDFD84B9CD4422FB66B3E6892C5034035BFE1CF071266C8325ED5B700B69C4A9B44AF13332EA31505AB60D9509BBBCB8DFE835F941304FB027E2A13FDA991F31161BB330C54ECE07E84F8BC2D9F887A4D9427E03C6937A7F235C5607ECDF4200104782B09B3703553CDF44BF5FDC895B3EB7FD1EFC3CCD56F9ADF04C842DED531C4EDE87DB83F6593D121C3979ABEFC7DC113DAC7D99BC01F4FA0E772F2C7567AB5529C55F1B89A1DA97B444772E58506409E5E5DD6A993C18292F1A768C7811F3D79B1EDDFF2B61352254B466664ED120ACD6B63F35A0985D868D2DF10512A4AD30C2CC8753DFED777ADCF31D6EA6114532033BB5944A12F0CB24DDD804C5E16E73EC7EBB7F04E089870C4EA524487ED6E8F16587422C71351E38A159899BAC5C1DBD9D93DE3D75F49F9CCABB090116A1C436B80D179CF93FA4C8D4FFD22B7F396BC786D9A9ABDC8211435CBE99AB8FAB5FF6F5C92172ED8FD1F3044BED87D6A08D2BB143F35D602358D8CFCFD7BA6DCE4BC4244B78D1F7D8D810971C02B09F2A2FAF1B9BAA52FD13839B1B72A65A019670D27787690186305D3230A2D220DA6A8FAE16244C8773B415B48A902D9732E97769CB1704D07F710575232CB1A382480B1E1375DB533A79F86D7B72C733D37B5FA3FE69082BD15EDB42DDA5FCA238929FD78823CC78EB9D6643BD5DF1D4D7F06814BF522A40BF316CA02EBBC55804A6E7063BD7C9F524E22B80C93FB5042D8A0F245C8B2C9A3193E65BEFD1F0B7B0D0FA3E298104D1E67AD80B2F75E261BEDB11F8BEBB3209D05E12403D76E699200E4D56E8624F06395DC77F07DE0C0AF634B4947C90665AF2AD28A6C7BA6AF4BEC8DBF3F2CA759BB098D190094750C3B0A32EA73AC1D1F2D64F91449955C638D470730AFCD89F50E32A09A8058473543CBF0DA9FF3D3D4671314DA7B743C35090E2729F6842F293F1872E27700CA7E9852FB6FC0351CDB6D4FF3948ADBEEBA892E1F1F800E73D4F83611E655DF8199D196F06DD43E31AFF275890159694EFB7F57503C0F3AEAF5BF07DB264C8A108B6F41F38DB461BAA23B037AEEA0D1B88459536188C97F21252425B931FB78C8511EBBD630C38A611EB2C33A26F0883B9525FDE183464BC5904C69F8691B841DA3B7EAF426A69E6463A87F8A3758D2E4A55B18A4A7317B10011DEB48F506E89B8B8646C657C3B6129A418229A6E4A5D278C47FBD8AC28D74C6212D9F490740FCBAB832FFD55D0945A1189A9E27800423EEB49F90DF1FF3F3AFE33426C2FEAED8F87323335046EDF0410ECDE5E150A1FEEFB621BAADEAAE6B938A1383A0007189254FC76609D55B43C06442E339E19BBFFAF708195D115B76E261736F65ED0F2FD3886EDFDA267A0FD9F6D62DA174CAADE201810C34ECBF0341DD6C7B39E42A6FDC2B562076189590DA99F9C518AFD7F1E40ED962A7F7174581DFE95D156786CB88E4376DB1820DA4B5E022AE333B5E95C136599C8254A25976E1001264B7A43A40BB73560997981E16A39144729D51AC0929ADD68E0B7CDFF35A2C4C990E5C122445DE0CC886BCCECEFF758E539C59E62281B86133B881DDE5F103A25221C5C997D908FC26C676FF6D04E7C86358DC1CF2584D2A79D7D380357E23FD17AE556BFEDEA2D511621F836AFEB7E224EBD0F0DB30ACCFA8C14D8FE211E4B54E5B893CF2C7D3DEACDCAAF9E0BEBAED2CDC21C46923ED18FB30C4F08FAEB84E3B56E0651FEEDC30248FC27C71F8FB4BEBD5D74C930B299603B23B260B64E9B4CBD5768B9F20FF9B2E5F59A93039DB176272C870455D9395A66D516EB5D38564099CBBF45E3700121E5C6961B50EA0952A197CD3E4B96CA0C715508604AC95A1E6FA293C9FC2FF5F61F544EC9B42439B0E39FEDCD483659B0A6292DE3CBC8092C237E29F5308E4C8BFD3B7AD7E4D537660FBBF3F9982923346E9E82197361A4313318769DFC3B060C230BB2A1CA477A0413AB58828A95F8FAB61BEDDC9ED9E73C01BED5F5C40A20288B5218F1EB1DF66310B0B262D354CE648ECD3870C8EEBADEC340FFC41C7E12A47984FE9F1F9E245049FFE6596CF27D2B6558D367023B22DF12AFF7D81057FA3EEDB8AA99B06A14CC0ADFD194258090015523BACFCCBAC73544BF6C9D76A8A317FE2F48352BC02F7E901B13AC012784E524D892B1237A8A618513B4554FB53F772A1AAA9C51E435297A2D6FDBEFDD71A3540A5F559960A5E85AE6A25EFDDB474B63A993E4FAE9669CC119538AB521FF3961CF73BCB06E0BCB98C1566DA916CB5AEE2678ED12E8E8AC829128D8CD31A1ABDE3443422A73834E47C8CCA47BDDB2FE4C2A578160C7A525EA6BB5FF48A2E943AB938918448835D648A9959FFC30B13645F39E18D6A751838292588B0F34600266C8E02BC5AA44BD80AF90C8D03D7A7339408A9317AA2D709B08A0D6A11BD22908C9BB8B815237E8DD08B6022F5B1C815237E197A1F01AD25908A481505A9F7E8895EAF80B63B169281695550A6EA8BCC99A6BF2E8355EECA0B7E1F2D959D982834AFA3B3D14E72322B7F4B26CC89DEFC818078967964B0B91EF230279C4CBCDBCC740549CA0701AABBC181CCD844C9E23186057DCD4251CC828637634064A183B8DACC3046066D94B354711B7215A1C62CF8AD2C8464AB548AB4E1005928EB9A310B54040BFA2A53F69E5A47A8372DD8C6552F58F02DB3908D56140B3F501794AF29C794DCBB7B4648168A362CA481CAB1066E7EE220988542B8E29A35295DAB316841BFCA7C8B36AC9A076523E28F7A70DED3D1951B9EA357DB785A8DA459C708FDF70916C0748339F29350943E66F0CA3A72F1EE747A58F728F8BDEC78C13388309A43109F86898A5E86DAC361D93B75C2A8DC56E0FA574CA69891ED808919B1FDF2BE61FCB5DEDF7168EF8376067C03B2C549DD47FCB8603430FF01D87A47AF9CB933D0ACD12467AA5BFDDC3CD521892550537DC686B06856B655A6A389DD01AA5AB71AE310C13FA315AE812E67C825D5B0BA313D518B63E8994DB7AFB3E570DACD1C9CBAC0B07560AB2FCDD661A9CBF73350E0DF5794E24791FB8124977996F17FF4651425C2EDBAFF4578463A411645FFE063CC00689F4BCDBAC6A4204CB1854A141D8A3BD9EC36CBA6A19347C24DAF18BB264F88E3470B8E6209C5BF19F7D312074DC3A655D2FAB7252B067EC34A73AC60EAD8E6643A42BB76B60F931718E18224157B9E8334A836D7E34A05F5739EA5DBD9212038E75992FEDAFCB9FEF18C1877292C547FF7DA29BB099DD434E65D223C409CEA7DA35F6301E1C2B20BD0CA49A95AA4C46864D2880F3D78C748187003392619750DB74DA1E9F794B12AD3485A260D5AD290CAD166715C6A8E6F656964557C36988F3929FF86F59C29F408AF52528DC26C56F3A17F00DEB4B86573CF12CC91EF3F9C81751FE0794FCAE61D8FB06F83FA6273EA15BFF6FEFF5F0BF63F9292982969F297B291FAE4239A986EA21645190C7A08CCF19600726FD5FCB763B37745F48B0219AC31561E890B34EA067F328EF3B9CCD8C9E6F1EB761C11B6B82E1F2D7D59381CEF57D1FFD6E7D85119580715D0CFD2E7A9C6EFAD7ECD6AAA5F3E96A328226584296FF8344E2D13FE93959CF263EBC4E77B13AA2A7CB37562DD9B5D5B6A03BF03AE6889572A747B8540E784E3337C91CD377730142119B1150238327147B85FD57DA2B013E3635887B4E69BA9686E649D9A74C336F88AAC107F395AA9445EBA3C516EEDC43AAB5A5596E52DBF599C7D15F75514CF90AA315906E594F4E5702BEEBDC5B0B3B3475D8DC017CB488FD1693FD3811B812DF7EF4CADF6ADCDC084E2A642F1FC5387E9268B917CD0F0879B7645F6413D0A89D295CFD7EA347DDEE6698661297318196F8EA54D2DE16294434774AE4762B5134516CE6CE45B4D71E2B8135EB95BF699AAD8A139C2935BFACD3A42BF4F5DABE8A446C57E08FEDF5CC796EFB7705D894309E4C7EFFDE7CE5031FA45F565A49BF5BED98AE6B32F44C2A737FEF45D769F0E6C9D015E8F0E28C59182A8F6695EE7AA914E2A65ECCA32507E43D816E9C90897DEC664886DB4F5D23E45500C604F1523E75410F39264C9D715C1FD667384E2C59349D36BFA0D22DAD3785C2EB66553805E5A5DEAAF4B45B08F1CC747C2E7D7FAE766AE267F3D4BCE074D97AEA0384646EF979FBCFDEBE801B633B0FED62574584C0C514CFD2FC260BDEBE91D53DA06C93C65513425F5E390EA893E15B108647BF067AFAA2343C2D8568E0737874E99619C7A28A20DC266FA9EC7D6B7AABEE62A57E5354291EA6614DE21D06FE813285D20F1EDC548B6B1D77DE54700C211E3C0A0B99A9C86E802485533941E05CF7FF3ED4085DC376CBAE72DD3BC51EB7C542E368237A9E3E1A10BC719262E19ED2B67E0E9EB2488CA7CED5CD172772272B32E70B22A9315E18D735551DB16B12FE88DBB01CBB262FA24F3811524872DB65CAD76EE23091A50EA81F300B047B5CC35758F923B010C99AE413D7E3B00BC4CF5E83E26BE5DACF16AC798FCE0FCBA707E4FDB7188C7B61F1BCFCEEDE635EF44534A4DE4357BC8E96C8147F0D71FA1B3D5B4BF4B0408C60A5F2F9B2B4B83463ABFB8A2DC9F663578E5DA4C37EA59EC1FFE3AA16FFF5B3ABD8737307829F3A507BEF9AD07E5DAF6EF2BFD6F9470F30296588791E23C90B9ED7895FF7965B1A13A6736758F2D0C0AAE68027E34D1F04987C9677E214F420E0B7EA451BC536BB97F9624B6E25E1A9ED1C65AB15100598CABBE62B73B0EE1ABC8AD5FCF9C9786152E668E9D71AD074A97BDAD30C583C09340683B56FEF0859C87A5830052838D90F2A33678BB06ABD1AE90C3B2C80CFAB3E725478828C0E24BD2966A6D5D5BF6CB839ED49BBC408EBA58E0A8817C1578655058E8B173EF000F2E5A9D64951F943D2673C01414235B85DF9CB0A3CB94A51B44D1FEC28C04D94AA57C3A4CFB65C8BFED7E0EA392D2DD0AF185A0DBCF65BCED00081F195F9A902C041FF4E4F69851707A97CB6BB54C820BB3A7E431F126FEFBD82069CC3428843977C1028C7FBCDE6508570762A48584FF0F4EE0F7DC064C690A4B54752729AC96970CD3EEA320701B44FFCC82F49560E09E998162D49244E14FED70D77B87902F63CBD4439F017197E7F732442AB4A353C09B898838705EFD4339B2DEDDDB50AAB3CF67AF2844BDF88C55C34216571DA6EED0DEA065E4852164C5A6E07FB86E3E3F2185EFD09E796C55635F8912B5F3FD100650290C9FD88DE6F8534F5F3EAE036686BB3CCCF3637E595FA3FF6E79D6D022D7FDBB0840EB30A3AD9759C2EE0ADF6748D2FDAFE7FBEBF05F99E9EEDF7E08BBFE103A52680704DE8535BCB3D361FF3E554807D0E309209E0A07EDCC6CFC47861C94A3A4B79A1C6A586F1A3068BBE9B67C9B72EBA77F2E30456B212E6F8E04704331552666091D36CAEE7D5F3053C654D9721E4E8DDEAEC2C4EFD6846E92E4C12D96A1840D500B464364918BAC9EE0F61FFF70691B0C8EE1959A458C0637AED38C858200FCF368E9695EFD9C4A74C836CBDF4D93D932CF644C09796DF6ED8865B14B9746D705DCF27C520D7162241C1D19525972AD139D83E3A103AA49571171D7B6438BEDAB70F46D06615EBA8B53D2D7A1E9B0ABE9FF34D6E35A493D124D256A3BECB4059A43AF7C36D607F242A00C9EE7ED4930F778CD9F6D002455C66056382BA94D99C6987E30B07FB718EF5D80B2CD91488753CE5DDA86103D82B1608041D3A49E412E982B5007302DC3E8924BA608AE1D26F8D093E6A945E758EC4730B1101AE7255A4C0F425E8642822BB240B3F1CDBCEF8DECB2E58BBAA384B3FE874C683088014F5C2917DBBE24D38C458BEFDFEFECB6EB11AF137DE7C989229AE4B886B65E7B42BADB2301DBBA5C4B3518EF2E8BBFDE49765F44AC6078C8D630094248EF4E0877AE72D7EE807B8EE14489B787850E4D4C1C738997DF4EA435A282B9CFA9911ABF7BB593399E9BEEC5D11C37477D052E5CD5E22FFE49DA2FA245C0A2594417F687116F43E1EF0BEC06B00A186FEEAA5F5C7CD05F605BFFBB02625D6CB0B5ED883DC68B1498D7773778772BFD3B050A4E207DCF762FF60AB52DA06317E6A73A51CDC0F1AFDD213BE31D4B2FC88FADB301A74BFFA5715F0E9F6D5F83A50F00201AC33D63DC585F126F8ED90DA764839A23EF485C44F2FF2BB2F3FF68DC0AD55FC1F831E217F0AD11E6ED1F164C335C8725E4D0806D0A25C8BAE5E215FBCF8856E25B4AC95F71F8768039FE513F1CB81DB318A54D5129B2A7530E413EB322394768A9ABB35E27B8950940E399EF41DC5C6C3736B2011D788AF3D0418FDB3AF4B9625B76278ACA408ACC0634FA55EE22C8C455959B98D83C90E91C6762354396D4F1DC3FF61E994BD5C2D80027FB063CF50047623B1C7AAEAC7F895159D9B25D9E96C5A04F45C08AB797280AB078475899AB86C4E943B8EB5BF7B7150F575EB4EC8E9FBB83BEA045A88805920B18EB0C11AFE310E666EA12F1E1494AB1AFDC6657B3DA5E99AFE4161000DDB4823306A92A9EEEF5FE3F8E51F0CE62B74D458FF9F9154793A36F5252C7D785CE71040FACE471172BFE174BF191F9CEECF5C3BC67CB23F649B7DFF5F25C928FCD2703F61FF03B2467E12393621F63D5C3B97D6AE100A73A7B22C9D229EAAAAC73110265A534D0F57B38C3831C738DA05F87DE146F3EC1E475B0DE151D0A7C4E539C9137A5451FE0F0F2266F5EE3099CE86B55B0000D64A0BFE5B94BA96B8E8ED1097324A46E1D0758FA2E4BB45E3F6D345D88643BD9E9DEA245FEAE9221902077DC1DF1720509D9015A72F727E17D15C8314528CF3CDBC3ABF7B005E361438D39AC404275C4814308A0DCC53EF33C36BB21B00AC7F3E84105745AD58B08DA328AD87B50614EB7A9790707BF402B917540CB41BC7052E03034FAF80E70864F5C318225B9FFA561EE1C8AFF2803823014ED2C8145EE574C9DAAFEFC70B18D0A2CD51744055281C4E750B43884FDF41655C1E06F300222BF17053BB5F864BF5327FAE608A408591AA1FCFF73D3F08B43EFA012D35C35FF1E8DFD8A9D02A004ED7CFE87035B771A35847B6339B683F536EFBC0995E98C65B7E6C38538748FFACA8F944DD7557D562779A4B509A55357EA547FEA62B6FF77A54035C3BF8997AB962ACACCFD90427B1B43BADFA8495585E11C118018F719EF0B7E016F078C4F8EFFC381F6AA0F434E2B7F77B1E27774CD5AFE2239CE8D03D5C086DC5EC3A53B5D1179B15F8B97453BC736705F75CFC621E17C04D8EC8A57D78A98812F5888A8ABCAE4EE008B79946FB62267ED5F8E3B6638355A6E47B6DB1E40BBD766B86E559B6126D7F92B38C85EDCF607A164503A015E6C1782C4BFD676E2697D0308CE537F7BD071BB2DC883E0EC271CF1B062DB6BFA604B3EEE886B81E51C9B1046B5676728B8CAB6FFCDD1D73387CAA374F562B64D68CD1D69E76D6DECBF0420CC69FDDFE29629B5445D8324CE828AF600E9F17C570F3593EC7A943A6D6D7EDF87996A3739F35017F4A9E1A63D9B221EB57C5751F84AA5FF2247609DA34D3D0DF5A477910457A2A71B44C1FFB7B49B7D6DE87F14F08F98A9C886EF567F425C1AD4AC2CA24BD8392927C88CA52F575A43F9D2F301FD3B75C3D50E006F08A8F30A7552A0EE6948996E0D965706ED7FF8C7CA67FD93E258CCC509D5A8F2CD261E2B42B46343622AEDCFDD72E100F40E7DC24262CADBE84A179AE0888BB2AF9F5F82F5521291638577DAAB932352070CDB0490D3D923D2B022459FAD0A7F3A5F34B058CA49C73E9E3B44D6CB511DCB9519168471A59DC097C130492247CAF9D7397B4FE3DD6FDEE50A9DC12C6B98A48FD48E9A52421D503B30E7B5D6A1C25A000D5B77AE5B539E93149E0A1D3E1B0B4AC84DC030C4E520AC90395717756F7A160C5369BF0DE8AB32444A1D42633925595CAFDFE0FF13377D2AE14F9CCA9FDD0DB573BE2FCF7AA7423C97418D0EAF712ED34040AB027ECF54240853A77BA7464F73E3F81F9A63DE6F5DB46599ED7FB811EFDB04342C7CE406DB7AA5066A7B38B96EFD47255865AF57EB36FCCD69082300D1530D8EF952F5613BE835FB1945AE0AF2D209BECC0329782CC982D973A5A57200EB05D9997223A8823780088294C58326B1386E75FBF77E7A405D7C46471E8B135AECA431B4B4A38017B020AE6DEE3F782ECA3FB15CA29BACE834FE23019CFE80D97AE22CEACF1589EE6D045A0DA8A50921915A9F80C6AD617BFA571449C0E7FA9A38B14D3F3E613DD17E37F8E5E0E5887AE92CE1A150422789E31F71437D8685F8A0E0B68FFA9FAF540942BB549878887D1C11AD40271AF7DA912766137A80B5622D087A30F0A71711C62E33C6F297B7A0BEB1BE8AE0A7D44BC22320497EA98E13A545DA9EB198F549932F40C4C50084F76A4CF70EB8E1386821DA5CB290D58596B659BEA58698450AF57F5C7D088980FDE36CCA4A51AA7098DBA867A1A49354E9897D563C045BEED92F3EC0AB5AFED82A03BE9FA50958B6B2C3F3E29FA57541D01C25C75F50D9A598E83E1D6956EF2B3188E3963E267540B4987EB8F79C114751A2D5A181E86422CE495C8CE006B53A6A72D014311D2E1BA4098519E32D758708C049BEC089E57BC499139F9D972A1CFB8AA53D8E50DEA0F667F4416291AFC2D718A0E4ACAF3142552AFFFFE6E2FBA6B49F8D5F4C800FD8D1C03CF2390DFECF38A3054C56188582768E99DA7174BF2A46BC40F277ECD2D8476C302C71C037E7B3ECDB59C20DB1CCFA85FCC4A9327C96CBF641222FB88CB1D35DD01FE1BE0A969F16406082DE72F6402F093175C3C050AFE3F81068C59AA4E6F0A1B9D9B00E027D47C1E0AE2DA16F810D4D2C3E9A23DB422253FB5F021DC371B7F6A17834BAF32B9F5502F6E07CCB01ECF280E3556DAC549D7ACF36059A3614DB8B947FBA49811D8AFBD443993800929A69EA773A916AB685B89FDA954A0566484F839B68328923C27C33492F0F310D5354C3D8AB5DA160BFA8CF1AAFF974435A44D789DC3FAA1FE7845730BD811882DB074C3E92C1ED52ADFB1CF020698EFB374936A2816C9DDC419BBCC188E8784BB95CEEAF83A67ACD18DF03CD79BE83423BCC064245AAC5F65301425D562354320BB54AEB1D38FD3B64C2ADE8A29135E6F3FCBAF08DA78B0C4DBB1B687532863F28A5AC1043AC053A59FB8822E83E33425A7AF5CE8DB8464F9B35ED1E5687873B67EAC2BB78171EC17A7C80455F7F6A213C2B0AE73669856BA32F56CE8E6CD851886FAC4273D30A8AA59DCD1BB6352CE79761F0EBBC014CCE7F14273574DB2F9963B5D97FACA8ADF6FF621671D786A5F3DEF648AEFAEE152A2D9C8FB25C64031F38F3B18D1D3A78E8551669403733B4510E30C7CEF007D6F23A2AE28964B5EE26459778A2350F2D446C544B27C0182F7E8886D55CA3C064148B6C55949CCBF2F91823D4EBDD20E67F66352D6774C9FBA19F8CD60CBBAD714F041601D3F693E07BCFC42393B37759F5FC1F07B0A85C0D208ABFFFA0F24F4A69B10022DFAF6AA0AB1BFE262B7CC388050DF30A6CDB6EC275DC3FE38087178060413211AD5698B9EA60B4F31AB95A1120BCF111ECD1745A219E482E37658B1A12046C2AAFDC701A301C8365BA2D61DCF9412FDBB2510E7AD50030D969B4FC87F3F3DF28F519602CC4E464FC29ADE053D49405A6AE53991AEBD73A10C6EF76938DC2A110460718E04E8C74054B230642036614522EDC4FC86B92FFAFEF290B3E4E66560B56904F1A671625C0ED56915711478D12DB830612D5087D3882AA3A5DA869229869AF86EE3CA6858303ED82CE8E69F0870499807ED107DD0BAC8974220F3F6F05F1F97D5DE14EA16D39C22F30580EC4CD27FF52ADA0C33D3A7416E8D060CFC1B1DBD4F63F8A69FF541444AB3434EEDD521EB60392BDE83F9F47020FFAB5BB365DD65A43B3CA90661065EF980B610B47D3F34E173176118330976CD904E64D92ECD2C141A3F3815E46CFB33D083902F87E80640081799072FD1AAEB8B97CFA452C864F5D19674BB198111AB9626F5CCE01DFC4D661B7B2DA6F0071DB815CD7FB896EBD0AA2A7B1F1D573FB1776039F6B581EB4E859660CCA79200C6B482C086410AF23A0D63401944CFCC2195AD590834694BD151F9990F842A85FDADBFE1AC12B5EBD20C02ADB232D71C42AE518FB13F8055A600954123DAA298AFB39F464EEBF192AC79A797133D9578354BE708708C0F5EA66B47A5000C4D343C3CF63F5D1A5325D8842167685FFC99941691AE5DD0E40872741E4076BBD98EF260CE9ADAECFC7F2813F37FD3CDAD1929B4EB8874DFF0923C7B441236882B8D2398976137FCBAD97D26AE7FA30097ED6760FCAA2557223D0BE0557EE38A1920A95BEB56C37169E40A031F77136D1FA8D6CCA6FE975F944E87A9E86CD2151B3480487E6CF10B10875407FF3A997D1297A7E524100E9D765917730FFC216C6FB12ECF0CB511C6181FAD60F0452173972BA414B639C5A2424775D2CB75FC7606C8267C0A3D963B9FCE5542C1C26073C3F80F7A04E76BDB3C62FF3ECAF2BDA2763ABF53B80DF3A25387EB58899DA8DEF83CA72371296E7AE5D0BECA190F411E03EB8F355DE5522E6DB3F24F0B533B9D56DDD5913B8121E4138C2CF14419861520C5CD26CC2A0E676FF8D0C024BCD69D6B5FD19E22990EB927B13798BE91704AE1165667FA11E8B95446C11E59FAED70F065E476ADD837DD3298F3349F227C785AF1332A325EB5775972DB369DCE3430F02AD79632FBE6E41D937309DF4816DC5A92D17394F8AF8EB9D2A7BCDF7326B42644EBF62E32406CF02026DF3330FD97E5C1AC020648830BDD19D798D5F844DFD8D8EE7F5809B516F763ED1B98BCC746F561E9369970FA896DC0876D958841E9ABB0BD218ECEA79ACD14FD96F9DCB733FAAD6721B2D76421D6A8A99A39E2FAFFC5125B87CD1C13D6DF9C78F26AD603352FCE790227F9DA56762C54A0D875F82AFB103755613FE70A7E070311C8833D4B938F2C5086637BB64A077B0101DB4E9678DF89108D3E471D3B8CD1D2733E1FCFB8845EF561CEC773D74733F0DD1F3EC7444A72F56485B75ECCEFFAF8AEEC15175C244C09229C1D2322ADB764EAD598BE7CFF7A46D387D5F6299D9CCB3D559E28AA2AEAC7AE799ED752EACE63F2252B8B2D77036AA76083F87B545E0A907DCA52C22FDCB74A7C24B17A021B740308DFE764DDC53E44AFE1F7FB73A1745A4AEFC8C155FC6A4F832E8A94C893A97C08FAB6FB8F84DD88AF5FB0203C6E079049F7DD132F5FC8C4C8870EC40DAEB74F19B90D21CBD6F08F1AF7EBF890F984C657E9B270AA8063D38B729F17471B854A2CE257A796751EEB6E7EB078978C6FE48D1CB20C67775B6E0E45BB69B69EC3F1B2364F9BC0BE96F503ACD1A378221FEF27D9EAE299B9A28C57639CAA6D39E85A6E81AA8F34C2AD7A156CEEE4D35D5C5B6CAD3B19021654C53386A318A20CDFF50432997D473DDD09997DD9FAEA5C3BE14160B16F0A5B1C93E294080B924C08557CACBBAD08A60765E3DFE965B38DFD5F2DECB62C3A8F551331BE846C775AD5039F0E47DC76AB93F0A67E71B93683E6AABBCCF1BB737E8F6E2951CAC9694D5FA23A12423BD500ED5A964385D1ACA764C1678A4BE1C699069981D8ED407B802DF3D7EFD6F0AC6865AD85FF117A3F58BE79217D888A3712A1E4F52565B1175E13B1E44D4DD7E5137FFC77A71DA28EE3B06EC34C59A66C76EAD12542FF20F453E6A0EAAF2D70FDB57D4C997E0FC0DAB27683AD06097A3DC86401650ADBE42C99A82B0D167002D7244DF8643CFCC825A51E962E6A61048D2D0B18E76BAEEA0D69B23EE49BA860AA64777384AE46AAB7A17F05D30969084AA74E715C55E00CEBF91EA2A03EB2145DBAE34F5C1311AA858EE95BAEFDEE38AA47061CAA3663A2B0002E2509F51256D6D702670635FEA9312C105E3087D671737BDFC8578111E5F3230AC30DB64F21E5064BC0BBD2E7B902D25318E3144EF628C7F4D3ECD2F4C911ECA1A0628D8B1C2D35D8C58B2907859E9BF86D2540A06F2BF19021666A9024AAF14138CBA9A0DFA7D2F811628A77A188FED7B88218105BDFF6D50C12DBFD9B067FD5BD1F1E85250528593E00973F783DD510414F84702DB0D9436EBC66418F83E1762DC562FB8FEF9B5042AF99FB16D73C1CF4E5D3496DE71FBE905CDE8DF9F27DCAE7206C5B235009FF987B47069FC1C63E956534A39305B075DF4905D8105C6416A82A26EDCF8072347999943A31F1E0A36686DB9A47A4D694B0962158595573D7215885D2199BB5ECC2839EAF49350C5547A85FD0C22E184A9F7A0EA58B12C71046C1891410784FC600B38A15716867861B7148E66E0181EFE39C159305C3415BF565440383041F600CCEAE03532D88ECA3BAC00073E4640BC2224D4489A7AF28DDECB6FA83A852125827C26559E2424113880C062C8C8D88A96FDE7F277ACCAB900CA9314F998C1E2C7BC74C993A2800088E47BD5BF9F6139AEDEBF00BBD208DCB671E28475B67C07BDD3A54D8BCA77739D40ABF8F220D5FC3A8E3A530C613B7C268C8557E548B59E7915CDC69705FA79B4D46DF80D7304ED287C0520CA267EBBD35F772A3E564FE833A4486EC523AC138A79A0A41FDC78F6C95F5534105114C5573BC13B02632F10DF42E8B261B0F34F3E9A311115881FCA93A984907FE42B66B41181965F28D55602D9FA1513F4D68B99C5E7B179666454D1C35C9B86EF66F1F7A16AB13BA48966BEB34136C608D3E00AF9A6323FF358DF1EC62F268805306D3A968B3C67BFB6BBFFED31E233A81EDD2610000C4D073B641A2A22A7CDBEA87BEA503C016825E34A275CFC5181F10561A33530E599C359A70949E8F7059AC242E58A9DC8591705C24BD6427BC257C35B87CC800E445539BB459B178D9A929895A534A56EE4C78BED2097FBC877AC9444D1E03278C1C9E8A45BC0E18073D9E6EDC9D4CF5F0BF75C35E07F6E9C120CBB56BBDE34A34EC727455E4E7B13683107273D553ED5B34A792ABEB325251DBF886C1E8A185CFF769F9AF04B8420A594CE738FB20E935DF9ACF887630A2D3BAB1D2570C298D3BBC8AD94FEACD34A9163865217FBF2E3C2CD8183BC9634322F902BA4DDC5941715AC1F0C4FF8A46706C87A6E4FDB9F1C5A4A0026B9C78B10EAA77D3F75C48706D272FBB29A5F6FFFF93AC08F06AA7173A0FFA7842A7AA41EB8B7ABF71E33E7F9E546AAEAE6F469969343A379523419578AC540FC290E7ADA50EE9C4732F2F2BF1B16C036659F9C957D93A8FCFB9BE8761251AD711A3BE8C5A0E669C203CD1CC0A72A3A083709DAAFE35B5E58AEB714C233636475DB86E05191447575A5E04028F99C3257F95EE91D841A1779537B59B882FE9BF899D1F73E53E34F925D67E85E39AF135B9E495C371771BEEB987CB664D0E142EAB5E908F9CB0F2C39CE99E4FAD7DA49B33F50821FA6C66E5690FE026619AB225D3F71C60204C4349A50E4FB0C14EA47FCF46D193F7A1E9A34A8F0B691825166BBB3E0360BBA4F95C887C6912C4CC834A4FF92CCA6C90F5BB905ECD0128BABECBB1CFAF0E30F9BFE856DDE153D44FAD69B42893F21D337AAF8BCD50432AADCDA00425DDE74B7E21750ACA6E97DDEDC8350F0FD512CF7456EE7AF794EDC17CEEA67A30E75B584312451C5BDC233E619A6688524723FFE6DC219BA82B8A89FD90B6CE3BCFE9A2E13ED27441348F15B669217E36B294F6ACF615CD2AC5A6B8BD486DBB739D49EB566DB4F6CA6334C759F829AD7B4C7E486DC96E6C5111F4E4AA2D7333CA348A19B45C0503C513402F566B130C2758FA3DBCB8185E8224B9E9047889038D5CD73235279EA75F5BA941FCAFA5DB341A4DC567E1AEA5A9C03872D49170AF3AEAB0F55B056A7A1ABB4BF195E7425E1A0E69DB9B1AD8F2A05ACEE7982217927A4433CBE8B4F3A123669ACDAFCF28A9E7285307709F9358513A5CD3FFF75ADE81B16B7B9C1E85A72F86348A0C04B6F6F67A72FB0D9B8FC955BB936421A1EBC1E0A56E9D7ADA74C972AF22CBD6D08D85EE5CC59F77CBE1124DC05DBC2B519FFF3C535033A2D64BEC94AD35274D4E47C5B4A101F97A3072382B2000213826C7D66A35EF79D2D1A0F8A2FAC2000107227A8ED3BF3B0A2B6CF409C7E2FF8ADFB38AF05A5E3CB23EB0FD87B88BEC35B6E0D6E9A12075EB30FB5FFD188C0D834BE7075D37EF7422D0C19C507BCBE5FADB879631FF376D9F786412958B84645707310AE075DEE30855AD3734F78969CF08573BA542C04B04D4CB995858D264F1B5738F2431EBE681AD78BA9BCFE522E5BCFFA991AAF961CFBF3B55A12554DE564E1BE5B680EA9456438B1AC7F13648C12468C89F3245354FB56EE56DC427720C8CC4FDCF7ACD5D44C7221E7F86017018F51B9FCFFE10B53139FB7CC8F68C292C69EDCCFE2893C0E5BBAE3089047850BD70755252CC3F7055E5FD7584529C57AE5AC2664085300A17E8FCC68135DB2FE3560FE56F9D1C1E16D23AE6AE75D5391A60627CE7AE48F18E31BCE67A1AED3EA436E4F73FFFCFFC640F864EDE3F9732CA603ED0084BF32B285F145175422BFB5690D48D79D664B5F84B0C99241028BCE8D2CFCB5A0D44FD2BA2FEA65C0ABDFAF451F05E3C73A2DA3E9D7FDED5DFEF8CC032A4672A709C5430B6780C9F08403445FE2CCEF383F68CAE4804C5826CB9BF8EED311517418B22458DE4961D41F7196F2B42F7BFC1C531FC37C81056A85D6E6DE7F2042D756BF0C327E696B0FFC6E71E6BC602BE9D84859E3AB2839F8BC1658375A1BC63262B13BC2D22349E3D2C2BF0892141ED8F5EF9EB7D479FA4C982EA0A90B8A676C322FB3BD6776067D5360749D41DB184778E63971D4ACEB19CA30B42653AFBBAE758FECCB67692C76CB258CC2381FEF7D917D9D8D2E75C2444394B2DDB745C6FAD044880F7CCCDD91312A85F7EDC059E509095E586C70594764D95858F6F38DF8FC427908239A902CA225732DFD60C071CDF381FBEFEE13A7867BE4C1AF934E3F119F958E3348C95A2F3A8A3BA1B95400EF4FE21EA7D43C4D50A963F79E60ACE38D543E93CDF5217EC7777BB4341287FFA949A97E6761FE23C8DD5B0A6A037DFF8B1FA81010B1D559C0F2F3C635A21DAB600D76FEAF43E1DDB7BE12399D617F3E2329B503B74A5288A4A4D444CFBADEA1906CFF1340CB6E28CFC83437AFDCD506FB19F37111BAE5388280541EB36A6C9FDB3D82D29C862D2D15DEDC9C330E5011220173DDE1C4D6768A38D3B00468DE13E765F606337269D487FF8C3FDFF88CF97CA10045CE9FC76229F59D9E52F9FFE762DC263954C2273A925BE7589CB4C19CCBD9F61826FA6DC44DBFD09CA775D11672A691BC2BDB98CE5145F471306955484BB1A4971BAA71E68BEB14E031EBAC86F9517BF9A46F484F80F3435825231D34D41D9A2D232A070B0BBD412414129C3415F75E6FF28BEF4BA51B5B7BDC965A93358EC95842356AF48F969E286D8A52D2127920852F428040CB1516410CDC7C7BD66A6B6D77A1BB2C011FD4C471ACDB8AC7B670A27DB3C20E08965A0923C00A991354A98B8173D84BE60BB2C27E5A25DA08725421311E97A60B2E478FFC6BE11CEBB3A0DF31B5E19F4C85BC753983FE90586DD6F97B01ED9378732C988400904565753691B0EEB5FCCDCA18E566581A2498FAAD1FFE5FCFFF695CC107160F0A69CB2F86B83DD589BCF2C83FE1D217049BF9E81BF87D6E30D8ACD81A9D9F26DD97C7E98D69D4B47E2C0254D3AF894634D669C2A7957B04CA26D40265902684E8FBCE4F52873DE7ECE598A6B5B8F3E7C8BB603C29B53E7B96886BF387FAEC58EEB1E461316A3C9558D7DD0D4CA606B98BC48BAEA2EB9FC9B297448D2625784A70B2D33FED089550491078CD3883C77CA337D5504AA7022B54205D37EDC358FD6B1F88DC868C47D09748055CB088BA536DAC9F601A6F266D182764A41265F05F4F7959CE186D3A7CCA0E443A20DEBB16A7F374000949FEF6410EE8C45C1689642C214B9B5B966056382C768FF9530C02D78CF497306DDFAFF7996A932481679944AAA2BC0E84D23F004BDCE981E173C2E92AFE58375794E7EF88CE2993ACAB8D79EC2EC7964CC022DEDAAB36E4E6AE7A2A1640641A487C1D86A7BDAEB42C1F8E1C2448758D59A1976015638C8BC1FB6E6D4704C27124374B1B0BDBEF7603334DB4BE7F53FD6F3E32FD44ABEC0FF585788BD51047793C280792FA48E4FDE15A697B8A7D808BE743952F596FA55F481D7EEFAAEA034F3765AD5600390F9497848ABC64ABF89616B7C7465508998EB8A306C7BC5D86DFB6BE3CD545461F8D66E9024D7AACC1773D66B75DC634000B4AC8CF1737A370F043C4F69FF6D972FE8F943FFC70C01A2F9AC6A7A182DA7007B22BEE02F1857A212E617AB2AF354394FA6A256C1A30C9B9E52C87BFE84661A6E3C3F0498932341254D7FCCC1C279D4DD7A73D267A2617F10DAF796EED71B24E48423775B6A937FD0AD4A6F46EA9761CE4CB7F3E805EED296BF6607284559C5A64FC7BA0AFF25ECBFE2572317377062F2AE8EA2BBF77FE382661D7A6F5F6D3637174640FD63DE1759BB81AF94DF4D2FCE05238D45EAF90C0961F061ADE1D8280D516D68646D8CD9263CD4006A3DCB8B694F03B21DB227407D24A52F793F466C88738DB141D475F98C3F2E8324DD81AE12E998057BE496AD1CE36845A57F1ABD06518ED99BB8510CECF9CAEB29C121CD88D453467C4C655C870960004A98672A0887F54EAA917B2A001CAFFCCC273E9D4ABCFB0DE51E93FD2CF3BA41E88BB7EFA6BE50FAE7729EF3019C0B00C1CB87AC93F672ADA699DCB9BE45DB3BAF8A934B382E6E0287AB6752FB25C4630117E197EC76D81B9FF48F61BBF7A4A3864BE19E5DD44B9C1E08085DBA5044BA72E853D39A36C4FD4E161BE6C8203F540BC3D7F9A32DD2102C8EB29FFA65F62179A0F95FCB1AFDAE16AB669B709A5EAB694651761EFAF87890EB009B57CE45B0AD87A2776A9151DE8BCE3AC30C99194EC970263AFE6F05D98BD1D0A30295703BDE626C22022D6B5397953909B8FE91A0CEBEDCB816037416AB71F089E21D3B88EE36C7B33E5B61D589B56427A3D6BC98F7169A607CB204B4B2C69F297A3964FD5B56029D6D51A328C4FB030EE8D3FBB8FD681625E156E35DC4D17A69AA3FA48516F9800369CFBAF8E0449DC71BF9174A90797FE9D663C4F0BE8E924868D1F7150446AF492288B19811102033BB1906B18CCE74F6CC9A72397223726C0A091E25A5387F419E8EE6A70CCE8AEA7B56F09431B4A6DB1C592779A4BB19F2F3562CBA97C8A84A6CB9A53881D5B26C77C73A3F454353126E66DA9551E22518B3EDF96BD0F0F9DC8B6CC3AC8997F5A694A3E3D7E55F48C2656107934BD3F5D8122C36AE8ACDE7648F4618634FF8BD47EAF1EF735D9E86656365F2D28475F23A1B3508C1172B153DB469D1458E07BE92DA1D60BDCAC7CC8BC7894007450376F28D0CFBD4FA0DAA237200C4FB8C5DA287DBA04DE1696E8B474C9A187296C3C97F531D2A2C175D49E77930D9445F9D8224CF7E3D6E1D127321D18604FFC9717E17E6EFF95132CC9668A256E5D1816654C4D4BECC3A4E3EA53541409152C51A67AA856EA352546C5524DD436954511869750636169D23A8A9D7A29499096511A6142D420E54CB94AB82821CA9F628B07DEA9273F35FC199D00216348C298143872229C5AF32A7835108E3FEBD55F480E08C4B3C3652E0AA6ADEF2C0E458EF2B1C5ECFC6B42F245FF08A094A661A1C58C664FA9B25D7681398E85FE0EE90E1EC7F513B5664BF9F5DD8F0D6D902F00CDD9D80EFA56DC1EAD45DEFC9BFE8FBD319C629B904FF1161A24A8DE7B2C55F575685E09CFF7EC977EE46814D6F842CEF727A1F55F46C7D8686C70D06BC49ED67310B6C298BB39713932F2858C5FBAF1AC12D5EC194EBABB9CE67E871D8508897F8F46EB3227D5EAEED0BB58510A98B8916C27D5D032667279599FC2EDFEDBB594F8DEF7F5C3D1CFF489892C90E289A58973ED8167A132B8A877789B45F355845FFF7109F4D740C55E31999660A86615725D25B09B545E169C70725C0EBDC69470D0AB3D82536AAED2EFC848D7E6DE91EF85CF99B924DFAA175F8B4A1F91ECD4F339D3046CC24AEDFBF524BF42B679145505B964921FC7744C0BD56625434C83A3CB211239DC451303D55F08C0D43C9A4465E5FAA8F7130070CF2933C533FDC3D9E80ACAE0C5879327DB98E5630CBDC6989A43A0912F7B0EA0A2F38DF2F8CA83629E17E9F70489764EFE1304A7B0DD4E855A7CBF15DC1D7C79527A807A99387F24B74E5B82559163F966F2ED5A0C9B99E442564AF9AD92545AB9174B024DDF027B5CA96A8DB2B0A23C2D25579A25DAAE0F548099D3748C06C12F8C18C69CF72C3C87A1C1F19196E80BD3B6AFCCC09886E68C939C5025F02E54072C0AD80A3AF23A6F373EFE3A8F1935B33CA2169C2051FBDB2E46CBBBFAA1EAF85383B403A57F1BC72458B0BA486DDA5474DC19F27EDE6C336646053B910686B9711B5EDEF62828940356BF53336427CF0D9DEE57398850F7434388C08124816714B99853FB2F6311D1DCE54EC6549F872F48C4828A048BA82616A3902CC63833B585C68017F8C8C7F49B0D1FB7FABC662AD5DD570D6FBD1CDE8FFB1E617D781D05FFD26083A968187782CFCCFACAA7B0A253FC317825F6DC667821A285634D4F66C76304CD68513AD223892CFD0CEEF2D3D8B0E8CFDBC0E6D21AC69824284E8ADFBDB4BC4A5391F1C7753071343A6CAA2876F9CF7531A79AA8C425A5D42B447096CC7DD56FD6051FD2E3865D8D7BBD4BD2F0FD286D14DD4F846D0A33C5C4F1FBFF399FE729FC085CFF4C4160277392F1C6355CC7E756CDD23BCC5DF9DFE30804DE81BEE0E0396A49092E5C1F4EFEA8D14F5FE1717F5F9C8D85B5EF458DF0DDB6E3CC7CFD5A3092564BB4AE25E975B0356FCDD65AACF9872113DAC717F9509466740C62941656EDE715AA54E07A1F85E6A4C8FD85C229DFD491054DB17066CF4AAA689782C0AE1E89AAE9B3D81C94AF1DD18E0663038494F7355FD93733D764B54643499F07314785DF9C9AD579E49854B1167AADC80CC3C60FCE3EA66CFC221E6923D07CB35A5876FDFBED1E1A9EA484DBF246AC395AF4B5D26F623860C2675B639ADC352D7894D6CBB3F94283D24A3E52F2AC55EEE5E3C6973B066060CC42AECE49C2769C02695418180B35D17DF8DE9E52E2E5D4143EDE1AC3A7E3D6E2E52EC570C7F0F1D21900A606002E36DC3CDFFB86FD5A7964C25D4274794DC745DBF5D3472E48EC2BAA2EE185C64206B09149D216ADFB0F810755254B2BD8E12D2CD8027FDEF90F09FAFEB5B1C8FD5FFDE7CDAFD2DC27098787731B1FCEF6B4D18A62D5A66B876DCBFEC19E2ABAE44D3D48B63AB1F3EADAE742A163CE4B287A7F2E98DC01E8D45F99B9ECC5BA8B243ECF6478CD987EC6C4284380671F4AD6A457F8494F131E03EBE0CB49A49246BDDF98F2F200F9CE4031ABC769FF9EA9AEDD7BDB69C680BAEBFE83F1E2A06875F75CC7F9E6C64F59A41AD5FA6751AD0F1CF605D99A15AA93D18293A9B0203D27FB36DFC97C7B6897C2DBDC13F0D8F146033D00A04B459CFC8CA53732BBB4E92DAB66E1F5FC199C8CE521E32E3EA4C9D93D2377FE93895933ABA9CD8BD6CA30FAAB2D615B4BB1B96E7EDBCC6B9A5ABB2382055F5E217A905DE1711A08A04E83C72F273000B0E772182E4F668D9691EF7FECBF0D6C854B2F5D81408A0602E32E505BA6E8569D8182432B9AC8F8F402D1D12D22D9FC65285B3746B9616923D0A2EE67C405F91077745646C61406F9AC1BEB0069147E784BEFF01F9FC75DF0600CC2F00A16B86DFBCD8EEDD7C7E6F281A0D291D8E5983057B80C4921FEEE112FF3A41AD03D521142BB0790AE7E5B281BC760730C0CBCD0ED71E4FD4D7F7F52273CB653928DC57475A7F89B7A7760112D3299DF0C04872E0F3B77251D78F3BF19070E2077F5CC6EF22CCA3B4425B5B1176425F112C5F4556760B84C5428B2C2177103BA429EAC479FB0E76E5F1571B15CC943E680C8D04EAD1C31861DD1471F72075F53F27AEF004EC0E603B182C42885A1A584043E59AC8FBA2F6CAB45D8E5E1228E8459BAAC8E445526FDB45FD238419B840409F0A955ACE301A874DEDCA49CB352554FB6491359C66CE8E90A206ED18EDCAFB434A127149D555491D312D09E56D6BC058AC3DC1C8D0E43B571174779512ADC626E2E28D52EEC63D4302216603148E3581CD319A109C15A8C4C1E9975C81183DDB8E1EAA84DDD28A66015B2ECB2DFCBE1014D5D185A720ECF78F912D0F6ED9255C62D53E612541DE8E53C6360F740F58584EBF3FEE69B2FBBF34E6354B9A8707420EE7B1278645FF539BB6A98E5BB9ED6BB5CA5F0DBE324D2F2F3DFF3DAE7CF042B8607D7D6F6E735F83FD9AEF7ED557EC1F4FE3573788493E11C1BFC74BCFAAD03B30030A007F3F2CE5EF3078B510A3998F7CF5597E6DEBCA6DF3CAD1ED1708E8007ECFDCF42C6C77F667B14E6BF0304DDBEF65DCAA2B171FEE32A1F934C5B6E23F2BEF6C32447D6E619118E272E3DCFD3A252A66D0D4FF3BC64B9DD1AD737B19668F3ABEF9F496D5F6E382477B929FFDA1BEFBD73B836990EF76BC1ECDF1EEDED3BFF7945BBBED6C766270A12F7A2C65AB383C3BE06CEC21AFA640E9AF376FB7C90D69EEC00012D225D1F04956632AD86453BAE4B0A48F8F678F2F3A414850EF54182D21874A6FFEB63186E1A08C97FC95D647EAECE1CA0BF34255B1EEF51F7F35A0EFE53D5071D19C00819AB68402E635F400897A6D02DB80010DC0997E845DF10C62FBC44C2E22820E1F33BEDCBC69BD410E5EE60F2B73E706ABF1B26E49338990CC6A3CB6ED7FF7FFD31F397E3DF5E74B0A3166D00E9F62FCBB05C145EFD6426EE30791613D9687B85A80C6FAB65575D32FBC883E81E135367974706CFB0D03B1E0970347D9FF2C3BEBF6629DFAC9A5A27D465E6B6E3A933619BCEB3294178FE3BD9BAD7236CD870418B3179A4EEDE628A8D0BEED3EAC8A51A4BDF6985F932F3FDE3F9159ACA82033AE1E01ED91F377A3611BE0EA11207A5DBF3E221DF1644428F070CA6F6440F071FF5877A9B39DF4286AF0D570BF7D43191A74C8084E3D650E05D7758CD31F449071E65E1FCD092F2A436B1ED5C61647446D814B96872A9D8853528CAB4137435FB76EBA37BFED3B4AD649147E1C2B19CB34A2D541A20BD3087922E84FF0C99A6817662D781A5FB2783D213580E298BC8CC607E49670E0887918C9A1D21537EF05A475F0004AB33C86842A46AA67A7B5E542DC52226B1D5E8E4BF64E89DF5030B39EDCF7F2FA05E32A44504A11D2F71F90FAFBFF8DDBFB556307729C818B1D0F275BD9DC622AC77ED239B9EE9D032A3688E37E131C2E26DA9D902393F16D3FA66E54FAE5E4CA8F7DB21EDB7AAD63B29662C2F2A5EFC470652FFAAFB60F324E27EFB747EBAFA4262AB18465AB07E394F81F7B5456EF09324909F7ED856C49C39CAC01B5E98AFA3DB18BDA2FB2FB5990317CCF74441E8931F004D77EAF6F2AAF7615420945DC9E7DF83BDAB7D6B5752BC524046FF898A87ED554A518B8E82EE6D489DB519F657BD3D0E12C9B7C780C53E59BAA6D8CAE9A19C64D6207E529B1B4F4223943EA9FFE4B64BD7D618E59C2F6408929B000D3B70FE81602E42ED63FB6B2F7E33662DD2CD34799B12BD421761010694582A3B343EA91AA6BCF2B367775701499FA03DED9288752E6B0B54F4843B8DBECB53CE49D54393B4F540134DB483D3424BF0B3FDD42BC44DE8C78C1D7C84EAE0D9FDCCA9EF2A435C0F9ACF151B2B6AA25FA859E7313ED938DCA2520F886B8E91758C31956A6C077C5A34E0E78DC1D661E9BEFD3B4A8145DA22A2497E0988452388A47F17A0CE5EE541773E0A9C7DDA37EEFE5B4AAF18B6868A0727868B4893F7331F7FB6C05784226739C48CCE0BE399B5CACA734C4B0F0A7C0F5C3DB14EADF42DC8797074314BD5A350CDD4740DDCC547B51723642F4E3BC0A30A59B7772CFA69755A3B4E1C2489B30A427311F207366BC03C17B7D3ED6E073924C948B31A6F45CE2467E03F0E6B1C2A010FDF41A301C08380F8EB5C7BADC908704543B5C564B17C1A8EB06A5593B4531E0E0D45D20EC417EDC111B2F97F06F60EB2EADC60023FBB23B375F7A29E32607F9E5FC0983809AE88C26D14F27562D541BC6148992E3E88C31D31CD3D5F2323A8553CDF7B07A372A3CC0FF4020AD55A99DE9F6556F238EBAF6365E81196E52B17AE5E5602BCBFC3A4BDFE96ADAE0E2717D8AC660046A87D2125B23B75BB7F4FEC5F49D473750C09F0AB2CCC83BD194EA3481B69605FEE7605634CB9454266DBEA1652B225A77A28E0A5E9C97F767280FC37B855C68D9C2F2F93BE7942C03D0E3C3C2E3E0D062D7CDB0522AC0D6030E125CA80C315F00558A98A352C53DEE4A607AAFFB26BBE8D03C89C1616035EB46E69B446B353E5D053F69E50F28B3C51B928A1DBB7D5C52B2AA8A4431CB766F5DB9937559D8144F4635613FF622F66BCC8C9173E77EB3BBDF197548BA1F5706446309EA7D6148FFDA56363F83302D669C2C246228F5B0A67FBDA3B862DE25539E1377FBA458CDFC987027746108A1B08DA391D1544D6EA908929E25F3119FD58EA5D82BE13E0B0B6F3BF1839B5DB278E6C37BC98F79B629D5FB572D957794773C1D2F61684AD0DFAEA2B336A3D462A55E75C712B783BB37530C78FE625CABD3D2D88FE1B276C1101BBB8F5FDFCD7F99539BEB5AC006BAF99E0CA470B13E60491318AB78513C8B0367BC8CE789896FBB66ED6DF1AE23BA4F03D00EEB441ACE0E76F306AFF9F20EDFCBD539A1AD3CCFCA50B18895F6B975CD6B9ECDF69261752F635FF33C30012E9DC42B36CE530BE5D988731E497048E252E0965276009B5FFF7210AF179B426B3082471EF3C3EF25D47250F9D40DA27235BFC1430A25116787A56360F9B96E721CDA5E9FF9D5DD00770D92D311F6B69616073DDAF4587E7FEE3DF157365758A82E6BCC371C7B398D22FB71DCCCBDBC9CE4F8804E8947C5369CF90F0B28F4BD084FE6ABDBB85DEAAA0E298689008658986C6A83F0148F9AF7222E77476B1DA85A065B639EE5DB3DFF57EE1B03857AB3CFFFA2C1A14EC005F158ADB9AC9739A84C1834A9D0B7AFBEFCBBA58C84656625EC7CB3AE28CF78B9BBF84B1D3B17A03EF87E513FBD827C7172175EF2C78F12002C5F646931B864C6E658C2390972880F100D7154E7505A37AA3C2998715F79E2FEF02C9B1CA8E9346E379E1038B248C50A166FDB755EA978B27669DB252DAFB65577EB5B5D48A58FFD067D861B5330E18E54AD9F5ED9BA54EAFDAF920FC81D40878C494F4563D529E54B2FFA674A545A546173754B81C7712A8D13B746EB9133EAE1B7E189F25A1B83DF0AE52CCCB1398A2846F48B4EE6CB284CABD3856EE855931F7AD4CC790371192554B7D022E54DCECEE3B682CF91DBEE20355E6DE0A6CB016B7618CF075EC8511808D4853078CC97A059430D344A70F85F6FA30273183626500BFEA7782F2C735B8893CEE38ADB7F8458B13D1CF59FCCC96F83D3E56F81187A8E8220926A1084DCA2E9BEEA1EBB4E9336810BFAE4BFD72F229F183FE90D4FBDFCA369E61CB07EB78427A33B8030295A436BA3FC1006E28E8F88CEF010F3BC62B51711FDDFC449C7D835DF387D2F4024508A376FAC3AB89A58B3BA42F35DC3E5C5237C5191A3A4B922B8142FCC4A4BCA06145DAC605819797E1B82484E99407ACE2F47E8B46D7FE29378CCA82DB35C64E4EBB7CC813D12222C4ADB40FA35AE84929FF8A92662C1BFA07A1C3A2A791224160BC74722AD871A12B9A47C7EAEB0ECE6EB692F3AB475C88DBDDEBCAFE36EE37336F596AA862E71147B40F3BDDDDE74DDCFC5F3637FA714609C8FB8021940CFD39AFABF531F966F0E780E9909841F212157B2ABC8574E19950136523F86ABB82C3989E3E92DB925FA9102AAD96FA83CA1132C54A7259EF8436C5893921919E640D5E7BC9C05306F40229234B05F897BF87CFA9D4429786B62524EFF0756F6EF5628F1EAB78BBED38C526EA986EF41C4CEB2D543F77076E0F1D7B3FB529538A523D7232C34596C1DC90716C66DE6000A2973CCA167F1A5EAB0F67975BB9D01239FC3E1736DC0A95360DD8A2AE7C015851C0F7AF8FA43B8F73CA7163324F3FE3AB62516ACD1E18E923B0D00B11FE9B5BE51CD321504B548D7BF3118008A1803BBA1AE8E5C1508A183CCE9F46090638CA830602504118F8F0B90302008A02BA62E38124289070DB552BDB090090796032809207620B00A005025134E1A9661C95CD6944D240DBAD8C5C9DC02AE9E06C6BC69B84213C41EACECFF1D499C54733BFD92F2F3F71169DF7A79A1B0D2B435CEF96F9C63F248AC59A3927EB8C34DD6EC7F8F75A7B79B0B05F98393C6B64657BA023510EE7035DB6A892CB29A58B9931A3C3C484338B54510EC17DA6274E2BC200A80CE0728D043A342AAAE56EB744548250195497EB0F3FED8CA6B8256502625221705F0305B527AF8E4B3B70AB0343C6F050BA9D3570A5379E886F1B07425E26FA6915CAEF405E1D89C527F73803E268676CAC187AE8D58C70026AE6089C8049A1709264F3C53D1195AE709FCA152908255500C8F3AF307B12825D04BCD68FC558B1B47A2D73265604F82366D73098AD404613A187259B60B4176582300AD2BBAB724FE82B1950F609C9AB5D3AC91E60B8AC555D425F1A269A9E995F3B6F44881010F3B68E738748D48C963FF157159EF5293F13213F4665BB89CF574CBE46FC0E3FFA995EA7A3967450EE41BCE6B9A723FD2BB56A02FB703DFDF9CC1793E90FA23AA693C2157B12E355941207F7867BB4913730C34260905FB121887629578FDA0E93D8CA5F4F62E111321349E669F8CB1EE22B01341484682FA9D17EB9EBC7A6ACF95D4AB513EA6B0BEA9F4316F1EA201078122FD54827EE4D5FE67D2EE59FC37CBFEC62AA2D46770F0ED116A6A73B250794DECEA96ABE89C2602675004817AB2ACE4148A5AF073F4F31540C5FE0A6C3D677EE0146727BE8DC8844A979DB2B8325533A2CB63350E392A476BABC3EEEF2FA22A28C8A78C91C46C3002AB41845A9CA03F790E8D164CA6F3FDF1FFEC1B8F020F0E798DD7C6115AE97125F43EE3213DCD530BCCAA8A9C242F2420D10F26099104B15B464FAF1DE09B7D93BFF2130361856C3D525C585765BC3B0BE29672DEE2D1FE6FC806FF3E1AC11248987D7B86B9D7CBBCCC9F9D1BDC63B947576A371EC9566C621001DF0E0A6BF56560A6E7CB2B58F22835D00FF2E29E19A23AF3D7760A1E3FA44632AD4DD97265B3F2F9D7F357629C88F3EF66FAFF58EDE165AC3E1877188DDD0361A7FA11D51C588E07FA65EA26725AF3A75C0E87EA118639F5C704336BEB2BB51A349397670056FD504806DD1FB3AFE8CF9CAE0D23D4B578F51230C8F8E9F267D6A2CF2CD696AB4A536FA0D132E42BD90E5908B06B972D0D19B6A9512EE8AEF884CE68DA01F2516A5D18E15168BB60057F58B5902E77DF34F6B9E8D277DB765B3CA6C162B059CB77FD3CC2892B80649F055E51FF5C38ED8CF71E860C5847B057E6887F1C9FD580C0919E2F93946548303F9F7613E4EE9FE9F2141AAE5BA1D18FBD476E61E4268AD7A9242FA95F401A190FA06C82D438B56C8FEC541C0BD5B80C8509F18BB4282BA218A53591C4D3EFEAC19ADE5FA4F67E28C29CD44AF851BAF4F4526321038C0475FD9FFBFF65FE7AD6D32FFD7FED25ABE524E03EC5170AB96BEFDA209EDE267D59D7C73EDCBE7DA64DA29B08A0008AF44E03CEA36972143EEA741D9CA3A2702B0CFECB78307217D22DAF562E4D882C37098669B49B2BDC6F46C14A9653BFB0D47121FDA181D4CFFDDC512ACFC7894E00C9B750C3A60691EA08E9204C8657BA49974A0A7B315C6768B67F00D07C0AC97BF38472D874C3D24A714ED283AC0BA2B272D6DEB62F154C4CFF6D2A5EA64C72C59EBEC3DEEC8C6DA4F0C5C119877A321CEB5A67567E4137EA36A29420E59D3EEE6E29E196318EA1604747735C97098F10E62BFC42E9490FE3A7830550CF232A959C08C1A98BB772A571DF76110D128716F1BB0735F6781030CD98B0BC535BB18CB38E65D9172E67629F3E38D8172E9DBD3E8574D16A08B9EF4F148721EA1A8F0D19FD3BC207D6D019B56D3FA516165283C9BDAE36E16C90FC3B71AEA5ED1CFE1366B9B69CA327FF7BEEE679D7EB1C8BFFBB712CDAB785D4B3A731E16C75752B69C1B67EA7DA1F7315AA0EB2BBCA440E5064FD2B00B3ABA5E5421DFD64BC741F678CD69BC7E7BFE0328A916F98D9D8CFC9B6F072AC31444B902A2AE0A3F214C1CB3355A4571FA0C373277B6836C11F76ED122EF2374D657469D375CC14C10D7E829B9B85BEB5CA8556089B668F9CD031289531B20D019A8D854572B0C4716A204C5A5D9EFCCEFB5625E574FD0AFF1204DFD13B42D2C286E4F832AFB878BD3A383AC064F6CF2AC9F27335D86664D4F2D7F65D0076FA97390AB7DD855008C4F798BA3D4E874CA18DBAAA1E160668531D2F12DF47C3BFA94DEA2FF227FECC325E1AD264B842D38D6C1ACCE1D8201F2EA3F8A57912EBDC37EC4D4ED8A6568CCD56B58ADAD9CB0AC8528D8B875CF420043A74FFD2751307BE53AD3EAE9F71C23EEDC82E494F8A0E09EAEA9885452726F18F1A69D26FA3199F0035D76DD9381FDE64E01026F2406146998348BF0C7F39A6F0D4AA47118CB23A95B07385C3D499B8778F0FE795335F959FB57F95BC8EE82C0A47CB69B312748B25DC50B99E9A9546FD108A527FD6425680EC71ACF4CAFDC51C2C834E90739B277CA51DDBA22D615E85CDF2FB23914CBD244669E12CEB116E4EA1DF6E2306280A1C0FDD1CC741ADD2DFFB55CDEBF5362A81AB3A365DB06B79BEED133266FF3CA9008D12CE1148F6DE6B3D734F82C7B156A0321AD60F1DF082CFB189FB8D6EC83C1EDC3D991BE55150470A25D5E0B2761D7107C4C62F24A2D089B8FD9F179DDC3B9430E92C9389240378393878DF6E4BC6DE4801E4E7B1FACD8328968F6ACAE2748897E30402F3CD41323E90553A4A76882FC430D7F122D75EF1B8E936392BFE11CCE4CD13920F81AD60EAF0CB6929BF31723DF1EABD19BB455EE1323F1300C836E49F9EDB2F2E813B3DB46359222801D417BC3889BC23F5ACB1405FE347DD49A1209EBDE99929B57717333D0626238809A3E6162408999810F927DAEC335CDD4C16D2A1A43C3F7CE5F15B323DFCEF3F53A90E75AF1EA0672695C75C93385D718038F9A1F4878C1C8335103F54BAF11851F47FC9922DCE7F40CDF8D00BB26D0BD8168D17060B45C1042EEC8BC07F639F3C9540F763ECCC5A7532CD702521E9B43AA3683038F56A27C76657E5387269A33EBBD50A866E01663BC0E155C3204804DCA39A3C88057999E93614F2AB248C7DF837F89A668969A760A9A6860CF7565E55FCBF96B7D7D24796E7C0E108F362F57A631F79108979A7D34AF0F25259AFFFCE83CA3CB6B76D6E34732460C532668632119713AA51EF378B8979E857588E99B2149C495A66E694B82CB2B58595074DF2AC301086B40F5F77166658CC4DC302C0E5E300EB0893FF798A7B0EC8434BB2C26219490DB3AE1F1581D2C6E49E7823F72BF0C714DAA38296464EB31DDD369C336A5398567A99129C6C428F9418D5853EBE224D7CCF84FC4D03CF2B9ED520D49DFAD56EB738C4000DE84C11CBB7E22B1DCA5DA78C21F2BDA9A1727858284F1D5C344BAE4CCFD977E84C9D76C7EC5F67CEB693725809A7E9C8A16BD06812FAC2004211884B36845CFC2A98085AEF902C8944B268FE6FD20EE3E343768E4B3062EA7C6705F75E2E2FA18562941C876D357FA897AC9283CE0F5858561A9D85EB27F5ADD93A8E907F91DC1B3EAE014B55C819A60B552DE34F97992914962AD83D8B7D1DEC9F6FE13F3ACABB2567C2761C61ACF3F5B84F80E63D9D4BC01C52785BFC9AEBF7ED315EA457B48BFBDA623F056BE72F618C0053C0E689FDE23F2A307F29766E27658FD18BE34A239EE8372FD742489F61C709C60DBFFC2833DD9129B8A4561661E62F4C4501692BFAA582E28CD99F1300F7015D65D2284D6B78EE4B946823DDD675EAEC49F9E328F539C40B2D51F8F25D90D99B7B7C4F53FFC87EF1FDB7486DECE107E81C823C9C2F01F056D5A770B8D04DA6503560A48655A9E682776A04FA690186B3C3C47A18A7F6EAA3AE5D79C6ADC5FE9AA835E5D5AA6246FC5095AAEAAB38758A949715F1ADCDFAAB88D06BB62FA1D586B8A84FFB1FF6E51016888A47EECDFBEF50DBA5813E94273DDD70593576D1425C87F77DA6EB1435D2F5E34A5009F5635388FB464FD6FFB76603A7DAC1BA3A31392B5E9182FD64408D2AAAC6F115C90CE777B3C9CD832B6842A6DD0690DD80BDAB663BCDFE4647BDF337E64E331EF337516EEFB9D3B82162A7F0F4F89F1F2DA8D92195AC777F03F5140DFA29DDFA9CACCFE66F5D37DAC42FCC1EAACA5CF5ED031DD561E5F923E0A2514D787916BAFDC2249262CEC37220901B184F3A9E2EAD9AA24B51B9DA17FF9AB431BBEA65BACFDA15F9D17D5042D3F51DE1663F5FFCBB7108A582F9F953C4113B48022387D30CC070C95E5E9710BBA3F4CB6E4F37CAB56A77973C8EF84EAD3BEADCCB832C11D8A7725F6A470C17DB073AC2A44E22D9EFA6450AECF22BAE477830E857ECEA4D41E4911ED810DB33D3ED77CA84C40D4EA3FBFAFB530EBE2D6D4ACCCCFC7882CC9B3A05694A8C30DEE9AA905AD60D60E987C4642FE41E6EC1A2F381CD644C6E50FF4DD225F30350E82F4CF5AEC96E31BA910271B38D9A8C545C5689A8E055F5A278B1BB83E927E4C3021AFA8EEE8D9727DEF88597AAC91826EF82F07200A051744591F5C0A181B9565665511BCE1DEC57DE2661CFE0C5252F39D8E89ED44484027FE380D1AC2A43C19D40B8F5A00661BAB484E6ED7086D25EFBE005DACBD73D8FF7A5810798BB3833B142A7A046B47F8A3D0741059C0FCFBEDF96AFCCC17C378517A8F5BC656EBFE898BE7B307DE25A5C30F95AE44BF0C591162FE77C5A1DB6741C235B4C0801F83DE95334ACAC15DB830240A621FCF58A4B2D5CF12ACFCEAF3DB94A797B2D881526C3B07519AB7403082934334DE94703A4166D3B5344D1E3637679DE021D7BB47E010CE34A1E61264362F9FE9696F50BCDED2B3CCF34C496E5C10821912B70A282282FB0CC4CC49A64590C5F8BF831F5E5E1A2F152F978B9FE88D5905BC8D0BE7C815687A8C52FDD915AE52CB70D7E55E802C5878B998ED11E67D116A3FD2CD0AC59494BA8D05C35813947C7F3A26388428A84D49823F738EC2108E3667B3A6B24CBB9B019BCB48C8474505F5EC2205DDF317C4B90F5BC5734ACD1ABD7DD3B6432CCF8D1933CD1407898FA9B1DCAC0136860DF19BE731809463687C07A1C79A98D950B1887CB402DD22D1F4D7570D489F41EEAEB4A6B02484FBB1A2CDD8442A971D9FC537D0FC898E0692FECEB9A26359ED743DBE7262FCE1FDE32259266BA85E76FAD165EF1EF1C1D1AEE41EF0FD97E4366E7C658D71A6A21F87AE4DDB10F48E4CE253BF5E9D6DFDBFD46A90ACDDE185B8C378F6706BDA79366FD860A8AD71002133B12D7EFB93AF1DF4E1CAD050FD5CECE1295FD8B6BB889F7D142B656A9D34EF76CF3B8391E0DDC797BFC503A47CF5C267C580E5ED2869CDFCB29BC22F56AAC0F471D14B2061A0579F3EA6B7686B2A5A9908753BC8E9CDF1C2CD8FD53577710774A67CEAA2E72A30FAD86015AF16640199B0FAF7AB8090018FDCC6A3BCEB1CA7FBFFF2C1BE25371E89DEC0BFFBC2EA77FD0F172FD2B25BA10B3D893C73DB8BAE1B65BDB49C2E9961D46169E926F1959F20CBA0B613B2F5ECAA17B69B984EA30566185D4BAE772D2303B4DEB6DF07468F77F12E3D5D4B4B41841F557F9FDD526DF4C1EFE6C4B80C2B2603CC5C04345224F03C90D5FA305A4DD8AB2105515E4D95CD01A724571F2E4E0EAF016BD8B7A2CF5D1586220F1FB57CE6806B13F38D295A5BE3BE9E323EEFF0FE9D946DBB4DFDA877B6517F305A40A16CD24F3BF02FA4D45FA368DD44EAD13DB429860967B6CC8E31768AC3F06D2A78BA2A2E7A3B1F9DC40A77B8491DCB5EFF5FA8708598140DF636A4658BA1A1400D1DDBA035A2AF79EC3134478368152C78504058778CEC77F641540E5B3CF1548CEC61F3A9BA272DF1D2495052881232B46B7391EF89C062EF783BBB53E595610A427171B2EA92F86A49D370AB095B84B31CBDFE4DD140CB334B306B472376F2CA57BF6289939A243C2E2C76A7B5D2E87F57D0A62F16C1E1DFFEE5CCD712746898E680147A2F2AF3EAFB6A3314442ABA78664CFB2133E3B6E60E0CD39A040142A547B1E501AC78E5C396C7F1F581701D2A065D423594FC556B20250CB7C711D9833B303F275CEA6C2A1E74D81AFF46FF2F031F55B3E27878A0B5AA8111377D4192753C9D917FE09C2FC1A346FA1112F69E129C97795FEB3D1E7044682565CCE5E3B917ED0D468710A8E31D5291C4DDE1BBF356CE8228BE7094C995B6D01394E716342F36FA45A2116F8B1F49E6308588466342607D5C93B5FE829C505136E6E090EB050B7AA29E2A54FA589053A71D51D59599F40685599D89CB68DA8652E14BAA1F00C52C51566FD4D7FD8F4203B883AF6D861E83669F4127549AF46B13FA6AD350E4E61F2961702F6F1FAE454F76AF80A93B795B972E2EF9D9CBDAF477741287BA7815EAEBFB703A076202FE3FC0556B8B0AF7F569FD4DF342299F532031AC8F9DF4E71F8D3D8C790CDA534751AF963123F0C4BDB5B22A85691568C649CFBF6EEF94B7B66338495CD35FFDED7F159103942578A23FF737F2019F3E7125380C87037C93ABF0DC46DDB3BEEFDAC6B67D2958347D2F22C3CC304D1D905A34CCE2C9A92017978F4F979A138A2774233B23155E245025029C29AF56FBB0613002C6F5AC7FA492CE708B981A79350C1E3DC9949A1726E0508CF28835115E7E851F78A37C4FFF620FD74D16AD9E67184C8FA4EA971C782B1B6430293642BD605D28FCC867A5F6D79B4FCB777A7ED65F4D50D950FA453DAEE8996B806C163228FE5C5C3BE8C51CBA61CC88372D4E2D8E3277D996C62E3791FB0CFAB5DE699F1DC05B999540E3CA7E3DCAF21C6DDB451DA7CF278E6DEEEFA1868DD202EAC7C5179E05ACEB99AB792373AB819924B8785EBE47E19E616830875EE00CB7A55DB7685FA278213373997D9B4E57C19ECD48CFECC6FDDC81543B3CB2AD0953AA79A0BF3EFEE640D8DD29DFEFEDB72470AA5E7CA919AC6F5AFEC7C3A882125395F6D639D8C1AD7AB96FB9BC03E071C7EA3A7C5D0D111457FFFC4D6CDF5C19358F1E9128CD96179F4682D39B9C678126EEBDBFE516C22CC5333E69F4714430032358A9CB1B08586763BD93F472FA1D859EE5465F93002D165B91996FF9456FB46B554B0A039558AB95241E6A5D72FF5C794F192D3F6B0724364C562B6B6AC8EB27F34BE33B9E96EBA8EFFAB100C3911255CE7DDA7ED97673EB9D1509FB58655DEDEFCCFBE4CE46EE917137D61D6F58D36D66D4DE8A442624D898BE08DC4443CD92D2B2CA104AB6ACCCE64C0C46010D21022F5959177221190F2D890E3B09DBBA73FB18A3CF4A8CFF5C274A078F29E8097E000C1FAD329CE0825265E4374BA60F5777B3D8DD5007CE54279B66BBF5F183AC8A94A862E50579DA38785C450A563B55B7AFC7A2A8BA111F233C0FA37C1647DB97EE76AD3FB3FD44244D64ED3E457BC2A78837DD7CB194842E679C488291C2639385CF0090966CB81E3B68F641C30F7E599FB9639E9BAB64A5333915CF9C444EE03491ED508A1ADCCB3B67CAFB60D1C4989E64E22A42AA3D7F8E76DA9A14946513BD69996C05BC58A9DD31E9AD01AC7435DA9BF8C145786496C6CD2A1636C61CCC792506D7AC997E54F0E97683B73B2B41B73D0CC3682A78D4D7E4844FD8670774C63B2413C6443F00B516F798D327BE55293FD9CBDBA922CC0F1856D7CE47D5EF274CC22436256C9EB2237AC29B2CC83BC0D3C2C775CCD5A557A41796AB652C52868F2D0A387190860968A71771AE51A6E410EB5C44630E88991EEF137F49B2432672A69AE939B36AFC7F1C8DC645AA157A9FF54704E1D40A49987F1490D9B33DD3547B1E75503945E375A691816F99425A7DDDC9C4095FC8478CA2FC073B82E70335641E30E57C96BFB2B23FC3D9C503D472428563C34BFFBD22C448AC5F6B969B97F137351E91022A65C769F22F01A3275B7FBF9C7F7D11D14EB45EAD55787A973DACDADBF14663E7EDCA08C9C84AA21B70B39DEA527AC3AF310608766CD341F4FF52CD4CD1B5E9EB50157D1327C5F86D9D8C8B21CFE67F6AC5F323B41110C260C89DACF68FC48523B57F40727EF682DB7422E65A402AF9D3AA7187C044CD79E5C29FCA785FA7B01EB8AE8E9EB0339878AA06C8C03E0E23B049C565941CF0BAFE6A2B6BEA2FBE7AF182AAD9C3D67C9448F187259C10F6B7E22D6D48E5C43F52577896D94599D6F74243FAA521BD61CE4F65BCDA6111D9FC11FE3A062C313FFB2E9A647BE03BAFE03EB96BE77D8DA4BE0339E16F5E24D3FB13033C33A713333365466DC21E07683C89F4626C055B807DC7588906FE7C0DF91753D57F1FD28C57FCB9C734BC2ACE2BCC072C7AB0F0C5FF9B025AE5A8F3FE4622AA89D7509E64E0AF66EC21067B12128712CCFF1DE87D367EDE3F33EE4362FF7F90E4936E65E867ECDD9F82DE95BEE38B4D17FBBD65629DB3CCE453691470AAD79212BCD96C400C16084652426A7BDCBC68FBE6B54CC2B5269940CAD2B9527F6382A299E8FC8B24775544102D7B030A2D1600A19CECCA4CCD4372428142899CFFF987315CDFA8D7E6F11D0776625509F12BE4F9CA6EDC23E4C2164C48182505BC1AF4EF4EE6A6EF0B5B4215E6F518B325F57EE52AE55A43C9E3DFFED1BB5A761A10AFB491EE57D62A7DD2C17F3AF6933C500DE602E30E8924FC6559FCA3F480E98FDA9CD38DF6F3AA7C4373A9157B25C4D65170B6588646CB48DB800E56D816ECCDA6AD845ACC68DA097EAFA520122E7C536C30F813ED683954165378CCF68FE61C0FF64443FE3B4D3DA4B8CF4592D5813D472AFE305068DF6C98982C26433430FB0511706569E909C404C440285BCC1678DD5F0C95988F8D1E676E3972C62D45769162395D9D7538FE9C4B76BB418F8141B6FF8A04CB28C6F1C411AC11BEA49CBF0B26A20673269CFDA4A7B49F833A690EDDD71472D7CC757DDB2D30DE78CB4DFC9A27C2F78FD6A487F71367A4D652B730BC4BCFC4313CE3CAF4CA2A92A347D7D12DFBB8B60310172C4442C3016C0068EA8C7CCFC8353A8EDE319CD7536876698FF5974BD24146A2B8777C57A520FA1F4130B40DF9C7E6176892EF0B14EB2B5711F086D07BD5B0A3A462F1CF201570530EFF2DE0BA87633B769074A0C6471E3C1D21C89A523261955FFC535339D2B703DA8F5CFF4442966B43B86A69D718FAB4BC67E7FEFE83175B1F28A2C6E0961D56E0FDCC19B08801A7014CF314BB7F42C5045D45D963FE8E0C3194FDF1E560BE9D7BC401AC828D0F557DC8FDA78CC4786167ED28FB2D0287BD8A73491CE9607CB3C8D647A79489591425BFF3B70374F25D965E7A7B799807FE578E7DCAAF7C4EC366FC3CCD89F46E23E42EE23E7F3D0901C8F5602F1478D93E2682630ACEC3C696C6E3375BDB62925FF4DCA366DC9D8AF5FB4BB341B7590D96BD8355E5BFE58BFF882FB275F2CE0FBD257ABF6E8A8230EBA26CF57458FB72E15610417E2C8F05996EEE6F0B77A3E2CE4A7F4EC0D156F939E5276424FB1814DC9515A5F22509544BE1355799A1E178F33A8C41ECC6807599E7E1B1D933DE20BAFDE6EA88FA85BAA5664775D501010780290D2FB19602969B2DE1072E9BE8F2B18790937FE2833BF230FE8DCAC09C43ABCF48D7E8048BA1A977F27776AE6A4A1266320C665FE996F51BA3F82A0B2B40B2E595E6C6A5D6A8EC8934907E5BFA48F55BECFF2CB46F848BA5C0A5FD83CE6CE1161877F225B021122BE57C809A8F54C1536BB5A09D2EE462D059DC21FC14E7CF6A25816C14E473ECA41E7BA21D701A20EA4A524485B8B7B118FFE1392C3D9DA645B91E0384366BC93A61374EE2FEC3263FE49240B63D6EB0FF33007F86B77FF477EAA3E40F3E29E75BB2B51924FA7EF9137B33B0415A4FC6782425C778324AA817C4080553F48325DB6AA434577F0758A8F2037908961EFF42C8B23476A79EEDB808E09CA58C449BDB710A7CC8D7AEA107A5BCF04C715576A15A7D2C4635A51F1342B727B1F754BEAA72DEF07B05C08E6D1DF3A5CC6A1C1D5FA82F8E4689058F142FD7C060425F5F34A55DF03807BA3213FA6F08F67BD41CE3DEEEF89CFE4F21441158305897FA832D1F960C2D525446A37B53FC138BB725B2037640A85A040C7CEFE819030FCEBF607566A3E4F809C74DF90FA423DCEDF28C2D5854ACBB72891817D933AA46F7EEE922EB8230DC6B6CAEB8FB5CCB3FB12FAD73C13D7D5D99753221440B6A45D3E43CFEC39E29FD1CE4E7BA87269160D17B90C1B5D85A3B8EA2C6F78D97F7EB0C91F050C382600E13DDEB3CD602D2376BF71FA26A46EAD33B3DFF693A5CDF6CABF74E09C562E8E2BE5F5C0361AB5569BD413A25EC9621B3CF6C873CD48000782E3B1EF7D9BEB90F974B603DA9A5E84EEE6127D761A254C277A526362AD410C0482F72C1E89BD4904FAFCFC60AADAB4235AB8A254D29B43D077B6EA5B48A12558698AB9DF06F1CACEFCE7588D74C281FAF97792D08EEA29E3337DA952DAA8324F73684C537446B70595514479518F605487230CBB06D729F59E3C642A51E58A44C937CE16B7EF3B76ADC2ACB547FF93D39D5DB0C115A91906CDFCAD4A04306C0636EFF1FFDCE9EF03DA4F73F52A6C2D26E23E60A0AAA79B820B558F55962055907F897E55527D0215DCADF3E9EF4BB020957E518ECFBD97E9FF515BC6DBA0740AB5E367175763241C6CDED5B026DF6CE4F94978818FF01F5C0F84F647644FCF93EB5BC1FB6FF900BA950254C3644AC7A756A86EB88DE2C52E062DE0960E52112F08946604EFA9C166B66F6E96D785E4719BA223D6D34AEF119EE76EE0C6E16BB063870FDAF3017E3BA66EAB11E841C0E4BBE3659B05E840930CE8D4B5D6EC401386C8BF269443F0B1E894BF85A0E88A9C326B1EEC2B9030C35F6908764A6D08299745BC6DA926A6E9D5F574985ED2683F86B4D713238F87141B3FDCD4810E4FC339CBBCA13F9D4336C1B4018273BECFCD58C3E61409F634DE158E219A444E303720842FAE102839B6D2B06D34D0990B676B9EC331D37717FCCC9404B98EB1F7F0343E295389FC6620CF02A9DFE5A970C6BA685A6E338D5832C7666DCE031AE6897B365287068B456566359AB366593092F78D2F419A6C5832D4E86FB79CA86713309553F10A80D7BEFBD9BA0D6A26356FBC56E9194D3D97FD2A14FE2A0E25CF96AF62EBBDC26690C2FB8B29CFD5DB30ED120216130921E8772B5E0C6045004328B59F8D85D38026B3592B9536503A18345AD16B15131FFC5549F44702E87C3161CB0B3F30034F4308DD7BF1DDF7F9CFBF242488FF90E12C200F2EB0EE1682BFAFD17254EE456FC119FA5E230FBE7E143FC31CEDE62E13C5EEFF001C050F6270752D70420A30A719486966B199D7EAE91F0D6AE7D6A66082FE13368304DCDED621FFB9BD5A7BB75F54547F82530997E25BE4F5AB77B31F30668C05C96E0346ABC53F6A80D786815C3A9F5EAC09764D435AA00700FDFEFCBBCA31404AF06A4C0408F3B97E055E51AB1A8DBF4472B643E25FDD87845C5FFFA5764391F7CFD1330CE21BE9CFCEAC597326EFC066F2C2D2C7EFEC261EAD5B47F88644B05B944E6C6BC3120F41775724C20A3E125B5B3DE63E543D8A988D71C197ABD7E5026A680EEF9F2E8B1EB1A027B357B7D7CCC72DE87E4A64E262CC38008F2BFCF3E9E5AE2BD445D2F191475A2D6387E906270712CDEAA5FE41B875FA1D05A026C7F08290D876F5A262F959F6B4DD4630988B02B1D8D4EA972C87A728B0AB49AAFFEB48D5B205301651DA0EB47FFE0C904EC5D7D484681624B8DDFE76F61B0F7850C53795830F7D958F405FE420628FA68D73FE7D95EA5C6026131007BC582C202B8E684E9D70902DF2EDF4EBC21CD998189E3E5121A0D43D54DAD819691C5BC2DAEFCC10880505DC88CE25B557E5B4F6CBAC81ABC09801BBD259848D45E514D407F0BE5260B1036FD2B5D691645B511DC2865A5C56CDB187111FDF63ECE558F5E180A472BA930FCAFEE025DA3E0000549DFE307418E58C0B4DA75211317763DE4A3AFFDFE3EEF92BFFB5D0D190757F442D16EAA8F489FFF3D75D1AE7C4A4434B316F0561DBA0AA1948F87C1E2558CC6BB77F9B968482AD7A6FECB61B4AB2F864BAF66ACC571114AA4E080E5EC242281A7BCF89F0DF2657C35F588910C97E92BFE86DFE40EC14094E67E29A5D84F687FF56443A2C79CC7D7AA19A777ACF3AD0B67CC7FDF5A03DB01C701AC4B61D88B55AD50F8526618DD5462CEB77DE451A9611D20C7E5D9EAE21546F6A147F2B4CF80B7C9FB2BDB2A7B99A1FBCE45BEE1271AE659436C9DEBC9DB838EC3FA86BF42647926F6B8F6CE3DDAC3083B1549F8798C191C56F32C2E811DAC8EF875DD9E1EABD508FA551A45D5B134E82A19CEFBCE20938EF280C0D7F9E915A3BB91A01EF7EFF051F1C25C28EBC21CB8E6FFDBE14EEE247A128B108030B5094CB1A2B9F2C4CE27E2D667EADE662ADB4ACCB7562A47047A819202F11398B91CB4EC9AA2B1FE67F7304AAD549598AD71A48E5B42507B1C66F558EBC263BC766A42C8473633E09A950F633227FB488B0FC0D8EC2B72DAD893E2ACC36071E1A6B39D2B9144EFFDF17ED5BC35374FE28C3DE980074074F2C2E23F74D396FB9B36D8118B7107045C0BFFF34ED8B5CDC6FA62895CAE26779CEE93DC9B3222FD59F4293D4846AA7706BE65FAC6F17EFA0B78DFE76BE3D252842D31B91A4DDED1B909E0D764305EE2C0C228FA0E239B764EC60AE172627A54EE345EF386835A519FAA203964B593399C7FCE9C41FDFCEFDB63134CA94332A044F725C04640FFEA48CC9433163E0D47F2A028C292576E282B6B798E7D6A0E0A77EA8E012A8215F3898460EB969764D10B8B7832182A5B954A4157AB5C7E4FF16D6990668095DA62EA36D02E56E89020E283F87B9F913034270540CAB972E96E679427E941E14745DE4DAA269FD674AB887656289239ED1D4F48DD01158A2661ED186DE3C03FE4FE8CE2A8F3B7C263515A9E91A9ED5F69B9474867FEE7DF08631A6FE0DFBC2A8140AFB55317F592FF88B1DAC3EEFFCAA05C37FB8539D2DE5DA8B103F7D3E888BFC4B1350CC27C6D590F32EB9498CD064A343F0C12BAD53EE032A2A7C0256B53D7FD221DCFCE5E3AAB3E42BE0F7B449B288E066BA9A68F76F2EDADE97D621AFBD476E94C36FA6184E97A3611EF9B41873E99BF769FE6FECF97866D39C8EE74281992F9807AB7D1B81587BB9F020A4387CDD99244FBF0CDF7752EC72B848E8DE906FBECAEB9A6272481B5E43DA8DE0154DE0A901D4E40CD128153FD3C249CB8E4B8E3A13B1B0F06202FC31E0AA4F7B31EF7B2DF5F9DBEBD2D1AFAFC6FD7E0370D7DA6612AC39C28B54BE09BB7098C3687C38C7F51F20A052A277E386E8E574CC25B64AC21048EE45F46EA09498DA0520C21642EE118BCF200D9473DD12DDAC20354238A1B89E34158823B44A16AB93FAA0DAF8AFF047FC7BC51F6181EAEBE9DB6F783A4307A71BCF9C61277548EB2D2207F8A9F74D11762F8572AEC644B2EAE92909FD8CA9C38E26523956A3FD711EE02D642AF713E3CAA5EF58567F6B174C3430D5B59A2698EB51B96E08009F4160B7739A328730B0B2790874E9C54781909C9D69D1463742DED4B33651F67AA07AC37BE287BEB2B5387230FD25BAE5B37087DE010C6DBF52791E358C8501588B4BD9B4839277FBD48B5839482407381CAE58C4BBB8F6AA4BAC89EC1AD536245E6891AEC906F65D8B759A6BB52263EAE26642AD87C123B7BA8F85C26DF7262EE5B37ACC4D0981FF59C4924205DCE695C6BFFAE73C8696BD679B0FCC7B4E5E960B8660952388ABCBC0D4B2EF528794C2F26B17A548DFE0FF212CE2F9AB69AF0A3412E34DE8AC8FB36E9E020A7F3FB3369AB402A5FBD4AA55659FDFB5AF76A2AC3BDD8A9FEE23F9389B6D605F629312A61C0E3ACCDBBD13E099CEA231FCC941FDFE3363E7099D52928F61220D827A680A4D503BD20E0715C41A6DC5A847F816297650D8A630C1CA238A323F02768FEA3008A0D401C0181881BEC1E2697EF192AA681F3CD2FD793E4B53F64B3E86A6C289621B0B88819FBA7AE2CFE595C3B0EEF79993A9C7DC24BB41454A585DA6FB9EF3C2DD0412D9212255242A9A23770BDA03CFF94512DFEEBA683CE968CE7CF133336ACF2806893BDEFC963218CFC92CB238CAB1B4A1D5BF0C47FBCF80F8D825ABAC4D8E94E2F0967A8B89006B806EC24E4979645124F3AEF2349CBBC1A7C866A70DBE8214BFC3E74D161A716B25F3EDD6C58D6C669027E2275CB9E1B40C7B7B2D85CEC77AA3A79A8D976AF657C943049F2929379D89C2C25864332627BC7E9723413DA144B7E26AF4393EDFDF4BC2AE227A53F9A1059D615AF608A82E9FA51544457776B79034781CBAD269FE7989666B7FBCC506F11F9EE8CA8C96311733F1838A8E09473F4A640D87393493D257E7BD7A5EB407A19B0D37E301529A2F423E61F60647969B59797C8B3CAE9DAB7A2F23617F7F6BB464ACC9BF899A34FD876842607266B44BAFB81798D3EC261333AEED08B1F7AF5D521202C7A30509A179DFAEBB0B4B883A5DE2203B909F294667368DDAAD80FF342B4256A7E0F09B0DCB6DBB17A249526C50E9CC2EA52C12D83BBBDB6B62282699143FE815DDDD9F8208F49E842E1FBBEFFBCCD6FD25534E779E664BEB213A369C4846DBCB6F4AF3F21C6075F7DCE66CC0FC0A11FA36D575B081B87022A2B99B0B8123C0F2AB84C544052F69CAB5B9CF982916D23EECDC5E47C5B6F8909867984A23B19119F399B5C15C25298E8980DF42B5F1D72029A84FB498070365B6F2FD1A2DDAB61EEDBCDECA6C9D6F7CEA0BFB09FB951ED23B704F697E1C2DB8190BEEB68B7491B7774472C2DB599C64FBBFF0EEB80F5F855758339C31EDF3C8A91E92DD8DC07E67D963FB7A86A0A023EB0969AEED22DC61338F52A533EE3CE03C93BDD7766A5EE8F81C07EB19AC7A25A1EDF22D8F316630E32F316302D9CCD5061838198EAA407B7D8016D2D8FE9B003C88CF454E5F92DABAA9CDB09D553D47E5C4EFE6F63919F915DC8ED507CADF7B328EEA35EFB10775E1FCAD45CD7A4E33A6EC45964D6FEB02F156E46BFAFEE5501A05AA86327BDFBC3E77E89D1B452098643DF06611F509559B3B1ECC9E9CD3014CF8D24D5B83D91498F5262FC09537947345A8DB09BF808225B9BF7350529E6CCED2ADCB1780E288FA5CCA71DA47FCFB5D92731CE3901DD954B17D764F2C0FC648CCD916FD730AE796A7F27F0A6B49C27CD0B483DCA023266D3F6ED346786E3A6ED224D062EEB8D25D8AEDA24FF88D5AF5CD627BCAE48C62F84FF4D9C422AF5F3912D569C1C9D3AAA62A55BA8F4007222C1A93B3DFB793B0A5974D8E41EC4D5B0F33FABD221A9F7942FD15B2DDB216FA7734B5E001D770987E57C2B5A135437628F47F1FACDE8410FEAEDBF9FC9E77C551A4567EBDFCCD60D84FD15D948A666B4C2C3E8804051F2143A66145CC1A540B9670037FA1784A83A2C4BD436BEBB1C65BC0707055AAEFDCBEE3ED154D83F42BC1BEBB1FE13290119E128F6F4C21B06D4BE969D68BF34FDF1C8DF4186FF0D8F04CE6E6AC9009AE9B7AF463E612158243B6E800BED2BF8224575FDE2DE3ECD57EEE25FC45B33595656BBA160F86AA0D10F934BE8DC77443195CE5FFB0AAFA60C554C7DFA6E3416C6BB0F8B7EF85B4B979559ECC5E4DD4A1B7A340720381A9B836864D98C99174A3E16C5937A16357E288086693625C79EFD35159604D33524AAC02D71EDDE0A88F5767A7CE0D58E6ACB53DEFB43FEA20D8AA6EE4F942A53BD0879C634B4677B59F7F4282EDD98DBB06AD33AB6282BC0803407D67717555A2EFEA873B8F9375BE8450C5DBFBB07331D95809AE1B9C1E50951C08E582DB6F2C6DF79558BE3EE2C9A0CAF1BA0F3477C8F861D91D09F485A9A0B09F097D01F33277CDC764628E382FAF17C6128B14DD23E004E63FEC5F5C81522A62D03DE5DF2B4A0D126C14710D2FCB4E5144DEF66969928FAA388EEE6D0FADF2A992CFBF984C2CF8947AB49FE83796176C58269756F1E59E22FE8871BBDDC367932375DC08F379D62A1A4521E88B45665B55F52FBF5F8B2C830134D2D0C5F42E2BDBF5F18C174F5E42AF0FEDEA1508F2303085C20AB9A6F73EC6EC6155472EEFAC7F83F82F8573C899FD5EAD9B8D75F6788E33BA2E357D81A332A9B2F33B38351809CA204436BA28BCF42597DBC58689925AC39EF830575A3C645F1DE48FBE59527962324628D8868400BF95AA47F61008513097900D422F012587223FFE58818125204F29D84C02F0CE26A97B97D3EEFC7F5D3FFA1D73D4E39B99736467D3D16898DCEC99EB914D2E760734616637EEA0ED8E363FEC232FF09F743C8E047F9F9D97B06FF830FC7D0F09441EC9C2959174E970982DDCFBF12B8C16BC37270CC502F908F3163BCE19C65F61FFD64BE2C66ADF3340DD6E72FDD7D6ADA258683DE6B1BB4440007B096DB921504AFBAFE349EF38B9AA7B9234070DADCDBD09496318F80AB2EEFCF85D4DB2E5019E5B7808308369B07BBA4C01792210FFB855BE8438717E94927336D183153F07C053B0D92D00007329C3A396253E201A02A107F6D6EF9A1B93BFF5DEAE817753A3D199F5FFE384A130CE47BDE795569F2495C4D273E3713B802D3E327FE753EFC4D98C7670AC5F41ACE638E850552B876E5EAEDCFA63A1BA35F29A8AF381A631F7E2B7A2E1600AC6604E0BFA5D07FFA5FC43A331CC53BF759CCEDD1AD6F3113928E3F7C50F81476A0F4F6064FD46E2F45BE1161917B775295828854DA42688417AB46953B4BCBC16D35185C4E9EE5EC35AF0056EFDF314E8A8B772EA8390B9236C6EA03CE7C720DEDD32726458215772B56BF2E3258E5BBA9D0C785B7A3E72A03F0C87F1F09AECF1D12F9B27435718DA074570532E4067EAADE59AC3FA23F899BEB76F6000DA1F3A21962F0BB1D3316B649A74A1FA50C41073A8FAEC381241FB314C761752D51129A24AC1AEEC2B367E8C6BA94D67CF000CF6208E5E2DF2CEB9FCE5852C6A05A9BDED62564570C5B652906AF77948F9F34436C0E8B0B0D3E18A17CA3F1DD1DEB12B1E3242C04141BD1DA86B6B9B936E5D763BE6D41A7E84A0466258F92590B53142A299879A62BEE81ADA3D5DF9C6C3D0735D3DA9C79AD54D25E71BB3D3D63CBF89987D77B33B21304CD68C3680DE9D421D9476EBD8A91695D2D38563D7F5D9909322D4658763B0BE53A5CC12873FE876240702990E944A5CE36E2DFE1E17994F73AC15A7885D302E9FF7D3420208260AFE94BB6B4B65AB6455AA877ADD024688366845EF91C2B6B0FE2C87BAAABA27BEF7549E0AF47812EDC73CA16910ED581515D93717118780D23B535EBA97845F8D4A3A5583A588EBFBFEDFB974FC927D4B6699A68F68017E5F1EA18DD53F48AD474B070162EE7B87F597F30D0C57F58EDB4C3EF29A8649532D3A858FBBFE9195E3A8396CEC23561A5E91FB270C1CF81B44D10A64F9AF9547CA89C293C46B64CC2FD4CD777B0DCDD4156A619D11C01C38A47CC54247CF76F744A824BA93BA48140485CAF212B55816B5B663F351EFA06177BE8B1566B3E94B85C389BD67B2B6242DE4E11F53A77D1CA330E1EE6B34D5DDA82B75C050FB8DA59FE5AEDE4E754F083E849ED2B0CDEE89B14EB0E459B42723DDB270079C52F89C742B05D9F81581A08AC3BEACB837C6A05FEC3A24F9FD9E09033E7504646C9F3BCCDE7F64485042729E77F1BA00882D74F935DF466968E59E4D55B6D6A7FEF5CEB37D2502C4324F639B8117554A9A0A981CDAC21D9270290976EA80BAA810B45FA77E7937A969D1A524D580188D68D2AC3ECEA92FB14A85ACDB792958BB5B2385FBE3E4F3B596AF731600BE490ABAA6D2248D694257FB912846AB3D2B36EFD3F09864B26F8517FAFAFC8DF481ED83C13BDAD733C6515307BB382E25ACFCC66800EED32448393EE77E302030A2795DFFB8E6C98BCA7F64487A745B681B90778257DEA692A072325EBD612E48C6C9CE7B1E9B41AE3D6C5D611B97BB392B497F983ACD0D81D006A3F81638FF66E828A3EEF26B384535E5B437CBD8B9F74FC951867AE8ADA06E11A2E8AA399C2F4F6D6769316F36D668172AEF6FA656040FAD51027C55F67CF59ACD416262B8FE4BAAA7D0E430A8ADA29491F23D4A5F4B08985A05DAADE7B0AFA007AB692D91C2994731A89B53F5BEC803FAD31E15828D74538F5C873790DB1F532677494982ADE5F9A1E74091CD500EC300C47F7D0B38299CC12B55DEB9601E76B69880B0B776F66E1964C76292CD30F0911A3265C1A0896B69924564F479FAE7E8A1DDA7E9D612A4646717E34E5BDB08AB776FA4F6F36E01B37A8ACA8B8268DB222B08EBDAE12BAD995D2AF25EA44ABC45F6E9638F7677307661388F6AEE3D05098B98B917DA2FB43751DC78BAA5DB7CF598F214E13AF2CC40231AD34BE8D66B7D09E891098FF950018C89CB60F6D72E7C0FC861955FBECD43BFBB7C5B19648FC5E53DBCDCBD036ACDC1EF69457193B15ABD21348FD7E3BD3AF85E6706A2F24BE2A0BC748C95162AB5CBB3E7A7BC2BF0AA96DF93A09D65BC4D773245D7C379BB3B738E35F0112E157742113A0EBA136F5923F259E89DAB9733AABF2F1E39CFE975617F27552686CE7660F333C06FF6F143068D6772C48414FD2920F0FB45059835BD6CCC071AABE36646610472E6ED7B7652C2E92582CAE7F127CB0C86514FD7B1149C9DB55D6CDF0A6C5D499317F8D65327B1826AE6EB89CA04884D053DCCF2C0F2F5FCE23A0528814351849164E068A6E74B187B11717F83EC4BF55303EB9BD8E7FFA94A678C318E7153BBDDF825CCF3F3FA43FBDB5361129E1C989655DD628DBA4EFFA4A28A1EC2A4374102E19D8C03D070B1E6023026D3609D50C6637937CD7B25DD7BD09570D0610C159FD32EFC6BEDA5B5F7BF7D775DC5EE943D989EEF2C0A0FFCDCFFFAFAC79955FD6D43918C79FB634287C56A784C333FBC5275D7CDB55FA773DD79ADB72BB259FCE67BFB82A11FF590750E95060D631D01C7C7383A383087E8B4A24557241CB4452622FD3958D5C9EB5DE0918AE8B1C178B05C2FD9014DB5F5425CF676DAD26B0448E4DF803BA45E33D3DF3BC6FCAB801498B74CBFFD1EAF61F0DC69CFB318EB4611F6E31F2BCE5DBDBF15273281A5E66E4172B78F6CF6AFADE0FD4A6791CF46C379F5F9CE3D9F08FC0ECA90AC0107A8263300463044193384593B81730849D40284420240941B484DE05FFFF9ED0D8CD982BC9009B20BE097A0EF13C7F71BAC1F8A26894591AB3B84F665B19B0E3A6723A5D8917720D1CDA7C05CBEEE8A063849661886E5714AB23F379CCAC7BC2E4604F1CE735549525DA8F1B88DDDBAE44F8D8DA26ED6426A4FAB815DC240E61446E0B95CD392F4ECA455DE47B2E20517AA450646BCCDC1AD3A885B4CF7C76328D424A3A60C244D9C8D8594FE9BCB75CF319719C0DEB0E43D879A3841493E5326FAD8A28E45CDC4CE5B14672D6E8103251507506432C864C3D89116C349B5C3E6D8FD97C98A7B36E6A9D9E59B061D78024379F11CADE212990AC0EC6C1C98CACF5C77DD03940396C0165543873DAA8043318E5D04BF86C336FA4D9561BCA8C46D64EE791613BC7E0441BF9BE0165B4057FA75E4C9E9F0DBCAFF85491EB92338DE9EF57B70FE9B11A9F0D13479DF9BE6E108D1F92277D7487B0ED4BCDE827E357C71EAFE146D14A8C3744C3B21A1CEFDB34521BFAEF08F627D43CFF0E6EBB38B9872714645DB9A96E2DA279096A5C6404185FA4568731E9597D46DC690BA2165E087C97190802DFDAC033CE51B5134C6A89DC227A6B84FA2117BA8EA3E31599396EA964E9A81F7A9A77803933A46AE4842CA62FD93FE2C3A856375BE06C753C382C9BE894C262317C9E9385D3B57800BE58C5C9E9394AEAFF14445B1506ABEE5D4F6E1EE7DE251A1539B447AEA70C129C79A1552785B6FBEEA46721F636692E1DA48BBEE70CD47E74C9A59702CD1F3239539D53FA6E3A18A97E1D75126BFC051FB352021C281E7580B65390E6B785DC1D332846B8976D8B4391FCE4B2A2446025562AB5CBC1E0125484CB34DF8C83DD14A7A3F3B726EC970E80DB8A6DFF479791B14809F1885A55EF283A7E1EA48DE1EF9794188014699FB03DAE390487FD163316A6EB5EFF479A6522271D25F5F8779E7AB5DA8722F519C1F8F66E2B6D851D4145ECC5A4787DB075ECD33FE5467F3049DE882CD98AA087821AAF38D80A65DDD358F5E74369AA8375D81A2E7F129E5DEF25C008B57D183C809017CF56547F9851AAC3D452E89CD1FEED5EE036C18A87B583D3DB9D903CDAF7AB6B973574F4828B4DE584E37C3FDFE3433C4ECAEA384D3EDA1414446FB9B89764BD453E010355D8533898202C40EA2F52A6F09E799622458E0DD3E4821C87FB3FC64F989FA2A353B7385772F7EC30592B9FF6C8C75FA9B25B1DDDC51496F70B90EF421DCADF100A3404C14061E6D7A243B6C58A7EBC9A82C5F4C5ECE908186F60D5950A475B8A2F481EE90C70F87B08AB5978F7A7A253AB5728DD7B6938C4E85C7565868414D6759CEF75E9A9B3077697FD34EDD6D91EAE979195D4957798AF095609BC41CE894BCFA6A5D97635E4C3538888C7244DC1BC03CC7AB64A424387257DAC6B4F2456A9D0167074FDEA7A0B334E143DC34EF8FA94707DE23F7B8EA960BBDC84CFB4AC16BDDC18A983B62D62E2D5D39D71C259BE40BB9AC60F015CF9DB2E781ED5D709E48F5D6DBDF7B97D27F6EAECCD4023A9DC08E4454F5C3F9D5C80C4578D6D402586055C184B42EFED08EA3DCD5B588F0AFFC705C7E2CF6BCF8D30FFDE15959084F29B9D58FDCEE8A8D31622D6FB4FA4252707AAE29182D790791BBC24E20F9A6AAC1CFE57153C2B48B31EDEA5B2EF7330821B3F4E79A830BB37C29653E803141E324DEFB9C21217F6D6F7F0C2B7D6B3EAC58BB088FED620E8CE097FD03D6D32A1EE0481FBD32FB1DD43E50439B187D9DA57500673E179F48301A5BB6EB79B5A0ABDC3E5540BF27E1E49622205C39707D8B669EFA9EFA499A4C90081EFD4E63B1D128FF4062A79AC6F544A07EC32561EBF6145A7AD38C7D0748C63AEEE1CA10A87EDF72FDBA8B9BB99A124BA14B07E66C9B16CF2DEB72551F1DB5F64F322C1ACB8FBF7C6A6C6423496E045A19B55662D7A40B9EF05D57C4FA9E6AFFDCC5EAAA83C05D5D7B4977ACB0F22D365BE2F4E2E7E835028B00906BE98BE98F7BC9C3B4402696A88D62EE8A6F61F529E2592B5A3C3072FE08EF6F6BF07253A3ADA7EC7439800551154A05E35A5338C3265C4F01F84D11CB96511D4E4C250E623226A8A26A37E4EC848A05E18B2D627330CC15A4FCB6FAEEBEA7ABE3A0CABE9B6EA8C09B1DCAE749FAEF97E8FF8FF6279EA6F56AC9A5F566BAF327369433D9B33C227094886833881229F75614B3B76487188245D6442D444FA7042F1F02E1E456FE7BF37C9936E368630D3DAE019C3723A16B35F295A49668E97735F4C613AA9DEBCF6759C69DCF6EAF07CD69E84FE32F0BD66D0D4A9C69394BE47B237FE7584D3973F4D80D9641B7773D0DE3CC250999C835702EAD6F009257614414C3342A55547E62B09D56B9758C46CEA52FC6399C2883A6287898783999449F213CA7F834CDA39CAA86E9E21E2DE4130FEE63523D41AFDBFB4A6D136937A86150260A6F46BE374CBE6668EAD74D19F819924D5B3C9361B2A7DFC0603BD663B98EF32F69FB66D971628347F77DF610B78DD5D1A497A60E247DA6CCE3ECAD8DFB1A644B4488718368732A7F2202C297B2186142C73727440BACFC3D11D38185393583C2B0BA7CFAA5D0BA9E8FC4EE649BE6E23946290E9D901759448495BE76E3D0A80EA80511F6E2A137B6F0D9831E00C1EBEEF8115EEFD421B149CF37AE73C9BE40D3C38492A62405058D5EAA6382FA3773DB002587FDAF1BDB39033FD43F879D0C41D92650AAC04B8337CFF34389213FB33177CD8C5CAF46CDB810E6D17EF6462D99B454955453CFA7F501B4C4CF27A6DDC809A0AFBF6548FF03D463F393A72D749290D362CC494D5A725C263A3E4016BA3845B15E08D597EB6C70835016343B46661FAAED9487A23C6F5BF404F5FD321774FE897356D63333EED4EC02747F7E78875447AC8461BAC20F2C44678215FEEAA9E4E0B04D8DB84A0B296410CA85C815AE037F7FB50A107F4EF0181D28EB6ECF6B7DE8BC52A18F55A2CBA64ED12D4315B9DDF823365732252149B66268E82DF5E85154B39BF8561C24B0239A608D44F90BC7EBDEF18DDEE811BDFA15E4FA7DDA804D85345C8153CFF9A321D8328435D0C1504F4F252416114E96592204253E8EAA37254E496FFBD6BF5543401498E55A28F3EF5D6197247B65E9B7D27B9A63D5990EACF07BB119806344FFEC39F7AE2A19EA805A11C9D081971C2972E85076435DFFD367224145DB8BB5662008C25EDC20B012EEED9A2110E2BC892AB053BEAB257BDAA6F2F277EE428D508B3F741DADAFA9C15B0D181BAB87AEE4E9CF471DC8426588ACEEF840F2F20FDD9C5F42DDA82F3E0803F62E9A33D2C7CC0050F9B47C25197028F1710F2C34DDA5D57EAE4E6AD16C7BC13ABCA3AC42C59204EB665F50F3557CF2C8880994BC458790FE461E8ED18A124BDE08E1365C207E35D4C9EEE081AEC4D3D70F0DDC9959A53CE95D02A8357DADD71D7F9D78DCF3686C89B2E620258393773FC5B957283299A468AE2434BABFC1830CBBE9BDB192BBB0B22F7D7E89FAA983DC6AE91100960BB67402F606CF1321CE5FA7F2774882A619590FBF4B0532D8754C2C6687A9906F820BB2F0F4267B2D3D4DDA97EC554D53EB82E7D4E7DA76890FCD2CE5C41F0AAEF009BF666F26088D370DF70D37094A3C6601D4D1C4C3B8C956B9D159A984032488C6BB30AD556B9A1FBC5DF19376E865E22CBA11961589750E6C3ADF8638FD22FFC384176A59282635FAFD1731E589C4CFB8B49829E6F7402B7DC7B8AC8D82CF59FE963FD85F8A13C35DC2425408F23A2DF0F06901EBF245B96C01F5DA27B17F80FBF293EEAC29EB661F34DEE4FBCB38C74F3B7009EF840A7A578ECE69F5285C7850103A59A9FB0F170DC74778FBDCE2D92CB6C3F2BDDAB8E493B2B952E4380CEBC37C77E5268B21DFA73B6C1D132BF3A0E1B96E97981FFBFAFE0B93AA01A2683AC7372FDA83FC57D0FC52B5BCF1BC0A767CBE98E51DDC21BAF4E83B8120EE6B3C6EFD2548E7DD4A5F0936B1C0A697119D366EA890E649E3747FE481AF4F00CDA1426D9A27BCEF0D34F5BBC37D84C06E3DB95BF50BED1EE594D33006998D163FC102519C6775B5595D0D01F7840275EB45B1F4648C64E2A6710A1D9C2532404A365DF0211B21E6E1D9BF89BEA790A0D5BFF6A8CFC9FBBB1ADC2EF830D9458350C1C4D75823D1E7F5AA62D7FB79048195807F3E4DE6105565099788FE3D322BD7CDD78A3F36641EB3AFB7AFA65BD59EB6C430182A7F32FFCDF4840D2F59D7497C774CE0AC41FBE2ED7DD0347D2FF2B6F43B1648E6A9A0155F520B299BC1488AC1F0D8A434D6A7AAFE24BB5B516D4FE85308BE64DE5A4BB305D33BDF1D7BF7BA9D6DDC7E273AC210003C40798BC32ED83B3DD46F353ECF07CDBD02CBCE9BE0D8DBE579413EF51085EE180589A9A3E8C8FED3E16A47481DB3DB93A157ACBAE1BFDE80E0182E324FBB28A66E4758439C2E6AC29F13C2DB1B4DF03023FFBE4ADF36E3896A613BF58649ADA1F4DECE9DAF02DFE6C0DF7A4AE78DCE34311EC755759FC6AC2277ABC5606F9364C13168ECF92E10348DCB3B64C419C63BDBFA506EFECA9A46BC05A85683D39604E0C43232D94B9D8F5CBE2F1FD399AAF5047B4EB17EDC1BF1F5F2306976992BD48D1FAAF43216B6D38B6A5CAC0548A68C36088C0BA067C27EFE4B13EEEBE062D264BFFD4767C97304FCDA78C5F6D50009CC00686125A26A8B6BA61704B10162325691B6ED510AF8A756A74E19FD79B73076A160657998DCBB840C123EE1C968E7A584AD72F6627AFFF532C7F75FF8FC28BF927EEB9400FD73B779D8C258123D3DC87B8EDEEB34F2E4A8D3E66532EC5ED15F2A35250F54D3F00C8EAA5BB89F4A9FEABF0BC0422B567710D2CD321A987D4C410FF3261849902584459BE6E63A97D2A1449F75C2CB10067541A5A201E1DF69F7F16BBDF91981EBCAB0F54176DCAE903F2C16BD66F518FB2C3A4B57428548E4EBAEBDED76A52F15AEAB7A74EC3A10D2BE72484950817B36D30057F00E56F150B1472198C911E920972715D749962211FB23E7832684FF47ACD6A67D52D1B1A5AA0723A212386ADEE44E2FFA390559B89EE1EA326CF1F8E58B9F59A3E34C8CA5082C3A9CE669DD3A447AF99951556E91D0FAA73F15441DCFCBE4E0A920CFEF45433821E3A8DA5B6DAA4FBCC8CD8D370BDCFD79F61A372DF68ECBC3CEC8418931CDD660FD6E2A21F6082535EDA6CE3DACEE6AF4A038C567EE79A58AC1E01758DF69CC944515E2DD88E59EA2DE89F74E52F46D65F83A7A491C72D94204FB4CF3162BE415F98B0EEA6EFE9EB5D0A6BAC4EB5C77C0C8C0D9B46357C01689A6E12A38F00DE58B78EE3E36FCBA9674BD72CEEAA070F0EFF6B14653D1DDD53122288675B2A88DD1D2DADC2681D4AD1502294E2610446C63A576BE0205EBF33DB4E32E88BA4F5C454D30807C93B282530DC5076AB75853DCBF247575E61117D7B3A9F3C73E12779B97C92C7C6F8EAB470D03A5150DEEF324855ACD7B5F6BB8F87D2E5D36B7E20923A59988CE02A1487B29F5E53C477599C07EDACE2FE91252B8165ECF656C7BBC49BAAD134567BD77FF99514878B228B8A99C6B9CD70E57EC34D0446C450C10652FE816BFAEA53A21438DAE49220D0D3C530220D5E59E659B802353FBFE1FD8AC91EABCC350A932BACDC480883D9FAE341B956F2D9525E9FFD17ED7349938087BC7AFCFC04C431855C7D95C2D06BE55BD459B932C73A455116F67646BA309A7A3DEBFA4F6D6DE25F4D8C4D2AB877CDE15B9D5B48B212F33578807B182248801B8B25446D96EC8A26152A6725C184EA8C50360349B9710D0F66301BCBCF32816781EA3449FF9A97BAC2D2045713936AC1717662393D4A349D2BFEF46FB92489E766E227FC5DA63F8BCECD71DB6B067BA6EB2EB9016F119E8719B5246957522086034F43146B78806C6B1E5222068D0AC291747C51841AB8FEBE482DE0B4F55D148A26B3407E2B07056A9D09586E887A82FC441A4DD27AD399BF08BF71ABAEE9C743A6B727C31764ACA1D354EC460D31EA1FF3C4594FF208AC681617A3A54233E1BCC274039CF76612146EF951E794ED71976D0DDBC7383840137430FB0BC6B922072D99F4AC0FDDFA952BF4AC4303A9A55908B1C15C82208F2F77BD61A35A4CD63578DA1F514BF610C2325DC3D15CE997946769FD9EA7E4C810C36DA54DE420D1BC0AED90437AF1BB475EF911F25F2C5DCD84059B8300953EB6D68B29BE44B4E28DC70949B3254F74E7D11AFFDAF28E12AF44ACA2F684312D5A9E708BAFC2A8DD9DC7C6AB538808FDBED87F17D46110B176BFF62290493114081C83E101F6DF0C84A9CFF5ADC8902D23B14A50F7C538A212E34A3435EAD1A9202B4234DC3B486F13ECA67BF6B71BC8A5BFAAC7D9F2BCDA663331EDD4408BCF907ECFC097A13BB35FB9A0DA774EDFAEFE224EF80B49819EC609947BF2176C79F222AC10DA88A0C0A10A82DC196A07DD39AAA91D709C65DF0B2151F1626B01A99CB847F1BADC7A1DFB24A5CED20EA35E34B109ECAD05C538F2DF7EE608A488E3A5824D2A3DA38C809758CB6D7AAFB0F593BBDC0A1DDAFED34534F5327A060D8AE892A7D9701ACE497BEC63F04BAFE2AE6FEFA01941F069ABC689E53057908372E8212CD96F461C31F689A2AD2A93E1846F5ABA0EB2AEF09EAEB1BA3445D8A3D3CD3A2F112BA720A76C39A124FFA4871C1CBAAE53E6684AFB88B58CB52B0543C6ABEB7D916BEEF0E05AFCB9C716AF0874BF283FAEBE3112B288A62BA0A09E7EC76B92920839F1BE8FCCD01419B32F8A803021C64EB269297D8782FCD5964691C6C4A349AB03B9995006902AE2D0879C979C88F281593D2E1552BB3AFB758E5C20F82F34FEA6F83B7D8CA56D2F3E31C90E6F9CED2C34A2AFBF16D144E97B7B715ACE66CEA729A0ADDB7AFE91658A50FF839045C89FA1325FF185FA48C266FACFC89AB8967A19AF0C01AFB686A64B5BD064596B854896E358AD472FA26666CA91BB9F73BB9ADFE194DEAD313B1BF33FAD188384884233AEB7357994BF805E0ECACBC90790F9922E5D07B94408930023959045F215F1CFB877BFB2BCC7A3F778EF38AB17A40C6FD93CE7AADDBEB621E41E5A3EB21466EDC7444A17EFF3430475A9363CC2C65F755DC899EA087889974235ACAF312DE63A97C361442C388F90403FCDDD1635D5E96D9A2C5AE4B5D24CB1E0199F70ACEA18D92E4A64217358B79789F1D32DC585016E41622A84BE8493F0FD3D09A7DAE600DE189E5A172A44FE3193BF335947F31E0AEC9D07933D027025C536D46DCDF1D8062FAF9293C7038B3DF00676687C32CB6588B6D3B805C23DC31BE27E1C60A802E4CE54FDF22541DD75D8A7B4C28881CFA97659F3F00DAD20827F5F218DDF7EECCBA7593FFAB23F7D5AF8CFB93FDEB2F5B41452F5E3054C58196506BC6A2132CC4D50897676F02C4AF372C2880A6E6DFF7FE396851D1849A0D0196697A4BF45ED2BDDE71CCFDBF9795CCD06CDC08B1F168AC3E53D78B67AF63944F8B8C1DE9BCAF0D93C441313061F4F82C24E7FEC576A3B0FED70762C78C196B01CFFE88DA3460EFDDD2223A8C4F5A2CA43E3C7409EAE26027332CD64BEC303240B680DFEC673D5705B765AD1129C1890DD88121D4F7618DA65C0DC77744AC87B082E084BA98EB3E22FD2A13DFC3D2B5D11465919FC58927498E27261594A2FC2C7DEC36DF77712F130A1838EC919D91E6E491A21365C983BAD0E29175FC8A28215C3B8FA589105F6B23A84CE58AE3CA33D3A73184C00475E66CC4B78F5840E0C1B391FB8D2E7025937FD5AF626044217C1208345AB7116CEA2CD392E29561AAF9C01AF1C7219C719910CF3D8F7D378982F958DCB5A88C77D6D3B957CDFB7DC2807EDC62B9B0AC7507914F7AC7A491FE037B3E4E835F87528665236A3A782792BA1203BE0435B1B5274A2982DED0844CA3FE1485BBC582DFC4628B7F0F08266193F80EBA4BDADB25C2726F5BA97C1FABFD5D8EFD0A872F3E0A2604250972DAA4DEDCCD48C077B3A32E2CED48903E364AAD1A96F7044A970DA38F9F784DFB49456CBBBE357F2D6E0B86721FF8FA59935FE2BD9E0FC93C2A423EC6E1E5B833B6D11EB3B8EE5C8B1CF8FF6FB18038C751D93EA9689D6D25648057E4B28D5C0D9EEFF52D0C5DD7E5547A81A5214B2A98C6FDF0B7B8405A2C4FCB0E8C79050BE35480FA6C1D670A538734B1EC89457818E8BEAC394D353B8429D449CA36B31FB9C8DFD791834AB4FA6A4AD7F00772BC111A6C01F6581C6BF84A2013DED68ED54F2273FB187FABCF5FE98849744749AA4982AF20F1AA9E7B16E18E2EF362BD272715D2EE8C213F21CBBF81B662719EB481D7E43038CE74DDA5A087B2A87DF1B6486055C67626FC97D27465AE466B42523EB4862A8F202A7ED2FB3913E5C9E24B1F53946470244B1E199F3FC174ADFE375EDCD9A36DFE2798BAE80EB086440493CCF5743023F34E52799CE9201FDF5152167B43D2D31EF04B70D5A426C3D0EFB68D644C2F0EBC53AF2A32AD6651CC80755C9F4FF57DD94D823E62C6D3DC52A753169D74CED8DEA497DED3228749234887C0D7B865FCD62E0D3DFDAED2A1294A7F994F2BF64CDA6B4683559EE4D05D8C5567B3346EB2CB5D45F508AE5082FDC378C70F045540EFFA3335FFDCBC1B28E60C8EB997ADCCA5F782932AB861A0066AD7D725093E4DD63E253BBB9F768A3E09C08D80FA9CA19F2C9B62CD994EC1779AF70F0D2C0DACE3F4C1B1B06BEBCF611B7D7008B55A7F1C3E1FCA4BE29CA1FEFB9370BDD239DACF61C35812DA523A9DF3ED68506B765E9FF37230653C78E96090A62676DC9FF160A35C9A0A08433C4F9BF97EB571959E808B65CFA5E9F25478E2823AF0D440D6095C7D8945F27C3561B444214A21BCB7312AC3264FD34E8D18CA51CC86EF601E16D994AE5F311A5169781D6C8B4E893693A0CF752F3B94157A3EFC9B999C18B3F4EEFB89C2CB9CC8420C4235F28D68062781E64288739D20595B60290BA712A87FA41B39F05156EB0978764BFD235491F4BE813ECBCEED8E1FE1C999F3BFCCB87B230518E1C7183DF2FD938AFE40370BBC94DC34B2683A34CFE2EDB52FE87EFA744705131F2525855D6818A1B4F52A8C58AA5409725EF2E945516DCB3F855270A30D9E06F916E63BA7872CB4C6183ABCC7392744979FDB744EFB60C749760641F5B9F11F756EC733D4400B5DA535C8275CC8510FE8662993B3B79B1B225D231AA3876EC9167887B15C03C78C8CCCBBD7217F11674F11527BDF01A1A53AED4FD95C70315D9456CBA474C2393ED668A843F156AEACBECF97CACEA0F384E34A43773F5E91A28CD9D0ED723C0A477136504C043F318DA14B6F0765022DEA2C5E04B07C3A005F63B93BC43F66715D1F407846721F72141F13F620F528D9051A7337FB93F181828A4C21B92D03E969C70B7B0E9193724AC7831722C4BC8FB3C924F601B3D9B0448A9576C04181F910E8D5ED1CBFEF25B8A3EEE1AEA0777275C518B62A72578C674C02AFD072011FAC318F4993819DB1B0C2F1284CF64BC40A1B655A114BDDA0EDDB6C46A3B619D82D4768335EFFF42EBEE60692253DB275D14942F5FA5273106BC2AA4CC7195624F7EAB412F7E1B4AA367639AE71F4950F32B6D0C3B7B236C19FBBD21FA1CA988D0AC21ED6A7896D3AA1054679DCFC54F0E6869A6166CB8D7DC1F2A8691A5E06796B8C5B7A95A7409E9CBC2A9AC41C8D314B959E37B72D17136979BD8167EEE182D1FCCCFFA1AD8B71EDCC51FFB67BF1F7187289C64C3A92E441663A937C068B8A181872D1E8C8FAF0403AF56C758FF2A1EA6B5DDB0623990A9FCF9EA78A725A2314EFCBB13CB2E1E11ADD9B3726962142DF1FF89209F58EC5E2C5891D08AED7F7BB09F97E9D178D416F52CA7787321FF850CFD718F7FDFDFA47CBC1B876F7FADD247773823B1604DB3815E1153BA9B33A1B5E8A0F8D28B0B33CED4229D8242E445C85AE4F3AFA6B2F9F9F613CA7767C6E9E281ED4A475CE118EC82C544BC43210350A1D12F4DC38FFA3085CBFE3E3F93D79E8C228DC7FFFB93BACDD21B1C9E4946315ACD6D207D728CF5EF75D2D46ADCF5C2CE3C42ED234FB898ECA062AA1F62577AC9271370CEF6D3D0FACC8E455A5B65909C9F5A2471757CB4A73A4896713F4A3290E3C472DE4B18C3CA9471B50F3DB6D608861F28BB7346D9E9AF312FD40E46283752745DBEDA2A22E4CB52A4E3767966B96DE0FE82A9BB2632630F07F94B2D197168048AF4296F0E1B8F90E535D694313831BE3F40EC9450688A8CFCE4D65FB0FC34BC0AF524483B725FB0EA702F718B5B3C842DDEE46DD3865F1F338B12AB5E309DFF18B2430829AC59F2F5EF18ADA35DED6E11EE05429C584E036F933992ECBEC3DC4A33A29D2F4FDB7E1558F6DF2DC35B2B57642C6B50DAC5838734197C51F00CEBE66A594D3DD15ECDFF2B34B7ADB4055F895CA00B56D4B505CF3C35ACF05EE011CFB26D2A2225AE8A10075A47D5AE6510028AF9D2C88FD84C340C75FB65766F35F94F216B063F5024C023C055916E2CE55B10B2888007F58ACBE16DC7C1235B95D07516D8CD15FCF74E59B9031CD9057BA5A0B09250E151BB40E714C5B4DD8D2C13D99BCAA7FAB98889DE8291BCB4EABEF3BFD07AA8F491DD858D54670895BBD2C170C0F551510B4663C7FCEEECF3F578B8C667CCD4BC7E8F30F4DE87EF5C964E7F4C384E774B596ABA4CA26B34B38FCB505A, afterDelayedMessagesRead=1315796, gasRefunder=0xe64a54E2533Fd126C2E452c5fAb544d80E2E4eb5, prevMessageCount=146912609, newMessageCount=146912762 )
TransparentUpgradeableProxy.STATICCALL( )
-
Bridge.DELEGATECALL( )
-
TransparentUpgradeableProxy.86598a56( )
-
Bridge.enqueueSequencerMessage( dataHash=2049F8A19BEA02AF998DA1D7CD916F31326574C5E3036335CABC77CD292A10DD, afterDelayedMessagesRead=1315796, prevMessageCount=146912609, newMessageCount=146912762 ) => ( seqMessageIndex=492717, beforeAcc=59B213A0D88B89EB81D23CC9EED6CA2347F0F5E4E05E5FE953FD53D49FEEEE3D, delayedAcc=BB28129E40D3B8610F0E31EAFA090B9C82D21CDA1312D0BD725A66B6D17880D7, acc=55947571310DE3A6BB5E928761009E1C3022D1CF72E913AAAA3AB022DC93C39A )
-
TransparentUpgradeableProxy.7a88b107( )
-
Bridge.submitBatchSpendingReport( sender=0xC1b634853Cb333D3aD8663715b08f41A3Aec47cc, messageDataHash=C653EC6E125009968E68244EA465ED1A45C0B649494B5A8D6081D0F6D3E51BA6 ) => ( 1315826 )
-
GasRefunder.onGasSpent( refundee=0xC1b634853Cb333D3aD8663715b08f41A3Aec47cc, gasUsed=172870, calldataSize=98628 ) => ( success=True )
- ETH 0.082233868370122728
Arbitrum: Batch Submitter.CALL( )
- ETH 0.082233868370122728
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); }