tx · GSTt7Z228WrMXnJgjAsmhPN3H9DTj2vrnW34G31kWnj5

3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm:  -0.10300000 Waves

2023.09.22 21:26 [2766947] smart account 3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm > SELF 0.00000000 Waves

{ "type": 13, "id": "GSTt7Z228WrMXnJgjAsmhPN3H9DTj2vrnW34G31kWnj5", "fee": 10300000, "feeAssetId": null, "timestamp": 1695407246378, "version": 2, "chainId": 84, "sender": "3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm", "senderPublicKey": "EVooykMNV691Venwp1dHUTBd7KWequzUcda57Wd3LQEX", "proofs": [ "3PboT87FfUaFGMfipuvY9d93DUdsc7GFtD2BhwHhtYWabHkdQo164XidQUHp3pAJhfFPYCp657nWUSCYm8DwCdRn" ], "script": "base64:BgLbAQgCEgMKAQgSAwoBBBIAEgMKAQgSABIDCgEIEgQKAgEIEgQKAgEIEgQKAgICEgUKAwEBARIAEgQKAggIEgASAwoBCBIAEgQKAgICEgASAwoBCBIECgIICBIDCgEYEgQKAggIEgQKAggIEgMKAQgSAwoBGBIDCgEIEgUKAwgICBIECgIICBIHCgUBAQEBARIDCgEBEgUKAwEBCBIDCgEIEgMKAQgSABIECgIIARIECgIIARIDCgEIEgQKAggIEgMKAQgSABIDCgEIEgMKAQgSBAoCAgISBAoCAgISAJMCAAlEQVlNSUxMSVMAgLiZKQEUa2V5TGFzdEFyYlRpbWVCeVVzZXIBBGFkZHIJAKwCAgIQbGFzdEFyYlRpbWVVc2VyXwUEYWRkcgAGU0NBTEU4AIDC1y8ADHhwTGV2ZWxTY2FsZQCAGQAPeHBMZXZlbFJlY2lwUG93AKAfABJudW1Qb2ludHNPbkxldmVsVXAAAwAOcm9iYmVyeUNvc3RNaW4AgMLXLwAUcm9iYmVyeUNvb2xkb3duQ29lZmYAkAMADHJlcXVpcmVtZW50cwkAzAgCAghTdHJlbmd0aAkAzAgCAghBY2N1cmFjeQkAzAgCAglJbnRlbGxlY3QJAMwIAgIJRW5kdXJhbmNlCQDMCAICCURleHRlcml0eQkAzAgCAgVMZXZlbAkAzAgCAgZIZWFsdGgFA25pbAAMY2hhclN0cmVuZ3RoAAAADGNoYXJBY2N1cmFjeQABAA1jaGFySW50ZWxsZWN0AAIADWNoYXJFbmR1cmFuY2UAAwANY2hhckRleHRlcml0eQAEAAtzZWdCYWNrcGFjawAAAAtOVU1TRUdNRU5UUwAGAApOVU1NQUlOQVVYAAIACE1BWFNMT1RTAAIADU1BWFBST0RJTlNMT1QAHgAQbGFuZFJvYkNvb2xkb3ducwkAzAgCAAAJAMwIAgDAzyQJAMwIAgCg9zYJAMwIAgCA3MwUCQDMCAIAgK6mCgUDbmlsAA5NSU5fUkVTX1RPX1JPQgCA2sQJAAxyb2JJZHhMb2NrZWQAAQALZHVja0lkeEZyZWUAAAAQZHVja0lkeFByZXBhcmluZwABAQ1rZXlEdWNrSGVhbHRoAQtkdWNrQXNzZXRJZAkArAICAgtkdWNrSGVhbHRoXwULZHVja0Fzc2V0SWQBDGtleUR1Y2tDaGFycwELZHVja0Fzc2V0SWQJAKwCAgIKZHVja0NoYXJzXwULZHVja0Fzc2V0SWQBCWtleUR1Y2tYUAELZHVja0Fzc2V0SWQJAKwCAgIHZHVja1hQXwULZHVja0Fzc2V0SWQBDGtleUR1Y2tMZXZlbAELZHVja0Fzc2V0SWQJAKwCAgIKZHVja0xldmVsXwULZHVja0Fzc2V0SWQBEWtleUR1Y2tGcmVlUG9pbnRzAQtkdWNrQXNzZXRJZAkArAICAg9kdWNrRnJlZVBvaW50c18FC2R1Y2tBc3NldElkARBrZXlEdWNrRXF1aXBtZW50AQtkdWNrQXNzZXRJZAkArAICAg5kdWNrRXF1aXBtZW50XwULZHVja0Fzc2V0SWQBCWtleVVzZXJYUAEEYWRkcgkArAICAgd1c2VyWFBfBQRhZGRyAQxrZXlVc2VyTGV2ZWwBBGFkZHIJAKwCAgIKdXNlckxldmVsXwUEYWRkcgERa2V5VXNlckZyZWVQb2ludHMBBGFkZHIJAKwCAgIPdXNlckZyZWVQb2ludHNfBQRhZGRyAQ5rZXlTYXZlZEhlYWx0aAELZHVja0Fzc2V0SWQJAKwCAgIMc2F2ZWRIZWFsdGhfBQtkdWNrQXNzZXRJZAEQa2V5U2F2ZWRMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgIOc2F2ZWRMb2NhdGlvbl8FC2R1Y2tBc3NldElkAQxrZXlEdWNrQnVmZnMBC2R1Y2tBc3NldElkCQCsAgICCmR1Y2tCdWZmc18FC2R1Y2tBc3NldElkARhrZXlMYXN0Um9iYmVyeVRpbWVCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICEGxhc3RSb2JiZXJ5VGltZV8FC2R1Y2tBc3NldElkARhrZXlMYXN0Um9iYmVyeUNvc3RCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICEGxhc3RSb2JiZXJ5Q29zdF8FC2R1Y2tBc3NldElkARNrZXlMYW5kUm9iYmVyeVN0YXRlAQtsYW5kQXNzZXRJZAkArAICAhFsYW5kUm9iYmVyeVN0YXRlXwULbGFuZEFzc2V0SWQBEmtleUxhbmRDb29sZG93bkVUQQELbGFuZEFzc2V0SWQJAKwCAgIQbGFuZENvb2xkb3duRVRBXwULbGFuZEFzc2V0SWQBE2tleUR1Y2tSb2JiZXJ5U3RhdGUBC2R1Y2tBc3NldElkCQCsAgICEWR1Y2tSb2JiZXJ5U3RhdGVfBQtkdWNrQXNzZXRJZAETa2V5TG9ja2VkTGFuZEJ5RHVjawELZHVja0Fzc2V0SWQJAKwCAgIRbG9ja2VkTGFuZEJ5RHVja18FC2R1Y2tBc3NldElkARZrZXlEZWxpdmVyeURlbGF5QnlEdWNrAQtkdWNrQXNzZXRJZAkArAICAhRkZWxpdmVyeURlbGF5QnlEdWNrXwULZHVja0Fzc2V0SWQAB3hwQ2xhaW0AkE4AD3hwU3VjY2Vzc0ZsaWdodACQTgAMeHBGYWlsRmxpZ2h0ANAPAAh4cENhbGxFUwCgjQYADHhwQ3VzdG9tTmFtZQDAhD0ACnhwTmV3U0xhbmQAwJaxAgAOeHBVcGdyYWRlSW5mcmEAkE4AB3hwTWVyZ2UAwIQ9AAl4cE9uYm9hcmQAwIQ9AAZ4cEhlYWwAkE4BCWxldmVsQnlYUAECeHAJAGsDBQx4cExldmVsU2NhbGUJAGwGBQJ4cAAEBQ94cExldmVsUmVjaXBQb3cABAAEBQRET1dOBQZTQ0FMRTgBCW1heEhlYWx0aAEFbGV2ZWwJAGQCAGQFBWxldmVsAQdsZXZlbFVwAgljdXJyTGV2ZWwFbmV3WFAECG5ld0xldmVsCQEJbGV2ZWxCeVhQAQUFbmV3WFAJAMwIAgUIbmV3TGV2ZWwJAMwIAgkAaAIFEm51bVBvaW50c09uTGV2ZWxVcAkAZQIFCG5ld0xldmVsBQljdXJyTGV2ZWwFA25pbAEMZ2V0RHVja1N0YXRzBA9zdGFraW5nQ29udHJhY3QLZHVja0Fzc2V0SWQKYnVmZkVmZmVjdApmb3JjZUJ1ZmZzBAVjaGFycwkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBDGtleUR1Y2tDaGFycwEFC2R1Y2tBc3NldElkAgkwXzBfMF8wXzACAV8EA2x2bAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QJAQxrZXlEdWNrTGV2ZWwBBQtkdWNrQXNzZXRJZAAABAZoZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkCQEJbWF4SGVhbHRoAQUDbHZsBApzdGF0ZUJ1ZmZzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEMa2V5RHVja0J1ZmZzAQULZHVja0Fzc2V0SWQCCTBfMF8wXzBfMAIBXwkAzggCCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUMY2hhclN0cmVuZ3RoCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUMY2hhckFjY3VyYWN5CQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUNY2hhckludGVsbGVjdAkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDWNoYXJFbmR1cmFuY2UJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQ1jaGFyRGV4dGVyaXR5CQDMCAIFA2x2bAkAzAgCBQZoZWFsdGgFA25pbAMFCmZvcmNlQnVmZnMJAMwIAgUKYnVmZkVmZmVjdAkAzAgCBQpidWZmRWZmZWN0CQDMCAIFCmJ1ZmZFZmZlY3QJAMwIAgUKYnVmZkVmZmVjdAkAzAgCBQpidWZmRWZmZWN0BQNuaWwJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCnN0YXRlQnVmZnMFDGNoYXJTdHJlbmd0aAkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKc3RhdGVCdWZmcwUMY2hhckFjY3VyYWN5CQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpzdGF0ZUJ1ZmZzBQ1jaGFySW50ZWxsZWN0CQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpzdGF0ZUJ1ZmZzBQ1jaGFyRW5kdXJhbmNlCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpzdGF0ZUJ1ZmZzBQ1jaGFyRGV4dGVyaXR5BQNuaWwBDmdldFJvYmJlcnlEYXRhAg9zdGFraW5nQ29udHJhY3QLZHVja0Fzc2V0SWQEC2xhc3RSb2JDb3N0CQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBGGtleUxhc3RSb2JiZXJ5Q29zdEJ5RHVjawEFC2R1Y2tBc3NldElkAAAEC2xhc3RSb2JUaW1lCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBGGtleUxhc3RSb2JiZXJ5VGltZUJ5RHVjawEFC2R1Y2tBc3NldElkAAAEA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEB3JvYkNvc3QJAJYDAQkAzAgCBQ5yb2JiZXJ5Q29zdE1pbgkAzAgCCQBlAgULbGFzdFJvYkNvc3QJAGgCBRRyb2JiZXJ5Q29vbGRvd25Db2VmZgkAZQIFA25vdwULbGFzdFJvYlRpbWUFA25pbAQJZHVja1N0YXRlCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBE2tleUR1Y2tSb2JiZXJ5U3RhdGUBBQtkdWNrQXNzZXRJZAAABApsb2NrZWRMYW5kCQELdmFsdWVPckVsc2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBE2tleUxvY2tlZExhbmRCeUR1Y2sBBQtkdWNrQXNzZXRJZAIABAdsYW5kRVRBCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBEmtleUxhbmRDb29sZG93bkVUQQEFCmxvY2tlZExhbmQAAAkAlwoFBQdyb2JDb3N0BQtsYXN0Um9iVGltZQUJZHVja1N0YXRlBQpsb2NrZWRMYW5kBQdsYW5kRVRBAApMQU5EUFJFRklYAgRMQU5EAApEVUNLUFJFRklYAgREVUNLAApBUlRQUkVTQUxFAgdQUkVTQUxFAAZOVU1SRVMABgAYTUFYX0xBTkRTX1NUQUtFRF9CWV9VU0VSABkAD0RBSUxZUkVTQllQSUVDRQCA+NIBAAxXSE1VTFRJUExJRVIAgMivoCUAD0RFRkFVTFRMT0NBVElPTgIPQWZyaWNhX0ZfQWZyaWNhABBSRVNPVVJDRVBSSUNFTUlOANW1AgAKRVNTRUxMQ09FRgAKABVNSU5fVVNEVF9GRUVfREVMSVZFUlkA0IYDAAlwcm9kVHlwZXMJAMwIAgIQRmlyc3QgQWlkIEtpdCBMMQkAzAgCAhBGaXJzdCBBaWQgS2l0IEwyCQDMCAICEEZpcnN0IEFpZCBLaXQgTDMJAMwIAgILQmFja3BhY2sgTDEJAMwIAgILQmFja3BhY2sgTDIJAMwIAgILQmFja3BhY2sgTDMJAMwIAgIORm9vZCBSYXRpb24gTDEJAMwIAgIORm9vZCBSYXRpb24gTDIJAMwIAgIORm9vZCBSYXRpb24gTDMJAMwIAgILSmV0IFBhY2sgTDEJAMwIAgILSmV0IFBhY2sgTDIJAMwIAgILSmV0IFBhY2sgTDMJAMwIAgIJU2hpZWxkIEwxCQDMCAICCVNoaWVsZCBMMgkAzAgCAglTaGllbGQgTDMJAMwIAgIHTWluZSBMMQkAzAgCAgdNaW5lIEwyCQDMCAICB01pbmUgTDMJAMwIAgIHVHJhcCBMMQkAzAgCAgdUcmFwIEwyCQDMCAICB1RyYXAgTDMFA25pbAAKY29udGluZW50cwkAzAgCAghBbWVyaWNhcwkAzAgCAgZFdXJvcGUJAMwIAgIEQXNpYQkAzAgCAgZBZnJpY2EJAMwIAgIHT2NlYW5pYQUDbmlsAAlDT0VGRjJNQVQAgK3iBAAQZm9ydEFsbG93ZWRQcm9kcwkAzAgCAA8JAMwIAgAQCQDMCAIAEQkAzAgCABIJAMwIAgATCQDMCAIAFAUDbmlsABBwcm9kdWN0aW9uTWF0cml4CQDMCAICJThfOF84XzE3XzE3XzQyXzEyXzBfMzBfMCwwLDAsMCwwLDAsMF8JAMwIAgIlOF84XzhfMTdfMTdfNDJfMjRfMF82MF8wLDAsNSwyLDAsMCwwXwkAzAgCAic4XzhfOF8xN18xN180Ml8zNl8wXzEyMF8wLDAsMTAsNCwwLDAsMF8JAMwIAgIpOF8xOV8xOV84XzI3XzE5XzI2XzFfMjBfMCwwLDAsMCwwLDAsMF8wMDEJAMwIAgIpOF8xOV8xOV84XzI3XzE5XzUyXzFfNDBfMCwwLDAsMCwwLDAsMF8wMDEJAMwIAgIpOF8xOV8xOV84XzI3XzE5Xzc4XzFfODBfMCwwLDAsMCwwLDAsMF8wMDEJAMwIAgIlOF84XzhfOF84XzYwXzEzXzJfMl8wLDAsMCwwLDAsMCwwXzAxMQkAzAgCAiU4XzhfOF84XzhfNjBfMjZfMl80XzAsMCwwLDAsMCwwLDBfMDExCQDMCAICJThfOF84XzhfOF82MF8zOV8yXzhfMCwwLDAsMCwwLDAsMF8wMTEJAMwIAgIpMzBfMzBfM18xN18xN18zXzMwXzNfMzBfMCwwLDAsMCwwLDAsMF8xMTEJAMwIAgIpMzBfMzBfM18xN18xN18zXzYwXzNfNTBfMCwwLDAsMCwwLDAsMF8xMTEJAMwIAgIpMzBfMzBfM18xN18xN18zXzkwXzNfNzBfMCwwLDAsMCwwLDAsMF8xMTEJAMwIAgIrMThfMThfMTBfMThfMThfMThfMTFfNF8xMF8wLDAsMCwwLDAsMCwwXzIwMQkAzAgCAisxOF8xOF8xMF8xOF8xOF8xOF8yMl80XzIwXzAsMCwwLDAsMCwwLDBfMjAxCQDMCAICKzE4XzE4XzEwXzE4XzE4XzE4XzMzXzRfMzBfMCwwLDAsMCwwLDAsMF8yMDEJAMwIAgIqNF8xM18yMl80XzM1XzIyXzIzXzBfNTAsMSwwXzAsMCwwLDAsMCwwLDBfCQDMCAICKjRfMTNfMjJfNF8zNV8yMl80Nl8wXzUwLDEsMV8wLDIsNSwwLDAsMCwwXwkAzAgCAis0XzEzXzIyXzRfMzVfMjJfNjlfMF81MCwyLDFfMCw1LDEwLDAsMCwwLDBfCQDMCAICKjVfMjVfNDBfNV8xMF8xNV8yMF8xXzMwLDEsMV8wLDAsMCwwLDAsMCwwXwkAzAgCAio1XzI1XzQwXzVfMTBfMTVfNDBfMV8zMCwxLDJfMiwxLDMsMCwwLDAsMF8JAMwIAgIqNV8yNV80MF81XzEwXzE1XzYwXzFfMzAsMSwzXzUsMiw4LDAsMCwwLDBfBQNuaWwACXJJZHhDb2VmZgAGAApySWR4RWZmZWN0AAgAEHJJZHhSZXF1aXJlbWVudHMACQAJcklkeFNsb3RzAAoADlBST0RVQ1RQS0dTSVpFAAoAC3doSWR4TGV2ZWxzAAAACHdoSWR4UmVzAAEACHdoSWR4TWF0AAIACXdoSWR4UHJvZAADAAl3aElkeExPRlQABAAJdm9sTG9ja2VkAAAAC3ZvbE9jY3VwaWVkAAEAB3ZvbEZyZWUAAgAIdm9sVG90YWwAAwAKYnBJZHhMZXZlbAAAAAhicElkeFJlcwABAAhicElkeE1hdAACAAlicElkeFByb2QAAwAPbG9jSWR4Q29udGluZW50AAAACmxvY0lkeFR5cGUAAQAIbG9jSWR4SWQAAgEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQdhc3NldElkCQCsAgICA25vXwUHYXNzZXRJZAEaa2V5TGFuZEFzc2V0SWRUb0N1c3RvbU5hbWUBB2Fzc2V0SWQJAKwCAgIFbGNuYV8FB2Fzc2V0SWQBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBB2Fzc2V0SWQJAKwCAgIDc3RfBQdhc3NldElkASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIEdHlwZQdhc3NldElkCQC5CQIJAMwIAgIDbGFzCQDMCAIFBHR5cGUJAMwIAgUHYXNzZXRJZAUDbmlsAgFfASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwduZnRUeXBlB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIGc3R0YW9fBQduZnRUeXBlAgFfBQdhc3NldElkAgFfBQlvd25lckFkZHIBEmtleVdhcmVob3VzZUJ5TGFuZAELbGFuZEFzc2V0SWQJAKwCAgIDd2hfBQtsYW5kQXNzZXRJZAEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEHYXNzZXRJZAkArAICAgtpbmZyYUxldmVsXwUHYXNzZXRJZAEXa2V5Rm9ydGlmaWNhdGlvbnNCeUxhbmQBC2xhbmRBc3NldElkCQCsAgICD2ZvcnRpZmljYXRpb25zXwULbGFuZEFzc2V0SWQBGmtleUR1Y2tBc3NldElkVG9DdXN0b21OYW1lAQdhc3NldElkCQCsAgICGGR1Y2tDdXN0b21OYW1lQnlBc3NldElkXwUHYXNzZXRJZAEWa2V5QWRkcmVzc1RvQ3VzdG9tTmFtZQEEYWRkcgkArAICAhhhY2NvdW50Q3VzdG9tTmFtZUJ5QWRkcl8FBGFkZHIBD2tleUFkZHJlc3NSZWZCeQEEYWRkcgkArAICAglhY2NSZWZCeV8FBGFkZHIBHGtleU9uYm9hcmRBcnRBY3RpdmF0ZWRPbkR1Y2sBC2R1Y2tBc3NldElkCQCsAgICGm9uYm9hcmRBcnRBY3RpdmF0ZWRPbkR1Y2tfBQtkdWNrQXNzZXRJZAEca2V5T25ib2FyZEFydER1Y2tBY3RpdmF0ZWRCeQEEYWRkcgkArAICAhpvbmJvYXJkQXJ0QWN0aXZhdGVkRHVja0J5XwUEYWRkcgETa2V5QWRkcmVzc1JlZmVycmFscwEEYWRkcgkArAICAg1hY2NSZWZlcnJhbHNfBQRhZGRyARBrZXlEdWNrSWRUb093bmVyAQdhc3NldElkCQCsAgICCmR1Y2tPd25lcl8FB2Fzc2V0SWQBFGtleVN0YWtlZER1Y2tCeU93bmVyAQlvd25lckFkZHIJAKwCAgISc3Rha2VkRHVja0J5T3duZXJfBQlvd25lckFkZHIBEWtleUJhY2twYWNrQnlEdWNrAQtkdWNrQXNzZXRJZAkArAICAgliYWNrUGFja18FC2R1Y2tBc3NldElkAQ9rZXlEdWNrTG9jYXRpb24BC2R1Y2tBc3NldElkCQCsAgICDWR1Y2tMb2NhdGlvbl8FC2R1Y2tBc3NldElkARVrZXlVc2VyR3dsUmVsZWFzZVRpbWUBCHVzZXJBZGRyCQCsAgICGiVzJXNfX3VzZXJHd2xSZWxlYXNlVGltZV9fBQh1c2VyQWRkcgEOa2V5RXNXYXJlaG91c2UAAhplbWVyZ2VuY3lXYXJlaG91c2VQcm9kdWN0cwAPZGVsaXZlcnlGdW5kS2V5AgxkZWxpdmVyeUZ1bmQAEWRlbGl2ZXJ5TG9ja2VkS2V5Ag5kZWxpdmVyeUxvY2tlZAANbGFzdFRvdXJJZEtleQIOJXNfX2xhc3RUb3VySWQBFWtleVRvdXJTdGF0aWNEYXRhQnlJZAEDdElkCQCsAgICFiVzJWRfX3RvdXJTdGF0aWNEYXRhX18JAKQDAQUDdElkARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQN0SWQJAKwCAgIXJXMlZF9fdG91ckR5bmFtaWNEYXRhX18JAKQDAQUDdElkARprZXlCZXN0UmVzdWx0QnlUb3VyQW5kRHVjawIDdElkC2R1Y2tBc3NldElkCQC5CQIJAMwIAgIfJXMlZCVzX19iZXN0UmVzdWx0QnlUb3VyQW5kRHVjawkAzAgCCQCkAwEFA3RJZAkAzAgCBQtkdWNrQXNzZXRJZAUDbmlsAgJfXwAJaWR4U3RhdGljAAAACmlkeER5bmFtaWMAAQAKdFN0YXRpY0VuZAAGAA50RHluYW1pY1N0YXR1cwABAQtnZXRUb3VyRGF0YQIMdG91ckNvbnRyYWN0A3RJZAQGc3RhdGljCQC1CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQx0b3VyQ29udHJhY3QJARVrZXlUb3VyU3RhdGljRGF0YUJ5SWQBBQN0SWQJAKwCAgkArAICAhlFcnJvciByZWFkaW5nIHRvdXJuYW1lbnQgCQCkAwEFA3RJZAIFIGRhdGECAl9fBAdkeW5hbWljCQC8CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQx0b3VyQ29udHJhY3QJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUDdElkCQCsAgIJAKwCAgIZRXJyb3IgcmVhZGluZyB0b3VybmFtZW50IAkApAMBBQN0SWQCBSBkYXRhAgJfXwkAzAgCBQZzdGF0aWMJAMwIAgUHZHluYW1pYwUDbmlsAQ5pc0luVG91cm5hbWVudAIMdG91ckNvbnRyYWN0CGxvY2F0aW9uBAZsYXN0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUMdG91ckNvbnRyYWN0BQ1sYXN0VG91cklkS2V5AAAEA2xvYwkAtQkCBQhsb2NhdGlvbgIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFDHRvdXJDb250cmFjdAUGbGFzdElkBAZzdGF0aWMJAJEDAgUFdERhdGEFCWlkeFN0YXRpYwQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwMDAwkAAAIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFUCQAAAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2xvYwUPbG9jSWR4Q29udGluZW50BQZsYXN0SWQHCQAAAgkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwIKSU5QUk9HUkVTUwcJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQNub3cHARJnZXRSZWNpcGVNYXRlcmlhbHMBBnJlY2lwZQkAaAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZyZWNpcGUFCXJJZHhDb2VmZgUJQ09FRkYyTUFUABZLU19TRVBBUkFURV9QVUJMSUNfS0VZBwAYS1NfQUxMT1dfQklHX0lORlJBX01FUkdFBwARS1NfQUxMT1dfREVMSVZFUlkGAAVjaGFpbgkAyQECCQDKAQIIBQR0aGlzBWJ5dGVzAAEAAQALdXNkdEFzc2V0SWQEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDABIITaerIIAz9O0bvKju6Lk7zJgt0LXfoHlqjUI/moD/+5AwkAAAIBAVQFByRtYXRjaDABIFWx2J9yh4Lv5eNbjawFq2XemkOhLxa7BfMat4el8cUYCQACAQINVW5rbm93biBjaGFpbgAVZGVmYXVsdFJlc3RBZGRyZXNzU3RyBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAiMzUFFDdXZGYnZoNExrUFVucm5VMXozam5iQTFwOW0zV05odgMJAAACAQFUBQckbWF0Y2gwAiMzTXVta0dHenRDS0FYcFdEcXhrZGRvZnFYU1VicVFrdlNKeQkAAgECDVVua25vd24gY2hhaW4AEUluZnJhVXBncmFkZUNvc3RTBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAIDIr6AlAwkAAAIBAVQFByRtYXRjaDAAgMLXLwkAAgECDVVua25vd24gY2hhaW4ADmFyYml0cmFnZURlbGF5BAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAIC4mSkDCQAAAgEBVAUHJG1hdGNoMADg1AMJAAIBAg1Vbmtub3duIGNoYWluAANTRVACAl9fAAVNVUxUNgDAhD0ABU1VTFQ4AIDC1y8ABVNTSVpFABkABU1TSVpFAGQABUxTSVpFAOEBAAZYTFNJWkUAkAMAB1hYTFNJWkUA8QQABUlURVI2CQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwBD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAABFJZHhDZmdTdGFraW5nRGFwcAABABFJZHhDZmdFY29ub215RGFwcAACABRJZHhDZmdHb3Zlcm5hbmNlRGFwcAADAA1JZHhDZmdXbGdEYXBwAAQAFElkeENmZ1RvdXJuYW1lbnREYXBwAAcAD0lkeENmZ0FjcmVzRGFwcAAIAQprZXlSZXN0Q2ZnAAIOJXNfX3Jlc3RDb25maWcBDmtleVJlc3RBZGRyZXNzAAIMJXNfX3Jlc3RBZGRyARFyZWFkUmVzdENmZ09yRmFpbAEEcmVzdAkAvAkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUEcmVzdAkBCmtleVJlc3RDZmcABQNTRVABGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIHcmVzdENmZwNpZHgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFB3Jlc3RDZmcFA2lkeAkArAICAipSZXN0IGNmZyBkb2Vzbid0IGNvbnRhaW4gYWRkcmVzcyBhdCBpbmRleCAJAKQDAQUDaWR4AAxyZXN0Q29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBDmtleVJlc3RBZGRyZXNzAAUVZGVmYXVsdFJlc3RBZGRyZXNzU3RyAAdyZXN0Q2ZnCQERcmVhZFJlc3RDZmdPckZhaWwBBQxyZXN0Q29udHJhY3QAD3N0YWtpbmdDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFEUlkeENmZ1N0YWtpbmdEYXBwAA9lY29ub215Q29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBRFJZHhDZmdFY29ub215RGFwcAALZ292Q29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBRRJZHhDZmdHb3Zlcm5hbmNlRGFwcAALd2xnQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBQ1JZHhDZmdXbGdEYXBwABJ0b3VybmFtZW50Q29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBRRJZHhDZmdUb3VybmFtZW50RGFwcAANYWNyZXNDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFD0lkeENmZ0FjcmVzRGFwcAAKcmVjTGFuZE51bQAAAAtyZWNMYW5kU2l6ZQABAAtyZWNUZXJyYWlucwACAAxyZWNDb250aW5lbnQAAwANd2xnQXNzZXRJZEtleQILd2xnX2Fzc2V0SWQACndsZ0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQt3bGdDb250cmFjdAUNd2xnQXNzZXRJZEtleQIYV0xHT0xEIGlzIG5vdCBpc3N1ZWQgeWV0AA9hY3Jlc0Fzc2V0SWRLZXkCDGFjcmVzQXNzZXRJZAAMYWNyZXNBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJwIAgUNYWNyZXNDb250cmFjdAUPYWNyZXNBc3NldElkS2V5AhdBQ1JFUyBpcyBub3QgaXNzdWVkIHlldAALcmFuZG9tRGVsYXkAAgEJa2V5Q29tbWl0AQdhZGRyZXNzCQCsAgICE2ZpbmlzaEJsb2NrRm9yQWRkcl8FB2FkZHJlc3MBEWtleVJlc1Byb3BvcnRpb25zAAITcmVzVHlwZXNQcm9wb3J0aW9ucwEWa2V5UmVzVHlwZXNCeUNvbnRpbmVudAEJY29udGluZW50CQCsAgICFHJlc1R5cGVzQnlDb250aW5lbnRfBQljb250aW5lbnQBFWtleVN0YWtlZExhbmRzQnlPd25lcgEJb3duZXJBZGRyCQCsAgICE3N0YWtlZExhbmRzQnlPd25lcl8FCW93bmVyQWRkcgEWa2V5U3Rha2VkUGllY2VzQnlPd25lcgEJb3duZXJBZGRyCQCsAgICFHN0YWtlZFBpZWNlc0J5T3duZXJfBQlvd25lckFkZHIBCGFzU3RyaW5nAQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAUBcwkAAgECGGZhaWwgdG8gY2FzdCBpbnRvIFN0cmluZwEFYXNJbnQBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIDSW50BAFuBQckbWF0Y2gwBQFuCQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AQlhc0Jvb2xlYW4BAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIHQm9vbGVhbgQBcwUHJG1hdGNoMAUBcwkAAgECGWZhaWwgdG8gY2FzdCBpbnRvIEJvb2xlYW4BD251bVBpZWNlc0J5U2l6ZQEIbGFuZFNpemUEByRtYXRjaDAFCGxhbmRTaXplAwkAAAICAVMFByRtYXRjaDAFBVNTSVpFAwkAAAICAU0FByRtYXRjaDAFBU1TSVpFAwkAAAICAUwFByRtYXRjaDAFBUxTSVpFAwkAAAICAlhMBQckbWF0Y2gwBQZYTFNJWkUDCQAAAgIDWFhMBQckbWF0Y2gwBQdYWExTSVpFCQACAQIRVW5rbm93biBsYW5kIHNpemUBB2lzRGlnaXQBAXMJAQlpc0RlZmluZWQBCQC2CQEFAXMBCmtleUJsb2NrZWQAAhBjb250cmFjdHNCbG9ja2VkARFrZXlMYXN0VHhJZEJ5VXNlcgEEYWRkcgkArAICAg9sYXN0VHhJZEJ5VXNlcl8FBGFkZHIBCmZpeGVkUG9pbnQCA3ZhbAhkZWNpbWFscwQGdGVuUG93CQBsBgAKAAAFCGRlY2ltYWxzAAAAAAUERE9XTgQHbG93UGFydAkApAMBCQBqAgUDdmFsBQZ0ZW5Qb3cEBnplcm9lcwkAsAICCQCkAwEFBnRlblBvdwkAZAIAAQkAsQIBBQdsb3dQYXJ0CQCsAgIJAKwCAgkArAICCQCkAwEJAGkCBQN2YWwFBnRlblBvdwIBLgUGemVyb2VzBQdsb3dQYXJ0AQ9nZXRSYW5kb21OdW1iZXIDCG1heFZhbHVlDGZpbmlzaEhlaWdodAphdXhFbnRyb3B5BA9yYW5kb21TZWVkQmxvY2sJAQV2YWx1ZQEJAO0HAQUMZmluaXNoSGVpZ2h0BApyYW5kb21IYXNoCQD3AwEJAMsBAgkBBXZhbHVlAQgFD3JhbmRvbVNlZWRCbG9jawN2cmYFCmF1eEVudHJvcHkJAGoCCQCxCQEFCnJhbmRvbUhhc2gFCG1heFZhbHVlAA1pbmN1YmF0b3JBZGRyBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwCQERQGV4dHJOYXRpdmUoMTA2MikBAiMzUEVrdFZ1eDJSaGNoU042M0RzRG80YjRtejRRcXpLU2VEdgMJAAACAQFUBQckbWF0Y2gwBQR0aGlzCQACAQINVW5rbm93biBjaGFpbgALYnJlZWRlckFkZHIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQRFZ1VTQ1SDdFaDVkbXROYm5STlJTdEd3VUxBN05ZNkhiAwkAAAIBAVQFByRtYXRjaDAFBHRoaXMJAAIBAg1Vbmtub3duIGNoYWluAANwdWIEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDADBRZLU19TRVBBUkFURV9QVUJMSUNfS0VZASCrF1ePFWfjWVRBsNZy62abxKPTZl7VmYZQ35g3H7IJCAEgT1PiGj9UqNadUk4THUYnVb2zU/Mse8lUVLD/Q8G0FCgDCQAAAgEBVAUHJG1hdGNoMAEgT1PiGj9UqNadUk4THUYnVb2zU/Mse8lUVLD/Q8G0FCgJAAIBAg1Vbmtub3duIGNoYWluAAxFTVBUWV9QUk9ENTABkAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFGSVZFTUlOVVRFU01JTExJUwDgpxIAElRFTl9NSU5VVEVTX01JTExJUwDAzyQADFJFTkFNSU5HQ09TVADAlrECAApNQVhOQU1FTEVOADIAFUluZnJhVXBncmFkZUNvc3RTVXNkdACAreIEAAxFWFBNQVRFUklBTFMEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAApt2C7asHAwkAAAIBAVQFByRtYXRjaDAAqqeBswkJAAIBAg1Vbmtub3duIGNoYWluAAdFWFBVU0RUBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAIDlmncDCQAAAgEBVAUHJG1hdGNoMACA5Zp3CQACAQINVW5rbm93biBjaGFpbgAMU19DT1NUX0FDUkVTAIDyi6gJAAVGSVZFWAkAtgIBAAUAB1RXRU5UWVgJALYCAQAUAAhUV0VOVFkyWAkAtgIBCQBoAgAUABQACFRXRU5UWTNYCQC2AgEJAGgCCQBoAgAUABQAFAAIVFdFTlRZNFgJALYCAQkAaAIJAGgCCQBoAgAUABQAFAAUAAhUV0VOVFk1WAkAtgIBCQBoAgkAaAIJAGgCCQBoAgAUABQAFAAUABQAD1BSRVNBTEVOVU1MQU5EUwD0AwESa2V5TmV4dEZyZWVMYW5kTnVtAAILbmV4dExhbmROdW0BGmtleUxhbmRDdXN0b21OYW1lVG9Bc3NldElkAQRuYW1lCQCsAgICBGxjbl8FBG5hbWUBEGtleUxhbmRUb0Fzc2V0SWQBB2xhbmROdW0JAKwCAgIDbGFfBQdsYW5kTnVtAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICAgVpbGFvXwUHYXNzZXRJZAIBXwUJb3duZXJBZGRyARFrZXlMYW5kTnVtVG9Pd25lcgEHbGFuZE51bQkArAICAgNsb18FB2xhbmROdW0BGmtleUR1Y2tDdXN0b21OYW1lVG9Bc3NldElkAQRuYW1lCQCsAgICEWR1Y2tCeUN1c3RvbU5hbWVfBQRuYW1lARZrZXlDdXN0b21OYW1lVG9BZGRyZXNzAQRuYW1lCQCsAgICFGFjY291bnRCeUN1c3RvbU5hbWVfBQRuYW1lAQlrZXlPbGRpZXMAAgpvbGRpZXNMaXN0AAtjbGFpbU1vZGVXaAAAAA1jbGFpbU1vZGVEdWNrAAEAE2NsYWltTW9kZVdoVGhlbkR1Y2sAAgAIZmxIZWFsdGgAAAALZmxUaW1lc3RhbXAABQAHZmxCb251cwAGAAtmbFByb2RzVXNlZAAHAQduZnROYW1lAgdsYW5kTnVtCGxhbmRTaXplCQCsAgIJAKwCAgUKTEFORFBSRUZJWAUHbGFuZE51bQUIbGFuZFNpemUBCHRvVm9sdW1lAgZhbW91bnQHcGtnU2l6ZQQEcGtncwMJAGcCBQZhbW91bnQAAAkAaQIJAGUCCQBkAgUGYW1vdW50BQdwa2dTaXplAAEFB3BrZ1NpemUJAQEtAQkAaQIJAGUCCQBkAgkBAS0BBQZhbW91bnQFB3BrZ1NpemUAAQUHcGtnU2l6ZQkAaAIFBHBrZ3MFBU1VTFQ4ARNkaXN0cmlidXRlQnlXZWlnaHRzAgV0b3RhbAd3ZWlnaHRzBANzdW0JAGQCCQBkAgkAZAIJAGQCCQBkAgkAkQMCBQd3ZWlnaHRzAAAJAJEDAgUHd2VpZ2h0cwABCQCRAwIFB3dlaWdodHMAAgkAkQMCBQd3ZWlnaHRzAAMJAJEDAgUHd2VpZ2h0cwAECQCRAwIFB3dlaWdodHMABQMJAGcCAAAFA3N1bQkAAgECEFplcm8gd2VpZ2h0cyBzdW0EBW5vcm02CQBrAwUFdG90YWwFBU1VTFQ2BQNzdW0KAQpub3JtYWxpemVyAgNhY2MEZWxlbQkAzQgCBQNhY2MJAGsDBQRlbGVtBQVub3JtNgUFTVVMVDYKAAIkbAUHd2VpZ2h0cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEKbm9ybWFsaXplcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgESZ2V0TmVlZGVkTWF0ZXJpYWxzAQV0b3RhbAQFcHJvcHMJALUJAgkBBXZhbHVlAQkAoggBCQERa2V5UmVzUHJvcG9ydGlvbnMAAgFfAwkBAiE9AgkAkAMBBQVwcm9wcwUGTlVNUkVTCQACAQIWV3JvbmcgcHJvcG9ydGlvbnMgZGF0YQQBcgkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMAAAkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMAAQkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMAAgkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMAAwkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMABAkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMABQUDbmlsCQETZGlzdHJpYnV0ZUJ5V2VpZ2h0cwIFBXRvdGFsBQFyARFzdWJ0cmFjdE1hdGVyaWFscwMMc2hvdWxkVXNlTWF0A2hhcwl0b3RhbE5lZWQEBG5lZWQJARJnZXROZWVkZWRNYXRlcmlhbHMBBQl0b3RhbE5lZWQKAQpzdWJ0cmFjdG9yAgNhY2MDaWR4BAZyZXN1bHQJAGUCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDaGFzBQNpZHgJAJEDAgUEbmVlZAUDaWR4AwkAZgIAAAUGcmVzdWx0CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICGE5vdCBlbm91Z2ggbWF0ZXJpYWwgaWR4PQkApAMBBQNpZHgCCywgeW91IGhhdmUgCQCRAwIFA2hhcwUDaWR4AgssIGJ1dCBuZWVkIAkApAMBCQCRAwIFBG5lZWQFA2lkeAkAzQgCBQNhY2MJAKQDAQUGcmVzdWx0AwUMc2hvdWxkVXNlTWF0CgACJGwFBUlURVI2CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpzdWJ0cmFjdG9yAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGBQNoYXMBEXN1YnRyYWN0RXF1aXBtZW50AgVvbGRFcQVwVXNlZAMJAAACBQVwVXNlZAIACQCUCgIFBW9sZEVxBwoBB3N1YlVzZWQCA2FjYwZpZHhBbXQEBXBhcnRzCQC1CQIFBmlkeEFtdAIBLAMJAQIhPQIJAJADAQUFcGFydHMAAgkAAgECKEluY29ycmVjdCBmb3JtYXQsIHNob3VsZCBiZSBpbmRleCxhbW91bnQEA2lkeAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXBhcnRzAAADAwkAZgIAAAUDaWR4BgkAZwIFA2lkeAkAkAMBBRBwcm9kdWN0aW9uTWF0cml4CQACAQITVW5rbm93biBwcm9kdWN0IGlkeAQDYW10CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAQQHZXFQYXJ0cwkAtQkCCAUDYWNjAl8xCQCsAgIJAJEDAgUFcGFydHMAAAIBOgMJAQIhPQIJAJADAQUHZXFQYXJ0cwACCQACAQkArAICCQCsAgICD1lvdSBkb24ndCBoYXZlIAkAkQMCBQlwcm9kVHlwZXMFA2lkeAIJIGVxdWlwcGVkBAN0bXAJAJEDAgUHZXFQYXJ0cwABBAZudW1MZW4DCQEHaXNEaWdpdAEJAK8CAgkAsAICBQN0bXAAAQABAAIAAQQEY3VycgkBDXBhcnNlSW50VmFsdWUBCQCvAgIFA3RtcAUGbnVtTGVuBAR0YWlsCQCwAgIFA3RtcAUGbnVtTGVuBAZuZXdBbXQDCQBnAgUEY3VycgUDYW10CQBlAgUEY3VycgUDYW10CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICDVlvdSBlcXVpcHBlZCAJAKQDAQUEY3VycgIEIG9mIAkAkQMCBQlwcm9kVHlwZXMFA2lkeAITLCBidXQgdHJpZWQgdG8gdXNlIAkApAMBBQNhbXQJAJQKAgkArAICCQCsAgIJAKwCAgkArAICCQCRAwIFB2VxUGFydHMAAAkAkQMCBQVwYXJ0cwAAAgE6CQCkAwEFBm5ld0FtdAUEdGFpbAMIBQNhY2MCXzIGAwMJAGcCBQNpZHgABgkAZwIACAUDaWR4BwkAAAIFBm5ld0FtdAAABwoAAiRsCQC1CQIFBXBVc2VkAgFfCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQVvbGRFcQcKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB3N1YlVzZWQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBl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DXBhcnNlSW50VmFsdWUBCQCRAwIFBXBhcnRzAAAEBWNvdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAQMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIFEGZvcnRBbGxvd2VkUHJvZHMFCnByb2R1Y3RJZHgJAAIBCQCsAgIJAKwCAgIJUHJvZHVjdCAnCQCRAwIFCXByb2RUeXBlcwUKcHJvZHVjdElkeAIhJyBjYW5ub3QgYmUgdXNlZCBmb3IgbGFuZCBkZWZlbnNlAwkAZgIAAAUFY291bnQJAAIBAhdDb3VudCBjYW4ndCBiZSBuZWdhdGl2ZQMJAGYCBQVjb3VudAUNTUFYUFJPRElOU0xPVAkAAgEJAKwCAgkArAICCQCsAgICFENhbid0IHB1dCBtb3JlIHRoYW4gCQCkAwEFDU1BWFBST0RJTlNMT1QCBCBvZiAJAJEDAgUJcHJvZFR5cGVzBQpwcm9kdWN0SWR4AwkAAAIFBWNvdW50AAAJAJUKAwUFcExpc3QFCG9jY3VwaWVkBQRmcmVlBARoZWFkCQDJAQIFBXBMaXN0CQBoAgAIBQpwcm9kdWN0SWR4BARjdXJyCQCxCQEJAMkBAgkAygECBQVwTGlzdAkAaAIACAUKcHJvZHVjdElkeAAIBAR0YWlsCQDKAQIFBXBMaXN0CQBoAgAICQBkAgUKcHJvZHVjdElkeAABBAZyZWNpcGUJALUJAgkAkQMCBRBwcm9kdWN0aW9uTWF0cml4BQpwcm9kdWN0SWR4AgFfAwMJAQEhAQUKaXNQb3NpdGl2ZQkAZgIFBWNvdW50BQRjdXJyBwkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAglZb3UgaGF2ZSAJAKQDAQUEY3VycgIEIG9mIAkAkQMCBQlwcm9kVHlwZXMFCnByb2R1Y3RJZHgCEywgYnV0IHRyaWVkIHRvIHVzZSAJAKQDAQUFY291bnQEBm5ld0FtdAMDCQEBIQEFCmlzUG9zaXRpdmUJARVjaGVja1N0YXRSZXF1aXJlbWVudHMCBQlkdWNrU3RhdHMJALUJAgkAkQMCBQZyZWNpcGUFEHJJZHhSZXF1aXJlbWVudHMCASwHCQBlAgUEY3VycgUFY291bnQJAGQCBQRjdXJyBQVjb3VudAQIZGVsdGFWb2wJAGUCCQEIdG9Wb2x1bWUCBQZuZXdBbXQFDlBST0RVQ1RQS0dTSVpFCQEIdG9Wb2x1bWUCBQRjdXJyBQ5QUk9EVUNUUEtHU0laRQkAlQoDCQDLAQIJAMsBAgUEaGVhZAkAmgMBBQZuZXdBbXQFBHRhaWwJAGQCBQhvY2N1cGllZAUIZGVsdGFWb2wJAGUCBQRmcmVlBQhkZWx0YVZvbAEIYWRkUHJvZEIHBmlkeENudAVwTGlzdAppc1Bvc2l0aXZlB3NlZ21lbnQHbWFpbkF1eARzbG90CWR1Y2tTdGF0cwQFcGFydHMJALUJAgUGaWR4Q250AgE6AwkBAiE9AgkAkAMBBQVwYXJ0cwACCQACAQIoSW5jb3JyZWN0IGZvcm1hdCwgc2hvdWxkIGJlIGluZGV4OmFtb3VudAMDCQEBIQEFCmlzUG9zaXRpdmUJAQIhPQIJALECAQkAkQMCBQVwYXJ0cwAAAAIHCQACAQIrUHJvZHVjdCBpZHggc2hvdWxkIGJlIDIgZGlnaXRzLCB6ZXJvIHBhZGRlZAQKcHJvZHVjdElkeAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXBhcnRzAAAEBWNvdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAQMDCQBmAgAABQpwcm9kdWN0SWR4BgkAZwIFCnByb2R1Y3RJZHgJAJADAQUQcHJvZHVjdGlvbk1hdHJpeAkAAgECE1Vua25vd24gcHJvZHVjdCBpZHgDCQBmAgAABQVjb3VudAkAAgECF0NvdW50IGNhbid0IGJlIG5lZ2F0aXZlAwkAZgIFBWNvdW50BQ1NQVhQUk9ESU5TTE9UCQACAQkArAICCQCsAgIJAKwCAgIUQ2FuJ3QgcHV0IG1vcmUgdGhhbiAJAKQDAQUNTUFYUFJPRElOU0xPVAIEIG9mIAkAkQMCBQlwcm9kVHlwZXMFCnByb2R1Y3RJZHgDCQAAAgUFY291bnQAAAkAlAoCBQVwTGlzdAcEBGhlYWQJAMkBAgUFcExpc3QJAGgCAAgFCnByb2R1Y3RJZHgEBGN1cnIJALEJAQkAyQECCQDKAQIFBXBMaXN0CQBoAgAIBQpwcm9kdWN0SWR4AAgEBHRhaWwJAMoBAgUFcExpc3QJAGgCAAgJAGQCBQpwcm9kdWN0SWR4AAEEBnJlY2lwZQkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgFCnByb2R1Y3RJZHgCAV8DAwkBASEBBQppc1Bvc2l0aXZlCQBmAgUFY291bnQFBGN1cnIHCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCVlvdSBoYXZlIAkApAMBBQRjdXJyAgQgb2YgCQCRAwIFCXByb2RUeXBlcwUKcHJvZHVjdElkeAITLCBidXQgdHJpZWQgdG8gdXNlIAkApAMBBQVjb3VudAQJaXNCaWdJdGVtAwMJAQEhAQUKaXNQb3NpdGl2ZQkBFWNoZWNrU3RhdFJlcXVpcmVtZW50cwIFCWR1Y2tTdGF0cwkAtQkCCQCRAwIFBnJlY2lwZQUQcklkeFJlcXVpcmVtZW50cwIBLAcEBmNvbXBhdAkAkQMCBQZyZWNpcGUFCXJJZHhTbG90cwMJAAACBQZjb21wYXQCAAkAAgECF0l0ZW0gY2Fubm90IGJlIGVxdWlwcGVkBAFjCQENcGFyc2VJbnRWYWx1ZQEFBmNvbXBhdAQEY1NlZwkAaQIFAWMAZAMJAQIhPQIFB3NlZ21lbnQFBGNTZWcJAAIBAhRTZWdtZW50IGluY29tcGF0aWJsZQQIY01haW5BdXgJAGkCCQBqAgUBYwBkAAoDCQECIT0CBQdtYWluQXV4BQhjTWFpbkF1eAkAAgECEVNsb3QgaW5jb21wYXRpYmxlBAljTnVtU2xvdHMJAGoCBQFjAAoDAwkBAiE9AgUEc2xvdAAACQBmAgUJY051bVNsb3RzAAEHCQACAQIeQmlnIGl0ZW1zIHNob3VsZCBvY2N1cHkgc2xvdCAwCQBmAgUJY051bVNsb3RzAAEHCQCUCgIJAMsBAgkAywECBQRoZWFkCQCaAwEJAGQCBQRjdXJyAwUKaXNQb3NpdGl2ZQUFY291bnQJAQEtAQUFY291bnQFBHRhaWwFCWlzQmlnSXRlbQELc2xvdHNHcm91cEIGAWcEYnBJbgppc1Bvc2l0aXZlB3NlZ21lbnQHbWFpbkF1eAVzdGF0cwMJAQIhPQIFAWcCAAQFc2xvdHMJALUJAgUBZwIBLAMJAGYCCQCQAwEFBXNsb3RzBQhNQVhTTE9UUwkAAgECEldyb25nIHNsb3RzIGZvcm1hdAQCczAJAJEDAgUFc2xvdHMAAAQCczEDCQBmAgkA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cQULc2VnQmFja3BhY2sCATsAAQQKYnVmZkVmZmVjdAMJAAACBQhzZWdCcEF1eAIAAAAEBGF1eDAJAJEDAgkAtQkCBQhzZWdCcEF1eAIBLAAAAwkAAAIFBGF1eDACAAAABAZpZHhDbnQJALUJAgUEYXV4MAIBOgQDaWR4CQCRAwIFBmlkeENudAAABANjbnQJAJEDAgUGaWR4Q250AAEDAwMDAwkAAAIFA2lkeAICMDYGCQAAAgUDaWR4AgIwNwYJAAACBQNpZHgCAjA4CQECIT0CBQNjbnQCAAcJAGYCCQENcGFyc2VJbnRWYWx1ZQEFA2NudAAABwkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgkAkQMCBRBwcm9kdWN0aW9uTWF0cml4CQENcGFyc2VJbnRWYWx1ZQEFA2lkeAIBXwUKcklkeEVmZmVjdAAABAVzdGF0cwkBDGdldER1Y2tTdGF0cwQFBHRoaXMFC2R1Y2tBc3NldElkBQpidWZmRWZmZWN0BgQIbmV3UHJvZEIJAQZkcmVzc0IEBQZjdXJyRXEFCXRlbXBQcm9kQgcFBXN0YXRzCQAAAgUIbmV3UHJvZEIFCG5ld1Byb2RCARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAhwcm9wTGlzdA10ZXJyYWluQ291bnRzDWxhbmRTaXplSW5kZXgEc2lnbgMJAQIhPQIJAJADAQUIcHJvcExpc3QFBk5VTVJFUwkAAgECFldyb25nIHByb3BvcnRpb25zIGRhdGEKAQd1cGRhdGVyAgNhY2MBaQQGcmVzdWx0CQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHByb3BMaXN0BQFpCQBoAgkAaAIFBHNpZ24JAJEDAgUNdGVycmFpbkNvdW50cwUBaQUNbGFuZFNpemVJbmRleAMJAGYCAAAFBnJlc3VsdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIWUGFuaWMhIFBpZWNlcyBvZiB0eXBlPQkApAMBBQFpAgcsIHNpZ249CQCkAwEFBHNpZ24CEywgdGVycmFpbkNvdW50c1tpXT0JAKQDAQkAkQMCBQ10ZXJyYWluQ291bnRzBQFpAhAsIGxhbmRTaXplSW5kZXg9CQCkAwEFDWxhbmRTaXplSW5kZXgJAM0IAgUDYWNjCQCkAwEFBnJlc3VsdAoAAiRsBQVJVEVSNgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHdXBkYXRlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgERdXBkYXRlUHJvcG9ydGlvbnMDDXRlcnJhaW5Db3VudHMNbGFuZFNpemVJbmRleARzaWduBAhwcm9wTGlzdAkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACCzBfMF8wXzBfMF8wAgFfCQC5CQIJARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAUIcHJvcExpc3QFDXRlcnJhaW5Db3VudHMFDWxhbmRTaXplSW5kZXgFBHNpZ24CAV8BDWNvdW50VGVycmFpbnMBCHRlcnJhaW5zCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUEAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFCAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBQwABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUQAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFFAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBRgABBQNuaWwBBmFkZFJlcwUKY3VycmVudFJlcw10ZXJyYWluQ291bnRzCWRlbHRhVGltZQ1sYW5kU2l6ZUluZGV4F2RhaWx5QnlQaWVjZVdpdGhCb251c2VzCgEFYWRkZXICA2FjYwFpBAlyZXNPZlR5cGUJAGgCCQBoAgkAawMFCWRlbHRhVGltZQUXZGFpbHlCeVBpZWNlV2l0aEJvbnVzZXMFCURBWU1JTExJUwkAkQMCBQ10ZXJyYWluQ291bnRzBQFpBQ1sYW5kU2l6ZUluZGV4CQDNCAIFA2FjYwkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCmN1cnJlbnRSZXMFAWkFCXJlc09mVHlwZQQBcgoAAiRsBQVJVEVSNgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEFYWRkZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJALkJAgUBcgIBXwEJdmlydENsYWltBA10ZXJyYWluQ291bnRzCWRlbHRhVGltZQ1sYW5kU2l6ZUluZGV4F2RhaWx5QnlQaWVjZVdpdGhCb251c2VzCgEFYWRkZXICA2FjYwFpBAlyZXNPZlR5cGUJAGgCCQBoAgkAawMFCWRlbHRhVGltZQUXZGFpbHlCeVBpZWNlV2l0aEJvbnVzZXMFCURBWU1JTExJUwkAkQMCBQ10ZXJyYWluQ291bnRzBQFpBQ1sYW5kU2l6ZUluZGV4CQCUCgIJAM0IAggFA2FjYwJfMQUJcmVzT2ZUeXBlCQBkAggFA2FjYwJfMgUJcmVzT2ZUeXBlCgACJGwFBUlURVI2CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEFYWRkZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYBDWRpc3RyaWJ1dGVSZXMEDGN1cnJlbnRXaFJlcw5jdXJyZW50UGFja1JlcwpyZXNUb0NsYWltC3doU3BhY2VMZWZ0BA5yZXNMaXN0VG9DbGFpbQgFCnJlc1RvQ2xhaW0CXzEEDHJlc0FtVG9DbGFpbQgFCnJlc1RvQ2xhaW0CXzIDCQAAAgUMcmVzQW1Ub0NsYWltAAAJAJQKAgkAuQkCBQxjdXJyZW50V2hSZXMCAV8JALkJAgUOY3VycmVudFBhY2tSZXMCAV8DCQBnAgULd2hTcGFjZUxlZnQFDHJlc0FtVG9DbGFpbQoBCGFkZExpc3RzAgNhY2MBaQkAzQgCBQNhY2MJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQxjdXJyZW50V2hSZXMFAWkJAJEDAgUOcmVzTGlzdFRvQ2xhaW0FAWkEAXIKAAIkbAUFSVRFUjYKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGFkZExpc3RzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGCQCUCgIJALkJAgUBcgIBXwkAuQkCBQ5jdXJyZW50UGFja1JlcwIBXwoBDGFkZFBhcnRMaXN0cwIDYWNjAWkEBndoUGFydAkAawMJAJEDAgUOcmVzTGlzdFRvQ2xhaW0FAWkFC3doU3BhY2VMZWZ0BQxyZXNBbVRvQ2xhaW0JAJQKAgkAzQgCCAUDYWNjAl8xCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUMY3VycmVudFdoUmVzBQFpBQZ3aFBhcnQJAM0IAggFA2FjYwJfMgkApAMBCQBlAgkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5jdXJyZW50UGFja1JlcwUBaQkAkQMCBQ5yZXNMaXN0VG9DbGFpbQUBaQUGd2hQYXJ0BAFyCgACJGwFBUlURVI2CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEMYWRkUGFydExpc3Rz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dGFsBQh3aExvY2tlZAUDb2NjCQDMCAIJAKQDAQUHd2hUb3RhbAUDbmlsAgFfCQDMCAIJAJEDAgUCd2gFC3doSWR4TGV2ZWxzCQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUCd2gFCHdoSWR4UmVzAgFfBQZOVU1SRVMJAJEDAgUCd2gFCHdoSWR4UmVzAgswXzBfMF8wXzBfMAkAzAgCAwkAAAIJAJADAQkAtQkCCQCRAwIFAndoBQh3aElkeE1hdAIBXwUGTlVNUkVTCQCRAwIFAndoBQh3aElkeE1hdAILMF8wXzBfMF8wXzAJAMwIAgkAkQMCBQJ3aAUJd2hJZHhQcm9kCQDMCAIFBndoTG9mdAUDbmlsARVnZXRXYXJlaG91c2VTcGFjZUxlZnQBCWN1cnJlbnRXaAQLb2NjdXBpZWRWb2wJARdnZXRXYXJlaG91c2VPY2N1cGllZFZvbAEFCWN1cnJlbnRXaAQPY3VycldoTG9ja2VkVm9sCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhMT0ZUAgFfBQl2b2xMb2NrZWQJAGUCCQBlAgkBF2dldFdhcmVob3VzZVRvdGFsVm9sdW1lAQkAkQMCBQljdXJyZW50V2gFC3doSWR4TGV2ZWxzBQtvY2N1cGllZFZvbAUPY3VycldoTG9ja2VkVm9sAQltb3ZlU3R1ZmYDCmNhcmdvUGFydHMJY3VycmVudFdoC2N1cnJlbnRQYWNrAwkBAiE9AgkAkAMBBQpjYXJnb1BhcnRzAAMJAAIBAjRjYXJnb0xpc3RTdHIgc2hvdWxkIGNvbnRhaW4gZXhhY3RseSAyICc6JyBzZXBhcmF0b3JzBAhyZXNQYXJ0cwkAtQkCCQCRAwIFCmNhcmdvUGFydHMAAAIBXwQIbWF0UGFydHMJALUJAgkAkQMCBQpjYXJnb1BhcnRzAAECAV8ECXByb2RQYXJ0cwMJAAACCQCRAwIFCmNhcmdvUGFydHMAAgIABQNuaWwJALwJAgkAkQMCBQpjYXJnb1BhcnRzAAICAV8DCQECIT0CCQCQAwEFCHJlc1BhcnRzBQZOVU1SRVMJAAIBAiBBbGwgNiByZXNvdXJjZXMgc2hvdWxkIGJlIHBhc3NlZAMJAQIhPQIJAJADAQUIbWF0UGFydHMFBk5VTVJFUwkAAgECIEFsbCA2IG1hdGVyaWFscyBzaG91bGQgYmUgcGFzc2VkBAt3aFNwYWNlTGVmdAkBFWdldFdhcmVob3VzZVNwYWNlTGVmdAEFCWN1cnJlbnRXaAQJY3VycldoUmVzCQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeFJlcwIBXwQJY3VycldoTWF0CQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeE1hdAIBXwQKY3VycldoUHJvZAMJAAACCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFCWN1cnJlbnRXaAUJd2hJZHhQcm9kAgFfBA5jdXJyZW50UGFja1JlcwkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQOY3VycmVudFBhY2tNYXQJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8ED2N1cnJlbnRQYWNrUHJvZAMJAAACCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIBXwoBA212UgIDYWNjBGl0ZW0EAWkIBQNhY2MCXzEEAmFtCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0EA3docgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWN1cnJXaFJlcwUBaQQDYnByCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOY3VycmVudFBhY2tSZXMFAWkDCQAAAgUCYW0AAAkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAJEDAgUJY3VycldoUmVzBQFpCQDNCAIIBQNhY2MCXzMJAJEDAgUOY3VycmVudFBhY2tSZXMFAWkIBQNhY2MCXzQDCQBmAgUCYW0AAAMJAGYCBQJhbQUDYnByCQACAQkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHRha2UgBQRpdGVtAhkgZnJvbSBiYWNrcGFjaywgYnV0IG9ubHkgCQCkAwEFA2JwcgIKIGF2YWlsYWJsZQkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZAIFA3docgUCYW0JAM0IAggFA2Fj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QUxFTlVNTEFORFMAAQQHbGFuZE51bQkApAMBBQdmcmVlTnVtBAxjb250aW5lbnRJZHgJAKADAQkAuwICBQZiaWdOdW0FBUZJVkVYBAh0ZXJyYWlucwkBC2dlblRlcnJhaW5zAgUGYmlnTnVtBQxjb250aW5lbnRJZHgECWNvbnRpbmVudAkAkQMCBQpjb250aW5lbnRzBQxjb250aW5lbnRJZHgEBWlzc3VlCQDCCAUJAQduZnROYW1lAgUHbGFuZE51bQIBUwkAuQkCCQDMCAIFB2xhbmROdW0JAMwIAgIBUwkAzAgCBQh0ZXJyYWlucwkAzAgCBQljb250aW5lbnQFA25pbAIBXwABAAAHBAdhc3NldElkCQC4CAEFBWlzc3VlBAJpZAkA2AQBBQdhc3NldElkCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJARJrZXlOZXh0RnJlZUxhbmROdW0ACQBkAgUHZnJlZU51bQABCQDMCAIFBWlzc3VlCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBrZXlMYW5kVG9Bc3NldElkAQUHbGFuZE51bQUCaWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFAmlkBQh1c2VyQWRkcgkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5TGFuZE51bVRvT3duZXIBBQdsYW5kTnVtBQh1c2VyQWRkcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQJpZAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAgUCaWQFCHVzZXJBZGRyAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyAAEFB2Fzc2V0SWQFA25pbAkAlAoCBQJpZAUJY29udGluZW50AQxmbGlnaHRDb21tb24DCHVzZXJBZGRyB21lc3NhZ2UDc2lnAwkBASEBCQDEEwMFB21lc3NhZ2UFA3NpZwUDcHViCQACAQIYc2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoBAVwYXJ0cwkAvAkCCQCwCQEFB21lc3NhZ2UCATsECWZsaWdodExvZwkAvAkCCQCRAwIFBXBhcnRzAAACAXwEAmhwCQC1CQIJAJEDAgUJZmxpZ2h0TG9nBQhmbEhlYWx0aAIBXwQFY3VySFAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJocAAABAVuZXdIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAEEC25ld0xvY1R4VmVyCQC1CQIJAJEDAgUFcGFydHMAAQIBOgQLbmV3TG9jYXRpb24JAJEDAgULbmV3TG9jVHhWZXIAAAQEdGltZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWZsaWdodExvZwULZmxUaW1lc3RhbXADAwkAZgIFBHRpbWUJAGQCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAURRklWRU1JTlVURVNNSUxMSVMGCQBmAgkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwUEdGltZQkAAgEJAKwCAgkArAICCQCsAgICHHNpZ25hdHVyZSBvdXRkYXRlZDogbG9nVGltZT0JAKQDAQUEdGltZQIJLCBiY1RpbWU9CQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAl0eEZyb21Nc2cJAJEDAgULbmV3TG9jVHhWZXIAAQQGbGFzdFR4CQELdmFsdWVPckVsc2UCCQCiCAEJARFrZXlMYXN0VHhJZEJ5VXNlcgEFCHVzZXJBZGRyAgADCQECIT0CBQZsYXN0VHgFCXR4RnJvbU1zZwkAAgEJAKwCAgkArAICCQCsAgICHlR4IGlkcyBkb24ndCBtYXRjaCEgSW4gc3RhdGU6IAUGbGFzdFR4AgosIGluIG1zZzogBQl0eEZyb21Nc2cEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUIdXNlckFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQFbWF4SFAJAQltYXhIZWFsdGgBCQELdmFsdWVPckVsc2UCCQCfCAEJAQxrZXlEdWNrTGV2ZWwBBQtkdWNrQXNzZXRJZAAABAxvbGRGcm9tU3RhdGUJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoBQVtYXhIUAMJAQIhPQIFDG9sZEZyb21TdGF0ZQUFY3VySFAJAAIBCQCsAgIJAKwCAgkArAICAgpvbGRIZWFsdGg9CQCkAwEFDG9sZEZyb21TdGF0ZQIvIGZyb20gc3RhdGUgZG9lcyBub3QgbWF0Y2ggb25lIGZyb20gZmxpZ2h0IGxvZz0JAKQDAQUFY3VySFADCQBnAgAABQVjdXJIUAkAAgECHllvdSBjYW4ndCBmbHkgd2l0aCB6ZXJvIGhlYWx0aAMJAQEhAQkBF2NhbldlYXJDdXJyZW50RXF1aXBtZW50AQULZHVja0Fzc2V0SWQJAAIBAhZFcXVpcG1lbnQgaW5jb21wYXRpYmxlBAVib251cwMJAGYCCQCQAwEFCWZsaWdodExvZwUHZmxCb251cwkAkQMCBQlmbGlnaHRMb2cFB2ZsQm9udXMCAAQIcHJvZFVzZWQDCQBmAgkAkAMBBQlmbGlnaHRMb2cFC2ZsUHJvZHNVc2VkCQCRAwIFCWZsaWdodExvZwULZmxQcm9kc1VzZWQCAAQKc2VudEFtb3VudAMDCQBmAgUFbmV3SFAAAAkAAAIFBWJvbnVzAgEkBwkBBWFzSW50AQkA/AcEBQxyZXN0Q29udHJhY3QCDXNlbmRVc2R0UHJpemUJAMwIAgUIdXNlckFkZHIFA25pbAUDbmlsAAAJAJcKBQUFbmV3SFAFC2R1Y2tBc3NldElkBQpzZW50QW1vdW50BQtuZXdMb2NhdGlvbgUIcHJvZFVzZWQBDGFwcGx5Qm9udXNlcwILbGFuZEFzc2V0SWQGcGllY2VzBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQJYXJ0UGllY2VzCQELdmFsdWVPckVsc2UCCQCfCAEJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkAAAEBGFkZDYJAGkCBQppbmZyYUxldmVsAAYEBGFkZDcJAGkCBQppbmZyYUxldmVsAAcJAGQCCQBkAgUPREFJTFlSRVNCWVBJRUNFCQBrAwUPREFJTFlSRVNCWVBJRUNFCQBkAgkAZAIFCmluZnJhTGV2ZWwFBGFkZDYJAGgCAAIFBGFkZDcABQkAawMFD0RBSUxZUkVTQllQSUVDRQUJYXJ0UGllY2VzCQBoAgUGcGllY2VzAAUBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwRhZGRyCWNsYWltTW9kZQ1sYW5kQXNzZXRJZEluBA0kdDAzMzc4NDM0MzIzAwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAJQKAgUNbGFuZEFzc2V0SWRJbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAgAEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04EA2xvYwkAtQkCCQEFdmFsdWUBBQtjdXJMb2NhdGlvbgIBXwMJAQIhPQIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFMCQACAQkArAICCQCsAgICFkR1Y2sgbG9jYXRpb24gdHlwZSBpcyAJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAhEsIGJ1dCBzaG91bGQgYmUgTAkAlAoCCQCRAwIFA2xvYwUIbG9jSWR4SWQFC2R1Y2tBc3NldElkBAtsYW5kQXNzZXRJZAgFDSR0MDMzNzg0MzQzMjMCXzEEBmR1Y2tJZAgFDSR0MDMzNzg0MzQzMjMCXzIEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFB3RpbWVLZXkJAKwCAgkArAICAgVMYW5kIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8JAJYKBAUGZHVja0lkBQtsYW5kQXNzZXRJZAUBZAUJc2F2ZWRUaW1lARBjbGFpbVJlc0ludGVybmFsBARhZGRyBmFtb3VudAljbGFpbU1vZGUNbGFuZEFzc2V0SWRJbgMJAGYCAAAFBmFtb3VudAkAAgECD05lZ2F0aXZlIGFtb3VudAQBYwkBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwUEYWRkcgUJY2xhaW1Nb2RlBQ1sYW5kQXNzZXRJZEluBAhsYW5kU2l6ZQkAkQMCCAUBYwJfMwULcmVjTGFuZFNpemUEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCCAUBYwJfMwULcmVjVGVycmFpbnMECWRlbHRhVGltZQkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wCAUBYwJfNAMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEIBQFjAl80AgwsIGN1cnJlbnQgPSAJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEFCGxhbmRTaXplBBZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQEMYXBwbHlCb251c2VzAggFAWMCXzIFBnBpZWNlcwQIYXZhaWxSZXMJAGsDBQlkZWx0YVRpbWUJAGgCBRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBQZwaWVjZXMFCURBWU1JTExJUwMJAGYCBQZhbW91bnQFCGF2YWlsUmVzCQACAQkArAICCQCsAgIJAKwCAgIiTm90IGVub3VnaCByZXNvdXJjZXMsIGF2YWlsYWJsZSA9IAkApAMBBQhhdmFpbFJlcwIOLCByZXF1ZXN0ZWQgPSAJAKQDAQUGYW1vdW50BAxuZXdEZWx0YVRpbWUJAGsDCQBlAgUIYXZhaWxSZXMFBmFtb3VudAUJREFZTUlMTElTCQBoAgUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQUGcGllY2VzBAxuZXdUaW1lc3RhbXAJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUMbmV3RGVsdGFUaW1lBAlsYW5kSW5kZXgJAGkCBQZwaWVjZXMFBVNTSVpFBApyZXNUb0NsYWltCQEJdmlydENsYWltBAUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UEBXdoS2V5CQESa2V5V2FyZWhvdXNlQnlMYW5kAQgFAWMCXzIECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBCAUBYwJfMgAABAljdXJyZW50V2gJAQxnZXRXYXJlaG91c2UDBQV3aEtleQUJbGFuZEluZGV4BQppbmZyYUxldmVsBARsb2Z0CQC1CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeExPRlQCAV8EC3doU3BhY2VMZWZ0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUHdm9sRnJlZQMDCQAAAgUJY2xhaW1Nb2RlBQtjbGFpbU1vZGVXaAkAZgIFBmFtb3VudAULd2hTcGFjZUxlZnQHCQACAQkArAICCQCsAgICBU9ubHkgCQCkAwEFC3doU3BhY2VMZWZ0Ahggc3BhY2UgbGVmdCBpbiB3YXJlaG91c2UEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBCAUBYwJfMQQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BA5jdXJyZW50UGFja1JlcwkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQMY3VycmVudFdoUmVzCQC1CQIJAJEDAgUJY3VycmVudFdoBQh3aElkeFJlcwIBXwQNJHQwMzY2OTczNzU2OAMJAAACBQljbGFpbU1vZGUFC2NsYWltTW9kZVdoCQCWCgQJAQZhZGRSZXMFBQxjdXJyZW50V2hSZXMFDXRlcnJhaW5Db3VudHMJAGUCBQlkZWx0YVRpbWUFDG5ld0RlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAgFCnJlc1RvQ2xhaW0CXzIJAGUCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUHdm9sRnJlZQgFCnJlc1RvQ2xhaW0CXzIDCQAAAgUJY2xhaW1Nb2RlBQ1jbGFpbU1vZGVEdWNrCQCWCgQJAJEDAgUJY3VycmVudFdoBQh3aElkeFJlcwkBBmFkZFJlcwUFDmN1cnJlbnRQYWNrUmVzBQ10ZXJyYWluQ291bnRzCQBlAgUJZGVsdGFUaW1lBQxuZXdEZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFC3ZvbE9jY3VwaWVkCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUHdm9sRnJlZQQFZGlzdHIJAQ1kaXN0cmlidXRlUmVzBAUMY3VycmVudFdoUmVzBQ5jdXJyZW50UGFja1JlcwUKcmVzVG9DbGFpbQULd2hTcGFjZUxlZnQEBHdoQW0JAJcDAQkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUHdm9sRnJlZQkAzAgCCAUKcmVzVG9DbGFpbQJfMgUDbmlsCQCWCgQIBQVkaXN0cgJfMQgFBWRpc3RyAl8yCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFC3ZvbE9jY3VwaWVkBQR3aEFtCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUFBHdoQW0EBXdoUmVzCAUNJHQwMzY2OTczNzU2OAJfMQQFYnBSZXMIBQ0kdDAzNjY5NzM3NTY4Al8yBAVsb2Z0TwgFDSR0MDM2Njk3Mzc1NjgCXzMEBWxvZnRGCAUNJHQwMzY2OTczNzU2OAJfNAkAlwoFCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEIBQFjAl8yBQxuZXdUaW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKTEFORFBSRUZJWAgFAWMCXzIFBGFkZHIFDG5ld1RpbWVzdGFtcAUDbmlsBQVicEtleQkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIFBWJwUmVzCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsBQV3aEtleQkAzAgCCQCRAwIFCWN1cnJlbnRXaAULd2hJZHhMZXZlbHMJAMwIAgUFd2hSZXMJAMwIAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4TWF0CQDMCAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QJAMwIAgkAuQkCCQDMCAIJAJEDAgUEbG9mdAUJdm9sTG9ja2VkCQDMCAIJAKQDAQUFbG9mdE8JAMwIAgkApAMBBQVsb2Z0RgkAzAgCCQCRAwIFBGxvZnQFCHZvbFRvdGFsBQNuaWwCAV8FA25pbAEIY2xhaW1BbGwEBGFkZHILbGFuZEFzc2V0SWQGcGllY2VzCWNsYWltTW9kZQQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAQJc2F2ZWRUaW1lCQEFdmFsdWUBCQCfCAEFB3RpbWVLZXkECGF2YWlsUmVzCQBoAgkAawMJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUJc2F2ZWRUaW1lCQEMYXBwbHlCb251c2VzAgULbGFuZEFzc2V0SWQFBnBpZWNlcwUJREFZTUlMTElTBQZwaWVjZXMJARBjbGFpbVJlc0ludGVybmFsBAUEYWRkcgUIYXZhaWxSZXMFCWNsYWltTW9kZQULbGFuZEFzc2V0SWQBDXVwSW5mcmFDb21tb24EDHNob3VsZFVzZU1hdAZjYWxsZXINcGF5bWVudEFtb3VudAtsYW5kQXNzZXRJZAQEYWRkcgkApQgBBQZjYWxsZXIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFE2NsYWltTW9kZVdoVGhlbkR1Y2sFC2xhbmRBc3NldElkBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQIaW5mcmFLZXkJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQgFAWMCXzIECGN1ckxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEFCGluZnJhS2V5AAADAwkBASEBBRhLU19BTExPV19CSUdfSU5GUkFfTUVSR0UJAGcCBQhjdXJMZXZlbAADBwkAAgECJkN1cnJlbnRseSBtYXggaW5mcmFzdHJ1Y3R1cmUgbGV2ZWwgPSAzBAhtYXhJbmZyYQkAZAIJAGkCCQEEc3FydAQFBnBpZWNlcwAAAAAFBERPV04ABQACBAhuZXdMZXZlbAkAZAIFCGN1ckxldmVsAAEDAwUYS1NfQUxMT1dfQklHX0lORlJBX01FUkdFCQBmAgUIbmV3TGV2ZWwFCG1heEluZnJhBwkAAgEJAKwCAgIlQ3VycmVudGx5IG1heCBpbmZyYXN0cnVjdHVyZSBsZXZlbCA9IAkApAMBBQhtYXhJbmZyYQQEY29zdAkAawMFFUluZnJhVXBncmFkZUNvc3RTVXNkdAkAaAIFBnBpZWNlcwUIbmV3TGV2ZWwFBVNTSVpFAwMJAQEhAQUMc2hvdWxkVXNlTWF0CQECIT0CBQ1wYXltZW50QW1vdW50BQRjb3N0BwkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFBGNvc3QEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBCAUBYwJfMQQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAVtTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQHbWF0VXNlZAkAawMFEUluZnJhVXBncmFkZUNvc3RTCQBoAgUGcGllY2VzBQhuZXdMZXZlbAUFU1NJWkUEBm5ld01hdAkAuQkCCQERc3VidHJhY3RNYXRlcmlhbHMDBQxzaG91bGRVc2VNYXQFBW1MaXN0BQdtYXRVc2VkAgFfBAtjbGFpbVJlc3VsdAkBCGNsYWltQWxsBAUEYWRkcggFAWMCXzIFBnBpZWNlcwUTY2xhaW1Nb2RlV2hUaGVuRHVjawQGd2hEYXRhCAULY2xhaW1SZXN1bHQCXzUEBm9sZFZvbAkBF2dldFdhcmVob3VzZVRvdGFsVm9sdW1lAQkAkQMCBQZ3aERhdGEFC3doSWR4TGV2ZWxzBApuZXdWb2xEYXRhCQC5CQIJAMwIAgkAkQMCCQC1CQIJAJEDAgUGd2hEYXRhBQt3aElkeExldmVscwIBXwAACQDMCAIJAKQDAQUIbmV3TGV2ZWwFA25pbAIBXwQGbmV3Vm9sCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBBQpuZXdWb2xEYXRhBARsb2Z0CQC1CQIJAJEDAgUGd2hEYXRhBQl3aElkeExPRlQCAV8ECm5ld0xvZnRTdHIJALkJAgkAzAgCCQCRAwIFBGxvZnQFCXZvbExvY2tlZAkAzAgCCQCRAwIFBGxvZnQFC3ZvbE9jY3VwaWVkCQDMCAIJAKQDAQkAZQIJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUHdm9sRnJlZQUGbmV3Vm9sBQZvbGRWb2wJAMwIAgkApAMBBQZuZXdWb2wFA25pbAIBXwkAlQoDCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFCGluZnJhS2V5BQhuZXdMZXZlbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIIBQFjAl8yBQRhZGRyBQhuZXdMZXZlbAkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCCAULY2xhaW1SZXN1bHQCXzMFCGJwSWR4UmVzCQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgkAzAgCCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzQJALkJAgkAzAgCBQpuZXdWb2xEYXRhCQDMCAIJAJEDAgUGd2hEYXRhBQh3aElkeFJlcwkAzAgCCQCRAwIFBndoRGF0YQUId2hJZHhNYXQJAMwIAgkAkQMCBQZ3aERhdGEFCXdoSWR4UHJvZAkAzAgCBQpuZXdMb2Z0U3RyBQNuaWwCAToFA25pbAgFC2NsYWltUmVzdWx0Al8xBQhuZXdMZXZlbAUHbWF0VXNlZAEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCC2R1Y2tBc3NldElkB2RlbHRhWFAEBmx2bEtleQkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkBAV4cEtleQkBCWtleUR1Y2tYUAEFC2R1Y2tBc3NldElkBAJ4cAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QFBXhwS2V5AAAEBW5ld1hQCQBkAgUCeHAFB2RlbHRhWFAECWx2bFBvaW50cwkBB2xldmVsVXACCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAUGbHZsS2V5AAAFBW5ld1hQBAlrZXlQb2ludHMJARFrZXlEdWNrRnJlZVBvaW50cwEFC2R1Y2tBc3NldElkCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFBmx2bEtleQkAkQMCBQlsdmxQb2ludHMAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUFeHBLZXkFBW5ld1hQCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrZXlQb2ludHMJAGQCCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleVBvaW50cwAACQCRAwIFCWx2bFBvaW50cwABBQNuaWwFBW5ld1hQARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgRhZGRyB2RlbHRhWFAEBmx2bEtleQkBDGtleVVzZXJMZXZlbAEFBGFkZHIEBXhwS2V5CQEJa2V5VXNlclhQAQUEYWRkcgQCeHAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPc3Rha2luZ0NvbnRyYWN0BQV4cEtleQAABAVuZXdYUAkAZAIFAnhwBQdkZWx0YVhQBAlsdmxQb2ludHMJAQdsZXZlbFVwAgkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QFBmx2bEtleQAABQVuZXdYUAQJa2V5UG9pbnRzCQERa2V5VXNlckZyZWVQb2ludHMBBQRhZGRyCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFBmx2bEtleQkAkQMCBQlsdmxQb2ludHMAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUFeHBLZXkFBW5ld1hQCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrZXlQb2ludHMJAGQCCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleVBvaW50cwAACQCRAwIFCWx2bFBvaW50cwABBQNuaWwFBW5ld1hQARJhY3RpdmF0ZU9uYm9hcmRBcnQBBGFkZHIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQIcmVmQnlLZXkJAQ9rZXlBZGRyZXNzUmVmQnkBBQRhZGRyBAVyZWZCeQkAoggBBQhyZWZCeUtleQMJAQEhAQkBCWlzRGVmaW5lZAEFBXJlZkJ5CQACAQIpWW91IGFyZSBub3QgZWxpZ2libGUgZm9yIE9OQk9BUkQgYXJ0aWZhY3QEBmFydEtleQkBHGtleU9uYm9hcmRBcnREdWNrQWN0aXZhdGVkQnkBBQRhZGRyBAdhcnREdWNrCQCiCAEFBmFydEtleQMJAQlpc0RlZmluZWQBBQdhcnREdWNrCQACAQkArAICAi9Zb3UgYWxyZWFkeSB1c2VkIHlvdXIgT05CT0FSRCBhcnRpZmFjdCBvbiBkdWNrIAkBBXZhbHVlAQUHYXJ0RHVjawQQZHVja0FjdGl2YXRvcktleQkBHGtleU9uYm9hcmRBcnRBY3RpdmF0ZWRPbkR1Y2sBBQtkdWNrQXNzZXRJZAQNZHVja0FjdGl2YXRvcgkAoggBBRBkdWNrQWN0aXZhdG9yS2V5AwkBCWlzRGVmaW5lZAEFDWR1Y2tBY3RpdmF0b3IJAAIBCQCsAgIJAKwCAgkArAICAglUaGUgZHVjayAFC2R1Y2tBc3NldElkAjQgYWxyZWFkeSBnb3QgcG9pbnRzIGZyb20gT05CT0FSRCBhcnRpZmFjdCBmcm9tIHVzZXIgCQEFdmFsdWUBBQ1kdWNrQWN0aXZhdG9yCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUGYXJ0S2V5BQtkdWNrQXNzZXRJZAkAzAgCCQELU3RyaW5nRW50cnkCBRBkdWNrQWN0aXZhdG9yS2V5BQRhZGRyBQNuaWwICQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQtkdWNrQXNzZXRJZAUJeHBPbmJvYXJkAl8xARJhY3RpdmF0ZVByZXNhbGVBcnQCBGFkZHINbGFuZEFzc2V0SWRJbgQBYwkBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwUEYWRkcgUTY2xhaW1Nb2RlV2hUaGVuRHVjawUNbGFuZEFzc2V0SWRJbgQLbGFuZEFzc2V0SWQIBQFjAl8yBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQNYWN0aXZhdGlvbktleQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQDCQBmAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ1hY3RpdmF0aW9uS2V5AAAAAAkAAgECJVByZXNhbGUgYXJ0aWZhY3QgaXMgYWxyZWFkeSBhY3RpdmF0ZWQDCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIIBQFjAl8zBQpyZWNMYW5kTnVtBQ9QUkVTQUxFTlVNTEFORFMJAAIBCQCsAgIJAKwCAgkArAICBQpMQU5EUFJFRklYAgEgBQtsYW5kQXNzZXRJZAIlIGlzIG5vdCBlbGlnaWJsZSBmb3IgcHJlc2FsZSBhcnRpZmFjdAQLY2xhaW1SZXN1bHQJAQhjbGFpbUFsbAQFBGFkZHIFC2xhbmRBc3NldElkBQZwaWVjZXMFE2NsYWltTW9kZVdoVGhlbkR1Y2sJAM0IAgkAzQgCCQDNCAIIBQtjbGFpbVJlc3VsdAJfMQkBDEludGVnZXJFbnRyeQIFDWFjdGl2YXRpb25LZXkFBnBpZWNlcwkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al8yCQC5CQIIBQtjbGFpbVJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al80CQC5CQIIBQtjbGFpbVJlc3VsdAJfNQIBOgEPY2hlY2tUb3VybmFtZW50AQtkdWNrQXNzZXRJZAQGbGFzdElkCQELdmFsdWVPckVsc2UCCQCaCAIFEnRvdXJuYW1lbnRDb250cmFjdAUNbGFzdFRvdXJJZEtleQAABAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAgFfBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAV0RGF0YQkBC2dldFRvdXJEYXRhAgUSdG91cm5hbWVudENvbnRyYWN0BQZsYXN0SWQEBnN0YXRpYwkAkQMCBQV0RGF0YQUJaWR4U3RhdGljBAdkeW5hbWljCQCRAwIFBXREYXRhBQppZHhEeW5hbWljAwkBAiE9AgkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQIBVAcDAwMJAAACCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgULY3VyTG9jYXRpb24FD2xvY0lkeENvbnRpbmVudAUGbGFzdElkCQAAAgkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwIKSU5QUk9HUkVTUwcJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQNub3cHCQACAQIqWW91ciBkdWNrIGlzIHRha2luZyBwYXJ0IGluIHRoZSB0b3VybmFtZW50CQEJYXNCb29sZWFuAQkA/AcEBQR0aGlzAhZleGl0VG91cm5hbWVudEludGVybmFsCQDMCAIFC2R1Y2tBc3NldElkBQNuaWwFA25pbAENY2hlY2tEZWxpdmVyeQELZHVja0Fzc2V0SWQEC2N1ckxvY2F0aW9uCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04CAV8EA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXADCQECIT0CCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlAgFEBwQJc3RhcnRUaW1lCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgULY3VyTG9jYXRpb24FD2xvY0lkeENvbnRpbmVudAQIZGlzdGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtjdXJMb2NhdGlvbgUIbG9jSWR4SWQDAwkAZgIFA25vdwkAZAIFCXN0YXJ0VGltZQUSVEVOX01JTlVURVNfTUlMTElTCQBmAgADBQhkaXN0YW5jZQcJAAIBAiBZb3VyIGR1Y2sgaXMgb24gZGVsaXZlcnkgbWlzc2lvbgkBCWFzQm9vbGVhbgEJAPwHBAUEdGhpcwIUZXhpdERlbGl2ZXJ5SW50ZXJuYWwJAMwIAgULZHVja0Fzc2V0SWQFA25pbAUDbmlsAQ1tZXJnZUludGVybmFsBgtuZXdMYW5kU2l6ZQhuZXdMZXZlbAdmb3JtdWxhBGFkZHIMbGFuZEFzc2V0SWRzB25lZWRNYXQEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAMJAQ9jaGVja1RvdXJuYW1lbnQBBQtkdWNrQXNzZXRJZAkAAgECHW1lcmdlSW50ZXJuYWxfY2hlY2tUb3VybmFtZW50AwkBDWNoZWNrRGVsaXZlcnkBBQtkdWNrQXNzZXRJZAkAAgECG21lcmdlSW50ZXJuYWxfY2hlY2tEZWxpdmVyeQoBCmNoZWNrTWVyZ2UCA2FjYwtsYW5kQXNzZXRJZAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAQJc2F2ZWRUaW1lCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUHdGltZUtleQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMEAWQJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBAljb250aW5lbnQJAJEDAgUBZAUMcmVjQ29udGluZW50AwMJAQIhPQIIBQNhY2MCXzMCAAkBAiE9AggFA2FjYwJfMwUJY29udGluZW50BwkAAgECLkxhbmRzIHNob3VsZCBiZSBvbiB0aGUgc2FtZSBjb250aW5lbnQgdG8gbWVyZ2UECGxhbmRTaXplCQCRAwIFAWQFC3JlY0xhbmRTaXplBAdzaXplc0luCAUDYWNjAl8xBAFpCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALMJAgUHc2l6ZXNJbgUIbGFuZFNpemUCJ1lvdSBoYXZlbid0IHBhc3NlZCBhbGwgdGhlIGxhbmRzIG5lZWRlZAQIc2l6ZXNPdXQJAKwCAgkArwICBQdzaXplc0luBQFpCQCwAgIFB3NpemVzSW4JAGQCBQFpAAEEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEFCGxhbmRTaXplBARhcnRzCQBkAggFA2FjYwJfMgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAAABAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQIcmVxTGV2ZWwEByRtYXRjaDAFCGxhbmRTaXplAwkAAAICAVMFByRtYXRjaDAAAwMJAAACAgFNBQckbWF0Y2gwAAQDCQAAAgIBTAUHJG1hdGNoMAAFAwkAAAICAlhMBQckbWF0Y2gwAAYJAAIBAhpPbmx5IFMsIE0sIEwsIFhMIGNhbiBtZXJnZQMJAQIhPQIFCmluZnJhTGV2ZWwFCHJlcUxldmVsCQACAQIiQWxsIGxhbmRzIHNob3VsZCBiZSBtYXhlZCB0byBtZXJnZQQHbGFuZE51bQkAkQMCBQFkBQpyZWNMYW5kTnVtBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAgUBZAULcmVjVGVycmFpbnMECWRlbHRhVGltZQkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQlzYXZlZFRpbWUDCQBmAgAABQlkZWx0YVRpbWUJAAIBCQCsAgIJAKwCAgkArAICAiZTYXZlZCB0aW1lc3RhbXAgaXMgaW4gZnV0dXJlLCBzYXZlZCA9IAkApAMBBQlzYXZlZFRpbWUCDCwgY3VycmVudCA9IAkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkBDGFwcGx5Qm9udXNlcwIFC2xhbmRBc3NldElkBQZwaWVjZXMECWxhbmRJbmRleAkAaQIFBnBpZWNlcwUFU1NJWkUEBWJwUmVzCQEGYWRkUmVzBQkAtQkCCAUDYWNjAl80AgFfBQ10ZXJyYWluQ291bnRzBQlkZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQQFcHJvcHMJARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAgFA2FjYwJfNgUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AP///////////wEEBmNQcm9wcwkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECAUDYWNjA18xMAUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AP///////////wEEC3N1bVRlcnJhaW5zCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQIBQNhY2MCXzkFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAABBAVsYW5kcwgFA2FjYwJfNwQDaWR4CQDPCAIFBWxhbmRzBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEFA2lkeAkAAgEJAKwCAgIgWW91ciBzdGFrZWQgbGFuZHMgZG9uJ3QgY29udGFpbiAFC2xhbmRBc3NldElkBAljdXN0b21LZXkJARprZXlMYW5kQXNzZXRJZFRvQ3VzdG9tTmFtZQEFC2xhbmRBc3NldElkBApjdXN0b21OYW1lCQELdmFsdWVPckVsc2UCCQCiCAEFCWN1c3RvbUtleQIACQCcCgoFCHNpemVzT3V0BQRhcnRzBQljb250aW5lbnQFBWJwUmVzCQDOCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCAUDYWNjAl81CQELRGVsZXRlRW50cnkBCQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQRhZGRyCQELRGVsZXRlRW50cnkBCQEQa2V5TGFuZFRvQXNzZXRJZAEFB2xhbmROdW0JAQtEZWxldGVFbnRyeQEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIFC2xhbmRBc3NldElkBQRhZGRyCQELRGVsZXRlRW50cnkBCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQkBC0RlbGV0ZUVudHJ5AQkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkCQELRGVsZXRlRW50cnkBBQljdXN0b21LZXkJAQRCdXJuAgkA2QQBBQtsYW5kQXNzZXRJZAABAwkBAiE9AgUKY3VzdG9tTmFtZQIACQDMCAIJAQtEZWxldGVFbnRyeQEJARprZXlMYW5kQ3VzdG9tTmFtZVRvQXNzZXRJZAEFCmN1c3RvbU5hbWUFA25pbAUDbmlsBQVwcm9wcwkA0QgCBQVsYW5kcwkBBXZhbHVlAQUDaWR4CQBkAggFA2FjYwJfOAUGcGllY2VzBQtzdW1UZXJyYWlucwUGY1Byb3BzBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQIcHJvcExpc3QJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBCQERa2V5UmVzUHJvcG9ydGlvbnMAAgswXzBfMF8wXzBfMAIBXwQIbGFuZHNLZXkJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQRhZGRyBAhsYW5kc1N0cgkAoggBBQhsYW5kc0tleQQHbGFuZHNJbgMJAQlpc0RlZmluZWQBBQhsYW5kc1N0cgkAvQkCCQEFdmFsdWUBBQhsYW5kc1N0cgIBXwUDbmlsBAVjb250MAkAkQMCCQC1CQIICQEFdmFsdWUBCQDsBwEJANkEAQkAkQMCBQxsYW5kQXNzZXRJZHMAAAtkZXNjcmlwdGlvbgIBXwUMcmVjQ29udGluZW50BAljb250UHJvcHMJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEWa2V5UmVzVHlwZXNCeUNvbnRpbmVudAEFBWNvbnQwAgswXzBfMF8wXzBfMAIBXwQBcgoAAiRsBQxsYW5kQXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCcCgoFB2Zvcm11bGEAAAIACQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwUDbmlsBQhwcm9wTGlzdAUHbGFuZHNJbgAACQC1CQICCzBfMF8wXzBfMF8wAgFfBQljb250UHJvcHMKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCmNoZWNrTWVyZ2UCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDUJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFBAljb250aW5lbnQIBQFyAl8zBAxjb250aW5lbnRJZHgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQpjb250aW5lbnRzBQljb250aW5lbnQJAKwCAgITVW5rbm93biBjb250aW5lbnQ6IAUJY29udGluZW50BAh0ZXJyYWlucwkBE2dlblRlcnJhaW5zRm9yTWVyZ2UCCAUBcgJfOQkAaQIJAQ9udW1QaWVjZXNCeVNpemUBBQtuZXdMYW5kU2l6ZQUFU1NJWkUEB2ZyZWVOdW0JAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEmtleU5leHRGcmVlTGFuZE51bQAJAGQCBQ9QUkVTQUxFTlVNTEFORFMAAQQKbmV3TGFuZE51bQkApAMBBQdmcmVlTnVtBAVpc3N1ZQkAwggFCQEHbmZ0TmFtZQIFCm5ld0xhbmROdW0FC25ld0xhbmRTaXplCQC5CQIJAMwIAgUKbmV3TGFuZE51bQkAzAgCBQtuZXdMYW5kU2l6ZQkAzAgCBQh0ZXJyYWlucwkAzAgCBQljb250aW5lbnQFA25pbAIBXwABAAAHBAdhc3NldElkCQC4CAEFBWlzc3VlBA5uZXdMYW5kQXNzZXRJZAkA2AQBBQdhc3NldElkBAZuZXdNYXQJALkJAgkBEXN1YnRyYWN0TWF0ZXJpYWxzAwkAZgIFB25lZWRNYXQAAAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwUHbmVlZE1hdAIBXwQJcGllY2VzS2V5CQEWa2V5U3Rha2VkUGllY2VzQnlPd25lcgEFBGFkZHIEDHN0YWtlZFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlwaWVjZXNLZXkAAAkAlAoCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCAUBcgJfNQMJAGYCCQCQAwEIBQFyAl83AAAJAQtTdHJpbmdFbnRyeQIFCGxhbmRzS2V5CQC7CQIIBQFyAl83AgFfCQELRGVsZXRlRW50cnkBBQhsYW5kc0tleQkBDEludGVnZXJFbnRyeQIFCXBpZWNlc0tleQMJAGYCCAUBcgJfOAUMc3Rha2VkUGllY2VzAAAJAGUCBQxzdGFrZWRQaWVjZXMIBQFyAl84CQEMSW50ZWdlckVudHJ5AgkBEmtleU5leHRGcmVlTGFuZE51bQAJAGQCBQdmcmVlTnVtAAEFBWlzc3VlCQELU3RyaW5nRW50cnkCCQEQa2V5TGFuZFRvQXNzZXRJZAEFCm5ld0xhbmROdW0FDm5ld0xhbmRBc3NldElkCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQUObmV3TGFuZEFzc2V0SWQFBGFkZHIJAQtTdHJpbmdFbnRyeQIJARFrZXlMYW5kTnVtVG9Pd25lcgEFCm5ld0xhbmROdW0FBGFkZHIJAQxJbnRlZ2VyRW50cnkCCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQ5uZXdMYW5kQXNzZXRJZAgFAXICXzIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFDm5ld0xhbmRBc3NldElkBQhuZXdMZXZlbAkBDEludGVnZXJFbnRyeQIJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQ5uZXdMYW5kQXNzZXRJZAUEYWRkcgUIbmV3TGV2ZWwJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCAUBcgJfNAkAzAgCBQZuZXdNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToJAQtTdHJpbmdFbnRyeQIJARFrZXlSZXNQcm9wb3J0aW9ucwAJALkJAggFAXICXzYCAV8JAQtTdHJpbmdFbnRyeQIJARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQUJY29udGluZW50CQC5CQIIBQFyA18xMAIBXwkBC1N0cmluZ0VudHJ5AgkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQC5CQIJAMwIAgUJY29udGluZW50CQDMCAICAUwJAMwIAgUObmV3TGFuZEFzc2V0SWQFA25pbAIBXwkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUEYWRkcgABBQdhc3NldElkBQ5uZXdMYW5kQXNzZXRJZAEDczJtAgRhZGRyDGxhbmRBc3NldElkcwkBDW1lcmdlSW50ZXJuYWwGAgFNAAMCBFNTU1MFBGFkZHIFDGxhbmRBc3NldElkcwAAAQNtMmwCBGFkZHIMbGFuZEFzc2V0SWRzCQENbWVyZ2VJbnRlcm5hbAYCAUwABAIDU01NBQRhZGRyBQxsYW5kQXNzZXRJZHMJAGgCBRFJbmZyYVVwZ3JhZGVDb3N0UwAEAQRsMnhsAgRhZGRyDGxhbmRBc3NldElkcwkBDW1lcmdlSW50ZXJuYWwGAgJYTAAFAgVTU1NNTAUEYWRkcgUMbGFuZEFzc2V0SWRzCQBoAgURSW5mcmFVcGdyYWRlQ29zdFMALwEGeGwyeHhsAgRhZGRyDGxhbmRBc3NldElkcwkBDW1lcmdlSW50ZXJuYWwGAgNYWEwABgIDTFhMBQRhZGRyBQxsYW5kQXNzZXRJZHMJAGgCBRFJbmZyYVVwZ3JhZGVDb3N0UwA2AQttZXJnZUNvbW1vbgIEYWRkcgxsYW5kQXNzZXRJZHMEByRtYXRjaDAJAJADAQUMbGFuZEFzc2V0SWRzAwkAAAIABAUHJG1hdGNoMAkBA3MybQIFBGFkZHIFDGxhbmRBc3NldElkcwMJAAACAAMFByRtYXRjaDAJAQNtMmwCBQRhZGRyBQxsYW5kQXNzZXRJZHMDCQAAAgAFBQckbWF0Y2gwCQEEbDJ4bAIFBGFkZHIFDGxhbmRBc3NldElkcwMJAAACAAIFByRtYXRjaDAJAQZ4bDJ4eGwCBQRhZGRyBQxsYW5kQXNzZXRJZHMJAAIBAg1Vbmtub3duIG1lcmdlAQZwcm9sb2cBAWkDAwkBAiE9AggFAWkMb3JpZ2luQ2FsbGVyBQxyZXN0Q29udHJhY3QJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBCmtleUJsb2NrZWQABwcJAAIBAh9Db250cmFjdHMgYXJlIHVuZGVyIG1haW50ZW5hbmNlCQELU3RyaW5nRW50cnkCCQERa2V5TGFzdFR4SWRCeVVzZXIBCQClCAEIBQFpDG9yaWdpbkNhbGxlcgkA2AQBCAUBaQ10cmFuc2FjdGlvbklkLAFpAQ1jb25zdHJ1Y3RvclYxAQhyZXN0QWRkcgMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEVBlcm1pc3Npb24gZGVuaWVkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ5rZXlSZXN0QWRkcmVzcwAFCHJlc3RBZGRyBQNuaWwBaQEKc2V0QmxvY2tlZAEJaXNCbG9ja2VkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRcGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQprZXlCbG9ja2VkAAUJaXNCbG9ja2VkBQNuaWwBaQEJc3Rha2VMYW5kAAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABAdhc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQEB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyAwkBAiE9AggFA3BtdAZhbW91bnQAAQkAAgEJAKwCAgkArAICAgRORlQgBQpMQU5EUFJFRklYAiQgdG9rZW4gc2hvdWxkIGJlIGF0dGFjaGVkIGFzIHBheW1lbnQEBWFzc2V0CQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQDCQECIT0CCAUFYXNzZXQGaXNzdWVyBQR0aGlzCQACAQIXVW5rbm93biBpc3N1ZXIgb2YgdG9rZW4DCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpMQU5EUFJFRklYCQACAQkArAICCQCsAgICCU9ubHkgTkZUIAUKTEFORFBSRUZJWAIUIHRva2VucyBhcmUgYWNjZXB0ZWQEC2xhbmROdW1TaXplCQCwAgIIBQVhc3NldARuYW1lAAQEB2xhbmROdW0DCQEIY29udGFpbnMCBQtsYW5kTnVtU2l6ZQIDWFhMCQCzAgIFC2xhbmROdW1TaXplAAMDCQEIY29udGFpbnMCBQtsYW5kTnVtU2l6ZQICWEwJALMCAgULbGFuZE51bVNpemUAAgkAswICBQtsYW5kTnVtU2l6ZQABAwkBASEBCQEJaXNEZWZpbmVkAQkAtgkBBQdsYW5kTnVtCQACAQkArAICAh5DYW5ub3QgcGFyc2UgbGFuZCBudW1iZXIgZnJvbSAIBQVhc3NldARuYW1lBAtsYW5kQXNzZXRJZAkA2AQBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAwkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQISIGlzIGFscmVhZHkgc3Rha2VkBAFkCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIFAWQFC3JlY1RlcnJhaW5zBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIFAWQFC3JlY0xhbmRTaXplBAlsYW5kSW5kZXgJAGkCBQZwaWVjZXMFBVNTSVpFBAVwcm9wcwkBEXVwZGF0ZVByb3BvcnRpb25zAwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AAEEDHJlc0J5Q29udEtleQkBFmtleVJlc1R5cGVzQnlDb250aW5lbnQBCQCRAwIFAWQFDHJlY0NvbnRpbmVudAQJY29udFByb3BzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUMcmVzQnlDb250S2V5AgswXzBfMF8wXzBfMAIBXwQQdXBkYXRlZENvbnRQcm9wcwkAuQkCCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQFCWNvbnRQcm9wcwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AAECAV8ECGxhbmRzS2V5CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUHYWRkcmVzcwQIbGFuZHNTdHIJAKIIAQUIbGFuZHNLZXkEBWxhbmRzAwkBCWlzRGVmaW5lZAEFCGxhbmRzU3RyCQC9CQIJAQV2YWx1ZQEFCGxhbmRzU3RyAgFfBQNuaWwDCQEPY29udGFpbnNFbGVtZW50AgUFbGFuZHMFC2xhbmRBc3NldElkCQACAQkArAICAiJZb3VyIHN0YWtlZCBsYW5kcyBhbHJlYWR5IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAMJAGcCCQCQAwEFBWxhbmRzBRhNQVhfTEFORFNfU1RBS0VEX0JZX1VTRVIJAAIBCQCsAgIJAKwCAgIZWW91ciBhbHJlYWR5IHN0YWtlZCBtYXggKAkApAMBBRhNQVhfTEFORFNfU1RBS0VEX0JZX1VTRVICBykgbGFuZHMECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAlwaWVjZXNLZXkJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUHYWRkcmVzcwQJb2xkUGllY2VzCQELdmFsdWVPckVsc2UCCQCfCAEFCXBpZWNlc0tleQAABAl3bGdSZXN1bHQJAPwHBAULd2xnQ29udHJhY3QCEm9uU3Rha2VVbnN0YWtlTGFuZAkAzAgCBQdhZGRyZXNzBQNuaWwFA25pbAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd0aW1lS2V5CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUHYWRkcmVzcwgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBC1N0cmluZ0VudHJ5AgUIbGFuZHNLZXkJALsJAgkAzQgCBQVsYW5kcwULbGFuZEFzc2V0SWQCAV8JAMwIAgkBDEludGVnZXJFbnRyeQIFCXBpZWNlc0tleQkAZAIFCW9sZFBpZWNlcwUGcGllY2VzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5TGFuZE51bVRvT3duZXIBBQdsYW5kTnVtBQdhZGRyZXNzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAgULbGFuZEFzc2V0SWQFB2FkZHJlc3MFCmluZnJhTGV2ZWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAUFcHJvcHMJAMwIAgkBC1N0cmluZ0VudHJ5AgUMcmVzQnlDb250S2V5BRB1cGRhdGVkQ29udFByb3BzCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsBQl3bGdSZXN1bHQBaQELdW5zdGFrZUxhbmQBDWxhbmRBc3NldElkSW4EDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQZjYWxsZXIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFDWNsYWltTW9kZUR1Y2sFDWxhbmRBc3NldElkSW4EC2xhbmRBc3NldElkCAUBYwJfMgQBZAgFAWMCXzMECGxhbmRzS2V5CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUEYWRkcgQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIFAWQFC3JlY1RlcnJhaW5zBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIFAWQFC3JlY0xhbmRTaXplBAlsYW5kSW5kZXgJAGkCBQZwaWVjZXMFBVNTSVpFBAVwcm9wcwkBEXVwZGF0ZVByb3BvcnRpb25zAwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AP///////////wEEDHJlc0J5Q29udEtleQkBFmtleVJlc1R5cGVzQnlDb250aW5lbnQBCQCRAwIFAWQFDHJlY0NvbnRpbmVudAQJY29udFByb3BzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUMcmVzQnlDb250S2V5AgswXzBfMF8wXzBfMAIBXwQQdXBkYXRlZENvbnRQcm9wcwkAuQkCCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQFCWNvbnRQcm9wcwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AP///////////wECAV8EC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyBQtsYW5kQXNzZXRJZAUGcGllY2VzBQ1jbGFpbU1vZGVEdWNrBAVsYW5kcwkAvQkCCQELdmFsdWVPckVsc2UCCQCiCAEFCGxhbmRzS2V5AgACAV8EA2lkeAkAzwgCBQVsYW5kcwULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQNpZHgJAAIBCQCsAgICIFlvdXIgc3Rha2VkIGxhbmRzIGRvbid0IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQOZ292UmVsZWFzZVRpbWUJAQt2YWx1ZU9yRWxzZQIJAJoIAgULZ292Q29udHJhY3QJARVrZXlVc2VyR3dsUmVsZWFzZVRpbWUBBQRhZGRyAAADCQBnAgUOZ292UmVsZWFzZVRpbWUFA25vdwkAAgEJAKwCAgI5WW91ciBnV0wgYXJlIHRha2luZyBwYXJ0IGluIHZvdGluZywgY2Fubm90IHVuc3Rha2UgdW50aWwgCQCkAwEFDmdvdlJlbGVhc2VUaW1lBA5hcmJSZWxlYXNlVGltZQkAZAIJAQt2YWx1ZU9yRWxzZQIJAJoIAgULd2xnQ29udHJhY3QJARRrZXlMYXN0QXJiVGltZUJ5VXNlcgEFBGFkZHIAAAUOYXJiaXRyYWdlRGVsYXkDCQBmAgUOYXJiUmVsZWFzZVRpbWUFA25vdwkAAgEJAKwCAgI/WW91ciBzdGFrZWQgbGFuZHMgdG9vayBwYXJ0IGluIGFyYml0cmFnZSwgY2Fubm90IHVuc3Rha2UgdW50aWwgCQCkAwEFDmFyYlJlbGVhc2VUaW1lBAlwaWVjZXNLZXkJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUEYWRkcgQMc3Rha2VkUGllY2VzCQELdmFsdWVPckVsc2UCCQCfCAEFCXBpZWNlc0tleQAABAluZXdQaWVjZXMDCQBmAgUGcGllY2VzBQxzdGFrZWRQaWVjZXMAAAkAZQIFDHN0YWtlZFBpZWNlcwUGcGllY2VzBAl3bGdSZXN1bHQJAPwHBAULd2xnQ29udHJhY3QCEm9uU3Rha2VVbnN0YWtlTGFuZAkAzAgCBQRhZGRyBQNuaWwFA25pbAkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgABCQDZBAEFC2xhbmRBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUEYWRkcgkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5UmVzUHJvcG9ydGlvbnMABQVwcm9wcwkAzAgCCQELU3RyaW5nRW50cnkCBQxyZXNCeUNvbnRLZXkFEHVwZGF0ZWRDb250UHJvcHMJAMwIAgkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al8yCQC5CQIIBQtjbGFpbVJlc3VsdAJfMwIBOgkAzAgCAwkAZgIJAJADAQUFbGFuZHMAAQkBC1N0cmluZ0VudHJ5AgUIbGFuZHNLZXkJALsJAgkA0QgCBQVsYW5kcwkBBXZhbHVlAQUDaWR4AgFfCQELRGVsZXRlRW50cnkBBQhsYW5kc0tleQkAzAgCCQEMSW50ZWdlckVudHJ5AgUJcGllY2VzS2V5BQluZXdQaWVjZXMJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwFCXdsZ1Jlc3VsdAFpAQlzdGFrZUR1Y2sABAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkRVQ0tQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMDCQECIT0CCAUFYXNzZXQGaXNzdWVyBQ1pbmN1YmF0b3JBZGRyCQECIT0CCAUFYXNzZXQGaXNzdWVyBQticmVlZGVyQWRkcgcJAAIBCQCsAgIJAKwCAgISVW5rbm93biBpc3N1ZXIgb2YgBQpEVUNLUFJFRklYAgYgdG9rZW4DCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpEVUNLUFJFRklYCQACAQkArAICCQCsAgICCU9ubHkgTkZUIAUKRFVDS1BSRUZJWAIUIHRva2VucyBhcmUgYWNjZXB0ZWQECmFzc2V0SWRTdHIJANgEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQphc3NldElkU3RyAwkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQISIGlzIGFscmVhZHkgc3Rha2VkAwkBCWlzRGVmaW5lZAEJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwkAAgEJAKwCAgIdWW91IGFscmVhZHkgc3Rha2VkIG9uZSBkdWNrOiAIBQVhc3NldARuYW1lBAZsb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQphc3NldElkU3RyBAhsb2NhdGlvbgkAoggBBQZsb2NLZXkEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQphc3NldElkU3RyBAhiYWNrcGFjawkAoggBBQVicEtleQQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFCmFzc2V0SWRTdHIEBW1heEhQCQEJbWF4SGVhbHRoAQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEMa2V5RHVja0xldmVsAQUKYXNzZXRJZFN0cgAABAljdXJIZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoBQVtYXhIUAkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd0aW1lS2V5CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpEVUNLUFJFRklYCQDYBAEFB2Fzc2V0SWQFB2FkZHJlc3MIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBrZXlEdWNrSWRUb093bmVyAQUKYXNzZXRJZFN0cgUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzBQphc3NldElkU3RyBQNuaWwDCQEJaXNEZWZpbmVkAQUIbG9jYXRpb24FA25pbAkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBmxvY0tleQUPREVGQVVMVExPQ0FUSU9OBQNuaWwDCQEJaXNEZWZpbmVkAQUIYmFja3BhY2sFA25pbAkAzQgCCQDNCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkCGjA6MF8wXzBfMF8wXzA6MF8wXzBfMF8wXzA6BQNuaWwJAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgFCWN1ckhlYWx0aAUMcHJvbG9nQWN0aW9uAWkBC3Vuc3Rha2VEdWNrAQphc3NldElkU3RyBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEBWFzc2V0CQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUKYXNzZXRJZFN0cgMJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQDCQEBIQEJAQlpc0RlZmluZWQBCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MJAAIBCQCsAgIJAKwCAgIJVGhlIGR1Y2sgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBEGtleUR1Y2tJZFRvT3duZXIBBQphc3NldElkU3RyCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQdhZGRyZXNzCQACAQIXU3Rha2VkIE5GVCBpcyBub3QgeW91cnMDCQEPY2hlY2tUb3VybmFtZW50AQUKYXNzZXRJZFN0cgkAAgECG3Vuc3Rha2VEdWNrX2NoZWNrVG91cm5hbWVudAMJAQ1jaGVja0RlbGl2ZXJ5AQUKYXNzZXRJZFN0cgkAAgECGXVuc3Rha2VEdWNrX2NoZWNrRGVsaXZlcnkECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQphc3NldElkU3RyBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFCmFzc2V0SWRTdHIAAAQGaGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFADCQBmAgUFbWF4SFAFBmhlYWx0aAkAAgEJAKwCAgkArAICAhlQbGVhc2UgaGVhbCB5b3VyIGR1Y2sgdG8gCQCkAwEFBW1heEhQAhNocCBiZWZvcmUgdW5zdGFraW5nCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgABBQdhc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEFB3RpbWVLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUJa2V5SGVhbHRoCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ9rZXlEdWNrTG9jYXRpb24BBQphc3NldElkU3RyCQDMCAIJAQtEZWxldGVFbnRyeQEJARBrZXlEdWNrSWRUb093bmVyAQUKYXNzZXRJZFN0cgkAzAgCCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkRVQ0tQUkVGSVgFCmFzc2V0SWRTdHIFB2FkZHJlc3MJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAFpAQhjbGFpbVJlcwIGYW1vdW50DmxhbmRBc3NldElkU3RyBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAZyZXN1bHQJARBjbGFpbVJlc0ludGVybmFsBAUEYWRkcgUGYW1vdW50BQ1jbGFpbU1vZGVEdWNrBQ5sYW5kQXNzZXRJZFN0cgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkCQCUCgIJAM0IAgkAzQgCCQDNCAIJAM4IAggFBnJlc3VsdAJfMQgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkCQBrAwUHeHBDbGFpbQUGYW1vdW50BQVNVUxUOAJfMQkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfMgkAuQkCCAUGcmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAUGcmVzdWx0Al80CQC5CQIIBQZyZXN1bHQCXzUCAToFDHByb2xvZ0FjdGlvbgkAkQMCCAUGcmVzdWx0Al8zBQhicElkeFJlcwFpAQxjbGFpbVJlc1RvV0gCBmFtb3VudA5sYW5kQXNzZXRJZFN0cgQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQGcmVzdWx0CQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFBmFtb3VudAULY2xhaW1Nb2RlV2gFDmxhbmRBc3NldElkU3RyCQCUCgIJAM0IAgkAzQgCCQDNCAIJAM4IAggFBnJlc3VsdAJfMQgJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgkAawMFB3hwQ2xhaW0FBmFtb3VudAUFTVVMVDgCXzEJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzIJALkJAggFBnJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfNAkAuQkCCAUGcmVzdWx0Al81AgE6BQxwcm9sb2dBY3Rpb24JAJEDAggFBnJlc3VsdAJfNQUId2hJZHhSZXMBaQEGZmxpZ2h0AgdtZXNzYWdlA3NpZwQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAh1c2VyQWRkcgkApQgBCAUBaQZjYWxsZXIEAWYJAQxmbGlnaHRDb21tb24DBQh1c2VyQWRkcgUHbWVzc2FnZQUDc2lnBAVuZXdIUAgFAWYCXzEEC2R1Y2tBc3NldElkCAUBZgJfMgQGbG9jS2V5CQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCiCAEFBmxvY0tleQUPREVGQVVMVExPQ0FUSU9OBAtuZXdMb2NhdGlvbggFAWYCXzQDCQAAAgULbmV3TG9jYXRpb24FC2N1ckxvY2F0aW9uCQACAQIiWW91IGNhbid0IGZseSB0byB0aGUgc2FtZSBsb2NhdGlvbgQGbmV3TG9jCQC1CQIFC25ld0xvY2F0aW9uAgFfBAZpc1RvdXIJAAACCQCRAwIFBm5ld0xvYwUKbG9jSWR4VHlwZQIBVAQFZXFLZXkJARBrZXlEdWNrRXF1aXBtZW50AQULZHVja0Fzc2V0SWQECWN1cnJlbnRFcQkBC3ZhbHVlT3JFbHNlAgkAoggBBQVlcUtleQIXLDssXyw7LF8sOyxfLDssXyw7LF8sOywEDSR0MDY2ODEzNjY5MTAJARFzdWJ0cmFjdEVxdWlwbWVudAIFCWN1cnJlbnRFcQgFAWYCXzUEBW5ld0VxCAUNJHQwNjY4MTM2NjkxMAJfMQQPc2hvdWxkWmVyb0J1ZmZzCAUNJHQwNjY4MTM2NjkxMAJfMgQJbG9jVG9TYXZlAwkBASEBCQEOaXNJblRvdXJuYW1lbnQCBRJ0b3VybmFtZW50Q29udHJhY3QFC2N1ckxvY2F0aW9uAwUGaXNUb3VyCQACAQkArAICCQCsAgIJAKwCAgIWQ2hlYXQgYXR0ZW1wdDogb2xkTG9jPQULY3VyTG9jYXRpb24CCSwgbmV3TG9jPQULbmV3TG9jYXRpb24DCQBmAgUFbmV3SFAAAAULbmV3TG9jYXRpb24FC2N1ckxvY2F0aW9uAwkBASEBCQEOaXNJblRvdXJuYW1lbnQCBRJ0b3VybmFtZW50Q29udHJhY3QFC25ld0xvY2F0aW9uCQACAQIqWW91ciBkdWNrIGlzIHRha2luZyBwYXJ0IGluIHRoZSB0b3VybmFtZW50BAVzY29yZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBm5ld0xvYwUIbG9jSWR4SWQEBmN1ckxvYwkAtQkCBQtjdXJMb2NhdGlvbgIBXwQGbGFzdElkCQELdmFsdWVPckVsc2UCCQCaCAIFEnRvdXJuYW1lbnRDb250cmFjdAUNbGFzdFRvdXJJZEtleQAAAwkBAiE9AgUFc2NvcmUJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGY3VyTG9jBQhsb2NJZHhJZAABCQACAQkArAICCQCsAgIJAKwCAgIWQ2hlYXQgYXR0ZW1wdDogb2xkTG9jPQULY3VyTG9jYXRpb24CCSwgbmV3TG9jPQULbmV3TG9jYXRpb24DCQBmAgUFbmV3SFAAAAQJbG9jYWxCZXN0CQELdmFsdWVPckVsc2UCCQCaCAIFEnRvdXJuYW1lbnRDb250cmFjdAkBGmtleUJlc3RSZXN1bHRCeVRvdXJBbmREdWNrAgUGbGFzdElkBQtkdWNrQXNzZXRJZAAABAh1cGRMb2NhbAMJAGYCBQVzY29yZQUJbG9jYWxCZXN0CQD8BwQFEnRvdXJuYW1lbnRDb250cmFjdAIOc2F2ZUR1Y2tSZXN1bHQJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUFc2NvcmUFA25pbAUDbmlsBQR1bml0AwkAAAIFCHVwZExvY2FsBQh1cGRMb2NhbAULbmV3TG9jYXRpb24JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FC2N1ckxvY2F0aW9uCQCUCgIJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQZsb2NLZXkFCWxvY1RvU2F2ZQkAzAgCCQELU3RyaW5nRW50cnkCBQVlcUtleQUFbmV3RXEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQFBW5ld0hQCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsAwUPc2hvdWxkWmVyb0J1ZmZzCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxrZXlEdWNrQnVmZnMBBQtkdWNrQXNzZXRJZAIJMF8wXzBfMF8wBQNuaWwJAM4IAgUDbmlsCAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQDCQBmAgUFbmV3SFAAAAUPeHBTdWNjZXNzRmxpZ2h0BQx4cEZhaWxGbGlnaHQCXzEIBQFmAl8zAWkBBGhlYWwDCnF1YW50aXR5TDEKcXVhbnRpdHlMMgpxdWFudGl0eUwzBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwMDCQBmAgAABQpxdWFudGl0eUwxBgkAZgIAAAUKcXVhbnRpdHlMMgYJAGYCAAAFCnF1YW50aXR5TDMJAAIBAhtRdWFudGl0eSBjYW5ub3QgYmUgbmVnYXRpdmUEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQDCQEPY2hlY2tUb3VybmFtZW50AQULZHVja0Fzc2V0SWQJAAIBAhRoZWFsX2NoZWNrVG91cm5hbWVudAMJAQ1jaGVja0RlbGl2ZXJ5AQULZHVja0Fzc2V0SWQJAAIBAhJoZWFsX2NoZWNrRGVsaXZlcnkEA3F0cwkAzAgCBQpxdWFudGl0eUwxCQDMCAIFCnF1YW50aXR5TDIJAMwIAgUKcXVhbnRpdHlMMwUDbmlsBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEBW1heEhQCQEJbWF4SGVhbHRoAQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEMa2V5RHVja0xldmVsAQULZHVja0Fzc2V0SWQAAAQJb2xkSGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFADCQBnAgUJb2xkSGVhbHRoBQVtYXhIUAkAAgEJAKwCAgkArAICAg9IUCBzaG91bGQgYmUgPCAJAKQDAQUFbWF4SFACCCB0byBoZWFsBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQIcHJvZExpc3QDCQAAAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAV8KAQtpdGVyYXRlUHJvZAIDYWNjBnJlY2lwZQQBbggFA2FjYwJfMgQBeAMJAGYCCQCQAwEFCHByb2RMaXN0BQFuCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvZExpc3QFAW4AAAMJAGYCAAMFAW4EAXEJAJEDAgUDcXRzBQFuAwkAZgIFAXEFAXgJAAIBCQCsAgIJAKwCAgkArAICAg5Zb3UgaGF2ZSBvbmx5IAkApAMBBQF4AgQgb2YgCQCRAwIFCXByb2RUeXBlcwUBbgkAlQoDCQDNCAIIBQNhY2MCXzEJAKQDAQkAZQIFAXgFAXEJAGQCBQFuAAEJAGQCCAUDYWNjAl8zCQBoAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgUGcmVjaXBlAgFfBQpySWR4RWZmZWN0BQFxCQCVCgMJAM0IAggFA2FjYwJfMQkApAMBBQF4CQBkAgUBbgABCAUDYWNjAl8zBAZyZXN1bHQKAAIkbAUQcHJvZHVjdGlvbk1hdHJpeAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJUKAwUDbmlsAAAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQELaXRlcmF0ZVByb2QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgQJbmV3SGVhbHRoCQCXAwEJAMwIAgUFbWF4SFAJAMwIAgkAZAIFCW9sZEhlYWx0aAgFBnJlc3VsdAJfMwUDbmlsCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQluZXdIZWFsdGgJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALoJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0CQDMCAIJALkJAggFBnJlc3VsdAJfMQIBXwUDbmlsAgE6CQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsCAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQJAGgCBQZ4cEhlYWwJAGQCCQBkAgUKcXVhbnRpdHlMMQUKcXVhbnRpdHlMMgUKcXVhbnRpdHlMMwJfMQUJbmV3SGVhbHRoAWkBBmhlYWxFUwAEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhpBbGxvd2VkIFVTRFQgcGF5bWVudCBvbmx5IQQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAMJAQ9jaGVja1RvdXJuYW1lbnQBBQtkdWNrQXNzZXRJZAkAAgECFmhlYWxFU19jaGVja1RvdXJuYW1lbnQDCQENY2hlY2tEZWxpdmVyeQEFC2R1Y2tBc3NldElkCQACAQIUaGVhbEVTX2NoZWNrRGVsaXZlcnkECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQFbWF4SFAJAQltYXhIZWFsdGgBCQELdmFsdWVPckVsc2UCCQCfCAEJAQxrZXlEdWNrTGV2ZWwBBQtkdWNrQXNzZXRJZAAABAlvbGRIZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoBQVtYXhIUAMJAGYCBQlvbGRIZWFsdGgAAAkAAgECKEhQIHNob3VsZCBiZSAwIHRvIGNhbGwgRW1lcmdlbmN5IFNlcnZpY2UEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAhwcm9kTGlzdAMJAAACCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIBXwQNbWVkS2l0QW1vdW50MQMJAGYCCQCQAwEFCHByb2RMaXN0AAAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhwcm9kTGlzdAAAAAAEDW1lZEtpdEFtb3VudDIDCQBmAgkAkAMBBQhwcm9kTGlzdAABCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvZExpc3QAAQAABA1tZWRLaXRBbW91bnQzAwkAZgIJAJADAQUIcHJvZExpc3QAAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHByb2RMaXN0AAIAAAMDAwkAZgIFDW1lZEtpdEFtb3VudDEAAAYJAGYCBQ1tZWRLaXRBbW91bnQyAAAGCQBmAgUNbWVkS2l0QW1vdW50MwAACQACAQIfWW91IGhhdmUgdG8gdXNlIG93biBNZWRpY2FsIEtpdAQIZXhpc3RTdHIJAJ0IAgUPZWNvbm9teUNvbnRyYWN0CQEOa2V5RXNXYXJlaG91c2UABAxleGlzdEFtb3VudHMDCQEJaXNEZWZpbmVkAQUIZXhpc3RTdHIJALwJAgkBBXZhbHVlAQUIZXhpc3RTdHICAV8FA25pbAQLZXhpc3RBbW91bnQDCQBmAgkAkAMBBQxleGlzdEFtb3VudHMAAAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDGV4aXN0QW1vdW50cwAAAAADCQBnAgAABQtleGlzdEFtb3VudAkAAgECOVRoZXJlIGFyZSBubyBNZWRpY2FsIEtpdHMgTDEgYXQgRW1lcmdlbmN5IFNlcnZpY2Ugc3RvcmFnZQQJbmV3SGVhbHRoCQBkAgUJb2xkSGVhbHRoCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgAAAIBXwUKcklkeEVmZmVjdAQFbmV3RVMJALkJAgkAzAgCCQCkAwEJAGUCBQtleGlzdEFtb3VudAABCQDRCAIFDGV4aXN0QW1vdW50cwAAAgFfBAZyZWNpcGUJALUJAgkAkQMCBRBwcm9kdWN0aW9uTWF0cml4AAACAV8ECHRvdGFsTWF0CQESZ2V0UmVjaXBlTWF0ZXJpYWxzAQUGcmVjaXBlBAlzZWxsUHJpY2UJAGsDCQBoAgUIdG90YWxNYXQFCkVTU0VMTENPRUYFEFJFU09VUkNFUFJJQ0VNSU4JAGgCBQVNVUxUOAUOUFJPRFVDVFBLR1NJWkUDCQECIT0CCAUDcG10BmFtb3VudAUJc2VsbFByaWNlCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUJc2VsbFByaWNlBAZyZXN1bHQJAQhhc1N0cmluZwEJAPwHBAUPZWNvbm9teUNvbnRyYWN0Ag91cGRhdGVFc1N0b3JhZ2UJAMwIAgUFbmV3RVMFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgULdXNkdEFzc2V0SWQFCXNlbGxQcmljZQUDbmlsCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQluZXdIZWFsdGgJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwICQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQtkdWNrQXNzZXRJZAUIeHBDYWxsRVMCXzEFBnJlc3VsdAFpAQ51cGRhdGVCYWNrcGFjawILZHVja0Fzc2V0SWQHbmV3UGFjawMJAQIhPQIIBQFpBmNhbGxlcgUPZWNvbm9teUNvbnRyYWN0CQACAQIRcGVybWlzc2lvbiBkZW5pZWQJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAUHbmV3UGFjawUDbmlsBQduZXdQYWNrAWkBD2NvbW1pdEZvclJhbmRvbQAEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkEC2ZpbmlzaEJsb2NrCQBkAgUGaGVpZ2h0BQtyYW5kb21EZWxheQQEYWRkcgkApQgBCAUBaQZjYWxsZXIJAJQKAgkAzQgCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEJa2V5Q29tbWl0AQUEYWRkcgULZmluaXNoQmxvY2sFA25pbAUMcHJvbG9nQWN0aW9uBQtmaW5pc2hCbG9jawFpAQphd2FyZFNMYW5kAQdhZGRyZXNzAwkBAiE9AggFAWkGY2FsbGVyBRJ0b3VybmFtZW50Q29udHJhY3QJAAIBAg1BY2Nlc3MgZGVuaWVkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBnJlc3VsdAkBEmV4cGVkaXRpb25JbnRlcm5hbAIJARFAZXh0ck5hdGl2ZSgxMDYyKQEFB2FkZHJlc3MIBQFpDXRyYW5zYWN0aW9uSWQJAJQKAggFBnJlc3VsdAJfMQgIBQZyZXN1bHQCXzICXzEBaQEIYnV5U0xhbmQABAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQIaQWxsb3dlZCBVU0RUIHBheW1lbnQgb25seSEDCQECIT0CCAUDcG10BmFtb3VudAUHRVhQVVNEVAkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFB0VYUFVTRFQEBnJlc3VsdAkBEmV4cGVkaXRpb25JbnRlcm5hbAIIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAQLYWNyZXNSZXN1bHQJAQVhc0ludAEJAPwHBAUNYWNyZXNDb250cmFjdAIJYnVybkFjcmVzCQDMCAIFDFNfQ09TVF9BQ1JFUwUDbmlsBQNuaWwJAJQKAgkAzQgCCQDOCAIJAM0IAggFBnJlc3VsdAJfMQkBDlNjcmlwdFRyYW5zZmVyAwUPZWNvbm9teUNvbnRyYWN0CAUDcG10BmFtb3VudAULdXNkdEFzc2V0SWQICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIJAKUIAQgFAWkGY2FsbGVyBQp4cE5ld1NMYW5kAl8xBQxwcm9sb2dBY3Rpb24JAJQKAggIBQZyZXN1bHQCXzICXzEFC2FjcmVzUmVzdWx0AWkBCmV4cGVkaXRpb24CB21lc3NhZ2UDc2lnBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQECHVzZXJBZGRyCQClCAEIBQFpBmNhbGxlcgQBZgkBDGZsaWdodENvbW1vbgMFCHVzZXJBZGRyBQdtZXNzYWdlBQNzaWcEC2R1Y2tBc3NldElkCAUBZgJfMgQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQFbUxpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8EBm5ld01hdAkAuQkCCQERc3VidHJhY3RNYXRlcmlhbHMDBgUFbUxpc3QFDEVYUE1BVEVSSUFMUwIBXwQFZXFLZXkJARBrZXlEdWNrRXF1aXBtZW50AQULZHVja0Fzc2V0SWQECWN1cnJlbnRFcQkBC3ZhbHVlT3JFbHNlAgkAoggBBQVlcUtleQIXLDssXyw7LF8sOyxfLDssXyw7LF8sOywEDSR0MDc1ODM4NzU5MzUJARFzdWJ0cmFjdEVxdWlwbWVudAIFCWN1cnJlbnRFcQgFAWYCXzUEBW5ld0VxCAUNJHQwNzU4Mzg3NTkzNQJfMQQPc2hvdWxkWmVyb0J1ZmZzCAUNJHQwNzU4Mzg3NTkzNQJfMgQBZQkBEmV4cGVkaXRpb25JbnRlcm5hbAIIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAQCaWQICAUBZQJfMgJfMQQGcmVzdWx0AwkAZwIAAAgFAWYCXzEJAJUKAwkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoAAAJAMwIAgkBC1N0cmluZ0VudHJ5AgUFZXFLZXkFBW5ld0VxBQNuaWwCAAAACQCVCgMJAM4IAggFAWUCXzEDBQ9zaG91bGRaZXJvQnVmZnMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDGtleUR1Y2tCdWZmcwEFC2R1Y2tBc3NldElkAgkwXzBfMF8wXzAFA25pbAkAzQgCCQDNCAIJAM0IAgkAzQgCBQNuaWwJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAuQkCCQDMCAIICAUBZQJfMgJfMgkAzAgCAgFMCQDMCAIFAmlkBQNuaWwCAV8JAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgIBQFmAl8xCQELU3RyaW5nRW50cnkCBQVlcUtleQUFbmV3RXEJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCBQZuZXdNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToFAmlkCAUBZgJfMwMJAQ9jaGVja1RvdXJuYW1lbnQBBQtkdWNrQXNzZXRJZAkAAgECGmV4cGVkaXRpb25fY2hlY2tUb3VybmFtZW50AwkBDWNoZWNrRGVsaXZlcnkBBQtkdWNrQXNzZXRJZAkAAgECGGV4cGVkaXRpb25fY2hlY2tEZWxpdmVyeQQLYWNyZXNSZXN1bHQJAQVhc0ludAEJAPwHBAUNYWNyZXNDb250cmFjdAIJYnVybkFjcmVzCQDMCAIFDFNfQ09TVF9BQ1JFUwUDbmlsBQNuaWwJAJQKAgkAzQgCCQDOCAIIBQZyZXN1bHQCXzEICQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQtkdWNrQXNzZXRJZAUKeHBOZXdTTGFuZAJfMQUMcHJvbG9nQWN0aW9uCQCVCgMIBQZyZXN1bHQCXzIIBQZyZXN1bHQCXzMFC2FjcmVzUmVzdWx0AWkBEGJ1eVNMYW5kRm9yQWNyZXMABAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEA2FtdAgFA3BtdAZhbW91bnQDAwkBASEBCQEJaXNEZWZpbmVkAQgFA3BtdAdhc3NldElkBgkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQxhY3Jlc0Fzc2V0SWQJAAIBAhRBQ1JFUyBwYXltZW50cyBvbmx5IQMJAQIhPQIFA2FtdAUMU19DT1NUX0FDUkVTCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUMU19DT1NUX0FDUkVTBAZyZXN1bHQJARJleHBlZGl0aW9uSW50ZXJuYWwCCAUBaQZjYWxsZXIIBQFpDXRyYW5zYWN0aW9uSWQEC2FjcmVzUmVzdWx0CQEFYXNJbnQBCQD8BwQFDWFjcmVzQ29udHJhY3QCCWJ1cm5BY3JlcwkAzAgCBQxTX0NPU1RfQUNSRVMFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUMYWNyZXNBc3NldElkBQNhbXQFA25pbAkAlAoCCQDNCAIJAM4IAgkAzQgCCAUGcmVzdWx0Al8xCQEOU2NyaXB0VHJhbnNmZXIDBQ9lY29ub215Q29udHJhY3QIBQNwbXQGYW1vdW50BQt1c2R0QXNzZXRJZAgJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgkApQgBCAUBaQZjYWxsZXIFCnhwTmV3U0xhbmQCXzEFDHByb2xvZ0FjdGlvbgkAlAoCCAgFBnJlc3VsdAJfMgJfMQULYWNyZXNSZXN1bHQBaQEMdXBncmFkZUluZnJhAQtsYW5kQXNzZXRJZAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAZyZXN1bHQJAQ11cEluZnJhQ29tbW9uBAYIBQFpBmNhbGxlcgAABQtsYW5kQXNzZXRJZAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAkAlAoCCQDOCAIJAM0IAggFBnJlc3VsdAJfMQUMcHJvbG9nQWN0aW9uCAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQJAGsDBQ54cFVwZ3JhZGVJbmZyYQgFBnJlc3VsdAJfMwUFTVVMVDgCXzEIBQZyZXN1bHQCXzIBaQEQYWN0aXZhdGVBcnRpZmFjdAIHYXJ0TmFtZQ5sYW5kQXNzZXRJZE9wdAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpBmNhbGxlcgQGcmVzdWx0BAckbWF0Y2gwBQdhcnROYW1lAwkAAAICB1BSRVNBTEUFByRtYXRjaDAJARJhY3RpdmF0ZVByZXNhbGVBcnQCBQRhZGRyBQ5sYW5kQXNzZXRJZE9wdAMJAAACAgdPTkJPQVJEBQckbWF0Y2gwCQESYWN0aXZhdGVPbmJvYXJkQXJ0AQUEYWRkcgkAAgECEFVua25vd24gYXJ0aWZhY3QJAM0IAgUGcmVzdWx0BQxwcm9sb2dBY3Rpb24BaQEKbWVyZ2VMYW5kcwEMbGFuZEFzc2V0SWRzBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBnJlc3VsdAkBC21lcmdlQ29tbW9uAgkApQgBCAUBaQZjYWxsZXIFDGxhbmRBc3NldElkcwkAlAoCCQDOCAIJAM0IAggFBnJlc3VsdAJfMQUMcHJvbG9nQWN0aW9uCAkBFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwCCQClCAEIBQFpBmNhbGxlcgUHeHBNZXJnZQJfMQgFBnJlc3VsdAJfMgFpAQ1jYXJnb0V4Y2hhbmdlAgxjYXJnb0xpc3RTdHILbGFuZEFzc2V0SWQEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQKY2FyZ29QYXJ0cwkAvAkCBQxjYXJnb0xpc3RTdHICAToEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwULcmVjTGFuZFNpemUFBVNTSVpFBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMAwkBAiE9AgkAkQMCBQNsb2MFCGxvY0lkeElkBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgIbRHVjayBzaG91bGQgYmUgb24gdGhlIGxhbmQgBQtsYW5kQXNzZXRJZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQJY3VycmVudFdoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBnJlc3VsdAkBCW1vdmVTdHVmZgMFCmNhcmdvUGFydHMFCWN1cnJlbnRXaAULY3VycmVudFBhY2sEBGxvZnQJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAIBXwQFbG9mdE8JAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQIBQZyZXN1bHQCXzcEBWxvZnRGCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUIBQZyZXN1bHQCXzcJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALoJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIIBQZyZXN1bHQCXzQJAMwIAggFBnJlc3VsdAJfNQkAzAgCCAUGcmVzdWx0Al82BQNuaWwCAToJAMwIAgkBC1N0cmluZ0VudHJ5AgUFd2hLZXkJALoJAgkAzAgCCQCRAwIFCWN1cnJlbnRXaAULd2hJZHhMZXZlbHMJAMwIAggFBnJlc3VsdAJfMQkAzAgCCAUGcmVzdWx0Al8yCQDMCAIIBQZyZXN1bHQCXzMJAMwIAgkAuQkCCQDMCAIJAJEDAgUEbG9mdAUJdm9sTG9ja2VkCQDMCAIJAKQDAQUFbG9mdE8JAMwIAgkApAMBBQVsb2Z0RgkAzAgCCQCRAwIFBGxvZnQFCHZvbFRvdGFsBQNuaWwCAV8FA25pbAIBOgkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAFpAQ1zYXZlV2FyZWhvdXNlAgV3aFN0cgtsYW5kQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUPZWNvbm9teUNvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQCd2gJALwJAgUFd2hTdHICAToDCQECIT0CCQCQAwEFAndoAAUJAAIBAjB3YXJlaG91c2Ugc3RyaW5nIHNob3VsZCBjb250YWluIDQgJzonIHNlcGFyYXRvcnMEBWxvZnRMCQCRAwIJALUJAgkAkQMCBQJ3aAUJd2hJZHhMT0ZUAgFfBQl2b2xMb2NrZWQEBWxvZnRPCQEXZ2V0V2FyZWhvdXNlT2NjdXBpZWRWb2wBBQJ3aAQFbG9mdFQJARdnZXRXYXJlaG91c2VUb3RhbFZvbHVtZQEJAJEDAgUCd2gFC3doSWR4TGV2ZWxzBAVsb2Z0RgkAZQIJAGUCBQVsb2Z0VAkBDXBhcnNlSW50VmFsdWUBBQVsb2Z0TAUFbG9mdE8ECG5ld1doU3RyCQC6CQIJAMwIAgkAkQMCBQJ3aAULd2hJZHhMZXZlbHMJAMwIAgkAkQMCBQJ3aAUId2hJZHhSZXMJAMwIAgkAkQMCBQJ3aAUId2hJZHhNYXQJAMwIAgkAkQMCBQJ3aAUJd2hJZHhQcm9kCQDMCAIJALkJAgkAzAgCBQVsb2Z0TAkAzAgCCQCkAwEFBWxvZnRPCQDMCAIJAKQDAQUFbG9mdEYJAMwIAgkApAMBBQVsb2Z0VAUDbmlsAgFfBQNuaWwCAToJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQV3aEtleQUIbmV3V2hTdHIFA25pbAUIbmV3V2hTdHIBaQESZml4V2FyZWhvdXNlRm9ybWF0AQtsYW5kQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUMcmVzdENvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQJbGFuZEluZGV4CQBpAgkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8FC3JlY0xhbmRTaXplBQVTU0laRQQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAEAndoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQFbG9mdEwJAQVhc0ludAEJAPwHBAUPZWNvbm9teUNvbnRyYWN0AhpyZWNhbGNMb2NrZWRWb2x1bWVSRUFET05MWQkAzAgCBQtsYW5kQXNzZXRJZAkAzAgCBQJ3aAUDbmlsBQNuaWwEBWxvZnRPCQEXZ2V0V2FyZWhvdXNlT2NjdXBpZWRWb2wBBQJ3aAQFbG9mdFQJARdnZXRXYXJlaG91c2VUb3RhbFZvbHVtZQEJAJEDAgUCd2gFC3doSWR4TGV2ZWxzBAVsb2Z0RgkAZQIJAGUCBQVsb2Z0VAUFbG9mdEwFBWxvZnRPBAhuZXdXaFN0cgkAugkCCQDMCAIJAJEDAgUCd2gFC3doSWR4TGV2ZWxzCQDMCAIJAJEDAgUCd2gFCHdoSWR4UmVzCQDMCAIJAJEDAgUCd2gFCHdoSWR4TWF0CQDMCAIJAJEDAgUCd2gFCXdoSWR4UHJvZAkAzAgCCQC5CQIJAMwIAgkApAMBBQVsb2Z0TAkAzAgCCQCkAwEFBWxvZnRPCQDMCAIJAKQDAQUFbG9mdEYJAMwIAgkApAMBBQVsb2Z0VAUDbmlsAgFfBQNuaWwCAToJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQV3aEtleQUIbmV3V2hTdHIFA25pbAUIbmV3V2hTdHIBaQEXZml4Q29udGluZW50UHJvcG9ydGlvbnMBDGxhbmRBc3NldElkcwMJAQIhPQIIBQFpBmNhbGxlcgUMcmVzdENvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAoBCGdldFByb3BzAgNhY2MEY29udAkAzQgCBQNhY2MJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBFmtleVJlc1R5cGVzQnlDb250aW5lbnQBBQRjb250AgswXzBfMF8wXzBfMAQBcAoAAiRsBQpjb250aW5lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhnZXRQcm9wcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUKAQlwcm9jZXNzb3ICA2FjYwtsYW5kQXNzZXRJZAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8ECWxhbmRJbmRleAkAaQIJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIFAWQFC3JlY0xhbmRTaXplBQVTU0laRQQEY29udAkAkQMCBQFkBQxyZWNDb250aW5lbnQEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQMY29udGluZW50SWR4CQEFdmFsdWUBCQDPCAIFCmNvbnRpbmVudHMFBGNvbnQECWNvbnRQcm9wcwkAtQkCCQCRAwIFA2FjYwUMY29udGluZW50SWR4AgFfBAd1cGRhdGVkCQC5CQIJARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAUJY29udFByb3BzBQ10ZXJyYWluQ291bnRzBQlsYW5kSW5kZXgAAQIBXwQHJG1hdGNoMAUEY29udAMJAAACAghBbWVyaWNhcwUHJG1hdGNoMAkAzAgCBQd1cGRhdGVkCQDMCAIJAJEDAgUDYWNjAAEJAMwIAgkAkQMCBQNhY2MAAgkAzAgCCQCRAwIFA2FjYwADCQDMCAIJAJEDAgUDYWNjAAQFA25pbAMJAAACAgZFdXJvcGUFByRtYXRjaDAJAMwIAgkAkQMCBQNhY2MAAAkAzAgCBQd1cGRhdGVkCQDMCAIJAJEDAgUDYWNjAAIJAMwIAgkAkQMCBQNhY2MAAwkAzAgCCQCRAwIFA2FjYwAEBQNuaWwDCQAAAgIEQXNpYQUHJG1hdGNoMAkAzAgCCQCRAwIFA2FjYwAACQDMCAIJAJEDAgUDYWNjAAEJAMwIAgUHdXBkYXRlZAkAzAgCCQCRAwIFA2FjYwADCQDMCAIJAJEDAgUDYWNjAAQFA25pbAMJAAACAgZBZnJpY2EFByRtYXRjaDAJAMwIAgkAkQMCBQNhY2MAAAkAzAgCCQCRAwIFA2FjYwABCQDMCAIJAJEDAgUDYWNjAAIJAMwIAgUHdXBkYXRlZAkAzAgCCQCRAwIFA2FjYwAEBQNuaWwDCQAAAgIHT2NlYW5pYQUHJG1hdGNoMAkAzAgCCQCR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cGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQIaQWxsb3dlZCBVU0RUIHBheW1lbnQgb25seSEDCQECIT0CCAUDcG10BmFtb3VudAUMUkVOQU1JTkdDT1NUCQACAQkArAICAhJQYXltZW50IHNob3VsZCBiZSAJAKQDAQUMUkVOQU1JTkdDT1NUAwkBCGNvbnRhaW5zAgUKY3VzdG9tTmFtZQICX18JAAIBCQCsAgICHk5hbWUgc2hvdWxkIG5vdCBjb250YWluICdfXyc6IAUKY3VzdG9tTmFtZQMJAGYCCQCxAgEFCmN1c3RvbU5hbWUFCk1BWE5BTUVMRU4JAAIBCQCsAgICGU5hbWUgdG9vIGxvbmcsIG1heExlbmd0aD0JAKQDAQUKTUFYTkFNRUxFTgQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEB2FjdGlvbnMEByRtYXRjaDAFBHR5cGUDCQAAAgIHQUNDT1VOVAUHJG1hdGNoMAQKcmV2ZXJzZUtleQkBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBBQpjdXN0b21OYW1lBAluYW1lT3duZXIJAKIIAQUKcmV2ZXJzZUtleQMJAQlpc0RlZmluZWQBBQluYW1lT3duZXIJAAIBCQCsAgICGU5hbWUgYWxyZWFkeSByZWdpc3RlcmVkOiAFCmN1c3RvbU5hbWUEDWFkZHJUb05hbWVLZXkJARZrZXlBZGRyZXNzVG9DdXN0b21OYW1lAQUEYWRkcgQHb2xkTmFtZQkAoggBBQ1hZGRyVG9OYW1lS2V5BAdmcmVlT2xkAwkBCWlzRGVmaW5lZAEFB29sZE5hbWUJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBCQEFdmFsdWUBBQdvbGROYW1lBQNuaWwFA25pbAkAzggCCQDNCAIJAM0IAgUHZnJlZU9sZAkBC1N0cmluZ0VudHJ5AgUNYWRkclRvTmFtZUtleQUKY3VzdG9tTmFtZQkBC1N0cmluZ0VudHJ5AgUKcmV2ZXJzZUtleQUEYWRkcggJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgUMeHBDdXN0b21OYW1lAl8xAwkAAAICBExBTkQFByRtYXRjaDAEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQdhc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFB2Fzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMECnJldmVyc2VLZXkJARprZXlMYW5kQ3VzdG9tTmFtZVRvQXNzZXRJZAEFCmN1c3RvbU5hbWUECW5hbWVPd25lcgkAoggBBQpyZXZlcnNlS2V5AwkBCWlzRGVmaW5lZAEFCW5hbWVPd25lcgkAAgEJAKwCAgIZTmFtZSBhbHJlYWR5IHJlZ2lzdGVyZWQ6IAUKY3VzdG9tTmFtZQQOYXNzZXRUb05hbWVLZXkJARprZXlMYW5kQXNzZXRJZFRvQ3VzdG9tTmFtZQEFB2Fzc2V0SWQEB29sZE5hbWUJAKIIAQUOYXNzZXRUb05hbWVLZXkEB2ZyZWVPbGQDCQEJaXNEZWZpbmVkAQUHb2xkTmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBCQEFdmFsdWUBBQdvbGROYW1lBQNuaWwFA25pbAkAzggCCQDNCAIJAM0IAgUHZnJlZU9sZAkBC1N0cmluZ0VudHJ5AgUOYXNzZXRUb05hbWVLZXkFCmN1c3RvbU5hbWUJAQtTdHJpbmdFbnRyeQIFCnJldmVyc2VLZXkFB2Fzc2V0SWQICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIFBGFkZHIFDHhwQ3VzdG9tTmFtZQJfMQMJAAACAgREVUNLBQckbWF0Y2gwBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUHYXNzZXRJZAMDCQEBIQEJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkGCQEBIQEJAQlpc0RlZmluZWQBCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHIJAAIBCQCsAgIIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEQa2V5RHVja0lkVG9Pd25lcgEFB2Fzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkRVQ0tQUkVGSVgCDSBpcyBub3QgeW91cnMECnJldmVyc2VLZXkJARprZXlEdWNrQ3VzdG9tTmFtZVRvQXNzZXRJZAEFCmN1c3RvbU5hbWUECW5hbWVPd25lcgkAoggBBQpyZXZlcnNlS2V5AwkBCWlzRGVmaW5lZAEFCW5hbWVPd25lcgkAAgEJAKwCAgIZTmFtZSBhbHJlYWR5IHJlZ2lzdGVyZWQ6IAUKY3VzdG9tTmFtZQQOYXNzZXRUb05hbWVLZXkJARprZXlEdWNrQXNzZXRJZFRvQ3VzdG9tTmFtZQEFB2Fzc2V0SWQEB29sZE5hbWUJAKIIAQUOYXNzZXRUb05hbWVLZXkEB2ZyZWVPbGQDCQEJaXNEZWZpbmVkAQUHb2xkTmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBCQEFdmFsdWUBBQdvbGROYW1lBQNuaWwFA25pbAkAzggCCQDNCAIJAM0IAgUHZnJlZU9sZAkBC1N0cmluZ0VudHJ5AgUOYXNzZXRUb05hbWVLZXkFCmN1c3RvbU5hbWUJAQtTdHJpbmdFbnRyeQIFCnJldmVyc2VLZXkFB2Fzc2V0SWQICQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQdhc3NldElkBQx4cEN1c3RvbU5hbWUCXzEJAAIBAhNVbmtub3duIGVudGl0eSB0eXBlCQCUCgIJAM0IAgkAzQgCBQdhY3Rpb25zCQEOU2NyaXB0VHJhbnNmZXIDBQ9lY29ub215Q29udHJhY3QIBQNwbXQGYW1vdW50BQt1c2R0QXNzZXRJZAUMcHJvbG9nQWN0aW9uAAABaQEMc2V0UmVmZXJyYWxzAglvbGRQbGF5ZXIJbmV3UGxheWVyAwkBAiE9AggFAWkPY2FsbGVyUHVibGljS2V5BQNwdWIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkAwkBASEBCQEJaXNEZWZpbmVkAQkApggBBQlvbGRQbGF5ZXIJAAIBCQCsAgICEUludmFsaWQgYWRkcmVzczogBQlvbGRQbGF5ZXIDCQEBIQEJAQlpc0RlZmluZWQBCQCmCAEFCW5ld1BsYXllcgkAAgEJAKwCAgIRSW52YWxpZCBhZGRyZXNzOiAFCW5ld1BsYXllcgQHb2xkc0tleQkBCWtleU9sZGllcwAEBG9sZHMJAKIIAQUHb2xkc0tleQQGb2xkaWVzAwkBCWlzRGVmaW5lZAEFBG9sZHMJALwJAgkBBXZhbHVlAQUEb2xkcwIBXwUDbmlsAwkBD2NvbnRhaW5zRWxlbWVudAIFBm9sZGllcwUJbmV3UGxheWVyCQACAQkArAICBQluZXdQbGF5ZXICJiBpcyBub3QgbmV3YmllIChhbHJlYWR5IGhhcyByZWZlcnJhbHMpBAhyZWZCeUtleQkBD2tleUFkZHJlc3NSZWZCeQEFCW5ld1BsYXllcgQFcmVmQnkJAKIIAQUIcmVmQnlLZXkDAwkBCWlzRGVmaW5lZAEFBXJlZkJ5CQEJaXNEZWZpbmVkAQkApggBCQEFdmFsdWUBBQVyZWZCeQcJAAIBCQCsAgIJAKwCAgUJbmV3UGxheWVyAhQgYWxyZWFkeSBoYXMgcmVmQnk6IAkBBXZhbHVlAQUFcmVmQnkEB3JlZnNLZXkJARNrZXlBZGRyZXNzUmVmZXJyYWxzAQUJb2xkUGxheWVyBARyZWZzCQCiCAEFB3JlZnNLZXkECXJlZnNBcnJheQMJAQlpc0RlZmluZWQBBQRyZWZzCQC8CQIJAQV2YWx1ZQEFBHJlZnMCAV8FA25pbAMJAQ9jb250YWluc0VsZW1lbnQCBQlyZWZzQXJyYXkFCW5ld1BsYXllcgkAAgEJAKwCAgkArAICCQCsAgIFCW9sZFBsYXllcgISIGFscmVhZHkgY29udGFpbnMgBQluZXdQbGF5ZXICESB3aXRoaW4gcmVmZXJyYWxzBAduZXdSZWZzCQC6CQIJAM0IAgUJcmVmc0FycmF5BQluZXdQbGF5ZXICAV8EB25ld09sZHMDCQEPY29udGFpbnNFbGVtZW50AgUGb2xkaWVzBQlvbGRQbGF5ZXIJAQV2YWx1ZQEFBG9sZHMJALoJAgkAzQgCBQZvbGRpZXMFCW9sZFBsYXllcgIBXwkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFCHJlZkJ5S2V5BQlvbGRQbGF5ZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgUHcmVmc0tleQUHbmV3UmVmcwkAzAgCCQELU3RyaW5nRW50cnkCBQdvbGRzS2V5BQduZXdPbGRzCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsAAABaQEQZGlzdHJpYnV0ZVBvaW50cwUIc3RyZW5ndGgIYWNjdXJhY3kJaW50ZWxsZWN0CWVuZHVyYW5jZQlkZXh0ZXJpdHkEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQKZnJlZUtleUFjYwkBEWtleVVzZXJGcmVlUG9pbnRzAQUEYWRkcgQNZnJlZVBvaW50c0FjYwkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QFCmZyZWVLZXlBY2MAAAQLZnJlZUtleUR1Y2sJARFrZXlEdWNrRnJlZVBvaW50cwEFC2R1Y2tBc3NldElkBA5mcmVlUG9pbnRzRHVjawkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QFC2ZyZWVLZXlEdWNrAAAEB3N1bUZyZWUJAGQCBQ1mcmVlUG9pbnRzQWNjBQ5mcmVlUG9pbnRzRHVjawQPc3VtVG9EaXN0cmlidXRlCQBkAgkAZAIJAGQCCQBkAgUIc3RyZW5ndGgFCGFjY3VyYWN5BQlpbnRlbGxlY3QFCWVuZHVyYW5jZQUJZGV4dGVyaXR5AwkAZgIFD3N1bVRvRGlzdHJpYnV0ZQUHc3VtRnJlZQkAAgEJAKwCAgkArAICAg9UaGVyZSBhcmUgb25seSAJAKQDAQUHc3VtRnJlZQIaIGZyZWUgcG9pbnRzIHRvIGRpc3RyaWJ1dGUECGNoYXJzS2V5CQEMa2V5RHVja0NoYXJzAQULZHVja0Fzc2V0SWQEBWNoYXJzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0BQhjaGFyc0tleQIJMF8wXzBfMF8wAgFfBAZuZXdBY2MJAGUCBQ1mcmVlUG9pbnRzQWNjBQ9zdW1Ub0Rpc3RyaWJ1dGUJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUKZnJlZUtleUFjYwMJAGYCAAAFBm5ld0FjYwAABQZuZXdBY2MJAMwIAgkBDEludGVnZXJFbnRyeQIFC2ZyZWVLZXlEdWNrAwkAZgIAAAUGbmV3QWNjCQBkAgUOZnJlZVBvaW50c0R1Y2sFBm5ld0FjYwUOZnJlZVBvaW50c0R1Y2sJAMwIAgkBC1N0cmluZ0VudHJ5AgUIY2hhcnNLZXkJALkJAgkAzAgCCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDGNoYXJTdHJlbmd0aAUIc3RyZW5ndGgJAMwIAgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQxjaGFyQWNjdXJhY3kFCGFjY3VyYWN5CQDMCAIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUNY2hhckludGVsbGVjdAUJaW50ZWxsZWN0CQDMCAIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUNY2hhckVuZHVyYW5jZQUJZW5kdXJhbmNlCQDMCAIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUNY2hhckRleHRlcml0eQUJZGV4dGVyaXR5BQNuaWwCAV8JAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwAAAFpARxzcGxpdEJ5R2xvYmFsV2VpZ2h0c1JFQURPTkxZAQZhbW91bnQJAJQKAgUDbmlsCQESZ2V0TmVlZGVkTWF0ZXJpYWxzAQUGYW1vdW50AWkBJHNwbGl0QnlHbG9iYWxBbmRMb2NhbFdlaWdodHNSRUFET05MWQMJbWF0QW1vdW50CXJlc0Ftb3VudAh0ZXJyYWlucwQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBBQh0ZXJyYWlucwkAlAoCBQNuaWwJAJQKAgkBEmdldE5lZWRlZE1hdGVyaWFscwEFCW1hdEFtb3VudAkBE2Rpc3RyaWJ1dGVCeVdlaWdodHMCBQlyZXNBbW91bnQFDXRlcnJhaW5Db3VudHMBaQETZ2V0QmFja3BhY2tSRUFET05MWQELZHVja0Fzc2V0SWQJAJQKAgUDbmlsCQC5CQIJAQtnZXRCYWNrcGFjawEJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkAgE6AWkBFGdldFdhcmVob3VzZVJFQURPTkxZAQtsYW5kQXNzZXRJZAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQJbGFuZEluZGV4CQBpAgkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8FC3JlY0xhbmRTaXplBQVTU0laRQQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAAJAJQKAgUDbmlsCQC6CQIJAQxnZXRXYXJlaG91c2UDCQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAIBOgFpAQpzYXZlTGFzdFR4AAQGY2FsbGVyCAUBaQZjYWxsZXIDCQEBIQEJAQ9jb250YWluc0VsZW1lbnQCCQDMCAIFC3dsZ0NvbnRyYWN0CQDMCAIFD2Vjb25vbXlDb250cmFjdAkAzAgCBRJ0b3VybmFtZW50Q29udHJhY3QJAMwIAgUNYWNyZXNDb250cmFjdAUDbmlsBQZjYWxsZXIJAAIBAg1BY2Nlc3MgZGVuaWVkCQCUCgIJAMwIAgkBBnByb2xvZwEFAWkFA25pbAAqAWkBD3VwZGF0ZUR1Y2tTdGF0cwILZHVja0Fzc2V0SWQHZGVsdGFYUAMJAQIhPQIIBQFpBmNhbGxlcgUPZWNvbm9teUNvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQFB2RlbHRhWFABaQEOdXBkYXRlQWNjU3RhdHMCBGFkZHIHZGVsdGFYUAMJAQIhPQIIBQFpBmNhbGxlcgUPZWNvbm9teUNvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAkBFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwCBQRhZGRyBQdkZWx0YVhQAWkBCWVxdWlwRHVjawEJZXF1aXBtZW50BAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQDCQEPY2hlY2tUb3VybmFtZW50AQULZHVja0Fzc2V0SWQJAAIBAhllcXVpcER1Y2tfY2hlY2tUb3VybmFtZW50AwkBDWNoZWNrRGVsaXZlcnkBBQtkdWNrQXNzZXRJZAkAAgECF2VxdWlwRHVja19jaGVja0RlbGl2ZXJ5BAVlcUtleQkBEGtleUR1Y2tFcXVpcG1lbnQBBQtkdWNrQXNzZXRJZAQLY3VycmVudFNlZ3MJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQVlcUtleQIXLDssXyw7LF8sOyxfLDssXyw7LF8sOywCAV8EBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAVuZXdFcQkAtQkCBQllcXVpcG1lbnQCAV8DCQECIT0CCQCQAwEFBW5ld0VxBQtOVU1TRUdNRU5UUwkAAgECFldyb25nIGVxdWlwbWVudCBzdHJpbmcECXRlbXBQcm9kQgkBBmRyZXNzQgQFC2N1cnJlbnRTZWdzCQEOcHJvZFN0clRvQnl0ZXMBCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QGBQNuaWwECHNlZ0JwQXV4CQCRAwIJALUJAgkAkQMCBQVuZXdFcQULc2VnQmFja3BhY2sCATsAAQQKYnVmZkVmZmVjdAMJAAACBQhzZWdCcEF1eAIAAAAEBGF1eDAJAJEDAgkAtQkCBQhzZWdCcEF1eAIBLAAAAwkAAAIFBGF1eDACAAAABAZpZHhDbnQJALUJAgUEYXV4MAIBOgQDaWR4CQCRAwIFBmlkeENudAAABANjbnQJAJEDAgUGaWR4Q250AAEDAwMDAwkAAAIFA2lkeAICMDYGCQAAAgUDaWR4AgIwNwYJAAACBQNpZHgCAjA4CQECIT0CBQNjbnQCAAcJAGYCCQENcGFyc2VJbnRWYWx1ZQEFA2NudAAABwkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgkAkQMCBRBwcm9kdWN0aW9uTWF0cml4CQENcGFyc2VJbnRWYWx1ZQEFA2lkeAIBXwUKcklkeEVmZmVjdAAABAVzdGF0cwkBDGdldER1Y2tTdGF0cwQFBHRoaXMFC2R1Y2tBc3NldElkBQpidWZmRWZmZWN0BgQIbmV3UHJvZEIJAQZkcmVzc0IEBQVuZXdFcQUJdGVtcFByb2RCBwUFc3RhdHMECm5ld1Byb2RTdHIJAQ5ieXRlc1RvUHJvZFN0cgEFCG5ld1Byb2RCCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFZXFLZXkFCWVxdWlwbWVudAkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAugkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQJAMwIAgUKbmV3UHJvZFN0cgUDbmlsAgE6CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxrZXlEdWNrQnVmZnMBBQtkdWNrQXNzZXRJZAkAuQkCCQDMCAIJAKQDAQkAkQMCBQVzdGF0cwAHCQDMCAIJAKQDAQkAkQMCBQVzdGF0cwAICQDMCAIJAKQDAQkAkQMCBQVzdGF0cwAJCQDMCAIJAKQDAQkAkQMCBQVzdGF0cwAKCQDMCAIJAKQDAQkAkQMCBQVzdGF0cwALBQNuaWwCAV8JAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwAAAFpAQ9mb3J0aWZpY2F0ZUxhbmQCC2xhbmRBc3NldElkBHBsYW4EDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEC2R1Y2tBc3NldElkCQELdmFsdWVPckVsc2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICAAQJZHVja1N0YXRzCQEMZ2V0RHVja1N0YXRzBAUEdGhpcwULZHVja0Fzc2V0SWQAAAcEB2ZvcnRLZXkJARdrZXlGb3J0aWZpY2F0aW9uc0J5TGFuZAEFC2xhbmRBc3NldElkBAxjdXJyZW50Rm9ydHMJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQdmb3J0S2V5Agw6MF8xNTowXzE4OjACAV8EBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQECWxhbmRJbmRleAkAaQIJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBQtyZWNMYW5kU2l6ZQUFU1NJWkUECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAV3aEtleQkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkBAJ3aAkBDGdldFdhcmVob3VzZQMFBXdoS2V5BQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwEB2N1ckxvZnQJALUJAgkAkQMCBQJ3aAUJd2hJZHhMT0ZUAgFfBARjdXJPCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHY3VyTG9mdAULdm9sT2NjdXBpZWQEBGN1ckYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdjdXJMb2Z0BQd2b2xGcmVlBAhuZXdGb3J0cwkAtQkCBQRwbGFuAgFfBA0kdDA5Nzk5Mzk4MTA4CQEFZm9ydEIGBQxjdXJyZW50Rm9ydHMJAQ5wcm9kU3RyVG9CeXRlcwEJAJEDAgUCd2gFCXdoSWR4UHJvZAUEY3VyTwUEY3VyRgYFA25pbAQJdGVtcFByb2RCCAUNJHQwOTc5OTM5ODEwOAJfMQQFdGVtcE8IBQ0kdDA5Nzk5Mzk4MTA4Al8yBAV0ZW1wRggFDSR0MDk3OTkzOTgxMDgCXzMEDSR0MDk4MTExOTgyMDcJAQVmb3J0QgYFCG5ld0ZvcnRzBQl0ZW1wUHJvZEIFBXRlbXBPBQV0ZW1wRgcFCWR1Y2tTdGF0cwQIbmV3UHJvZEIIBQ0kdDA5ODExMTk4MjA3Al8xBARuZXdPCAUNJHQwOTgxMTE5ODIwNwJfMgQEbmV3RggFDSR0MDk4MTExOTgyMDcCXzMECm5ld1Byb2RTdHIJAQ5ieXRlc1RvUHJvZFN0cgEFCG5ld1Byb2RCBApuZXdMb2Z0U3RyCQC5CQIJAMwIAgkAkQMCBQdjdXJMb2Z0BQl2b2xMb2NrZWQJAMwIAgkApAMBBQRuZXdPCQDMCAIJAKQDAQUEbmV3RgkAzAgCCQCRAwIFB2N1ckxvZnQFCHZvbFRvdGFsBQNuaWwCAV8JAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQdmb3J0S2V5BQRwbGFuCQDMCAIJAQtTdHJpbmdFbnRyeQIFBXdoS2V5CQC6CQIJAMwIAgkAkQMCBQJ3aAULd2hJZHhMZXZlbHMJAMwIAgkAkQMCBQJ3aAUId2hJZHhSZXMJAMwIAgkAkQMCBQJ3aAUId2hJZHhNYXQJAMwIAgUKbmV3UHJvZFN0cgkAzAgCBQpuZXdMb2Z0U3RyBQNuaWwCAToJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwAAAFpARNpbml0RHVja1RvdXJBdHRlbXB0AQtkdWNrQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUSdG91cm5hbWVudENvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkAAAECWN1ckhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgFBW1heEhQBAljdXJMb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VyTG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04EBmxhc3RJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBRJ0b3VybmFtZW50Q29udHJhY3QFDWxhc3RUb3VySWRLZXkAAAQMdG91ckxvY2F0aW9uCQCsAgIJAKQDAQUGbGFzdElkAgRfVF8wCQCUCgIJAMwIAgUMcHJvbG9nQWN0aW9uCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOa2V5U2F2ZWRIZWFsdGgBBQtkdWNrQXNzZXRJZAUJY3VySGVhbHRoCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgFBW1heEhQCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBrZXlTYXZlZExvY2F0aW9uAQULZHVja0Fzc2V0SWQFC2N1ckxvY2F0aW9uCQDMCAIJAQtTdHJpbmdFbnRyeQIFCWN1ckxvY0tleQUMdG91ckxvY2F0aW9uBQNuaWwFDHRvdXJMb2NhdGlvbgFpAQxicmVha0F0dGVtcHQABAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAljdXJMb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VyTG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04DCQECIT0CCQCRAwIJALUJAgULY3VyTG9jYXRpb24CAV8FCmxvY0lkeFR5cGUCAVQJAAIBAiJZb3VyIGR1Y2sgaXMgbm90IGluIHRoZSB0b3VybmFtZW50BAtzYXZlZEhlYWx0aAkBEUBleHRyTmF0aXZlKDEwNTUpAQkBDmtleVNhdmVkSGVhbHRoAQULZHVja0Fzc2V0SWQEDXNhdmVkTG9jYXRpb24JARFAZXh0ck5hdGl2ZSgxMDU4KQEJARBrZXlTYXZlZExvY2F0aW9uAQULZHVja0Fzc2V0SWQJAJQKAgkAzAgCBQxwcm9sb2dBY3Rpb24JAMwIAgkBDEludGVnZXJFbnRyeQIJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQFC3NhdmVkSGVhbHRoCQDMCAIJAQtTdHJpbmdFbnRyeQIFCWN1ckxvY0tleQUNc2F2ZWRMb2NhdGlvbgUDbmlsBQtjdXJMb2NhdGlvbgFpARZleGl0VG91cm5hbWVudEludGVybmFsAQtkdWNrQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECDUFjY2VzcyBkZW5pZWQEC3NhdmVkSGVhbHRoCQERQGV4dHJOYXRpdmUoMTA1NSkBCQEOa2V5U2F2ZWRIZWFsdGgBBQtkdWNrQXNzZXRJZAQNc2F2ZWRMb2NhdGlvbgkBEUBleHRyTmF0aXZlKDEwNTgpAQkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBQtzYXZlZEhlYWx0aAkAzAgCCQELU3RyaW5nRW50cnkCCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFDXNhdmVkTG9jYXRpb24FA25pbAcBaQEUZXhpdERlbGl2ZXJ5SW50ZXJuYWwBC2R1Y2tBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQINQWNjZXNzIGRlbmllZAQLY3VyTG9jYXRpb24JALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQJc3RhcnRUaW1lCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgULY3VyTG9jYXRpb24FD2xvY0lkeENvbnRpbmVudAQIZGlzdGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtjdXJMb2NhdGlvbgUIbG9jSWR4SWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBEGtleUR1Y2tJZFRvT3duZXIBBQtkdWNrQXNzZXRJZAIUTkZUIGR1Y2sgaXMgb3JwaGFuZWQECWhlYWx0aEtleQkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQJY3VySGVhbHRoCQERQGV4dHJOYXRpdmUoMTA1NSkBBQloZWFsdGhLZXkEDm91dGNvbWVBY3Rpb25zAwkAZwIFCGRpc3RhbmNlAAMEBnJld2FyZAkA/AcEBQ9lY29ub215Q29udHJhY3QCEnNlbmREZWxpdmVyeVJld2FyZAkAzAgCBQVvd25lcgUDbmlsBQNuaWwDCQAAAgUGcmV3YXJkBQZyZXdhcmQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQLbG9ja2VkVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPZWNvbm9teUNvbnRyYWN0BRFkZWxpdmVyeUxvY2tlZEtleQAABAZ1bmxvY2sJAPwHBAUPZWNvbm9teUNvbnRyYWN0AhR1cGRhdGVEZWxpdmVyeUxvY2tlZAkAzAgCCQBlAgULbG9ja2VkVG90YWwFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUDbmlsBQNuaWwDCQAAAgUGdW5sb2NrBQZ1bmxvY2sDCQBnAgAABQljdXJIZWFsdGgFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFmtleURlbGl2ZXJ5RGVsYXlCeUR1Y2sBBQtkdWNrQXNzZXRJZAkAZAIFCXN0YXJ0VGltZQUJREFZTUlMTElTBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EC3NhdmVkSGVhbHRoCQERQGV4dHJOYXRpdmUoMTA1NSkBCQEOa2V5U2F2ZWRIZWFsdGgBBQtkdWNrQXNzZXRJZAQNc2F2ZWRMb2NhdGlvbgkBEUBleHRyTmF0aXZlKDEwNTgpAQkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAlAoCCQDNCAIJAM0IAgUOb3V0Y29tZUFjdGlvbnMJAQxJbnRlZ2VyRW50cnkCBQloZWFsdGhLZXkFC3NhdmVkSGVhbHRoCQELU3RyaW5nRW50cnkCCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFDXNhdmVkTG9jYXRpb24HAWkBDnByZXBhcmVSb2JiZXJ5AgdtZXNzYWdlA3NpZwQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQEhAQkAxBMDBQdtZXNzYWdlBQNzaWcFA3B1YgkAAgECGHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABAZ3bGdBbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAUKd2xnQXNzZXRJZAkAAgECFVdMR09MRCBwYXltZW50cyBvbmx5IQQFcGFydHMJALUJAgkAsAkBBQdtZXNzYWdlAgF8AwkBAiE9AgkAkAMBBQVwYXJ0cwACCQACAQIUV3JvbmcgbWVzc2FnZSBmb3JtYXQEC2R1Y2tBc3NldElkCQCRAwIFBXBhcnRzAAAEB3JvYkNvc3QICQEOZ2V0Um9iYmVyeURhdGECBQR0aGlzBQtkdWNrQXNzZXRJZAJfMQMJAGYCBQdyb2JDb3N0BQZ3bGdBbXQJAAIBCQCsAgIJAKwCAgkArAICAghQYXltZW50IAkApAMBBQZ3bGdBbXQCDCA8IHJlcXVpcmVkIAkApAMBBQdyb2JDb3N0BApjYW5kaWRhdGVzCQC1CQIJAJEDAgUFcGFydHMAAQIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQJZHVja1N0YXRlCQELdmFsdWVPckVsc2UCCQCfCAEJARNrZXlEdWNrUm9iYmVyeVN0YXRlAQULZHVja0Fzc2V0SWQAAAQKbG9ja2VkTGFuZAkBC3ZhbHVlT3JFbHNlAgkAoggBCQETa2V5TG9ja2VkTGFuZEJ5RHVjawEFC2R1Y2tBc3NldElkAgAEB2xhbmRFVEEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEmtleUxhbmRDb29sZG93bkVUQQEFCmxvY2tlZExhbmQAAAMDCQECIT0CBQlkdWNrU3RhdGUFC2R1Y2tJZHhGcmVlCQBmAgUHbGFuZEVUQQUDbm93BwkAAgEJAKwCAgInWW91IGFscmVhZHkgc3RhcnRlZCByb2JiaW5nLCB3YWl0IHRpbGwgCQCkAwEFB2xhbmRFVEEKAQdjaGVja2VyAgNhY2MLbGFuZEFzc2V0SWQEBXN0YXRlCQELdmFsdWVPckVsc2UCCQCfCAEJARNrZXlMYW5kUm9iYmVyeVN0YXRlAQULbGFuZEFzc2V0SWQAAAQLY29vbGRvd25FVEEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEmtleUxhbmRDb29sZG93bkVUQQEFC2xhbmRBc3NldElkAAADCQBmAgUFc3RhdGUJAJADAQUQbGFuZFJvYkNvb2xkb3ducwkAAgECDUludmFsaWQgc3RhdGUDCQBmAgUDbm93BQtjb29sZG93bkVUQQQKc3Rha2VkVGltZQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAADCQBnAgAABQpzdGFrZWRUaW1lBQNhY2MEAWEJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQBZAkAtQkCCAUBYQtkZXNjcmlwdGlvbgIBXwQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQQMcHJvZHVjdGl2aXR5CQEMYXBwbHlCb251c2VzAgULbGFuZEFzc2V0SWQFBnBpZWNlcwQJZGVsdGFUaW1lCQBlAgUDbm93BQpzdGFrZWRUaW1lBAhhdmFpbFJlcwkAawMFCWRlbHRhVGltZQkAaAIFDHByb2R1Y3Rpdml0eQUGcGllY2VzBQlEQVlNSUxMSVMDCQBmAgUOTUlOX1JFU19UT19ST0IFCGF2YWlsUmVzBQNhY2MJAM0IAgUDYWNjBQtsYW5kQXNzZXRJZAUDYWNjBAhmaWx0ZXJlZAoAAiRsBQpjYW5kaWRhdGVzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdjaGVja2VyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIJAJADAQUIZmlsdGVyZWQAAAkAAgECGU5vIGNhbmRpZGF0ZXMgZm9yIHJvYmJlcnkEBnJuZElkeAkBD2dldFJhbmRvbU51bWJlcgMJAJADAQUIZmlsdGVyZWQFBmhlaWdodAkAywECBQNzaWcIBQFpDXRyYW5zYWN0aW9uSWQEC2xhbmRBc3NldElkCQCRAwIFCGZpbHRlcmVkBQZybmRJZHgJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBE2tleUxhbmRSb2JiZXJ5U3RhdGUBBQtsYW5kQXNzZXRJZAUMcm9iSWR4TG9ja2VkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESa2V5TGFuZENvb2xkb3duRVRBAQULbGFuZEFzc2V0SWQJAGQCBQNub3cJAJEDAgUQbGFuZFJvYkNvb2xkb3ducwUMcm9iSWR4TG9ja2VkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQETa2V5RHVja1JvYmJlcnlTdGF0ZQEFC2R1Y2tBc3NldElkBRBkdWNrSWR4UHJlcGFyaW5nCQDMCAIJAQtTdHJpbmdFbnRyeQIJARNrZXlMb2NrZWRMYW5kQnlEdWNrAQULZHVja0Fzc2V0SWQFC2xhbmRBc3NldElkCQDMCAIFDHByb2xvZ0FjdGlvbgUDbmlsBQtsYW5kQXNzZXRJZAFpAQdyb2JMYW5kAgdtZXNzYWdlA3NpZwQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQEhAQkAxBMDBQdtZXNzYWdlBQNzaWcFA3B1YgkAAgECGHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaAQIdXNlckFkZHIJAKUIAQgFAWkGY2FsbGVyBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFCHVzZXJBZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQCUCgIJAMwIAgUMcHJvbG9nQWN0aW9uCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEYa2V5TGFzdFJvYmJlcnlUaW1lQnlEdWNrAQULZHVja0Fzc2V0SWQFA25vdwUDbmlsAAABaQEOYWNjZXB0RGVsaXZlcnkAAwkBASEBBRFLU19BTExPV19ERUxJVkVSWQkAAgECH0RlbGl2ZXJ5IGZlYXR1cmUgaXMgdHVybmVkIG9mZiEEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkECHVzZXJBZGRyCQClCAEIBQFpBmNhbGxlcgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQh1c2VyQWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQJZnVuZFRvdGFsCQELdmFsdWVPckVsc2UCCQCaCAIFD2Vjb25vbXlDb250cmFjdAUPZGVsaXZlcnlGdW5kS2V5AAAEC2xvY2tlZFRvdGFsCQELdmFsdWVPckVsc2UCCQCaCAIFD2Vjb25vbXlDb250cmFjdAURZGVsaXZlcnlMb2NrZWRLZXkAAAMJAGYCBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkJAGUCBQlmdW5kVG90YWwFC2xvY2tlZFRvdGFsCQACAQkArAICCQCsAgIJAKwCAgIgRGVsaXZlcnkgaXMgbm90IGF2YWlsYWJsZSwgZnVuZD0JAQpmaXhlZFBvaW50AgUJZnVuZFRvdGFsAAYCCSwgbG9ja2VkPQkBCmZpeGVkUG9pbnQCBQtsb2NrZWRUb3RhbAAGBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAhkZWxheUVUQQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5RGVsaXZlcnlEZWxheUJ5RHVjawEFC2R1Y2tBc3NldElkAAADCQBmAgUIZGVsYXlFVEEFA25vdwkAAgEJAKwCAgIqRGVsaXZlcnkgaXMgZm9yYmlkZGVuIGZvciB5b3VyIGR1Y2sgdW50aWwgCQCkAwEFCGRlbGF5RVRBAwkBD2NoZWNrVG91cm5hbWVudAEFC2R1Y2tBc3NldElkCQACAQIeYWNjZXB0RGVsaXZlcnlfY2hlY2tUb3VybmFtZW50AwkBDWNoZWNrRGVsaXZlcnkBBQtkdWNrQXNzZXRJZAkAAgECHGFjY2VwdERlbGl2ZXJ5X2NoZWNrRGVsaXZlcnkEDm5ld0xvY2tlZFRvdGFsCQEFYXNJbnQBCQD8BwQFD2Vjb25vbXlDb250cmFjdAIUdXBkYXRlRGVsaXZlcnlMb2NrZWQJAMwIAgkAZAIFC2xvY2tlZFRvdGFsBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFA25pbAUDbmlsBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEBW1heEhQCQEJbWF4SGVhbHRoAQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEMa2V5RHVja0xldmVsAQULZHVja0Fzc2V0SWQAAAQJY3VySGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFAECWN1ckxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBBQljdXJMb2NLZXkFD0RFRkFVTFRMT0NBVElPTgQQZGVsaXZlcnlMb2NhdGlvbgkArAICCQCkAwEFA25vdwIEX0RfMAkAlAoCCQDMCAIFDHByb2xvZ0FjdGlvbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDmtleVNhdmVkSGVhbHRoAQULZHVja0Fzc2V0SWQFCWN1ckhlYWx0aAkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQVtYXhIUAkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQtjdXJMb2NhdGlvbgkAzAgCCQELU3RyaW5nRW50cnkCBQljdXJMb2NLZXkFEGRlbGl2ZXJ5TG9jYXRpb24FA25pbAkAlAoCBRBkZWxpdmVyeUxvY2F0aW9uBQ5uZXdMb2NrZWRUb3RhbADfahVG", "height": 2766947, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HtbEAwFirdhETNzJKDa2ujMfb3udqtbRryyuY5Pv1bzR Next: 7j34EtuKEvVTLxQkXEdxVXzBS6knWJGGToPdzcTbUEZ3 Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let DAYMILLIS = 86400000
5+
46 func keyLastArbTimeByUser (addr) = ("lastArbTimeUser_" + addr)
57
68
100102
101103
102104 func keyLockedLandByDuck (duckAssetId) = ("lockedLandByDuck_" + duckAssetId)
105+
106+
107+func keyDeliveryDelayByDuck (duckAssetId) = ("deliveryDelayByDuck_" + duckAssetId)
103108
104109
105110 let xpClaim = 10000
169174
170175 let DAILYRESBYPIECE = 3456000
171176
172-let DAYMILLIS = 86400000
173-
174177 let WHMULTIPLIER = 10000000000
175178
176179 let DEFAULTLOCATION = "Africa_F_Africa"
294297
295298
296299 let deliveryFundKey = "deliveryFund"
300+
301+let deliveryLockedKey = "deliveryLocked"
297302
298303 let lastTourIdKey = "%s__lastTourId"
299304
528533 func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
529534
530535
536+func fixedPoint (val,decimals) = {
537+ let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
538+ let lowPart = toString((val % tenPow))
539+ let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
540+ (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
541+ }
542+
543+
531544 func getRandomNumber (maxValue,finishHeight,auxEntropy) = {
532545 let randomSeedBlock = value(blockInfoByHeight(finishHeight))
533546 let randomHash = sha256((value(randomSeedBlock.vrf) + auxEntropy))
567580 let EMPTY_PROD50 = base64'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
568581
569582 let FIVEMINUTESMILLIS = 300000
583+
584+let TEN_MINUTES_MILLIS = 600000
570585
571586 let RENAMINGCOST = 5000000
572587
16701685
16711686
16721687 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
1673- let $t03373834277 = if ((claimMode == claimModeWh))
1688+ let $t03378434323 = if ((claimMode == claimModeWh))
16741689 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
16751690 else {
16761691 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
16801695 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
16811696 else $Tuple2(loc[locIdxId], duckAssetId)
16821697 }
1683- let landAssetId = $t03373834277._1
1684- let duckId = $t03373834277._2
1698+ let landAssetId = $t03378434323._1
1699+ let duckId = $t03378434323._2
16851700 let asset = value(assetInfo(fromBase58String(landAssetId)))
16861701 let timeKey = keyStakedTimeByAssetId(landAssetId)
16871702 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
17291744 let currentPack = getBackpack(bpKey)
17301745 let currentPackRes = split(currentPack[bpIdxRes], "_")
17311746 let currentWhRes = split(currentWh[whIdxRes], "_")
1732- let $t03665137522 = if ((claimMode == claimModeWh))
1747+ let $t03669737568 = if ((claimMode == claimModeWh))
17331748 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
17341749 else if ((claimMode == claimModeDuck))
17351750 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
17381753 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
17391754 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
17401755 }
1741- let whRes = $t03665137522._1
1742- let bpRes = $t03665137522._2
1743- let loftO = $t03665137522._3
1744- let loftF = $t03665137522._4
1756+ let whRes = $t03669737568._1
1757+ let bpRes = $t03669737568._2
1758+ let loftO = $t03669737568._3
1759+ let loftF = $t03669737568._4
17451760 $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxLevels], whRes, currentWh[whIdxMat], currentWh[whIdxProd], makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")])
17461761 }
17471762 }
18791894 }
18801895
18811896
1897+func checkDelivery (duckAssetId) = {
1898+ let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1899+ let now = lastBlock.timestamp
1900+ if ((curLocation[locIdxType] != "D"))
1901+ then false
1902+ else {
1903+ let startTime = parseIntValue(curLocation[locIdxContinent])
1904+ let distance = parseIntValue(curLocation[locIdxId])
1905+ if (if ((now > (startTime + TEN_MINUTES_MILLIS)))
1906+ then (3 > distance)
1907+ else false)
1908+ then throw("Your duck is on delivery mission")
1909+ else asBoolean(invoke(this, "exitDeliveryInternal", [duckAssetId], nil))
1910+ }
1911+ }
1912+
1913+
18821914 func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,needMat) = {
18831915 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
18841916 if (checkTournament(duckAssetId))
18851917 then throw("mergeInternal_checkTournament")
1886- else {
1887- func checkMerge (acc,landAssetId) = {
1888- let asset = value(assetInfo(fromBase58String(landAssetId)))
1889- let timeKey = keyStakedTimeByAssetId(landAssetId)
1890- let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
1891- let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1892- if ((owner != addr))
1893- then throw((LANDPREFIX + " is not yours"))
1894- else {
1895- let d = split(asset.description, "_")
1896- let continent = d[recContinent]
1897- if (if ((acc._3 != ""))
1898- then (acc._3 != continent)
1899- else false)
1900- then throw("Lands should be on the same continent to merge")
1901- else {
1902- let landSize = d[recLandSize]
1903- let sizesIn = acc._1
1904- let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
1905- let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
1906- let pieces = numPiecesBySize(landSize)
1907- let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
1908- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1909- let reqLevel = match landSize {
1910- case _ =>
1911- if (("S" == $match0))
1912- then 3
1913- else if (("M" == $match0))
1914- then 4
1915- else if (("L" == $match0))
1916- then 5
1917- else if (("XL" == $match0))
1918- then 6
1919- else throw("Only S, M, L, XL can merge")
1920- }
1921- if ((infraLevel != reqLevel))
1922- then throw("All lands should be maxed to merge")
1923- else {
1924- let landNum = d[recLandNum]
1925- let terrainCounts = countTerrains(d[recTerrains])
1926- let deltaTime = (lastBlock.timestamp - savedTime)
1927- if ((0 > deltaTime))
1928- then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
1929- else {
1930- let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
1931- let landIndex = (pieces / SSIZE)
1932- let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
1933- let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
1934- let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
1935- let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
1936- let lands = acc._7
1937- let idx = indexOf(lands, landAssetId)
1938- if (!(isDefined(idx)))
1939- then throw(("Your staked lands don't contain " + landAssetId))
1940- else {
1941- let customKey = keyLandAssetIdToCustomName(landAssetId)
1942- let customName = valueOrElse(getString(customKey), "")
1943- $Tuple10(sizesOut, arts, continent, bpRes, ((((((((((((acc._5 :+ DeleteEntry(keyStakedTimeByAssetId(landAssetId))) :+ DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))) :+ DeleteEntry(keyLandToAssetId(landNum))) :+ DeleteEntry(keyLandAssetIdToOwner(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetId(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
1944- then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
1945- else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
1946- }
1947- }
1948- }
1949- }
1950- }
1918+ else if (checkDelivery(duckAssetId))
1919+ then throw("mergeInternal_checkDelivery")
1920+ else {
1921+ func checkMerge (acc,landAssetId) = {
1922+ let asset = value(assetInfo(fromBase58String(landAssetId)))
1923+ let timeKey = keyStakedTimeByAssetId(landAssetId)
1924+ let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
1925+ let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1926+ if ((owner != addr))
1927+ then throw((LANDPREFIX + " is not yours"))
1928+ else {
1929+ let d = split(asset.description, "_")
1930+ let continent = d[recContinent]
1931+ if (if ((acc._3 != ""))
1932+ then (acc._3 != continent)
1933+ else false)
1934+ then throw("Lands should be on the same continent to merge")
1935+ else {
1936+ let landSize = d[recLandSize]
1937+ let sizesIn = acc._1
1938+ let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
1939+ let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
1940+ let pieces = numPiecesBySize(landSize)
1941+ let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
1942+ let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1943+ let reqLevel = match landSize {
1944+ case _ =>
1945+ if (("S" == $match0))
1946+ then 3
1947+ else if (("M" == $match0))
1948+ then 4
1949+ else if (("L" == $match0))
1950+ then 5
1951+ else if (("XL" == $match0))
1952+ then 6
1953+ else throw("Only S, M, L, XL can merge")
1954+ }
1955+ if ((infraLevel != reqLevel))
1956+ then throw("All lands should be maxed to merge")
1957+ else {
1958+ let landNum = d[recLandNum]
1959+ let terrainCounts = countTerrains(d[recTerrains])
1960+ let deltaTime = (lastBlock.timestamp - savedTime)
1961+ if ((0 > deltaTime))
1962+ then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
1963+ else {
1964+ let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
1965+ let landIndex = (pieces / SSIZE)
1966+ let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
1967+ let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
1968+ let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
1969+ let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
1970+ let lands = acc._7
1971+ let idx = indexOf(lands, landAssetId)
1972+ if (!(isDefined(idx)))
1973+ then throw(("Your staked lands don't contain " + landAssetId))
1974+ else {
1975+ let customKey = keyLandAssetIdToCustomName(landAssetId)
1976+ let customName = valueOrElse(getString(customKey), "")
1977+ $Tuple10(sizesOut, arts, continent, bpRes, ((((((((((((acc._5 :+ DeleteEntry(keyStakedTimeByAssetId(landAssetId))) :+ DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))) :+ DeleteEntry(keyLandToAssetId(landNum))) :+ DeleteEntry(keyLandAssetIdToOwner(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetId(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
1978+ then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
1979+ else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
1980+ }
1981+ }
1982+ }
1983+ }
1984+ }
1985+ }
1986+
1987+ let bpKey = keyBackpackByDuck(duckAssetId)
1988+ let currentPack = getBackpack(bpKey)
1989+ let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
1990+ let landsKey = keyStakedLandsByOwner(addr)
1991+ let landsStr = getString(landsKey)
1992+ let landsIn = if (isDefined(landsStr))
1993+ then split_51C(value(landsStr), "_")
1994+ else nil
1995+ let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
1996+ let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
1997+ let r = {
1998+ let $l = landAssetIds
1999+ let $s = size($l)
2000+ let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
2001+ func $f0_1 ($a,$i) = if (($i >= $s))
2002+ then $a
2003+ else checkMerge($a, $l[$i])
2004+
2005+ func $f0_2 ($a,$i) = if (($i >= $s))
2006+ then $a
2007+ else throw("List size exceeds 5")
2008+
2009+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
2010+ }
2011+ let continent = r._3
2012+ let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
2013+ let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
2014+ let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
2015+ let newLandNum = toString(freeNum)
2016+ let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
2017+ let assetId = calculateAssetId(issue)
2018+ let newLandAssetId = toBase58String(assetId)
2019+ let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
2020+ let piecesKey = keyStakedPiecesByOwner(addr)
2021+ let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
2022+ $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
2023+ then StringEntry(landsKey, makeString_11C(r._7, "_"))
2024+ else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
2025+ then 0
2026+ else (stakedPieces - r._8))) :+ IntegerEntry(keyNextFreeLandNum(), (freeNum + 1))) :+ issue) :+ StringEntry(keyLandToAssetId(newLandNum), newLandAssetId)) :+ StringEntry(keyLandAssetIdToOwner(newLandAssetId), addr)) :+ StringEntry(keyLandNumToOwner(newLandNum), addr)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, newLandAssetId), r._2)) :+ IntegerEntry(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
19512027 }
1952-
1953- let bpKey = keyBackpackByDuck(duckAssetId)
1954- let currentPack = getBackpack(bpKey)
1955- let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
1956- let landsKey = keyStakedLandsByOwner(addr)
1957- let landsStr = getString(landsKey)
1958- let landsIn = if (isDefined(landsStr))
1959- then split_51C(value(landsStr), "_")
1960- else nil
1961- let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
1962- let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
1963- let r = {
1964- let $l = landAssetIds
1965- let $s = size($l)
1966- let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
1967- func $f0_1 ($a,$i) = if (($i >= $s))
1968- then $a
1969- else checkMerge($a, $l[$i])
1970-
1971- func $f0_2 ($a,$i) = if (($i >= $s))
1972- then $a
1973- else throw("List size exceeds 5")
1974-
1975- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
1976- }
1977- let continent = r._3
1978- let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
1979- let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
1980- let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
1981- let newLandNum = toString(freeNum)
1982- let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
1983- let assetId = calculateAssetId(issue)
1984- let newLandAssetId = toBase58String(assetId)
1985- let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
1986- let piecesKey = keyStakedPiecesByOwner(addr)
1987- let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
1988- $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
1989- then StringEntry(landsKey, makeString_11C(r._7, "_"))
1990- else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
1991- then 0
1992- else (stakedPieces - r._8))) :+ IntegerEntry(keyNextFreeLandNum(), (freeNum + 1))) :+ issue) :+ StringEntry(keyLandToAssetId(newLandNum), newLandAssetId)) :+ StringEntry(keyLandAssetIdToOwner(newLandAssetId), addr)) :+ StringEntry(keyLandNumToOwner(newLandNum), addr)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, newLandAssetId), r._2)) :+ IntegerEntry(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
1993- }
19942028 }
19952029
19962030
21822216 then throw((("NFT " + asset.name) + " is already staked"))
21832217 else if (isDefined(getString(keyStakedDuckByOwner(address))))
21842218 then throw(("You already staked one duck: " + asset.name))
2185- else if (checkTournament(assetIdStr))
2186- then throw("stakeDuck_checkTournament")
2187- else {
2188- let locKey = keyDuckLocation(assetIdStr)
2189- let location = getString(locKey)
2190- let bpKey = keyBackpackByDuck(assetIdStr)
2191- let backpack = getString(bpKey)
2192- let keyHealth = keyDuckHealth(assetIdStr)
2193- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2194- let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
2195- ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
2219+ else {
2220+ let locKey = keyDuckLocation(assetIdStr)
2221+ let location = getString(locKey)
2222+ let bpKey = keyBackpackByDuck(assetIdStr)
2223+ let backpack = getString(bpKey)
2224+ let keyHealth = keyDuckHealth(assetIdStr)
2225+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2226+ let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
2227+ ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
2228+ then nil
2229+ else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
21962230 then nil
2197- else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
2198- then nil
2199- else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) :+ prologAction)))))
2200- }
2231+ else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) :+ prologAction)))))
2232+ }
22012233 }
22022234 }
22032235 }
22252257 then throw("Staked NFT is not yours")
22262258 else if (checkTournament(assetIdStr))
22272259 then throw("unstakeDuck_checkTournament")
2228- else {
2229- let keyHealth = keyDuckHealth(assetIdStr)
2230- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2231- let health = valueOrElse(getInteger(keyHealth), maxHP)
2232- if ((maxHP > health))
2233- then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
2234- else [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address)), prologAction]
2235- }
2260+ else if (checkDelivery(assetIdStr))
2261+ then throw("unstakeDuck_checkDelivery")
2262+ else {
2263+ let keyHealth = keyDuckHealth(assetIdStr)
2264+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2265+ let health = valueOrElse(getInteger(keyHealth), maxHP)
2266+ if ((maxHP > health))
2267+ then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
2268+ else [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address)), prologAction]
2269+ }
22362270 }
22372271 }
22382272 }
22882322 let isTour = (newLoc[locIdxType] == "T")
22892323 let eqKey = keyDuckEquipment(duckAssetId)
22902324 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2291- let $t06601366110 = subtractEquipment(currentEq, f._5)
2292- let newEq = $t06601366110._1
2293- let shouldZeroBuffs = $t06601366110._2
2325+ let $t06681366910 = subtractEquipment(currentEq, f._5)
2326+ let newEq = $t06681366910._1
2327+ let shouldZeroBuffs = $t06681366910._2
22942328 let locToSave = if (!(isInTournament(tournamentContract, curLocation)))
22952329 then if (isTour)
22962330 then throw(((("Cheat attempt: oldLoc=" + curLocation) + ", newLoc=") + newLocation))
23412375 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
23422376 if (checkTournament(duckAssetId))
23432377 then throw("heal_checkTournament")
2344- else {
2345- let qts = [quantityL1, quantityL2, quantityL3]
2346- let keyHealth = keyDuckHealth(duckAssetId)
2347- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2348- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2349- if ((oldHealth >= maxHP))
2350- then throw((("HP should be < " + toString(maxHP)) + " to heal"))
2351- else {
2352- let bpKey = keyBackpackByDuck(duckAssetId)
2353- let currentPack = getBackpack(bpKey)
2354- let prodList = if ((currentPack[bpIdxProd] == ""))
2355- then nil
2356- else split_4C(currentPack[bpIdxProd], "_")
2357- func iterateProd (acc,recipe) = {
2358- let n = acc._2
2359- let x = if ((size(prodList) > n))
2360- then parseIntValue(prodList[n])
2361- else 0
2362- if ((3 > n))
2363- then {
2364- let q = qts[n]
2365- if ((q > x))
2366- then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
2367- else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
2368- }
2369- else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
2378+ else if (checkDelivery(duckAssetId))
2379+ then throw("heal_checkDelivery")
2380+ else {
2381+ let qts = [quantityL1, quantityL2, quantityL3]
2382+ let keyHealth = keyDuckHealth(duckAssetId)
2383+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2384+ let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2385+ if ((oldHealth >= maxHP))
2386+ then throw((("HP should be < " + toString(maxHP)) + " to heal"))
2387+ else {
2388+ let bpKey = keyBackpackByDuck(duckAssetId)
2389+ let currentPack = getBackpack(bpKey)
2390+ let prodList = if ((currentPack[bpIdxProd] == ""))
2391+ then nil
2392+ else split_4C(currentPack[bpIdxProd], "_")
2393+ func iterateProd (acc,recipe) = {
2394+ let n = acc._2
2395+ let x = if ((size(prodList) > n))
2396+ then parseIntValue(prodList[n])
2397+ else 0
2398+ if ((3 > n))
2399+ then {
2400+ let q = qts[n]
2401+ if ((q > x))
2402+ then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
2403+ else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
2404+ }
2405+ else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
2406+ }
2407+
2408+ let result = {
2409+ let $l = productionMatrix
2410+ let $s = size($l)
2411+ let $acc0 = $Tuple3(nil, 0, 0)
2412+ func $f0_1 ($a,$i) = if (($i >= $s))
2413+ then $a
2414+ else iterateProd($a, $l[$i])
2415+
2416+ func $f0_2 ($a,$i) = if (($i >= $s))
2417+ then $a
2418+ else throw("List size exceeds 50")
2419+
2420+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
2421+ }
2422+ let newHealth = min([maxHP, (oldHealth + result._3)])
2423+ $Tuple2(([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":")), prologAction] ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
23702424 }
2371-
2372- let result = {
2373- let $l = productionMatrix
2374- let $s = size($l)
2375- let $acc0 = $Tuple3(nil, 0, 0)
2376- func $f0_1 ($a,$i) = if (($i >= $s))
2377- then $a
2378- else iterateProd($a, $l[$i])
2379-
2380- func $f0_2 ($a,$i) = if (($i >= $s))
2381- then $a
2382- else throw("List size exceeds 50")
2383-
2384- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
2385- }
2386- let newHealth = min([maxHP, (oldHealth + result._3)])
2387- $Tuple2(([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":")), prologAction] ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
2388- }
2389- }
2425+ }
23902426 }
23912427 }
23922428
24052441 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
24062442 if (checkTournament(duckAssetId))
24072443 then throw("healES_checkTournament")
2408- else {
2409- let keyHealth = keyDuckHealth(duckAssetId)
2410- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2411- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2412- if ((oldHealth > 0))
2413- then throw("HP should be 0 to call Emergency Service")
2414- else {
2415- let bpKey = keyBackpackByDuck(duckAssetId)
2416- let currentPack = getBackpack(bpKey)
2417- let prodList = if ((currentPack[bpIdxProd] == ""))
2418- then nil
2419- else split_4C(currentPack[bpIdxProd], "_")
2420- let medKitAmount1 = if ((size(prodList) > 0))
2421- then parseIntValue(prodList[0])
2422- else 0
2423- let medKitAmount2 = if ((size(prodList) > 1))
2424- then parseIntValue(prodList[1])
2425- else 0
2426- let medKitAmount3 = if ((size(prodList) > 2))
2427- then parseIntValue(prodList[2])
2428- else 0
2429- if (if (if ((medKitAmount1 > 0))
2430- then true
2431- else (medKitAmount2 > 0))
2432- then true
2433- else (medKitAmount3 > 0))
2434- then throw("You have to use own Medical Kit")
2435- else {
2436- let existStr = getString(economyContract, keyEsWarehouse())
2437- let existAmounts = if (isDefined(existStr))
2438- then split_4C(value(existStr), "_")
2439- else nil
2440- let existAmount = if ((size(existAmounts) > 0))
2441- then parseIntValue(existAmounts[0])
2442- else 0
2443- if ((0 >= existAmount))
2444- then throw("There are no Medical Kits L1 at Emergency Service storage")
2445- else {
2446- let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
2447- let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
2448- let recipe = split(productionMatrix[0], "_")
2449- let totalMat = getRecipeMaterials(recipe)
2450- let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
2451- if ((pmt.amount != sellPrice))
2452- then throw(("Payment attached should be " + toString(sellPrice)))
2453- else {
2454- let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
2455- $Tuple2(([IntegerEntry(keyHealth, newHealth), prologAction] ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
2456- }
2457- }
2458- }
2459- }
2460- }
2444+ else if (checkDelivery(duckAssetId))
2445+ then throw("healES_checkDelivery")
2446+ else {
2447+ let keyHealth = keyDuckHealth(duckAssetId)
2448+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2449+ let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2450+ if ((oldHealth > 0))
2451+ then throw("HP should be 0 to call Emergency Service")
2452+ else {
2453+ let bpKey = keyBackpackByDuck(duckAssetId)
2454+ let currentPack = getBackpack(bpKey)
2455+ let prodList = if ((currentPack[bpIdxProd] == ""))
2456+ then nil
2457+ else split_4C(currentPack[bpIdxProd], "_")
2458+ let medKitAmount1 = if ((size(prodList) > 0))
2459+ then parseIntValue(prodList[0])
2460+ else 0
2461+ let medKitAmount2 = if ((size(prodList) > 1))
2462+ then parseIntValue(prodList[1])
2463+ else 0
2464+ let medKitAmount3 = if ((size(prodList) > 2))
2465+ then parseIntValue(prodList[2])
2466+ else 0
2467+ if (if (if ((medKitAmount1 > 0))
2468+ then true
2469+ else (medKitAmount2 > 0))
2470+ then true
2471+ else (medKitAmount3 > 0))
2472+ then throw("You have to use own Medical Kit")
2473+ else {
2474+ let existStr = getString(economyContract, keyEsWarehouse())
2475+ let existAmounts = if (isDefined(existStr))
2476+ then split_4C(value(existStr), "_")
2477+ else nil
2478+ let existAmount = if ((size(existAmounts) > 0))
2479+ then parseIntValue(existAmounts[0])
2480+ else 0
2481+ if ((0 >= existAmount))
2482+ then throw("There are no Medical Kits L1 at Emergency Service storage")
2483+ else {
2484+ let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
2485+ let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
2486+ let recipe = split(productionMatrix[0], "_")
2487+ let totalMat = getRecipeMaterials(recipe)
2488+ let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
2489+ if ((pmt.amount != sellPrice))
2490+ then throw(("Payment attached should be " + toString(sellPrice)))
2491+ else {
2492+ let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
2493+ $Tuple2(([IntegerEntry(keyHealth, newHealth), prologAction] ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
2494+ }
2495+ }
2496+ }
2497+ }
2498+ }
24612499 }
24622500 }
24632501 }
25302568 let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
25312569 let eqKey = keyDuckEquipment(duckAssetId)
25322570 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2533- let $t07486774964 = subtractEquipment(currentEq, f._5)
2534- let newEq = $t07486774964._1
2535- let shouldZeroBuffs = $t07486774964._2
2571+ let $t07583875935 = subtractEquipment(currentEq, f._5)
2572+ let newEq = $t07583875935._1
2573+ let shouldZeroBuffs = $t07583875935._2
25362574 let e = expeditionInternal(i.caller, i.transactionId)
25372575 let id = e._2._1
25382576 let result = if ((0 >= f._1))
25422580 else ((((nil :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, f._1)) :+ StringEntry(eqKey, newEq)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))))), id, f._3)
25432581 if (checkTournament(duckAssetId))
25442582 then throw("expedition_checkTournament")
2545- else {
2546- let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2547- $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) :+ prologAction), $Tuple3(result._2, result._3, acresResult))
2548- }
2583+ else if (checkDelivery(duckAssetId))
2584+ then throw("expedition_checkDelivery")
2585+ else {
2586+ let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2587+ $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) :+ prologAction), $Tuple3(result._2, result._3, acresResult))
2588+ }
25492589 }
25502590 }
25512591
30433083 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
30443084 if (checkTournament(duckAssetId))
30453085 then throw("equipDuck_checkTournament")
3046- else {
3047- let eqKey = keyDuckEquipment(duckAssetId)
3048- let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
3049- let bpKey = keyBackpackByDuck(duckAssetId)
3050- let currentPack = getBackpack(bpKey)
3051- let newEq = split(equipment, "_")
3052- if ((size(newEq) != NUMSEGMENTS))
3053- then throw("Wrong equipment string")
3054- else {
3055- let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
3056- let segBpAux = split(newEq[segBackpack], ";")[1]
3057- let buffEffect = if ((segBpAux == ""))
3058- then 0
3059- else {
3060- let aux0 = split(segBpAux, ",")[0]
3061- if ((aux0 == ""))
3062- then 0
3063- else {
3064- let idxCnt = split(aux0, ":")
3065- let idx = idxCnt[0]
3066- let cnt = idxCnt[1]
3067- if (if (if (if (if ((idx == "06"))
3068- then true
3069- else (idx == "07"))
3070- then true
3071- else (idx == "08"))
3072- then (cnt != "")
3073- else false)
3074- then (parseIntValue(cnt) > 0)
3075- else false)
3076- then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
3077- else 0
3078- }
3079- }
3080- let stats = getDuckStats(this, duckAssetId, buffEffect, true)
3081- let newProdB = dressB(newEq, tempProdB, false, stats)
3082- let newProdStr = bytesToProdStr(newProdB)
3083- $Tuple2([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_")), prologAction], 0)
3084- }
3085- }
3086+ else if (checkDelivery(duckAssetId))
3087+ then throw("equipDuck_checkDelivery")
3088+ else {
3089+ let eqKey = keyDuckEquipment(duckAssetId)
3090+ let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
3091+ let bpKey = keyBackpackByDuck(duckAssetId)
3092+ let currentPack = getBackpack(bpKey)
3093+ let newEq = split(equipment, "_")
3094+ if ((size(newEq) != NUMSEGMENTS))
3095+ then throw("Wrong equipment string")
3096+ else {
3097+ let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
3098+ let segBpAux = split(newEq[segBackpack], ";")[1]
3099+ let buffEffect = if ((segBpAux == ""))
3100+ then 0
3101+ else {
3102+ let aux0 = split(segBpAux, ",")[0]
3103+ if ((aux0 == ""))
3104+ then 0
3105+ else {
3106+ let idxCnt = split(aux0, ":")
3107+ let idx = idxCnt[0]
3108+ let cnt = idxCnt[1]
3109+ if (if (if (if (if ((idx == "06"))
3110+ then true
3111+ else (idx == "07"))
3112+ then true
3113+ else (idx == "08"))
3114+ then (cnt != "")
3115+ else false)
3116+ then (parseIntValue(cnt) > 0)
3117+ else false)
3118+ then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
3119+ else 0
3120+ }
3121+ }
3122+ let stats = getDuckStats(this, duckAssetId, buffEffect, true)
3123+ let newProdB = dressB(newEq, tempProdB, false, stats)
3124+ let newProdStr = bytesToProdStr(newProdB)
3125+ $Tuple2([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_")), prologAction], 0)
3126+ }
3127+ }
30863128 }
30873129 }
30883130
31083150 let curO = parseIntValue(curLoft[volOccupied])
31093151 let curF = parseIntValue(curLoft[volFree])
31103152 let newForts = split(plan, "_")
3111- let $t09686796982 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3112- let tempProdB = $t09686796982._1
3113- let tempO = $t09686796982._2
3114- let tempF = $t09686796982._3
3115- let $t09698597081 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3116- let newProdB = $t09698597081._1
3117- let newO = $t09698597081._2
3118- let newF = $t09698597081._3
3153+ let $t09799398108 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3154+ let tempProdB = $t09799398108._1
3155+ let tempO = $t09799398108._2
3156+ let tempF = $t09799398108._3
3157+ let $t09811198207 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3158+ let newProdB = $t09811198207._1
3159+ let newO = $t09811198207._2
3160+ let newF = $t09811198207._3
31193161 let newProdStr = bytesToProdStr(newProdB)
31203162 let newLoftStr = makeString([curLoft[volLocked], toString(newO), toString(newF), curLoft[volTotal]], "_")
31213163 $Tuple2([StringEntry(fortKey, plan), StringEntry(whKey, makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], newProdStr, newLoftStr], ":")), prologAction], 0)
31653207 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
31663208 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
31673209 $Tuple2([IntegerEntry(keyDuckHealth(duckAssetId), savedHealth), StringEntry(keyDuckLocation(duckAssetId), savedLocation)], false)
3210+ }
3211+
3212+
3213+
3214+@Callable(i)
3215+func exitDeliveryInternal (duckAssetId) = if ((i.caller != this))
3216+ then throw("Access denied")
3217+ else {
3218+ let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
3219+ let now = lastBlock.timestamp
3220+ let startTime = parseIntValue(curLocation[locIdxContinent])
3221+ let distance = parseIntValue(curLocation[locIdxId])
3222+ let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(duckAssetId)), "NFT duck is orphaned")
3223+ let healthKey = keyDuckHealth(duckAssetId)
3224+ let curHealth = getIntegerValue(healthKey)
3225+ let outcomeActions = if ((distance >= 3))
3226+ then {
3227+ let reward = invoke(economyContract, "sendDeliveryReward", [owner], nil)
3228+ if ((reward == reward))
3229+ then nil
3230+ else throw("Strict value is not equal to itself.")
3231+ }
3232+ else {
3233+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
3234+ let unlock = invoke(economyContract, "updateDeliveryLocked", [(lockedTotal - MIN_USDT_FEE_DELIVERY)], nil)
3235+ if ((unlock == unlock))
3236+ then if ((0 >= curHealth))
3237+ then nil
3238+ else [IntegerEntry(keyDeliveryDelayByDuck(duckAssetId), (startTime + DAYMILLIS))]
3239+ else throw("Strict value is not equal to itself.")
3240+ }
3241+ let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
3242+ let savedLocation = getStringValue(keySavedLocation(duckAssetId))
3243+ $Tuple2(((outcomeActions :+ IntegerEntry(healthKey, savedHealth)) :+ StringEntry(keyDuckLocation(duckAssetId), savedLocation)), false)
31683244 }
31693245
31703246
32813357 let userAddr = toString(i.caller)
32823358 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
32833359 let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
3284- if ((MIN_USDT_FEE_DELIVERY > fundTotal))
3285- then throw(("Delivery is not available, fund=" + toString(fundTotal)))
3360+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
3361+ if ((MIN_USDT_FEE_DELIVERY > (fundTotal - lockedTotal)))
3362+ then throw(((("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)) + ", locked=") + fixedPoint(lockedTotal, 6)))
32863363 else {
3287- let keyHealth = keyDuckHealth(duckAssetId)
3288- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
3289- let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
3290- let curLocKey = keyDuckLocation(duckAssetId)
3291- let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
32923364 let now = lastBlock.timestamp
3293- let deliveryLocation = (toString(now) + "_D_0")
3294- $Tuple2([prologAction, IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, deliveryLocation)], deliveryLocation)
3365+ let delayETA = valueOrElse(getInteger(keyDeliveryDelayByDuck(duckAssetId)), 0)
3366+ if ((delayETA > now))
3367+ then throw(("Delivery is forbidden for your duck until " + toString(delayETA)))
3368+ else if (checkTournament(duckAssetId))
3369+ then throw("acceptDelivery_checkTournament")
3370+ else if (checkDelivery(duckAssetId))
3371+ then throw("acceptDelivery_checkDelivery")
3372+ else {
3373+ let newLockedTotal = asInt(invoke(economyContract, "updateDeliveryLocked", [(lockedTotal + MIN_USDT_FEE_DELIVERY)], nil))
3374+ let keyHealth = keyDuckHealth(duckAssetId)
3375+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
3376+ let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
3377+ let curLocKey = keyDuckLocation(duckAssetId)
3378+ let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
3379+ let deliveryLocation = (toString(now) + "_D_0")
3380+ $Tuple2([prologAction, IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, deliveryLocation)], $Tuple2(deliveryLocation, newLockedTotal))
3381+ }
32953382 }
32963383 }
32973384
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let DAYMILLIS = 86400000
5+
46 func keyLastArbTimeByUser (addr) = ("lastArbTimeUser_" + addr)
57
68
79 let SCALE8 = 100000000
810
911 let xpLevelScale = 3200
1012
1113 let xpLevelRecipPow = 4000
1214
1315 let numPointsOnLevelUp = 3
1416
1517 let robberyCostMin = 100000000
1618
1719 let robberyCooldownCoeff = 400
1820
1921 let requirements = ["Strength", "Accuracy", "Intellect", "Endurance", "Dexterity", "Level", "Health"]
2022
2123 let charStrength = 0
2224
2325 let charAccuracy = 1
2426
2527 let charIntellect = 2
2628
2729 let charEndurance = 3
2830
2931 let charDexterity = 4
3032
3133 let segBackpack = 0
3234
3335 let NUMSEGMENTS = 6
3436
3537 let NUMMAINAUX = 2
3638
3739 let MAXSLOTS = 2
3840
3941 let MAXPRODINSLOT = 30
4042
4143 let landRobCooldowns = [0, 600000, 900000, 43200000, 21600000]
4244
4345 let MIN_RES_TO_ROB = 20000000
4446
4547 let robIdxLocked = 1
4648
4749 let duckIdxFree = 0
4850
4951 let duckIdxPreparing = 1
5052
5153 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
5254
5355
5456 func keyDuckChars (duckAssetId) = ("duckChars_" + duckAssetId)
5557
5658
5759 func keyDuckXP (duckAssetId) = ("duckXP_" + duckAssetId)
5860
5961
6062 func keyDuckLevel (duckAssetId) = ("duckLevel_" + duckAssetId)
6163
6264
6365 func keyDuckFreePoints (duckAssetId) = ("duckFreePoints_" + duckAssetId)
6466
6567
6668 func keyDuckEquipment (duckAssetId) = ("duckEquipment_" + duckAssetId)
6769
6870
6971 func keyUserXP (addr) = ("userXP_" + addr)
7072
7173
7274 func keyUserLevel (addr) = ("userLevel_" + addr)
7375
7476
7577 func keyUserFreePoints (addr) = ("userFreePoints_" + addr)
7678
7779
7880 func keySavedHealth (duckAssetId) = ("savedHealth_" + duckAssetId)
7981
8082
8183 func keySavedLocation (duckAssetId) = ("savedLocation_" + duckAssetId)
8284
8385
8486 func keyDuckBuffs (duckAssetId) = ("duckBuffs_" + duckAssetId)
8587
8688
8789 func keyLastRobberyTimeByDuck (duckAssetId) = ("lastRobberyTime_" + duckAssetId)
8890
8991
9092 func keyLastRobberyCostByDuck (duckAssetId) = ("lastRobberyCost_" + duckAssetId)
9193
9294
9395 func keyLandRobberyState (landAssetId) = ("landRobberyState_" + landAssetId)
9496
9597
9698 func keyLandCooldownETA (landAssetId) = ("landCooldownETA_" + landAssetId)
9799
98100
99101 func keyDuckRobberyState (duckAssetId) = ("duckRobberyState_" + duckAssetId)
100102
101103
102104 func keyLockedLandByDuck (duckAssetId) = ("lockedLandByDuck_" + duckAssetId)
105+
106+
107+func keyDeliveryDelayByDuck (duckAssetId) = ("deliveryDelayByDuck_" + duckAssetId)
103108
104109
105110 let xpClaim = 10000
106111
107112 let xpSuccessFlight = 10000
108113
109114 let xpFailFlight = 2000
110115
111116 let xpCallES = 100000
112117
113118 let xpCustomName = 1000000
114119
115120 let xpNewSLand = 5000000
116121
117122 let xpUpgradeInfra = 10000
118123
119124 let xpMerge = 1000000
120125
121126 let xpOnboard = 1000000
122127
123128 let xpHeal = 10000
124129
125130 func levelByXP (xp) = fraction(xpLevelScale, pow(xp, 4, xpLevelRecipPow, 4, 4, DOWN), SCALE8)
126131
127132
128133 func maxHealth (level) = (100 + level)
129134
130135
131136 func levelUp (currLevel,newXP) = {
132137 let newLevel = levelByXP(newXP)
133138 [newLevel, (numPointsOnLevelUp * (newLevel - currLevel))]
134139 }
135140
136141
137142 func getDuckStats (stakingContract,duckAssetId,buffEffect,forceBuffs) = {
138143 let chars = split(valueOrElse(getString(stakingContract, keyDuckChars(duckAssetId)), "0_0_0_0_0"), "_")
139144 let lvl = valueOrElse(getInteger(stakingContract, keyDuckLevel(duckAssetId)), 0)
140145 let health = valueOrElse(getInteger(stakingContract, keyDuckHealth(duckAssetId)), maxHealth(lvl))
141146 let stateBuffs = split(valueOrElse(getString(stakingContract, keyDuckBuffs(duckAssetId)), "0_0_0_0_0"), "_")
142147 ([parseIntValue(chars[charStrength]), parseIntValue(chars[charAccuracy]), parseIntValue(chars[charIntellect]), parseIntValue(chars[charEndurance]), parseIntValue(chars[charDexterity]), lvl, health] ++ (if (forceBuffs)
143148 then [buffEffect, buffEffect, buffEffect, buffEffect, buffEffect]
144149 else [parseIntValue(stateBuffs[charStrength]), parseIntValue(stateBuffs[charAccuracy]), parseIntValue(stateBuffs[charIntellect]), parseIntValue(stateBuffs[charEndurance]), parseIntValue(stateBuffs[charDexterity])]))
145150 }
146151
147152
148153 func getRobberyData (stakingContract,duckAssetId) = {
149154 let lastRobCost = valueOrElse(getInteger(stakingContract, keyLastRobberyCostByDuck(duckAssetId)), 0)
150155 let lastRobTime = valueOrElse(getInteger(stakingContract, keyLastRobberyTimeByDuck(duckAssetId)), 0)
151156 let now = lastBlock.timestamp
152157 let robCost = max([robberyCostMin, (lastRobCost - (robberyCooldownCoeff * (now - lastRobTime)))])
153158 let duckState = valueOrElse(getInteger(stakingContract, keyDuckRobberyState(duckAssetId)), 0)
154159 let lockedLand = valueOrElse(getString(stakingContract, keyLockedLandByDuck(duckAssetId)), "")
155160 let landETA = valueOrElse(getInteger(stakingContract, keyLandCooldownETA(lockedLand)), 0)
156161 $Tuple5(robCost, lastRobTime, duckState, lockedLand, landETA)
157162 }
158163
159164
160165 let LANDPREFIX = "LAND"
161166
162167 let DUCKPREFIX = "DUCK"
163168
164169 let ARTPRESALE = "PRESALE"
165170
166171 let NUMRES = 6
167172
168173 let MAX_LANDS_STAKED_BY_USER = 25
169174
170175 let DAILYRESBYPIECE = 3456000
171176
172-let DAYMILLIS = 86400000
173-
174177 let WHMULTIPLIER = 10000000000
175178
176179 let DEFAULTLOCATION = "Africa_F_Africa"
177180
178181 let RESOURCEPRICEMIN = 39637
179182
180183 let ESSELLCOEF = 10
181184
182185 let MIN_USDT_FEE_DELIVERY = 50000
183186
184187 let prodTypes = ["First Aid Kit L1", "First Aid Kit L2", "First Aid Kit L3", "Backpack L1", "Backpack L2", "Backpack L3", "Food Ration L1", "Food Ration L2", "Food Ration L3", "Jet Pack L1", "Jet Pack L2", "Jet Pack L3", "Shield L1", "Shield L2", "Shield L3", "Mine L1", "Mine L2", "Mine L3", "Trap L1", "Trap L2", "Trap L3"]
185188
186189 let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
187190
188191 let COEFF2MAT = 10000000
189192
190193 let fortAllowedProds = [15, 16, 17, 18, 19, 20]
191194
192195 let productionMatrix = ["8_8_8_17_17_42_12_0_30_0,0,0,0,0,0,0_", "8_8_8_17_17_42_24_0_60_0,0,5,2,0,0,0_", "8_8_8_17_17_42_36_0_120_0,0,10,4,0,0,0_", "8_19_19_8_27_19_26_1_20_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_52_1_40_0,0,0,0,0,0,0_001", "8_19_19_8_27_19_78_1_80_0,0,0,0,0,0,0_001", "8_8_8_8_8_60_13_2_2_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_26_2_4_0,0,0,0,0,0,0_011", "8_8_8_8_8_60_39_2_8_0,0,0,0,0,0,0_011", "30_30_3_17_17_3_30_3_30_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_60_3_50_0,0,0,0,0,0,0_111", "30_30_3_17_17_3_90_3_70_0,0,0,0,0,0,0_111", "18_18_10_18_18_18_11_4_10_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_22_4_20_0,0,0,0,0,0,0_201", "18_18_10_18_18_18_33_4_30_0,0,0,0,0,0,0_201", "4_13_22_4_35_22_23_0_50,1,0_0,0,0,0,0,0,0_", "4_13_22_4_35_22_46_0_50,1,1_0,2,5,0,0,0,0_", "4_13_22_4_35_22_69_0_50,2,1_0,5,10,0,0,0,0_", "5_25_40_5_10_15_20_1_30,1,1_0,0,0,0,0,0,0_", "5_25_40_5_10_15_40_1_30,1,2_2,1,3,0,0,0,0_", "5_25_40_5_10_15_60_1_30,1,3_5,2,8,0,0,0,0_"]
193196
194197 let rIdxCoeff = 6
195198
196199 let rIdxEffect = 8
197200
198201 let rIdxRequirements = 9
199202
200203 let rIdxSlots = 10
201204
202205 let PRODUCTPKGSIZE = 10
203206
204207 let whIdxLevels = 0
205208
206209 let whIdxRes = 1
207210
208211 let whIdxMat = 2
209212
210213 let whIdxProd = 3
211214
212215 let whIdxLOFT = 4
213216
214217 let volLocked = 0
215218
216219 let volOccupied = 1
217220
218221 let volFree = 2
219222
220223 let volTotal = 3
221224
222225 let bpIdxLevel = 0
223226
224227 let bpIdxRes = 1
225228
226229 let bpIdxMat = 2
227230
228231 let bpIdxProd = 3
229232
230233 let locIdxContinent = 0
231234
232235 let locIdxType = 1
233236
234237 let locIdxId = 2
235238
236239 func keyLandAssetIdToOwner (assetId) = ("no_" + assetId)
237240
238241
239242 func keyLandAssetIdToCustomName (assetId) = ("lcna_" + assetId)
240243
241244
242245 func keyStakedTimeByAssetId (assetId) = ("st_" + assetId)
243246
244247
245248 func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["las", type, assetId], "_")
246249
247250
248251 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("sttao_" + nftType) + "_") + assetId) + "_") + ownerAddr)
249252
250253
251254 func keyWarehouseByLand (landAssetId) = ("wh_" + landAssetId)
252255
253256
254257 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
255258
256259
257260 func keyFortificationsByLand (landAssetId) = ("fortifications_" + landAssetId)
258261
259262
260263 func keyDuckAssetIdToCustomName (assetId) = ("duckCustomNameByAssetId_" + assetId)
261264
262265
263266 func keyAddressToCustomName (addr) = ("accountCustomNameByAddr_" + addr)
264267
265268
266269 func keyAddressRefBy (addr) = ("accRefBy_" + addr)
267270
268271
269272 func keyOnboardArtActivatedOnDuck (duckAssetId) = ("onboardArtActivatedOnDuck_" + duckAssetId)
270273
271274
272275 func keyOnboardArtDuckActivatedBy (addr) = ("onboardArtActivatedDuckBy_" + addr)
273276
274277
275278 func keyAddressReferrals (addr) = ("accReferrals_" + addr)
276279
277280
278281 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
279282
280283
281284 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
282285
283286
284287 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
285288
286289
287290 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
288291
289292
290293 func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
291294
292295
293296 func keyEsWarehouse () = "emergencyWarehouseProducts"
294297
295298
296299 let deliveryFundKey = "deliveryFund"
300+
301+let deliveryLockedKey = "deliveryLocked"
297302
298303 let lastTourIdKey = "%s__lastTourId"
299304
300305 func keyTourStaticDataById (tId) = ("%s%d__tourStaticData__" + toString(tId))
301306
302307
303308 func keyTourDynamicDataById (tId) = ("%s%d__tourDynamicData__" + toString(tId))
304309
305310
306311 func keyBestResultByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestResultByTourAndDuck", toString(tId), duckAssetId], "__")
307312
308313
309314 let idxStatic = 0
310315
311316 let idxDynamic = 1
312317
313318 let tStaticEnd = 6
314319
315320 let tDynamicStatus = 1
316321
317322 func getTourData (tourContract,tId) = {
318323 let static = split(valueOrErrorMessage(getString(tourContract, keyTourStaticDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
319324 let dynamic = split_4C(valueOrErrorMessage(getString(tourContract, keyTourDynamicDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
320325 [static, dynamic]
321326 }
322327
323328
324329 func isInTournament (tourContract,location) = {
325330 let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
326331 let loc = split(location, "_")
327332 let now = lastBlock.timestamp
328333 let tData = getTourData(tourContract, lastId)
329334 let static = tData[idxStatic]
330335 let dynamic = tData[idxDynamic]
331336 if (if (if ((loc[locIdxType] == "T"))
332337 then (parseIntValue(loc[locIdxContinent]) == lastId)
333338 else false)
334339 then (dynamic[tDynamicStatus] == "INPROGRESS")
335340 else false)
336341 then (parseIntValue(static[tStaticEnd]) > now)
337342 else false
338343 }
339344
340345
341346 func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT)
342347
343348
344349 let KS_SEPARATE_PUBLIC_KEY = false
345350
346351 let KS_ALLOW_BIG_INFRA_MERGE = false
347352
348353 let KS_ALLOW_DELIVERY = true
349354
350355 let chain = take(drop(this.bytes, 1), 1)
351356
352357 let usdtAssetId = match chain {
353358 case _ =>
354359 if ((base58'2W' == $match0))
355360 then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
356361 else if ((base58'2T' == $match0))
357362 then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
358363 else throw("Unknown chain")
359364 }
360365
361366 let defaultRestAddressStr = match chain {
362367 case _ =>
363368 if ((base58'2W' == $match0))
364369 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
365370 else if ((base58'2T' == $match0))
366371 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
367372 else throw("Unknown chain")
368373 }
369374
370375 let InfraUpgradeCostS = match chain {
371376 case _ =>
372377 if ((base58'2W' == $match0))
373378 then 10000000000
374379 else if ((base58'2T' == $match0))
375380 then 100000000
376381 else throw("Unknown chain")
377382 }
378383
379384 let arbitrageDelay = match chain {
380385 case _ =>
381386 if ((base58'2W' == $match0))
382387 then 86400000
383388 else if ((base58'2T' == $match0))
384389 then 60000
385390 else throw("Unknown chain")
386391 }
387392
388393 let SEP = "__"
389394
390395 let MULT6 = 1000000
391396
392397 let MULT8 = 100000000
393398
394399 let SSIZE = 25
395400
396401 let MSIZE = 100
397402
398403 let LSIZE = 225
399404
400405 let XLSIZE = 400
401406
402407 let XXLSIZE = 625
403408
404409 let ITER6 = [0, 1, 2, 3, 4, 5]
405410
406411 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
407412
408413
409414 let IdxCfgStakingDapp = 1
410415
411416 let IdxCfgEconomyDapp = 2
412417
413418 let IdxCfgGovernanceDapp = 3
414419
415420 let IdxCfgWlgDapp = 4
416421
417422 let IdxCfgTournamentDapp = 7
418423
419424 let IdxCfgAcresDapp = 8
420425
421426 func keyRestCfg () = "%s__restConfig"
422427
423428
424429 func keyRestAddress () = "%s__restAddr"
425430
426431
427432 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
428433
429434
430435 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
431436
432437
433438 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
434439
435440 let restCfg = readRestCfgOrFail(restContract)
436441
437442 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
438443
439444 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
440445
441446 let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
442447
443448 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
444449
445450 let tournamentContract = getContractAddressOrFail(restCfg, IdxCfgTournamentDapp)
446451
447452 let acresContract = getContractAddressOrFail(restCfg, IdxCfgAcresDapp)
448453
449454 let recLandNum = 0
450455
451456 let recLandSize = 1
452457
453458 let recTerrains = 2
454459
455460 let recContinent = 3
456461
457462 let wlgAssetIdKey = "wlg_assetId"
458463
459464 let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "WLGOLD is not issued yet")
460465
461466 let acresAssetIdKey = "acresAssetId"
462467
463468 let acresAssetId = valueOrErrorMessage(getBinary(acresContract, acresAssetIdKey), "ACRES is not issued yet")
464469
465470 let randomDelay = 2
466471
467472 func keyCommit (address) = ("finishBlockForAddr_" + address)
468473
469474
470475 func keyResProportions () = "resTypesProportions"
471476
472477
473478 func keyResTypesByContinent (continent) = ("resTypesByContinent_" + continent)
474479
475480
476481 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
477482
478483
479484 func keyStakedPiecesByOwner (ownerAddr) = ("stakedPiecesByOwner_" + ownerAddr)
480485
481486
482487 func asString (v) = match v {
483488 case s: String =>
484489 s
485490 case _ =>
486491 throw("fail to cast into String")
487492 }
488493
489494
490495 func asInt (v) = match v {
491496 case n: Int =>
492497 n
493498 case _ =>
494499 throw("fail to cast into Int")
495500 }
496501
497502
498503 func asBoolean (v) = match v {
499504 case s: Boolean =>
500505 s
501506 case _ =>
502507 throw("fail to cast into Boolean")
503508 }
504509
505510
506511 func numPiecesBySize (landSize) = match landSize {
507512 case _ =>
508513 if (("S" == $match0))
509514 then SSIZE
510515 else if (("M" == $match0))
511516 then MSIZE
512517 else if (("L" == $match0))
513518 then LSIZE
514519 else if (("XL" == $match0))
515520 then XLSIZE
516521 else if (("XXL" == $match0))
517522 then XXLSIZE
518523 else throw("Unknown land size")
519524 }
520525
521526
522527 func isDigit (s) = isDefined(parseInt(s))
523528
524529
525530 func keyBlocked () = "contractsBlocked"
526531
527532
528533 func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
529534
530535
536+func fixedPoint (val,decimals) = {
537+ let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
538+ let lowPart = toString((val % tenPow))
539+ let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
540+ (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
541+ }
542+
543+
531544 func getRandomNumber (maxValue,finishHeight,auxEntropy) = {
532545 let randomSeedBlock = value(blockInfoByHeight(finishHeight))
533546 let randomHash = sha256((value(randomSeedBlock.vrf) + auxEntropy))
534547 (toInt(randomHash) % maxValue)
535548 }
536549
537550
538551 let incubatorAddr = match chain {
539552 case _ =>
540553 if ((base58'2W' == $match0))
541554 then addressFromStringValue("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
542555 else if ((base58'2T' == $match0))
543556 then this
544557 else throw("Unknown chain")
545558 }
546559
547560 let breederAddr = match chain {
548561 case _ =>
549562 if ((base58'2W' == $match0))
550563 then addressFromStringValue("3PDVuU45H7Eh5dmtNbnRNRStGwULA7NY6Hb")
551564 else if ((base58'2T' == $match0))
552565 then this
553566 else throw("Unknown chain")
554567 }
555568
556569 let pub = match chain {
557570 case _ =>
558571 if ((base58'2W' == $match0))
559572 then if (KS_SEPARATE_PUBLIC_KEY)
560573 then base58'CWsMtTZC5BjjoL4Q1ayW4Wwb1ehGACQB6DrKyPgotKfm'
561574 else base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
562575 else if ((base58'2T' == $match0))
563576 then base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
564577 else throw("Unknown chain")
565578 }
566579
567580 let EMPTY_PROD50 = base64'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
568581
569582 let FIVEMINUTESMILLIS = 300000
583+
584+let TEN_MINUTES_MILLIS = 600000
570585
571586 let RENAMINGCOST = 5000000
572587
573588 let MAXNAMELEN = 50
574589
575590 let InfraUpgradeCostSUsdt = 10000000
576591
577592 let EXPMATERIALS = match chain {
578593 case _ =>
579594 if ((base58'2W' == $match0))
580595 then 252289527462
581596 else if ((base58'2T' == $match0))
582597 then 2522895274
583598 else throw("Unknown chain")
584599 }
585600
586601 let EXPUSDT = match chain {
587602 case _ =>
588603 if ((base58'2W' == $match0))
589604 then 250000000
590605 else if ((base58'2T' == $match0))
591606 then 250000000
592607 else throw("Unknown chain")
593608 }
594609
595610 let S_COST_ACRES = 2500000000
596611
597612 let FIVEX = toBigInt(5)
598613
599614 let TWENTYX = toBigInt(20)
600615
601616 let TWENTY2X = toBigInt((20 * 20))
602617
603618 let TWENTY3X = toBigInt(((20 * 20) * 20))
604619
605620 let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
606621
607622 let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
608623
609624 let PRESALENUMLANDS = 500
610625
611626 func keyNextFreeLandNum () = "nextLandNum"
612627
613628
614629 func keyLandCustomNameToAssetId (name) = ("lcn_" + name)
615630
616631
617632 func keyLandToAssetId (landNum) = ("la_" + landNum)
618633
619634
620635 func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("ilao_" + assetId) + "_") + ownerAddr)
621636
622637
623638 func keyLandNumToOwner (landNum) = ("lo_" + landNum)
624639
625640
626641 func keyDuckCustomNameToAssetId (name) = ("duckByCustomName_" + name)
627642
628643
629644 func keyCustomNameToAddress (name) = ("accountByCustomName_" + name)
630645
631646
632647 func keyOldies () = "oldiesList"
633648
634649
635650 let claimModeWh = 0
636651
637652 let claimModeDuck = 1
638653
639654 let claimModeWhThenDuck = 2
640655
641656 let flHealth = 0
642657
643658 let flTimestamp = 5
644659
645660 let flBonus = 6
646661
647662 let flProdsUsed = 7
648663
649664 func nftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
650665
651666
652667 func toVolume (amount,pkgSize) = {
653668 let pkgs = if ((amount >= 0))
654669 then (((amount + pkgSize) - 1) / pkgSize)
655670 else -((((-(amount) + pkgSize) - 1) / pkgSize))
656671 (pkgs * MULT8)
657672 }
658673
659674
660675 func distributeByWeights (total,weights) = {
661676 let sum = (((((weights[0] + weights[1]) + weights[2]) + weights[3]) + weights[4]) + weights[5])
662677 if ((0 >= sum))
663678 then throw("Zero weights sum")
664679 else {
665680 let norm6 = fraction(total, MULT6, sum)
666681 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
667682
668683 let $l = weights
669684 let $s = size($l)
670685 let $acc0 = nil
671686 func $f0_1 ($a,$i) = if (($i >= $s))
672687 then $a
673688 else normalizer($a, $l[$i])
674689
675690 func $f0_2 ($a,$i) = if (($i >= $s))
676691 then $a
677692 else throw("List size exceeds 6")
678693
679694 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
680695 }
681696 }
682697
683698
684699 func getNeededMaterials (total) = {
685700 let props = split(value(getString(keyResProportions())), "_")
686701 if ((size(props) != NUMRES))
687702 then throw("Wrong proportions data")
688703 else {
689704 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
690705 distributeByWeights(total, r)
691706 }
692707 }
693708
694709
695710 func subtractMaterials (shouldUseMat,has,totalNeed) = {
696711 let need = getNeededMaterials(totalNeed)
697712 func subtractor (acc,idx) = {
698713 let result = (parseIntValue(has[idx]) - need[idx])
699714 if ((0 > result))
700715 then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
701716 else (acc :+ toString(result))
702717 }
703718
704719 if (shouldUseMat)
705720 then {
706721 let $l = ITER6
707722 let $s = size($l)
708723 let $acc0 = nil
709724 func $f0_1 ($a,$i) = if (($i >= $s))
710725 then $a
711726 else subtractor($a, $l[$i])
712727
713728 func $f0_2 ($a,$i) = if (($i >= $s))
714729 then $a
715730 else throw("List size exceeds 6")
716731
717732 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
718733 }
719734 else has
720735 }
721736
722737
723738 func subtractEquipment (oldEq,pUsed) = if ((pUsed == ""))
724739 then $Tuple2(oldEq, false)
725740 else {
726741 func subUsed (acc,idxAmt) = {
727742 let parts = split(idxAmt, ",")
728743 if ((size(parts) != 2))
729744 then throw("Incorrect format, should be index,amount")
730745 else {
731746 let idx = parseIntValue(parts[0])
732747 if (if ((0 > idx))
733748 then true
734749 else (idx >= size(productionMatrix)))
735750 then throw("Unknown product idx")
736751 else {
737752 let amt = parseIntValue(parts[1])
738753 let eqParts = split(acc._1, (parts[0] + ":"))
739754 if ((size(eqParts) != 2))
740755 then throw((("You don't have " + prodTypes[idx]) + " equipped"))
741756 else {
742757 let tmp = eqParts[1]
743758 let numLen = if (isDigit(take(drop(tmp, 1), 1)))
744759 then 2
745760 else 1
746761 let curr = parseIntValue(take(tmp, numLen))
747762 let tail = drop(tmp, numLen)
748763 let newAmt = if ((curr >= amt))
749764 then (curr - amt)
750765 else throw(((((("You equipped " + toString(curr)) + " of ") + prodTypes[idx]) + ", but tried to use ") + toString(amt)))
751766 $Tuple2(((((eqParts[0] + parts[0]) + ":") + toString(newAmt)) + tail), if (acc._2)
752767 then true
753768 else if (if ((idx >= 6))
754769 then (8 >= idx)
755770 else false)
756771 then (newAmt == 0)
757772 else false)
758773 }
759774 }
760775 }
761776 }
762777
763778 let $l = split(pUsed, "_")
764779 let $s = size($l)
765780 let $acc0 = $Tuple2(oldEq, false)
766781 func $f0_1 ($a,$i) = if (($i >= $s))
767782 then $a
768783 else subUsed($a, $l[$i])
769784
770785 func $f0_2 ($a,$i) = if (($i >= $s))
771786 then $a
772787 else throw("List size exceeds 10")
773788
774789 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
775790 }
776791
777792
778793 func prodStrToBytes (prodStr) = {
779794 let pList = if ((prodStr == ""))
780795 then nil
781796 else split_4C(prodStr, "_")
782797 func toBV (acc,recipe) = {
783798 let j = (size(acc) / 8)
784799 let curr = if ((size(pList) > j))
785800 then parseIntValue(pList[j])
786801 else 0
787802 (acc + toBytes(curr))
788803 }
789804
790805 let $l = productionMatrix
791806 let $s = size($l)
792807 let $acc0 = base58''
793808 func $f0_1 ($a,$i) = if (($i >= $s))
794809 then $a
795810 else toBV($a, $l[$i])
796811
797812 func $f0_2 ($a,$i) = if (($i >= $s))
798813 then $a
799814 else throw("List size exceeds 50")
800815
801816 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
802817 }
803818
804819
805820 func bytesToProdStr (bv) = {
806821 func fromBV (acc,recipe) = {
807822 let j = size(acc)
808823 let b = take(drop(bv, (8 * j)), 8)
809824 (acc :+ toString(toInt(b)))
810825 }
811826
812827 makeString_2C({
813828 let $l = productionMatrix
814829 let $s = size($l)
815830 let $acc0 = nil
816831 func $f0_1 ($a,$i) = if (($i >= $s))
817832 then $a
818833 else fromBV($a, $l[$i])
819834
820835 func $f0_2 ($a,$i) = if (($i >= $s))
821836 then $a
822837 else throw("List size exceeds 50")
823838
824839 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
825840 }, "_")
826841 }
827842
828843
829844 func checkStatRequirements (duckStats,reqs) = {
830845 func check (acc,j) = {
831846 let buff = if ((size(duckStats) > (7 + j)))
832847 then duckStats[(7 + j)]
833848 else 0
834849 if ((parseIntValue(reqs[j]) > (duckStats[j] + buff)))
835850 then throw(("Requirement not satisfied: " + requirements[j]))
836851 else true
837852 }
838853
839854 let $l = [0, 1, 2, 3, 4, 5, 6]
840855 let $s = size($l)
841856 let $acc0 = false
842857 func $f0_1 ($a,$i) = if (($i >= $s))
843858 then $a
844859 else check($a, $l[$i])
845860
846861 func $f0_2 ($a,$i) = if (($i >= $s))
847862 then $a
848863 else throw("List size exceeds 7")
849864
850865 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7)
851866 }
852867
853868
854869 func placeProdB (idxCnt,pList,isPositive,duckStats,occupied,free) = {
855870 let parts = split(idxCnt, ":")
856871 if ((size(parts) != 2))
857872 then throw("Incorrect format, should be index:amount")
858873 else if (if (!(isPositive))
859874 then (size(parts[0]) != 2)
860875 else false)
861876 then throw("Product idx should be 2 digits, zero padded")
862877 else {
863878 let productIdx = parseIntValue(parts[0])
864879 let count = parseIntValue(parts[1])
865880 if (!(containsElement(fortAllowedProds, productIdx)))
866881 then throw((("Product '" + prodTypes[productIdx]) + "' cannot be used for land defense"))
867882 else if ((0 > count))
868883 then throw("Count can't be negative")
869884 else if ((count > MAXPRODINSLOT))
870885 then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
871886 else if ((count == 0))
872887 then $Tuple3(pList, occupied, free)
873888 else {
874889 let head = take(pList, (8 * productIdx))
875890 let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
876891 let tail = drop(pList, (8 * (productIdx + 1)))
877892 let recipe = split(productionMatrix[productIdx], "_")
878893 if (if (!(isPositive))
879894 then (count > curr)
880895 else false)
881896 then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
882897 else {
883898 let newAmt = if (if (!(isPositive))
884899 then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
885900 else false)
886901 then (curr - count)
887902 else (curr + count)
888903 let deltaVol = (toVolume(newAmt, PRODUCTPKGSIZE) - toVolume(curr, PRODUCTPKGSIZE))
889904 $Tuple3(((head + toBytes(newAmt)) + tail), (occupied + deltaVol), (free - deltaVol))
890905 }
891906 }
892907 }
893908 }
894909
895910
896911 func addProdB (idxCnt,pList,isPositive,segment,mainAux,slot,duckStats) = {
897912 let parts = split(idxCnt, ":")
898913 if ((size(parts) != 2))
899914 then throw("Incorrect format, should be index:amount")
900915 else if (if (!(isPositive))
901916 then (size(parts[0]) != 2)
902917 else false)
903918 then throw("Product idx should be 2 digits, zero padded")
904919 else {
905920 let productIdx = parseIntValue(parts[0])
906921 let count = parseIntValue(parts[1])
907922 if (if ((0 > productIdx))
908923 then true
909924 else (productIdx >= size(productionMatrix)))
910925 then throw("Unknown product idx")
911926 else if ((0 > count))
912927 then throw("Count can't be negative")
913928 else if ((count > MAXPRODINSLOT))
914929 then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
915930 else if ((count == 0))
916931 then $Tuple2(pList, false)
917932 else {
918933 let head = take(pList, (8 * productIdx))
919934 let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
920935 let tail = drop(pList, (8 * (productIdx + 1)))
921936 let recipe = split(productionMatrix[productIdx], "_")
922937 if (if (!(isPositive))
923938 then (count > curr)
924939 else false)
925940 then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
926941 else {
927942 let isBigItem = if (if (!(isPositive))
928943 then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
929944 else false)
930945 then {
931946 let compat = recipe[rIdxSlots]
932947 if ((compat == ""))
933948 then throw("Item cannot be equipped")
934949 else {
935950 let c = parseIntValue(compat)
936951 let cSeg = (c / 100)
937952 if ((segment != cSeg))
938953 then throw("Segment incompatible")
939954 else {
940955 let cMainAux = ((c % 100) / 10)
941956 if ((mainAux != cMainAux))
942957 then throw("Slot incompatible")
943958 else {
944959 let cNumSlots = (c % 10)
945960 if (if ((slot != 0))
946961 then (cNumSlots > 1)
947962 else false)
948963 then throw("Big items should occupy slot 0")
949964 else (cNumSlots > 1)
950965 }
951966 }
952967 }
953968 }
954969 else false
955970 $Tuple2(((head + toBytes((curr + (if (isPositive)
956971 then count
957972 else -(count))))) + tail), isBigItem)
958973 }
959974 }
960975 }
961976 }
962977
963978
964979 func slotsGroupB (g,bpIn,isPositive,segment,mainAux,stats) = if ((g != ""))
965980 then {
966981 let slots = split(g, ",")
967982 if ((size(slots) > MAXSLOTS))
968983 then throw("Wrong slots format")
969984 else {
970985 let s0 = slots[0]
971986 let s1 = if ((size(slots) > 1))
972987 then slots[1]
973988 else ""
974989 if (if ((s0 == ""))
975990 then (s1 == "")
976991 else false)
977992 then bpIn
978993 else {
979994 let tmpS0 = if ((s0 != ""))
980995 then addProdB(s0, bpIn, isPositive, segment, mainAux, 0, stats)
981996 else $Tuple2(bpIn, false)
982997 if ((s1 != ""))
983998 then if (tmpS0._2)
984999 then throw("Big item already occupies slot")
9851000 else addProdB(s1, tmpS0._1, isPositive, segment, mainAux, 1, stats)._1
9861001 else tmpS0._1
9871002 }
9881003 }
9891004 }
9901005 else bpIn
9911006
9921007
9931008 func dressB (segList,pBytes,isPositive,stats) = {
9941009 func segment (acc,seg) = {
9951010 let j = acc._1
9961011 let mainAux = split(seg, ";")
9971012 if ((size(mainAux) != NUMMAINAUX))
9981013 then throw("Wrong segment format")
9991014 else {
10001015 let m = mainAux[0]
10011016 let a = mainAux[1]
10021017 if (if ((m == ""))
10031018 then (a == "")
10041019 else false)
10051020 then $Tuple2((j + 1), acc._2)
10061021 else {
10071022 let tmpM = slotsGroupB(m, acc._2, isPositive, j, 0, stats)
10081023 $Tuple2((j + 1), slotsGroupB(a, tmpM, isPositive, j, 1, stats))
10091024 }
10101025 }
10111026 }
10121027
10131028 ( let $l = segList
10141029 let $s = size($l)
10151030 let $acc0 = $Tuple2(0, pBytes)
10161031 func $f0_1 ($a,$i) = if (($i >= $s))
10171032 then $a
10181033 else segment($a, $l[$i])
10191034
10201035 func $f0_2 ($a,$i) = if (($i >= $s))
10211036 then $a
10221037 else throw("List size exceeds 6")
10231038
10241039 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6))._2
10251040 }
10261041
10271042
10281043 func fortB (segList,pBytes,occupied,free,isPositive,duckStats) = if ((3 > size(segList)))
10291044 then throw("At least duck, mines and traps parts are required")
10301045 else {
10311046 func segment (acc,seg) = {
10321047 let j = acc._1
10331048 if ((j == 0))
10341049 then $Tuple4((j + 1), acc._2, acc._3, acc._4)
10351050 else {
10361051 let p = placeProdB(seg, acc._2, isPositive, duckStats, acc._3, acc._4)
10371052 $Tuple4((j + 1), p._1, p._2, p._3)
10381053 }
10391054 }
10401055
10411056 let t = {
10421057 let $l = segList
10431058 let $s = size($l)
10441059 let $acc0 = $Tuple4(0, pBytes, occupied, free)
10451060 func $f0_1 ($a,$i) = if (($i >= $s))
10461061 then $a
10471062 else segment($a, $l[$i])
10481063
10491064 func $f0_2 ($a,$i) = if (($i >= $s))
10501065 then $a
10511066 else throw("List size exceeds 10")
10521067
10531068 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
10541069 }
10551070 $Tuple3(t._2, t._3, t._4)
10561071 }
10571072
10581073
10591074 func canWearCurrentEquipment (duckAssetId) = {
10601075 let eqKey = keyDuckEquipment(duckAssetId)
10611076 let currEq = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
10621077 let tempProdB = dressB(currEq, EMPTY_PROD50, true, nil)
10631078 let segBpAux = split(currEq[segBackpack], ";")[1]
10641079 let buffEffect = if ((segBpAux == ""))
10651080 then 0
10661081 else {
10671082 let aux0 = split(segBpAux, ",")[0]
10681083 if ((aux0 == ""))
10691084 then 0
10701085 else {
10711086 let idxCnt = split(aux0, ":")
10721087 let idx = idxCnt[0]
10731088 let cnt = idxCnt[1]
10741089 if (if (if (if (if ((idx == "06"))
10751090 then true
10761091 else (idx == "07"))
10771092 then true
10781093 else (idx == "08"))
10791094 then (cnt != "")
10801095 else false)
10811096 then (parseIntValue(cnt) > 0)
10821097 else false)
10831098 then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
10841099 else 0
10851100 }
10861101 }
10871102 let stats = getDuckStats(this, duckAssetId, buffEffect, true)
10881103 let newProdB = dressB(currEq, tempProdB, false, stats)
10891104 (newProdB == newProdB)
10901105 }
10911106
10921107
10931108 func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
10941109 then throw("Wrong proportions data")
10951110 else {
10961111 func updater (acc,i) = {
10971112 let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
10981113 if ((0 > result))
10991114 then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
11001115 else (acc :+ toString(result))
11011116 }
11021117
11031118 let $l = ITER6
11041119 let $s = size($l)
11051120 let $acc0 = nil
11061121 func $f0_1 ($a,$i) = if (($i >= $s))
11071122 then $a
11081123 else updater($a, $l[$i])
11091124
11101125 func $f0_2 ($a,$i) = if (($i >= $s))
11111126 then $a
11121127 else throw("List size exceeds 6")
11131128
11141129 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
11151130 }
11161131
11171132
11181133 func updateProportions (terrainCounts,landSizeIndex,sign) = {
11191134 let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
11201135 makeString(updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign), "_")
11211136 }
11221137
11231138
11241139 func countTerrains (terrains) = [(size(split(terrains, "A")) - 1), (size(split(terrains, "B")) - 1), (size(split(terrains, "C")) - 1), (size(split(terrains, "D")) - 1), (size(split(terrains, "E")) - 1), (size(split(terrains, "F")) - 1)]
11251140
11261141
11271142 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
11281143 func adder (acc,i) = {
11291144 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
11301145 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
11311146 }
11321147
11331148 let r = {
11341149 let $l = ITER6
11351150 let $s = size($l)
11361151 let $acc0 = nil
11371152 func $f0_1 ($a,$i) = if (($i >= $s))
11381153 then $a
11391154 else adder($a, $l[$i])
11401155
11411156 func $f0_2 ($a,$i) = if (($i >= $s))
11421157 then $a
11431158 else throw("List size exceeds 6")
11441159
11451160 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
11461161 }
11471162 makeString(r, "_")
11481163 }
11491164
11501165
11511166 func virtClaim (terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
11521167 func adder (acc,i) = {
11531168 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
11541169 $Tuple2((acc._1 :+ resOfType), (acc._2 + resOfType))
11551170 }
11561171
11571172 let $l = ITER6
11581173 let $s = size($l)
11591174 let $acc0 = $Tuple2(nil, 0)
11601175 func $f0_1 ($a,$i) = if (($i >= $s))
11611176 then $a
11621177 else adder($a, $l[$i])
11631178
11641179 func $f0_2 ($a,$i) = if (($i >= $s))
11651180 then $a
11661181 else throw("List size exceeds 6")
11671182
11681183 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
11691184 }
11701185
11711186
11721187 func distributeRes (currentWhRes,currentPackRes,resToClaim,whSpaceLeft) = {
11731188 let resListToClaim = resToClaim._1
11741189 let resAmToClaim = resToClaim._2
11751190 if ((resAmToClaim == 0))
11761191 then $Tuple2(makeString(currentWhRes, "_"), makeString(currentPackRes, "_"))
11771192 else if ((whSpaceLeft >= resAmToClaim))
11781193 then {
11791194 func addLists (acc,i) = (acc :+ toString((parseIntValue(currentWhRes[i]) + resListToClaim[i])))
11801195
11811196 let r = {
11821197 let $l = ITER6
11831198 let $s = size($l)
11841199 let $acc0 = nil
11851200 func $f0_1 ($a,$i) = if (($i >= $s))
11861201 then $a
11871202 else addLists($a, $l[$i])
11881203
11891204 func $f0_2 ($a,$i) = if (($i >= $s))
11901205 then $a
11911206 else throw("List size exceeds 6")
11921207
11931208 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
11941209 }
11951210 $Tuple2(makeString(r, "_"), makeString(currentPackRes, "_"))
11961211 }
11971212 else {
11981213 func addPartLists (acc,i) = {
11991214 let whPart = fraction(resListToClaim[i], whSpaceLeft, resAmToClaim)
12001215 $Tuple2((acc._1 :+ toString((parseIntValue(currentWhRes[i]) + whPart))), (acc._2 :+ toString(((parseIntValue(currentPackRes[i]) + resListToClaim[i]) - whPart))))
12011216 }
12021217
12031218 let r = {
12041219 let $l = ITER6
12051220 let $s = size($l)
12061221 let $acc0 = $Tuple2(nil, nil)
12071222 func $f0_1 ($a,$i) = if (($i >= $s))
12081223 then $a
12091224 else addPartLists($a, $l[$i])
12101225
12111226 func $f0_2 ($a,$i) = if (($i >= $s))
12121227 then $a
12131228 else throw("List size exceeds 6")
12141229
12151230 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12161231 }
12171232 $Tuple2(makeString(r._1, "_"), makeString(r._2, "_"))
12181233 }
12191234 }
12201235
12211236
12221237 func abs (x) = if ((x >= toBigInt(0)))
12231238 then x
12241239 else -(x)
12251240
12261241
12271242 let freq = [[6, 9, 14, 15, 16], [5, 8, 13, 14, 15], [1, 4, 9, 10, 15], [1, 6, 7, 15, 19], [4, 7, 8, 13, 18]]
12281243
12291244 func genChar (n,freqs) = {
12301245 let rem = toInt((n % TWENTYX))
12311246 let letter = if ((freqs[0] > rem))
12321247 then "A"
12331248 else if ((freqs[1] > rem))
12341249 then "B"
12351250 else if ((freqs[2] > rem))
12361251 then "C"
12371252 else if ((freqs[3] > rem))
12381253 then "D"
12391254 else if ((freqs[4] > rem))
12401255 then "E"
12411256 else "F"
12421257 letter
12431258 }
12441259
12451260
12461261 func genTerrains (seed,continentIdx) = {
12471262 let f = freq[continentIdx]
12481263 func terrainGenerator (acc,elem) = $Tuple2((((((acc._1 + genChar(acc._2, f)) + genChar((acc._2 / TWENTYX), f)) + genChar((acc._2 / TWENTY2X), f)) + genChar((acc._2 / TWENTY3X), f)) + genChar((acc._2 / TWENTY4X), f)), (acc._2 / TWENTY5X))
12491264
12501265 let t = {
12511266 let $l = [1, 2, 3, 4, 5]
12521267 let $s = size($l)
12531268 let $acc0 = $Tuple2("", (seed / FIVEX))
12541269 func $f0_1 ($a,$i) = if (($i >= $s))
12551270 then $a
12561271 else terrainGenerator($a, $l[$i])
12571272
12581273 func $f0_2 ($a,$i) = if (($i >= $s))
12591274 then $a
12601275 else throw("List size exceeds 5")
12611276
12621277 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
12631278 }
12641279 t._1
12651280 }
12661281
12671282
12681283 let PERM25 = [7, 2, 15, 19, 8, 24, 1, 21, 16, 5, 0, 22, 20, 23, 11, 4, 18, 12, 6, 10, 3, 17, 13, 9, 14]
12691284
12701285 let TCHARS = ["A", "B", "C", "D", "E", "F"]
12711286
12721287 func genTerrainsForMerge (sumTerrains,landSizeIndex) = {
12731288 func step1 (acc,s) = {
12741289 let j = acc._2
12751290 let el = parseIntValue(s)
12761291 let x = if ((el == 0))
12771292 then 0
12781293 else if ((el >= (4 * landSizeIndex)))
12791294 then (el / landSizeIndex)
12801295 else if ((el > (3 * landSizeIndex)))
12811296 then 3
12821297 else (((el - 1) / landSizeIndex) + 1)
12831298 $Tuple3((acc._1 :+ x), (acc._2 + 1), (acc._3 + x))
12841299 }
12851300
12861301 let t = {
12871302 let $l = sumTerrains
12881303 let $s = size($l)
12891304 let $acc0 = $Tuple3(nil, 0, 0)
12901305 func $f0_1 ($a,$i) = if (($i >= $s))
12911306 then $a
12921307 else step1($a, $l[$i])
12931308
12941309 func $f0_2 ($a,$i) = if (($i >= $s))
12951310 then $a
12961311 else throw("List size exceeds 6")
12971312
12981313 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12991314 }
13001315 let arr = t._1
13011316 let maxIdx = value(indexOf(arr, max(arr)))
13021317 let delta = (t._3 - 25)
13031318 func subber (acc,idx) = {
13041319 let val = if ((idx == maxIdx))
13051320 then (arr[idx] - delta)
13061321 else arr[idx]
13071322 let zeroes = if ((val == 0))
13081323 then nil
13091324 else split(drop(toString(pow(10, 0, val, 0, 0, DOWN)), 1), "")
13101325 let c = TCHARS[idx]
13111326 func listGen (ac,ignored) = (ac :+ c)
13121327
13131328 let z = {
13141329 let $l = zeroes
13151330 let $s = size($l)
13161331 let $acc0 = nil
13171332 func $f1_1 ($a,$i) = if (($i >= $s))
13181333 then $a
13191334 else listGen($a, $l[$i])
13201335
13211336 func $f1_2 ($a,$i) = if (($i >= $s))
13221337 then $a
13231338 else throw("List size exceeds 25")
13241339
13251340 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25)
13261341 }
13271342 (acc ++ z)
13281343 }
13291344
13301345 let r = {
13311346 let $l = ITER6
13321347 let $s = size($l)
13331348 let $acc0 = nil
13341349 func $f1_1 ($a,$i) = if (($i >= $s))
13351350 then $a
13361351 else subber($a, $l[$i])
13371352
13381353 func $f1_2 ($a,$i) = if (($i >= $s))
13391354 then $a
13401355 else throw("List size exceeds 6")
13411356
13421357 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
13431358 }
13441359 func permut (acc,j) = (acc + r[j])
13451360
13461361 let $l = PERM25
13471362 let $s = size($l)
13481363 let $acc0 = ""
13491364 func $f2_1 ($a,$i) = if (($i >= $s))
13501365 then $a
13511366 else permut($a, $l[$i])
13521367
13531368 func $f2_2 ($a,$i) = if (($i >= $s))
13541369 then $a
13551370 else throw("List size exceeds 25")
13561371
13571372 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25)
13581373 }
13591374
13601375
13611376 func getBackpack (bpKey) = {
13621377 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
13631378 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
13641379 then p[bpIdxRes]
13651380 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
13661381 then p[bpIdxMat]
13671382 else "0_0_0_0_0_0", p[bpIdxProd]]
13681383 }
13691384
13701385
13711386 func getWarehouseTotalVolume (volPrefix) = {
13721387 let parts = split(volPrefix, "_")
13731388 ((WHMULTIPLIER * (parseIntValue(parts[1]) + 1)) * parseIntValue(parts[0]))
13741389 }
13751390
13761391
13771392 func getWarehouseOccupiedVol (currentWh) = {
13781393 let goods = currentWh[whIdxProd]
13791394 func sumResMat (acc,item) = (acc + parseIntValue(item))
13801395
13811396 func sumProd (acc,item) = {
13821397 let idx = acc._1
13831398 let pkgs = (((parseIntValue(item) + PRODUCTPKGSIZE) - 1) / PRODUCTPKGSIZE)
13841399 $Tuple2((idx + 1), (acc._2 + (pkgs * MULT8)))
13851400 }
13861401
13871402 let whResVol = {
13881403 let $l = split(currentWh[whIdxRes], "_")
13891404 let $s = size($l)
13901405 let $acc0 = 0
13911406 func $f0_1 ($a,$i) = if (($i >= $s))
13921407 then $a
13931408 else sumResMat($a, $l[$i])
13941409
13951410 func $f0_2 ($a,$i) = if (($i >= $s))
13961411 then $a
13971412 else throw("List size exceeds 6")
13981413
13991414 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
14001415 }
14011416 let whMatVol = {
14021417 let $l = split(currentWh[whIdxMat], "_")
14031418 let $s = size($l)
14041419 let $acc0 = 0
14051420 func $f1_1 ($a,$i) = if (($i >= $s))
14061421 then $a
14071422 else sumResMat($a, $l[$i])
14081423
14091424 func $f1_2 ($a,$i) = if (($i >= $s))
14101425 then $a
14111426 else throw("List size exceeds 6")
14121427
14131428 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
14141429 }
14151430 let whGoodsVol = if ((goods == ""))
14161431 then 0
14171432 else ( let $l = split_4C(goods, "_")
14181433 let $s = size($l)
14191434 let $acc0 = $Tuple2(0, 0)
14201435 func $f2_1 ($a,$i) = if (($i >= $s))
14211436 then $a
14221437 else sumProd($a, $l[$i])
14231438
14241439 func $f2_2 ($a,$i) = if (($i >= $s))
14251440 then $a
14261441 else throw("List size exceeds 50")
14271442
14281443 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50))._2
14291444 ((whResVol + whMatVol) + whGoodsVol)
14301445 }
14311446
14321447
14331448 func getWarehouse (whKey,landIndex,infraLevel) = {
14341449 let volPrefix = ((toString(landIndex) + "_") + toString(infraLevel))
14351450 let whTotal = getWarehouseTotalVolume(volPrefix)
14361451 let whStr = valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0::0"))
14371452 let wh = split_4C(whStr, ":")
14381453 let whOccupied = getWarehouseOccupiedVol(wh)
14391454 let whLoft = if ((5 > size(wh)))
14401455 then makeString(["0", toString(whOccupied), toString((whTotal - whOccupied)), toString(whTotal)], "_")
14411456 else {
14421457 let loft = split(wh[whIdxLOFT], "_")
14431458 let whLocked = parseIntValue(loft[volLocked])
14441459 let occ = if ((size(loft) > 1))
14451460 then parseIntValue(loft[volOccupied])
14461461 else whOccupied
14471462 makeString([toString(whLocked), toString(occ), toString(((whTotal - whLocked) - occ)), toString(whTotal)], "_")
14481463 }
14491464 [wh[whIdxLevels], if ((size(split(wh[whIdxRes], "_")) == NUMRES))
14501465 then wh[whIdxRes]
14511466 else "0_0_0_0_0_0", if ((size(split(wh[whIdxMat], "_")) == NUMRES))
14521467 then wh[whIdxMat]
14531468 else "0_0_0_0_0_0", wh[whIdxProd], whLoft]
14541469 }
14551470
14561471
14571472 func getWarehouseSpaceLeft (currentWh) = {
14581473 let occupiedVol = getWarehouseOccupiedVol(currentWh)
14591474 let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
14601475 ((getWarehouseTotalVolume(currentWh[whIdxLevels]) - occupiedVol) - currWhLockedVol)
14611476 }
14621477
14631478
14641479 func moveStuff (cargoParts,currentWh,currentPack) = if ((size(cargoParts) != 3))
14651480 then throw("cargoListStr should contain exactly 2 ':' separators")
14661481 else {
14671482 let resParts = split(cargoParts[0], "_")
14681483 let matParts = split(cargoParts[1], "_")
14691484 let prodParts = if ((cargoParts[2] == ""))
14701485 then nil
14711486 else split_4C(cargoParts[2], "_")
14721487 if ((size(resParts) != NUMRES))
14731488 then throw("All 6 resources should be passed")
14741489 else if ((size(matParts) != NUMRES))
14751490 then throw("All 6 materials should be passed")
14761491 else {
14771492 let whSpaceLeft = getWarehouseSpaceLeft(currentWh)
14781493 let currWhRes = split(currentWh[whIdxRes], "_")
14791494 let currWhMat = split(currentWh[whIdxMat], "_")
14801495 let currWhProd = if ((currentWh[whIdxProd] == ""))
14811496 then nil
14821497 else split_4C(currentWh[whIdxProd], "_")
14831498 let currentPackRes = split(currentPack[bpIdxRes], "_")
14841499 let currentPackMat = split(currentPack[bpIdxMat], "_")
14851500 let currentPackProd = if ((currentPack[bpIdxProd] == ""))
14861501 then nil
14871502 else split_4C(currentPack[bpIdxProd], "_")
14881503 func mvR (acc,item) = {
14891504 let i = acc._1
14901505 let am = parseIntValue(item)
14911506 let whr = parseIntValue(currWhRes[i])
14921507 let bpr = parseIntValue(currentPackRes[i])
14931508 if ((am == 0))
14941509 then $Tuple4((i + 1), (acc._2 :+ currWhRes[i]), (acc._3 :+ currentPackRes[i]), acc._4)
14951510 else if ((am > 0))
14961511 then if ((am > bpr))
14971512 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpr)) + " available"))
14981513 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
14991514 else if ((-(am) > whr))
15001515 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whr)) + " available"))
15011516 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
15021517 }
15031518
15041519 let r = {
15051520 let $l = resParts
15061521 let $s = size($l)
15071522 let $acc0 = $Tuple4(0, nil, nil, 0)
15081523 func $f0_1 ($a,$i) = if (($i >= $s))
15091524 then $a
15101525 else mvR($a, $l[$i])
15111526
15121527 func $f0_2 ($a,$i) = if (($i >= $s))
15131528 then $a
15141529 else throw("List size exceeds 6")
15151530
15161531 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
15171532 }
15181533 func mvM (acc,item) = {
15191534 let i = acc._1
15201535 let am = parseIntValue(item)
15211536 let whm = parseIntValue(currWhMat[i])
15221537 let bpm = parseIntValue(currentPackMat[i])
15231538 if ((am == 0))
15241539 then $Tuple4((i + 1), (acc._2 :+ currWhMat[i]), (acc._3 :+ currentPackMat[i]), acc._4)
15251540 else if ((am > 0))
15261541 then if ((am > bpm))
15271542 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpm)) + " available"))
15281543 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
15291544 else if ((-(am) > whm))
15301545 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whm)) + " available"))
15311546 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
15321547 }
15331548
15341549 let m = {
15351550 let $l = matParts
15361551 let $s = size($l)
15371552 let $acc0 = $Tuple4(0, nil, nil, r._4)
15381553 func $f1_1 ($a,$i) = if (($i >= $s))
15391554 then $a
15401555 else mvM($a, $l[$i])
15411556
15421557 func $f1_2 ($a,$i) = if (($i >= $s))
15431558 then $a
15441559 else throw("List size exceeds 6")
15451560
15461561 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
15471562 }
15481563 func mvP (acc,item) = {
15491564 let i = acc._1
15501565 let am = parseIntValue(item)
15511566 let whp = if ((size(currWhProd) > i))
15521567 then parseIntValue(currWhProd[i])
15531568 else 0
15541569 let bpp = if ((size(currentPackProd) > i))
15551570 then parseIntValue(currentPackProd[i])
15561571 else 0
15571572 if ((am == 0))
15581573 then $Tuple4((i + 1), (acc._2 :+ toString(whp)), (acc._3 :+ toString(bpp)), acc._4)
15591574 else if ((am > 0))
15601575 then if ((am > bpp))
15611576 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpp)) + " available"))
15621577 else {
15631578 let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
15641579 $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
15651580 }
15661581 else if ((-(am) > whp))
15671582 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whp)) + " available"))
15681583 else {
15691584 let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
15701585 $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
15711586 }
15721587 }
15731588
15741589 let p = if ((size(prodParts) != 0))
15751590 then {
15761591 let $l = prodParts
15771592 let $s = size($l)
15781593 let $acc0 = $Tuple4(0, nil, nil, m._4)
15791594 func $f2_1 ($a,$i) = if (($i >= $s))
15801595 then $a
15811596 else mvP($a, $l[$i])
15821597
15831598 func $f2_2 ($a,$i) = if (($i >= $s))
15841599 then $a
15851600 else throw("List size exceeds 50")
15861601
15871602 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
15881603 }
15891604 else $Tuple4(0, currWhProd, currentPackProd, m._4)
15901605 let volSaldo = p._4
15911606 if ((volSaldo > whSpaceLeft))
15921607 then throw((((("Attempt to put total " + toString(volSaldo)) + " stuff, but only ") + toString(whSpaceLeft)) + " warehouse space left"))
15931608 else $Tuple7(makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_"), makeString(r._3, "_"), makeString(m._3, "_"), makeString_2C(p._3, "_"), volSaldo)
15941609 }
15951610 }
15961611
15971612
15981613 func expeditionInternal (caller,txId) = {
15991614 let userAddr = toString(caller)
16001615 let bigNum = abs(toBigInt(txId))
16011616 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
16021617 let landNum = toString(freeNum)
16031618 let continentIdx = toInt((bigNum % FIVEX))
16041619 let terrains = genTerrains(bigNum, continentIdx)
16051620 let continent = continents[continentIdx]
16061621 let issue = Issue(nftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
16071622 let assetId = calculateAssetId(issue)
16081623 let id = toBase58String(assetId)
16091624 $Tuple2([IntegerEntry(keyNextFreeLandNum(), (freeNum + 1)), issue, StringEntry(keyLandToAssetId(landNum), id), StringEntry(keyLandAssetIdToOwner(id), userAddr), StringEntry(keyLandNumToOwner(landNum), userAddr), IntegerEntry(keyInfraLevelByAssetId(id), 0), IntegerEntry(keyInfraLevelByAssetIdAndOwner(id, userAddr), 0), ScriptTransfer(caller, 1, assetId)], $Tuple2(id, continent))
16101625 }
16111626
16121627
16131628 func flightCommon (userAddr,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
16141629 then throw("signature does not match")
16151630 else {
16161631 let parts = split_4C(toUtf8String(message), ";")
16171632 let flightLog = split_4C(parts[0], "|")
16181633 let hp = split(flightLog[flHealth], "_")
16191634 let curHP = parseIntValue(hp[0])
16201635 let newHP = parseIntValue(hp[1])
16211636 let newLocTxVer = split(parts[1], ":")
16221637 let newLocation = newLocTxVer[0]
16231638 let time = parseIntValue(flightLog[flTimestamp])
16241639 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
16251640 then true
16261641 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
16271642 then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
16281643 else {
16291644 let txFromMsg = newLocTxVer[1]
16301645 let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
16311646 if ((lastTx != txFromMsg))
16321647 then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
16331648 else {
16341649 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
16351650 let keyHealth = keyDuckHealth(duckAssetId)
16361651 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
16371652 let oldFromState = valueOrElse(getInteger(keyHealth), maxHP)
16381653 if ((oldFromState != curHP))
16391654 then throw(((("oldHealth=" + toString(oldFromState)) + " from state does not match one from flight log=") + toString(curHP)))
16401655 else if ((0 >= curHP))
16411656 then throw("You can't fly with zero health")
16421657 else if (!(canWearCurrentEquipment(duckAssetId)))
16431658 then throw("Equipment incompatible")
16441659 else {
16451660 let bonus = if ((size(flightLog) > flBonus))
16461661 then flightLog[flBonus]
16471662 else ""
16481663 let prodUsed = if ((size(flightLog) > flProdsUsed))
16491664 then flightLog[flProdsUsed]
16501665 else ""
16511666 let sentAmount = if (if ((newHP > 0))
16521667 then (bonus == "$")
16531668 else false)
16541669 then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
16551670 else 0
16561671 $Tuple5(newHP, duckAssetId, sentAmount, newLocation, prodUsed)
16571672 }
16581673 }
16591674 }
16601675 }
16611676
16621677
16631678 func applyBonuses (landAssetId,pieces) = {
16641679 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
16651680 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
16661681 let add6 = (infraLevel / 6)
16671682 let add7 = (infraLevel / 7)
16681683 ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, ((infraLevel + add6) + (2 * add7)), 5)) + fraction(DAILYRESBYPIECE, artPieces, (pieces * 5)))
16691684 }
16701685
16711686
16721687 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
1673- let $t03373834277 = if ((claimMode == claimModeWh))
1688+ let $t03378434323 = if ((claimMode == claimModeWh))
16741689 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
16751690 else {
16761691 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
16771692 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
16781693 let loc = split(value(curLocation), "_")
16791694 if ((loc[locIdxType] != "L"))
16801695 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
16811696 else $Tuple2(loc[locIdxId], duckAssetId)
16821697 }
1683- let landAssetId = $t03373834277._1
1684- let duckId = $t03373834277._2
1698+ let landAssetId = $t03378434323._1
1699+ let duckId = $t03378434323._2
16851700 let asset = value(assetInfo(fromBase58String(landAssetId)))
16861701 let timeKey = keyStakedTimeByAssetId(landAssetId)
16871702 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
16881703 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
16891704 if ((owner != addr))
16901705 then throw((LANDPREFIX + " is not yours"))
16911706 else {
16921707 let d = split(asset.description, "_")
16931708 $Tuple4(duckId, landAssetId, d, savedTime)
16941709 }
16951710 }
16961711
16971712
16981713 func claimResInternal (addr,amount,claimMode,landAssetIdIn) = if ((0 > amount))
16991714 then throw("Negative amount")
17001715 else {
17011716 let c = checkClaimConditions(addr, claimMode, landAssetIdIn)
17021717 let landSize = c._3[recLandSize]
17031718 let terrainCounts = countTerrains(c._3[recTerrains])
17041719 let deltaTime = (lastBlock.timestamp - c._4)
17051720 if ((0 > deltaTime))
17061721 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", current = ") + toString(lastBlock.timestamp)))
17071722 else {
17081723 let pieces = numPiecesBySize(landSize)
17091724 let dailyProductionByPiece = applyBonuses(c._2, pieces)
17101725 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
17111726 if ((amount > availRes))
17121727 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
17131728 else {
17141729 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
17151730 let newTimestamp = (lastBlock.timestamp - newDeltaTime)
17161731 let landIndex = (pieces / SSIZE)
17171732 let resToClaim = virtClaim(terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece)
17181733 let whKey = keyWarehouseByLand(c._2)
17191734 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(c._2)), 0)
17201735 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
17211736 let loft = split(currentWh[whIdxLOFT], "_")
17221737 let whSpaceLeft = parseIntValue(loft[volFree])
17231738 if (if ((claimMode == claimModeWh))
17241739 then (amount > whSpaceLeft)
17251740 else false)
17261741 then throw((("Only " + toString(whSpaceLeft)) + " space left in warehouse"))
17271742 else {
17281743 let bpKey = keyBackpackByDuck(c._1)
17291744 let currentPack = getBackpack(bpKey)
17301745 let currentPackRes = split(currentPack[bpIdxRes], "_")
17311746 let currentWhRes = split(currentWh[whIdxRes], "_")
1732- let $t03665137522 = if ((claimMode == claimModeWh))
1747+ let $t03669737568 = if ((claimMode == claimModeWh))
17331748 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
17341749 else if ((claimMode == claimModeDuck))
17351750 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
17361751 else {
17371752 let distr = distributeRes(currentWhRes, currentPackRes, resToClaim, whSpaceLeft)
17381753 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
17391754 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
17401755 }
1741- let whRes = $t03665137522._1
1742- let bpRes = $t03665137522._2
1743- let loftO = $t03665137522._3
1744- let loftF = $t03665137522._4
1756+ let whRes = $t03669737568._1
1757+ let bpRes = $t03669737568._2
1758+ let loftO = $t03669737568._3
1759+ let loftF = $t03669737568._4
17451760 $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxLevels], whRes, currentWh[whIdxMat], currentWh[whIdxProd], makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")])
17461761 }
17471762 }
17481763 }
17491764 }
17501765
17511766
17521767 func claimAll (addr,landAssetId,pieces,claimMode) = {
17531768 let timeKey = keyStakedTimeByAssetId(landAssetId)
17541769 let savedTime = value(getInteger(timeKey))
17551770 let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
17561771 claimResInternal(addr, availRes, claimMode, landAssetId)
17571772 }
17581773
17591774
17601775 func upInfraCommon (shouldUseMat,caller,paymentAmount,landAssetId) = {
17611776 let addr = toString(caller)
17621777 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetId)
17631778 let pieces = numPiecesBySize(c._3[recLandSize])
17641779 let infraKey = keyInfraLevelByAssetId(c._2)
17651780 let curLevel = valueOrElse(getInteger(infraKey), 0)
17661781 if (if (!(KS_ALLOW_BIG_INFRA_MERGE))
17671782 then (curLevel >= 3)
17681783 else false)
17691784 then throw("Currently max infrastructure level = 3")
17701785 else {
17711786 let maxInfra = ((sqrt(pieces, 0, 0, DOWN) / 5) + 2)
17721787 let newLevel = (curLevel + 1)
17731788 if (if (KS_ALLOW_BIG_INFRA_MERGE)
17741789 then (newLevel > maxInfra)
17751790 else false)
17761791 then throw(("Currently max infrastructure level = " + toString(maxInfra)))
17771792 else {
17781793 let cost = fraction(InfraUpgradeCostSUsdt, (pieces * newLevel), SSIZE)
17791794 if (if (!(shouldUseMat))
17801795 then (paymentAmount != cost)
17811796 else false)
17821797 then throw(("Payment attached should be " + toString(cost)))
17831798 else {
17841799 let bpKey = keyBackpackByDuck(c._1)
17851800 let currentPack = getBackpack(bpKey)
17861801 let mList = split(currentPack[bpIdxMat], "_")
17871802 let matUsed = fraction(InfraUpgradeCostS, (pieces * newLevel), SSIZE)
17881803 let newMat = makeString(subtractMaterials(shouldUseMat, mList, matUsed), "_")
17891804 let claimResult = claimAll(addr, c._2, pieces, claimModeWhThenDuck)
17901805 let whData = claimResult._5
17911806 let oldVol = getWarehouseTotalVolume(whData[whIdxLevels])
17921807 let newVolData = makeString([split(whData[whIdxLevels], "_")[0], toString(newLevel)], "_")
17931808 let newVol = getWarehouseTotalVolume(newVolData)
17941809 let loft = split(whData[whIdxLOFT], "_")
17951810 let newLoftStr = makeString([loft[volLocked], loft[volOccupied], toString(((parseIntValue(loft[volFree]) + newVol) - oldVol)), toString(newVol)], "_")
17961811 $Tuple3(([IntegerEntry(infraKey, newLevel), IntegerEntry(keyInfraLevelByAssetIdAndOwner(c._2, addr), newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], claimResult._3[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), StringEntry(claimResult._4, makeString([newVolData, whData[whIdxRes], whData[whIdxMat], whData[whIdxProd], newLoftStr], ":"))] ++ claimResult._1), newLevel, matUsed)
17971812 }
17981813 }
17991814 }
18001815 }
18011816
18021817
18031818 func updateDuckStatsInternal (duckAssetId,deltaXP) = {
18041819 let lvlKey = keyDuckLevel(duckAssetId)
18051820 let xpKey = keyDuckXP(duckAssetId)
18061821 let xp = valueOrElse(getInteger(stakingContract, xpKey), 0)
18071822 let newXP = (xp + deltaXP)
18081823 let lvlPoints = levelUp(valueOrElse(getInteger(stakingContract, lvlKey), 0), newXP)
18091824 let keyPoints = keyDuckFreePoints(duckAssetId)
18101825 $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(keyPoints, (valueOrElse(getInteger(keyPoints), 0) + lvlPoints[1]))], newXP)
18111826 }
18121827
18131828
18141829 func updateAccStatsInternal (addr,deltaXP) = {
18151830 let lvlKey = keyUserLevel(addr)
18161831 let xpKey = keyUserXP(addr)
18171832 let xp = valueOrElse(getInteger(stakingContract, xpKey), 0)
18181833 let newXP = (xp + deltaXP)
18191834 let lvlPoints = levelUp(valueOrElse(getInteger(stakingContract, lvlKey), 0), newXP)
18201835 let keyPoints = keyUserFreePoints(addr)
18211836 $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(keyPoints, (valueOrElse(getInteger(keyPoints), 0) + lvlPoints[1]))], newXP)
18221837 }
18231838
18241839
18251840 func activateOnboardArt (addr) = {
18261841 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
18271842 let refByKey = keyAddressRefBy(addr)
18281843 let refBy = getString(refByKey)
18291844 if (!(isDefined(refBy)))
18301845 then throw("You are not eligible for ONBOARD artifact")
18311846 else {
18321847 let artKey = keyOnboardArtDuckActivatedBy(addr)
18331848 let artDuck = getString(artKey)
18341849 if (isDefined(artDuck))
18351850 then throw(("You already used your ONBOARD artifact on duck " + value(artDuck)))
18361851 else {
18371852 let duckActivatorKey = keyOnboardArtActivatedOnDuck(duckAssetId)
18381853 let duckActivator = getString(duckActivatorKey)
18391854 if (isDefined(duckActivator))
18401855 then throw(((("The duck " + duckAssetId) + " already got points from ONBOARD artifact from user ") + value(duckActivator)))
18411856 else ([StringEntry(artKey, duckAssetId), StringEntry(duckActivatorKey, addr)] ++ updateDuckStatsInternal(duckAssetId, xpOnboard)._1)
18421857 }
18431858 }
18441859 }
18451860
18461861
18471862 func activatePresaleArt (addr,landAssetIdIn) = {
18481863 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetIdIn)
18491864 let landAssetId = c._2
18501865 let pieces = numPiecesBySize(c._3[recLandSize])
18511866 let activationKey = keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)
18521867 if ((valueOrElse(getInteger(activationKey), 0) > 0))
18531868 then throw("Presale artifact is already activated")
18541869 else if ((parseIntValue(c._3[recLandNum]) > PRESALENUMLANDS))
18551870 then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
18561871 else {
18571872 let claimResult = claimAll(addr, landAssetId, pieces, claimModeWhThenDuck)
18581873 (((claimResult._1 :+ IntegerEntry(activationKey, pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":"))) :+ StringEntry(claimResult._4, makeString(claimResult._5, ":")))
18591874 }
18601875 }
18611876
18621877
18631878 func checkTournament (duckAssetId) = {
18641879 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
18651880 let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
18661881 let now = lastBlock.timestamp
18671882 let tData = getTourData(tournamentContract, lastId)
18681883 let static = tData[idxStatic]
18691884 let dynamic = tData[idxDynamic]
18701885 if ((curLocation[locIdxType] != "T"))
18711886 then false
18721887 else if (if (if ((parseIntValue(curLocation[locIdxContinent]) == lastId))
18731888 then (dynamic[tDynamicStatus] == "INPROGRESS")
18741889 else false)
18751890 then (parseIntValue(static[tStaticEnd]) > now)
18761891 else false)
18771892 then throw("Your duck is taking part in the tournament")
18781893 else asBoolean(invoke(this, "exitTournamentInternal", [duckAssetId], nil))
18791894 }
18801895
18811896
1897+func checkDelivery (duckAssetId) = {
1898+ let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1899+ let now = lastBlock.timestamp
1900+ if ((curLocation[locIdxType] != "D"))
1901+ then false
1902+ else {
1903+ let startTime = parseIntValue(curLocation[locIdxContinent])
1904+ let distance = parseIntValue(curLocation[locIdxId])
1905+ if (if ((now > (startTime + TEN_MINUTES_MILLIS)))
1906+ then (3 > distance)
1907+ else false)
1908+ then throw("Your duck is on delivery mission")
1909+ else asBoolean(invoke(this, "exitDeliveryInternal", [duckAssetId], nil))
1910+ }
1911+ }
1912+
1913+
18821914 func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,needMat) = {
18831915 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
18841916 if (checkTournament(duckAssetId))
18851917 then throw("mergeInternal_checkTournament")
1886- else {
1887- func checkMerge (acc,landAssetId) = {
1888- let asset = value(assetInfo(fromBase58String(landAssetId)))
1889- let timeKey = keyStakedTimeByAssetId(landAssetId)
1890- let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
1891- let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1892- if ((owner != addr))
1893- then throw((LANDPREFIX + " is not yours"))
1894- else {
1895- let d = split(asset.description, "_")
1896- let continent = d[recContinent]
1897- if (if ((acc._3 != ""))
1898- then (acc._3 != continent)
1899- else false)
1900- then throw("Lands should be on the same continent to merge")
1901- else {
1902- let landSize = d[recLandSize]
1903- let sizesIn = acc._1
1904- let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
1905- let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
1906- let pieces = numPiecesBySize(landSize)
1907- let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
1908- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1909- let reqLevel = match landSize {
1910- case _ =>
1911- if (("S" == $match0))
1912- then 3
1913- else if (("M" == $match0))
1914- then 4
1915- else if (("L" == $match0))
1916- then 5
1917- else if (("XL" == $match0))
1918- then 6
1919- else throw("Only S, M, L, XL can merge")
1920- }
1921- if ((infraLevel != reqLevel))
1922- then throw("All lands should be maxed to merge")
1923- else {
1924- let landNum = d[recLandNum]
1925- let terrainCounts = countTerrains(d[recTerrains])
1926- let deltaTime = (lastBlock.timestamp - savedTime)
1927- if ((0 > deltaTime))
1928- then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
1929- else {
1930- let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
1931- let landIndex = (pieces / SSIZE)
1932- let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
1933- let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
1934- let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
1935- let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
1936- let lands = acc._7
1937- let idx = indexOf(lands, landAssetId)
1938- if (!(isDefined(idx)))
1939- then throw(("Your staked lands don't contain " + landAssetId))
1940- else {
1941- let customKey = keyLandAssetIdToCustomName(landAssetId)
1942- let customName = valueOrElse(getString(customKey), "")
1943- $Tuple10(sizesOut, arts, continent, bpRes, ((((((((((((acc._5 :+ DeleteEntry(keyStakedTimeByAssetId(landAssetId))) :+ DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))) :+ DeleteEntry(keyLandToAssetId(landNum))) :+ DeleteEntry(keyLandAssetIdToOwner(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetId(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
1944- then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
1945- else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
1946- }
1947- }
1948- }
1949- }
1950- }
1918+ else if (checkDelivery(duckAssetId))
1919+ then throw("mergeInternal_checkDelivery")
1920+ else {
1921+ func checkMerge (acc,landAssetId) = {
1922+ let asset = value(assetInfo(fromBase58String(landAssetId)))
1923+ let timeKey = keyStakedTimeByAssetId(landAssetId)
1924+ let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
1925+ let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
1926+ if ((owner != addr))
1927+ then throw((LANDPREFIX + " is not yours"))
1928+ else {
1929+ let d = split(asset.description, "_")
1930+ let continent = d[recContinent]
1931+ if (if ((acc._3 != ""))
1932+ then (acc._3 != continent)
1933+ else false)
1934+ then throw("Lands should be on the same continent to merge")
1935+ else {
1936+ let landSize = d[recLandSize]
1937+ let sizesIn = acc._1
1938+ let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
1939+ let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
1940+ let pieces = numPiecesBySize(landSize)
1941+ let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
1942+ let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
1943+ let reqLevel = match landSize {
1944+ case _ =>
1945+ if (("S" == $match0))
1946+ then 3
1947+ else if (("M" == $match0))
1948+ then 4
1949+ else if (("L" == $match0))
1950+ then 5
1951+ else if (("XL" == $match0))
1952+ then 6
1953+ else throw("Only S, M, L, XL can merge")
1954+ }
1955+ if ((infraLevel != reqLevel))
1956+ then throw("All lands should be maxed to merge")
1957+ else {
1958+ let landNum = d[recLandNum]
1959+ let terrainCounts = countTerrains(d[recTerrains])
1960+ let deltaTime = (lastBlock.timestamp - savedTime)
1961+ if ((0 > deltaTime))
1962+ then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
1963+ else {
1964+ let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
1965+ let landIndex = (pieces / SSIZE)
1966+ let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
1967+ let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
1968+ let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
1969+ let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
1970+ let lands = acc._7
1971+ let idx = indexOf(lands, landAssetId)
1972+ if (!(isDefined(idx)))
1973+ then throw(("Your staked lands don't contain " + landAssetId))
1974+ else {
1975+ let customKey = keyLandAssetIdToCustomName(landAssetId)
1976+ let customName = valueOrElse(getString(customKey), "")
1977+ $Tuple10(sizesOut, arts, continent, bpRes, ((((((((((((acc._5 :+ DeleteEntry(keyStakedTimeByAssetId(landAssetId))) :+ DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))) :+ DeleteEntry(keyLandToAssetId(landNum))) :+ DeleteEntry(keyLandAssetIdToOwner(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetId(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ Burn(fromBase58String(landAssetId), 1)) ++ (if ((customName != ""))
1978+ then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
1979+ else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
1980+ }
1981+ }
1982+ }
1983+ }
1984+ }
1985+ }
1986+
1987+ let bpKey = keyBackpackByDuck(duckAssetId)
1988+ let currentPack = getBackpack(bpKey)
1989+ let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
1990+ let landsKey = keyStakedLandsByOwner(addr)
1991+ let landsStr = getString(landsKey)
1992+ let landsIn = if (isDefined(landsStr))
1993+ then split_51C(value(landsStr), "_")
1994+ else nil
1995+ let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
1996+ let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
1997+ let r = {
1998+ let $l = landAssetIds
1999+ let $s = size($l)
2000+ let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
2001+ func $f0_1 ($a,$i) = if (($i >= $s))
2002+ then $a
2003+ else checkMerge($a, $l[$i])
2004+
2005+ func $f0_2 ($a,$i) = if (($i >= $s))
2006+ then $a
2007+ else throw("List size exceeds 5")
2008+
2009+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
2010+ }
2011+ let continent = r._3
2012+ let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
2013+ let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
2014+ let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
2015+ let newLandNum = toString(freeNum)
2016+ let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
2017+ let assetId = calculateAssetId(issue)
2018+ let newLandAssetId = toBase58String(assetId)
2019+ let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
2020+ let piecesKey = keyStakedPiecesByOwner(addr)
2021+ let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
2022+ $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
2023+ then StringEntry(landsKey, makeString_11C(r._7, "_"))
2024+ else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
2025+ then 0
2026+ else (stakedPieces - r._8))) :+ IntegerEntry(keyNextFreeLandNum(), (freeNum + 1))) :+ issue) :+ StringEntry(keyLandToAssetId(newLandNum), newLandAssetId)) :+ StringEntry(keyLandAssetIdToOwner(newLandAssetId), addr)) :+ StringEntry(keyLandNumToOwner(newLandNum), addr)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, newLandAssetId), r._2)) :+ IntegerEntry(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
19512027 }
1952-
1953- let bpKey = keyBackpackByDuck(duckAssetId)
1954- let currentPack = getBackpack(bpKey)
1955- let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
1956- let landsKey = keyStakedLandsByOwner(addr)
1957- let landsStr = getString(landsKey)
1958- let landsIn = if (isDefined(landsStr))
1959- then split_51C(value(landsStr), "_")
1960- else nil
1961- let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
1962- let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
1963- let r = {
1964- let $l = landAssetIds
1965- let $s = size($l)
1966- let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
1967- func $f0_1 ($a,$i) = if (($i >= $s))
1968- then $a
1969- else checkMerge($a, $l[$i])
1970-
1971- func $f0_2 ($a,$i) = if (($i >= $s))
1972- then $a
1973- else throw("List size exceeds 5")
1974-
1975- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
1976- }
1977- let continent = r._3
1978- let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
1979- let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
1980- let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
1981- let newLandNum = toString(freeNum)
1982- let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
1983- let assetId = calculateAssetId(issue)
1984- let newLandAssetId = toBase58String(assetId)
1985- let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
1986- let piecesKey = keyStakedPiecesByOwner(addr)
1987- let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
1988- $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
1989- then StringEntry(landsKey, makeString_11C(r._7, "_"))
1990- else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
1991- then 0
1992- else (stakedPieces - r._8))) :+ IntegerEntry(keyNextFreeLandNum(), (freeNum + 1))) :+ issue) :+ StringEntry(keyLandToAssetId(newLandNum), newLandAssetId)) :+ StringEntry(keyLandAssetIdToOwner(newLandAssetId), addr)) :+ StringEntry(keyLandNumToOwner(newLandNum), addr)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, newLandAssetId), r._2)) :+ IntegerEntry(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), makeString(r._6, "_"))) :+ StringEntry(keyResTypesByContinent(continent), makeString(r._10, "_"))) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
1993- }
19942028 }
19952029
19962030
19972031 func s2m (addr,landAssetIds) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, 0)
19982032
19992033
20002034 func m2l (addr,landAssetIds) = mergeInternal("L", 4, "SMM", addr, landAssetIds, (InfraUpgradeCostS * 4))
20012035
20022036
20032037 func l2xl (addr,landAssetIds) = mergeInternal("XL", 5, "SSSML", addr, landAssetIds, (InfraUpgradeCostS * 47))
20042038
20052039
20062040 func xl2xxl (addr,landAssetIds) = mergeInternal("XXL", 6, "LXL", addr, landAssetIds, (InfraUpgradeCostS * 54))
20072041
20082042
20092043 func mergeCommon (addr,landAssetIds) = match size(landAssetIds) {
20102044 case _ =>
20112045 if ((4 == $match0))
20122046 then s2m(addr, landAssetIds)
20132047 else if ((3 == $match0))
20142048 then m2l(addr, landAssetIds)
20152049 else if ((5 == $match0))
20162050 then l2xl(addr, landAssetIds)
20172051 else if ((2 == $match0))
20182052 then xl2xxl(addr, landAssetIds)
20192053 else throw("Unknown merge")
20202054 }
20212055
20222056
20232057 func prolog (i) = if (if ((i.originCaller != restContract))
20242058 then valueOrElse(getBoolean(keyBlocked()), false)
20252059 else false)
20262060 then throw("Contracts are under maintenance")
20272061 else StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))
20282062
20292063
20302064 @Callable(i)
20312065 func constructorV1 (restAddr) = if ((i.caller != this))
20322066 then throw("Permission denied")
20332067 else [StringEntry(keyRestAddress(), restAddr)]
20342068
20352069
20362070
20372071 @Callable(i)
20382072 func setBlocked (isBlocked) = if ((i.caller != this))
20392073 then throw("permission denied")
20402074 else [BooleanEntry(keyBlocked(), isBlocked)]
20412075
20422076
20432077
20442078 @Callable(i)
20452079 func stakeLand () = {
20462080 let prologAction = prolog(i)
20472081 if ((size(i.payments) != 1))
20482082 then throw("Exactly one payment required")
20492083 else {
20502084 let pmt = value(i.payments[0])
20512085 let assetId = value(pmt.assetId)
20522086 let address = toString(i.caller)
20532087 if ((pmt.amount != 1))
20542088 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
20552089 else {
20562090 let asset = value(assetInfo(assetId))
20572091 if ((asset.issuer != this))
20582092 then throw("Unknown issuer of token")
20592093 else if (!(contains(asset.name, LANDPREFIX)))
20602094 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
20612095 else {
20622096 let landNumSize = drop(asset.name, 4)
20632097 let landNum = if (contains(landNumSize, "XXL"))
20642098 then dropRight(landNumSize, 3)
20652099 else if (contains(landNumSize, "XL"))
20662100 then dropRight(landNumSize, 2)
20672101 else dropRight(landNumSize, 1)
20682102 if (!(isDefined(parseInt(landNum))))
20692103 then throw(("Cannot parse land number from " + asset.name))
20702104 else {
20712105 let landAssetId = toBase58String(assetId)
20722106 let timeKey = keyStakedTimeByAssetId(landAssetId)
20732107 if (isDefined(getInteger(timeKey)))
20742108 then throw((("NFT " + asset.name) + " is already staked"))
20752109 else {
20762110 let d = split(asset.description, "_")
20772111 let terrainCounts = countTerrains(d[recTerrains])
20782112 let pieces = numPiecesBySize(d[recLandSize])
20792113 let landIndex = (pieces / SSIZE)
20802114 let props = updateProportions(terrainCounts, landIndex, 1)
20812115 let resByContKey = keyResTypesByContinent(d[recContinent])
20822116 let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
20832117 let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, 1), "_")
20842118 let landsKey = keyStakedLandsByOwner(address)
20852119 let landsStr = getString(landsKey)
20862120 let lands = if (isDefined(landsStr))
20872121 then split_51C(value(landsStr), "_")
20882122 else nil
20892123 if (containsElement(lands, landAssetId))
20902124 then throw(("Your staked lands already contain " + landAssetId))
20912125 else if ((size(lands) >= MAX_LANDS_STAKED_BY_USER))
20922126 then throw((("Your already staked max (" + toString(MAX_LANDS_STAKED_BY_USER)) + ") lands"))
20932127 else {
20942128 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
20952129 let piecesKey = keyStakedPiecesByOwner(address)
20962130 let oldPieces = valueOrElse(getInteger(piecesKey), 0)
20972131 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
20982132 $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(landsKey, makeString_11C((lands :+ landAssetId), "_")), IntegerEntry(piecesKey, (oldPieces + pieces)), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), IntegerEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, address), infraLevel), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps), prologAction], wlgResult)
20992133 }
21002134 }
21012135 }
21022136 }
21032137 }
21042138 }
21052139 }
21062140
21072141
21082142
21092143 @Callable(i)
21102144 func unstakeLand (landAssetIdIn) = {
21112145 let prologAction = prolog(i)
21122146 if ((size(i.payments) != 0))
21132147 then throw("No payments required")
21142148 else {
21152149 let addr = toString(i.caller)
21162150 let c = checkClaimConditions(addr, claimModeDuck, landAssetIdIn)
21172151 let landAssetId = c._2
21182152 let d = c._3
21192153 let landsKey = keyStakedLandsByOwner(addr)
21202154 let terrainCounts = countTerrains(d[recTerrains])
21212155 let pieces = numPiecesBySize(d[recLandSize])
21222156 let landIndex = (pieces / SSIZE)
21232157 let props = updateProportions(terrainCounts, landIndex, -1)
21242158 let resByContKey = keyResTypesByContinent(d[recContinent])
21252159 let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
21262160 let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, -1), "_")
21272161 let claimResult = claimAll(addr, landAssetId, pieces, claimModeDuck)
21282162 let lands = split_51C(valueOrElse(getString(landsKey), ""), "_")
21292163 let idx = indexOf(lands, landAssetId)
21302164 if (!(isDefined(idx)))
21312165 then throw(("Your staked lands don't contain " + landAssetId))
21322166 else {
21332167 let now = lastBlock.timestamp
21342168 let govReleaseTime = valueOrElse(getInteger(govContract, keyUserGwlReleaseTime(addr)), 0)
21352169 if ((govReleaseTime >= now))
21362170 then throw(("Your gWL are taking part in voting, cannot unstake until " + toString(govReleaseTime)))
21372171 else {
21382172 let arbReleaseTime = (valueOrElse(getInteger(wlgContract, keyLastArbTimeByUser(addr)), 0) + arbitrageDelay)
21392173 if ((arbReleaseTime > now))
21402174 then throw(("Your staked lands took part in arbitrage, cannot unstake until " + toString(arbReleaseTime)))
21412175 else {
21422176 let piecesKey = keyStakedPiecesByOwner(addr)
21432177 let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
21442178 let newPieces = if ((pieces > stakedPieces))
21452179 then 0
21462180 else (stakedPieces - pieces)
21472181 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
21482182 $Tuple2([ScriptTransfer(i.caller, 1, fromBase58String(landAssetId)), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr)), StringEntry(keyResProportions(), props), StringEntry(resByContKey, updatedContProps), StringEntry(claimResult._2, makeString(claimResult._3, ":")), if ((size(lands) > 1))
21492183 then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
21502184 else DeleteEntry(landsKey), IntegerEntry(piecesKey, newPieces), prologAction], wlgResult)
21512185 }
21522186 }
21532187 }
21542188 }
21552189 }
21562190
21572191
21582192
21592193 @Callable(i)
21602194 func stakeDuck () = {
21612195 let prologAction = prolog(i)
21622196 if ((size(i.payments) != 1))
21632197 then throw("Exactly one payment required")
21642198 else {
21652199 let pmt = value(i.payments[0])
21662200 let assetId = value(pmt.assetId)
21672201 let address = toString(i.caller)
21682202 if ((pmt.amount != 1))
21692203 then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
21702204 else {
21712205 let asset = value(assetInfo(assetId))
21722206 if (if ((asset.issuer != incubatorAddr))
21732207 then (asset.issuer != breederAddr)
21742208 else false)
21752209 then throw((("Unknown issuer of " + DUCKPREFIX) + " token"))
21762210 else if (!(contains(asset.name, DUCKPREFIX)))
21772211 then throw((("Only NFT " + DUCKPREFIX) + " tokens are accepted"))
21782212 else {
21792213 let assetIdStr = toBase58String(assetId)
21802214 let timeKey = keyStakedTimeByAssetId(assetIdStr)
21812215 if (isDefined(getInteger(timeKey)))
21822216 then throw((("NFT " + asset.name) + " is already staked"))
21832217 else if (isDefined(getString(keyStakedDuckByOwner(address))))
21842218 then throw(("You already staked one duck: " + asset.name))
2185- else if (checkTournament(assetIdStr))
2186- then throw("stakeDuck_checkTournament")
2187- else {
2188- let locKey = keyDuckLocation(assetIdStr)
2189- let location = getString(locKey)
2190- let bpKey = keyBackpackByDuck(assetIdStr)
2191- let backpack = getString(bpKey)
2192- let keyHealth = keyDuckHealth(assetIdStr)
2193- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2194- let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
2195- ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
2219+ else {
2220+ let locKey = keyDuckLocation(assetIdStr)
2221+ let location = getString(locKey)
2222+ let bpKey = keyBackpackByDuck(assetIdStr)
2223+ let backpack = getString(bpKey)
2224+ let keyHealth = keyDuckHealth(assetIdStr)
2225+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2226+ let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
2227+ ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
2228+ then nil
2229+ else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
21962230 then nil
2197- else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
2198- then nil
2199- else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) :+ prologAction)))))
2200- }
2231+ else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) :+ prologAction)))))
2232+ }
22012233 }
22022234 }
22032235 }
22042236 }
22052237
22062238
22072239
22082240 @Callable(i)
22092241 func unstakeDuck (assetIdStr) = {
22102242 let prologAction = prolog(i)
22112243 if ((size(i.payments) != 0))
22122244 then throw("No payments required")
22132245 else {
22142246 let assetId = fromBase58String(assetIdStr)
22152247 let address = toString(i.caller)
22162248 let asset = value(assetInfo(assetId))
22172249 let timeKey = keyStakedTimeByAssetId(assetIdStr)
22182250 if (!(isDefined(getInteger(timeKey))))
22192251 then throw((("NFT " + asset.name) + " is not staked"))
22202252 else if (!(isDefined(getString(keyStakedDuckByOwner(address)))))
22212253 then throw((("The duck " + asset.name) + " is not staked"))
22222254 else {
22232255 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetIdStr)), (("NFT " + asset.name) + " is orphaned"))
22242256 if ((owner != address))
22252257 then throw("Staked NFT is not yours")
22262258 else if (checkTournament(assetIdStr))
22272259 then throw("unstakeDuck_checkTournament")
2228- else {
2229- let keyHealth = keyDuckHealth(assetIdStr)
2230- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2231- let health = valueOrElse(getInteger(keyHealth), maxHP)
2232- if ((maxHP > health))
2233- then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
2234- else [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address)), prologAction]
2235- }
2260+ else if (checkDelivery(assetIdStr))
2261+ then throw("unstakeDuck_checkDelivery")
2262+ else {
2263+ let keyHealth = keyDuckHealth(assetIdStr)
2264+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
2265+ let health = valueOrElse(getInteger(keyHealth), maxHP)
2266+ if ((maxHP > health))
2267+ then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
2268+ else [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address)), prologAction]
2269+ }
22362270 }
22372271 }
22382272 }
22392273
22402274
22412275
22422276 @Callable(i)
22432277 func claimRes (amount,landAssetIdStr) = {
22442278 let prologAction = prolog(i)
22452279 if ((size(i.payments) != 0))
22462280 then throw("No payments required")
22472281 else {
22482282 let addr = toString(i.originCaller)
22492283 let result = claimResInternal(addr, amount, claimModeDuck, landAssetIdStr)
22502284 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
22512285 $Tuple2(((((result._1 ++ updateDuckStatsInternal(duckAssetId, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._3[bpIdxRes])
22522286 }
22532287 }
22542288
22552289
22562290
22572291 @Callable(i)
22582292 func claimResToWH (amount,landAssetIdStr) = {
22592293 let prologAction = prolog(i)
22602294 if ((size(i.payments) != 0))
22612295 then throw("No payments required")
22622296 else {
22632297 let addr = toString(i.originCaller)
22642298 let result = claimResInternal(addr, amount, claimModeWh, landAssetIdStr)
22652299 $Tuple2(((((result._1 ++ updateAccStatsInternal(addr, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._5[whIdxRes])
22662300 }
22672301 }
22682302
22692303
22702304
22712305 @Callable(i)
22722306 func flight (message,sig) = {
22732307 let prologAction = prolog(i)
22742308 if ((size(i.payments) != 0))
22752309 then throw("No payments required")
22762310 else {
22772311 let userAddr = toString(i.caller)
22782312 let f = flightCommon(userAddr, message, sig)
22792313 let newHP = f._1
22802314 let duckAssetId = f._2
22812315 let locKey = keyDuckLocation(duckAssetId)
22822316 let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
22832317 let newLocation = f._4
22842318 if ((newLocation == curLocation))
22852319 then throw("You can't fly to the same location")
22862320 else {
22872321 let newLoc = split(newLocation, "_")
22882322 let isTour = (newLoc[locIdxType] == "T")
22892323 let eqKey = keyDuckEquipment(duckAssetId)
22902324 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2291- let $t06601366110 = subtractEquipment(currentEq, f._5)
2292- let newEq = $t06601366110._1
2293- let shouldZeroBuffs = $t06601366110._2
2325+ let $t06681366910 = subtractEquipment(currentEq, f._5)
2326+ let newEq = $t06681366910._1
2327+ let shouldZeroBuffs = $t06681366910._2
22942328 let locToSave = if (!(isInTournament(tournamentContract, curLocation)))
22952329 then if (isTour)
22962330 then throw(((("Cheat attempt: oldLoc=" + curLocation) + ", newLoc=") + newLocation))
22972331 else if ((newHP > 0))
22982332 then newLocation
22992333 else curLocation
23002334 else if (!(isInTournament(tournamentContract, newLocation)))
23012335 then throw("Your duck is taking part in the tournament")
23022336 else {
23032337 let score = parseIntValue(newLoc[locIdxId])
23042338 let curLoc = split(curLocation, "_")
23052339 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
23062340 if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
23072341 then throw(((("Cheat attempt: oldLoc=" + curLocation) + ", newLoc=") + newLocation))
23082342 else if ((newHP > 0))
23092343 then {
23102344 let localBest = valueOrElse(getInteger(tournamentContract, keyBestResultByTourAndDuck(lastId, duckAssetId)), 0)
23112345 let updLocal = if ((score > localBest))
23122346 then invoke(tournamentContract, "saveDuckResult", [duckAssetId, score], nil)
23132347 else unit
23142348 if ((updLocal == updLocal))
23152349 then newLocation
23162350 else throw("Strict value is not equal to itself.")
23172351 }
23182352 else curLocation
23192353 }
23202354 $Tuple2(([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), newHP), prologAction] ++ (if (shouldZeroBuffs)
23212355 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
23222356 else (nil ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
23232357 then xpSuccessFlight
23242358 else xpFailFlight)._1))), f._3)
23252359 }
23262360 }
23272361 }
23282362
23292363
23302364
23312365 @Callable(i)
23322366 func heal (quantityL1,quantityL2,quantityL3) = {
23332367 let prologAction = prolog(i)
23342368 if (if (if ((0 > quantityL1))
23352369 then true
23362370 else (0 > quantityL2))
23372371 then true
23382372 else (0 > quantityL3))
23392373 then throw("Quantity cannot be negative")
23402374 else {
23412375 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
23422376 if (checkTournament(duckAssetId))
23432377 then throw("heal_checkTournament")
2344- else {
2345- let qts = [quantityL1, quantityL2, quantityL3]
2346- let keyHealth = keyDuckHealth(duckAssetId)
2347- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2348- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2349- if ((oldHealth >= maxHP))
2350- then throw((("HP should be < " + toString(maxHP)) + " to heal"))
2351- else {
2352- let bpKey = keyBackpackByDuck(duckAssetId)
2353- let currentPack = getBackpack(bpKey)
2354- let prodList = if ((currentPack[bpIdxProd] == ""))
2355- then nil
2356- else split_4C(currentPack[bpIdxProd], "_")
2357- func iterateProd (acc,recipe) = {
2358- let n = acc._2
2359- let x = if ((size(prodList) > n))
2360- then parseIntValue(prodList[n])
2361- else 0
2362- if ((3 > n))
2363- then {
2364- let q = qts[n]
2365- if ((q > x))
2366- then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
2367- else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
2368- }
2369- else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
2378+ else if (checkDelivery(duckAssetId))
2379+ then throw("heal_checkDelivery")
2380+ else {
2381+ let qts = [quantityL1, quantityL2, quantityL3]
2382+ let keyHealth = keyDuckHealth(duckAssetId)
2383+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2384+ let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2385+ if ((oldHealth >= maxHP))
2386+ then throw((("HP should be < " + toString(maxHP)) + " to heal"))
2387+ else {
2388+ let bpKey = keyBackpackByDuck(duckAssetId)
2389+ let currentPack = getBackpack(bpKey)
2390+ let prodList = if ((currentPack[bpIdxProd] == ""))
2391+ then nil
2392+ else split_4C(currentPack[bpIdxProd], "_")
2393+ func iterateProd (acc,recipe) = {
2394+ let n = acc._2
2395+ let x = if ((size(prodList) > n))
2396+ then parseIntValue(prodList[n])
2397+ else 0
2398+ if ((3 > n))
2399+ then {
2400+ let q = qts[n]
2401+ if ((q > x))
2402+ then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
2403+ else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
2404+ }
2405+ else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
2406+ }
2407+
2408+ let result = {
2409+ let $l = productionMatrix
2410+ let $s = size($l)
2411+ let $acc0 = $Tuple3(nil, 0, 0)
2412+ func $f0_1 ($a,$i) = if (($i >= $s))
2413+ then $a
2414+ else iterateProd($a, $l[$i])
2415+
2416+ func $f0_2 ($a,$i) = if (($i >= $s))
2417+ then $a
2418+ else throw("List size exceeds 50")
2419+
2420+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
2421+ }
2422+ let newHealth = min([maxHP, (oldHealth + result._3)])
2423+ $Tuple2(([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":")), prologAction] ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
23702424 }
2371-
2372- let result = {
2373- let $l = productionMatrix
2374- let $s = size($l)
2375- let $acc0 = $Tuple3(nil, 0, 0)
2376- func $f0_1 ($a,$i) = if (($i >= $s))
2377- then $a
2378- else iterateProd($a, $l[$i])
2379-
2380- func $f0_2 ($a,$i) = if (($i >= $s))
2381- then $a
2382- else throw("List size exceeds 50")
2383-
2384- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
2385- }
2386- let newHealth = min([maxHP, (oldHealth + result._3)])
2387- $Tuple2(([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":")), prologAction] ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
2388- }
2389- }
2425+ }
23902426 }
23912427 }
23922428
23932429
23942430
23952431 @Callable(i)
23962432 func healES () = {
23972433 let prologAction = prolog(i)
23982434 if ((size(i.payments) != 1))
23992435 then throw("Exactly one payment required")
24002436 else {
24012437 let pmt = value(i.payments[0])
24022438 if ((pmt.assetId != usdtAssetId))
24032439 then throw("Allowed USDT payment only!")
24042440 else {
24052441 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
24062442 if (checkTournament(duckAssetId))
24072443 then throw("healES_checkTournament")
2408- else {
2409- let keyHealth = keyDuckHealth(duckAssetId)
2410- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2411- let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2412- if ((oldHealth > 0))
2413- then throw("HP should be 0 to call Emergency Service")
2414- else {
2415- let bpKey = keyBackpackByDuck(duckAssetId)
2416- let currentPack = getBackpack(bpKey)
2417- let prodList = if ((currentPack[bpIdxProd] == ""))
2418- then nil
2419- else split_4C(currentPack[bpIdxProd], "_")
2420- let medKitAmount1 = if ((size(prodList) > 0))
2421- then parseIntValue(prodList[0])
2422- else 0
2423- let medKitAmount2 = if ((size(prodList) > 1))
2424- then parseIntValue(prodList[1])
2425- else 0
2426- let medKitAmount3 = if ((size(prodList) > 2))
2427- then parseIntValue(prodList[2])
2428- else 0
2429- if (if (if ((medKitAmount1 > 0))
2430- then true
2431- else (medKitAmount2 > 0))
2432- then true
2433- else (medKitAmount3 > 0))
2434- then throw("You have to use own Medical Kit")
2435- else {
2436- let existStr = getString(economyContract, keyEsWarehouse())
2437- let existAmounts = if (isDefined(existStr))
2438- then split_4C(value(existStr), "_")
2439- else nil
2440- let existAmount = if ((size(existAmounts) > 0))
2441- then parseIntValue(existAmounts[0])
2442- else 0
2443- if ((0 >= existAmount))
2444- then throw("There are no Medical Kits L1 at Emergency Service storage")
2445- else {
2446- let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
2447- let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
2448- let recipe = split(productionMatrix[0], "_")
2449- let totalMat = getRecipeMaterials(recipe)
2450- let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
2451- if ((pmt.amount != sellPrice))
2452- then throw(("Payment attached should be " + toString(sellPrice)))
2453- else {
2454- let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
2455- $Tuple2(([IntegerEntry(keyHealth, newHealth), prologAction] ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
2456- }
2457- }
2458- }
2459- }
2460- }
2444+ else if (checkDelivery(duckAssetId))
2445+ then throw("healES_checkDelivery")
2446+ else {
2447+ let keyHealth = keyDuckHealth(duckAssetId)
2448+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
2449+ let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
2450+ if ((oldHealth > 0))
2451+ then throw("HP should be 0 to call Emergency Service")
2452+ else {
2453+ let bpKey = keyBackpackByDuck(duckAssetId)
2454+ let currentPack = getBackpack(bpKey)
2455+ let prodList = if ((currentPack[bpIdxProd] == ""))
2456+ then nil
2457+ else split_4C(currentPack[bpIdxProd], "_")
2458+ let medKitAmount1 = if ((size(prodList) > 0))
2459+ then parseIntValue(prodList[0])
2460+ else 0
2461+ let medKitAmount2 = if ((size(prodList) > 1))
2462+ then parseIntValue(prodList[1])
2463+ else 0
2464+ let medKitAmount3 = if ((size(prodList) > 2))
2465+ then parseIntValue(prodList[2])
2466+ else 0
2467+ if (if (if ((medKitAmount1 > 0))
2468+ then true
2469+ else (medKitAmount2 > 0))
2470+ then true
2471+ else (medKitAmount3 > 0))
2472+ then throw("You have to use own Medical Kit")
2473+ else {
2474+ let existStr = getString(economyContract, keyEsWarehouse())
2475+ let existAmounts = if (isDefined(existStr))
2476+ then split_4C(value(existStr), "_")
2477+ else nil
2478+ let existAmount = if ((size(existAmounts) > 0))
2479+ then parseIntValue(existAmounts[0])
2480+ else 0
2481+ if ((0 >= existAmount))
2482+ then throw("There are no Medical Kits L1 at Emergency Service storage")
2483+ else {
2484+ let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
2485+ let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
2486+ let recipe = split(productionMatrix[0], "_")
2487+ let totalMat = getRecipeMaterials(recipe)
2488+ let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
2489+ if ((pmt.amount != sellPrice))
2490+ then throw(("Payment attached should be " + toString(sellPrice)))
2491+ else {
2492+ let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
2493+ $Tuple2(([IntegerEntry(keyHealth, newHealth), prologAction] ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
2494+ }
2495+ }
2496+ }
2497+ }
2498+ }
24612499 }
24622500 }
24632501 }
24642502
24652503
24662504
24672505 @Callable(i)
24682506 func updateBackpack (duckAssetId,newPack) = if ((i.caller != economyContract))
24692507 then throw("permission denied")
24702508 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack)], newPack)
24712509
24722510
24732511
24742512 @Callable(i)
24752513 func commitForRandom () = {
24762514 let prologAction = prolog(i)
24772515 let finishBlock = (height + randomDelay)
24782516 let addr = toString(i.caller)
24792517 $Tuple2(([IntegerEntry(keyCommit(addr), finishBlock)] :+ prologAction), finishBlock)
24802518 }
24812519
24822520
24832521
24842522 @Callable(i)
24852523 func awardSLand (address) = if ((i.caller != tournamentContract))
24862524 then throw("Access denied")
24872525 else if ((size(i.payments) != 0))
24882526 then throw("No payments required")
24892527 else {
24902528 let result = expeditionInternal(addressFromStringValue(address), i.transactionId)
24912529 $Tuple2(result._1, result._2._1)
24922530 }
24932531
24942532
24952533
24962534 @Callable(i)
24972535 func buySLand () = {
24982536 let prologAction = prolog(i)
24992537 if ((size(i.payments) != 1))
25002538 then throw("Exactly one payment required")
25012539 else {
25022540 let pmt = value(i.payments[0])
25032541 if ((pmt.assetId != usdtAssetId))
25042542 then throw("Allowed USDT payment only!")
25052543 else if ((pmt.amount != EXPUSDT))
25062544 then throw(("Payment attached should be " + toString(EXPUSDT)))
25072545 else {
25082546 let result = expeditionInternal(i.caller, i.transactionId)
25092547 let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
25102548 $Tuple2((((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) :+ prologAction), $Tuple2(result._2._1, acresResult))
25112549 }
25122550 }
25132551 }
25142552
25152553
25162554
25172555 @Callable(i)
25182556 func expedition (message,sig) = {
25192557 let prologAction = prolog(i)
25202558 if ((size(i.payments) != 0))
25212559 then throw("No payments required")
25222560 else {
25232561 let userAddr = toString(i.caller)
25242562 let f = flightCommon(userAddr, message, sig)
25252563 let duckAssetId = f._2
25262564 let keyHealth = keyDuckHealth(duckAssetId)
25272565 let bpKey = keyBackpackByDuck(duckAssetId)
25282566 let currentPack = getBackpack(bpKey)
25292567 let mList = split(currentPack[bpIdxMat], "_")
25302568 let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
25312569 let eqKey = keyDuckEquipment(duckAssetId)
25322570 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2533- let $t07486774964 = subtractEquipment(currentEq, f._5)
2534- let newEq = $t07486774964._1
2535- let shouldZeroBuffs = $t07486774964._2
2571+ let $t07583875935 = subtractEquipment(currentEq, f._5)
2572+ let newEq = $t07583875935._1
2573+ let shouldZeroBuffs = $t07583875935._2
25362574 let e = expeditionInternal(i.caller, i.transactionId)
25372575 let id = e._2._1
25382576 let result = if ((0 >= f._1))
25392577 then $Tuple3([IntegerEntry(keyHealth, 0), StringEntry(eqKey, newEq)], "", 0)
25402578 else $Tuple3((e._1 ++ (if (shouldZeroBuffs)
25412579 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
25422580 else ((((nil :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, f._1)) :+ StringEntry(eqKey, newEq)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))))), id, f._3)
25432581 if (checkTournament(duckAssetId))
25442582 then throw("expedition_checkTournament")
2545- else {
2546- let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2547- $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) :+ prologAction), $Tuple3(result._2, result._3, acresResult))
2548- }
2583+ else if (checkDelivery(duckAssetId))
2584+ then throw("expedition_checkDelivery")
2585+ else {
2586+ let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
2587+ $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) :+ prologAction), $Tuple3(result._2, result._3, acresResult))
2588+ }
25492589 }
25502590 }
25512591
25522592
25532593
25542594 @Callable(i)
25552595 func buySLandForAcres () = {
25562596 let prologAction = prolog(i)
25572597 if ((size(i.payments) != 1))
25582598 then throw("exactly 1 payment must be attached")
25592599 else {
25602600 let pmt = i.payments[0]
25612601 let amt = pmt.amount
25622602 if (if (!(isDefined(pmt.assetId)))
25632603 then true
25642604 else (value(pmt.assetId) != acresAssetId))
25652605 then throw("ACRES payments only!")
25662606 else if ((amt != S_COST_ACRES))
25672607 then throw(("Payment attached should be " + toString(S_COST_ACRES)))
25682608 else {
25692609 let result = expeditionInternal(i.caller, i.transactionId)
25702610 let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], [AttachedPayment(acresAssetId, amt)]))
25712611 $Tuple2((((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) :+ prologAction), $Tuple2(result._2._1, acresResult))
25722612 }
25732613 }
25742614 }
25752615
25762616
25772617
25782618 @Callable(i)
25792619 func upgradeInfra (landAssetId) = {
25802620 let prologAction = prolog(i)
25812621 if ((size(i.payments) != 0))
25822622 then throw("No payments required")
25832623 else {
25842624 let result = upInfraCommon(true, i.caller, 0, landAssetId)
25852625 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
25862626 $Tuple2(((result._1 :+ prologAction) ++ updateDuckStatsInternal(duckAssetId, fraction(xpUpgradeInfra, result._3, MULT8))._1), result._2)
25872627 }
25882628 }
25892629
25902630
25912631
25922632 @Callable(i)
25932633 func activateArtifact (artName,landAssetIdOpt) = {
25942634 let prologAction = prolog(i)
25952635 if ((size(i.payments) != 0))
25962636 then throw("No payments required")
25972637 else {
25982638 let addr = toString(i.caller)
25992639 let result = match artName {
26002640 case _ =>
26012641 if (("PRESALE" == $match0))
26022642 then activatePresaleArt(addr, landAssetIdOpt)
26032643 else if (("ONBOARD" == $match0))
26042644 then activateOnboardArt(addr)
26052645 else throw("Unknown artifact")
26062646 }
26072647 (result :+ prologAction)
26082648 }
26092649 }
26102650
26112651
26122652
26132653 @Callable(i)
26142654 func mergeLands (landAssetIds) = {
26152655 let prologAction = prolog(i)
26162656 if ((size(i.payments) != 0))
26172657 then throw("No payments required")
26182658 else {
26192659 let result = mergeCommon(toString(i.caller), landAssetIds)
26202660 $Tuple2(((result._1 :+ prologAction) ++ updateAccStatsInternal(toString(i.caller), xpMerge)._1), result._2)
26212661 }
26222662 }
26232663
26242664
26252665
26262666 @Callable(i)
26272667 func cargoExchange (cargoListStr,landAssetId) = {
26282668 let prologAction = prolog(i)
26292669 if ((size(i.payments) != 0))
26302670 then throw("No payments required")
26312671 else {
26322672 let cargoParts = split_4C(cargoListStr, ":")
26332673 let addr = toString(i.originCaller)
26342674 let asset = value(assetInfo(fromBase58String(landAssetId)))
26352675 let timeKey = keyStakedTimeByAssetId(landAssetId)
26362676 if (!(isDefined(getInteger(timeKey))))
26372677 then throw((asset.name + " is not staked"))
26382678 else {
26392679 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
26402680 if ((owner != addr))
26412681 then throw((LANDPREFIX + " is not yours"))
26422682 else {
26432683 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
26442684 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
26452685 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
26462686 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
26472687 let loc = split(value(curLocation), "_")
26482688 if ((loc[locIdxType] != "L"))
26492689 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
26502690 else if ((loc[locIdxId] != landAssetId))
26512691 then throw(("Duck should be on the land " + landAssetId))
26522692 else {
26532693 let whKey = keyWarehouseByLand(landAssetId)
26542694 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
26552695 let bpKey = keyBackpackByDuck(duckAssetId)
26562696 let currentPack = getBackpack(bpKey)
26572697 let result = moveStuff(cargoParts, currentWh, currentPack)
26582698 let loft = split(currentWh[whIdxLOFT], "_")
26592699 let loftO = (parseIntValue(loft[volOccupied]) + result._7)
26602700 let loftF = (parseIntValue(loft[volFree]) - result._7)
26612701 [StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], result._4, result._5, result._6], ":")), StringEntry(whKey, makeString_2C([currentWh[whIdxLevels], result._1, result._2, result._3, makeString([loft[volLocked], toString(loftO), toString(loftF), loft[volTotal]], "_")], ":")), prologAction]
26622702 }
26632703 }
26642704 }
26652705 }
26662706 }
26672707
26682708
26692709
26702710 @Callable(i)
26712711 func saveWarehouse (whStr,landAssetId) = if ((i.caller != economyContract))
26722712 then throw("Access denied")
26732713 else {
26742714 let whKey = keyWarehouseByLand(landAssetId)
26752715 let wh = split_4C(whStr, ":")
26762716 if ((size(wh) != 5))
26772717 then throw("warehouse string should contain 4 ':' separators")
26782718 else {
26792719 let loftL = split(wh[whIdxLOFT], "_")[volLocked]
26802720 let loftO = getWarehouseOccupiedVol(wh)
26812721 let loftT = getWarehouseTotalVolume(wh[whIdxLevels])
26822722 let loftF = ((loftT - parseIntValue(loftL)) - loftO)
26832723 let newWhStr = makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], wh[whIdxProd], makeString([loftL, toString(loftO), toString(loftF), toString(loftT)], "_")], ":")
26842724 $Tuple2([StringEntry(whKey, newWhStr)], newWhStr)
26852725 }
26862726 }
26872727
26882728
26892729
26902730 @Callable(i)
26912731 func fixWarehouseFormat (landAssetId) = if ((i.caller != restContract))
26922732 then throw("Access denied")
26932733 else {
26942734 let whKey = keyWarehouseByLand(landAssetId)
26952735 let asset = value(assetInfo(fromBase58String(landAssetId)))
26962736 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
26972737 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
26982738 let wh = getWarehouse(whKey, landIndex, infraLevel)
26992739 let loftL = asInt(invoke(economyContract, "recalcLockedVolumeREADONLY", [landAssetId, wh], nil))
27002740 let loftO = getWarehouseOccupiedVol(wh)
27012741 let loftT = getWarehouseTotalVolume(wh[whIdxLevels])
27022742 let loftF = ((loftT - loftL) - loftO)
27032743 let newWhStr = makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], wh[whIdxProd], makeString([toString(loftL), toString(loftO), toString(loftF), toString(loftT)], "_")], ":")
27042744 $Tuple2([StringEntry(whKey, newWhStr)], newWhStr)
27052745 }
27062746
27072747
27082748
27092749 @Callable(i)
27102750 func fixContinentProportions (landAssetIds) = if ((i.caller != restContract))
27112751 then throw("Access denied")
27122752 else {
27132753 func getProps (acc,cont) = (acc :+ valueOrElse(getString(keyResTypesByContinent(cont)), "0_0_0_0_0_0"))
27142754
27152755 let p = {
27162756 let $l = continents
27172757 let $s = size($l)
27182758 let $acc0 = nil
27192759 func $f0_1 ($a,$i) = if (($i >= $s))
27202760 then $a
27212761 else getProps($a, $l[$i])
27222762
27232763 func $f0_2 ($a,$i) = if (($i >= $s))
27242764 then $a
27252765 else throw("List size exceeds 5")
27262766
27272767 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
27282768 }
27292769 func processor (acc,landAssetId) = {
27302770 let asset = value(assetInfo(fromBase58String(landAssetId)))
27312771 let d = split(asset.description, "_")
27322772 let landIndex = (numPiecesBySize(d[recLandSize]) / SSIZE)
27332773 let cont = d[recContinent]
27342774 let terrainCounts = countTerrains(d[recTerrains])
27352775 let continentIdx = value(indexOf(continents, cont))
27362776 let contProps = split(acc[continentIdx], "_")
27372777 let updated = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, 1), "_")
27382778 match cont {
27392779 case _ =>
27402780 if (("Americas" == $match0))
27412781 then [updated, acc[1], acc[2], acc[3], acc[4]]
27422782 else if (("Europe" == $match0))
27432783 then [acc[0], updated, acc[2], acc[3], acc[4]]
27442784 else if (("Asia" == $match0))
27452785 then [acc[0], acc[1], updated, acc[3], acc[4]]
27462786 else if (("Africa" == $match0))
27472787 then [acc[0], acc[1], acc[2], updated, acc[4]]
27482788 else if (("Oceania" == $match0))
27492789 then [acc[0], acc[1], acc[2], acc[3], updated]
27502790 else throw("wrong continent")
27512791 }
27522792 }
27532793
27542794 let r = {
27552795 let $l = landAssetIds
27562796 let $s = size($l)
27572797 let $acc0 = p
27582798 func $f1_1 ($a,$i) = if (($i >= $s))
27592799 then $a
27602800 else processor($a, $l[$i])
27612801
27622802 func $f1_2 ($a,$i) = if (($i >= $s))
27632803 then $a
27642804 else throw("List size exceeds 100")
27652805
27662806 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100)
27672807 }
27682808 $Tuple2([StringEntry(keyResTypesByContinent("Americas"), r[0]), StringEntry(keyResTypesByContinent("Europe"), r[1]), StringEntry(keyResTypesByContinent("Asia"), r[2]), StringEntry(keyResTypesByContinent("Africa"), r[3]), StringEntry(keyResTypesByContinent("Oceania"), r[4])], 0)
27692809 }
27702810
27712811
27722812
27732813 @Callable(i)
27742814 func fixStakedPieces (address) = if ((i.caller != restContract))
27752815 then throw("Access denied")
27762816 else {
27772817 let stakedPieces = if ((address == ""))
27782818 then 0
27792819 else {
27802820 let landsStr = getString(stakingContract, keyStakedLandsByOwner(address))
27812821 let lands = if (isDefined(landsStr))
27822822 then split_51C(value(landsStr), "_")
27832823 else nil
27842824 func oneLand (acc,landAssetId) = {
27852825 let asset = value(assetInfo(fromBase58String(landAssetId)))
27862826 let landSize = split(asset.description, "_")[recLandSize]
27872827 (acc + numPiecesBySize(landSize))
27882828 }
27892829
27902830 let $l = lands
27912831 let $s = size($l)
27922832 let $acc0 = 0
27932833 func $f0_1 ($a,$i) = if (($i >= $s))
27942834 then $a
27952835 else oneLand($a, $l[$i])
27962836
27972837 func $f0_2 ($a,$i) = if (($i >= $s))
27982838 then $a
27992839 else throw("List size exceeds 100")
28002840
28012841 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100)
28022842 }
28032843 $Tuple2([IntegerEntry(keyStakedPiecesByOwner(address), stakedPieces)], stakedPieces)
28042844 }
28052845
28062846
28072847
28082848 @Callable(i)
28092849 func setCustomName (assetId,customName,type) = {
28102850 let prologAction = prolog(i)
28112851 if ((size(i.payments) != 1))
28122852 then throw("Exactly one payment required")
28132853 else {
28142854 let pmt = value(i.payments[0])
28152855 if ((pmt.assetId != usdtAssetId))
28162856 then throw("Allowed USDT payment only!")
28172857 else if ((pmt.amount != RENAMINGCOST))
28182858 then throw(("Payment should be " + toString(RENAMINGCOST)))
28192859 else if (contains(customName, "__"))
28202860 then throw(("Name should not contain '__': " + customName))
28212861 else if ((size(customName) > MAXNAMELEN))
28222862 then throw(("Name too long, maxLength=" + toString(MAXNAMELEN)))
28232863 else {
28242864 let addr = toString(i.originCaller)
28252865 let actions = match type {
28262866 case _ =>
28272867 if (("ACCOUNT" == $match0))
28282868 then {
28292869 let reverseKey = keyCustomNameToAddress(customName)
28302870 let nameOwner = getString(reverseKey)
28312871 if (isDefined(nameOwner))
28322872 then throw(("Name already registered: " + customName))
28332873 else {
28342874 let addrToNameKey = keyAddressToCustomName(addr)
28352875 let oldName = getString(addrToNameKey)
28362876 let freeOld = if (isDefined(oldName))
28372877 then [DeleteEntry(keyCustomNameToAddress(value(oldName)))]
28382878 else nil
28392879 (((freeOld :+ StringEntry(addrToNameKey, customName)) :+ StringEntry(reverseKey, addr)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
28402880 }
28412881 }
28422882 else if (("LAND" == $match0))
28432883 then {
28442884 let asset = value(assetInfo(fromBase58String(assetId)))
28452885 let timeKey = keyStakedTimeByAssetId(assetId)
28462886 if (!(isDefined(getInteger(timeKey))))
28472887 then throw((asset.name + " is not staked"))
28482888 else {
28492889 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
28502890 if ((owner != addr))
28512891 then throw((LANDPREFIX + " is not yours"))
28522892 else {
28532893 let reverseKey = keyLandCustomNameToAssetId(customName)
28542894 let nameOwner = getString(reverseKey)
28552895 if (isDefined(nameOwner))
28562896 then throw(("Name already registered: " + customName))
28572897 else {
28582898 let assetToNameKey = keyLandAssetIdToCustomName(assetId)
28592899 let oldName = getString(assetToNameKey)
28602900 let freeOld = if (isDefined(oldName))
28612901 then [DeleteEntry(keyLandCustomNameToAssetId(value(oldName)))]
28622902 else nil
28632903 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
28642904 }
28652905 }
28662906 }
28672907 }
28682908 else if (("DUCK" == $match0))
28692909 then {
28702910 let asset = value(assetInfo(fromBase58String(assetId)))
28712911 let timeKey = keyStakedTimeByAssetId(assetId)
28722912 if (if (!(isDefined(getInteger(timeKey))))
28732913 then true
28742914 else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
28752915 then throw((asset.name + " is not staked"))
28762916 else {
28772917 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
28782918 if ((owner != addr))
28792919 then throw((DUCKPREFIX + " is not yours"))
28802920 else {
28812921 let reverseKey = keyDuckCustomNameToAssetId(customName)
28822922 let nameOwner = getString(reverseKey)
28832923 if (isDefined(nameOwner))
28842924 then throw(("Name already registered: " + customName))
28852925 else {
28862926 let assetToNameKey = keyDuckAssetIdToCustomName(assetId)
28872927 let oldName = getString(assetToNameKey)
28882928 let freeOld = if (isDefined(oldName))
28892929 then [DeleteEntry(keyDuckCustomNameToAssetId(value(oldName)))]
28902930 else nil
28912931 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateDuckStatsInternal(assetId, xpCustomName)._1)
28922932 }
28932933 }
28942934 }
28952935 }
28962936 else throw("Unknown entity type")
28972937 }
28982938 $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), 0)
28992939 }
29002940 }
29012941 }
29022942
29032943
29042944
29052945 @Callable(i)
29062946 func setReferrals (oldPlayer,newPlayer) = if ((i.callerPublicKey != pub))
29072947 then throw("Permission denied")
29082948 else {
29092949 let prologAction = prolog(i)
29102950 if ((size(i.payments) != 0))
29112951 then throw("No payments required")
29122952 else if (!(isDefined(addressFromString(oldPlayer))))
29132953 then throw(("Invalid address: " + oldPlayer))
29142954 else if (!(isDefined(addressFromString(newPlayer))))
29152955 then throw(("Invalid address: " + newPlayer))
29162956 else {
29172957 let oldsKey = keyOldies()
29182958 let olds = getString(oldsKey)
29192959 let oldies = if (isDefined(olds))
29202960 then split_4C(value(olds), "_")
29212961 else nil
29222962 if (containsElement(oldies, newPlayer))
29232963 then throw((newPlayer + " is not newbie (already has referrals)"))
29242964 else {
29252965 let refByKey = keyAddressRefBy(newPlayer)
29262966 let refBy = getString(refByKey)
29272967 if (if (isDefined(refBy))
29282968 then isDefined(addressFromString(value(refBy)))
29292969 else false)
29302970 then throw(((newPlayer + " already has refBy: ") + value(refBy)))
29312971 else {
29322972 let refsKey = keyAddressReferrals(oldPlayer)
29332973 let refs = getString(refsKey)
29342974 let refsArray = if (isDefined(refs))
29352975 then split_4C(value(refs), "_")
29362976 else nil
29372977 if (containsElement(refsArray, newPlayer))
29382978 then throw((((oldPlayer + " already contains ") + newPlayer) + " within referrals"))
29392979 else {
29402980 let newRefs = makeString_2C((refsArray :+ newPlayer), "_")
29412981 let newOlds = if (containsElement(oldies, oldPlayer))
29422982 then value(olds)
29432983 else makeString_2C((oldies :+ oldPlayer), "_")
29442984 $Tuple2([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), StringEntry(oldsKey, newOlds), prologAction], 0)
29452985 }
29462986 }
29472987 }
29482988 }
29492989 }
29502990
29512991
29522992
29532993 @Callable(i)
29542994 func distributePoints (strength,accuracy,intellect,endurance,dexterity) = {
29552995 let prologAction = prolog(i)
29562996 if ((size(i.payments) != 0))
29572997 then throw("No payments required")
29582998 else {
29592999 let addr = toString(i.originCaller)
29603000 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
29613001 let freeKeyAcc = keyUserFreePoints(addr)
29623002 let freePointsAcc = valueOrElse(getInteger(stakingContract, freeKeyAcc), 0)
29633003 let freeKeyDuck = keyDuckFreePoints(duckAssetId)
29643004 let freePointsDuck = valueOrElse(getInteger(stakingContract, freeKeyDuck), 0)
29653005 let sumFree = (freePointsAcc + freePointsDuck)
29663006 let sumToDistribute = ((((strength + accuracy) + intellect) + endurance) + dexterity)
29673007 if ((sumToDistribute > sumFree))
29683008 then throw((("There are only " + toString(sumFree)) + " free points to distribute"))
29693009 else {
29703010 let charsKey = keyDuckChars(duckAssetId)
29713011 let chars = split(valueOrElse(getString(stakingContract, charsKey), "0_0_0_0_0"), "_")
29723012 let newAcc = (freePointsAcc - sumToDistribute)
29733013 $Tuple2([IntegerEntry(freeKeyAcc, if ((0 > newAcc))
29743014 then 0
29753015 else newAcc), IntegerEntry(freeKeyDuck, if ((0 > newAcc))
29763016 then (freePointsDuck + newAcc)
29773017 else freePointsDuck), StringEntry(charsKey, makeString([toString((parseIntValue(chars[charStrength]) + strength)), toString((parseIntValue(chars[charAccuracy]) + accuracy)), toString((parseIntValue(chars[charIntellect]) + intellect)), toString((parseIntValue(chars[charEndurance]) + endurance)), toString((parseIntValue(chars[charDexterity]) + dexterity))], "_")), prologAction], 0)
29783018 }
29793019 }
29803020 }
29813021
29823022
29833023
29843024 @Callable(i)
29853025 func splitByGlobalWeightsREADONLY (amount) = $Tuple2(nil, getNeededMaterials(amount))
29863026
29873027
29883028
29893029 @Callable(i)
29903030 func splitByGlobalAndLocalWeightsREADONLY (matAmount,resAmount,terrains) = {
29913031 let terrainCounts = countTerrains(terrains)
29923032 $Tuple2(nil, $Tuple2(getNeededMaterials(matAmount), distributeByWeights(resAmount, terrainCounts)))
29933033 }
29943034
29953035
29963036
29973037 @Callable(i)
29983038 func getBackpackREADONLY (duckAssetId) = $Tuple2(nil, makeString(getBackpack(keyBackpackByDuck(duckAssetId)), ":"))
29993039
30003040
30013041
30023042 @Callable(i)
30033043 func getWarehouseREADONLY (landAssetId) = {
30043044 let asset = value(assetInfo(fromBase58String(landAssetId)))
30053045 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
30063046 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
30073047 $Tuple2(nil, makeString_2C(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
30083048 }
30093049
30103050
30113051
30123052 @Callable(i)
30133053 func saveLastTx () = {
30143054 let caller = i.caller
30153055 if (!(containsElement([wlgContract, economyContract, tournamentContract, acresContract], caller)))
30163056 then throw("Access denied")
30173057 else $Tuple2([prolog(i)], 42)
30183058 }
30193059
30203060
30213061
30223062 @Callable(i)
30233063 func updateDuckStats (duckAssetId,deltaXP) = if ((i.caller != economyContract))
30243064 then throw("Access denied")
30253065 else updateDuckStatsInternal(duckAssetId, deltaXP)
30263066
30273067
30283068
30293069 @Callable(i)
30303070 func updateAccStats (addr,deltaXP) = if ((i.caller != economyContract))
30313071 then throw("Access denied")
30323072 else updateAccStatsInternal(addr, deltaXP)
30333073
30343074
30353075
30363076 @Callable(i)
30373077 func equipDuck (equipment) = {
30383078 let prologAction = prolog(i)
30393079 if ((size(i.payments) != 0))
30403080 then throw("No payments required")
30413081 else {
30423082 let addr = toString(i.originCaller)
30433083 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
30443084 if (checkTournament(duckAssetId))
30453085 then throw("equipDuck_checkTournament")
3046- else {
3047- let eqKey = keyDuckEquipment(duckAssetId)
3048- let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
3049- let bpKey = keyBackpackByDuck(duckAssetId)
3050- let currentPack = getBackpack(bpKey)
3051- let newEq = split(equipment, "_")
3052- if ((size(newEq) != NUMSEGMENTS))
3053- then throw("Wrong equipment string")
3054- else {
3055- let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
3056- let segBpAux = split(newEq[segBackpack], ";")[1]
3057- let buffEffect = if ((segBpAux == ""))
3058- then 0
3059- else {
3060- let aux0 = split(segBpAux, ",")[0]
3061- if ((aux0 == ""))
3062- then 0
3063- else {
3064- let idxCnt = split(aux0, ":")
3065- let idx = idxCnt[0]
3066- let cnt = idxCnt[1]
3067- if (if (if (if (if ((idx == "06"))
3068- then true
3069- else (idx == "07"))
3070- then true
3071- else (idx == "08"))
3072- then (cnt != "")
3073- else false)
3074- then (parseIntValue(cnt) > 0)
3075- else false)
3076- then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
3077- else 0
3078- }
3079- }
3080- let stats = getDuckStats(this, duckAssetId, buffEffect, true)
3081- let newProdB = dressB(newEq, tempProdB, false, stats)
3082- let newProdStr = bytesToProdStr(newProdB)
3083- $Tuple2([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_")), prologAction], 0)
3084- }
3085- }
3086+ else if (checkDelivery(duckAssetId))
3087+ then throw("equipDuck_checkDelivery")
3088+ else {
3089+ let eqKey = keyDuckEquipment(duckAssetId)
3090+ let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
3091+ let bpKey = keyBackpackByDuck(duckAssetId)
3092+ let currentPack = getBackpack(bpKey)
3093+ let newEq = split(equipment, "_")
3094+ if ((size(newEq) != NUMSEGMENTS))
3095+ then throw("Wrong equipment string")
3096+ else {
3097+ let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
3098+ let segBpAux = split(newEq[segBackpack], ";")[1]
3099+ let buffEffect = if ((segBpAux == ""))
3100+ then 0
3101+ else {
3102+ let aux0 = split(segBpAux, ",")[0]
3103+ if ((aux0 == ""))
3104+ then 0
3105+ else {
3106+ let idxCnt = split(aux0, ":")
3107+ let idx = idxCnt[0]
3108+ let cnt = idxCnt[1]
3109+ if (if (if (if (if ((idx == "06"))
3110+ then true
3111+ else (idx == "07"))
3112+ then true
3113+ else (idx == "08"))
3114+ then (cnt != "")
3115+ else false)
3116+ then (parseIntValue(cnt) > 0)
3117+ else false)
3118+ then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
3119+ else 0
3120+ }
3121+ }
3122+ let stats = getDuckStats(this, duckAssetId, buffEffect, true)
3123+ let newProdB = dressB(newEq, tempProdB, false, stats)
3124+ let newProdStr = bytesToProdStr(newProdB)
3125+ $Tuple2([StringEntry(eqKey, equipment), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], newProdStr], ":")), StringEntry(keyDuckBuffs(duckAssetId), makeString([toString(stats[7]), toString(stats[8]), toString(stats[9]), toString(stats[10]), toString(stats[11])], "_")), prologAction], 0)
3126+ }
3127+ }
30863128 }
30873129 }
30883130
30893131
30903132
30913133 @Callable(i)
30923134 func fortificateLand (landAssetId,plan) = {
30933135 let prologAction = prolog(i)
30943136 if ((size(i.payments) != 0))
30953137 then throw("No payments required")
30963138 else {
30973139 let addr = toString(i.originCaller)
30983140 let duckAssetId = valueOrElse(getString(keyStakedDuckByOwner(addr)), "")
30993141 let duckStats = getDuckStats(this, duckAssetId, 0, false)
31003142 let fortKey = keyFortificationsByLand(landAssetId)
31013143 let currentForts = split(valueOrElse(getString(fortKey), ":0_15:0_18:0"), "_")
31023144 let asset = value(assetInfo(fromBase58String(landAssetId)))
31033145 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
31043146 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
31053147 let whKey = keyWarehouseByLand(landAssetId)
31063148 let wh = getWarehouse(whKey, landIndex, infraLevel)
31073149 let curLoft = split(wh[whIdxLOFT], "_")
31083150 let curO = parseIntValue(curLoft[volOccupied])
31093151 let curF = parseIntValue(curLoft[volFree])
31103152 let newForts = split(plan, "_")
3111- let $t09686796982 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3112- let tempProdB = $t09686796982._1
3113- let tempO = $t09686796982._2
3114- let tempF = $t09686796982._3
3115- let $t09698597081 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3116- let newProdB = $t09698597081._1
3117- let newO = $t09698597081._2
3118- let newF = $t09698597081._3
3153+ let $t09799398108 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3154+ let tempProdB = $t09799398108._1
3155+ let tempO = $t09799398108._2
3156+ let tempF = $t09799398108._3
3157+ let $t09811198207 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3158+ let newProdB = $t09811198207._1
3159+ let newO = $t09811198207._2
3160+ let newF = $t09811198207._3
31193161 let newProdStr = bytesToProdStr(newProdB)
31203162 let newLoftStr = makeString([curLoft[volLocked], toString(newO), toString(newF), curLoft[volTotal]], "_")
31213163 $Tuple2([StringEntry(fortKey, plan), StringEntry(whKey, makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], newProdStr, newLoftStr], ":")), prologAction], 0)
31223164 }
31233165 }
31243166
31253167
31263168
31273169 @Callable(i)
31283170 func initDuckTourAttempt (duckAssetId) = if ((i.caller != tournamentContract))
31293171 then throw("Access denied")
31303172 else {
31313173 let prologAction = prolog(i)
31323174 let keyHealth = keyDuckHealth(duckAssetId)
31333175 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
31343176 let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
31353177 let curLocKey = keyDuckLocation(duckAssetId)
31363178 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
31373179 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
31383180 let tourLocation = (toString(lastId) + "_T_0")
31393181 $Tuple2([prologAction, IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, tourLocation)], tourLocation)
31403182 }
31413183
31423184
31433185
31443186 @Callable(i)
31453187 func breakAttempt () = {
31463188 let prologAction = prolog(i)
31473189 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
31483190 let curLocKey = keyDuckLocation(duckAssetId)
31493191 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
31503192 if ((split(curLocation, "_")[locIdxType] != "T"))
31513193 then throw("Your duck is not in the tournament")
31523194 else {
31533195 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
31543196 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
31553197 $Tuple2([prologAction, IntegerEntry(keyDuckHealth(duckAssetId), savedHealth), StringEntry(curLocKey, savedLocation)], curLocation)
31563198 }
31573199 }
31583200
31593201
31603202
31613203 @Callable(i)
31623204 func exitTournamentInternal (duckAssetId) = if ((i.caller != this))
31633205 then throw("Access denied")
31643206 else {
31653207 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
31663208 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
31673209 $Tuple2([IntegerEntry(keyDuckHealth(duckAssetId), savedHealth), StringEntry(keyDuckLocation(duckAssetId), savedLocation)], false)
3210+ }
3211+
3212+
3213+
3214+@Callable(i)
3215+func exitDeliveryInternal (duckAssetId) = if ((i.caller != this))
3216+ then throw("Access denied")
3217+ else {
3218+ let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
3219+ let now = lastBlock.timestamp
3220+ let startTime = parseIntValue(curLocation[locIdxContinent])
3221+ let distance = parseIntValue(curLocation[locIdxId])
3222+ let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(duckAssetId)), "NFT duck is orphaned")
3223+ let healthKey = keyDuckHealth(duckAssetId)
3224+ let curHealth = getIntegerValue(healthKey)
3225+ let outcomeActions = if ((distance >= 3))
3226+ then {
3227+ let reward = invoke(economyContract, "sendDeliveryReward", [owner], nil)
3228+ if ((reward == reward))
3229+ then nil
3230+ else throw("Strict value is not equal to itself.")
3231+ }
3232+ else {
3233+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
3234+ let unlock = invoke(economyContract, "updateDeliveryLocked", [(lockedTotal - MIN_USDT_FEE_DELIVERY)], nil)
3235+ if ((unlock == unlock))
3236+ then if ((0 >= curHealth))
3237+ then nil
3238+ else [IntegerEntry(keyDeliveryDelayByDuck(duckAssetId), (startTime + DAYMILLIS))]
3239+ else throw("Strict value is not equal to itself.")
3240+ }
3241+ let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
3242+ let savedLocation = getStringValue(keySavedLocation(duckAssetId))
3243+ $Tuple2(((outcomeActions :+ IntegerEntry(healthKey, savedHealth)) :+ StringEntry(keyDuckLocation(duckAssetId), savedLocation)), false)
31683244 }
31693245
31703246
31713247
31723248 @Callable(i)
31733249 func prepareRobbery (message,sig) = {
31743250 let prologAction = prolog(i)
31753251 if (!(sigVerify_8Kb(message, sig, pub)))
31763252 then throw("signature does not match")
31773253 else if ((size(i.payments) != 1))
31783254 then throw("exactly 1 payment must be attached")
31793255 else {
31803256 let pmt = i.payments[0]
31813257 let wlgAmt = pmt.amount
31823258 if (if (!(isDefined(pmt.assetId)))
31833259 then true
31843260 else (value(pmt.assetId) != wlgAssetId))
31853261 then throw("WLGOLD payments only!")
31863262 else {
31873263 let parts = split(toUtf8String(message), "|")
31883264 if ((size(parts) != 2))
31893265 then throw("Wrong message format")
31903266 else {
31913267 let duckAssetId = parts[0]
31923268 let robCost = getRobberyData(this, duckAssetId)._1
31933269 if ((robCost > wlgAmt))
31943270 then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
31953271 else {
31963272 let candidates = split(parts[1], "_")
31973273 let now = lastBlock.timestamp
31983274 let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
31993275 let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
32003276 let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
32013277 if (if ((duckState != duckIdxFree))
32023278 then (landETA > now)
32033279 else false)
32043280 then throw(("You already started robbing, wait till " + toString(landETA)))
32053281 else {
32063282 func checker (acc,landAssetId) = {
32073283 let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
32083284 let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
32093285 if ((state > size(landRobCooldowns)))
32103286 then throw("Invalid state")
32113287 else if ((now > cooldownETA))
32123288 then {
32133289 let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
32143290 if ((0 >= stakedTime))
32153291 then acc
32163292 else {
32173293 let a = value(assetInfo(fromBase58String(landAssetId)))
32183294 let d = split(a.description, "_")
32193295 let pieces = numPiecesBySize(d[recLandSize])
32203296 let productivity = applyBonuses(landAssetId, pieces)
32213297 let deltaTime = (now - stakedTime)
32223298 let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
32233299 if ((MIN_RES_TO_ROB > availRes))
32243300 then acc
32253301 else (acc :+ landAssetId)
32263302 }
32273303 }
32283304 else acc
32293305 }
32303306
32313307 let filtered = {
32323308 let $l = candidates
32333309 let $s = size($l)
32343310 let $acc0 = nil
32353311 func $f0_1 ($a,$i) = if (($i >= $s))
32363312 then $a
32373313 else checker($a, $l[$i])
32383314
32393315 func $f0_2 ($a,$i) = if (($i >= $s))
32403316 then $a
32413317 else throw("List size exceeds 10")
32423318
32433319 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
32443320 }
32453321 if ((size(filtered) == 0))
32463322 then throw("No candidates for robbery")
32473323 else {
32483324 let rndIdx = getRandomNumber(size(filtered), height, (sig + i.transactionId))
32493325 let landAssetId = filtered[rndIdx]
32503326 $Tuple2([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId), prologAction], landAssetId)
32513327 }
32523328 }
32533329 }
32543330 }
32553331 }
32563332 }
32573333 }
32583334
32593335
32603336
32613337 @Callable(i)
32623338 func robLand (message,sig) = {
32633339 let prologAction = prolog(i)
32643340 if (!(sigVerify_8Kb(message, sig, pub)))
32653341 then throw("signature does not match")
32663342 else {
32673343 let userAddr = toString(i.caller)
32683344 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
32693345 let now = lastBlock.timestamp
32703346 $Tuple2([prologAction, IntegerEntry(keyLastRobberyTimeByDuck(duckAssetId), now)], 0)
32713347 }
32723348 }
32733349
32743350
32753351
32763352 @Callable(i)
32773353 func acceptDelivery () = if (!(KS_ALLOW_DELIVERY))
32783354 then throw("Delivery feature is turned off!")
32793355 else {
32803356 let prologAction = prolog(i)
32813357 let userAddr = toString(i.caller)
32823358 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
32833359 let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
3284- if ((MIN_USDT_FEE_DELIVERY > fundTotal))
3285- then throw(("Delivery is not available, fund=" + toString(fundTotal)))
3360+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
3361+ if ((MIN_USDT_FEE_DELIVERY > (fundTotal - lockedTotal)))
3362+ then throw(((("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)) + ", locked=") + fixedPoint(lockedTotal, 6)))
32863363 else {
3287- let keyHealth = keyDuckHealth(duckAssetId)
3288- let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
3289- let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
3290- let curLocKey = keyDuckLocation(duckAssetId)
3291- let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
32923364 let now = lastBlock.timestamp
3293- let deliveryLocation = (toString(now) + "_D_0")
3294- $Tuple2([prologAction, IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, deliveryLocation)], deliveryLocation)
3365+ let delayETA = valueOrElse(getInteger(keyDeliveryDelayByDuck(duckAssetId)), 0)
3366+ if ((delayETA > now))
3367+ then throw(("Delivery is forbidden for your duck until " + toString(delayETA)))
3368+ else if (checkTournament(duckAssetId))
3369+ then throw("acceptDelivery_checkTournament")
3370+ else if (checkDelivery(duckAssetId))
3371+ then throw("acceptDelivery_checkDelivery")
3372+ else {
3373+ let newLockedTotal = asInt(invoke(economyContract, "updateDeliveryLocked", [(lockedTotal + MIN_USDT_FEE_DELIVERY)], nil))
3374+ let keyHealth = keyDuckHealth(duckAssetId)
3375+ let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
3376+ let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
3377+ let curLocKey = keyDuckLocation(duckAssetId)
3378+ let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
3379+ let deliveryLocation = (toString(now) + "_D_0")
3380+ $Tuple2([prologAction, IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, deliveryLocation)], $Tuple2(deliveryLocation, newLockedTotal))
3381+ }
32953382 }
32963383 }
32973384
32983385

github/deemru/w8io/169f3d6 
311.14 ms