tx · 8q1UYuRzWnDJQRxsgDEhX7c3YHaefqDXH2nfHV3pcE6f

3PLncXtS1U83D6cQbFD3H8rBHPLgzxSFKZ1:  -0.10200000 Waves

2023.11.05 15:06 [3895834] smart account 3PLncXtS1U83D6cQbFD3H8rBHPLgzxSFKZ1 > SELF 0.00000000 Waves

{ "type": 13, "id": "8q1UYuRzWnDJQRxsgDEhX7c3YHaefqDXH2nfHV3pcE6f", "fee": 10200000, "feeAssetId": null, "timestamp": 1699185981389, "version": 2, "chainId": 87, "sender": "3PLncXtS1U83D6cQbFD3H8rBHPLgzxSFKZ1", "senderPublicKey": "BtDpFhgHQKHFVqYTMLReuZzqy94CRPSRkrYcSEVyjt4q", "proofs": [ "2cGkQP4uGi3Za9kVrd71hwHJiVsg5ifSfF6sPxBPNFKE6JFCJ8eyxXD9NZuMswoLLJv34SR3GScUs4qr3r4Ei5zq" ], "script": "base64:BgLcAQgCEgMKAQgSBAoCCAESAwoBBBIAEgMKAQgSABIDCgEIEgQKAgEIEgQKAgEIEgQKAgICEgUKAwEBARIAEgQKAggIEgASABIECgICAhIAEgMKAQgSBAoCCAgSAwoBGBIECgIICBIECgIICBIFCgMICAgSBAoCCAgSBwoFAQEBAQESAwoBARIFCgMBAQgSAwoBCBIDCgEIEgASBAoCCAESBAoCCAESAwoBCBIECgIICBIDCgEIEgASAwoBCBIDCgEIEgYKBAgBCAESABIECgICAhIECgICAhIAEgMKAQiiAgAJREFZTUlMTElTAIC4mSkBFGtleUxhc3RBcmJUaW1lQnlVc2VyAQRhZGRyCQCsAgICEGxhc3RBcmJUaW1lVXNlcl8FBGFkZHIBGmtleUFjcmVzU3Rha2VkQW1vdW50QnlVc2VyAQRhZGRyCQCsAgICGGFjcmVzU3Rha2VkQW1vdW50QnlVc2VyXwUEYWRkcgAGU0NBTEU4AIDC1y8ADHhwTGV2ZWxTY2FsZQCAGQAPeHBMZXZlbFJlY2lwUG93AKAfABJudW1Qb2ludHNPbkxldmVsVXAAAwAOcm9iYmVyeUNvc3RNaW4AgMLXLwAUcm9iYmVyeUNvb2xkb3duQ29lZmYAkAMADHJlcXVpcmVtZW50cwkAzAgCAghTdHJlbmd0aAkAzAgCAghBY2N1cmFjeQkAzAgCAglJbnRlbGxlY3QJAMwIAgIJRW5kdXJhbmNlCQDMCAICCURleHRlcml0eQkAzAgCAgVMZXZlbAkAzAgCAgZIZWFsdGgFA25pbAAMY2hhclN0cmVuZ3RoAAAADGNoYXJBY2N1cmFjeQABAA1jaGFySW50ZWxsZWN0AAIADWNoYXJFbmR1cmFuY2UAAwANY2hhckRleHRlcml0eQAEAAtzZWdCYWNrcGFjawAAAAtOVU1TRUdNRU5UUwAGAApOVU1NQUlOQVVYAAIACE1BWFNMT1RTAAIADU1BWFBST0RJTlNMT1QAHgAQbGFuZFJvYkNvb2xkb3ducwkAzAgCAAAJAMwIAgDAzyQJAMwIAgCg9zYJAMwIAgCA3MwUCQDMCAIAgK6mCgUDbmlsAA5NSU5fUkVTX1RPX1JPQgCA2sQJAAxyb2JJZHhMb2NrZWQAAQALZHVja0lkeEZyZWUAAAAQZHVja0lkeFByZXBhcmluZwABAQ1rZXlEdWNrSGVhbHRoAQtkdWNrQXNzZXRJZAkArAICAgtkdWNrSGVhbHRoXwULZHVja0Fzc2V0SWQBDGtleUR1Y2tDaGFycwELZHVja0Fzc2V0SWQJAKwCAgIKZHVja0NoYXJzXwULZHVja0Fzc2V0SWQBCWtleUR1Y2tYUAELZHVja0Fzc2V0SWQJAKwCAgIHZHVja1hQXwULZHVja0Fzc2V0SWQBDGtleUR1Y2tMZXZlbAELZHVja0Fzc2V0SWQJAKwCAgIKZHVja0xldmVsXwULZHVja0Fzc2V0SWQBEWtleUR1Y2tGcmVlUG9pbnRzAQtkdWNrQXNzZXRJZAkArAICAg9kdWNrRnJlZVBvaW50c18FC2R1Y2tBc3NldElkARBrZXlEdWNrRXF1aXBtZW50AQtkdWNrQXNzZXRJZAkArAICAg5kdWNrRXF1aXBtZW50XwULZHVja0Fzc2V0SWQBCWtleVVzZXJYUAEEYWRkcgkArAICAgd1c2VyWFBfBQRhZGRyAQxrZXlVc2VyTGV2ZWwBBGFkZHIJAKwCAgIKdXNlckxldmVsXwUEYWRkcgERa2V5VXNlckZyZWVQb2ludHMBBGFkZHIJAKwCAgIPdXNlckZyZWVQb2ludHNfBQRhZGRyAQ5rZXlTYXZlZEhlYWx0aAELZHVja0Fzc2V0SWQJAKwCAgIMc2F2ZWRIZWFsdGhfBQtkdWNrQXNzZXRJZAEQa2V5U2F2ZWRMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgIOc2F2ZWRMb2NhdGlvbl8FC2R1Y2tBc3NldElkAQxrZXlEdWNrQnVmZnMBC2R1Y2tBc3NldElkCQCsAgICCmR1Y2tCdWZmc18FC2R1Y2tBc3NldElkARhrZXlMYXN0Um9iYmVyeVRpbWVCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICEGxhc3RSb2JiZXJ5VGltZV8FC2R1Y2tBc3NldElkARhrZXlMYXN0Um9iYmVyeUNvc3RCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICEGxhc3RSb2JiZXJ5Q29zdF8FC2R1Y2tBc3NldElkARNrZXlMYW5kUm9iYmVyeVN0YXRlAQtsYW5kQXNzZXRJZAkArAICAhFsYW5kUm9iYmVyeVN0YXRlXwULbGFuZEFzc2V0SWQBEmtleUxhbmRDb29sZG93bkVUQQELbGFuZEFzc2V0SWQJAKwCAgIQbGFuZENvb2xkb3duRVRBXwULbGFuZEFzc2V0SWQBE2tleUR1Y2tSb2JiZXJ5U3RhdGUBC2R1Y2tBc3NldElkCQCsAgICEWR1Y2tSb2JiZXJ5U3RhdGVfBQtkdWNrQXNzZXRJZAETa2V5TG9ja2VkTGFuZEJ5RHVjawELZHVja0Fzc2V0SWQJAKwCAgIRbG9ja2VkTGFuZEJ5RHVja18FC2R1Y2tBc3NldElkARZrZXlEZWxpdmVyeURlbGF5QnlEdWNrAQtkdWNrQXNzZXRJZAkArAICAhRkZWxpdmVyeURlbGF5QnlEdWNrXwULZHVja0Fzc2V0SWQBFGtleVVzZXJEZWxpdmVyeUNvdW50AQRhZGRyCQCsAgICEnVzZXJEZWxpdmVyeUNvdW50XwUEYWRkcgEWa2V5VXNlckxhc3REZWxpdmVyeURheQEEYWRkcgkArAICAhR1c2VyTGFzdERlbGl2ZXJ5RGF5XwUEYWRkcgAHeHBDbGFpbQCQTgAPeHBTdWNjZXNzRmxpZ2h0AJBOAAx4cEZhaWxGbGlnaHQA0A8ACHhwQ2FsbEVTAKCNBgAMeHBDdXN0b21OYW1lAMCEPQAKeHBOZXdTTGFuZADAlrECAA54cFVwZ3JhZGVJbmZyYQCQTgAHeHBNZXJnZQDAhD0ACXhwT25ib2FyZADAhD0ABnhwSGVhbACQTgEJbGV2ZWxCeVhQAQJ4cAkAawMFDHhwTGV2ZWxTY2FsZQkAbAYFAnhwAAQFD3hwTGV2ZWxSZWNpcFBvdwAEAAQFBERPV04FBlNDQUxFOAEJbWF4SGVhbHRoAQVsZXZlbAkAZAIAZAUFbGV2ZWwBB2xldmVsVXACCWN1cnJMZXZlbAVuZXdYUAQIbmV3TGV2ZWwJAQlsZXZlbEJ5WFABBQVuZXdYUAkAzAgCBQhuZXdMZXZlbAkAzAgCCQBoAgUSbnVtUG9pbnRzT25MZXZlbFVwCQBlAgUIbmV3TGV2ZWwFCWN1cnJMZXZlbAUDbmlsAQxnZXREdWNrU3RhdHMED3N0YWtpbmdDb250cmFjdAtkdWNrQXNzZXRJZApidWZmRWZmZWN0CmZvcmNlQnVmZnMEBWNoYXJzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEMa2V5RHVja0NoYXJzAQULZHVja0Fzc2V0SWQCCTBfMF8wXzBfMAIBXwQDbHZsCQELdmFsdWVPckVsc2UCCQCaCAIFD3N0YWtpbmdDb250cmFjdAkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkAAAEBmhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9zdGFraW5nQ29udHJhY3QJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQJAQltYXhIZWFsdGgBBQNsdmwECnN0YXRlQnVmZnMJALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQxrZXlEdWNrQnVmZnMBBQtkdWNrQXNzZXRJZAIJMF8wXzBfMF8wAgFfCQDOCAIJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQxjaGFyU3RyZW5ndGgJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQxjaGFyQWNjdXJhY3kJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQ1jaGFySW50ZWxsZWN0CQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUNY2hhckVuZHVyYW5jZQkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDWNoYXJEZXh0ZXJpdHkJAMwIAgUDbHZsCQDMCAIFBmhlYWx0aAUDbmlsAwUKZm9yY2VCdWZmcwkAzAgCBQpidWZmRWZmZWN0CQDMCAIFCmJ1ZmZFZmZlY3QJAMwIAgUKYnVmZkVmZmVjdAkAzAgCBQpidWZmRWZmZWN0CQDMCAIFCmJ1ZmZFZmZlY3QFA25pbAkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKc3RhdGVCdWZmcwUMY2hhclN0cmVuZ3RoCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpzdGF0ZUJ1ZmZzBQxjaGFyQWNjdXJhY3kJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCnN0YXRlQnVmZnMFDWNoYXJJbnRlbGxlY3QJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCnN0YXRlQnVmZnMFDWNoYXJFbmR1cmFuY2UJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCnN0YXRlQnVmZnMFDWNoYXJEZXh0ZXJpdHkFA25pbAEOZ2V0Um9iYmVyeURhdGECD3N0YWtpbmdDb250cmFjdAtkdWNrQXNzZXRJZAQLbGFzdFJvYkNvc3QJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQEYa2V5TGFzdFJvYmJlcnlDb3N0QnlEdWNrAQULZHVja0Fzc2V0SWQAAAQLbGFzdFJvYlRpbWUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQEYa2V5TGFzdFJvYmJlcnlUaW1lQnlEdWNrAQULZHVja0Fzc2V0SWQAAAQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQHcm9iQ29zdAkAlgMBCQDMCAIFDnJvYmJlcnlDb3N0TWluCQDMCAIJAGUCBQtsYXN0Um9iQ29zdAkAaAIFFHJvYmJlcnlDb29sZG93bkNvZWZmCQBlAgUDbm93BQtsYXN0Um9iVGltZQUDbmlsBAlkdWNrU3RhdGUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQETa2V5RHVja1JvYmJlcnlTdGF0ZQEFC2R1Y2tBc3NldElkAAAECmxvY2tlZExhbmQJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQETa2V5TG9ja2VkTGFuZEJ5RHVjawEFC2R1Y2tBc3NldElkAgAEB2xhbmRFVEEJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPc3Rha2luZ0NvbnRyYWN0CQESa2V5TGFuZENvb2xkb3duRVRBAQUKbG9ja2VkTGFuZAAACQCXCgUFB3JvYkNvc3QFC2xhc3RSb2JUaW1lBQlkdWNrU3RhdGUFCmxvY2tlZExhbmQFB2xhbmRFVEEACkxBTkRQUkVGSVgCBExBTkQACkRVQ0tQUkVGSVgCBERVQ0sACkFSVFBSRVNBTEUCB1BSRVNBTEUABk5VTVJFUwAGABhNQVhfTEFORFNfU1RBS0VEX0JZX1VTRVIAGQAPREFJTFlSRVNCWVBJRUNFAID40gEADFdITVVMVElQTElFUgCAyK+gJQAPREVGQVVMVExPQ0FUSU9OAg9BZnJpY2FfRl9BZnJpY2EAEFJFU09VUkNFUFJJQ0VNSU4A1bUCAApFU1NFTExDT0VGAAoAFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQDQhgMAElRFTl9NSU5VVEVTX01JTExJUwDAzyQAF0FMTE9XRURfRlJFRV9ERUxJVkVSSUVTAAEAGkFDUkVTX0ZPUl9ERUxJVkVSWV9BVFRFTVBUAIDh6xcACXByb2RUeXBlcwkAzAgCAhBGaXJzdCBBaWQgS2l0IEwxCQDMCAICEEZpcnN0IEFpZCBLaXQgTDIJAMwIAgIQRmlyc3QgQWlkIEtpdCBMMwkAzAgCAgtCYWNrcGFjayBMMQkAzAgCAgtCYWNrcGFjayBMMgkAzAgCAgtCYWNrcGFjayBMMwkAzAgCAg5Gb29kIFJhdGlvbiBMMQkAzAgCAg5Gb29kIFJhdGlvbiBMMgkAzAgCAg5Gb29kIFJhdGlvbiBMMwkAzAgCAgtKZXQgUGFjayBMMQkAzAgCAgtKZXQgUGFjayBMMgkAzAgCAgtKZXQgUGFjayBMMwkAzAgCAglTaGllbGQgTDEJAMwIAgIJU2hpZWxkIEwyCQDMCAICCVNoaWVsZCBMMwkAzAgCAgdNaW5lIEwxCQDMCAICB01pbmUgTDIJAMwIAgIHTWluZSBMMwkAzAgCAgdUcmFwIEwxCQDMCAICB1RyYXAgTDIJAMwIAgIHVHJhcCBMMwUDbmlsAApjb250aW5lbnRzCQDMCAICCEFtZXJpY2FzCQDMCAICBkV1cm9wZQkAzAgCAgRBc2lhCQDMCAICBkFmcmljYQkAzAgCAgdPY2VhbmlhBQNuaWwACUNPRUZGMk1BVACAreIEABBmb3J0QWxsb3dlZFByb2RzCQDMCAIADwkAzAgCABAJAMwIAgARCQDMCAIAEgkAzAgCABMJAMwIAgAUBQNuaWwAEHByb2R1Y3Rpb25NYXRyaXgJAMwIAgIlOF84XzhfMTdfMTdfNDJfMTJfMF8zMF8wLDAsMCwwLDAsMCwwXwkAzAgCAiU4XzhfOF8xN18xN180Ml8yNF8wXzYwXzAsMCw1LDIsMCwwLDBfCQDMCAICJzhfOF84XzE3XzE3XzQyXzM2XzBfMTIwXzAsMCwxMCw0LDAsMCwwXwkAzAgCAik4XzE5XzE5XzhfMjdfMTlfMjZfMV8yMF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAik4XzE5XzE5XzhfMjdfMTlfNTJfMV80MF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAik4XzE5XzE5XzhfMjdfMTlfNzhfMV84MF8wLDAsMCwwLDAsMCwwXzAwMQkAzAgCAiU4XzhfOF84XzhfNjBfMTNfMl8yXzAsMCwwLDAsMCwwLDBfMDExCQDMCAICJThfOF84XzhfOF82MF8yNl8yXzRfMCwwLDAsMCwwLDAsMF8wMTEJAMwIAgIlOF84XzhfOF84XzYwXzM5XzJfOF8wLDAsMCwwLDAsMCwwXzAxMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfMzBfM18zMF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfNjBfM181MF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAikzMF8zMF8zXzE3XzE3XzNfOTBfM183MF8wLDAsMCwwLDAsMCwwXzExMQkAzAgCAisxOF8xOF8xMF8xOF8xOF8xOF8xMV80XzEwXzAsMCwwLDAsMCwwLDBfMjAxCQDMCAICKzE4XzE4XzEwXzE4XzE4XzE4XzIyXzRfMjBfMCwwLDAsMCwwLDAsMF8yMDEJAMwIAgIrMThfMThfMTBfMThfMThfMThfMzNfNF8zMF8wLDAsMCwwLDAsMCwwXzIwMQkAzAgCAio0XzEzXzIyXzRfMzVfMjJfMjNfMF81MCwxLDBfMCwwLDAsMCwwLDAsMF8JAMwIAgIqNF8xM18yMl80XzM1XzIyXzQ2XzBfNTAsMSwxXzAsMiw1LDAsMCwwLDBfCQDMCAICKzRfMTNfMjJfNF8zNV8yMl82OV8wXzUwLDIsMV8wLDUsMTAsMCwwLDAsMF8JAMwIAgIqNV8yNV80MF81XzEwXzE1XzIwXzFfMzAsMSwxXzAsMCwwLDAsMCwwLDBfCQDMCAICKjVfMjVfNDBfNV8xMF8xNV80MF8xXzMwLDEsMl8yLDEsMywwLDAsMCwwXwkAzAgCAio1XzI1XzQwXzVfMTBfMTVfNjBfMV8zMCwxLDNfNSwyLDgsMCwwLDAsMF8FA25pbAAJcklkeENvZWZmAAYACnJJZHhFZmZlY3QACAAQcklkeFJlcXVpcmVtZW50cwAJAAlySWR4U2xvdHMACgAOUFJPRFVDVFBLR1NJWkUACgALd2hJZHhMZXZlbHMAAAAId2hJZHhSZXMAAQAId2hJZHhNYXQAAgAJd2hJZHhQcm9kAAMACXdoSWR4TE9GVAAEAAl2b2xMb2NrZWQAAAALdm9sT2NjdXBpZWQAAQAHdm9sRnJlZQACAAh2b2xUb3RhbAADAApicElkeExldmVsAAAACGJwSWR4UmVzAAEACGJwSWR4TWF0AAIACWJwSWR4UHJvZAADAA9sb2NJZHhDb250aW5lbnQAAAAKbG9jSWR4VHlwZQABAAhsb2NJZHhJZAACARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBB2Fzc2V0SWQJAKwCAgIDbm9fBQdhc3NldElkARprZXlMYW5kQXNzZXRJZFRvQ3VzdG9tTmFtZQEHYXNzZXRJZAkArAICAgVsY25hXwUHYXNzZXRJZAEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEHYXNzZXRJZAkArAICAgNzdF8FB2Fzc2V0SWQBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgR0eXBlB2Fzc2V0SWQJALkJAgkAzAgCAgNsYXMJAMwIAgUEdHlwZQkAzAgCBQdhc3NldElkBQNuaWwCAV8BImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDB25mdFR5cGUHYXNzZXRJZAlvd25lckFkZHIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAgZzdHRhb18FB25mdFR5cGUCAV8FB2Fzc2V0SWQCAV8FCW93bmVyQWRkcgESa2V5V2FyZWhvdXNlQnlMYW5kAQtsYW5kQXNzZXRJZAkArAICAgN3aF8FC2xhbmRBc3NldElkARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQdhc3NldElkCQCsAgICC2luZnJhTGV2ZWxfBQdhc3NldElkARdrZXlGb3J0aWZpY2F0aW9uc0J5TGFuZAELbGFuZEFzc2V0SWQJAKwCAgIPZm9ydGlmaWNhdGlvbnNfBQtsYW5kQXNzZXRJZAEaa2V5RHVja0Fzc2V0SWRUb0N1c3RvbU5hbWUBB2Fzc2V0SWQJAKwCAgIYZHVja0N1c3RvbU5hbWVCeUFzc2V0SWRfBQdhc3NldElkARZrZXlBZGRyZXNzVG9DdXN0b21OYW1lAQRhZGRyCQCsAgICGGFjY291bnRDdXN0b21OYW1lQnlBZGRyXwUEYWRkcgEPa2V5QWRkcmVzc1JlZkJ5AQRhZGRyCQCsAgICCWFjY1JlZkJ5XwUEYWRkcgEca2V5T25ib2FyZEFydEFjdGl2YXRlZE9uRHVjawELZHVja0Fzc2V0SWQJAKwCAgIab25ib2FyZEFydEFjdGl2YXRlZE9uRHVja18FC2R1Y2tBc3NldElkARxrZXlPbmJvYXJkQXJ0RHVja0FjdGl2YXRlZEJ5AQRhZGRyCQCsAgICGm9uYm9hcmRBcnRBY3RpdmF0ZWREdWNrQnlfBQRhZGRyARNrZXlBZGRyZXNzUmVmZXJyYWxzAQRhZGRyCQCsAgICDWFjY1JlZmVycmFsc18FBGFkZHIBEGtleUR1Y2tJZFRvT3duZXIBB2Fzc2V0SWQJAKwCAgIKZHVja093bmVyXwUHYXNzZXRJZAEUa2V5U3Rha2VkRHVja0J5T3duZXIBCW93bmVyQWRkcgkArAICAhJzdGFrZWREdWNrQnlPd25lcl8FCW93bmVyQWRkcgERa2V5QmFja3BhY2tCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICCWJhY2tQYWNrXwULZHVja0Fzc2V0SWQBD2tleUR1Y2tMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgINZHVja0xvY2F0aW9uXwULZHVja0Fzc2V0SWQBFWtleVVzZXJHd2xSZWxlYXNlVGltZQEIdXNlckFkZHIJAKwCAgIaJXMlc19fdXNlckd3bFJlbGVhc2VUaW1lX18FCHVzZXJBZGRyAQ5rZXlFc1dhcmVob3VzZQACGmVtZXJnZW5jeVdhcmVob3VzZVByb2R1Y3RzAA9kZWxpdmVyeUZ1bmRLZXkCDGRlbGl2ZXJ5RnVuZAARZGVsaXZlcnlMb2NrZWRLZXkCDmRlbGl2ZXJ5TG9ja2VkAA1sYXN0VG91cklkS2V5Ag4lc19fbGFzdFRvdXJJZAEVa2V5VG91clN0YXRpY0RhdGFCeUlkAQN0SWQJAKwCAgIWJXMlZF9fdG91clN0YXRpY0RhdGFfXwkApAMBBQN0SWQBFmtleVRvdXJEeW5hbWljRGF0YUJ5SWQBA3RJZAkArAICAhclcyVkX190b3VyRHluYW1pY0RhdGFfXwkApAMBBQN0SWQBGmtleUJlc3RSZXN1bHRCeVRvdXJBbmREdWNrAgN0SWQLZHVja0Fzc2V0SWQJALkJAgkAzAgCAh8lcyVkJXNfX2Jlc3RSZXN1bHRCeVRvdXJBbmREdWNrCQDMCAIJAKQDAQUDdElkCQDMCAIFC2R1Y2tBc3NldElkBQNuaWwCAl9fAAlpZHhTdGF0aWMAAAAKaWR4RHluYW1pYwABAAp0U3RhdGljRW5kAAYADnREeW5hbWljU3RhdHVzAAEBC2dldFRvdXJEYXRhAgx0b3VyQ29udHJhY3QDdElkBAZzdGF0aWMJALUJAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFDHRvdXJDb250cmFjdAkBFWtleVRvdXJTdGF0aWNEYXRhQnlJZAEFA3RJZAkArAICCQCsAgICGUVycm9yIHJlYWRpbmcgdG91cm5hbWVudCAJAKQDAQUDdElkAgUgZGF0YQICX18EB2R5bmFtaWMJALwJAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFDHRvdXJDb250cmFjdAkBFmtleVRvdXJEeW5hbWljRGF0YUJ5SWQBBQN0SWQJAKwCAgkArAICAhlFcnJvciByZWFkaW5nIHRvdXJuYW1lbnQgCQCkAwEFA3RJZAIFIGRhdGECAl9fCQDMCAIFBnN0YXRpYwkAzAgCBQdkeW5hbWljBQNuaWwBDmlzSW5Ub3VybmFtZW50Agx0b3VyQ29udHJhY3QIbG9jYXRpb24EBmxhc3RJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBQx0b3VyQ29udHJhY3QFDWxhc3RUb3VySWRLZXkAAAQDbG9jCQC1CQIFCGxvY2F0aW9uAgFfBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAV0RGF0YQkBC2dldFRvdXJEYXRhAgUMdG91ckNvbnRyYWN0BQZsYXN0SWQEBnN0YXRpYwkAkQMCBQV0RGF0YQUJaWR4U3RhdGljBAdkeW5hbWljCQCRAwIFBXREYXRhBQppZHhEeW5hbWljAwMDCQAAAgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAVQJAAACCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDbG9jBQ9sb2NJZHhDb250aW5lbnQFBmxhc3RJZAcJAAACCQCRAwIFB2R5bmFtaWMFDnREeW5hbWljU3RhdHVzAgpJTlBST0dSRVNTBwkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFCnRTdGF0aWNFbmQFA25vdwcBDGlzSW5EZWxpdmVyeQEIbG9jYXRpb24EA2xvYwkAtQkCBQhsb2NhdGlvbgIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQJc3RhcnRUaW1lCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDbG9jBQ9sb2NJZHhDb250aW5lbnQECGRpc3RhbmNlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDbG9jBQhsb2NJZHhJZAMDCQAAAgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUQJAGYCCQBkAgUJc3RhcnRUaW1lBRJURU5fTUlOVVRFU19NSUxMSVMFA25vdwcJAGcCAAMFCGRpc3RhbmNlBwEPaXNVc3VhbExvY2F0aW9uAQhsb2NhdGlvbgQHbG9jVHlwZQkAkQMCCQC1CQIFCGxvY2F0aW9uAgFfBQpsb2NJZHhUeXBlAwkBAiE9AgUHbG9jVHlwZQIBVAkBAiE9AgUHbG9jVHlwZQIBRAcBCW9uTWlzc2lvbgIMdG91ckNvbnRyYWN0CGxvY2F0aW9uBAZsYXN0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUMdG91ckNvbnRyYWN0BQ1sYXN0VG91cklkS2V5AAAEA2xvYwkAtQkCBQhsb2NhdGlvbgIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFDHRvdXJDb250cmFjdAUGbGFzdElkBAZzdGF0aWMJAJEDAgUFdERhdGEFCWlkeFN0YXRpYwQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwQHbG9jVHlwZQkAkQMCBQNsb2MFCmxvY0lkeFR5cGUDCQAAAgUHbG9jVHlwZQIBRAYDAwMJAAACCQCRAwIFA2xvYwUKbG9jSWR4VHlwZQIBVAkAAAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNsb2MFD2xvY0lkeENvbnRpbmVudAUGbGFzdElkBwkAAAIJAJEDAgUHZHluYW1pYwUOdER5bmFtaWNTdGF0dXMCCklOUFJPR1JFU1MHCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUKdFN0YXRpY0VuZAUDbm93BwESZ2V0UmVjaXBlTWF0ZXJpYWxzAQZyZWNpcGUJAGgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcmVjaXBlBQlySWR4Q29lZmYFCUNPRUZGMk1BVAEMY2hlYXRBdHRlbXB0AwZvbGRMb2MGbmV3TG9jCWNoZWF0Q2FzZQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhZDaGVhdCBhdHRlbXB0OiBvbGRMb2M9BQZvbGRMb2MCCSwgbmV3TG9jPQUGbmV3TG9jAgcsIGNhc2U9CQCkAwEFCWNoZWF0Q2FzZQAWS1NfU0VQQVJBVEVfUFVCTElDX0tFWQcAGEtTX0FMTE9XX0JJR19JTkZSQV9NRVJHRQcACkRBWV9NSUxMSVMAgLiZKQAFY2hhaW4JAMkBAgkAygECCAUEdGhpcwVieXRlcwABAAEAC3VzZHRBc3NldElkBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwASCE2nqyCAM/TtG7yo7ui5O8yYLdC136B5ao1CP5qA//uQMJAAACAQFUBQckbWF0Y2gwASBVsdifcoeC7+XjW42sBatl3ppDoS8WuwXzGreHpfHFGAkAAgECDVVua25vd24gY2hhaW4AFWRlZmF1bHRSZXN0QWRkcmVzc1N0cgQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAIjM1BRQ3V2RmJ2aDRMa1BVbnJuVTF6M2puYkExcDltM1dOaHYDCQAAAgEBVAUHJG1hdGNoMAIjM011bWtHR3p0Q0tBWHBXRHF4a2Rkb2ZxWFNVYnFRa3ZTSnkJAAIBAg1Vbmtub3duIGNoYWluABFJbmZyYVVwZ3JhZGVDb3N0UwQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMACAyK+gJQMJAAACAQFUBQckbWF0Y2gwAIDC1y8JAAIBAg1Vbmtub3duIGNoYWluAA5hcmJpdHJhZ2VEZWxheQQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAUKREFZX01JTExJUwMJAAACAQFUBQckbWF0Y2gwAODUAwkAAgECDVVua25vd24gY2hhaW4AE0RFTElWRVJZX1BVTklTSE1FTlQEByRtYXRjaDAFBWNoYWluAwkAAAIBAVcFByRtYXRjaDAAgJeTBQMJAAACAQFUBQckbWF0Y2gwAKD3NgkAAgECDVVua25vd24gY2hhaW4AA1NFUAICX18ABU1VTFQ2AMCEPQAFTVVMVDgAgMLXLwAFU1NJWkUAGQAFTVNJWkUAZAAFTFNJWkUA4QEABlhMU0laRQCQAwAHWFhMU0laRQDxBAAFSVRFUjYJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAEPZ2V0U3RyaW5nT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFB2FkZHJlc3MFA2tleQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQdhZGRyZXNzCQDMCAICAS4JAMwIAgUDa2V5CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgAAEUlkeENmZ1N0YWtpbmdEYXBwAAEAEUlkeENmZ0Vjb25vbXlEYXBwAAIAFElkeENmZ0dvdmVybmFuY2VEYXBwAAMADUlkeENmZ1dsZ0RhcHAABAAUSWR4Q2ZnVG91cm5hbWVudERhcHAABwAPSWR4Q2ZnQWNyZXNEYXBwAAgBCmtleVJlc3RDZmcAAg4lc19fcmVzdENvbmZpZwEOa2V5UmVzdEFkZHJlc3MAAgwlc19fcmVzdEFkZHIBEXJlYWRSZXN0Q2ZnT3JGYWlsAQRyZXN0CQC8CQIJAQ9nZXRTdHJpbmdPckZhaWwCBQRyZXN0CQEKa2V5UmVzdENmZwAFA1NFUAEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgdyZXN0Q2ZnA2lkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUHcmVzdENmZwUDaWR4CQCsAgICKlJlc3QgY2ZnIGRvZXNuJ3QgY29udGFpbiBhZGRyZXNzIGF0IGluZGV4IAkApAMBBQNpZHgADHJlc3RDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEOa2V5UmVzdEFkZHJlc3MABRVkZWZhdWx0UmVzdEFkZHJlc3NTdHIAB3Jlc3RDZmcJARFyZWFkUmVzdENmZ09yRmFpbAEFDHJlc3RDb250cmFjdAAPc3Rha2luZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwURSWR4Q2ZnU3Rha2luZ0RhcHAAD2Vjb25vbXlDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFEUlkeENmZ0Vjb25vbXlEYXBwAAtnb3ZDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFFElkeENmZ0dvdmVybmFuY2VEYXBwAAt3bGdDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFDUlkeENmZ1dsZ0RhcHAAEnRvdXJuYW1lbnRDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFFElkeENmZ1RvdXJuYW1lbnREYXBwAA1hY3Jlc0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUPSWR4Q2ZnQWNyZXNEYXBwAApyZWNMYW5kTnVtAAAAC3JlY0xhbmRTaXplAAEAC3JlY1RlcnJhaW5zAAIADHJlY0NvbnRpbmVudAADAA13bGdBc3NldElkS2V5Agt3bGdfYXNzZXRJZAAKd2xnQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCcCAIFC3dsZ0NvbnRyYWN0BQ13bGdBc3NldElkS2V5AhhXTEdPTEQgaXMgbm90IGlzc3VlZCB5ZXQAD2FjcmVzQXNzZXRJZEtleQIMYWNyZXNBc3NldElkAAxhY3Jlc0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQ1hY3Jlc0NvbnRyYWN0BQ9hY3Jlc0Fzc2V0SWRLZXkCF0FDUkVTIGlzIG5vdCBpc3N1ZWQgeWV0AAtyYW5kb21EZWxheQACAQlrZXlDb21taXQBB2FkZHJlc3MJAKwCAgITZmluaXNoQmxvY2tGb3JBZGRyXwUHYWRkcmVzcwERa2V5UmVzUHJvcG9ydGlvbnMAAhNyZXNUeXBlc1Byb3BvcnRpb25zARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQljb250aW5lbnQJAKwCAgIUcmVzVHlwZXNCeUNvbnRpbmVudF8FCWNvbnRpbmVudAEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQlvd25lckFkZHIJAKwCAgITc3Rha2VkTGFuZHNCeU93bmVyXwUJb3duZXJBZGRyARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQlvd25lckFkZHIJAKwCAgIUc3Rha2VkUGllY2VzQnlPd25lcl8FCW93bmVyQWRkcgEIYXNTdHJpbmcBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwBQFzCQACAQIYZmFpbCB0byBjYXN0IGludG8gU3RyaW5nAQVhc0ludAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgNJbnQEAW4FByRtYXRjaDAFAW4JAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBCWFzQW55TGlzdAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAglMaXN0W0FueV0EAWwFByRtYXRjaDAFAWwJAAIBAhtmYWlsIHRvIGNhc3QgaW50byBMaXN0W0FueV0BCWFzQm9vbGVhbgEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAFzBQckbWF0Y2gwBQFzCQACAQIZZmFpbCB0byBjYXN0IGludG8gQm9vbGVhbgEPbnVtUGllY2VzQnlTaXplAQhsYW5kU2l6ZQQHJG1hdGNoMAUIbGFuZFNpemUDCQAAAgIBUwUHJG1hdGNoMAUFU1NJWkUDCQAAAgIBTQUHJG1hdGNoMAUFTVNJWkUDCQAAAgIBTAUHJG1hdGNoMAUFTFNJWkUDCQAAAgICWEwFByRtYXRjaDAFBlhMU0laRQMJAAACAgNYWEwFByRtYXRjaDAFB1hYTFNJWkUJAAIBAhFVbmtub3duIGxhbmQgc2l6ZQEHaXNEaWdpdAEBcwkBCWlzRGVmaW5lZAEJALYJAQUBcwEKa2V5QmxvY2tlZAACEGNvbnRyYWN0c0Jsb2NrZWQBEWtleUxhc3RUeElkQnlVc2VyAQRhZGRyCQCsAgICD2xh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ZXRJZAEHbGFuZE51bQkArAICAgNsYV8FB2xhbmROdW0BHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIHYXNzZXRJZAlvd25lckFkZHIJAKwCAgkArAICCQCsAgICBWlsYW9fBQdhc3NldElkAgFfBQlvd25lckFkZHIBEWtleUxhbmROdW1Ub093bmVyAQdsYW5kTnVtCQCsAgICA2xvXwUHbGFuZE51bQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBBG5hbWUJAKwCAgIRZHVja0J5Q3VzdG9tTmFtZV8FBG5hbWUBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBBG5hbWUJAKwCAgIUYWNjb3VudEJ5Q3VzdG9tTmFtZV8FBG5hbWUBCWtleU9sZGllcwACCm9sZGllc0xpc3QAC2NsYWltTW9kZVdoAAAADWNsYWltTW9kZUR1Y2sAAQATY2xhaW1Nb2RlV2hUaGVuRHVjawACAAhmbEhlYWx0aAAAAAtmbFRpbWVzdGFtcAAFAAdmbEJvbnVzAAYAC2ZsUHJvZHNVc2VkAAcBB25mdE5hbWUCB2xhbmROdW0IbGFuZFNpemUJAKwCAgkArAICBQpMQU5EUFJFRklYBQdsYW5kTnVtBQhsYW5kU2l6ZQEIdG9Wb2x1bWUCBmFtb3VudAdwa2dTaXplBARwa2dzAwkAZwIFBmFtb3VudAAACQBpAgkAZQIJAGQCBQZhbW91bnQFB3BrZ1NpemUAAQUHcGtnU2l6ZQkBAS0BCQBpAgkAZQIJAGQCCQEBLQEFBmFtb3VudAUHcGtnU2l6ZQABBQdwa2dTaXplCQBoAgUEcGtncwUFTVVMVDgBE2Rpc3RyaWJ1dGVCeVdlaWdodHMCBXRvdGFsB3dlaWdodHMEA3N1bQkAZAIJAGQCCQBkAgkAZAIJAGQCCQCRAwIFB3dlaWdodHMAAAkAkQMCBQd3ZWlnaHRzAAEJAJEDAgUHd2VpZ2h0cwACCQCRAwIFB3dlaWdodHMAAwkAkQMCBQd3ZWlnaHRzAAQJAJEDAgUHd2VpZ2h0cwAFAwkAZwIAAAUDc3VtCQACAQIQWmVybyB3ZWlnaHRzIHN1bQQFbm9ybTYJAGsDBQV0b3RhbAUFTVVMVDYFA3N1bQoBCm5vcm1hbGl6ZXICA2FjYwRlbGVtCQDNCAIFA2FjYwkAawMFBGVsZW0FBW5vcm02BQVNVUxUNgoAAiRsBQd3ZWlnaHRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpub3JtYWxpemVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGARJnZXROZWVkZWRNYXRlcmlhbHMBBXRvdGFsBAVwcm9wcwkAtQkCCQEFdmFsdWUBCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACAV8DCQECIT0CCQCQAwEFBXByb3BzBQZOVU1SRVMJAAIBAhZXcm9uZyBwcm9wb3J0aW9ucyBkYXRhBAFyCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAACQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwABCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwACCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwADCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAECQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAFBQNuaWwJARNkaXN0cmlidXRlQnlXZWlnaHRzAgUFdG90YWwFAXIBEXN1YnRyYWN0TWF0ZXJpYWxzAwxzaG91bGRVc2VNYXQDaGFzCXRvdGFsTmVlZAQEbmVlZAkBEmdldE5lZWRlZE1hdGVyaWFscwEFCXRvdGFsTmVlZAoBCnN1YnRyYWN0b3ICA2FjYwNpZHgEBnJlc3VsdAkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNoYXMFA2lkeAkAkQMCBQRuZWVkBQNpZHgDCQBmAgAABQZyZXN1bHQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIYTm90IGVub3VnaCBtYXRlcmlh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BGhlYWQJAMkBAgUFcExpc3QJAGgCAAgFCnByb2R1Y3RJZHgEBGN1cnIJALEJAQkAyQECCQDKAQIFBXBMaXN0CQBoAgAIBQpwcm9kdWN0SWR4AAgEBHRhaWwJAMoBAgUFcExpc3QJAGgCAAgJAGQCBQpwcm9kdWN0SWR4AAEEBnJlY2lwZQkAtQkCCQCRAwIFEHByb2R1Y3Rpb25NYXRyaXgFCnByb2R1Y3RJZHgCAV8DAwkBASEBBQppc1Bvc2l0aXZlCQBmAgUFY291bnQFBGN1cnIHCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCVlvdSBoYXZlIAkApAMBBQRjdXJyAgQgb2YgCQCRAwIFCXByb2RUeXBlcwUKcHJvZHVjdElkeAITLCBidXQgdHJpZWQgdG8gdXNlIAkApAMBBQVjb3VudAQGbmV3QW10AwMJAQEhAQUKaXNQb3NpdGl2ZQkBFWNoZWNrU3RhdFJlcXVpcmVtZW50cwIFCWR1Y2tTdGF0cwkAtQkCCQCRAwIFBnJlY2lwZQUQcklkeFJlcXVpcmVtZW50cwIBLAcJAGUCBQRjdXJyBQVjb3VudAkAZAIFBGN1cnIFBWNvdW50BAhkZWx0YVZvbAkAZQIJAQh0b1ZvbHVtZQIFBm5ld0FtdAUOUFJPRFVDVFBLR1NJWkUJAQh0b1ZvbHVtZQIFBGN1cnIFDlBST0RVQ1RQS0dTSVpFCQCVCgMJAMsBAgkAywECBQRoZWFkCQCaAwEFBm5ld0FtdAUEdGFpbAkAZAIFCG9jY3VwaWVkBQhkZWx0YVZvbAkAZQIFBGZyZWUFCGRlbHRhVm9sAQhhZGRQcm9kQgcGaWR4Q250BXBMaXN0CmlzUG9zaXRpdmUHc2VnbWVudAdtYWluQXV4BHNsb3QJZHVja1N0YXRzBAVwYXJ0cwkAtQkCBQZpZHhDbnQCAToDCQECIT0CCQCQAwEFBXBhcnRzAAIJAAIBAihJbmNvcnJlY3QgZm9ybWF0LCBzaG91bGQgYmUgaW5kZXg6YW1vdW50AwMJAQEhAQUKaXNQb3NpdGl2ZQkBAiE9AgkAsQIBCQCRAwIFBXBhcnRzAAAAAgcJAAIBAitQcm9kdWN0IGlkeCBzaG91bGQgYmUgMiBkaWdpdHMsIHplcm8gcGFkZGVkBApwcm9kdWN0SWR4CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcGFydHMAAAQFY291bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwYXJ0cwABAwMJAGYCAAAFCnByb2R1Y3RJZHgGCQBnAgUKcHJvZHVjdElkeAkAkAMBBRBwcm9kdWN0aW9uTWF0cml4CQACAQITVW5rbm93biBwcm9kdWN0IGlkeAMJAGYCAAAFBWNvdW50CQACAQIXQ291bnQgY2FuJ3QgYmUgbmVnYXRpdmUDCQBmAgUFY291bnQFDU1BWFBST0RJTlNMT1QJAAIBCQCsAgIJAKwCAgkArAICAhRDYW4ndCBwdXQgbW9yZSB0aGFuIAkApAMBBQ1NQVhQUk9ESU5TTE9UAgQgb2YgCQCRAwIFCXByb2RUeXBlcwUKcHJvZHVjdElkeAMJAAACBQVjb3VudAAACQCUCgIFBXBMaXN0BwQEaGVhZAkAyQECBQVwTGlzdAkAaAIACAUKcHJvZHVjdElkeAQEY3VycgkAsQkBCQDJAQIJAMoBAgUFcExpc3QJAGgCAAgFCnByb2R1Y3RJZHgACAQEdGFpbAkAygECBQVwTGlzdAkAaAIACAkAZAIFCnByb2R1Y3RJZHgAAQQGcmVjaXBlCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAUKcHJvZHVjdElkeAIBXwMDCQEBIQEFCmlzUG9zaXRpdmUJAGYCBQVjb3VudAUEY3VycgcJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIJWW91IGhhdmUgCQCkAwEFBGN1cnICBCBvZiAJAJEDAgUJcHJvZFR5cGVzBQpwcm9kdWN0SWR4AhMsIGJ1dCB0cmllZCB0byB1c2UgCQCkAwEFBWNvdW50BAlpc0JpZ0l0ZW0DAwkBASEBBQppc1Bvc2l0aXZlCQEVY2hlY2tTdGF0UmVxdWlyZW1lbnRzAgUJZHVja1N0YXRzCQC1CQIJAJEDAgUGcmVjaXBlBRBySWR4UmVxdWlyZW1lbnRzAgEsBwQGY29tcGF0CQCRAwIFBnJlY2lwZQUJcklkeFNsb3RzAwkAAAIFBmNvbXBhdAIACQACAQIXSXRlbSBjYW5ub3QgYmUgZXF1aXBwZWQEAWMJAQ1wYXJzZUludFZhbHVlAQUGY29tcGF0BARjU2VnCQBpAgUBYwBkAwkBAiE9AgUHc2VnbWVudAUEY1NlZwkAAgECFFNlZ21lbnQgaW5jb21wYXRpYmxlBAhjTWFpbkF1eAkAaQIJAGoCBQFjAGQACgMJAQIhPQIFB21haW5BdXgFCGNNYWluQXV4CQACAQIRU2xvdCBpbmNvbXBhdGlibGUECWNOdW1TbG90cwkAagIFAWMACgMDCQECIT0CBQRzbG90AAAJAGYCBQljTnVtU2xvdHMAAQcJAAIBAh5CaWcgaXRlbXMgc2hvdWxkIG9jY3VweSBzbG90IDAJAGYCBQljTnVtU2xvdHMAAQcJAJQKAgkAywECCQDLAQIFBGhlYWQJAJoDAQkAZAIFBGN1cnIDBQppc1Bvc2l0aXZlBQVjb3VudAkBAS0BBQVjb3VudAUEdGFpbAUJaXNCaWdJdGVtAQtzbG90c0dyb3VwQgYBZwRicEluCmlzUG9zaXRpdmUHc2VnbWVudAdtYWluQXV4BXN0YXRzAwkBAiE9AgUBZwIABAVzbG90cwkAtQkCBQFnAgEsAwkAZgIJAJADAQUFc2xvdHMFCE1BWFNMT1RTCQACAQISV3Jvbmcgc2xvdHMgZm9ybWF0BAJzMAkAkQMCBQVzbG90cwAABAJzMQMJAGYCCQCQAwEFBXNsb3RzAAEJAJEDAgUFc2xvdHMAAQIAAwMJAAACBQJzMAIACQAAAgUCczECAAcFBGJwSW4EBXRtcFMwAwkBAiE9AgUCczACAAkBCGFkZFByb2RCBwUCczAFBGJwSW4FCmlzUG9zaXRpdmUFB3NlZ21lbnQFB21haW5BdXgAAAUFc3RhdHMJAJQKAgUEYnBJbgcDCQECIT0CBQJzMQIAAwgFBXRtcFMwAl8yCQACAQIeQmlnIGl0ZW0gYWxyZWFkeSBvY2N1cGllcyBzbG90CAkBCGFkZFByb2RCBwUCczEIBQV0bXBTMAJfMQUKaXNQb3NpdGl2ZQUHc2VnbWVudAUHbWFpbkF1eAABBQVzdGF0cwJfMQgFBXRtcFMwAl8xBQRicEluAQZkcmVzc0IEB3NlZ0xpc3QGcEJ5dGVzCmlzUG9zaXRpdmUFc3RhdHMKAQdzZWdtZW50AgNhY2MDc2VnBAFqCAUDYWNjAl8xBAdtYWluQXV4CQC1CQIFA3NlZwIBOwMJAQIhPQIJAJADAQUHbWFpbkF1eAUKTlVN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cQUJdGVtcFByb2RCBwUFc3RhdHMJAAACBQhuZXdQcm9kQgUIbmV3UHJvZEIBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECHByb3BMaXN0DXRlcnJhaW5Db3VudHMNbGFuZFNpemVJbmRleARzaWduAwkBAiE9AgkAkAMBBQhwcm9wTGlzdAUGTlVNUkVTCQACAQIWV3JvbmcgcHJvcG9ydGlvbnMgZGF0YQoBB3VwZGF0ZXICA2FjYwFpBAZyZXN1bHQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvcExpc3QFAWkJAGgCCQBoAgUEc2lnbgkAkQMCBQ10ZXJyYWluQ291bnRzBQFpBQ1sYW5kU2l6ZUluZGV4AwkAZgIAAAUGcmVzdWx0CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhZQYW5pYyEgUGllY2VzIG9mIHR5cGU9CQCkAwEFAWkCBywgc2lnbj0JAKQDAQUEc2lnbgITLCB0ZXJyYWluQ291bnRzW2ldPQkApAMBCQCRAwIFDXRlcnJhaW5Db3VudHMFAWkCECwgbGFuZFNpemVJbmRleD0JAKQDAQUNbGFuZFNpemVJbmRleAkAzQgCBQNhY2MJAKQDAQUGcmVzdWx0CgACJGwFBUlURVI2CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQd1cGRhdGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGARF1cGRhdGVQcm9wb3J0aW9ucwMNdGVycmFpbkNvdW50cw1sYW5kU2l6ZUluZGV4BHNpZ24ECHByb3BMaXN0CQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBEWtleVJlc1Byb3BvcnRpb25zAAILMF8wXzBfMF8wXzACAV8JALkJAgkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwEBQhwcm9wTGlzdAUNdGVycmFpbkNvdW50cwUNbGFuZFNpemVJbmRleAUEc2lnbgIBXwENY291bnRUZXJyYWlucwEIdGVycmFpbnMJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBQQABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUIAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFDAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBRAABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUUAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFGAAEFA25pbAEGYWRkUmVzBQpjdXJyZW50UmVzDXRlcnJhaW5Db3VudHMJZGVsdGFUaW1lDWxhbmRTaXplSW5kZXgXZGFpbHlCeVBpZWNlV2l0aEJvbnVzZXMKAQVhZGRlcgIDYWNjAWkECXJlc09mVHlwZQkAaAIJAGgCCQBrAwUJZGVsdGFUaW1lBRdkYWlseUJ5UGllY2VXaXRoQm9udXNlcwUJREFZTUlMTElTCQCRAwIFDXRlcnJhaW5Db3VudHMFAWkFDWxhbmRTaXplSW5kZXgJAM0IAgUDYWNjCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKY3VycmVudFJlcwUBaQUJcmVzT2ZUeXBlBAFyCgACJGwFBUlURVI2CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQVhZGRlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgkAuQkCBQFyAgFfAQl2aXJ0Q2xhaW0EDXRlcnJhaW5Db3VudHMJZGVsdGFUaW1lDWxhbmRTaXplSW5kZXgXZGFpbHlCeVBpZWNlV2l0aEJvbnVzZXMKAQVhZGRlcgIDYWNjAWkE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aFN0cgkBC3ZhbHVlT3JFbHNlAgkAoggBBQV3aEtleQkArAICBQl2b2xQcmVmaXgCGzowXzBfMF8wXzBfMDowXzBfMF8wXzBfMDo6MAQCd2gJALwJAgUFd2hTdHICAToECndoT2NjdXBpZWQJARdnZXRXYXJlaG91c2VPY2N1cGllZFZvbAEFAndoBAZ3aExvZnQDCQBmAgAFCQCQAwEFAndoCQC5CQIJAMwIAgIBMAkAzAgCCQCkAwEFCndoT2NjdXBpZWQJAMwIAgkApAMBCQBlAgUHd2hUb3RhbAUKd2hPY2N1cGllZAkAzAgCCQCkAwEFB3doVG90YWwFA25pbAIBXwQEbG9mdAkAtQkCCQCRAwIFAndoBQl3aElkeExPRlQCAV8ECHdoTG9ja2VkCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUJdm9sTG9ja2VkBANvY2MDCQBmAgkAkAMBBQRsb2Z0AAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQt2b2xPY2N1cGllZAUKd2hPY2N1cGllZAkAuQkCCQDMCAIJAKQDAQUId2hMb2NrZWQJAMwIAgkApAMBBQNvY2MJAMwIAgkApAMBCQBlAgkAZQIFB3doVG90YWwFCHdoTG9ja2VkBQNvY2MJAMwIAgkApAMBBQd3aFRvdGFsBQNuaWwCAV8JAMwIAgkAkQMCBQJ3aAULd2hJZHhMZXZlbHMJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQJ3aAUId2hJZHhSZXMCAV8FBk5VTVJFUwkAkQMCBQJ3aAUId2hJZHhSZXMCCzBfMF8wXzBfMF8wCQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUCd2gFCHdoSWR4TWF0AgFfBQZOVU1SRVMJAJEDAgUCd2gFCHdoSWR4TWF0AgswXzBfMF8wXzBfMAkAzAgCCQCRAwIFAndoBQl3aElkeFByb2QJAMwIAgUGd2hMb2Z0BQNuaWwBFWdldFdhcmVob3VzZVNwYWNlTGVmdAEJY3VycmVudFdoBAtvY2N1cGllZFZvbAkBF2dldFdhcmVob3VzZU9jY3VwaWVkVm9sAQUJY3VycmVudFdoBA9jdXJyV2hMb2NrZWRWb2wJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeExPRlQCAV8FCXZvbExvY2tlZAkAZQIJAGUCCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFCWN1cnJlbnRXaAULd2hJZHhMZXZlbHMFC29jY3VwaWVkVm9sBQ9jdXJyV2hMb2NrZWRWb2wBCW1vdmVTdHVmZgMKY2FyZ29QYXJ0cwljdXJyZW50V2gLY3VycmVudFBhY2sDCQECIT0CCQCQAwEFCmNhcmdvUGFydHMAAwkAAgECNGNhcmdvTGlzdFN0ciBzaG91bGQgY29udGFpbiBleGFjdGx5IDIgJzonIHNlcGFyYXRvcnMECHJlc1BhcnRzCQC1CQIJAJEDAgUKY2FyZ29QYXJ0cwAAAgFfBAhtYXRQYXJ0cwkAtQkCCQCRAwIFCmNhcmdvUGFydHMAAQIBXwQJcHJvZFBhcnRzAwkAAAIJAJEDAgUKY2FyZ29QYXJ0cwACAgAFA25pbAkAvAkCCQCRAwIFCmNhcmdvUGFydHMAAgIBXwMJAQIhPQIJAJADAQUIcmVzUGFydHMFBk5VTVJFUwkAAgECIEFsbCA2IHJlc291cmNlcyBzaG91bGQgYmUgcGFzc2VkAwkBAiE9AgkAkAMBBQhtYXRQYXJ0cwUGTlVNUkVTCQACAQIgQWxsIDYgbWF0ZXJpYWxzIHNob3VsZCBiZSBwYXNzZWQEC3doU3BhY2VMZWZ0CQEVZ2V0V2FyZWhvdXNlU3BhY2VMZWZ0AQUJY3VycmVudFdoBAljdXJyV2hSZXMJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBAljdXJyV2hNYXQJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4TWF0AgFfBApjdXJyV2hQcm9kAwkAAAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAV8EDmN1cnJlbnRQYWNrUmVzCQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAgFfBA5jdXJyZW50UGFja01hdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQPY3VycmVudFBhY2tQcm9kAwkAAAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIABQNuaWwJALwJAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgFfCgEDbXZSAgNhY2MEaXRlbQQBaQgFA2FjYwJfMQQCYW0JAQ1wYXJzZUludFZhbHVlAQUEaXRlbQQDd2hyCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJY3VycldoUmVzBQFpBANicHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5jdXJyZW50UGFja1JlcwUBaQMJAAACBQJhbQAACQCWCgQJAGQCBQFpAAEJAM0IAggFA2FjYwJfMgkAkQMCBQljdXJyV2hSZXMFAWkJAM0IAggFA2FjYwJfMwkAkQMCBQ5jdXJyZW50UGFja1JlcwUBaQgFA2FjYwJfNAMJAGYCBQJhbQAAAwkAZgIFAmFtBQNicHIJAAIBCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gdGFrZSAFBGl0ZW0CGSBmcm9tIGJhY2twYWNrLCBidXQgb25seSAJAKQDAQUDYnByAgogYXZhaWxhYmxlCQCWCgQJAGQCBQFpAAEJAM0IAggFA2FjYwJfMgkApAMBCQBkAgUDd2hyBQJhbQkAzQgCCAUDYWNjAl8zCQCkAwEJAGUCBQNicHIFAmFtCQBkAggFA2FjYwJfNAUCYW0DCQBmAgkBAS0BBQJhbQUDd2hyCQACAQkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHRha2UgCQCkAwEJAQEtAQUCYW0CGiBmcm9tIHdhcmVob3VzZSwgYnV0IG9ubHkgCQCkAwEFA3docgIKIGF2YWlsYWJsZQkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZAIFA3docgUCYW0JAM0IAggFA2FjYwJfMwkApAMBCQBlAgUDYnByBQJhbQkAZAIIBQNhY2MCXzQFAmFtBAFyCgACJGwFCHJlc1BhcnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlgoEAAAFA25pbAUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBA212UgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgoBA212TQIDYWNjBGl0ZW0EAWkIBQNhY2MCXzEEAmFtCQENcGFyc2VJbnRWYWx1ZQEFBGl0ZW0EA3dobQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWN1cnJXaE1hdAUBaQQDYnBtCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOY3VycmVudFBhY2tNYXQFAWkDCQAAAgUCYW0AAAkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAJEDAgUJY3VycldoTWF0BQFpCQDNCAIIBQNhY2MCXzMJAJEDAgUOY3VycmVudFBhY2tNYXQFAWkIBQNhY2MCXzQDCQBmAgUCYW0AAAMJAGYCBQJhbQUDYnBtCQACAQkArAICCQCsAgIJAKwCAgkArAICAhBBdHRlbXB0IHRvIHRha2UgBQRpdGVtAhkgZnJvbSBiYWNrcGFjaywgYnV0IG9ubHkgCQCkAwEFA2JwbQIKIGF2YWlsYWJsZQkAlgoECQBkAgUBaQABCQDNCAIIBQNhY2MCXzIJAKQDAQkAZAIFA3dobQUCYW0JAM0IAggFA2FjYwJfMwkApAMBCQBlAgUDYnBtBQJhbQkAZAIIBQNhY2MCXzQFAmFtAwkAZgIJAQEtAQUCYW0FA3dobQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIQQXR0ZW1wdCB0byB0YWtlIAkApAMBCQEBLQEFAmFtAhogZnJvbSB3YXJlaG91c2UsIGJ1dCBvbmx5IAkApAMBBQN3aG0CCiBhdmFpbGFibGUJAJYKBAkAZAIFAWkAAQkAzQgCCAUDYWNjAl8yCQCkAwEJAGQCBQN3aG0FAmFtCQDNCAIIBQNhY2MCXzMJAKQDAQkAZQIFA2JwbQUCYW0JAGQCCAUDYWNjAl80BQJhbQQBbQoAAiRsBQhtYXRQYXJ0cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJYKBAAABQNuaWwFA25pbAgFAXICXzQKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBA212TQIFAiRhCQCRAwIFAiRsBQIk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ACcAKAApACoAKwAsAC0ALgAvADAAMQAyCQCWCgQAAAUKY3VycldoUHJvZAUPY3VycmVudFBhY2tQcm9kCAUBbQJfNAQIdm9sU2FsZG8IBQFwAl80AwkAZgIFCHZvbFNhbGRvBQt3aFNwYWNlTGVmdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIVQXR0ZW1wdCB0byBwdXQgdG90YWwgCQCkAwEFCHZvbFNhbGRvAhEgc3R1ZmYsIGJ1dCBvbmx5IAkApAMBBQt3aFNwYWNlTGVmdAIVIHdhcmVob3VzZSBzcGFjZSBsZWZ0CQCZCgcJALkJAggFAXICXzICAV8JALkJAggFAW0CXzICAV8JALoJAggFAXACXzICAV8JALkJAggFAXICXzMCAV8JALkJAggFAW0CXzMCAV8JALoJAggFAXACXzMCAV8FCHZvbFNhbGRvARJleHBlZGl0aW9uSW50ZXJuYWwCBmNhbGxlcgR0eElkBAh1c2VyQWRkcgkApQgBBQZjYWxsZXIEBmJpZ051bQkBA2FicwEJAJ4DAQUEdHhJZAQHZnJlZU51bQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFD1BSRVNBTEVOVU1MQU5EUwABBAdsYW5kTnVtCQCkAwEFB2ZyZWVOdW0EDGNvbnRpbmVudElkeAkAoAMBCQC7AgIFBmJpZ051bQUFRklWRVgECHRlcnJhaW5zCQELZ2VuVGVycmFpbnMCBQZiaWdOdW0FDGNvbnRpbmVudElkeAQJY29udGluZW50CQCRAwIFCmNvbnRpbmVudHMFDGNvbnRpbmVudElkeAQFaXNzdWUJAMIIBQkBB25mdE5hbWUCBQdsYW5kTnVtAgFTCQC5CQIJAMwIAgUHbGFuZE51bQkAzAgCAgFTCQDMCAIFCHRlcnJhaW5zCQDMCAIFCWNvbnRpbmVudAUDbmlsAgFfAAEAAAcEB2Fzc2V0SWQJALgIAQUFaXNzdWUEAmlkCQDYBAEFB2Fzc2V0SWQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmtleU5leHRGcmVlTGFuZE51bQAJAGQCBQdmcmVlTnVtAAEJAMwIAgUFaXNzdWUJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleUxhbmRUb0Fzc2V0SWQBBQdsYW5kTnVtBQJpZAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQUCaWQFCHVzZXJBZGRyCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlMYW5kTnVtVG9Pd25lcgEFB2xhbmROdW0FCHVzZXJBZGRyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFAmlkAAAJAMwIAgkBDEludGVnZXJFbnRyeQIJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQJpZAUIdXNlckFkZHIAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIAAQUHYXNzZXRJZAUDbmlsCQCUCgIFAmlkBQljb250aW5lbnQBDGZsaWdodENvbW1vbgMIdXNlckFkZHIHbWVzc2FnZQNzaWcDCQEBIQEJAMQTAwUHbWVzc2FnZQUDc2lnBQNwdWIJAAIBAhhzaWduYXR1cmUgZG9lcyBub3QgbWF0Y2gEBXBhcnRzCQC8CQIJALAJAQUHbWVzc2FnZQIBOwQJZmxpZ2h0TG9nCQC8CQIJAJEDAgUFcGFydHMAAAIBfAQCaHAJALUJAgkAkQMCBQlmbGlnaHRMb2cFCGZsSGVhbHRoAgFfBAVjdXJIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAAEBW5ld0hQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaHAAAQQLbmV3TG9jVHhWZXIJALUJAgkAkQMCBQVwYXJ0cwABAgE6BAtuZXdMb2NhdGlvbgkAkQMCBQtuZXdMb2NUeFZlcgAABAR0aW1lCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJZmxpZ2h0TG9nBQtmbFRpbWVzdGFtcAMDCQBmAgUEdGltZQkAZAIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwYJAGYCCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFEUZJVkVNSU5VVEVTTUlMTElTBQR0aW1lCQACAQkArAICCQCsAgIJAKwCAgIcc2lnbmF0dXJlIG91dGRhdGVkOiBsb2dUaW1lPQkApAMBBQR0aW1lAgksIGJjVGltZT0JAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAECXR4RnJvbU1zZwkAkQMCBQtuZXdMb2NUeFZlcgABBAZsYXN0VHgJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBEWtleUxhc3RUeElkQnlVc2VyAQUIdXNlckFkZHICAAMJAQIhPQIFBmxhc3RUeAUJdHhGcm9tTXNnCQACAQkArAICCQCsAgIJAKwCAgIeVHggaWRzIGRvbid0IG1hdGNoISBJbiBzdGF0ZTogBQZsYXN0VHgCCiwgaW4gbXNnOiAFCXR4RnJvbU1zZwQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQh1c2VyQWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAVtYXhIUAkBCW1heEhlYWx0aAEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkAAAEDG9sZEZyb21TdGF0ZQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgFBW1heEhQAwkBAiE9AgUMb2xkRnJvbVN0YXRlBQVjdXJIUAkAAgEJAKwCAgkArAICCQCsAgICCm9sZEhlYWx0aD0JAKQDAQUMb2xkRnJvbVN0YXRlAi8gZnJvbSBzdGF0ZSBkb2VzIG5vdCBtYXRjaCBvbmUgZnJvbSBmbGlnaHQgbG9nPQkApAMBBQVjdXJIUAMJAGcCAAAFBWN1ckhQCQACAQIeWW91IGNhbid0IGZseSB3aXRoIHplcm8gaGVhbHRoAwkBASEBCQEXY2FuV2VhckN1cnJlbnRFcXVpcG1lbnQBBQtkdWNrQXNzZXRJZAkAAgECFkVxdWlwbWVudCBpbmNvbXBhdGlibGUEBWJvbnVzAwkAZgIJAJADAQUJZmxpZ2h0TG9nBQdmbEJvbnVzCQCRAwIFCWZsaWdodExvZwUHZmxCb251cwIABAhwcm9kVXNlZAMJAGYCCQCQAwEFCWZsaWdodExvZwULZmxQcm9kc1VzZWQJAJEDAgUJZmxpZ2h0TG9nBQtmbFByb2RzVXNlZAIABApzZW50QW1vdW50AwMJAGYCBQVuZXdIUAAACQAAAgUFYm9udXMCASQHCQEFYXNJbnQBCQD8BwQFDHJlc3RDb250cmFjdAINc2VuZFVzZHRQcml6ZQkAzAgCBQh1c2VyQWRkcgUDbmlsBQNuaWwAAAkAlwoFBQVuZXdIUAULZHVja0Fzc2V0SWQFCnNlbnRBbW91bnQFC25ld0xvY2F0aW9uBQhwcm9kVXNlZAEMYXBwbHlCb251c2VzAgtsYW5kQXNzZXRJZAZwaWVjZXMECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAlhcnRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQAAAQEYWRkNgkAaQIFCmluZnJhTGV2ZWwABgQEYWRkNwkAaQIFCmluZnJhTGV2ZWwABwkAZAIJAGQCBQ9EQUlMWVJFU0JZUElFQ0UJAGsDBQ9EQUlMWVJFU0JZUElFQ0UJAGQCCQBkAgUKaW5mcmFMZXZlbAUEYWRkNgkAaAIAAgUEYWRkNwAFCQBrAwUPREFJTFlSRVNCWVBJRUNFBQlhcnRQaWVjZXMJAGgCBQZwaWVjZXMABQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBGFkZHIJY2xhaW1Nb2RlDWxhbmRBc3NldElkSW4EDSR0MDMzNzM4MzQyNzcDCQAAAgUJY2xhaW1Nb2RlBQtjbGFpbU1vZGVXaAkAlAoCBQ1sYW5kQXNzZXRJZEluCQELdmFsdWVPckVsc2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMCQCUCgIJAJEDAgUDbG9jBQhsb2NJZHhJZAULZHVja0Fzc2V0SWQEC2xhbmRBc3NldElkCAUNJHQwMzM3MzgzNDI3NwJfMQQGZHVja0lkCAUNJHQwMzM3MzgzNDI3NwJfMgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAQJc2F2ZWRUaW1lCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUHdGltZUtleQkArAICCQCsAgICBUxhbmQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAFkCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwkAlgoEBQZkdWNrSWQFC2xhbmRBc3NldElkBQFkBQlzYXZlZFRpbWUBEGNsYWltUmVzSW50ZXJuYWwEBGFkZHIGYW1vdW50CWNsYWltTW9kZQ1sYW5kQXNzZXRJZEluAwkAZgIAAAUGYW1vdW50CQACAQIPTmVnYXRpdmUgYW1vdW50BAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBQRhZGRyBQljbGFpbU1vZGUFDWxhbmRBc3NldElkSW4ECGxhbmRTaXplCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIIBQFjAl8zBQtyZWNUZXJyYWlucwQJZGVsdGFUaW1lCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAIBQFjAl80AwkAZgIAAAUJZGVsdGFUaW1lCQACAQkArAICCQCsAgIJAKwCAgImU2F2ZWQgdGltZXN0YW1wIGlzIGluIGZ1dHVyZSwgc2F2ZWQgPSAJAKQDAQgFAWMCXzQCDCwgY3VycmVudCA9IAkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUEFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQxhcHBseUJvbnVzZXMCCAUBYwJfMgUGcGllY2VzBAhhdmFpbFJlcwkAawMFCWRlbHRhVGltZQkAaAIFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UFBnBpZWNlcwUJREFZTUlMTElTAwkAZgIFBmFtb3VudAUIYXZhaWxSZXMJAAIBCQCsAgIJAKwCAgkArAICAiJOb3QgZW5vdWdoIHJlc291cmNlcywgYXZhaWxhYmxlID0gCQCkAwEFCGF2YWlsUmVzAg4sIHJlcXVlc3RlZCA9IAkApAMBBQZhbW91bnQEDG5ld0RlbHRhVGltZQkAawMJAGUCBQhhdmFpbFJlcwUGYW1vdW50BQlEQVlNSUxMSVMJAGgCBRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBQZwaWVjZXMEDG5ld1RpbWVzdGFtcAkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQxuZXdEZWx0YVRpbWUECWxhbmRJbmRleAkAaQIFBnBpZWNlcwUFU1NJWkUECnJlc1RvQ2xhaW0JAQl2aXJ0Q2xhaW0EBQ10ZXJyYWluQ291bnRzCQBlAgUJZGVsdGFUaW1lBQxuZXdEZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBCAUBYwJfMgQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEIBQFjAl8yAAAECWN1cnJlbnRXaAkBDGdldFdhcmVob3VzZQMFBXdoS2V5BQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwEBGxvZnQJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAIBXwQLd2hTcGFjZUxlZnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlAwMJAAACBQljbGFpbU1vZGUFC2NsYWltTW9kZVdoCQBmAgUGYW1vdW50BQt3aFNwYWNlTGVmdAcJAAIBCQCsAgIJAKwCAgIFT25seSAJAKQDAQULd2hTcGFjZUxlZnQCGCBzcGFjZSBsZWZ0IGluIHdhcmVob3VzZQQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEIBQFjAl8xBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEDmN1cnJlbnRQYWNrUmVzCQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAgFfBAxjdXJyZW50V2hSZXMJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBA0kdDAzNjY1MTM3NTIyAwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAJYKBAkBBmFkZFJlcwUFDGN1cnJlbnRXaFJlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFC3ZvbE9jY3VwaWVkCAUKcmVzVG9DbGFpbQJfMgkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlCAUKcmVzVG9DbGFpbQJfMgMJAAACBQljbGFpbU1vZGUFDWNsYWltTW9kZUR1Y2sJAJYKBAkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzCQEGYWRkUmVzBQUOY3VycmVudFBhY2tSZXMFDXRlcnJhaW5Db3VudHMJAGUCBQlkZWx0YVRpbWUFDG5ld0RlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlBAVkaXN0cgkBDWRpc3RyaWJ1dGVSZXMEBQxjdXJyZW50V2hSZXMFDmN1cnJlbnRQYWNrUmVzBQpyZXNUb0NsYWltBQt3aFNwYWNlTGVmdAQEd2hBbQkAlwMBCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlCQDMCAIIBQpyZXNUb0NsYWltAl8yBQNuaWwJAJYKBAgFBWRpc3RyAl8xCAUFZGlzdHICXzIJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQFBHdoQW0JAGUCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAUHdm9sRnJlZQUEd2hBbQQFd2hSZXMIBQ0kdDAzNjY1MTM3NTIyAl8xBAVicFJlcwgFDSR0MDM2NjUxMzc1MjICXzIEBWxvZnRPCAUNJHQwMzY2NTEzNzUyMgJfMwQFbG9mdEYIBQ0kdDAzNjY1MTM3NTIyAl80CQCXCgUJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQgFAWMCXzIFDG5ld1RpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYCAUBYwJfMgUEYWRkcgUMbmV3VGltZXN0YW1wBQNuaWwFBWJwS2V5CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgUFYnBSZXMJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwFBXdoS2V5CQDMCAIJAJEDAgUJY3VycmVudFdoBQt3aElkeExldmVscwkAzAgCBQV3aFJlcwkAzAgCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQJAMwIAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAkAzAgCCQC5CQIJAMwIAgkAkQMCBQRsb2Z0BQl2b2xMb2NrZWQJAMwIAgkApAMBBQVsb2Z0TwkAzAgCCQCkAwEFBWxvZnRGCQDMCAIJAJEDAgUEbG9mdAUIdm9sVG90YWwFA25pbAIBXwUDbmlsAQhjbGFpbUFsbAQEYWRkcgtsYW5kQXNzZXRJZAZwaWVjZXMJY2xhaW1Nb2RlBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBAlzYXZlZFRpbWUJAQV2YWx1ZQEJAJ8IAQUHdGltZUtleQQIYXZhaWxSZXMJAGgCCQBrAwkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQlzYXZlZFRpbWUJAQxhcHBseUJvbnVzZXMCBQtsYW5kQXNzZXRJZAUGcGllY2VzBQlEQVlNSUxMSVMFBnBpZWNlcwkBEGNsYWltUmVzSW50ZXJuYWwEBQRhZGRyBQhhdmFpbFJlcwUJY2xhaW1Nb2RlBQtsYW5kQXNzZXRJZAENdXBJbmZyYUNvbW1vbgQMc2hvdWxkVXNlTWF0BmNhbGxlcg1wYXltZW50QW1vdW50C2xhbmRBc3NldElkBARhZGRyCQClCAEFBmNhbGxlcgQBYwkBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwUEYWRkcgUTY2xhaW1Nb2RlV2hUaGVuRHVjawULbGFuZEFzc2V0SWQEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAggFAWMCXzMFC3JlY0xhbmRTaXplBAhpbmZyYUtleQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBCAUBYwJfMgQIY3VyTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUIaW5mcmFLZXkAAAMDCQEBIQEFGEtTX0FMTE9XX0JJR19JTkZSQV9NRVJHRQkAZwIFCGN1ckxldmVsAAMHCQACAQImQ3VycmVudGx5IG1heCBpbmZyYXN0cnVjdHVyZSBsZXZlbCA9IDMECG1heEluZnJhCQBkAgkAaQIJAQRzcXJ0BAUGcGllY2VzAAAAAAUERE9XTgAFAAIECG5ld0xldmVsCQBkAgUIY3VyTGV2ZWwAAQMDBRhLU19BTExPV19CSUdfSU5GUkFfTUVSR0UJAGYCBQhuZXdMZXZlbAUIbWF4SW5mcmEHCQACAQkArAICAiVDdXJyZW50bHkgbWF4IGluZnJhc3RydWN0dXJlIGxldmVsID0gCQCkAwEFCG1heEluZnJhBARjb3N0CQBrAwUVSW5mcmFVcGdyYWRlQ29zdFNVc2R0CQBoAgUGcGllY2VzBQhuZXdMZXZlbAUFU1NJWkUDAwkBASEBBQxzaG91bGRVc2VNYXQJAQIhPQIFDXBheW1lbnRBbW91bnQFBGNvc3QHCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUEY29zdAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEIBQFjAl8xBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBW1MaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBAdtYXRVc2VkCQBrAwURSW5mcmFVcGdyYWRlQ29zdFMJAGgCBQZwaWVjZXMFCG5ld0xldmVsBQVTU0laRQQGbmV3TWF0CQC5CQIJARFzdWJ0cmFjdE1hdGVyaWFscwMFDHNob3VsZFVzZU1hdAUFbUxpc3QFB21hdFVzZWQCAV8EC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyCAUBYwJfMgUGcGllY2VzBRNjbGFpbU1vZGVXaFRoZW5EdWNrBAZ3aERhdGEIBQtjbGFpbVJlc3VsdAJfNQQGb2xkVm9sCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFBndoRGF0YQULd2hJZHhMZXZlbHMECm5ld1ZvbERhdGEJALkJAgkAzAgCCQCRAwIJALUJAgkAkQMCBQZ3aERhdGEFC3doSWR4TGV2ZWxzAgFfAAAJAMwIAgkApAMBBQhuZXdMZXZlbAUDbmlsAgFfBAZuZXdWb2wJARdnZXRXYXJlaG91c2VUb3RhbFZvbHVtZQEFCm5ld1ZvbERhdGEEBGxvZnQJALUJAgkAkQMCBQZ3aERhdGEFCXdoSWR4TE9GVAIBXwQKbmV3TG9mdFN0cgkAuQkCCQDMCAIJAJEDAgUEbG9mdAUJdm9sTG9ja2VkCQDMCAIJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQJAMwIAgkApAMBCQBlAgkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsb2Z0BQd2b2xGcmVlBQZuZXdWb2wFBm9sZFZvbAkAzAgCCQCkAwEFBm5ld1ZvbAUDbmlsAgFfCQCVCgMJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUIaW5mcmFLZXkFCG5ld0xldmVsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAggFAWMCXzIFBGFkZHIFCG5ld0xldmVsCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIIBQtjbGFpbVJlc3VsdAJfMwUIYnBJZHhSZXMJAMwIAgUGbmV3TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6CQDMCAIJAQtTdHJpbmdFbnRyeQIIBQtjbGFpbVJlc3VsdAJfNAkAuQkCCQDMCAIFCm5ld1ZvbERhdGEJAMwIAgkAkQMCBQZ3aERhdGEFCHdoSWR4UmVzCQDMCAIJAJEDAgUGd2hEYXRhBQh3aElkeE1hdAkAzAgCCQCRAwIFBndoRGF0YQUJd2hJZHhQcm9kCQDMCAIFCm5ld0xvZnRTdHIFA25pbAIBOgUDbmlsCAULY2xhaW1SZXN1bHQCXzEFCG5ld0xldmVsBQdtYXRVc2VkARN1cGRhdGVTdGF0c0ludGVybmFsBAZsdmxLZXkFeHBLZXkJcG9pbnRzS2V5B2RlbHRhWFAEAnhwCQELdmFsdWVPckVsc2UCCQCfCAEFBXhwS2V5AAAEBW5ld1hQCQBkAgUCeHAFB2RlbHRhWFAECWx2bFBvaW50cwkBB2xldmVsVXACCQELdmFsdWVPckVsc2UCCQCfCAEFBmx2bEtleQAABQVuZXdYUAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQZsdmxLZXkJAJEDAgUJbHZsUG9pbnRzAAAJAMwIAgkBDEludGVnZXJFbnRyeQIFBXhwS2V5BQVuZXdYUAkAzAgCCQEMSW50ZWdlckVudHJ5AgUJcG9pbnRzS2V5CQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlwb2ludHNLZXkAAAkAkQMCBQlsdmxQb2ludHMAAQUDbmlsBQVuZXdYUAEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCC2R1Y2tBc3NldElkB2RlbHRhWFAJARN1cGRhdGVTdGF0c0ludGVybmFsBAkBDGtleUR1Y2tMZXZlbAEFC2R1Y2tBc3NldElkCQEJa2V5RHVja1hQAQULZHVja0Fzc2V0SWQJARFrZXlEdWNrRnJlZVBvaW50cwEFC2R1Y2tBc3NldElkBQdkZWx0YVhQARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgRhZGRyB2RlbHRhWFAJARN1cGRhdGVTdGF0c0ludGVybmFsBAkBDGtleVVzZXJMZXZlbAEFBGFkZHIJAQlrZXlVc2VyWFABBQRhZGRyCQERa2V5VXNlckZyZWVQb2ludHMBBQRhZGRyBQdkZWx0YVhQARJhY3RpdmF0ZU9uYm9hcmRBcnQBBGFkZHIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQIcmVmQnlLZXkJAQ9rZXlBZGRyZXNzUmVmQnkBBQRhZGRyBAVyZWZCeQkAoggBBQhyZWZCeUtleQMJAQEhAQkBCWlzRGVmaW5lZAEFBXJlZkJ5CQACAQIpWW91IGFyZSBub3QgZWxpZ2libGUgZm9yIE9OQk9BUkQgYXJ0aWZhY3QEBmFydEtleQkBHGtleU9uYm9hcmRBcnREdWNrQWN0aXZhdGVkQnkBBQRhZGRyBAdhcnREdWNrCQCiCAEFBmFydEtleQMJAQlpc0RlZmluZWQBBQdhcnREdWNrCQACAQkArAICAi9Zb3UgYWxyZWFkeSB1c2VkIHlvdXIgT05CT0FSRCBhcnRpZmFjdCBvbiBkdWNrIAkBBXZhbHVlAQUHYXJ0RHVjawQQZHVja0FjdGl2YXRvcktleQkBHGtleU9uYm9hcmRBcnRBY3RpdmF0ZWRPbkR1Y2sBBQtkdWNrQXNzZXRJZAQNZHVja0FjdGl2YXRvcgkAoggBBRBkdWNrQWN0aXZhdG9yS2V5AwkBCWlzRGVmaW5lZAEFDWR1Y2tBY3RpdmF0b3IJAAIBCQCsAgIJAKwCAgkArAICAglUaGUgZHVjayAFC2R1Y2tBc3NldElkAjQgYWxyZWFkeSBnb3QgcG9pbnRzIGZyb20gT05CT0FSRCBhcnRpZmFjdCBmcm9tIHVzZXIgCQEFdmFsdWUBBQ1kdWNrQWN0aXZhdG9yCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUGYXJ0S2V5BQtkdWNrQXNzZXRJZAkAzAgCCQELU3RyaW5nRW50cnkCBRBkdWNrQWN0aXZhdG9yS2V5BQRhZGRyBQNuaWwICQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQtkdWNrQXNzZXRJZAUJeHBPbmJvYXJkAl8xARJhY3RpdmF0ZVByZXNhbGVBcnQCBGFkZHINbGFuZEFzc2V0SWRJbgQBYwkBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwUEYWRkcgUTY2xhaW1Nb2RlV2hUaGVuRHVjawUNbGFuZEFzc2V0SWRJbgQLbGFuZEFzc2V0SWQIBQFjAl8yBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQNYWN0aXZhdGlvbktleQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQDCQBmAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ1hY3RpdmF0aW9uS2V5AAAAAAkAAgECJVByZXNhbGUgYXJ0aWZhY3QgaXMgYWxyZWFkeSBhY3RpdmF0ZWQDCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIIBQFjAl8zBQpyZWNMYW5kTnVtBQ9QUkVTQUxFTlVNTEFORFMJAAIBCQCsAgIJAKwCAgkArAICBQpMQU5EUFJFRklYAgEgBQtsYW5kQXNzZXRJZAIlIGlzIG5vdCBlbGlnaWJsZSBmb3IgcHJlc2FsZSBhcnRpZmFjdAQLY2xhaW1SZXN1bHQJAQhjbGFpbUFsbAQFBGFkZHIFC2xhbmRBc3NldElkBQZwaWVjZXMFE2NsYWltTW9kZVdoVGhlbkR1Y2sJAM0IAgkAzQgCCQDNCAIIBQtjbGFpbVJlc3VsdAJfMQkBDEludGVnZXJFbnRyeQIFDWFjdGl2YXRpb25LZXkFBnBpZWNlcwkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al8yCQC5CQIIBQtjbGFpbVJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al80CQC5CQIIBQtjbGFpbVJlc3VsdAJfNQIBOgEPY2hlY2tUb3VybmFtZW50AQtkdWNrQXNzZXRJZAQGbGFzdElkCQELdmFsdWVPckVsc2UCCQCaCAIFEnRvdXJuYW1lbnRDb250cmFjdAUNbGFzdFRvdXJJZEtleQAABAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAgFfBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAV0RGF0YQkBC2dldFRvdXJEYXRhAgUSdG91cm5hbWVudENvbnRyYWN0BQZsYXN0SWQEBnN0YXRpYwkAkQMCBQV0RGF0YQUJaWR4U3RhdGljBAdkeW5hbWljCQCRAwIFBXREYXRhBQppZHhEeW5hbWljAwkBAiE9AgkAkQMCBQtjdXJMb2NhdGlvbgUKbG9jSWR4VHlwZQIBVAcDAwMJAAACCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgULY3VyTG9jYXRpb24FD2xvY0lkeENvbnRpbmVudAUGbGFzdElkCQAAAgkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwIKSU5QUk9HUkVTUwcJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQNub3cHCQACAQIqWW91ciBkdWNrIGlzIHRha2luZyBwYXJ0IGluIHRoZSB0b3VybmFtZW50CQEJYXNCb29sZWFuAQkA/AcEBQR0aGlzAhZleGl0VG91cm5hbWVudEludGVybmFsCQDMCAIFC2R1Y2tBc3NldElkBQNuaWwFA25pbAENY2hlY2tEZWxpdmVyeQELZHVja0Fzc2V0SWQEC2N1ckxvY2F0aW9uCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04CAV8EA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXADCQECIT0CCQCRAwIFC2N1ckxvY2F0aW9uBQpsb2NJZHhUeXBlAgFEBwQJc3RhcnRUaW1lCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgULY3VyTG9jYXRpb24FD2xvY0lkeENvbnRpbmVudAQIZGlzdGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtjdXJMb2NhdGlvbgUIbG9jSWR4SWQDAwkAZgIJAGQCBQlzdGFydFRpbWUFElRFTl9NSU5VVEVTX01JTExJUwUDbm93CQBmAgABBQhkaXN0YW5jZQcJAAIBAiBZb3VyIGR1Y2sgaXMgb24gZGVsaXZlcnkgbWlzc2lvbgkBCWFzQm9vbGVhbgEJAPwHBAUEdGhpcwIUZXhpdERlbGl2ZXJ5SW50ZXJuYWwJAMwIAgULZHVja0Fzc2V0SWQFA25pbAUDbmlsARJleGl0RGVsaXZlcnlDb21tb24EC2R1Y2tBc3NldElkBWNoZWNrBW5ld0hQBXNjb3JlBAtjdXJMb2NhdGlvbgkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAgFfBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAlzdGFydFRpbWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQtjdXJMb2NhdGlvbgUPbG9jSWR4Q29udGluZW50BAhkaXN0YW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFC2N1ckxvY2F0aW9uBQhsb2NJZHhJZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEQa2V5RHVja0lkVG9Pd25lcgEFC2R1Y2tBc3NldElkAhRORlQgZHVjayBpcyBvcnBoYW5lZAQJaGVhbHRoS2V5CQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAljdXJIZWFsdGgJARFAZXh0ck5hdGl2ZSgxMDU1KQEFCWhlYWx0aEtleQQOb3V0Y29tZUFjdGlvbnMDAwkAZgIFCGRpc3RhbmNlAAAGAwMFBWNoZWNrCQBmAgUFc2NvcmUAAAcJAGYCBQVuZXdIUAAABwQGcmV3YXJkCQD8BwQFD2Vjb25vbXlDb250cmFjdAISc2VuZERlbGl2ZXJ5UmV3YXJkCQDMCAIFBW93bmVyBQNuaWwFA25pbAMJAAACBQZyZXdhcmQFBnJld2FyZAQIY291bnRLZXkJARRrZXlVc2VyRGVsaXZlcnlDb3VudAEFBW93bmVyCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQhjb3VudEtleQkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUIY291bnRLZXkAAAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5VXNlckxhc3REZWxpdmVyeURheQEFBW93bmVyCQBpAgUJc3RhcnRUaW1lBQlEQVlNSUxMSVMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMDAwUFY2hlY2sJAGYCBQVuZXdIUAAABwkAZgIJAGQCBQlzdGFydFRpbWUFElRFTl9NSU5VVEVTX01JTExJUwUDbm93BwkAAgECJllvdXIgZHVjayBpcyBzdGlsbCBvbiBkZWxpdmVyeSBtaXNzaW9uBAtsb2NrZWRUb3RhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9lY29ub215Q29udHJhY3QFEWRlbGl2ZXJ5TG9ja2VkS2V5AAAEBnVubG9jawkA/AcEBQ9lY29ub215Q29udHJhY3QCFHVwZGF0ZURlbGl2ZXJ5TG9ja2VkCQDMCAIJAGUCBQtsb2NrZWRUb3RhbAUVTUlOX1VTRFRfRkVFX0RFTElWRVJZBQNuaWwFA25pbAMJAAACBQZ1bmxvY2sFBnVubG9jawMDAwUFY2hlY2sJAGcCAAAFBW5ld0hQBwYJAGcCAAAFCWN1ckhlYWx0aAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5RGVsaXZlcnlEZWxheUJ5RHVjawEFC2R1Y2tBc3NldElkCQBkAgUJc3RhcnRUaW1lBRNERUxJVkVSWV9QVU5JU0hNRU5UBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EDXNhdmVkTG9jYXRpb24JARFAZXh0ck5hdGl2ZSgxMDU4KQEJARBrZXlTYXZlZExvY2F0aW9uAQULZHVja0Fzc2V0SWQJAJUKAwUOb3V0Y29tZUFjdGlvbnMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ1zYXZlZExvY2F0aW9uBQNuaWwFDXNhdmVkTG9jYXRpb24BDW1lcmdlSW50ZXJuYWwGC25ld0xhbmRTaXplCG5ld0xldmVsB2Zvcm11bGEEYWRkcgxsYW5kQXNzZXRJZHMHbmVlZE1hdAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBD2NoZWNrVG91cm5hbWVudAEFC2R1Y2tBc3NldElkCQACAQIdbWVyZ2VJbnRlcm5hbF9jaGVja1RvdXJuYW1lbnQDCQENY2hlY2tEZWxpdmVyeQEFC2R1Y2tBc3NldElkCQACAQIbbWVyZ2VJbnRlcm5hbF9jaGVja0RlbGl2ZXJ5CgEKY2hlY2tNZXJnZQIDYWNjC2xhbmRBc3NldElkBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBAlzYXZlZFRpbWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQd0aW1lS2V5CQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8ECWNvbnRpbmVudAkAkQMCBQFkBQxyZWNDb250aW5lbnQDAwkBAiE9AggFA2FjYwJfMwIACQECIT0CCAUDYWNjAl8zBQljb250aW5lbnQHCQACAQIuTGFuZHMgc2hvdWxkIGJlIG9uIHRoZSBzYW1lIGNvbnRpbmVudCB0byBtZXJnZQQIbGFuZFNpemUJAJEDAgUBZAULcmVjTGFuZFNpemUEB3NpemVzSW4IBQNhY2MCXzEEAWkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAswkCBQdzaXplc0luBQhsYW5kU2l6ZQInWW91IGhhdmVuJ3QgcGFzc2VkIGFsbCB0aGUgbGFuZHMgbmVlZGVkBAhzaXplc091dAkArAICCQCvAgIFB3NpemVzSW4FAWkJALACAgUHc2l6ZXNJbgkAZAIFAWkAAQQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUEBGFydHMJAGQCCAUDYWNjAl8yCQELdmFsdWVPckVsc2UCCQCfCAEJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkAAAECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAhyZXFMZXZlbAQHJG1hdGNoMAUIbGFuZFNpemUDCQAAAgIBUwUHJG1hdGNoMAADAwkAAAICAU0FByRtYXRjaDAABAMJAAACAgFMBQckbWF0Y2gwAAUDCQAAAgICWEwFByRtYXRjaDAABgkAAgECGk9ubHkgUywgTSwgTCwgWEwgY2FuIG1lcmdlAwkBAiE9AgUKaW5mcmFMZXZlbAUIcmVxTGV2ZWwJAAIBAiJBbGwgbGFuZHMgc2hvdWxkIGJlIG1heGVkIHRvIG1lcmdlBAdsYW5kTnVtCQCRAwIFAWQFCnJlY0xhbmROdW0EDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQJZGVsdGFUaW1lCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFCXNhdmVkVGltZQMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEFCXNhdmVkVGltZQIMLCBjdXJyZW50ID0gCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBBZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQEMYXBwbHlCb251c2VzAgULbGFuZEFzc2V0SWQFBnBpZWNlcwQJbGFuZEluZGV4CQBpAgUGcGllY2VzBQVTU0laRQQFYnBSZXMJAQZhZGRSZXMFCQC1CQIIBQNhY2MCXzQCAV8FDXRlcnJhaW5Db3VudHMFCWRlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBAVwcm9wcwkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECAUDYWNjAl82BQ10ZXJyYWluQ291bnRzBQlsYW5kSW5kZXgA////////////AQQGY1Byb3BzCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQIBQNhY2MDXzEwBQ10ZXJyYWluQ291bnRzBQlsYW5kSW5kZXgA////////////AQQLc3VtVGVycmFpbnMJARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAgFA2FjYwJfOQUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AAEEBWxhbmRzCAUDYWNjAl83BANpZHgJAM8IAgUFbGFuZHMFC2xhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQUDaWR4CQACAQkArAICAiBZb3VyIHN0YWtlZCBsYW5kcyBkb24ndCBjb250YWluIAULbGFuZEFzc2V0SWQECWN1c3RvbUtleQkBGmtleUxhbmRBc3NldElkVG9DdXN0b21OYW1lAQULbGFuZEFzc2V0SWQECmN1c3RvbU5hbWUJAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VzdG9tS2V5AgAJAJwKCgUIc2l6ZXNPdXQFBGFydHMFCWNvbnRpbmVudAUFYnBSZXMJAM4IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIIBQNhY2MCXzUJAQtEZWxldGVFbnRyeQEJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKTEFORFBSRUZJWAULbGFuZEFzc2V0SWQFBGFkZHIJAQtEZWxldGVFbnRyeQEJARBrZXlMYW5kVG9Bc3NldElkAQUHbGFuZE51bQkBC0RlbGV0ZUVudHJ5AQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQELRGVsZXRlRW50cnkBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQELRGVsZXRlRW50cnkBCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAgULbGFuZEFzc2V0SWQFBGFkZHIJAQtEZWxldGVFbnRyeQEJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkCQELRGVsZXRlRW50cnkBCQERa2V5TGFuZE51bVRvT3duZXIBBQdsYW5kTnVtCQELRGVsZXRlRW50cnkBCQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEFCWN1c3RvbUtleQkBBEJ1cm4CCQDZBAEFC2xhbmRBc3NldElkAAEDCQECIT0CBQpjdXN0b21OYW1lAgAJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBGmtleUxhbmRDdXN0b21OYW1lVG9Bc3NldElkAQUKY3VzdG9tTmFtZQUDbmlsBQNuaWwFBXByb3BzCQDRCAIFBWxhbmRzCQEFdmFsdWUBBQNpZHgJAGQCCAUDYWNjAl84BQZwaWVjZXMFC3N1bVRlcnJhaW5zBQZjUHJvcHMEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAhwcm9wTGlzdAkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACCzBfMF8wXzBfMF8wAgFfBAhsYW5kc0tleQkBFWtleVN0YWtlZExhbmRzQnlPd25lcgEFBGFkZHIECGxhbmRzU3RyCQCiCAEFCGxhbmRzS2V5BAdsYW5kc0luAwkBCWlzRGVmaW5lZAEFCGxhbmRzU3RyCQC9CQIJAQV2YWx1ZQEFCGxhbmRzU3RyAgFfBQNuaWwEBWNvbnQwCQCRAwIJALUJAggJAQV2YWx1ZQEJAOwHAQkA2QQBCQCRAwIFDGxhbmRBc3NldElkcwAAC2Rlc2NyaXB0aW9uAgFfBQxyZWNDb250aW5lbnQECWNvbnRQcm9wcwkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQUFY29udDACCzBfMF8wXzBfMF8wAgFfBAFyCgACJGwFDGxhbmRBc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJwKCgUHZm9ybXVsYQAAAgAJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzBQNuaWwFCHByb3BMaXN0BQdsYW5kc0luAAAJALUJAgILMF8wXzBfMF8wXzACAV8FCWNvbnRQcm9wcwoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEKY2hlY2tNZXJnZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUECWNvbnRpbmVudAgFAXICXzMEDGNvbnRpbmVudElkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDPCAIFCmNvbnRpbmVudHMFCWNvbnRpbmVudAkArAICAhNVbmtub3duIGNvbnRpbmVudDogBQljb250aW5lbnQECHRlcnJhaW5zCQETZ2VuVGVycmFpbnNGb3JNZXJnZQIIBQFyAl85CQBpAgkBD251bVBpZWNlc0J5U2l6ZQEFC25ld0xhbmRTaXplBQVTU0laRQQHZnJlZU51bQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFD1BSRVNBTEVOVU1MQU5EUwABBApuZXdMYW5kTnVtCQCkAwEFB2ZyZWVOdW0EBWlzc3VlCQDCCAUJAQduZnROYW1lAgUKbmV3TGFuZE51bQULbmV3TGFuZFNpemUJALkJAgkAzAgCBQpuZXdMYW5kTnVtCQDMCAIFC25ld0xhbmRTaXplCQDMCAIFCHRlcnJhaW5zCQDMCAIFCWNvbnRpbmVudAUDbmlsAgFfAAEAAAcEB2Fzc2V0SWQJALgIAQUFaXNzdWUEDm5ld0xhbmRBc3NldElkCQDYBAEFB2Fzc2V0SWQEBm5ld01hdAkAuQkCCQERc3VidHJhY3RNYXRlcmlhbHMDCQBmAgUHbmVlZE1hdAAACQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBQduZWVkTWF0AgFfBAlwaWVjZXNLZXkJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUEYWRkcgQMc3Rha2VkUGllY2VzCQELdmFsdWVPckVsc2UCCQCfCAEFCXBpZWNlc0tleQAACQCUCgIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIIBQFyAl81AwkAZgIJAJADAQgFAXICXzcAAAkBC1N0cmluZ0VudHJ5AgUIbGFuZHNLZXkJALsJAggFAXICXzcCAV8JAQtEZWxldGVFbnRyeQEFCGxhbmRzS2V5CQEMSW50ZWdlckVudHJ5AgUJcGllY2VzS2V5AwkAZgIIBQFyAl84BQxzdGFrZWRQaWVjZXMAAAkAZQIFDHN0YWtlZFBpZWNlcwgFAXICXzgJAQxJbnRlZ2VyRW50cnkCCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFB2ZyZWVOdW0AAQUFaXNzdWUJAQtTdHJpbmdFbnRyeQIJARBrZXlMYW5kVG9Bc3NldElkAQUKbmV3TGFuZE51bQUObmV3TGFuZEFzc2V0SWQJAQtTdHJpbmdFbnRyeQIJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQ5uZXdMYW5kQXNzZXRJZAUEYWRkcgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUKbmV3TGFuZE51bQUEYWRkcgkBDEludGVnZXJFbnRyeQIJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFDm5ld0xhbmRBc3NldElkCAUBcgJfMgkBDEludGVnZXJFbnRyeQIJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQUObmV3TGFuZEFzc2V0SWQFCG5ld0xldmVsCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIFDm5ld0xhbmRBc3NldElkBQRhZGRyBQhuZXdMZXZlbAkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIIBQFyAl80CQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAkAuQkCCAUBcgJfNgIBXwkBC1N0cmluZ0VudHJ5AgkBFmtleVJlc1R5cGVzQnlDb250aW5lbnQBBQljb250aW5lbnQJALkJAggFAXIDXzEwAgFfCQELU3RyaW5nRW50cnkCCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQJALkJAgkAzAgCBQljb250aW5lbnQJAMwIAgIBTAkAzAgCBQ5uZXdMYW5kQXNzZXRJZAUDbmlsAgFfCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQRhZGRyAAEFB2Fzc2V0SWQFDm5ld0xhbmRBc3NldElkAQNzMm0CBGFkZHIMbGFuZEFzc2V0SWRzCQENbWVyZ2VJbnRlcm5hbAYCAU0AAwIEU1NTUwUEYWRkcgUMbGFuZEFzc2V0SWRzAAABA20ybAIEYWRkcgxsYW5kQXNzZXRJZHMJAQ1tZXJnZUludGVybmFsBgIBTAAEAgNTTU0FBGFkZHIFDGxhbmRBc3NldElkcwkAaAIFEUluZnJhVXBncmFkZUNvc3RTAAQBBGwyeGwCBGFkZHIMbGFuZEFzc2V0SWRzCQENbWVyZ2VJbnRlcm5hbAYCAlhMAAUCBVNTU01MBQRhZGRyBQxsYW5kQXNzZXRJZHMJAGgCBRFJbmZyYVVwZ3JhZGVDb3N0UwAvAQZ4bDJ4eGwCBGFkZHIMbGFuZEFzc2V0SWRzCQENbWVyZ2VJbnRlcm5hbAYCA1hYTAAGAgNMWEwFBGFkZHIFDGxhbmRBc3NldElkcwkAaAIFEUluZnJhVXBncmFkZUNvc3RTADYBC21lcmdlQ29tbW9uAgRhZGRyDGxhbmRBc3NldElkcwQHJG1hdGNoMAkAkAMBBQxsYW5kQXNzZXRJZHMDCQAAAgAEBQckbWF0Y2gwCQEDczJtAgUEYWRkcgUMbGFuZEFzc2V0SWRzAwkAAAIAAwUHJG1hdGNoMAkBA20ybAIFBGFkZHIFDGxhbmRBc3NldElkcwMJAAACAAUFByRtYXRjaDAJAQRsMnhsAgUEYWRkcgUMbGFuZEFzc2V0SWRzAwkAAAIAAgUHJG1hdGNoMAkBBnhsMnh4bAIFBGFkZHIFDGxhbmRBc3NldElkcwkAAgECDVVua25vd24gbWVyZ2UBFWNoZWNrT3V0ZGF0ZWREZWxpdmVyeQEIdXNlckFkZHIEBGR1Y2sJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUIdXNlckFkZHIDCQEJaXNEZWZpbmVkAQUEZHVjawQLZHVja0Fzc2V0SWQJAQV2YWx1ZQEFBGR1Y2sEBmxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBANsb2MJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQZsb2NLZXkFD0RFRkFVTFRMT0NBVElPTgIBXwQJc3RhcnRUaW1lCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDbG9jBQ9sb2NJZHhDb250aW5lbnQDAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUQGCQBmAgkAZAIFCXN0YXJ0VGltZQUSVEVOX01JTlVURVNfTUlMTElTCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUDbmlsBAloZWFsdGhLZXkJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQDCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2xvYwUIbG9jSWR4SWQAAAQGcmV3YXJkCQD8BwQFD2Vjb25vbXlDb250cmFjdAISc2VuZERlbGl2ZXJ5UmV3YXJkCQDMCAIFCHVzZXJBZGRyBQNuaWwFA25pbAMJAAACBQZyZXdhcmQFBnJld2FyZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDNCAIEC2xvY2tlZFRvdGFsCQELdmFsdWVPckVsc2UCCQCaCAIFD2Vjb25vbXlDb250cmFjdAURZGVsaXZlcnlMb2NrZWRLZXkAAAQGdW5sb2NrCQD8BwQFD2Vjb25vbXlDb250cmFjdAIUdXBkYXRlRGVsaXZlcnlMb2NrZWQJAMwIAgkAZQIFC2xvY2tlZFRvdGFsBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkFA25pbAUDbmlsAwkAAAIFBnVubG9jawUGdW5sb2NrAwkAZwIAAAkBEUBleHRyTmF0aXZlKDEwNTUpAQUJaGVhbHRoS2V5BQNuaWwECnB1bmlzaG1lbnQJAPwHBAUEdGhpcwILc2F2ZUludGVnZXIJAMwIAgkBFmtleURlbGl2ZXJ5RGVsYXlCeUR1Y2sBBQtkdWNrQXNzZXRJZAkAzAgCCQBkAgUJc3RhcnRUaW1lBRNERUxJVkVSWV9QVU5JU0hNRU5UBQNuaWwFA25pbAMJAAACBQpwdW5pc2htZW50BQpwdW5pc2htZW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAQtTdHJpbmdFbnRyeQIFBmxvY0tleQkBEUBleHRyTmF0aXZlKDEwNTgpAQkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUDbmlsAQZwcm9sb2cBAWkDAwkBAiE9AggFAWkMb3JpZ2luQ2FsbGVyBQxyZXN0Q29udHJhY3QJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBCmtleUJsb2NrZWQABwcJAAIBAh9Db250cmFjdHMgYXJlIHVuZGVyIG1haW50ZW5hbmNlBAh1c2VyQWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIJAM0IAgkBFWNoZWNrT3V0ZGF0ZWREZWxpdmVyeQEFCHVzZXJBZGRyCQELU3RyaW5nRW50cnkCCQERa2V5TGFzdFR4SWRCeVVzZXIBBQh1c2VyQWRkcgkA2AQBCAUBaQ10cmFuc2FjdGlvbklkAQxwcm9sb2dGbGlnaHQBAWkDAwkBAiE9AggFAWkMb3JpZ2luQ2FsbGVyBQxyZXN0Q29udHJhY3QJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBCmtleUJsb2NrZWQABwcJAAIBAh9Db250cmFjdHMgYXJlIHVuZGVyIG1haW50ZW5hbmNlCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlMYXN0VHhJZEJ5VXNlcgEJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQFA25pbCwBaQENY29uc3RydWN0b3JWMQEIcmVzdEFkZHIDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAkAzAgCCQELU3RyaW5nRW50cnkCCQEOa2V5UmVzdEFkZHJlc3MABQhyZXN0QWRkcgUDbmlsAWkBC3NhdmVJbnRlZ2VyAgNrZXkGYW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIgc2F2ZUludGVnZXIgaXMgbm90IHB1YmxpYyBtZXRob2QJAMwIAgkBDEludGVnZXJFbnRyeQIFA2tleQUGYW1vdW50BQNuaWwBaQEKc2V0QmxvY2tlZAEJaXNCbG9ja2VkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRcGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQprZXlCbG9ja2VkAAUJaXNCbG9ja2VkBQNuaWwBaQEJc3Rha2VMYW5kAAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQHYXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAQIhPQIIBQNwbXQGYW1vdW50AAEJAAIBCQCsAgIJAKwCAgIETkZUIAUKTEFORFBSRUZJWAIkIHRva2VuIHNob3VsZCBiZSBhdHRhY2hlZCBhcyBwYXltZW50BAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkAwkBAiE9AggFBWFzc2V0Bmlzc3VlcgUEdGhpcwkAAgECF1Vua25vd24gaXNzdWVyIG9mIHRva2VuAwkBASEBCQEIY29udGFpbnMCCAUFYXNzZXQEbmFtZQUKTEFORFBSRUZJWAkAAgEJAKwCAgkArAICAglPbmx5IE5GVCAFCkxBTkRQUkVGSVgCFCB0b2tlbnMgYXJlIGFjY2VwdGVkBAtsYW5kTnVtU2l6ZQkAsAICCAUFYXNzZXQEbmFtZQAEBAdsYW5kTnVtAwkBCGNvbnRhaW5zAgULbGFuZE51bVNpemUCA1hYTAkAswICBQtsYW5kTnVtU2l6ZQADAwkBCGNvbnRhaW5zAgULbGFuZE51bVNpemUCAlhMCQCzAgIFC2xhbmROdW1TaXplAAIJALMCAgULbGFuZE51bVNpemUAAQMJAQEhAQkBCWlzRGVmaW5lZAEJALYJAQUHbGFuZE51bQkAAgEJAKwCAgIeQ2Fubm90IHBhcnNlIGxhbmQgbnVtYmVyIGZyb20gCAUFYXNzZXQEbmFtZQQLbGFuZEFzc2V0SWQJANgEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAMJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCEiBpcyBhbHJlYWR5IHN0YWtlZAQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8EDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQQJbGFuZEluZGV4CQBpAgUGcGllY2VzBQVTU0laRQQFcHJvcHMJARF1cGRhdGVQcm9wb3J0aW9ucwMFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAABBAxyZXNCeUNvbnRLZXkJARZrZXlSZXNUeXBlc0J5Q29udGluZW50AQkAkQMCBQFkBQxyZWNDb250aW5lbnQECWNvbnRQcm9wcwkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFDHJlc0J5Q29udEtleQILMF8wXzBfMF8wXzACAV8EEHVwZGF0ZWRDb250UHJvcHMJALkJAgkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwEBQljb250UHJvcHMFDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAABAgFfBAhsYW5kc0tleQkBFWtleVN0YWtlZExhbmRzQnlPd25lcgEFB2FkZHJlc3MECGxhbmRzU3RyCQCiCAEFCGxhbmRzS2V5BAVsYW5kcwMJAQlpc0RlZmluZWQBBQhsYW5kc1N0cgkAvQkCCQEFdmFsdWUBBQhsYW5kc1N0cgIBXwUDbmlsAwkBD2NvbnRhaW5zRWxlbWVudAIFBWxhbmRzBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgIiWW91ciBzdGFrZWQgbGFuZHMgYWxyZWFkeSBjb250YWluIAULbGFuZEFzc2V0SWQDCQBnAgkAkAMBBQVsYW5kcwUYTUFYX0xBTkRTX1NUQUtFRF9CWV9VU0VSCQACAQkArAICCQCsAgICGVlvdXIgYWxyZWFkeSBzdGFrZWQgbWF4ICgJAKQDAQUYTUFYX0xBTkRTX1NUQUtFRF9CWV9VU0VSAgcpIGxhbmRzBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQJcGllY2VzS2V5CQEWa2V5U3Rha2VkUGllY2VzQnlPd25lcgEFB2FkZHJlc3MECW9sZFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlwaWVjZXNLZXkAAAQJd2xnUmVzdWx0CQD8BwQFC3dsZ0NvbnRyYWN0AhJvblN0YWtlVW5zdGFrZUxhbmQJAMwIAgUHYWRkcmVzcwUDbmlsBQNuaWwJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd0aW1lS2V5CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUHYWRkcmVzcwgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBC1N0cmluZ0VudHJ5AgUIbGFuZHNLZXkJALsJAgkAzQgCBQVsYW5kcwULbGFuZEFzc2V0SWQCAV8JAMwIAgkBDEludGVnZXJFbnRyeQIFCXBpZWNlc0tleQkAZAIFCW9sZFBpZWNlcwUGcGllY2VzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5TGFuZE51bVRvT3duZXIBBQdsYW5kTnVtBQdhZGRyZXNzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAgULbGFuZEFzc2V0SWQFB2FkZHJlc3MFCmluZnJhTGV2ZWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAUFcHJvcHMJAMwIAgkBC1N0cmluZ0VudHJ5AgUMcmVzQnlDb250S2V5BRB1cGRhdGVkQ29udFByb3BzBQNuaWwFDXByb2xvZ0FjdGlvbnMFCXdsZ1Jlc3VsdAFpAQt1bnN0YWtlTGFuZAENbGFuZEFzc2V0SWRJbgQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQZjYWxsZXIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFDWNsYWltTW9kZUR1Y2sFDWxhbmRBc3NldElkSW4EC2xhbmRBc3NldElkCAUBYwJfMgQBZAgFAWMCXzMECGxhbmRzS2V5CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUEYWRkcgQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIFAWQFC3JlY1RlcnJhaW5zBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIFAWQFC3JlY0xhbmRTaXplBAlsYW5kSW5kZXgJAGkCBQZwaWVjZXMFBVNTSVpFBAVwcm9wcwkBEXVwZGF0ZVByb3BvcnRpb25zAwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AP///////////wEEDHJlc0J5Q29udEtleQkBFmtleVJlc1R5cGVzQnlDb250aW5lbnQBCQCRAwIFAWQFDHJlY0NvbnRpbmVudAQJY29udFByb3BzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUMcmVzQnlDb250S2V5AgswXzBfMF8wXzBfMAIBXwQQdXBkYXRlZENvbnRQcm9wcwkAuQkCCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQFCWNvbnRQcm9wcwUNdGVycmFpbkNvdW50cwUJbGFuZEluZGV4AP///////////wECAV8EC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyBQtsYW5kQXNzZXRJZAUGcGllY2VzBQ1jbGFpbU1vZGVEdWNrBAVsYW5kcwkAvQkCCQELdmFsdWVPckVsc2UCCQCiCAEFCGxhbmRzS2V5AgACAV8EA2lkeAkAzwgCBQVsYW5kcwULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQNpZHgJAAIBCQCsAgICIFlvdXIgc3Rha2VkIGxhbmRzIGRvbid0IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQOZ292UmVsZWFzZVRpbWUJAQt2YWx1ZU9yRWxzZQIJAJoIAgULZ292Q29udHJhY3QJARVrZXlVc2VyR3dsUmVsZWFzZVRpbWUBBQRhZGRyAAADCQBnAgUOZ292UmVsZWFzZVRpbWUFA25vdwkAAgEJAKwCAgI5WW91ciBnV0wgYXJlIHRha2luZyBwYXJ0IGluIHZvdGluZywgY2Fubm90IHVuc3Rha2UgdW50aWwgCQCkAwEFDmdvdlJlbGVhc2VUaW1lBA5hcmJSZWxlYXNlVGltZQkAZAIJAQt2YWx1ZU9yRWxzZQIJAJoIAgULd2xnQ29udHJhY3QJARRrZXlMYXN0QXJiVGltZUJ5VXNlcgEFBGFkZHIAAAUOYXJiaXRyYWdlRGVsYXkDCQBmAgUOYXJiUmVsZWFzZVRpbWUFA25vdwkAAgEJAKwCAgI/WW91ciBzdGFrZWQgbGFuZHMgdG9vayBwYXJ0IGluIGFyYml0cmFnZSwgY2Fubm90IHVuc3Rha2UgdW50aWwgCQCkAwEFDmFyYlJlbGVhc2VUaW1lBAlwaWVjZXNLZXkJARZrZXlTdGFrZWRQaWVjZXNCeU93bmVyAQUEYWRkcgQMc3Rha2VkUGllY2VzCQELdmFsdWVPckVsc2UCCQCfCAEFCXBpZWNlc0tleQAABAluZXdQaWVjZXMDCQBmAgUGcGllY2VzBQxzdGFrZWRQaWVjZXMAAAkAZQIFDHN0YWtlZFBpZWNlcwUGcGllY2VzBAl3bGdSZXN1bHQJAPwHBAULd2xnQ29udHJhY3QCEm9uU3Rha2VVbnN0YWtlTGFuZAkAzAgCBQRhZGRyBQNuaWwFA25pbAkAlAoCCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEJANkEAQULbGFuZEFzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQRhZGRyCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlSZXNQcm9wb3J0aW9ucwAFBXByb3BzCQDMCAIJAQtTdHJpbmdFbnRyeQIFDHJlc0J5Q29udEtleQUQdXBkYXRlZENvbnRQcm9wcwkAzAgCCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzIJALkJAggFC2NsYWltUmVzdWx0Al8zAgE6CQDMCAIDCQBmAgkAkAMBBQVsYW5kcwABCQELU3RyaW5nRW50cnkCBQhsYW5kc0tleQkAuwkCCQDRCAIFBWxhbmRzCQEFdmFsdWUBBQNpZHgCAV8JAQtEZWxldGVFbnRyeQEFCGxhbmRzS2V5CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlwaWVjZXNLZXkFCW5ld1BpZWNlcwUDbmlsBQ1wcm9sb2dBY3Rpb25zBQl3bGdSZXN1bHQBaQEJc3Rha2VEdWNrAAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQHYXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAQIhPQIIBQNwbXQGYW1vdW50AAEJAAIBCQCsAgIJAKwCAgIETkZUIAUKRFVDS1BSRUZJWAIkIHRva2VuIHNob3VsZCBiZSBhdHRhY2hlZCBhcyBwYXltZW50BAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkAwMJAQIhPQIIBQVhc3NldAZpc3N1ZXIFDWluY3ViYXRvckFkZHIJAQIhPQIIBQVhc3NldAZpc3N1ZXIFC2JyZWVkZXJBZGRyBwkAAgEJAKwCAgkArAICAhJVbmtub3duIGlzc3VlciBvZiAFCkRVQ0tQUkVGSVgCBiB0b2tlbgMJAQEhAQkBCGNvbnRhaW5zAggFBWFzc2V0BG5hbWUFCkRVQ0tQUkVGSVgJAAIBCQCsAgIJAKwCAgIJT25seSBORlQgBQpEVUNLUFJFRklYAhQgdG9rZW5zIGFyZSBhY2NlcHRlZAQKYXNzZXRJZFN0cgkA2AQBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFCmFzc2V0SWRTdHIDCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAhIgaXMgYWxyZWFkeSBzdGFrZWQDCQEJaXNEZWZpbmVkAQkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzCQACAQkArAICAh1Zb3UgYWxyZWFkeSBzdGFrZWQgb25lIGR1Y2s6IAgFBWFzc2V0BG5hbWUEBmxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFCmFzc2V0SWRTdHIECGxvY2F0aW9uCQCiCAEFBmxvY0tleQQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFCmFzc2V0SWRTdHIECGJhY2twYWNrCQCiCAEFBWJwS2V5BAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQUKYXNzZXRJZFN0cgQFbWF4SFAJAQltYXhIZWFsdGgBCQELdmFsdWVPckVsc2UCCQCfCAEJAQxrZXlEdWNrTGV2ZWwBBQphc3NldElkU3RyAAAECWN1ckhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgFBW1heEhQCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFB3RpbWVLZXkIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkRVQ0tQUkVGSVgJANgEAQUHYXNzZXRJZAUHYWRkcmVzcwgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleUR1Y2tJZFRvT3duZXIBBQphc3NldElkU3RyBQdhZGRyZXNzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MFCmFzc2V0SWRTdHIFA25pbAMJAQlpc0RlZmluZWQBBQhsb2NhdGlvbgUDbmlsCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUGbG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04FA25pbAMJAQlpc0RlZmluZWQBBQhiYWNrcGFjawUDbmlsCQDOCAIJAM0IAgkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQIaMDowXzBfMF8wXzBfMDowXzBfMF8wXzBfMDoFA25pbAkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUJY3VySGVhbHRoBQ1wcm9sb2dBY3Rpb25zAWkBC3Vuc3Rha2VEdWNrAQphc3NldElkU3RyBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAdhc3NldElkCQDZBAEFCmFzc2V0SWRTdHIEB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFCmFzc2V0SWRTdHIDCQEBIQEJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkAwkBASEBCQEJaXNEZWZpbmVkAQkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzCQACAQkArAICCQCsAgICCVRoZSBkdWNrIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARBrZXlEdWNrSWRUb093bmVyAQUKYXNzZXRJZFN0cgkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUHYWRkcmVzcwkAAgECF1N0YWtlZCBORlQgaXMgbm90IHlvdXJzAwkBD2NoZWNrVG91cm5hbWVudAEFCmFzc2V0SWRTdHIJAAIBAht1bnN0YWtlRHVja19jaGVja1RvdXJuYW1lbnQDCQENY2hlY2tEZWxpdmVyeQEFCmFzc2V0SWRTdHIJAAIBAhl1bnN0YWtlRHVja19jaGVja0RlbGl2ZXJ5BAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQUKYXNzZXRJZFN0cgQFbWF4SFAJAQltYXhIZWFsdGgBCQELdmFsdWVPckVsc2UCCQCfCAEJAQxrZXlEdWNrTGV2ZWwBBQphc3NldElkU3RyAAAEBmhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgFBW1heEhQAwkAZgIFBW1heEhQBQZoZWFsdGgJAAIBCQCsAgIJAKwCAgIZUGxlYXNlIGhlYWwgeW91ciBkdWNrIHRvIAkApAMBBQVtYXhIUAITaHAgYmVmb3JlIHVuc3Rha2luZwkAzggCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgABBQdhc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEFB3RpbWVLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUJa2V5SGVhbHRoCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ9rZXlEdWNrTG9jYXRpb24BBQphc3NldElkU3RyCQDMCAIJAQtEZWxldGVFbnRyeQEJARBrZXlEdWNrSWRUb093bmVyAQUKYXNzZXRJZFN0cgkAzAgCCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkRVQ0tQUkVGSVgFCmFzc2V0SWRTdHIFB2FkZHJlc3MJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwUDbmlsBQ1wcm9sb2dBY3Rpb25zAWkBCGNsYWltUmVzAgZhbW91bnQObGFuZEFzc2V0SWRTdHIEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAZyZXN1bHQJARBjbGFpbVJlc0ludGVybmFsBAUEYWRkcgUGYW1vdW50BQ1jbGFpbU1vZGVEdWNrBQ5sYW5kQXNzZXRJZFN0cgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkCQCUCgIJAM4IAgkAzQgCCQDNCAIJAM4IAggFBnJlc3VsdAJfMQgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkCQBrAwUHeHBDbGFpbQUGYW1vdW50BQVNVUxUOAJfMQkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfMgkAuQkCCAUGcmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAUGcmVzdWx0Al80CQC5CQIIBQZyZXN1bHQCXzUCAToFDXByb2xvZ0FjdGlvbnMJAJEDAggFBnJlc3VsdAJfMwUIYnBJZHhSZXMBaQEMY2xhaW1SZXNUb1dIAgZhbW91bnQObGFuZEFzc2V0SWRTdHIEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAZyZXN1bHQJARBjbGFpbVJlc0ludGVybmFsBAUEYWRkcgUGYW1vdW50BQtjbGFpbU1vZGVXaAUObGFuZEFzc2V0SWRTdHIJAJQKAgkAzggCCQDNCAIJAM0IAgkAzggCCAUGcmVzdWx0Al8xCAkBFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwCBQRhZGRyCQBrAwUHeHBDbGFpbQUGYW1vdW50BQVNVUxUOAJfMQkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfMgkAuQkCCAUGcmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAUGcmVzdWx0Al80CQC5CQIIBQZyZXN1bHQCXzUCAToFDXByb2xvZ0FjdGlvbnMJAJEDAggFBnJlc3VsdAJfNQUId2hJZHhSZXMBaQEGZmxpZ2h0AgdtZXNzYWdlA3NpZwQNcHJvbG9nQWN0aW9ucwkBDHByb2xvZ0ZsaWdodAEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQIdXNlckFkZHIJAKUIAQgFAWkGY2FsbGVyBAFmCQEMZmxpZ2h0Q29tbW9uAwUIdXNlckFkZHIFB21lc3NhZ2UFA3NpZwQFbmV3SFAIBQFmAl8xBAtkdWNrQXNzZXRJZAgFAWYCXzIEBmxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBBQZsb2NLZXkFD0RFRkFVTFRMT0NBVElPTgQLbmV3TG9jYXRpb24IBQFmAl80AwkAAAIFC25ld0xvY2F0aW9uBQtjdXJMb2NhdGlvbgkAAgECIllvdSBjYW4ndCBmbHkgdG8gdGhlIHNhbWUgbG9jYXRpb24EBm5ld0xvYwkAtQkCBQtuZXdMb2NhdGlvbgIBXwQGaXNUb3VyCQAAAgkAkQMCBQZuZXdMb2MFCmxvY0lkeFR5cGUCAVQEB2lzRGVsaXYJAAACCQCRAwIFBm5ld0xvYwUKbG9jSWR4VHlwZQIBRAQFZXFLZXkJARBrZXlEdWNrRXF1aXBtZW50AQULZHVja0Fzc2V0SWQECWN1cnJlbnRFcQkBC3ZhbHVlT3JFbHNlAgkAoggBBQVlcUtleQIXLDssXyw7LF8sOyxfLDssXyw7LF8sOywEDSR0MDcwMDg3NzAxODQJARFzdWJ0cmFjdEVxdWlwbWVudAIFCWN1cnJlbnRFcQgFAWYCXzUEBW5ld0VxCAUNJHQwNzAwODc3MDE4NAJfMQQPc2hvdWxkWmVyb0J1ZmZzCAUNJHQwNzAwODc3MDE4NAJfMgQNJHQwNzAxODc3MzI5OQMJAQEhAQkBCW9uTWlzc2lvbgIFEnRvdXJuYW1lbnRDb250cmFjdAULY3VyTG9jYXRpb24DCQEBIQEJAQ9pc1VzdWFsTG9jYXRpb24BBQtuZXdMb2NhdGlvbgkBDGNoZWF0QXR0ZW1wdAMFC2N1ckxvY2F0aW9uBQtuZXdMb2NhdGlvbgAFAwkAZgIFBW5ld0hQAAAJAJQKAgULbmV3TG9jYXRpb24FBW5ld0hQCQCUCgIFC2N1ckxvY2F0aW9uAAADCQEOaXNJblRvdXJuYW1lbnQCBRJ0b3VybmFtZW50Q29udHJhY3QFC2N1ckxvY2F0aW9uAwkBASEBCQEOaXNJblRvdXJuYW1lbnQCBRJ0b3VybmFtZW50Q29udHJhY3QFC25ld0xvY2F0aW9uCQACAQIqWW91ciBkdWNrIGlzIHRha2luZyBwYXJ0IGluIHRoZSB0b3VybmFtZW50BAVzY29yZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBm5ld0xvYwUIbG9jSWR4SWQEBmN1ckxvYwkAtQkCBQtjdXJMb2NhdGlvbgIBXwQGbGFzdElkCQELdmFsdWVPckVsc2UCCQCaCAIFEnRvdXJuYW1lbnRDb250cmFjdAUNbGFzdFRvdXJJZEtleQAAAwkBAiE9AgUFc2NvcmUJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGY3VyTG9jBQhsb2NJZHhJZAABCQEMY2hlYXRBdHRlbXB0AwULY3VyTG9jYXRpb24FC25ld0xvY2F0aW9uAAcDCQBmAgUFbmV3SFAAAAQJbG9jYWxCZXN0CQELdmFsdWVPckVsc2UCCQCaCAIFEnRvdXJuYW1lbnRDb250cmFjdAkBGmtleUJlc3RSZXN1bHRCeVRvdXJBbmREdWNrAgUGbGFzdElkBQtkdWNrQXNzZXRJZAAABAh1cGRMb2NhbAMJAGYCBQVzY29yZQUJbG9jYWxCZXN0CQD8BwQFEnRvdXJuYW1lbnRDb250cmFjdAIOc2F2ZUR1Y2tSZXN1bHQJAMwIAgULZHVja0Fzc2V0SWQJAMwIAgUFc2NvcmUFA25pbAUDbmlsBQR1bml0AwkAAAIFCHVwZExvY2FsBQh1cGRMb2NhbAkAlAoCBQtuZXdMb2NhdGlvbgUFbmV3SFAJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAJQKAgULY3VyTG9jYXRpb24AAAMJAQEhAQkBDGlzSW5EZWxpdmVyeQEFC2N1ckxvY2F0aW9uBAhzYXZlZExvYwkBCGFzU3RyaW5nAQkA/AcEBQR0aGlzAhBhdXRvRXhpdERlbGl2ZXJ5CQDMCAIFC2R1Y2tBc3NldElkCQDMCAIFBW5ld0hQCQDMCAIDBQdpc0RlbGl2AgIxMAICMTEJAMwIAgAABQNuaWwFA25pbAMJAAACBQhzYXZlZExvYwUIc2F2ZWRMb2MDBQdpc0RlbGl2CQCUCgIFCHNhdmVkTG9jBQVuZXdIUAMJAGYCBQVuZXdIUAAACQCUCgIFC25ld0xvY2F0aW9uBQVuZXdIUAkAlAoCBQhzYXZlZExvYwAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkBASEBBQdpc0RlbGl2CQACAQIkWW91ciBkdWNrIGlzIHRha2luZyBwYXJ0IGluIGRlbGl2ZXJ5AwkBASEBCQEMaXNJbkRlbGl2ZXJ5AQULbmV3TG9jYXRpb24JAQxjaGVhdEF0dGVtcHQDBQtjdXJMb2NhdGlvbgULbmV3TG9jYXRpb24ADQQFc2NvcmUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZuZXdMb2MFCGxvY0lkeElkBAZjdXJMb2MJALUJAgULY3VyTG9jYXRpb24CAV8DCQECIT0CBQVzY29yZQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZjdXJMb2MFCGxvY0lkeElkAAEJAQxjaGVhdEF0dGVtcHQDBQtjdXJMb2NhdGlvbgULbmV3TG9jYXRpb24ADgMDCQBmAgUFbmV3SFAAAAkAZgIAAQUFc2NvcmUHCQCUCgIFC25ld0xvY2F0aW9uBQVuZXdIUAQIc2F2ZWRMb2MJAQhhc1N0cmluZwEJAPwHBAUEdGhpcwIQYXV0b0V4aXREZWxpdmVyeQkAzAgCBQtkdWNrQXNzZXRJZAkAzAgCBQVuZXdIUAkAzAgCAgUxNS0xNwkAzAgCBQVzY29yZQUDbmlsBQNuaWwDCQAAAgUIc2F2ZWRMb2MFCHNhdmVkTG9jCQCUCgIFCHNhdmVkTG9jBQVuZXdIUAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQJbG9jVG9TYXZlCAUNJHQwNzAxODc3MzI5OQJfMQQIaHBUb1NhdmUIBQ0kdDA3MDE4NzczMjk5Al8yCQCUCgIJAM4IAgkAzggCCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUGbG9jS2V5BQlsb2NUb1NhdmUJAMwIAgkBC1N0cmluZ0VudHJ5AgUFZXFLZXkFBW5ld0VxCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBQhocFRvU2F2ZQUDbmlsBQ1wcm9sb2dBY3Rpb25zAwUPc2hvdWxkWmVyb0J1ZmZzCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxrZXlEdWNrQnVmZnMBBQtkdWNrQXNzZXRJZAIJMF8wXzBfMF8wBQNuaWwFA25pbAgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkAwkAZgIFBW5ld0hQAAAFD3hwU3VjY2Vzc0ZsaWdodAUMeHBGYWlsRmxpZ2h0Al8xCAUBZgJfMwFpAQRoZWFsAwpxdWFudGl0eUwxCnF1YW50aXR5TDIKcXVhbnRpdHlMMwQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDAwMJAGYCAAAFCnF1YW50aXR5TDEGCQBmAgAABQpxdWFudGl0eUwyBgkAZgIAAAUKcXVhbnRpdHlMMwkAAgECG1F1YW50aXR5IGNhbm5vdCBiZSBuZWdhdGl2ZQQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAMJAQ9jaGVja1RvdXJuYW1lbnQBBQtkdWNrQXNzZXRJZAkAAgECFGhlYWxfY2hlY2tUb3VybmFtZW50AwkBDWNoZWNrRGVsaXZlcnkBBQtkdWNrQXNzZXRJZAkAAgECEmhlYWxfY2hlY2tEZWxpdmVyeQQDcXRzCQDMCAIFCnF1YW50aXR5TDEJAMwIAgUKcXVhbnRpdHlMMgkAzAgCBQpxdWFudGl0eUwzBQNuaWwECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQFbWF4SFAJAQltYXhIZWFsdGgBCQELdmFsdWVPckVsc2UCCQCfCAEJAQxrZXlEdWNrTGV2ZWwBBQtkdWNrQXNzZXRJZAAABAlvbGRIZWFsdGgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoBQVtYXhIUAMJAGcCBQlvbGRIZWFsdGgFBW1heEhQCQACAQkArAICCQCsAgICD0hQIHNob3VsZCBiZSA8IAkApAMBBQVtYXhIUAIIIHRvIGhlYWwEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAhwcm9kTGlzdAMJAAACCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAAUDbmlsCQC8CQIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIBXwoBC2l0ZXJhdGVQcm9kAgNhY2MGcmVjaXBlBAFuCAUDYWNjAl8yBAF4AwkAZgIJAJADAQUIcHJvZExpc3QFAW4JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhwcm9kTGlzdAUBbgAAAwkAZgIAAwUBbgQBcQkAkQMCBQNxdHMFAW4DCQBmAgUBcQUBeAkAAgEJAKwCAgkArAICCQCsAgICDllvdSBoYXZlIG9ubHkgCQCkAwEFAXgCBCBvZiAJAJEDAgUJcHJvZFR5cGVzBQFuCQCVCgMJAM0IAggFA2FjYwJfMQkApAMBCQBlAgUBeAUBcQkAZAIFAW4AAQkAZAIIBQNhY2MCXzMJAGgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCBQZyZWNpcGUCAV8FCnJJZHhFZmZlY3QFAXEJAJUKAwkAzQgCCAUDYWNjAl8xCQCkAwEFAXgJAGQCBQFuAAEIBQNhY2MCXzMEBnJlc3VsdAoAAiRsBRBwcm9kdWN0aW9uTWF0cml4CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlQoDBQNuaWwAAAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQtpdGVyYXRlUHJvZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyBAluZXdIZWFsdGgJAJcDAQkAzAgCBQVtYXhIUAkAzAgCCQBkAgUJb2xkSGVhbHRoCAUGcmVzdWx0Al8zBQNuaWwJAJQKAgkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUJbmV3SGVhbHRoCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC6CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAkAzAgCCQC5CQIIBQZyZXN1bHQCXzECAV8FA25pbAIBOgUDbmlsBQ1wcm9sb2dBY3Rpb25zCAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQJAGgCBQZ4cEhlYWwJAGQCCQBkAgUKcXVhbnRpdHlMMQUKcXVhbnRpdHlMMgUKcXVhbnRpdHlMMwJfMQUJbmV3SGVhbHRoAWkBBmhlYWxFUwAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQIaQWxsb3dlZCBVU0RUIHBheW1lbnQgb25seSEEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQDCQEPY2hlY2tUb3VybmFtZW50AQULZHVja0Fzc2V0SWQJAAIBAhZoZWFsRVNfY2hlY2tUb3VybmFtZW50AwkBDWNoZWNrRGVsaXZlcnkBBQtkdWNrQXNzZXRJZAkAAgECFGhlYWxFU19jaGVja0RlbGl2ZXJ5BAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEBW1heEhQCQEJbWF4SGVhbHRoAQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEMa2V5RHVja0xldmVsAQULZHVja0Fzc2V0SWQAAAQJb2xkSGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFADCQBmAgUJb2xkSGVhbHRoAAAJAAIBAihIUCBzaG91bGQgYmUgMCB0byBjYWxsIEVtZXJnZW5jeSBTZXJ2aWNlBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQIcHJvZExpc3QDCQAAAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgAFA25pbAkAvAkCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QCAV8EDW1lZEtpdEFtb3VudDEDCQBmAgkAkAMBBQhwcm9kTGlzdAAACQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvZExpc3QAAAAABA1tZWRLaXRBbW91bnQyAwkAZgIJAJADAQUIcHJvZExpc3QAAQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHByb2RMaXN0AAEAAAQNbWVkS2l0QW1vdW50MwMJAGYCCQCQAwEFCHByb2RMaXN0AAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhwcm9kTGlzdAACAAADAwMJAGYCBQ1tZWRLaXRBbW91bnQxAAAGCQBmAgUNbWVkS2l0QW1vdW50MgAABgkAZgIFDW1lZEtpdEFtb3VudDMAAAkAAgECH1lvdSBoYXZlIHRvIHVzZSBvd24gTWVkaWNhbCBLaXQECGV4aXN0U3RyCQCdCAIFD2Vjb25vbXlDb250cmFjdAkBDmtleUVzV2FyZWhvdXNlAAQMZXhpc3RBbW91bnRzAwkBCWlzRGVmaW5lZAEFCGV4aXN0U3RyCQC8CQIJAQV2YWx1ZQEFCGV4aXN0U3RyAgFfBQNuaWwEC2V4aXN0QW1vdW50AwkAZgIJAJADAQUMZXhpc3RBbW91bnRzAAAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQxleGlzdEFtb3VudHMAAAAAAwkAZwIAAAULZXhpc3RBbW91bnQJAAIBAjlUaGVyZSBhcmUgbm8gTWVkaWNhbCBLaXRzIEwxIGF0IEVtZXJnZW5jeSBTZXJ2aWNlIHN0b3JhZ2UECW5ld0hlYWx0aAkAZAIFCW9sZEhlYWx0aAkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgkAkQMCBRBwcm9kdWN0aW9uTWF0cml4AAACAV8FCnJJZHhFZmZlY3QEBW5ld0VTCQC5CQIJAMwIAgkApAMBCQBlAgULZXhpc3RBbW91bnQAAQkA0QgCBQxleGlzdEFtb3VudHMAAAIBXwQGcmVjaXBlCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAAAAgFfBAh0b3RhbE1hdAkBEmdldFJlY2lwZU1hdGVyaWFscwEFBnJlY2lwZQQJc2VsbFByaWNlCQBrAwkAaAIFCHRvdGFsTWF0BQpFU1NFTExDT0VGBRBSRVNPVVJDRVBSSUNFTUlOCQBoAgUFTVVMVDgFDlBST0RVQ1RQS0dTSVpFAwkBAiE9AggFA3BtdAZhbW91bnQFCXNlbGxQcmljZQkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFCXNlbGxQcmljZQQGcmVzdWx0CQEIYXNTdHJpbmcBCQD8BwQFD2Vjb25vbXlDb250cmFjdAIPdXBkYXRlRXNTdG9yYWdlCQDMCAIFBW5ld0VTBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFC3VzZHRBc3NldElkBQlzZWxsUHJpY2UFA25pbAkAlAoCCQDOCAIJAM0IAgUNcHJvbG9nQWN0aW9ucwkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUJbmV3SGVhbHRoCAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQFCHhwQ2FsbEVTAl8xBQZyZXN1bHQBaQEOdXBkYXRlQmFja3BhY2sCC2R1Y2tBc3NldElkB25ld1BhY2sDCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkAAgECEXBlcm1pc3Npb24gZGVuaWVkCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQFB25ld1BhY2sFA25pbAUHbmV3UGFjawFpAQ9jb21taXRGb3JSYW5kb20ABA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQQLZmluaXNoQmxvY2sJAGQCBQZoZWlnaHQFC3JhbmRvbURlbGF5BARhZGRyCQClCAEIBQFpBmNhbGxlcgkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQlrZXlDb21taXQBBQRhZGRyBQtmaW5pc2hCbG9jawUDbmlsBQ1wcm9sb2dBY3Rpb25zBQtmaW5pc2hCbG9jawFpAQhidXlTTGFuZAAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQIaQWxsb3dlZCBVU0RUIHBheW1lbnQgb25seSEDCQECIT0CCAUDcG10BmFtb3VudAUHRVhQVVNEVAkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFB0VYUFVTRFQEBnJlc3VsdAkBEmV4cGVkaXRpb25JbnRlcm5hbAIIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAQLYWNyZXNSZXN1bHQJAQVhc0ludAEJAPwHBAUNYWNyZXNDb250cmFjdAIJYnVybkFjcmVzCQDMCAIFDFNfQ09TVF9BQ1JFUwUDbmlsBQNuaWwJAJQKAgkAzggCCQDOCAIJAM0IAggFBnJlc3VsdAJfMQkBDlNjcmlwdFRyYW5zZmVyAwUPZWNvbm9teUNvbnRyYWN0CAUDcG10BmFtb3VudAULdXNkdEFzc2V0SWQICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIJAKUIAQgFAWkGY2FsbGVyBQp4cE5ld1NMYW5kAl8xBQ1wcm9sb2dBY3Rpb25zCQCUCgIICAUGcmVzdWx0Al8yAl8xBQthY3Jlc1Jlc3VsdAFpAQpleHBlZGl0aW9uAgdtZXNzYWdlA3NpZwQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQIdXNlckFkZHIJAKUIAQgFAWkGY2FsbGVyBAFmCQEMZmxpZ2h0Q29tbW9uAwUIdXNlckFkZHIFB21lc3NhZ2UFA3NpZwQLZHVja0Fzc2V0SWQIBQFmAl8yBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAVtTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQGbmV3TWF0CQC5CQIJARFzdWJ0cmFjdE1hdGVyaWFscwMGBQVtTGlzdAUMRVhQTUFURVJJQUxTAgFfBAVlcUtleQkBEGtleUR1Y2tFcXVpcG1lbnQBBQtkdWNrQXNzZXRJZAQJY3VycmVudEVxCQELdmFsdWVPckVsc2UCCQCiCAEFBWVxS2V5AhcsOyxfLDssXyw7LF8sOyxfLDssXyw7LAQNJHQwODA3Mzk4MDgzNgkBEXN1YnRyYWN0RXF1aXBtZW50AgUJY3VycmVudEVxCAUBZgJfNQQFbmV3RXEIBQ0kdDA4MDczOTgwODM2Al8xBA9zaG91bGRaZXJvQnVmZnMIBQ0kdDA4MDczOTgwODM2Al8yBAFlCQESZXhwZWRpdGlvbkludGVybmFsAggFAWkGY2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkBAJpZAgIBQFlAl8yAl8xBAZyZXN1bHQDCQBnAgAACAUBZgJfMQkAlQoDCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgAAAkAzAgCCQELU3RyaW5nRW50cnkCBQVlcUtleQUFbmV3RXEFA25pbAIAAAAJAJUKAwkAzggCCAUBZQJfMQMFD3Nob3VsZFplcm9CdWZmcwkAzAgCCQELU3RyaW5nRW50cnkCCQEMa2V5RHVja0J1ZmZzAQULZHVja0Fzc2V0SWQCCTBfMF8wXzBfMAUDbmlsCQDNCAIJAM0IAgkAzQgCCQDNCAIFA25pbAkBC1N0cmluZ0VudHJ5AgkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQC5CQIJAMwIAggIBQFlAl8yAl8yCQDMCAICAUwJAMwIAgUCaWQFA25pbAIBXwkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAgFAWYCXzEJAQtTdHJpbmdFbnRyeQIFBWVxS2V5BQVuZXdFcQkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgUCaWQIBQFmAl8zAwkBD2NoZWNrVG91cm5hbWVudAEFC2R1Y2tBc3NldElkCQACAQIaZXhwZWRpdGlvbl9jaGVja1RvdXJuYW1lbnQDCQENY2hlY2tEZWxpdmVyeQEFC2R1Y2tBc3NldElkCQACAQIYZXhwZWRpdGlvbl9jaGVja0RlbGl2ZXJ5BAthY3Jlc1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ1hY3Jlc0NvbnRyYWN0AglidXJuQWNyZXMJAMwIAgUMU19DT1NUX0FDUkVTBQNuaWwFA25pbAkAlAoCCQDOCAIJAM4IAggFBnJlc3VsdAJfMQgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkBQp4cE5ld1NMYW5kAl8xBQ1wcm9sb2dBY3Rpb25zCQCVCgMIBQZyZXN1bHQCXzIIBQZyZXN1bHQCXzMFC2FjcmVzUmVzdWx0AWkBEGJ1eVNMYW5kRm9yQWNyZXMABA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAUMYWNyZXNBc3NldElkCQACAQIUQUNSRVMgcGF5bWVudHMgb25seSEDCQECIT0CBQNhbXQFDFNfQ09TVF9BQ1JFUwkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFDFNfQ09TVF9BQ1JFUwQGcmVzdWx0CQESZXhwZWRpdGlvbkludGVybmFsAggFAWkGY2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkBAthY3Jlc1Jlc3VsdAkBBWFzSW50AQkA/AcEBQ1hY3Jlc0NvbnRyYWN0AglidXJuQWNyZXMJAMwIAgUMU19DT1NUX0FDUkVTBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFDGFjcmVzQXNzZXRJZAUDYW10BQNuaWwJAJQKAgkAzggCCQDOCAIIBQZyZXN1bHQCXzEICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIJAKUIAQgFAWkGY2FsbGVyBQp4cE5ld1NMYW5kAl8xBQ1wcm9sb2dBY3Rpb25zCQCUCgIICAUGcmVzdWx0Al8yAl8xBQthY3Jlc1Jlc3VsdAFpAQx1cGdyYWRlSW5mcmEBC2xhbmRBc3NldElkBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAZyZXN1bHQJAQ11cEluZnJhQ29tbW9uBAYIBQFpBmNhbGxlcgAABQtsYW5kQXNzZXRJZAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAkAlAoCCQDOCAIJAM4IAggFBnJlc3VsdAJfMQUNcHJvbG9nQWN0aW9ucwgJARd1cGRhdGVEdWNrU3RhdHNJbnRlcm5hbAIFC2R1Y2tBc3NldElkCQBrAwUOeHBVcGdyYWRlSW5mcmEIBQZyZXN1bHQCXzMFBU1VTFQ4Al8xCAUGcmVzdWx0Al8yAWkBEGFjdGl2YXRlQXJ0aWZhY3QCB2FydE5hbWUObGFuZEFzc2V0SWRPcHQEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBGFkZHIJAKUIAQgFAWkGY2FsbGVyBAZyZXN1bHQEByRtYXRjaDAFB2FydE5hbWUDCQAAAgIHUFJFU0FMRQUHJG1hdGNoMAkBEmFjdGl2YXRlUHJlc2FsZUFydAIFBGFkZHIFDmxhbmRBc3NldElkT3B0AwkAAAICB09OQk9BUkQFByRtYXRjaDAJARJhY3RpdmF0ZU9uYm9hcmRBcnQBBQRhZGRyCQACAQIQVW5rbm93biBhcnRpZmFjdAkAzggCBQZyZXN1bHQFDXByb2xvZ0FjdGlvbnMBaQEKbWVyZ2VMYW5kcwEMbGFuZEFzc2V0SWRzBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAZyZXN1bHQJAQttZXJnZUNvbW1vbgIJAKUIAQgFAWkGY2FsbGVyBQxsYW5kQXNzZXRJZHMJAJQKAgkAzggCCQDOCAIIBQZyZXN1bHQCXzEFDXByb2xvZ0FjdGlvbnMICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIJAKUIAQgFAWkGY2FsbGVyBQd4cE1lcmdlAl8xCAUGcmVzdWx0Al8yAWkBDWNhcmdvRXhjaGFuZ2UCDGNhcmdvTGlzdFN0cgtsYW5kQXNzZXRJZAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQKY2FyZ29QYXJ0cwkAvAkCBQxjYXJnb0xpc3RTdHICAToEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwULcmVjTGFuZFNpemUFBVNTSVpFBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMAwkBAiE9AgkAkQMCBQNsb2MFCGxvY0lkeElkBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgIbRHVjayBzaG91bGQgYmUgb24gdGhlIGxhbmQgBQtsYW5kQXNzZXRJZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQJY3VycmVudFdoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBnJlc3VsdAkBCW1vdmVTdHVmZgMFCmNhcmdvUGFydHMFCWN1cnJlbnRXaAULY3VycmVudFBhY2sEBGxvZnQJALUJAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4TE9GVAIBXwQFbG9mdE8JAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbG9mdAULdm9sT2NjdXBpZWQIBQZyZXN1bHQCXzcEBWxvZnRGCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGxvZnQFB3ZvbEZyZWUIBQZyZXN1bHQCXzcJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAugkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAggFBnJlc3VsdAJfNAkAzAgCCAUGcmVzdWx0Al81CQDMCAIIBQZyZXN1bHQCXzYFA25pbAIBOgkAzAgCCQELU3RyaW5nRW50cnkCBQV3aEtleQkAugkCCQDMCAIJAJEDAgUJY3VycmVudFdoBQt3aElkeExldmVscwkAzAgCCAUGcmVzdWx0Al8xCQDMCAIIBQZyZXN1bHQCXzIJAMwIAggFBnJlc3VsdAJfMwkAzAgCCQC5CQIJAMwIAgkAkQMCBQRsb2Z0BQl2b2xMb2NrZWQJAMwIAgkApAMBBQVsb2Z0TwkAzAgCCQCkAwEFBWxvZnRGCQDMCAIJAJEDAgUEbG9mdAUIdm9sVG90YWwFA25pbAIBXwUDbmlsAgE6BQNuaWwFDXByb2xvZ0FjdGlvbnMBaQENc2F2ZVdhcmVob3VzZQIFd2hTdHILbGFuZEFzc2V0SWQDCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEBXdoS2V5CQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQEAndoCQC8CQIFBXdoU3RyAgE6AwkBAiE9AgkAkAMBBQJ3aAAFCQACAQIwd2FyZWhvdXNlIHN0cmluZyBzaG91bGQgY29udGFpbiA0ICc6JyBzZXBhcmF0b3JzBAVsb2Z0TAkAkQMCCQC1CQIJAJEDAgUCd2gFCXdoSWR4TE9GVAIBXwUJdm9sTG9ja2VkBAVsb2Z0TwkBF2dldFdhcmVob3VzZU9jY3VwaWVkVm9sAQUCd2gEBWxvZnRUCQEXZ2V0V2FyZWhvdXNlVG90YWxWb2x1bWUBCQCRAwIFAndoBQt3aElkeExldmVscwQFbG9mdEYJAGUCCQBlAgUFbG9mdFQJAQ1wYXJzZUludFZhbHVlAQUFbG9mdEwFBWxvZnRPAwkAZgIAAAUFbG9mdEYJAAIBAjBPcGVyYXRpb24gbGVhZHMgdG8gbmVnYXRpdmUgZnJlZSB3YXJlaG91c2Ugc3BhY2UECG5ld1doU3RyCQC6CQIJAMwIAgkAkQMCBQJ3aAULd2hJZHhMZXZlbHMJAMwIAgkAkQMCBQJ3aAUId2hJZHhSZXMJAMwIAgkAkQMCBQJ3aAUId2hJZHhNYXQJAMwIAgkAkQMCBQJ3aAUJd2hJZHhQcm9kCQDMCAIJALkJAgkAzAgCBQVsb2Z0TAkAzAgCCQCkAwEFBWxvZnRPCQDMCAIJAKQDAQUFbG9mdEYJAMwIAgkApAMBBQVsb2Z0VAUDbmlsAgFfBQNuaWwCAToJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQV3aEtleQUIbmV3V2hTdHIFA25pbAUIbmV3V2hTdHIBaQENc2V0Q3VzdG9tTmFtZQMHYXNzZXRJZApjdXN0b21OYW1lBHR5cGUEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQIaQWxsb3dlZCBVU0RUIHBheW1lbnQgb25seSEDCQECIT0CCAUDcG10BmFtb3VudAUMUkVOQU1JTkdDT1NUCQACAQkArAICAhJQYXltZW50IHNob3VsZCBiZSAJAKQDAQUMUkVOQU1JTkdDT1NUAwkBCGNvbnRhaW5zAgUKY3VzdG9tTmFtZQICX18JAAIBCQCsAgICHk5hbWUgc2hvdWxkIG5vdCBjb250YWluICdfXyc6IAUKY3VzdG9tTmFtZQMJAGYCCQCxAgEFCmN1c3RvbU5hbWUFCk1BWE5BTUVMRU4JAAIBCQCsAgICGU5hbWUgdG9vIGxvbmcsIG1heExlbmd0aD0JAKQDAQUKTUFYTkFNRUxFTgQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEB2FjdGlvbnMEByRtYXRjaDAFBHR5cGUDCQAAAgIHQUNDT1VOVAUHJG1hdGNoMAQKcmV2ZXJzZUtleQkBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBBQpjdXN0b21OYW1lBAluYW1lT3duZXIJAKIIAQUKcmV2ZXJzZUtleQMJAQlpc0RlZmluZWQBBQluYW1lT3duZXIJAAIBCQCsAgICGU5hbWUgYWxyZWFkeSByZWdpc3RlcmVkOiAFCmN1c3RvbU5hbWUEDWFkZHJUb05hbWVLZXkJARZrZXlBZGRyZXNzVG9DdXN0b21OYW1lAQUEYWRkcgQHb2xkTmFtZQkAoggBBQ1hZGRyVG9OYW1lS2V5BAdmcmVlT2xkAwkBCWlzRGVmaW5lZAEFB29sZE5hbWUJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBCQEFdmFsdWUBBQdvbGROYW1lBQNuaWwFA25pbAkAzggCCQDNCAIJAM0IAgUHZnJlZU9sZAkBC1N0cmluZ0VudHJ5AgUNYWRkclRvTmFtZUtleQUKY3VzdG9tTmFtZQkBC1N0cmluZ0VudHJ5AgUKcmV2ZXJzZUtleQUEYWRkcggJARZ1cGRhdGVBY2NTdGF0c0ludGVybmFsAgUEYWRkcgUMeHBDdXN0b21OYW1lAl8xAwkAAAICBExBTkQFByRtYXRjaDAEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQdhc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFB2Fzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMECnJldmVyc2VLZXkJARprZXlMYW5kQ3VzdG9tTmFtZVRvQXNzZXRJZAEFCmN1c3RvbU5hbWUECW5hbWVPd25lcgkAoggBBQpyZXZlcnNlS2V5AwkBCWlzRGVmaW5lZAEFCW5hbWVPd25lcgkAAgEJAKwCAgIZTmFtZSBhbHJlYWR5IHJlZ2lzdGVyZWQ6IAUKY3VzdG9tTmFtZQQOYXNzZXRUb05hbWVLZXkJARprZXlMYW5kQXNzZXRJZFRvQ3VzdG9tTmFtZQEFB2Fzc2V0SWQEB29sZE5hbWUJAKIIAQUOYXNzZXRUb05hbWVLZXkEB2ZyZWVPbGQDCQEJaXNEZWZpbmVkAQUHb2xkTmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBCQEFdmFsdWUBBQdvbGROYW1lBQNuaWwFA25pbAkAzggCCQDNCAIJAM0IAgUHZnJlZU9sZAkBC1N0cmluZ0VudHJ5AgUOYXNzZXRUb05hbWVLZXkFCmN1c3RvbU5hbWUJAQtTdHJpbmdFbnRyeQIFCnJldmVyc2VLZXkFB2Fzc2V0SWQICQEWdXBkYXRlQWNjU3RhdHNJbnRlcm5hbAIFBGFkZHIFDHhwQ3VzdG9tTmFtZQJfMQMJAAACAgREVUNLBQckbWF0Y2gwBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQUHYXNzZXRJZAMDCQEBIQEJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkGCQEBIQEJAQlpc0RlZmluZWQBCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHIJAAIBCQCsAgIIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEQa2V5RHVja0lkVG9Pd25lcgEFB2Fzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkRVQ0tQUkVGSVgCDSBpcyBub3QgeW91cnMECnJldmVyc2VLZXkJARprZXlEdWNrQ3VzdG9tTmFtZVRvQXNzZXRJZAEFCmN1c3RvbU5hbWUECW5hbWVPd25lcgkAoggBBQpyZXZlcnNlS2V5AwkBCWlzRGVmaW5lZAEFCW5hbWVPd25lcgkAAgEJAKwCAgIZTmFtZSBhbHJlYWR5IHJlZ2lzdGVyZWQ6IAUKY3VzdG9tTmFtZQQOYXNzZXRUb05hbWVLZXkJARprZXlEdWNrQXNzZXRJZFRvQ3VzdG9tTmFtZQEFB2Fzc2V0SWQEB29sZE5hbWUJAKIIAQUOYXNzZXRUb05hbWVLZXkEB2ZyZWVPbGQDCQEJaXNEZWZpbmVkAQUHb2xkTmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBCQEFdmFsdWUBBQdvbGROYW1lBQNuaWwFA25pbAkAzggCCQDNCAIJAM0IAgUHZnJlZU9sZAkBC1N0cmluZ0VudHJ5AgUOYXNzZXRUb05hbWVLZXkFCmN1c3RvbU5hbWUJAQtTdHJpbmdFbnRyeQIFCnJldmVyc2VLZXkFB2Fzc2V0SWQICQEXdXBkYXRlRHVja1N0YXRzSW50ZXJuYWwCBQdhc3NldElkBQx4cEN1c3RvbU5hbWUCXzEJAAIBAhNVbmtub3duIGVudGl0eSB0eXBlCQCUCgIJAM4IAgkAzQgCBQdhY3Rpb25zCQEOU2NyaXB0VHJhbnNmZXIDBQ9lY29ub215Q29udHJhY3QIBQNwbXQGYW1vdW50BQt1c2R0QXNzZXRJZAUNcHJvbG9nQWN0aW9ucwAAAWkBDHNldFJlZmVycmFscwIJb2xkUGxheWVyCW5ld1BsYXllcgMJAQIhPQIIBQFpD2NhbGxlclB1YmxpY0tleQUDcHViCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQDCQEBIQEJAQlpc0RlZmluZWQBCQCmCAEFCW9sZFBsYXllcgkAAgEJAKwCAgIRSW52YWxpZCBhZGRyZXNzOiAFCW9sZFBsYXllcgMJAQEhAQkBCWlzRGVmaW5lZAEJAKYIAQUJbmV3UGxheWVyCQACAQkArAICAhFJbnZhbGlkIGFkZHJlc3M6IAUJbmV3UGxheWVyBAdvbGRzS2V5CQEJa2V5T2xkaWVzAAQEb2xkcwkAoggBBQdvbGRzS2V5BAZvbGRpZXMDCQEJaXNEZWZpbmVkAQUEb2xkcwkAvAkCCQEFdmFsdWUBBQRvbGRzAgFfBQNuaWwDCQEPY29udGFpbnNFbGVtZW50AgUGb2xkaWVzBQluZXdQbGF5ZXIJAAIBCQCsAgIFCW5ld1BsYXllcgImIGlzIG5vdCBuZXdiaWUgKGFscmVhZHkgaGFzIHJlZmVycmFscykECHJlZkJ5S2V5CQEPa2V5QWRkcmVzc1JlZkJ5AQUJbmV3UGxheWVyBAVyZWZCeQkAoggBBQhyZWZCeUtleQMDCQEJaXNEZWZpbmVkAQUFcmVmQnkJAQlpc0RlZmluZWQBCQCmCAEJAQV2YWx1ZQEFBXJlZkJ5BwkAAgEJAKwCAgkArAICBQluZXdQbGF5ZXICFCBhbHJlYWR5IGhhcyByZWZCeTogCQEFdmFsdWUBBQVyZWZCeQQHcmVmc0tleQkBE2tleUFkZHJlc3NSZWZlcnJhbHMBBQlvbGRQbGF5ZXIEBHJlZnMJAKIIAQUHcmVmc0tleQQJcmVmc0FycmF5AwkBCWlzRGVmaW5lZAEFBHJlZnMJALwJAgkBBXZhbHVlAQUEcmVmcwIBXwUDbmlsAwkBD2NvbnRhaW5zRWxlbWVudAIFCXJlZnNBcnJheQUJbmV3UGxheWVyCQACAQkArAICCQCsAgIJAKwCAgUJb2xkUGxheWVyAhIgYWxyZWFkeSBjb250YWlucyAFCW5ld1BsYXllcgIRIHdpdGhpbiByZWZlcnJhbHMEB25ld1JlZnMJALoJAgkAzQgCBQlyZWZzQXJyYXkFCW5ld1BsYXllcgIBXwQHbmV3T2xkcwMJAQ9jb250YWluc0VsZW1lbnQCBQZvbGRpZXMFCW9sZFBsYXllcgkBBXZhbHVlAQUEb2xkcwkAugkCCQDNCAIFBm9sZGllcwUJb2xkUGxheWVyAgFfCQCUCgIJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQhyZWZCeUtleQUJb2xkUGxheWVyCQDMCAIJAQtTdHJpbmdFbnRyeQIFB3JlZnNLZXkFB25ld1JlZnMJAMwIAgkBC1N0cmluZ0VudHJ5AgUHb2xkc0tleQUHbmV3T2xkcwUDbmlsBQ1wcm9sb2dBY3Rpb25zAAABaQEQZGlzdHJpYnV0ZVBvaW50cwUIc3RyZW5ndGgIYWNjdXJhY3kJaW50ZWxsZWN0CWVuZHVyYW5jZQlkZXh0ZXJpdHkEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAt2aXJ0V2xnRGF0YQkBCWFzQW55TGlzdAEJAPwHBAULd2xnQ29udHJhY3QCEmNoZWNrV2xnWHBSRUFET05MWQkAzAgCBQRhZGRyBQNuaWwFA25pbAQNdmlydFdsZ1BvaW50cwkBBWFzSW50AQkAkQMCBQt2aXJ0V2xnRGF0YQABBA0kdDA5NjQ1Njk2ODQ2AwkAZwIAAAUNdmlydFdsZ1BvaW50cwkAlAoCAAAFA25pbAQHZGVsdGFYUAkBBWFzSW50AQkA/AcEBQt3bGdDb250cmFjdAIJdGFrZVdsZ1hwCQDMCAIFBGFkZHIFA25pbAUDbmlsAwkAAAIFB2RlbHRhWFAFB2RlbHRhWFAJAJQKAgUNdmlydFdsZ1BvaW50cwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDGtleVVzZXJMZXZlbAEFBGFkZHIJAQVhc0ludAEJAJEDAgULdmlydFdsZ0RhdGEAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBCWtleVVzZXJYUAEFBGFkZHIJAQVhc0ludAEJAJEDAgULdmlydFdsZ0RhdGEAAgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAl3bGdQb2ludHMIBQ0kdDA5NjQ1Njk2ODQ2Al8xBAp3bGdBY3Rpb25zCAUNJHQwOTY0NTY5Njg0NgJfMgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBApmcmVlS2V5QWNjCQERa2V5VXNlckZyZWVQb2ludHMBBQRhZGRyBA1mcmVlUG9pbnRzQWNjCQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQpmcmVlS2V5QWNjAAAFCXdsZ1BvaW50cwQLZnJlZUtleUR1Y2sJARFrZXlEdWNrRnJlZVBvaW50cwEFC2R1Y2tBc3NldElkBA5mcmVlUG9pbnRzRHVjawkBC3ZhbHVlT3JFbHNlAgkAnwgBBQtmcmVlS2V5RHVjawAABAdzdW1GcmVlCQBkAgUNZnJlZVBvaW50c0FjYwUOZnJlZVBvaW50c0R1Y2sED3N1bVRvRGlzdHJpYnV0ZQkAZAIJAGQCCQBkAgkAZAIFCHN0cmVuZ3RoBQhhY2N1cmFjeQUJaW50ZWxsZWN0BQllbmR1cmFuY2UFCWRleHRlcml0eQMJAGYCBQ9zdW1Ub0Rpc3RyaWJ1dGUFB3N1bUZyZWUJAAIBCQCsAgIJAKwCAgIPVGhlcmUgYXJlIG9ubHkgCQCkAwEFB3N1bUZyZWUCGiBmcmVlIHBvaW50cyB0byBkaXN0cmlidXRlBAhjaGFyc0tleQkBDGtleUR1Y2tDaGFycwEFC2R1Y2tBc3NldElkBAVjaGFycwkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEFCGNoYXJzS2V5AgkwXzBfMF8wXzACAV8EBm5ld0FjYwkAZQIFDWZyZWVQb2ludHNBY2MFD3N1bVRvRGlzdHJpYnV0ZQkAlAoCCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUKZnJlZUtleUFjYwMJAGYCAAAFBm5ld0FjYwAABQZuZXdBY2MJAMwIAgkBDEludGVnZXJFbnRyeQIFC2ZyZWVLZXlEdWNrAwkAZgIAAAUGbmV3QWNjCQBkAgUOZnJlZVBvaW50c0R1Y2sFBm5ld0FjYwUOZnJlZVBvaW50c0R1Y2sJAMwIAgkBC1N0cmluZ0VudHJ5AgUIY2hhcnNLZXkJALkJAgkAzAgCCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFY2hhcnMFDGNoYXJTdHJlbmd0aAUIc3RyZW5ndGgJAMwIAgkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWNoYXJzBQxjaGFyQWNjdXJhY3kFCGFjY3VyYWN5CQDMCAIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUNY2hhckludGVsbGVjdAUJaW50ZWxsZWN0CQDMCAIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUNY2hhckVuZHVyYW5jZQUJZW5kdXJhbmNlCQDMCAIJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVjaGFycwUNY2hhckRleHRlcml0eQUJZGV4dGVyaXR5BQNuaWwCAV8FA25pbAUNcHJvbG9nQWN0aW9ucwUKd2xnQWN0aW9ucwAAAWkBHHNwbGl0QnlHbG9iYWxXZWlnaHRzUkVBRE9OTFkBBmFtb3VudAkAlAoCBQNuaWwJARJnZXROZWVkZWRNYXRlcmlhbHMBBQZhbW91bnQBaQEkc3BsaXRCeUdsb2JhbEFuZExvY2FsV2VpZ2h0c1JFQURPTkxZAwltYXRBbW91bnQJcmVzQW1vdW50CHRlcnJhaW5zBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEFCHRlcnJhaW5zCQCUCgIFA25pbAkAlAoCCQESZ2V0TmVlZGVkTWF0ZXJpYWxzAQUJbWF0QW1vdW50CQETZGlzdHJpYnV0ZUJ5V2VpZ2h0cwIFCXJlc0Ftb3VudAUNdGVycmFpbkNvdW50cwFpARNnZXRCYWNrcGFja1JFQURPTkxZAQtkdWNrQXNzZXRJZAkAlAoCBQNuaWwJALkJAgkBC2dldEJhY2twYWNrAQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQCAToBaQEUZ2V0V2FyZWhvdXNlUkVBRE9OTFkBC2xhbmRBc3NldElkBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwULcmVjTGFuZFNpemUFBVNTSVpFBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAkAlAoCBQNuaWwJALoJAgkBDGdldFdhcmVob3VzZQMJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAUJbGFuZEluZGV4BQppbmZyYUxldmVsAgE6AWkBCnNhdmVMYXN0VHgAAwkBASEBCQEPY29udGFpbnNFbGVtZW50AgkAzAgCBQt3bGdDb250cmFjdAkAzAgCBQ9lY29ub215Q29udHJhY3QJAMwIAgUSdG91cm5hbWVudENvbnRyYWN0CQDMCAIFDWFjcmVzQ29udHJhY3QFA25pbAgFAWkGY2FsbGVyCQACAQINQWNjZXNzIGRlbmllZAkAlAoCCQEGcHJvbG9nAQUBaQAqAWkBD3VwZGF0ZUR1Y2tTdGF0cwILZHVja0Fzc2V0SWQHZGVsdGFYUAMJAQIhPQIIBQFpBmNhbGxlcgUPZWNvbm9teUNvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAkBF3VwZGF0ZUR1Y2tTdGF0c0ludGVybmFsAgULZHVja0Fzc2V0SWQFB2RlbHRhWFABaQEOdXBkYXRlQWNjU3RhdHMCBGFkZHIHZGVsdGFYUAMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIJAMwIAgULd2xnQ29udHJhY3QJAMwIAgUPZWNvbm9teUNvbnRyYWN0CQDMCAIFDWFjcmVzQ29udHJhY3QFA25pbAgFAWkGY2FsbGVyCQACAQINQWNjZXNzIGRlbmllZAkBFnVwZGF0ZUFjY1N0YXRzSW50ZXJuYWwCBQRhZGRyBQdkZWx0YVhQAWkBCWVxdWlwRHVjawEJZXF1aXBtZW50BA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkAwkBD2NoZWNrVG91cm5hbWVudAEFC2R1Y2tBc3NldElkCQACAQIZZXF1aXBEdWNrX2NoZWNrVG91cm5hbWVudAMJAQ1jaGVja0RlbGl2ZXJ5AQULZHVja0Fzc2V0SWQJAAIBAhdlcXVpcER1Y2tfY2hlY2tEZWxpdmVyeQQFZXFLZXkJARBrZXlEdWNrRXF1aXBtZW50AQULZHVja0Fzc2V0SWQEC2N1cnJlbnRTZWdzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUFZXFLZXkCFyw7LF8sOyxfLDssXyw7LF8sOyxfLDssAgFfBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQFbmV3RXEJALUJAgUJZXF1aXBtZW50AgFfAwkBAiE9AgkAkAMBBQVuZXdFcQULTlVNU0VHTUVOVFMJAAIBAhZXcm9uZyBlcXVpcG1lbnQgc3RyaW5nBAl0ZW1wUHJvZEIJAQZkcmVzc0IEBQtjdXJyZW50U2VncwkBDnByb2RTdHJUb0J5dGVzAQkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBgUDbmlsBAhzZWdCcEF1eAkAkQMCCQC1CQIJAJEDAgUFbmV3RXEFC3NlZ0JhY2twYWNrAgE7AAEECmJ1ZmZFZmZlY3QDCQAAAgUIc2VnQnBBdXgCAAAABARhdXgwCQCRAwIJALUJAgUIc2VnQnBBdXgCASwAAAMJAAACBQRhdXgwAgAAAAQGaWR4Q250CQC1CQIFBGF1eDACAToEA2lkeAkAkQMCBQZpZHhDbnQAAAQDY250CQCRAwIFBmlkeENudAABAwMDAwMJAAACBQNpZHgCAjA2BgkAAAIFA2lkeAICMDcGCQAAAgUDaWR4AgIwOAkBAiE9AgUDY250AgAHCQBmAgkBDXBhcnNlSW50VmFsdWUBBQNjbnQAAAcJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgUQcHJvZHVjdGlvbk1hdHJpeAkBDXBhcnNlSW50VmFsdWUBBQNpZHgCAV8FCnJJZHhFZmZlY3QAAAQFc3RhdHMJAQxnZXREdWNrU3RhdHMEBQR0aGlzBQtkdWNrQXNzZXRJZAUKYnVmZkVmZmVjdAYECG5ld1Byb2RCCQEGZHJlc3NCBAUFbmV3RXEFCXRlbXBQcm9kQgcFBXN0YXRzBApuZXdQcm9kU3RyCQEOYnl0ZXNUb1Byb2RTdHIBBQhuZXdQcm9kQgkAlAoCCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFZXFLZXkFCWVxdWlwbWVudAkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAugkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQJAMwIAgUKbmV3UHJvZFN0cgUDbmlsAgE6CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxrZXlEdWNrQnVmZnMBBQtkdWNrQXNzZXRJZAkAuQkCCQDMCAIJAKQDAQkAkQMCBQVzdGF0cwAHCQDMCAIJAKQDAQkAkQMCBQVzdGF0cwAICQDMCAIJAKQDAQkAkQMCBQVzdGF0cwAJCQDMCAIJAKQDAQkAkQMCBQVzdGF0cwAKCQDMCAIJAKQDAQkAkQMCBQVzdGF0cwALBQNuaWwCAV8FA25pbAUNcHJvbG9nQWN0aW9ucwAAAWkBD2ZvcnRpZmljYXRlTGFuZAILbGFuZEFzc2V0SWQEcGxhbgQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEC2R1Y2tBc3NldElkCQELdmFsdWVPckVsc2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICAAQJZHVja1N0YXRzCQEMZ2V0RHVja1N0YXRzBAUEdGhpcwULZHVja0Fzc2V0SWQAAAcEB2ZvcnRLZXkJARdrZXlGb3J0aWZpY2F0aW9uc0J5TGFuZAEFC2xhbmRBc3NldElkBAxjdXJyZW50Rm9ydHMJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQdmb3J0S2V5Agw6MF8xNTowXzE4OjACAV8EBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQECWxhbmRJbmRleAkAaQIJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBQtyZWNMYW5kU2l6ZQUFU1NJWkUECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAV3aEtleQkBEmtleVdhcmVob3VzZUJ5TGFuZAEFC2xhbmRBc3NldElkBAJ3aAkBDGdldFdhcmVob3VzZQMFBXdoS2V5BQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwEB2N1ckxvZnQJALUJAgkAkQMCBQJ3aAUJd2hJZHhMT0ZUAgFfBARjdXJPCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHY3VyTG9mdAULdm9sT2NjdXBpZWQEBGN1ckYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdjdXJMb2Z0BQd2b2xGcmVlBAhuZXdGb3J0cwkAtQkCBQRwbGFuAgFfBA8kdDAxMDM2ODQxMDM3OTkJAQVmb3J0QgYFDGN1cnJlbnRGb3J0cwkBDnByb2RTdHJUb0J5dGVzAQkAkQMCBQJ3aAUJd2hJZHhQcm9kBQRjdXJPBQRjdXJGBgUDbmlsBAl0ZW1wUHJvZEIIBQ8kdDAxMDM2ODQxMDM3OTkCXzEEBXRlbXBPCAUPJHQwMTAzNjg0MTAzNzk5Al8yBAV0ZW1wRggFDyR0MDEwMzY4NDEwMzc5OQJfMwQPJHQwMTAzODAyMTAzODk4CQEFZm9ydEIGBQhuZXdGb3J0cwUJdGVtcFByb2RCBQV0ZW1wTwUFdGVtcEYHBQlkdWNrU3RhdHMECG5ld1Byb2RCCAUPJHQwMTAzODAyMTAzODk4Al8xBARuZXdPCAUPJHQwMTAzODAyMTAzODk4Al8yBARuZXdGCAUPJHQwMTAzODAyMTAzODk4Al8zBApuZXdQcm9kU3RyCQEOYnl0ZXNUb1Byb2RTdHIBBQhuZXdQcm9kQgQKbmV3TG9mdFN0cgkAuQkCCQDMCAIJAJEDAgUHY3VyTG9mdAUJdm9sTG9ja2VkCQDMCAIJAKQDAQUEbmV3TwkAzAgCCQCkAwEFBG5ld0YJAMwIAgkAkQMCBQdjdXJMb2Z0BQh2b2xUb3RhbAUDbmlsAgFfCQCUCgIJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQdmb3J0S2V5BQRwbGFuCQDMCAIJAQtTdHJpbmdFbnRyeQIFBXdoS2V5CQC6CQIJAMwIAgkAkQMCBQJ3aAULd2hJZHhMZXZlbHMJAMwIAgkAkQMCBQJ3aAUId2hJZHhSZXMJAMwIAgkAkQMCBQJ3aAUId2hJZHhNYXQJAMwIAgUKbmV3UHJvZFN0cgkAzAgCBQpuZXdMb2Z0U3RyBQNuaWwCAToFA25pbAUNcHJvbG9nQWN0aW9ucwAAAWkBE2luaXREdWNrVG91ckF0dGVtcHQBC2R1Y2tBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBRJ0b3VybmFtZW50Q29udHJhY3QJAAIBAg1BY2Nlc3MgZGVuaWVkBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEBW1heEhQCQEJbWF4SGVhbHRoAQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEMa2V5RHVja0xldmVsAQULZHVja0Fzc2V0SWQAAAQJY3VySGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aAUFbWF4SFAECWN1ckxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBBQljdXJMb2NLZXkFD0RFRkFVTFRMT0NBVElPTgQGbGFzdElkCQELdmFsdWVPckVsc2UCCQCaCAIFEnRvdXJuYW1lbnRDb250cmFjdAUNbGFzdFRvdXJJZEtleQAABAx0b3VyTG9jYXRpb24JAKwCAgkApAMBBQZsYXN0SWQCBF9UXzAJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDmtleVNhdmVkSGVhbHRoAQULZHVja0Fzc2V0SWQFCWN1ckhlYWx0aAkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQVtYXhIUAkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQtjdXJMb2NhdGlvbgkAzAgCCQELU3RyaW5nRW50cnkCBQljdXJMb2NLZXkFDHRvdXJMb2NhdGlvbgUDbmlsBQx0b3VyTG9jYXRpb24BaQEMYnJlYWtBdHRlbXB0AAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQECWN1ckxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBBQljdXJMb2NLZXkFD0RFRkFVTFRMT0NBVElPTgMJAQIhPQIJAJEDAgkAtQkCBQtjdXJMb2NhdGlvbgIBXwUKbG9jSWR4VHlwZQIBVAkAAgECIllvdXIgZHVjayBpcyBub3QgaW4gdGhlIHRvdXJuYW1lbnQEC3NhdmVkSGVhbHRoCQERQGV4dHJOYXRpdmUoMTA1NSkBCQEOa2V5U2F2ZWRIZWFsdGgBBQtkdWNrQXNzZXRJZAQNc2F2ZWRMb2NhdGlvbgkBEUBleHRyTmF0aXZlKDEwNTgpAQkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAlAoCCQDNCAIJAM0IAgUNcHJvbG9nQWN0aW9ucwkBDEludGVnZXJFbnRyeQIJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQFC3NhdmVkSGVhbHRoCQELU3RyaW5nRW50cnkCBQljdXJMb2NLZXkFDXNhdmVkTG9jYXRpb24FC2N1ckxvY2F0aW9uAWkBFmV4aXRUb3VybmFtZW50SW50ZXJuYWwBC2R1Y2tBc3NldElkAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQINQWNjZXNzIGRlbmllZAQLc2F2ZWRIZWFsdGgJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAQ5rZXlTYXZlZEhlYWx0aAEFC2R1Y2tBc3NldElkBA1zYXZlZExvY2F0aW9uCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEQa2V5U2F2ZWRMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQFC3NhdmVkSGVhbHRoCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUNc2F2ZWRMb2NhdGlvbgUDbmlsBwFpARRleGl0RGVsaXZlcnlJbnRlcm5hbAELZHVja0Fzc2V0SWQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAg1BY2Nlc3MgZGVuaWVkBAFlCQESZXhpdERlbGl2ZXJ5Q29tbW9uBAULZHVja0Fzc2V0SWQHAAAAAAkAlAoCCQDOCAIIBQFlAl8xCAUBZQJfMgcBaQEQYXV0b0V4aXREZWxpdmVyeQQLZHVja0Fzc2V0SWQFbmV3SFAGcmVhc29uBXNjb3JlAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQINQWNjZXNzIGRlbmllZAQBZQkBEmV4aXREZWxpdmVyeUNvbW1vbgQFC2R1Y2tBc3NldElkBgUFbmV3SFAFBXNjb3JlCQCUCgIIBQFlAl8xCAUBZQJfMwFpAQ1icmVha0RlbGl2ZXJ5AAkAlAoCCQEGcHJvbG9nAQUBaQINYnJlYWtEZWxpdmVyeQFpAQ5wcmVwYXJlUm9iYmVyeQIHbWVzc2FnZQNzaWcEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBASEBCQDEEwMFB21lc3NhZ2UFA3NpZwUDcHViCQACAQIYc2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEBndsZ0FtdAgFA3BtdAZhbW91bnQDAwkBASEBCQEJaXNEZWZpbmVkAQgFA3BtdAdhc3NldElkBgkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQp3bGdBc3NldElkCQACAQIVV0xHT0xEIHBheW1lbnRzIG9ubHkhBAVwYXJ0cwkAtQkCCQCwCQEFB21lc3NhZ2UCAXwDCQBmAgACCQCQAwEFBXBhcnRzCQACAQIUV3JvbmcgbWVzc2FnZSBmb3JtYXQECXR4RnJvbU1zZwMJAGcCCQCQAwEFBXBhcnRzAAIJAJEDAgUFcGFydHMAAgIABAh1c2VyQWRkcgkApQgBCAUBaQZjYWxsZXIEBmxhc3RUeAkBC3ZhbHVlT3JFbHNlAgkAoggBCQERa2V5TGFzdFR4SWRCeVVzZXIBBQh1c2VyQWRkcgIAAwkBAiE9AgUGbGFzdFR4BQl0eEZyb21Nc2cJAAIBCQCsAgIJAKwCAgkArAICAh5UeCBpZHMgZG9uJ3QgbWF0Y2ghIEluIHN0YXRlOiAFBmxhc3RUeAIKLCBpbiBtc2c6IAUJdHhGcm9tTXNnBAtkdWNrQXNzZXRJZAkAkQMCBQVwYXJ0cwAAAwkBD2NoZWNrVG91cm5hbWVudAEFC2R1Y2tBc3NldElkCQACAQIecHJlcGFyZVJvYmJlcnlfY2hlY2tUb3VybmFtZW50AwkBDWNoZWNrRGVsaXZlcnkBBQtkdWNrQXNzZXRJZAkAAgECHHByZXBhcmVSb2JiZXJ5X2NoZWNrRGVsaXZlcnkEB3JvYkNvc3QICQEOZ2V0Um9iYmVyeURhdGECBQR0aGlzBQtkdWNrQXNzZXRJZAJfMQMJAGYCBQdyb2JDb3N0BQZ3bGdBbXQJAAIBCQCsAgIJAKwCAgkArAICAghQYXltZW50IAkApAMBBQZ3bGdBbXQCDCA8IHJlcXVpcmVkIAkApAMBBQdyb2JDb3N0BApjYW5kaWRhdGVzCQC1CQIJAJEDAgUFcGFydHMAAQIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQJZHVja1N0YXRlCQELdmFsdWVPckVsc2UCCQCfCAEJARNrZXlEdWNrUm9iYmVyeVN0YXRlAQULZHVja0Fzc2V0SWQAAAQKbG9ja2VkTGFuZAkBC3ZhbHVlT3JFbHNlAgkAoggBCQETa2V5TG9ja2VkTGFuZEJ5RHVjawEFC2R1Y2tBc3NldElkAgAEB2xhbmRFVEEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEmtleUxhbmRDb29sZG93bkVUQQEFCmxvY2tlZExhbmQAAAMDCQECIT0CBQlkdWNrU3RhdGUFC2R1Y2tJZHhGcmVlCQBmAgUHbGFuZEVUQQUDbm93BwkAAgEJAKwCAgInWW91IGFscmVhZHkgc3RhcnRlZCByb2JiaW5nLCB3YWl0IHRpbGwgCQCkAwEFB2xhbmRFVEEKAQdjaGVja2VyAgNhY2MLbGFuZEFzc2V0SWQEBXN0YXRlCQELdmFsdWVPckVsc2UCCQCfCAEJARNrZXlMYW5kUm9iYmVyeVN0YXRlAQULbGFuZEFzc2V0SWQAAAQLY29vbGRvd25FVEEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEmtleUxhbmRDb29sZG93bkVUQQEFC2xhbmRBc3NldElkAAADCQBmAgUFc3RhdGUJAJADAQUQbGFuZFJvYkNvb2xkb3ducwkAAgECDUludmFsaWQgc3RhdGUDCQBmAgUDbm93BQtjb29sZG93bkVUQQQKc3Rha2VkVGltZQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAAADCQBnAgAABQpzdGFrZWRUaW1lBQNhY2MEAWEJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQBZAkAtQkCCAUBYQtkZXNjcmlwdGlvbgIBXwQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQQMcHJvZHVjdGl2aXR5CQEMYXBwbHlCb251c2VzAgULbGFuZEFzc2V0SWQFBnBpZWNlcwQJZGVsdGFUaW1lCQBlAgUDbm93BQpzdGFrZWRUaW1lBAhhdmFpbFJlcwkAawMFCWRlbHRhVGltZQkAaAIFDHByb2R1Y3Rpdml0eQUGcGllY2VzBQlEQVlNSUxMSVMDCQBmAgUOTUlOX1JFU19UT19ST0IFCGF2YWlsUmVzBQNhY2MJAM0IAgUDYWNjBQtsYW5kQXNzZXRJZAUDYWNjBAhmaWx0ZXJlZAoAAiRsBQpjYW5kaWRhdGVzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdjaGVja2VyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIJAJADAQUIZmlsdGVyZWQAAAkAAgECGU5vIGNhbmRpZGF0ZXMgZm9yIHJvYmJlcnkEBnJuZElkeAkBD2dldFJhbmRvbU51bWJlcgMJAJADAQUIZmlsdGVyZWQFB21lc3NhZ2UFA3NpZwQLbGFuZEFzc2V0SWQJAJEDAgUIZmlsdGVyZWQFBnJuZElkeAkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJARNrZXlMYW5kUm9iYmVyeVN0YXRlAQULbGFuZEFzc2V0SWQFDHJvYklkeExvY2tlZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmtleUxhbmRDb29sZG93bkVUQQEFC2xhbmRBc3NldElkCQBkAgUDbm93CQCRAwIFEGxhbmRSb2JDb29sZG93bnMFDHJvYklkeExvY2tlZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBE2tleUR1Y2tSb2JiZXJ5U3RhdGUBBQtkdWNrQXNzZXRJZAUQZHVja0lkeFByZXBhcmluZwkAzAgCCQELU3RyaW5nRW50cnkCCQETa2V5TG9ja2VkTGFuZEJ5RHVjawEFC2R1Y2tBc3NldElkBQtsYW5kQXNzZXRJZAUDbmlsBQ1wcm9sb2dBY3Rpb25zBQtsYW5kQXNzZXRJZAFpAQdyb2JMYW5kAgdtZXNzYWdlA3NpZwQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQEBIQEJAMQTAwUHbWVzc2FnZQUDc2lnBQNwdWIJAAIBAhhzaWduYXR1cmUgZG9lcyBub3QgbWF0Y2gECHVzZXJBZGRyCQClCAEIBQFpBmNhbGxlcgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQh1c2VyQWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAlAoCCQDNCAIFDXByb2xvZ0FjdGlvbnMJAQxJbnRlZ2VyRW50cnkCCQEYa2V5TGFzdFJvYmJlcnlUaW1lQnlEdWNrAQULZHVja0Fzc2V0SWQFA25vdwAAAWkBDmFjY2VwdERlbGl2ZXJ5AAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkECHVzZXJBZGRyCQClCAEIBQFpBmNhbGxlcgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQh1c2VyQWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQJZnVuZFRvdGFsCQELdmFsdWVPckVsc2UCCQCaCAIFD2Vjb25vbXlDb250cmFjdAUPZGVsaXZlcnlGdW5kS2V5AAAEC2xvY2tlZFRvdGFsCQELdmFsdWVPckVsc2UCCQCaCAIFD2Vjb25vbXlDb250cmFjdAURZGVsaXZlcnlMb2NrZWRLZXkAAAMJAGYCBRVNSU5fVVNEVF9GRUVfREVMSVZFUlkJAGUCBQlmdW5kVG90YWwFC2xvY2tlZFRvdGFsCQACAQkArAICCQCsAgIJAKwCAgIgRGVsaXZlcnkgaXMgbm90IGF2YWlsYWJsZSwgZnVuZD0JAQpmaXhlZFBvaW50AgUJZnVuZFRvdGFsAAYCCSwgbG9ja2VkPQkBCmZpeGVkUG9pbnQCBQtsb2NrZWRUb3RhbAAGBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAhkZWxheUVUQQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5RGVsaXZlcnlEZWxheUJ5RHVjawEFC2R1Y2tBc3NldElkAAADCQBmAgUIZGVsYXlFVEEFA25vdwkAAgEJAKwCAgIqRGVsaXZlcnkgaXMgZm9yYmlkZGVuIGZvciB5b3VyIGR1Y2sgdW50aWwgCQCkAwEFCGRlbGF5RVRBBAZoZWFsdGgJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQDCQBnAgAABQZoZWFsdGgJAAIBAitZb3UgY2Fubm90IGFjY2VwdCBkZWxpdmVyeSB3aXRoIHplcm8gaGVhbHRoBAhjb3VudEtleQkBFGtleVVzZXJEZWxpdmVyeUNvdW50AQUIdXNlckFkZHIEBWNvdW50CQELdmFsdWVPckVsc2UCCQCfCAEFCGNvdW50S2V5AAAEB2xhc3REYXkJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleVVzZXJMYXN0RGVsaXZlcnlEYXkBBQh1c2VyQWRkcgAABAV0b2RheQkAaQIFA25vdwUJREFZTUlMTElTBAVhY3JlcwkBC3ZhbHVlT3JFbHNlAgkAmggCBQ1hY3Jlc0NvbnRyYWN0CQEaa2V5QWNyZXNTdGFrZWRBbW91bnRCeVVzZXIBBQh1c2VyQWRkcgAABBFhbGxvd2VkRGVsaXZlcmllcwkAZAIFF0FMTE9XRURfRlJFRV9ERUxJVkVSSUVTCQBpAgUFYWNyZXMFGkFDUkVTX0ZPUl9ERUxJVkVSWV9BVFRFTVBUAwMJAGcCBQVjb3VudAURYWxsb3dlZERlbGl2ZXJpZXMJAAACBQdsYXN0RGF5BQV0b2RheQcJAAIBCQCsAgIJAKwCAgIRWW91IGFscmVhZHkgdXNlZCAJAKQDAQURYWxsb3dlZERlbGl2ZXJpZXMCHCBkZWxpdmVyeSBhdHRlbXB0cyBmb3IgdG9kYXkDCQEPY2hlY2tUb3VybmFtZW50AQULZHVja0Fzc2V0SWQJAAIBAh5hY2NlcHREZWxpdmVyeV9jaGVja1RvdXJuYW1lbnQDCQENY2hlY2tEZWxpdmVyeQEFC2R1Y2tBc3NldElkCQACAQIcYWNjZXB0RGVsaXZlcnlfY2hlY2tEZWxpdmVyeQQObmV3TG9ja2VkVG90YWwJAQVhc0ludAEJAPwHBAUPZWNvbm9teUNvbnRyYWN0AhR1cGRhdGVEZWxpdmVyeUxvY2tlZAkAzAgCCQBkAgULbG9ja2VkVG90YWwFFU1JTl9VU0RUX0ZFRV9ERUxJVkVSWQUDbmlsBQNuaWwECWN1ckxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBBQljdXJMb2NLZXkFD0RFRkFVTFRMT0NBVElPTgQQZGVsaXZlcnlMb2NhdGlvbgkArAICCQCkAwEFA25vdwIEX0RfMAkAlAoCCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleVNhdmVkTG9jYXRpb24BBQtkdWNrQXNzZXRJZAULY3VyTG9jYXRpb24JAMwIAgkBC1N0cmluZ0VudHJ5AgUJY3VyTG9jS2V5BRBkZWxpdmVyeUxvY2F0aW9uCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQhjb3VudEtleQMJAQIhPQIFB2xhc3REYXkFBXRvZGF5AAAFBWNvdW50BQNuaWwFDXByb2xvZ0FjdGlvbnMJAJQKAgUQZGVsaXZlcnlMb2NhdGlvbgUObmV3TG9ja2VkVG90YWwBaQEVY2hlY2tEZWxpdmVyeUNhbGxiYWNrAQtkdWNrQXNzZXRJZAMJAQIhPQIIBQFpBmNhbGxlcgUSdG91cm5hbWVudENvbnRyYWN0CQACAQINQWNjZXNzIGRlbmllZAkAlAoCBQNuaWwJAQ1jaGVja0RlbGl2ZXJ5AQULZHVja0Fzc2V0SWQAkF5vlw==", "height": 3895834, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 7KVkiexn5qSKJJZE6P7VKMcpmRJ3o7oka3tGdSPzPinx Next: DT811yXj5TqrgmFTqEkhY5PYsK6gzKCrq5FGdzhsTGWj Diff:
OldNewDifferences
409409
410410 let KS_ALLOW_BIG_INFRA_MERGE = false
411411
412-let KS_ALLOW_DELIVERY = true
413-
414412 let DAY_MILLIS = 86400000
415413
416414 let chain = take(drop(this.bytes, 1), 1)
619617 }
620618
621619
622-func getRandomNumber (maxValue,finishHeight,auxEntropy) = {
623- let randomSeedBlock = value(blockInfoByHeight(finishHeight))
624- let randomHash = sha256((value(randomSeedBlock.vrf) + auxEntropy))
620+func getRandomNumber (maxValue,salt,entropy) = {
621+ let randomHash = sha256((salt + entropy))
625622 (toInt(randomHash) % maxValue)
626623 }
627624
18911888 }
18921889
18931890
1894-func updateDuckStatsInternal (duckAssetId,deltaXP) = {
1895- let lvlKey = keyDuckLevel(duckAssetId)
1896- let xpKey = keyDuckXP(duckAssetId)
1891+func updateStatsInternal (lvlKey,xpKey,pointsKey,deltaXP) = {
18971892 let xp = valueOrElse(getInteger(xpKey), 0)
18981893 let newXP = (xp + deltaXP)
18991894 let lvlPoints = levelUp(valueOrElse(getInteger(lvlKey), 0), newXP)
1900- let keyPoints = keyDuckFreePoints(duckAssetId)
1901- $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(keyPoints, (valueOrElse(getInteger(keyPoints), 0) + lvlPoints[1]))], newXP)
1902- }
1903-
1904-
1905-func updateAccStatsInternal (addr,deltaXP) = {
1906- let lvlKey = keyUserLevel(addr)
1907- let xpKey = keyUserXP(addr)
1908- let xp = valueOrElse(getInteger(xpKey), 0)
1909- let newXP = (xp + deltaXP)
1910- let lvlPoints = levelUp(valueOrElse(getInteger(lvlKey), 0), newXP)
1911- let keyPoints = keyUserFreePoints(addr)
1912- $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(keyPoints, (valueOrElse(getInteger(keyPoints), 0) + lvlPoints[1]))], newXP)
1913- }
1895+ $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(pointsKey, (valueOrElse(getInteger(pointsKey), 0) + lvlPoints[1]))], newXP)
1896+ }
1897+
1898+
1899+func updateDuckStatsInternal (duckAssetId,deltaXP) = updateStatsInternal(keyDuckLevel(duckAssetId), keyDuckXP(duckAssetId), keyDuckFreePoints(duckAssetId), deltaXP)
1900+
1901+
1902+func updateAccStatsInternal (addr,deltaXP) = updateStatsInternal(keyUserLevel(addr), keyUserXP(addr), keyUserFreePoints(addr), deltaXP)
19141903
19151904
19161905 func activateOnboardArt (addr) = {
19701959 }
19711960
19721961
1973-func checkDelivery (duckAssetId) = if (!(KS_ALLOW_DELIVERY))
1974- then false
1975- else {
1976- let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1977- let now = lastBlock.timestamp
1978- if ((curLocation[locIdxType] != "D"))
1979- then false
1980- else {
1981- let startTime = parseIntValue(curLocation[locIdxContinent])
1982- let distance = parseIntValue(curLocation[locIdxId])
1983- if (if (((startTime + TEN_MINUTES_MILLIS) > now))
1984- then (1 > distance)
1985- else false)
1986- then throw("Your duck is on delivery mission")
1987- else asBoolean(invoke(this, "exitDeliveryInternal", [duckAssetId], nil))
1988- }
1989- }
1962+func checkDelivery (duckAssetId) = {
1963+ let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1964+ let now = lastBlock.timestamp
1965+ if ((curLocation[locIdxType] != "D"))
1966+ then false
1967+ else {
1968+ let startTime = parseIntValue(curLocation[locIdxContinent])
1969+ let distance = parseIntValue(curLocation[locIdxId])
1970+ if (if (((startTime + TEN_MINUTES_MILLIS) > now))
1971+ then (1 > distance)
1972+ else false)
1973+ then throw("Your duck is on delivery mission")
1974+ else asBoolean(invoke(this, "exitDeliveryInternal", [duckAssetId], nil))
1975+ }
1976+ }
19901977
19911978
19921979 func exitDeliveryCommon (duckAssetId,check,newHP,score) = {
21822169
21832170 func checkOutdatedDelivery (userAddr) = {
21842171 let duck = getString(keyStakedDuckByOwner(userAddr))
2185- if (if (KS_ALLOW_DELIVERY)
2186- then isDefined(duck)
2187- else false)
2172+ if (isDefined(duck))
21882173 then {
21892174 let duckAssetId = value(duck)
21902175 let locKey = keyDuckLocation(duckAssetId)
22032188 then nil
22042189 else throw("Strict value is not equal to itself.")
22052190 }
2206- else (({
2191+ else ({
22072192 let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
22082193 let unlock = invoke(economyContract, "updateDeliveryLocked", [(lockedTotal - MIN_USDT_FEE_DELIVERY)], nil)
22092194 if ((unlock == unlock))
22162201 else throw("Strict value is not equal to itself.")
22172202 }
22182203 else throw("Strict value is not equal to itself.")
2219- } :+ IntegerEntry(healthKey, getIntegerValue(keySavedHealth(duckAssetId)))) :+ StringEntry(locKey, getStringValue(keySavedLocation(duckAssetId))))
2204+ } :+ StringEntry(locKey, getStringValue(keySavedLocation(duckAssetId))))
22202205 }
22212206 }
22222207 else nil
25092494 let isDeliv = (newLoc[locIdxType] == "D")
25102495 let eqKey = keyDuckEquipment(duckAssetId)
25112496 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2512- let $t07046670563 = subtractEquipment(currentEq, f._5)
2513- let newEq = $t07046670563._1
2514- let shouldZeroBuffs = $t07046670563._2
2515- let $t07056673678 = if (!(onMission(tournamentContract, curLocation)))
2497+ let $t07008770184 = subtractEquipment(currentEq, f._5)
2498+ let newEq = $t07008770184._1
2499+ let shouldZeroBuffs = $t07008770184._2
2500+ let $t07018773299 = if (!(onMission(tournamentContract, curLocation)))
25162501 then if (!(isUsualLocation(newLocation)))
25172502 then cheatAttempt(curLocation, newLocation, 5)
25182503 else if ((newHP > 0))
25722557 else throw("Strict value is not equal to itself.")
25732558 }
25742559 }
2575- let locToSave = $t07056673678._1
2576- let hpToSave = $t07056673678._2
2560+ let locToSave = $t07018773299._1
2561+ let hpToSave = $t07018773299._2
25772562 $Tuple2(((([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), hpToSave)] ++ prologActions) ++ (if (shouldZeroBuffs)
25782563 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
25792564 else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
27792764 let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
27802765 let eqKey = keyDuckEquipment(duckAssetId)
27812766 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2782- let $t08111881215 = subtractEquipment(currentEq, f._5)
2783- let newEq = $t08111881215._1
2784- let shouldZeroBuffs = $t08111881215._2
2767+ let $t08073980836 = subtractEquipment(currentEq, f._5)
2768+ let newEq = $t08073980836._1
2769+ let shouldZeroBuffs = $t08073980836._2
27852770 let e = expeditionInternal(i.caller, i.transactionId)
27862771 let id = e._2._1
27872772 let result = if ((0 >= f._1))
30963081 let addr = toString(i.originCaller)
30973082 let virtWlgData = asAnyList(invoke(wlgContract, "checkWlgXpREADONLY", [addr], nil))
30983083 let virtWlgPoints = asInt(virtWlgData[1])
3099- let $t09683597225 = if ((0 >= virtWlgPoints))
3084+ let $t09645696846 = if ((0 >= virtWlgPoints))
31003085 then $Tuple2(0, nil)
31013086 else {
31023087 let deltaXP = asInt(invoke(wlgContract, "takeWlgXp", [addr], nil))
31043089 then $Tuple2(virtWlgPoints, [IntegerEntry(keyUserLevel(addr), asInt(virtWlgData[0])), IntegerEntry(keyUserXP(addr), asInt(virtWlgData[2]))])
31053090 else throw("Strict value is not equal to itself.")
31063091 }
3107- let wlgPoints = $t09683597225._1
3108- let wlgActions = $t09683597225._2
3092+ let wlgPoints = $t09645696846._1
3093+ let wlgActions = $t09645696846._2
31093094 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
31103095 let freeKeyAcc = keyUserFreePoints(addr)
31113096 let freePointsAcc = (valueOrElse(getInteger(freeKeyAcc), 0) + wlgPoints)
32563241 let curO = parseIntValue(curLoft[volOccupied])
32573242 let curF = parseIntValue(curLoft[volFree])
32583243 let newForts = split(plan, "_")
3259- let $t0104063104178 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3260- let tempProdB = $t0104063104178._1
3261- let tempO = $t0104063104178._2
3262- let tempF = $t0104063104178._3
3263- let $t0104181104277 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3264- let newProdB = $t0104181104277._1
3265- let newO = $t0104181104277._2
3266- let newF = $t0104181104277._3
3244+ let $t0103684103799 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3245+ let tempProdB = $t0103684103799._1
3246+ let tempO = $t0103684103799._2
3247+ let tempF = $t0103684103799._3
3248+ let $t0103802103898 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3249+ let newProdB = $t0103802103898._1
3250+ let newO = $t0103802103898._2
3251+ let newF = $t0103802103898._3
32673252 let newProdStr = bytesToProdStr(newProdB)
32683253 let newLoftStr = makeString([curLoft[volLocked], toString(newO), toString(newF), curLoft[volTotal]], "_")
32693254 $Tuple2(([StringEntry(fortKey, plan), StringEntry(whKey, makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], newProdStr, newLoftStr], ":"))] ++ prologActions), 0)
33573342 then throw("WLGOLD payments only!")
33583343 else {
33593344 let parts = split(toUtf8String(message), "|")
3360- if ((size(parts) != 2))
3345+ if ((2 > size(parts)))
33613346 then throw("Wrong message format")
33623347 else {
3363- let duckAssetId = parts[0]
3364- if (checkTournament(duckAssetId))
3365- then throw("prepareRobbery_checkTournament")
3366- else if (checkDelivery(duckAssetId))
3367- then throw("prepareRobbery_checkDelivery")
3368- else {
3369- let robCost = getRobberyData(this, duckAssetId)._1
3370- if ((robCost > wlgAmt))
3371- then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
3348+ let txFromMsg = if ((size(parts) >= 2))
3349+ then parts[2]
3350+ else ""
3351+ let userAddr = toString(i.caller)
3352+ let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
3353+ if ((lastTx != txFromMsg))
3354+ then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
3355+ else {
3356+ let duckAssetId = parts[0]
3357+ if (checkTournament(duckAssetId))
3358+ then throw("prepareRobbery_checkTournament")
3359+ else if (checkDelivery(duckAssetId))
3360+ then throw("prepareRobbery_checkDelivery")
33723361 else {
3373- let candidates = split(parts[1], "_")
3374- let now = lastBlock.timestamp
3375- let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
3376- let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
3377- let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
3378- if (if ((duckState != duckIdxFree))
3379- then (landETA > now)
3380- else false)
3381- then throw(("You already started robbing, wait till " + toString(landETA)))
3362+ let robCost = getRobberyData(this, duckAssetId)._1
3363+ if ((robCost > wlgAmt))
3364+ then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
33823365 else {
3383- func checker (acc,landAssetId) = {
3384- let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
3385- let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
3386- if ((state > size(landRobCooldowns)))
3387- then throw("Invalid state")
3388- else if ((now > cooldownETA))
3389- then {
3390- let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
3391- if ((0 >= stakedTime))
3392- then acc
3393- else {
3394- let a = value(assetInfo(fromBase58String(landAssetId)))
3395- let d = split(a.description, "_")
3396- let pieces = numPiecesBySize(d[recLandSize])
3397- let productivity = applyBonuses(landAssetId, pieces)
3398- let deltaTime = (now - stakedTime)
3399- let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
3400- if ((MIN_RES_TO_ROB > availRes))
3366+ let candidates = split(parts[1], "_")
3367+ let now = lastBlock.timestamp
3368+ let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
3369+ let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
3370+ let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
3371+ if (if ((duckState != duckIdxFree))
3372+ then (landETA > now)
3373+ else false)
3374+ then throw(("You already started robbing, wait till " + toString(landETA)))
3375+ else {
3376+ func checker (acc,landAssetId) = {
3377+ let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
3378+ let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
3379+ if ((state > size(landRobCooldowns)))
3380+ then throw("Invalid state")
3381+ else if ((now > cooldownETA))
3382+ then {
3383+ let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
3384+ if ((0 >= stakedTime))
34013385 then acc
3402- else (acc :+ landAssetId)
3386+ else {
3387+ let a = value(assetInfo(fromBase58String(landAssetId)))
3388+ let d = split(a.description, "_")
3389+ let pieces = numPiecesBySize(d[recLandSize])
3390+ let productivity = applyBonuses(landAssetId, pieces)
3391+ let deltaTime = (now - stakedTime)
3392+ let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
3393+ if ((MIN_RES_TO_ROB > availRes))
3394+ then acc
3395+ else (acc :+ landAssetId)
3396+ }
34033397 }
3398+ else acc
3399+ }
3400+
3401+ let filtered = {
3402+ let $l = candidates
3403+ let $s = size($l)
3404+ let $acc0 = nil
3405+ func $f0_1 ($a,$i) = if (($i >= $s))
3406+ then $a
3407+ else checker($a, $l[$i])
3408+
3409+ func $f0_2 ($a,$i) = if (($i >= $s))
3410+ then $a
3411+ else throw("List size exceeds 10")
3412+
3413+ $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)
3414+ }
3415+ if ((size(filtered) == 0))
3416+ then throw("No candidates for robbery")
3417+ else {
3418+ let rndIdx = getRandomNumber(size(filtered), message, sig)
3419+ let landAssetId = filtered[rndIdx]
3420+ $Tuple2(([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId)] ++ prologActions), landAssetId)
34043421 }
3405- else acc
3406- }
3407-
3408- let filtered = {
3409- let $l = candidates
3410- let $s = size($l)
3411- let $acc0 = nil
3412- func $f0_1 ($a,$i) = if (($i >= $s))
3413- then $a
3414- else checker($a, $l[$i])
3415-
3416- func $f0_2 ($a,$i) = if (($i >= $s))
3417- then $a
3418- else throw("List size exceeds 10")
3419-
3420- $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)
3421- }
3422- if ((size(filtered) == 0))
3423- then throw("No candidates for robbery")
3424- else {
3425- let rndIdx = getRandomNumber(size(filtered), height, (sig + i.transactionId))
3426- let landAssetId = filtered[rndIdx]
3427- $Tuple2(([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId)] ++ prologActions), landAssetId)
34283422 }
34293423 }
34303424 }
3431- }
3425+ }
34323426 }
34333427 }
34343428 }
34523446
34533447
34543448 @Callable(i)
3455-func acceptDelivery () = if (!(KS_ALLOW_DELIVERY))
3456- then throw("Delivery feature is turned off!")
3457- else {
3458- let prologActions = prolog(i)
3459- let userAddr = toString(i.caller)
3460- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
3461- let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
3462- let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
3463- if ((MIN_USDT_FEE_DELIVERY > (fundTotal - lockedTotal)))
3464- then throw(((("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)) + ", locked=") + fixedPoint(lockedTotal, 6)))
3465- else {
3466- let now = lastBlock.timestamp
3467- let delayETA = valueOrElse(getInteger(keyDeliveryDelayByDuck(duckAssetId)), 0)
3468- if ((delayETA > now))
3469- then throw(("Delivery is forbidden for your duck until " + toString(delayETA)))
3470- else {
3471- let health = getIntegerValue(keyDuckHealth(duckAssetId))
3472- if ((0 >= health))
3473- then throw("You cannot accept delivery with zero health")
3474- else {
3475- let countKey = keyUserDeliveryCount(userAddr)
3476- let count = valueOrElse(getInteger(countKey), 0)
3477- let lastDay = valueOrElse(getInteger(keyUserLastDeliveryDay(userAddr)), 0)
3478- let today = (now / DAYMILLIS)
3479- let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(userAddr)), 0)
3480- let allowedDeliveries = (ALLOWED_FREE_DELIVERIES + (acres / ACRES_FOR_DELIVERY_ATTEMPT))
3481- if (if ((count >= allowedDeliveries))
3482- then (lastDay == today)
3483- else false)
3484- then throw((("You already used " + toString(allowedDeliveries)) + " delivery attempts for today"))
3485- else if (checkTournament(duckAssetId))
3486- then throw("acceptDelivery_checkTournament")
3487- else if (checkDelivery(duckAssetId))
3488- then throw("acceptDelivery_checkDelivery")
3489- else {
3490- let newLockedTotal = asInt(invoke(economyContract, "updateDeliveryLocked", [(lockedTotal + MIN_USDT_FEE_DELIVERY)], nil))
3491- let curLocKey = keyDuckLocation(duckAssetId)
3492- let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
3493- let deliveryLocation = (toString(now) + "_D_0")
3494- $Tuple2(([StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, deliveryLocation), IntegerEntry(countKey, if ((lastDay != today))
3495- then 0
3496- else count)] ++ prologActions), $Tuple2(deliveryLocation, newLockedTotal))
3497- }
3498- }
3499- }
3500- }
3501- }
3449+func acceptDelivery () = {
3450+ let prologActions = prolog(i)
3451+ let userAddr = toString(i.caller)
3452+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
3453+ let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
3454+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
3455+ if ((MIN_USDT_FEE_DELIVERY > (fundTotal - lockedTotal)))
3456+ then throw(((("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)) + ", locked=") + fixedPoint(lockedTotal, 6)))
3457+ else {
3458+ let now = lastBlock.timestamp
3459+ let delayETA = valueOrElse(getInteger(keyDeliveryDelayByDuck(duckAssetId)), 0)
3460+ if ((delayETA > now))
3461+ then throw(("Delivery is forbidden for your duck until " + toString(delayETA)))
3462+ else {
3463+ let health = getIntegerValue(keyDuckHealth(duckAssetId))
3464+ if ((0 >= health))
3465+ then throw("You cannot accept delivery with zero health")
3466+ else {
3467+ let countKey = keyUserDeliveryCount(userAddr)
3468+ let count = valueOrElse(getInteger(countKey), 0)
3469+ let lastDay = valueOrElse(getInteger(keyUserLastDeliveryDay(userAddr)), 0)
3470+ let today = (now / DAYMILLIS)
3471+ let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(userAddr)), 0)
3472+ let allowedDeliveries = (ALLOWED_FREE_DELIVERIES + (acres / ACRES_FOR_DELIVERY_ATTEMPT))
3473+ if (if ((count >= allowedDeliveries))
3474+ then (lastDay == today)
3475+ else false)
3476+ then throw((("You already used " + toString(allowedDeliveries)) + " delivery attempts for today"))
3477+ else if (checkTournament(duckAssetId))
3478+ then throw("acceptDelivery_checkTournament")
3479+ else if (checkDelivery(duckAssetId))
3480+ then throw("acceptDelivery_checkDelivery")
3481+ else {
3482+ let newLockedTotal = asInt(invoke(economyContract, "updateDeliveryLocked", [(lockedTotal + MIN_USDT_FEE_DELIVERY)], nil))
3483+ let curLocKey = keyDuckLocation(duckAssetId)
3484+ let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
3485+ let deliveryLocation = (toString(now) + "_D_0")
3486+ $Tuple2(([StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, deliveryLocation), IntegerEntry(countKey, if ((lastDay != today))
3487+ then 0
3488+ else count)] ++ prologActions), $Tuple2(deliveryLocation, newLockedTotal))
3489+ }
3490+ }
3491+ }
3492+ }
3493+ }
35023494
35033495
35043496
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let DAYMILLIS = 86400000
55
66 func keyLastArbTimeByUser (addr) = ("lastArbTimeUser_" + addr)
77
88
99 func keyAcresStakedAmountByUser (addr) = ("acresStakedAmountByUser_" + addr)
1010
1111
1212 let SCALE8 = 100000000
1313
1414 let xpLevelScale = 3200
1515
1616 let xpLevelRecipPow = 4000
1717
1818 let numPointsOnLevelUp = 3
1919
2020 let robberyCostMin = 100000000
2121
2222 let robberyCooldownCoeff = 400
2323
2424 let requirements = ["Strength", "Accuracy", "Intellect", "Endurance", "Dexterity", "Level", "Health"]
2525
2626 let charStrength = 0
2727
2828 let charAccuracy = 1
2929
3030 let charIntellect = 2
3131
3232 let charEndurance = 3
3333
3434 let charDexterity = 4
3535
3636 let segBackpack = 0
3737
3838 let NUMSEGMENTS = 6
3939
4040 let NUMMAINAUX = 2
4141
4242 let MAXSLOTS = 2
4343
4444 let MAXPRODINSLOT = 30
4545
4646 let landRobCooldowns = [0, 600000, 900000, 43200000, 21600000]
4747
4848 let MIN_RES_TO_ROB = 20000000
4949
5050 let robIdxLocked = 1
5151
5252 let duckIdxFree = 0
5353
5454 let duckIdxPreparing = 1
5555
5656 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
5757
5858
5959 func keyDuckChars (duckAssetId) = ("duckChars_" + duckAssetId)
6060
6161
6262 func keyDuckXP (duckAssetId) = ("duckXP_" + duckAssetId)
6363
6464
6565 func keyDuckLevel (duckAssetId) = ("duckLevel_" + duckAssetId)
6666
6767
6868 func keyDuckFreePoints (duckAssetId) = ("duckFreePoints_" + duckAssetId)
6969
7070
7171 func keyDuckEquipment (duckAssetId) = ("duckEquipment_" + duckAssetId)
7272
7373
7474 func keyUserXP (addr) = ("userXP_" + addr)
7575
7676
7777 func keyUserLevel (addr) = ("userLevel_" + addr)
7878
7979
8080 func keyUserFreePoints (addr) = ("userFreePoints_" + addr)
8181
8282
8383 func keySavedHealth (duckAssetId) = ("savedHealth_" + duckAssetId)
8484
8585
8686 func keySavedLocation (duckAssetId) = ("savedLocation_" + duckAssetId)
8787
8888
8989 func keyDuckBuffs (duckAssetId) = ("duckBuffs_" + duckAssetId)
9090
9191
9292 func keyLastRobberyTimeByDuck (duckAssetId) = ("lastRobberyTime_" + duckAssetId)
9393
9494
9595 func keyLastRobberyCostByDuck (duckAssetId) = ("lastRobberyCost_" + duckAssetId)
9696
9797
9898 func keyLandRobberyState (landAssetId) = ("landRobberyState_" + landAssetId)
9999
100100
101101 func keyLandCooldownETA (landAssetId) = ("landCooldownETA_" + landAssetId)
102102
103103
104104 func keyDuckRobberyState (duckAssetId) = ("duckRobberyState_" + duckAssetId)
105105
106106
107107 func keyLockedLandByDuck (duckAssetId) = ("lockedLandByDuck_" + duckAssetId)
108108
109109
110110 func keyDeliveryDelayByDuck (duckAssetId) = ("deliveryDelayByDuck_" + duckAssetId)
111111
112112
113113 func keyUserDeliveryCount (addr) = ("userDeliveryCount_" + addr)
114114
115115
116116 func keyUserLastDeliveryDay (addr) = ("userLastDeliveryDay_" + addr)
117117
118118
119119 let xpClaim = 10000
120120
121121 let xpSuccessFlight = 10000
122122
123123 let xpFailFlight = 2000
124124
125125 let xpCallES = 100000
126126
127127 let xpCustomName = 1000000
128128
129129 let xpNewSLand = 5000000
130130
131131 let xpUpgradeInfra = 10000
132132
133133 let xpMerge = 1000000
134134
135135 let xpOnboard = 1000000
136136
137137 let xpHeal = 10000
138138
139139 func levelByXP (xp) = fraction(xpLevelScale, pow(xp, 4, xpLevelRecipPow, 4, 4, DOWN), SCALE8)
140140
141141
142142 func maxHealth (level) = (100 + level)
143143
144144
145145 func levelUp (currLevel,newXP) = {
146146 let newLevel = levelByXP(newXP)
147147 [newLevel, (numPointsOnLevelUp * (newLevel - currLevel))]
148148 }
149149
150150
151151 func getDuckStats (stakingContract,duckAssetId,buffEffect,forceBuffs) = {
152152 let chars = split(valueOrElse(getString(stakingContract, keyDuckChars(duckAssetId)), "0_0_0_0_0"), "_")
153153 let lvl = valueOrElse(getInteger(stakingContract, keyDuckLevel(duckAssetId)), 0)
154154 let health = valueOrElse(getInteger(stakingContract, keyDuckHealth(duckAssetId)), maxHealth(lvl))
155155 let stateBuffs = split(valueOrElse(getString(stakingContract, keyDuckBuffs(duckAssetId)), "0_0_0_0_0"), "_")
156156 ([parseIntValue(chars[charStrength]), parseIntValue(chars[charAccuracy]), parseIntValue(chars[charIntellect]), parseIntValue(chars[charEndurance]), parseIntValue(chars[charDexterity]), lvl, health] ++ (if (forceBuffs)
157157 then [buffEffect, buffEffect, buffEffect, buffEffect, buffEffect]
158158 else [parseIntValue(stateBuffs[charStrength]), parseIntValue(stateBuffs[charAccuracy]), parseIntValue(stateBuffs[charIntellect]), parseIntValue(stateBuffs[charEndurance]), parseIntValue(stateBuffs[charDexterity])]))
159159 }
160160
161161
162162 func getRobberyData (stakingContract,duckAssetId) = {
163163 let lastRobCost = valueOrElse(getInteger(stakingContract, keyLastRobberyCostByDuck(duckAssetId)), 0)
164164 let lastRobTime = valueOrElse(getInteger(stakingContract, keyLastRobberyTimeByDuck(duckAssetId)), 0)
165165 let now = lastBlock.timestamp
166166 let robCost = max([robberyCostMin, (lastRobCost - (robberyCooldownCoeff * (now - lastRobTime)))])
167167 let duckState = valueOrElse(getInteger(stakingContract, keyDuckRobberyState(duckAssetId)), 0)
168168 let lockedLand = valueOrElse(getString(stakingContract, keyLockedLandByDuck(duckAssetId)), "")
169169 let landETA = valueOrElse(getInteger(stakingContract, keyLandCooldownETA(lockedLand)), 0)
170170 $Tuple5(robCost, lastRobTime, duckState, lockedLand, landETA)
171171 }
172172
173173
174174 let LANDPREFIX = "LAND"
175175
176176 let DUCKPREFIX = "DUCK"
177177
178178 let ARTPRESALE = "PRESALE"
179179
180180 let NUMRES = 6
181181
182182 let MAX_LANDS_STAKED_BY_USER = 25
183183
184184 let DAILYRESBYPIECE = 3456000
185185
186186 let WHMULTIPLIER = 10000000000
187187
188188 let DEFAULTLOCATION = "Africa_F_Africa"
189189
190190 let RESOURCEPRICEMIN = 39637
191191
192192 let ESSELLCOEF = 10
193193
194194 let MIN_USDT_FEE_DELIVERY = 50000
195195
196196 let TEN_MINUTES_MILLIS = 600000
197197
198198 let ALLOWED_FREE_DELIVERIES = 1
199199
200200 let ACRES_FOR_DELIVERY_ATTEMPT = 50000000
201201
202202 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"]
203203
204204 let continents = ["Americas", "Europe", "Asia", "Africa", "Oceania"]
205205
206206 let COEFF2MAT = 10000000
207207
208208 let fortAllowedProds = [15, 16, 17, 18, 19, 20]
209209
210210 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_"]
211211
212212 let rIdxCoeff = 6
213213
214214 let rIdxEffect = 8
215215
216216 let rIdxRequirements = 9
217217
218218 let rIdxSlots = 10
219219
220220 let PRODUCTPKGSIZE = 10
221221
222222 let whIdxLevels = 0
223223
224224 let whIdxRes = 1
225225
226226 let whIdxMat = 2
227227
228228 let whIdxProd = 3
229229
230230 let whIdxLOFT = 4
231231
232232 let volLocked = 0
233233
234234 let volOccupied = 1
235235
236236 let volFree = 2
237237
238238 let volTotal = 3
239239
240240 let bpIdxLevel = 0
241241
242242 let bpIdxRes = 1
243243
244244 let bpIdxMat = 2
245245
246246 let bpIdxProd = 3
247247
248248 let locIdxContinent = 0
249249
250250 let locIdxType = 1
251251
252252 let locIdxId = 2
253253
254254 func keyLandAssetIdToOwner (assetId) = ("no_" + assetId)
255255
256256
257257 func keyLandAssetIdToCustomName (assetId) = ("lcna_" + assetId)
258258
259259
260260 func keyStakedTimeByAssetId (assetId) = ("st_" + assetId)
261261
262262
263263 func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["las", type, assetId], "_")
264264
265265
266266 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("sttao_" + nftType) + "_") + assetId) + "_") + ownerAddr)
267267
268268
269269 func keyWarehouseByLand (landAssetId) = ("wh_" + landAssetId)
270270
271271
272272 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
273273
274274
275275 func keyFortificationsByLand (landAssetId) = ("fortifications_" + landAssetId)
276276
277277
278278 func keyDuckAssetIdToCustomName (assetId) = ("duckCustomNameByAssetId_" + assetId)
279279
280280
281281 func keyAddressToCustomName (addr) = ("accountCustomNameByAddr_" + addr)
282282
283283
284284 func keyAddressRefBy (addr) = ("accRefBy_" + addr)
285285
286286
287287 func keyOnboardArtActivatedOnDuck (duckAssetId) = ("onboardArtActivatedOnDuck_" + duckAssetId)
288288
289289
290290 func keyOnboardArtDuckActivatedBy (addr) = ("onboardArtActivatedDuckBy_" + addr)
291291
292292
293293 func keyAddressReferrals (addr) = ("accReferrals_" + addr)
294294
295295
296296 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
297297
298298
299299 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
300300
301301
302302 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
303303
304304
305305 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
306306
307307
308308 func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
309309
310310
311311 func keyEsWarehouse () = "emergencyWarehouseProducts"
312312
313313
314314 let deliveryFundKey = "deliveryFund"
315315
316316 let deliveryLockedKey = "deliveryLocked"
317317
318318 let lastTourIdKey = "%s__lastTourId"
319319
320320 func keyTourStaticDataById (tId) = ("%s%d__tourStaticData__" + toString(tId))
321321
322322
323323 func keyTourDynamicDataById (tId) = ("%s%d__tourDynamicData__" + toString(tId))
324324
325325
326326 func keyBestResultByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestResultByTourAndDuck", toString(tId), duckAssetId], "__")
327327
328328
329329 let idxStatic = 0
330330
331331 let idxDynamic = 1
332332
333333 let tStaticEnd = 6
334334
335335 let tDynamicStatus = 1
336336
337337 func getTourData (tourContract,tId) = {
338338 let static = split(valueOrErrorMessage(getString(tourContract, keyTourStaticDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
339339 let dynamic = split_4C(valueOrErrorMessage(getString(tourContract, keyTourDynamicDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
340340 [static, dynamic]
341341 }
342342
343343
344344 func isInTournament (tourContract,location) = {
345345 let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
346346 let loc = split(location, "_")
347347 let now = lastBlock.timestamp
348348 let tData = getTourData(tourContract, lastId)
349349 let static = tData[idxStatic]
350350 let dynamic = tData[idxDynamic]
351351 if (if (if ((loc[locIdxType] == "T"))
352352 then (parseIntValue(loc[locIdxContinent]) == lastId)
353353 else false)
354354 then (dynamic[tDynamicStatus] == "INPROGRESS")
355355 else false)
356356 then (parseIntValue(static[tStaticEnd]) > now)
357357 else false
358358 }
359359
360360
361361 func isInDelivery (location) = {
362362 let loc = split(location, "_")
363363 let now = lastBlock.timestamp
364364 let startTime = parseIntValue(loc[locIdxContinent])
365365 let distance = parseIntValue(loc[locIdxId])
366366 if (if ((loc[locIdxType] == "D"))
367367 then ((startTime + TEN_MINUTES_MILLIS) > now)
368368 else false)
369369 then (3 >= distance)
370370 else false
371371 }
372372
373373
374374 func isUsualLocation (location) = {
375375 let locType = split(location, "_")[locIdxType]
376376 if ((locType != "T"))
377377 then (locType != "D")
378378 else false
379379 }
380380
381381
382382 func onMission (tourContract,location) = {
383383 let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
384384 let loc = split(location, "_")
385385 let now = lastBlock.timestamp
386386 let tData = getTourData(tourContract, lastId)
387387 let static = tData[idxStatic]
388388 let dynamic = tData[idxDynamic]
389389 let locType = loc[locIdxType]
390390 if ((locType == "D"))
391391 then true
392392 else if (if (if ((loc[locIdxType] == "T"))
393393 then (parseIntValue(loc[locIdxContinent]) == lastId)
394394 else false)
395395 then (dynamic[tDynamicStatus] == "INPROGRESS")
396396 else false)
397397 then (parseIntValue(static[tStaticEnd]) > now)
398398 else false
399399 }
400400
401401
402402 func getRecipeMaterials (recipe) = (parseIntValue(recipe[rIdxCoeff]) * COEFF2MAT)
403403
404404
405405 func cheatAttempt (oldLoc,newLoc,cheatCase) = throw(((((("Cheat attempt: oldLoc=" + oldLoc) + ", newLoc=") + newLoc) + ", case=") + toString(cheatCase)))
406406
407407
408408 let KS_SEPARATE_PUBLIC_KEY = false
409409
410410 let KS_ALLOW_BIG_INFRA_MERGE = false
411411
412-let KS_ALLOW_DELIVERY = true
413-
414412 let DAY_MILLIS = 86400000
415413
416414 let chain = take(drop(this.bytes, 1), 1)
417415
418416 let usdtAssetId = match chain {
419417 case _ =>
420418 if ((base58'2W' == $match0))
421419 then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
422420 else if ((base58'2T' == $match0))
423421 then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
424422 else throw("Unknown chain")
425423 }
426424
427425 let defaultRestAddressStr = match chain {
428426 case _ =>
429427 if ((base58'2W' == $match0))
430428 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
431429 else if ((base58'2T' == $match0))
432430 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
433431 else throw("Unknown chain")
434432 }
435433
436434 let InfraUpgradeCostS = match chain {
437435 case _ =>
438436 if ((base58'2W' == $match0))
439437 then 10000000000
440438 else if ((base58'2T' == $match0))
441439 then 100000000
442440 else throw("Unknown chain")
443441 }
444442
445443 let arbitrageDelay = match chain {
446444 case _ =>
447445 if ((base58'2W' == $match0))
448446 then DAY_MILLIS
449447 else if ((base58'2T' == $match0))
450448 then 60000
451449 else throw("Unknown chain")
452450 }
453451
454452 let DELIVERY_PUNISHMENT = match chain {
455453 case _ =>
456454 if ((base58'2W' == $match0))
457455 then 10800000
458456 else if ((base58'2T' == $match0))
459457 then 900000
460458 else throw("Unknown chain")
461459 }
462460
463461 let SEP = "__"
464462
465463 let MULT6 = 1000000
466464
467465 let MULT8 = 100000000
468466
469467 let SSIZE = 25
470468
471469 let MSIZE = 100
472470
473471 let LSIZE = 225
474472
475473 let XLSIZE = 400
476474
477475 let XXLSIZE = 625
478476
479477 let ITER6 = [0, 1, 2, 3, 4, 5]
480478
481479 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
482480
483481
484482 let IdxCfgStakingDapp = 1
485483
486484 let IdxCfgEconomyDapp = 2
487485
488486 let IdxCfgGovernanceDapp = 3
489487
490488 let IdxCfgWlgDapp = 4
491489
492490 let IdxCfgTournamentDapp = 7
493491
494492 let IdxCfgAcresDapp = 8
495493
496494 func keyRestCfg () = "%s__restConfig"
497495
498496
499497 func keyRestAddress () = "%s__restAddr"
500498
501499
502500 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
503501
504502
505503 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
506504
507505
508506 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
509507
510508 let restCfg = readRestCfgOrFail(restContract)
511509
512510 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
513511
514512 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
515513
516514 let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
517515
518516 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
519517
520518 let tournamentContract = getContractAddressOrFail(restCfg, IdxCfgTournamentDapp)
521519
522520 let acresContract = getContractAddressOrFail(restCfg, IdxCfgAcresDapp)
523521
524522 let recLandNum = 0
525523
526524 let recLandSize = 1
527525
528526 let recTerrains = 2
529527
530528 let recContinent = 3
531529
532530 let wlgAssetIdKey = "wlg_assetId"
533531
534532 let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "WLGOLD is not issued yet")
535533
536534 let acresAssetIdKey = "acresAssetId"
537535
538536 let acresAssetId = valueOrErrorMessage(getBinary(acresContract, acresAssetIdKey), "ACRES is not issued yet")
539537
540538 let randomDelay = 2
541539
542540 func keyCommit (address) = ("finishBlockForAddr_" + address)
543541
544542
545543 func keyResProportions () = "resTypesProportions"
546544
547545
548546 func keyResTypesByContinent (continent) = ("resTypesByContinent_" + continent)
549547
550548
551549 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
552550
553551
554552 func keyStakedPiecesByOwner (ownerAddr) = ("stakedPiecesByOwner_" + ownerAddr)
555553
556554
557555 func asString (v) = match v {
558556 case s: String =>
559557 s
560558 case _ =>
561559 throw("fail to cast into String")
562560 }
563561
564562
565563 func asInt (v) = match v {
566564 case n: Int =>
567565 n
568566 case _ =>
569567 throw("fail to cast into Int")
570568 }
571569
572570
573571 func asAnyList (v) = match v {
574572 case l: List[Any] =>
575573 l
576574 case _ =>
577575 throw("fail to cast into List[Any]")
578576 }
579577
580578
581579 func asBoolean (v) = match v {
582580 case s: Boolean =>
583581 s
584582 case _ =>
585583 throw("fail to cast into Boolean")
586584 }
587585
588586
589587 func numPiecesBySize (landSize) = match landSize {
590588 case _ =>
591589 if (("S" == $match0))
592590 then SSIZE
593591 else if (("M" == $match0))
594592 then MSIZE
595593 else if (("L" == $match0))
596594 then LSIZE
597595 else if (("XL" == $match0))
598596 then XLSIZE
599597 else if (("XXL" == $match0))
600598 then XXLSIZE
601599 else throw("Unknown land size")
602600 }
603601
604602
605603 func isDigit (s) = isDefined(parseInt(s))
606604
607605
608606 func keyBlocked () = "contractsBlocked"
609607
610608
611609 func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
612610
613611
614612 func fixedPoint (val,decimals) = {
615613 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
616614 let lowPart = toString((val % tenPow))
617615 let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
618616 (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
619617 }
620618
621619
622-func getRandomNumber (maxValue,finishHeight,auxEntropy) = {
623- let randomSeedBlock = value(blockInfoByHeight(finishHeight))
624- let randomHash = sha256((value(randomSeedBlock.vrf) + auxEntropy))
620+func getRandomNumber (maxValue,salt,entropy) = {
621+ let randomHash = sha256((salt + entropy))
625622 (toInt(randomHash) % maxValue)
626623 }
627624
628625
629626 let incubatorAddr = match chain {
630627 case _ =>
631628 if ((base58'2W' == $match0))
632629 then addressFromStringValue("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
633630 else if ((base58'2T' == $match0))
634631 then this
635632 else throw("Unknown chain")
636633 }
637634
638635 let breederAddr = match chain {
639636 case _ =>
640637 if ((base58'2W' == $match0))
641638 then addressFromStringValue("3PDVuU45H7Eh5dmtNbnRNRStGwULA7NY6Hb")
642639 else if ((base58'2T' == $match0))
643640 then this
644641 else throw("Unknown chain")
645642 }
646643
647644 let pub = match chain {
648645 case _ =>
649646 if ((base58'2W' == $match0))
650647 then if (KS_SEPARATE_PUBLIC_KEY)
651648 then base58'CWsMtTZC5BjjoL4Q1ayW4Wwb1ehGACQB6DrKyPgotKfm'
652649 else base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
653650 else if ((base58'2T' == $match0))
654651 then base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
655652 else throw("Unknown chain")
656653 }
657654
658655 let EMPTY_PROD50 = base64'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='
659656
660657 let FIVEMINUTESMILLIS = 300000
661658
662659 let RENAMINGCOST = 5000000
663660
664661 let MAXNAMELEN = 50
665662
666663 let InfraUpgradeCostSUsdt = 10000000
667664
668665 let EXPMATERIALS = match chain {
669666 case _ =>
670667 if ((base58'2W' == $match0))
671668 then 252289527462
672669 else if ((base58'2T' == $match0))
673670 then 2522895274
674671 else throw("Unknown chain")
675672 }
676673
677674 let EXPUSDT = match chain {
678675 case _ =>
679676 if ((base58'2W' == $match0))
680677 then 250000000
681678 else if ((base58'2T' == $match0))
682679 then 250000000
683680 else throw("Unknown chain")
684681 }
685682
686683 let S_COST_ACRES = 2500000000
687684
688685 let FIVEX = toBigInt(5)
689686
690687 let TWENTYX = toBigInt(20)
691688
692689 let TWENTY2X = toBigInt((20 * 20))
693690
694691 let TWENTY3X = toBigInt(((20 * 20) * 20))
695692
696693 let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
697694
698695 let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
699696
700697 let PRESALENUMLANDS = 500
701698
702699 func keyNextFreeLandNum () = "nextLandNum"
703700
704701
705702 func keyLandCustomNameToAssetId (name) = ("lcn_" + name)
706703
707704
708705 func keyLandToAssetId (landNum) = ("la_" + landNum)
709706
710707
711708 func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("ilao_" + assetId) + "_") + ownerAddr)
712709
713710
714711 func keyLandNumToOwner (landNum) = ("lo_" + landNum)
715712
716713
717714 func keyDuckCustomNameToAssetId (name) = ("duckByCustomName_" + name)
718715
719716
720717 func keyCustomNameToAddress (name) = ("accountByCustomName_" + name)
721718
722719
723720 func keyOldies () = "oldiesList"
724721
725722
726723 let claimModeWh = 0
727724
728725 let claimModeDuck = 1
729726
730727 let claimModeWhThenDuck = 2
731728
732729 let flHealth = 0
733730
734731 let flTimestamp = 5
735732
736733 let flBonus = 6
737734
738735 let flProdsUsed = 7
739736
740737 func nftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
741738
742739
743740 func toVolume (amount,pkgSize) = {
744741 let pkgs = if ((amount >= 0))
745742 then (((amount + pkgSize) - 1) / pkgSize)
746743 else -((((-(amount) + pkgSize) - 1) / pkgSize))
747744 (pkgs * MULT8)
748745 }
749746
750747
751748 func distributeByWeights (total,weights) = {
752749 let sum = (((((weights[0] + weights[1]) + weights[2]) + weights[3]) + weights[4]) + weights[5])
753750 if ((0 >= sum))
754751 then throw("Zero weights sum")
755752 else {
756753 let norm6 = fraction(total, MULT6, sum)
757754 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
758755
759756 let $l = weights
760757 let $s = size($l)
761758 let $acc0 = nil
762759 func $f0_1 ($a,$i) = if (($i >= $s))
763760 then $a
764761 else normalizer($a, $l[$i])
765762
766763 func $f0_2 ($a,$i) = if (($i >= $s))
767764 then $a
768765 else throw("List size exceeds 6")
769766
770767 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
771768 }
772769 }
773770
774771
775772 func getNeededMaterials (total) = {
776773 let props = split(value(getString(keyResProportions())), "_")
777774 if ((size(props) != NUMRES))
778775 then throw("Wrong proportions data")
779776 else {
780777 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
781778 distributeByWeights(total, r)
782779 }
783780 }
784781
785782
786783 func subtractMaterials (shouldUseMat,has,totalNeed) = {
787784 let need = getNeededMaterials(totalNeed)
788785 func subtractor (acc,idx) = {
789786 let result = (parseIntValue(has[idx]) - need[idx])
790787 if ((0 > result))
791788 then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
792789 else (acc :+ toString(result))
793790 }
794791
795792 if (shouldUseMat)
796793 then {
797794 let $l = ITER6
798795 let $s = size($l)
799796 let $acc0 = nil
800797 func $f0_1 ($a,$i) = if (($i >= $s))
801798 then $a
802799 else subtractor($a, $l[$i])
803800
804801 func $f0_2 ($a,$i) = if (($i >= $s))
805802 then $a
806803 else throw("List size exceeds 6")
807804
808805 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
809806 }
810807 else has
811808 }
812809
813810
814811 func subtractEquipment (oldEq,pUsed) = if ((pUsed == ""))
815812 then $Tuple2(oldEq, false)
816813 else {
817814 func subUsed (acc,idxAmt) = {
818815 let parts = split(idxAmt, ",")
819816 if ((size(parts) != 2))
820817 then throw("Incorrect format, should be index,amount")
821818 else {
822819 let idx = parseIntValue(parts[0])
823820 if (if ((0 > idx))
824821 then true
825822 else (idx >= size(productionMatrix)))
826823 then throw("Unknown product idx")
827824 else {
828825 let amt = parseIntValue(parts[1])
829826 let eqParts = split(acc._1, (parts[0] + ":"))
830827 if ((size(eqParts) != 2))
831828 then throw((("You don't have " + prodTypes[idx]) + " equipped"))
832829 else {
833830 let tmp = eqParts[1]
834831 let numLen = if (isDigit(take(drop(tmp, 1), 1)))
835832 then 2
836833 else 1
837834 let curr = parseIntValue(take(tmp, numLen))
838835 let tail = drop(tmp, numLen)
839836 let newAmt = if ((curr >= amt))
840837 then (curr - amt)
841838 else throw(((((("You equipped " + toString(curr)) + " of ") + prodTypes[idx]) + ", but tried to use ") + toString(amt)))
842839 $Tuple2(((((eqParts[0] + parts[0]) + ":") + toString(newAmt)) + tail), if (acc._2)
843840 then true
844841 else if (if ((idx >= 6))
845842 then (8 >= idx)
846843 else false)
847844 then (newAmt == 0)
848845 else false)
849846 }
850847 }
851848 }
852849 }
853850
854851 let $l = split(pUsed, "_")
855852 let $s = size($l)
856853 let $acc0 = $Tuple2(oldEq, false)
857854 func $f0_1 ($a,$i) = if (($i >= $s))
858855 then $a
859856 else subUsed($a, $l[$i])
860857
861858 func $f0_2 ($a,$i) = if (($i >= $s))
862859 then $a
863860 else throw("List size exceeds 10")
864861
865862 $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)
866863 }
867864
868865
869866 func prodStrToBytes (prodStr) = {
870867 let pList = if ((prodStr == ""))
871868 then nil
872869 else split_4C(prodStr, "_")
873870 func toBV (acc,recipe) = {
874871 let j = (size(acc) / 8)
875872 let curr = if ((size(pList) > j))
876873 then parseIntValue(pList[j])
877874 else 0
878875 (acc + toBytes(curr))
879876 }
880877
881878 let $l = productionMatrix
882879 let $s = size($l)
883880 let $acc0 = base58''
884881 func $f0_1 ($a,$i) = if (($i >= $s))
885882 then $a
886883 else toBV($a, $l[$i])
887884
888885 func $f0_2 ($a,$i) = if (($i >= $s))
889886 then $a
890887 else throw("List size exceeds 50")
891888
892889 $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)
893890 }
894891
895892
896893 func bytesToProdStr (bv) = {
897894 func fromBV (acc,recipe) = {
898895 let j = size(acc)
899896 let b = take(drop(bv, (8 * j)), 8)
900897 (acc :+ toString(toInt(b)))
901898 }
902899
903900 makeString_2C({
904901 let $l = productionMatrix
905902 let $s = size($l)
906903 let $acc0 = nil
907904 func $f0_1 ($a,$i) = if (($i >= $s))
908905 then $a
909906 else fromBV($a, $l[$i])
910907
911908 func $f0_2 ($a,$i) = if (($i >= $s))
912909 then $a
913910 else throw("List size exceeds 50")
914911
915912 $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)
916913 }, "_")
917914 }
918915
919916
920917 func checkStatRequirements (duckStats,reqs) = {
921918 func check (acc,j) = {
922919 let buff = if ((size(duckStats) > (7 + j)))
923920 then duckStats[(7 + j)]
924921 else 0
925922 if ((parseIntValue(reqs[j]) > (duckStats[j] + buff)))
926923 then throw(("Requirement not satisfied: " + requirements[j]))
927924 else true
928925 }
929926
930927 let $l = [0, 1, 2, 3, 4, 5, 6]
931928 let $s = size($l)
932929 let $acc0 = false
933930 func $f0_1 ($a,$i) = if (($i >= $s))
934931 then $a
935932 else check($a, $l[$i])
936933
937934 func $f0_2 ($a,$i) = if (($i >= $s))
938935 then $a
939936 else throw("List size exceeds 7")
940937
941938 $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)
942939 }
943940
944941
945942 func placeProdB (idxCnt,pList,isPositive,duckStats,occupied,free) = {
946943 let parts = split(idxCnt, ":")
947944 if ((size(parts) != 2))
948945 then throw("Incorrect format, should be index:amount")
949946 else if (if (!(isPositive))
950947 then (size(parts[0]) != 2)
951948 else false)
952949 then throw("Product idx should be 2 digits, zero padded")
953950 else {
954951 let productIdx = parseIntValue(parts[0])
955952 let count = parseIntValue(parts[1])
956953 if (!(containsElement(fortAllowedProds, productIdx)))
957954 then throw((("Product '" + prodTypes[productIdx]) + "' cannot be used for land defense"))
958955 else if ((0 > count))
959956 then throw("Count can't be negative")
960957 else if ((count > MAXPRODINSLOT))
961958 then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
962959 else if ((count == 0))
963960 then $Tuple3(pList, occupied, free)
964961 else {
965962 let head = take(pList, (8 * productIdx))
966963 let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
967964 let tail = drop(pList, (8 * (productIdx + 1)))
968965 let recipe = split(productionMatrix[productIdx], "_")
969966 if (if (!(isPositive))
970967 then (count > curr)
971968 else false)
972969 then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
973970 else {
974971 let newAmt = if (if (!(isPositive))
975972 then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
976973 else false)
977974 then (curr - count)
978975 else (curr + count)
979976 let deltaVol = (toVolume(newAmt, PRODUCTPKGSIZE) - toVolume(curr, PRODUCTPKGSIZE))
980977 $Tuple3(((head + toBytes(newAmt)) + tail), (occupied + deltaVol), (free - deltaVol))
981978 }
982979 }
983980 }
984981 }
985982
986983
987984 func addProdB (idxCnt,pList,isPositive,segment,mainAux,slot,duckStats) = {
988985 let parts = split(idxCnt, ":")
989986 if ((size(parts) != 2))
990987 then throw("Incorrect format, should be index:amount")
991988 else if (if (!(isPositive))
992989 then (size(parts[0]) != 2)
993990 else false)
994991 then throw("Product idx should be 2 digits, zero padded")
995992 else {
996993 let productIdx = parseIntValue(parts[0])
997994 let count = parseIntValue(parts[1])
998995 if (if ((0 > productIdx))
999996 then true
1000997 else (productIdx >= size(productionMatrix)))
1001998 then throw("Unknown product idx")
1002999 else if ((0 > count))
10031000 then throw("Count can't be negative")
10041001 else if ((count > MAXPRODINSLOT))
10051002 then throw(((("Can't put more than " + toString(MAXPRODINSLOT)) + " of ") + prodTypes[productIdx]))
10061003 else if ((count == 0))
10071004 then $Tuple2(pList, false)
10081005 else {
10091006 let head = take(pList, (8 * productIdx))
10101007 let curr = toInt(take(drop(pList, (8 * productIdx)), 8))
10111008 let tail = drop(pList, (8 * (productIdx + 1)))
10121009 let recipe = split(productionMatrix[productIdx], "_")
10131010 if (if (!(isPositive))
10141011 then (count > curr)
10151012 else false)
10161013 then throw(((((("You have " + toString(curr)) + " of ") + prodTypes[productIdx]) + ", but tried to use ") + toString(count)))
10171014 else {
10181015 let isBigItem = if (if (!(isPositive))
10191016 then checkStatRequirements(duckStats, split(recipe[rIdxRequirements], ","))
10201017 else false)
10211018 then {
10221019 let compat = recipe[rIdxSlots]
10231020 if ((compat == ""))
10241021 then throw("Item cannot be equipped")
10251022 else {
10261023 let c = parseIntValue(compat)
10271024 let cSeg = (c / 100)
10281025 if ((segment != cSeg))
10291026 then throw("Segment incompatible")
10301027 else {
10311028 let cMainAux = ((c % 100) / 10)
10321029 if ((mainAux != cMainAux))
10331030 then throw("Slot incompatible")
10341031 else {
10351032 let cNumSlots = (c % 10)
10361033 if (if ((slot != 0))
10371034 then (cNumSlots > 1)
10381035 else false)
10391036 then throw("Big items should occupy slot 0")
10401037 else (cNumSlots > 1)
10411038 }
10421039 }
10431040 }
10441041 }
10451042 else false
10461043 $Tuple2(((head + toBytes((curr + (if (isPositive)
10471044 then count
10481045 else -(count))))) + tail), isBigItem)
10491046 }
10501047 }
10511048 }
10521049 }
10531050
10541051
10551052 func slotsGroupB (g,bpIn,isPositive,segment,mainAux,stats) = if ((g != ""))
10561053 then {
10571054 let slots = split(g, ",")
10581055 if ((size(slots) > MAXSLOTS))
10591056 then throw("Wrong slots format")
10601057 else {
10611058 let s0 = slots[0]
10621059 let s1 = if ((size(slots) > 1))
10631060 then slots[1]
10641061 else ""
10651062 if (if ((s0 == ""))
10661063 then (s1 == "")
10671064 else false)
10681065 then bpIn
10691066 else {
10701067 let tmpS0 = if ((s0 != ""))
10711068 then addProdB(s0, bpIn, isPositive, segment, mainAux, 0, stats)
10721069 else $Tuple2(bpIn, false)
10731070 if ((s1 != ""))
10741071 then if (tmpS0._2)
10751072 then throw("Big item already occupies slot")
10761073 else addProdB(s1, tmpS0._1, isPositive, segment, mainAux, 1, stats)._1
10771074 else tmpS0._1
10781075 }
10791076 }
10801077 }
10811078 else bpIn
10821079
10831080
10841081 func dressB (segList,pBytes,isPositive,stats) = {
10851082 func segment (acc,seg) = {
10861083 let j = acc._1
10871084 let mainAux = split(seg, ";")
10881085 if ((size(mainAux) != NUMMAINAUX))
10891086 then throw("Wrong segment format")
10901087 else {
10911088 let m = mainAux[0]
10921089 let a = mainAux[1]
10931090 if (if ((m == ""))
10941091 then (a == "")
10951092 else false)
10961093 then $Tuple2((j + 1), acc._2)
10971094 else {
10981095 let tmpM = slotsGroupB(m, acc._2, isPositive, j, 0, stats)
10991096 $Tuple2((j + 1), slotsGroupB(a, tmpM, isPositive, j, 1, stats))
11001097 }
11011098 }
11021099 }
11031100
11041101 ( let $l = segList
11051102 let $s = size($l)
11061103 let $acc0 = $Tuple2(0, pBytes)
11071104 func $f0_1 ($a,$i) = if (($i >= $s))
11081105 then $a
11091106 else segment($a, $l[$i])
11101107
11111108 func $f0_2 ($a,$i) = if (($i >= $s))
11121109 then $a
11131110 else throw("List size exceeds 6")
11141111
11151112 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6))._2
11161113 }
11171114
11181115
11191116 func fortB (segList,pBytes,occupied,free,isPositive,duckStats) = if ((3 > size(segList)))
11201117 then throw("At least duck, mines and traps parts are required")
11211118 else {
11221119 func segment (acc,seg) = {
11231120 let j = acc._1
11241121 if ((j == 0))
11251122 then $Tuple4((j + 1), acc._2, acc._3, acc._4)
11261123 else {
11271124 let p = placeProdB(seg, acc._2, isPositive, duckStats, acc._3, acc._4)
11281125 $Tuple4((j + 1), p._1, p._2, p._3)
11291126 }
11301127 }
11311128
11321129 let t = {
11331130 let $l = segList
11341131 let $s = size($l)
11351132 let $acc0 = $Tuple4(0, pBytes, occupied, free)
11361133 func $f0_1 ($a,$i) = if (($i >= $s))
11371134 then $a
11381135 else segment($a, $l[$i])
11391136
11401137 func $f0_2 ($a,$i) = if (($i >= $s))
11411138 then $a
11421139 else throw("List size exceeds 10")
11431140
11441141 $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)
11451142 }
11461143 $Tuple3(t._2, t._3, t._4)
11471144 }
11481145
11491146
11501147 func canWearCurrentEquipment (duckAssetId) = {
11511148 let eqKey = keyDuckEquipment(duckAssetId)
11521149 let currEq = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
11531150 let tempProdB = dressB(currEq, EMPTY_PROD50, true, nil)
11541151 let segBpAux = split(currEq[segBackpack], ";")[1]
11551152 let buffEffect = if ((segBpAux == ""))
11561153 then 0
11571154 else {
11581155 let aux0 = split(segBpAux, ",")[0]
11591156 if ((aux0 == ""))
11601157 then 0
11611158 else {
11621159 let idxCnt = split(aux0, ":")
11631160 let idx = idxCnt[0]
11641161 let cnt = idxCnt[1]
11651162 if (if (if (if (if ((idx == "06"))
11661163 then true
11671164 else (idx == "07"))
11681165 then true
11691166 else (idx == "08"))
11701167 then (cnt != "")
11711168 else false)
11721169 then (parseIntValue(cnt) > 0)
11731170 else false)
11741171 then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
11751172 else 0
11761173 }
11771174 }
11781175 let stats = getDuckStats(this, duckAssetId, buffEffect, true)
11791176 let newProdB = dressB(currEq, tempProdB, false, stats)
11801177 (newProdB == newProdB)
11811178 }
11821179
11831180
11841181 func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
11851182 then throw("Wrong proportions data")
11861183 else {
11871184 func updater (acc,i) = {
11881185 let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
11891186 if ((0 > result))
11901187 then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
11911188 else (acc :+ toString(result))
11921189 }
11931190
11941191 let $l = ITER6
11951192 let $s = size($l)
11961193 let $acc0 = nil
11971194 func $f0_1 ($a,$i) = if (($i >= $s))
11981195 then $a
11991196 else updater($a, $l[$i])
12001197
12011198 func $f0_2 ($a,$i) = if (($i >= $s))
12021199 then $a
12031200 else throw("List size exceeds 6")
12041201
12051202 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12061203 }
12071204
12081205
12091206 func updateProportions (terrainCounts,landSizeIndex,sign) = {
12101207 let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
12111208 makeString(updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign), "_")
12121209 }
12131210
12141211
12151212 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)]
12161213
12171214
12181215 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
12191216 func adder (acc,i) = {
12201217 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
12211218 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
12221219 }
12231220
12241221 let r = {
12251222 let $l = ITER6
12261223 let $s = size($l)
12271224 let $acc0 = nil
12281225 func $f0_1 ($a,$i) = if (($i >= $s))
12291226 then $a
12301227 else adder($a, $l[$i])
12311228
12321229 func $f0_2 ($a,$i) = if (($i >= $s))
12331230 then $a
12341231 else throw("List size exceeds 6")
12351232
12361233 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12371234 }
12381235 makeString(r, "_")
12391236 }
12401237
12411238
12421239 func virtClaim (terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
12431240 func adder (acc,i) = {
12441241 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
12451242 $Tuple2((acc._1 :+ resOfType), (acc._2 + resOfType))
12461243 }
12471244
12481245 let $l = ITER6
12491246 let $s = size($l)
12501247 let $acc0 = $Tuple2(nil, 0)
12511248 func $f0_1 ($a,$i) = if (($i >= $s))
12521249 then $a
12531250 else adder($a, $l[$i])
12541251
12551252 func $f0_2 ($a,$i) = if (($i >= $s))
12561253 then $a
12571254 else throw("List size exceeds 6")
12581255
12591256 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12601257 }
12611258
12621259
12631260 func distributeRes (currentWhRes,currentPackRes,resToClaim,whSpaceLeft) = {
12641261 let resListToClaim = resToClaim._1
12651262 let resAmToClaim = resToClaim._2
12661263 if ((resAmToClaim == 0))
12671264 then $Tuple2(makeString(currentWhRes, "_"), makeString(currentPackRes, "_"))
12681265 else if ((whSpaceLeft >= resAmToClaim))
12691266 then {
12701267 func addLists (acc,i) = (acc :+ toString((parseIntValue(currentWhRes[i]) + resListToClaim[i])))
12711268
12721269 let r = {
12731270 let $l = ITER6
12741271 let $s = size($l)
12751272 let $acc0 = nil
12761273 func $f0_1 ($a,$i) = if (($i >= $s))
12771274 then $a
12781275 else addLists($a, $l[$i])
12791276
12801277 func $f0_2 ($a,$i) = if (($i >= $s))
12811278 then $a
12821279 else throw("List size exceeds 6")
12831280
12841281 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
12851282 }
12861283 $Tuple2(makeString(r, "_"), makeString(currentPackRes, "_"))
12871284 }
12881285 else {
12891286 func addPartLists (acc,i) = {
12901287 let whPart = fraction(resListToClaim[i], whSpaceLeft, resAmToClaim)
12911288 $Tuple2((acc._1 :+ toString((parseIntValue(currentWhRes[i]) + whPart))), (acc._2 :+ toString(((parseIntValue(currentPackRes[i]) + resListToClaim[i]) - whPart))))
12921289 }
12931290
12941291 let r = {
12951292 let $l = ITER6
12961293 let $s = size($l)
12971294 let $acc0 = $Tuple2(nil, nil)
12981295 func $f0_1 ($a,$i) = if (($i >= $s))
12991296 then $a
13001297 else addPartLists($a, $l[$i])
13011298
13021299 func $f0_2 ($a,$i) = if (($i >= $s))
13031300 then $a
13041301 else throw("List size exceeds 6")
13051302
13061303 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
13071304 }
13081305 $Tuple2(makeString(r._1, "_"), makeString(r._2, "_"))
13091306 }
13101307 }
13111308
13121309
13131310 func abs (x) = if ((x >= toBigInt(0)))
13141311 then x
13151312 else -(x)
13161313
13171314
13181315 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]]
13191316
13201317 func genChar (n,freqs) = {
13211318 let rem = toInt((n % TWENTYX))
13221319 let letter = if ((freqs[0] > rem))
13231320 then "A"
13241321 else if ((freqs[1] > rem))
13251322 then "B"
13261323 else if ((freqs[2] > rem))
13271324 then "C"
13281325 else if ((freqs[3] > rem))
13291326 then "D"
13301327 else if ((freqs[4] > rem))
13311328 then "E"
13321329 else "F"
13331330 letter
13341331 }
13351332
13361333
13371334 func genTerrains (seed,continentIdx) = {
13381335 let f = freq[continentIdx]
13391336 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))
13401337
13411338 let t = {
13421339 let $l = [1, 2, 3, 4, 5]
13431340 let $s = size($l)
13441341 let $acc0 = $Tuple2("", (seed / FIVEX))
13451342 func $f0_1 ($a,$i) = if (($i >= $s))
13461343 then $a
13471344 else terrainGenerator($a, $l[$i])
13481345
13491346 func $f0_2 ($a,$i) = if (($i >= $s))
13501347 then $a
13511348 else throw("List size exceeds 5")
13521349
13531350 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
13541351 }
13551352 t._1
13561353 }
13571354
13581355
13591356 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]
13601357
13611358 let TCHARS = ["A", "B", "C", "D", "E", "F"]
13621359
13631360 func genTerrainsForMerge (sumTerrains,landSizeIndex) = {
13641361 func step1 (acc,s) = {
13651362 let j = acc._2
13661363 let el = parseIntValue(s)
13671364 let x = if ((el == 0))
13681365 then 0
13691366 else if ((el >= (4 * landSizeIndex)))
13701367 then (el / landSizeIndex)
13711368 else if ((el > (3 * landSizeIndex)))
13721369 then 3
13731370 else (((el - 1) / landSizeIndex) + 1)
13741371 $Tuple3((acc._1 :+ x), (acc._2 + 1), (acc._3 + x))
13751372 }
13761373
13771374 let t = {
13781375 let $l = sumTerrains
13791376 let $s = size($l)
13801377 let $acc0 = $Tuple3(nil, 0, 0)
13811378 func $f0_1 ($a,$i) = if (($i >= $s))
13821379 then $a
13831380 else step1($a, $l[$i])
13841381
13851382 func $f0_2 ($a,$i) = if (($i >= $s))
13861383 then $a
13871384 else throw("List size exceeds 6")
13881385
13891386 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
13901387 }
13911388 let arr = t._1
13921389 let maxIdx = value(indexOf(arr, max(arr)))
13931390 let delta = (t._3 - 25)
13941391 func subber (acc,idx) = {
13951392 let val = if ((idx == maxIdx))
13961393 then (arr[idx] - delta)
13971394 else arr[idx]
13981395 let zeroes = if ((val == 0))
13991396 then nil
14001397 else split(drop(toString(pow(10, 0, val, 0, 0, DOWN)), 1), "")
14011398 let c = TCHARS[idx]
14021399 func listGen (ac,ignored) = (ac :+ c)
14031400
14041401 let z = {
14051402 let $l = zeroes
14061403 let $s = size($l)
14071404 let $acc0 = nil
14081405 func $f1_1 ($a,$i) = if (($i >= $s))
14091406 then $a
14101407 else listGen($a, $l[$i])
14111408
14121409 func $f1_2 ($a,$i) = if (($i >= $s))
14131410 then $a
14141411 else throw("List size exceeds 25")
14151412
14161413 $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)
14171414 }
14181415 (acc ++ z)
14191416 }
14201417
14211418 let r = {
14221419 let $l = ITER6
14231420 let $s = size($l)
14241421 let $acc0 = nil
14251422 func $f1_1 ($a,$i) = if (($i >= $s))
14261423 then $a
14271424 else subber($a, $l[$i])
14281425
14291426 func $f1_2 ($a,$i) = if (($i >= $s))
14301427 then $a
14311428 else throw("List size exceeds 6")
14321429
14331430 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
14341431 }
14351432 func permut (acc,j) = (acc + r[j])
14361433
14371434 let $l = PERM25
14381435 let $s = size($l)
14391436 let $acc0 = ""
14401437 func $f2_1 ($a,$i) = if (($i >= $s))
14411438 then $a
14421439 else permut($a, $l[$i])
14431440
14441441 func $f2_2 ($a,$i) = if (($i >= $s))
14451442 then $a
14461443 else throw("List size exceeds 25")
14471444
14481445 $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)
14491446 }
14501447
14511448
14521449 func getBackpack (bpKey) = {
14531450 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
14541451 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
14551452 then p[bpIdxRes]
14561453 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
14571454 then p[bpIdxMat]
14581455 else "0_0_0_0_0_0", p[bpIdxProd]]
14591456 }
14601457
14611458
14621459 func getWarehouseTotalVolume (volPrefix) = {
14631460 let parts = split(volPrefix, "_")
14641461 ((WHMULTIPLIER * (parseIntValue(parts[1]) + 1)) * parseIntValue(parts[0]))
14651462 }
14661463
14671464
14681465 func getWarehouseOccupiedVol (currentWh) = {
14691466 let goods = currentWh[whIdxProd]
14701467 func sumResMat (acc,item) = (acc + parseIntValue(item))
14711468
14721469 func sumProd (acc,item) = {
14731470 let idx = acc._1
14741471 let pkgs = (((parseIntValue(item) + PRODUCTPKGSIZE) - 1) / PRODUCTPKGSIZE)
14751472 $Tuple2((idx + 1), (acc._2 + (pkgs * MULT8)))
14761473 }
14771474
14781475 let whResVol = {
14791476 let $l = split(currentWh[whIdxRes], "_")
14801477 let $s = size($l)
14811478 let $acc0 = 0
14821479 func $f0_1 ($a,$i) = if (($i >= $s))
14831480 then $a
14841481 else sumResMat($a, $l[$i])
14851482
14861483 func $f0_2 ($a,$i) = if (($i >= $s))
14871484 then $a
14881485 else throw("List size exceeds 6")
14891486
14901487 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
14911488 }
14921489 let whMatVol = {
14931490 let $l = split(currentWh[whIdxMat], "_")
14941491 let $s = size($l)
14951492 let $acc0 = 0
14961493 func $f1_1 ($a,$i) = if (($i >= $s))
14971494 then $a
14981495 else sumResMat($a, $l[$i])
14991496
15001497 func $f1_2 ($a,$i) = if (($i >= $s))
15011498 then $a
15021499 else throw("List size exceeds 6")
15031500
15041501 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
15051502 }
15061503 let whGoodsVol = if ((goods == ""))
15071504 then 0
15081505 else ( let $l = split_4C(goods, "_")
15091506 let $s = size($l)
15101507 let $acc0 = $Tuple2(0, 0)
15111508 func $f2_1 ($a,$i) = if (($i >= $s))
15121509 then $a
15131510 else sumProd($a, $l[$i])
15141511
15151512 func $f2_2 ($a,$i) = if (($i >= $s))
15161513 then $a
15171514 else throw("List size exceeds 50")
15181515
15191516 $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
15201517 ((whResVol + whMatVol) + whGoodsVol)
15211518 }
15221519
15231520
15241521 func getWarehouse (whKey,landIndex,infraLevel) = {
15251522 let volPrefix = ((toString(landIndex) + "_") + toString(infraLevel))
15261523 let whTotal = getWarehouseTotalVolume(volPrefix)
15271524 let whStr = valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0::0"))
15281525 let wh = split_4C(whStr, ":")
15291526 let whOccupied = getWarehouseOccupiedVol(wh)
15301527 let whLoft = if ((5 > size(wh)))
15311528 then makeString(["0", toString(whOccupied), toString((whTotal - whOccupied)), toString(whTotal)], "_")
15321529 else {
15331530 let loft = split(wh[whIdxLOFT], "_")
15341531 let whLocked = parseIntValue(loft[volLocked])
15351532 let occ = if ((size(loft) > 1))
15361533 then parseIntValue(loft[volOccupied])
15371534 else whOccupied
15381535 makeString([toString(whLocked), toString(occ), toString(((whTotal - whLocked) - occ)), toString(whTotal)], "_")
15391536 }
15401537 [wh[whIdxLevels], if ((size(split(wh[whIdxRes], "_")) == NUMRES))
15411538 then wh[whIdxRes]
15421539 else "0_0_0_0_0_0", if ((size(split(wh[whIdxMat], "_")) == NUMRES))
15431540 then wh[whIdxMat]
15441541 else "0_0_0_0_0_0", wh[whIdxProd], whLoft]
15451542 }
15461543
15471544
15481545 func getWarehouseSpaceLeft (currentWh) = {
15491546 let occupiedVol = getWarehouseOccupiedVol(currentWh)
15501547 let currWhLockedVol = parseIntValue(split(currentWh[whIdxLOFT], "_")[volLocked])
15511548 ((getWarehouseTotalVolume(currentWh[whIdxLevels]) - occupiedVol) - currWhLockedVol)
15521549 }
15531550
15541551
15551552 func moveStuff (cargoParts,currentWh,currentPack) = if ((size(cargoParts) != 3))
15561553 then throw("cargoListStr should contain exactly 2 ':' separators")
15571554 else {
15581555 let resParts = split(cargoParts[0], "_")
15591556 let matParts = split(cargoParts[1], "_")
15601557 let prodParts = if ((cargoParts[2] == ""))
15611558 then nil
15621559 else split_4C(cargoParts[2], "_")
15631560 if ((size(resParts) != NUMRES))
15641561 then throw("All 6 resources should be passed")
15651562 else if ((size(matParts) != NUMRES))
15661563 then throw("All 6 materials should be passed")
15671564 else {
15681565 let whSpaceLeft = getWarehouseSpaceLeft(currentWh)
15691566 let currWhRes = split(currentWh[whIdxRes], "_")
15701567 let currWhMat = split(currentWh[whIdxMat], "_")
15711568 let currWhProd = if ((currentWh[whIdxProd] == ""))
15721569 then nil
15731570 else split_4C(currentWh[whIdxProd], "_")
15741571 let currentPackRes = split(currentPack[bpIdxRes], "_")
15751572 let currentPackMat = split(currentPack[bpIdxMat], "_")
15761573 let currentPackProd = if ((currentPack[bpIdxProd] == ""))
15771574 then nil
15781575 else split_4C(currentPack[bpIdxProd], "_")
15791576 func mvR (acc,item) = {
15801577 let i = acc._1
15811578 let am = parseIntValue(item)
15821579 let whr = parseIntValue(currWhRes[i])
15831580 let bpr = parseIntValue(currentPackRes[i])
15841581 if ((am == 0))
15851582 then $Tuple4((i + 1), (acc._2 :+ currWhRes[i]), (acc._3 :+ currentPackRes[i]), acc._4)
15861583 else if ((am > 0))
15871584 then if ((am > bpr))
15881585 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpr)) + " available"))
15891586 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
15901587 else if ((-(am) > whr))
15911588 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whr)) + " available"))
15921589 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
15931590 }
15941591
15951592 let r = {
15961593 let $l = resParts
15971594 let $s = size($l)
15981595 let $acc0 = $Tuple4(0, nil, nil, 0)
15991596 func $f0_1 ($a,$i) = if (($i >= $s))
16001597 then $a
16011598 else mvR($a, $l[$i])
16021599
16031600 func $f0_2 ($a,$i) = if (($i >= $s))
16041601 then $a
16051602 else throw("List size exceeds 6")
16061603
16071604 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
16081605 }
16091606 func mvM (acc,item) = {
16101607 let i = acc._1
16111608 let am = parseIntValue(item)
16121609 let whm = parseIntValue(currWhMat[i])
16131610 let bpm = parseIntValue(currentPackMat[i])
16141611 if ((am == 0))
16151612 then $Tuple4((i + 1), (acc._2 :+ currWhMat[i]), (acc._3 :+ currentPackMat[i]), acc._4)
16161613 else if ((am > 0))
16171614 then if ((am > bpm))
16181615 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpm)) + " available"))
16191616 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
16201617 else if ((-(am) > whm))
16211618 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whm)) + " available"))
16221619 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
16231620 }
16241621
16251622 let m = {
16261623 let $l = matParts
16271624 let $s = size($l)
16281625 let $acc0 = $Tuple4(0, nil, nil, r._4)
16291626 func $f1_1 ($a,$i) = if (($i >= $s))
16301627 then $a
16311628 else mvM($a, $l[$i])
16321629
16331630 func $f1_2 ($a,$i) = if (($i >= $s))
16341631 then $a
16351632 else throw("List size exceeds 6")
16361633
16371634 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
16381635 }
16391636 func mvP (acc,item) = {
16401637 let i = acc._1
16411638 let am = parseIntValue(item)
16421639 let whp = if ((size(currWhProd) > i))
16431640 then parseIntValue(currWhProd[i])
16441641 else 0
16451642 let bpp = if ((size(currentPackProd) > i))
16461643 then parseIntValue(currentPackProd[i])
16471644 else 0
16481645 if ((am == 0))
16491646 then $Tuple4((i + 1), (acc._2 :+ toString(whp)), (acc._3 :+ toString(bpp)), acc._4)
16501647 else if ((am > 0))
16511648 then if ((am > bpp))
16521649 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpp)) + " available"))
16531650 else {
16541651 let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
16551652 $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
16561653 }
16571654 else if ((-(am) > whp))
16581655 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whp)) + " available"))
16591656 else {
16601657 let deltaVol = (toVolume((whp + am), PRODUCTPKGSIZE) - toVolume(whp, PRODUCTPKGSIZE))
16611658 $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + deltaVol))
16621659 }
16631660 }
16641661
16651662 let p = if ((size(prodParts) != 0))
16661663 then {
16671664 let $l = prodParts
16681665 let $s = size($l)
16691666 let $acc0 = $Tuple4(0, nil, nil, m._4)
16701667 func $f2_1 ($a,$i) = if (($i >= $s))
16711668 then $a
16721669 else mvP($a, $l[$i])
16731670
16741671 func $f2_2 ($a,$i) = if (($i >= $s))
16751672 then $a
16761673 else throw("List size exceeds 50")
16771674
16781675 $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)
16791676 }
16801677 else $Tuple4(0, currWhProd, currentPackProd, m._4)
16811678 let volSaldo = p._4
16821679 if ((volSaldo > whSpaceLeft))
16831680 then throw((((("Attempt to put total " + toString(volSaldo)) + " stuff, but only ") + toString(whSpaceLeft)) + " warehouse space left"))
16841681 else $Tuple7(makeString(r._2, "_"), makeString(m._2, "_"), makeString_2C(p._2, "_"), makeString(r._3, "_"), makeString(m._3, "_"), makeString_2C(p._3, "_"), volSaldo)
16851682 }
16861683 }
16871684
16881685
16891686 func expeditionInternal (caller,txId) = {
16901687 let userAddr = toString(caller)
16911688 let bigNum = abs(toBigInt(txId))
16921689 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
16931690 let landNum = toString(freeNum)
16941691 let continentIdx = toInt((bigNum % FIVEX))
16951692 let terrains = genTerrains(bigNum, continentIdx)
16961693 let continent = continents[continentIdx]
16971694 let issue = Issue(nftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
16981695 let assetId = calculateAssetId(issue)
16991696 let id = toBase58String(assetId)
17001697 $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))
17011698 }
17021699
17031700
17041701 func flightCommon (userAddr,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
17051702 then throw("signature does not match")
17061703 else {
17071704 let parts = split_4C(toUtf8String(message), ";")
17081705 let flightLog = split_4C(parts[0], "|")
17091706 let hp = split(flightLog[flHealth], "_")
17101707 let curHP = parseIntValue(hp[0])
17111708 let newHP = parseIntValue(hp[1])
17121709 let newLocTxVer = split(parts[1], ":")
17131710 let newLocation = newLocTxVer[0]
17141711 let time = parseIntValue(flightLog[flTimestamp])
17151712 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
17161713 then true
17171714 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
17181715 then throw(((("signature outdated: logTime=" + toString(time)) + ", bcTime=") + toString(lastBlock.timestamp)))
17191716 else {
17201717 let txFromMsg = newLocTxVer[1]
17211718 let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
17221719 if ((lastTx != txFromMsg))
17231720 then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
17241721 else {
17251722 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
17261723 let keyHealth = keyDuckHealth(duckAssetId)
17271724 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
17281725 let oldFromState = valueOrElse(getInteger(keyHealth), maxHP)
17291726 if ((oldFromState != curHP))
17301727 then throw(((("oldHealth=" + toString(oldFromState)) + " from state does not match one from flight log=") + toString(curHP)))
17311728 else if ((0 >= curHP))
17321729 then throw("You can't fly with zero health")
17331730 else if (!(canWearCurrentEquipment(duckAssetId)))
17341731 then throw("Equipment incompatible")
17351732 else {
17361733 let bonus = if ((size(flightLog) > flBonus))
17371734 then flightLog[flBonus]
17381735 else ""
17391736 let prodUsed = if ((size(flightLog) > flProdsUsed))
17401737 then flightLog[flProdsUsed]
17411738 else ""
17421739 let sentAmount = if (if ((newHP > 0))
17431740 then (bonus == "$")
17441741 else false)
17451742 then asInt(invoke(restContract, "sendUsdtPrize", [userAddr], nil))
17461743 else 0
17471744 $Tuple5(newHP, duckAssetId, sentAmount, newLocation, prodUsed)
17481745 }
17491746 }
17501747 }
17511748 }
17521749
17531750
17541751 func applyBonuses (landAssetId,pieces) = {
17551752 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
17561753 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0)
17571754 let add6 = (infraLevel / 6)
17581755 let add7 = (infraLevel / 7)
17591756 ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, ((infraLevel + add6) + (2 * add7)), 5)) + fraction(DAILYRESBYPIECE, artPieces, (pieces * 5)))
17601757 }
17611758
17621759
17631760 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
17641761 let $t03373834277 = if ((claimMode == claimModeWh))
17651762 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
17661763 else {
17671764 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
17681765 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
17691766 let loc = split(value(curLocation), "_")
17701767 if ((loc[locIdxType] != "L"))
17711768 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
17721769 else $Tuple2(loc[locIdxId], duckAssetId)
17731770 }
17741771 let landAssetId = $t03373834277._1
17751772 let duckId = $t03373834277._2
17761773 let asset = value(assetInfo(fromBase58String(landAssetId)))
17771774 let timeKey = keyStakedTimeByAssetId(landAssetId)
17781775 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
17791776 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
17801777 if ((owner != addr))
17811778 then throw((LANDPREFIX + " is not yours"))
17821779 else {
17831780 let d = split(asset.description, "_")
17841781 $Tuple4(duckId, landAssetId, d, savedTime)
17851782 }
17861783 }
17871784
17881785
17891786 func claimResInternal (addr,amount,claimMode,landAssetIdIn) = if ((0 > amount))
17901787 then throw("Negative amount")
17911788 else {
17921789 let c = checkClaimConditions(addr, claimMode, landAssetIdIn)
17931790 let landSize = c._3[recLandSize]
17941791 let terrainCounts = countTerrains(c._3[recTerrains])
17951792 let deltaTime = (lastBlock.timestamp - c._4)
17961793 if ((0 > deltaTime))
17971794 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", current = ") + toString(lastBlock.timestamp)))
17981795 else {
17991796 let pieces = numPiecesBySize(landSize)
18001797 let dailyProductionByPiece = applyBonuses(c._2, pieces)
18011798 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
18021799 if ((amount > availRes))
18031800 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
18041801 else {
18051802 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
18061803 let newTimestamp = (lastBlock.timestamp - newDeltaTime)
18071804 let landIndex = (pieces / SSIZE)
18081805 let resToClaim = virtClaim(terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece)
18091806 let whKey = keyWarehouseByLand(c._2)
18101807 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(c._2)), 0)
18111808 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
18121809 let loft = split(currentWh[whIdxLOFT], "_")
18131810 let whSpaceLeft = parseIntValue(loft[volFree])
18141811 if (if ((claimMode == claimModeWh))
18151812 then (amount > whSpaceLeft)
18161813 else false)
18171814 then throw((("Only " + toString(whSpaceLeft)) + " space left in warehouse"))
18181815 else {
18191816 let bpKey = keyBackpackByDuck(c._1)
18201817 let currentPack = getBackpack(bpKey)
18211818 let currentPackRes = split(currentPack[bpIdxRes], "_")
18221819 let currentWhRes = split(currentWh[whIdxRes], "_")
18231820 let $t03665137522 = if ((claimMode == claimModeWh))
18241821 then $Tuple4(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes], (parseIntValue(loft[volOccupied]) + resToClaim._2), (parseIntValue(loft[volFree]) - resToClaim._2))
18251822 else if ((claimMode == claimModeDuck))
18261823 then $Tuple4(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), parseIntValue(loft[volOccupied]), parseIntValue(loft[volFree]))
18271824 else {
18281825 let distr = distributeRes(currentWhRes, currentPackRes, resToClaim, whSpaceLeft)
18291826 let whAm = min([parseIntValue(loft[volFree]), resToClaim._2])
18301827 $Tuple4(distr._1, distr._2, (parseIntValue(loft[volOccupied]) + whAm), (parseIntValue(loft[volFree]) - whAm))
18311828 }
18321829 let whRes = $t03665137522._1
18331830 let bpRes = $t03665137522._2
18341831 let loftO = $t03665137522._3
18351832 let loftF = $t03665137522._4
18361833 $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]], "_")])
18371834 }
18381835 }
18391836 }
18401837 }
18411838
18421839
18431840 func claimAll (addr,landAssetId,pieces,claimMode) = {
18441841 let timeKey = keyStakedTimeByAssetId(landAssetId)
18451842 let savedTime = value(getInteger(timeKey))
18461843 let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
18471844 claimResInternal(addr, availRes, claimMode, landAssetId)
18481845 }
18491846
18501847
18511848 func upInfraCommon (shouldUseMat,caller,paymentAmount,landAssetId) = {
18521849 let addr = toString(caller)
18531850 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetId)
18541851 let pieces = numPiecesBySize(c._3[recLandSize])
18551852 let infraKey = keyInfraLevelByAssetId(c._2)
18561853 let curLevel = valueOrElse(getInteger(infraKey), 0)
18571854 if (if (!(KS_ALLOW_BIG_INFRA_MERGE))
18581855 then (curLevel >= 3)
18591856 else false)
18601857 then throw("Currently max infrastructure level = 3")
18611858 else {
18621859 let maxInfra = ((sqrt(pieces, 0, 0, DOWN) / 5) + 2)
18631860 let newLevel = (curLevel + 1)
18641861 if (if (KS_ALLOW_BIG_INFRA_MERGE)
18651862 then (newLevel > maxInfra)
18661863 else false)
18671864 then throw(("Currently max infrastructure level = " + toString(maxInfra)))
18681865 else {
18691866 let cost = fraction(InfraUpgradeCostSUsdt, (pieces * newLevel), SSIZE)
18701867 if (if (!(shouldUseMat))
18711868 then (paymentAmount != cost)
18721869 else false)
18731870 then throw(("Payment attached should be " + toString(cost)))
18741871 else {
18751872 let bpKey = keyBackpackByDuck(c._1)
18761873 let currentPack = getBackpack(bpKey)
18771874 let mList = split(currentPack[bpIdxMat], "_")
18781875 let matUsed = fraction(InfraUpgradeCostS, (pieces * newLevel), SSIZE)
18791876 let newMat = makeString(subtractMaterials(shouldUseMat, mList, matUsed), "_")
18801877 let claimResult = claimAll(addr, c._2, pieces, claimModeWhThenDuck)
18811878 let whData = claimResult._5
18821879 let oldVol = getWarehouseTotalVolume(whData[whIdxLevels])
18831880 let newVolData = makeString([split(whData[whIdxLevels], "_")[0], toString(newLevel)], "_")
18841881 let newVol = getWarehouseTotalVolume(newVolData)
18851882 let loft = split(whData[whIdxLOFT], "_")
18861883 let newLoftStr = makeString([loft[volLocked], loft[volOccupied], toString(((parseIntValue(loft[volFree]) + newVol) - oldVol)), toString(newVol)], "_")
18871884 $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)
18881885 }
18891886 }
18901887 }
18911888 }
18921889
18931890
1894-func updateDuckStatsInternal (duckAssetId,deltaXP) = {
1895- let lvlKey = keyDuckLevel(duckAssetId)
1896- let xpKey = keyDuckXP(duckAssetId)
1891+func updateStatsInternal (lvlKey,xpKey,pointsKey,deltaXP) = {
18971892 let xp = valueOrElse(getInteger(xpKey), 0)
18981893 let newXP = (xp + deltaXP)
18991894 let lvlPoints = levelUp(valueOrElse(getInteger(lvlKey), 0), newXP)
1900- let keyPoints = keyDuckFreePoints(duckAssetId)
1901- $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(keyPoints, (valueOrElse(getInteger(keyPoints), 0) + lvlPoints[1]))], newXP)
1902- }
1903-
1904-
1905-func updateAccStatsInternal (addr,deltaXP) = {
1906- let lvlKey = keyUserLevel(addr)
1907- let xpKey = keyUserXP(addr)
1908- let xp = valueOrElse(getInteger(xpKey), 0)
1909- let newXP = (xp + deltaXP)
1910- let lvlPoints = levelUp(valueOrElse(getInteger(lvlKey), 0), newXP)
1911- let keyPoints = keyUserFreePoints(addr)
1912- $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(keyPoints, (valueOrElse(getInteger(keyPoints), 0) + lvlPoints[1]))], newXP)
1913- }
1895+ $Tuple2([IntegerEntry(lvlKey, lvlPoints[0]), IntegerEntry(xpKey, newXP), IntegerEntry(pointsKey, (valueOrElse(getInteger(pointsKey), 0) + lvlPoints[1]))], newXP)
1896+ }
1897+
1898+
1899+func updateDuckStatsInternal (duckAssetId,deltaXP) = updateStatsInternal(keyDuckLevel(duckAssetId), keyDuckXP(duckAssetId), keyDuckFreePoints(duckAssetId), deltaXP)
1900+
1901+
1902+func updateAccStatsInternal (addr,deltaXP) = updateStatsInternal(keyUserLevel(addr), keyUserXP(addr), keyUserFreePoints(addr), deltaXP)
19141903
19151904
19161905 func activateOnboardArt (addr) = {
19171906 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
19181907 let refByKey = keyAddressRefBy(addr)
19191908 let refBy = getString(refByKey)
19201909 if (!(isDefined(refBy)))
19211910 then throw("You are not eligible for ONBOARD artifact")
19221911 else {
19231912 let artKey = keyOnboardArtDuckActivatedBy(addr)
19241913 let artDuck = getString(artKey)
19251914 if (isDefined(artDuck))
19261915 then throw(("You already used your ONBOARD artifact on duck " + value(artDuck)))
19271916 else {
19281917 let duckActivatorKey = keyOnboardArtActivatedOnDuck(duckAssetId)
19291918 let duckActivator = getString(duckActivatorKey)
19301919 if (isDefined(duckActivator))
19311920 then throw(((("The duck " + duckAssetId) + " already got points from ONBOARD artifact from user ") + value(duckActivator)))
19321921 else ([StringEntry(artKey, duckAssetId), StringEntry(duckActivatorKey, addr)] ++ updateDuckStatsInternal(duckAssetId, xpOnboard)._1)
19331922 }
19341923 }
19351924 }
19361925
19371926
19381927 func activatePresaleArt (addr,landAssetIdIn) = {
19391928 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetIdIn)
19401929 let landAssetId = c._2
19411930 let pieces = numPiecesBySize(c._3[recLandSize])
19421931 let activationKey = keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)
19431932 if ((valueOrElse(getInteger(activationKey), 0) > 0))
19441933 then throw("Presale artifact is already activated")
19451934 else if ((parseIntValue(c._3[recLandNum]) > PRESALENUMLANDS))
19461935 then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
19471936 else {
19481937 let claimResult = claimAll(addr, landAssetId, pieces, claimModeWhThenDuck)
19491938 (((claimResult._1 :+ IntegerEntry(activationKey, pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":"))) :+ StringEntry(claimResult._4, makeString(claimResult._5, ":")))
19501939 }
19511940 }
19521941
19531942
19541943 func checkTournament (duckAssetId) = {
19551944 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
19561945 let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
19571946 let now = lastBlock.timestamp
19581947 let tData = getTourData(tournamentContract, lastId)
19591948 let static = tData[idxStatic]
19601949 let dynamic = tData[idxDynamic]
19611950 if ((curLocation[locIdxType] != "T"))
19621951 then false
19631952 else if (if (if ((parseIntValue(curLocation[locIdxContinent]) == lastId))
19641953 then (dynamic[tDynamicStatus] == "INPROGRESS")
19651954 else false)
19661955 then (parseIntValue(static[tStaticEnd]) > now)
19671956 else false)
19681957 then throw("Your duck is taking part in the tournament")
19691958 else asBoolean(invoke(this, "exitTournamentInternal", [duckAssetId], nil))
19701959 }
19711960
19721961
1973-func checkDelivery (duckAssetId) = if (!(KS_ALLOW_DELIVERY))
1974- then false
1975- else {
1976- let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1977- let now = lastBlock.timestamp
1978- if ((curLocation[locIdxType] != "D"))
1979- then false
1980- else {
1981- let startTime = parseIntValue(curLocation[locIdxContinent])
1982- let distance = parseIntValue(curLocation[locIdxId])
1983- if (if (((startTime + TEN_MINUTES_MILLIS) > now))
1984- then (1 > distance)
1985- else false)
1986- then throw("Your duck is on delivery mission")
1987- else asBoolean(invoke(this, "exitDeliveryInternal", [duckAssetId], nil))
1988- }
1989- }
1962+func checkDelivery (duckAssetId) = {
1963+ let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
1964+ let now = lastBlock.timestamp
1965+ if ((curLocation[locIdxType] != "D"))
1966+ then false
1967+ else {
1968+ let startTime = parseIntValue(curLocation[locIdxContinent])
1969+ let distance = parseIntValue(curLocation[locIdxId])
1970+ if (if (((startTime + TEN_MINUTES_MILLIS) > now))
1971+ then (1 > distance)
1972+ else false)
1973+ then throw("Your duck is on delivery mission")
1974+ else asBoolean(invoke(this, "exitDeliveryInternal", [duckAssetId], nil))
1975+ }
1976+ }
19901977
19911978
19921979 func exitDeliveryCommon (duckAssetId,check,newHP,score) = {
19931980 let curLocation = split(valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
19941981 let now = lastBlock.timestamp
19951982 let startTime = parseIntValue(curLocation[locIdxContinent])
19961983 let distance = parseIntValue(curLocation[locIdxId])
19971984 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(duckAssetId)), "NFT duck is orphaned")
19981985 let healthKey = keyDuckHealth(duckAssetId)
19991986 let curHealth = getIntegerValue(healthKey)
20001987 let outcomeActions = if (if ((distance > 0))
20011988 then true
20021989 else if (if (check)
20031990 then (score > 0)
20041991 else false)
20051992 then (newHP > 0)
20061993 else false)
20071994 then {
20081995 let reward = invoke(economyContract, "sendDeliveryReward", [owner], nil)
20091996 if ((reward == reward))
20101997 then {
20111998 let countKey = keyUserDeliveryCount(owner)
20121999 [IntegerEntry(countKey, (valueOrElse(getInteger(countKey), 0) + 1)), IntegerEntry(keyUserLastDeliveryDay(owner), (startTime / DAYMILLIS))]
20132000 }
20142001 else throw("Strict value is not equal to itself.")
20152002 }
20162003 else if (if (if (check)
20172004 then (newHP > 0)
20182005 else false)
20192006 then ((startTime + TEN_MINUTES_MILLIS) > now)
20202007 else false)
20212008 then throw("Your duck is still on delivery mission")
20222009 else {
20232010 let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
20242011 let unlock = invoke(economyContract, "updateDeliveryLocked", [(lockedTotal - MIN_USDT_FEE_DELIVERY)], nil)
20252012 if ((unlock == unlock))
20262013 then if (if (if (check)
20272014 then (0 >= newHP)
20282015 else false)
20292016 then true
20302017 else (0 >= curHealth))
20312018 then nil
20322019 else [IntegerEntry(keyDeliveryDelayByDuck(duckAssetId), (startTime + DELIVERY_PUNISHMENT))]
20332020 else throw("Strict value is not equal to itself.")
20342021 }
20352022 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
20362023 $Tuple3(outcomeActions, [StringEntry(keyDuckLocation(duckAssetId), savedLocation)], savedLocation)
20372024 }
20382025
20392026
20402027 func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,needMat) = {
20412028 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
20422029 if (checkTournament(duckAssetId))
20432030 then throw("mergeInternal_checkTournament")
20442031 else if (checkDelivery(duckAssetId))
20452032 then throw("mergeInternal_checkDelivery")
20462033 else {
20472034 func checkMerge (acc,landAssetId) = {
20482035 let asset = value(assetInfo(fromBase58String(landAssetId)))
20492036 let timeKey = keyStakedTimeByAssetId(landAssetId)
20502037 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
20512038 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
20522039 if ((owner != addr))
20532040 then throw((LANDPREFIX + " is not yours"))
20542041 else {
20552042 let d = split(asset.description, "_")
20562043 let continent = d[recContinent]
20572044 if (if ((acc._3 != ""))
20582045 then (acc._3 != continent)
20592046 else false)
20602047 then throw("Lands should be on the same continent to merge")
20612048 else {
20622049 let landSize = d[recLandSize]
20632050 let sizesIn = acc._1
20642051 let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
20652052 let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
20662053 let pieces = numPiecesBySize(landSize)
20672054 let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), 0))
20682055 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
20692056 let reqLevel = match landSize {
20702057 case _ =>
20712058 if (("S" == $match0))
20722059 then 3
20732060 else if (("M" == $match0))
20742061 then 4
20752062 else if (("L" == $match0))
20762063 then 5
20772064 else if (("XL" == $match0))
20782065 then 6
20792066 else throw("Only S, M, L, XL can merge")
20802067 }
20812068 if ((infraLevel != reqLevel))
20822069 then throw("All lands should be maxed to merge")
20832070 else {
20842071 let landNum = d[recLandNum]
20852072 let terrainCounts = countTerrains(d[recTerrains])
20862073 let deltaTime = (lastBlock.timestamp - savedTime)
20872074 if ((0 > deltaTime))
20882075 then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
20892076 else {
20902077 let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
20912078 let landIndex = (pieces / SSIZE)
20922079 let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
20932080 let props = updateProportionsInternal(acc._6, terrainCounts, landIndex, -1)
20942081 let cProps = updateProportionsInternal(acc._10, terrainCounts, landIndex, -1)
20952082 let sumTerrains = updateProportionsInternal(acc._9, terrainCounts, landIndex, 1)
20962083 let lands = acc._7
20972084 let idx = indexOf(lands, landAssetId)
20982085 if (!(isDefined(idx)))
20992086 then throw(("Your staked lands don't contain " + landAssetId))
21002087 else {
21012088 let customKey = keyLandAssetIdToCustomName(landAssetId)
21022089 let customName = valueOrElse(getString(customKey), "")
21032090 $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 != ""))
21042091 then [DeleteEntry(keyLandCustomNameToAssetId(customName))]
21052092 else nil)), props, removeByIndex(lands, value(idx)), (acc._8 + pieces), sumTerrains, cProps)
21062093 }
21072094 }
21082095 }
21092096 }
21102097 }
21112098 }
21122099
21132100 let bpKey = keyBackpackByDuck(duckAssetId)
21142101 let currentPack = getBackpack(bpKey)
21152102 let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
21162103 let landsKey = keyStakedLandsByOwner(addr)
21172104 let landsStr = getString(landsKey)
21182105 let landsIn = if (isDefined(landsStr))
21192106 then split_51C(value(landsStr), "_")
21202107 else nil
21212108 let cont0 = split(value(assetInfo(fromBase58String(landAssetIds[0]))).description, "_")[recContinent]
21222109 let contProps = split(valueOrElse(getString(keyResTypesByContinent(cont0)), "0_0_0_0_0_0"), "_")
21232110 let r = {
21242111 let $l = landAssetIds
21252112 let $s = size($l)
21262113 let $acc0 = $Tuple10(formula, 0, "", currentPack[bpIdxRes], nil, propList, landsIn, 0, split("0_0_0_0_0_0", "_"), contProps)
21272114 func $f0_1 ($a,$i) = if (($i >= $s))
21282115 then $a
21292116 else checkMerge($a, $l[$i])
21302117
21312118 func $f0_2 ($a,$i) = if (($i >= $s))
21322119 then $a
21332120 else throw("List size exceeds 5")
21342121
21352122 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
21362123 }
21372124 let continent = r._3
21382125 let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
21392126 let terrains = genTerrainsForMerge(r._9, (numPiecesBySize(newLandSize) / SSIZE))
21402127 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
21412128 let newLandNum = toString(freeNum)
21422129 let issue = Issue(nftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
21432130 let assetId = calculateAssetId(issue)
21442131 let newLandAssetId = toBase58String(assetId)
21452132 let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
21462133 let piecesKey = keyStakedPiecesByOwner(addr)
21472134 let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
21482135 $Tuple2((((((((((((((((r._5 :+ (if ((size(r._7) > 0))
21492136 then StringEntry(landsKey, makeString_11C(r._7, "_"))
21502137 else DeleteEntry(landsKey))) :+ IntegerEntry(piecesKey, if ((r._8 > stakedPieces))
21512138 then 0
21522139 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)
21532140 }
21542141 }
21552142
21562143
21572144 func s2m (addr,landAssetIds) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, 0)
21582145
21592146
21602147 func m2l (addr,landAssetIds) = mergeInternal("L", 4, "SMM", addr, landAssetIds, (InfraUpgradeCostS * 4))
21612148
21622149
21632150 func l2xl (addr,landAssetIds) = mergeInternal("XL", 5, "SSSML", addr, landAssetIds, (InfraUpgradeCostS * 47))
21642151
21652152
21662153 func xl2xxl (addr,landAssetIds) = mergeInternal("XXL", 6, "LXL", addr, landAssetIds, (InfraUpgradeCostS * 54))
21672154
21682155
21692156 func mergeCommon (addr,landAssetIds) = match size(landAssetIds) {
21702157 case _ =>
21712158 if ((4 == $match0))
21722159 then s2m(addr, landAssetIds)
21732160 else if ((3 == $match0))
21742161 then m2l(addr, landAssetIds)
21752162 else if ((5 == $match0))
21762163 then l2xl(addr, landAssetIds)
21772164 else if ((2 == $match0))
21782165 then xl2xxl(addr, landAssetIds)
21792166 else throw("Unknown merge")
21802167 }
21812168
21822169
21832170 func checkOutdatedDelivery (userAddr) = {
21842171 let duck = getString(keyStakedDuckByOwner(userAddr))
2185- if (if (KS_ALLOW_DELIVERY)
2186- then isDefined(duck)
2187- else false)
2172+ if (isDefined(duck))
21882173 then {
21892174 let duckAssetId = value(duck)
21902175 let locKey = keyDuckLocation(duckAssetId)
21912176 let loc = split(valueOrElse(getString(locKey), DEFAULTLOCATION), "_")
21922177 let startTime = parseIntValue(loc[locIdxContinent])
21932178 if (if ((loc[locIdxType] != "D"))
21942179 then true
21952180 else ((startTime + TEN_MINUTES_MILLIS) > lastBlock.timestamp))
21962181 then nil
21972182 else {
21982183 let healthKey = keyDuckHealth(duckAssetId)
21992184 if ((parseIntValue(loc[locIdxId]) > 0))
22002185 then {
22012186 let reward = invoke(economyContract, "sendDeliveryReward", [userAddr], nil)
22022187 if ((reward == reward))
22032188 then nil
22042189 else throw("Strict value is not equal to itself.")
22052190 }
2206- else (({
2191+ else ({
22072192 let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
22082193 let unlock = invoke(economyContract, "updateDeliveryLocked", [(lockedTotal - MIN_USDT_FEE_DELIVERY)], nil)
22092194 if ((unlock == unlock))
22102195 then if ((0 >= getIntegerValue(healthKey)))
22112196 then nil
22122197 else {
22132198 let punishment = invoke(this, "saveInteger", [keyDeliveryDelayByDuck(duckAssetId), (startTime + DELIVERY_PUNISHMENT)], nil)
22142199 if ((punishment == punishment))
22152200 then nil
22162201 else throw("Strict value is not equal to itself.")
22172202 }
22182203 else throw("Strict value is not equal to itself.")
2219- } :+ IntegerEntry(healthKey, getIntegerValue(keySavedHealth(duckAssetId)))) :+ StringEntry(locKey, getStringValue(keySavedLocation(duckAssetId))))
2204+ } :+ StringEntry(locKey, getStringValue(keySavedLocation(duckAssetId))))
22202205 }
22212206 }
22222207 else nil
22232208 }
22242209
22252210
22262211 func prolog (i) = if (if ((i.originCaller != restContract))
22272212 then valueOrElse(getBoolean(keyBlocked()), false)
22282213 else false)
22292214 then throw("Contracts are under maintenance")
22302215 else {
22312216 let userAddr = toString(i.originCaller)
22322217 (checkOutdatedDelivery(userAddr) :+ StringEntry(keyLastTxIdByUser(userAddr), toBase58String(i.transactionId)))
22332218 }
22342219
22352220
22362221 func prologFlight (i) = if (if ((i.originCaller != restContract))
22372222 then valueOrElse(getBoolean(keyBlocked()), false)
22382223 else false)
22392224 then throw("Contracts are under maintenance")
22402225 else [StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))]
22412226
22422227
22432228 @Callable(i)
22442229 func constructorV1 (restAddr) = if ((i.caller != this))
22452230 then throw("Permission denied")
22462231 else [StringEntry(keyRestAddress(), restAddr)]
22472232
22482233
22492234
22502235 @Callable(i)
22512236 func saveInteger (key,amount) = if ((i.caller != this))
22522237 then throw("saveInteger is not public method")
22532238 else [IntegerEntry(key, amount)]
22542239
22552240
22562241
22572242 @Callable(i)
22582243 func setBlocked (isBlocked) = if ((i.caller != this))
22592244 then throw("permission denied")
22602245 else [BooleanEntry(keyBlocked(), isBlocked)]
22612246
22622247
22632248
22642249 @Callable(i)
22652250 func stakeLand () = {
22662251 let prologActions = prolog(i)
22672252 if ((size(i.payments) != 1))
22682253 then throw("Exactly one payment required")
22692254 else {
22702255 let pmt = value(i.payments[0])
22712256 let assetId = value(pmt.assetId)
22722257 let address = toString(i.caller)
22732258 if ((pmt.amount != 1))
22742259 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
22752260 else {
22762261 let asset = value(assetInfo(assetId))
22772262 if ((asset.issuer != this))
22782263 then throw("Unknown issuer of token")
22792264 else if (!(contains(asset.name, LANDPREFIX)))
22802265 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
22812266 else {
22822267 let landNumSize = drop(asset.name, 4)
22832268 let landNum = if (contains(landNumSize, "XXL"))
22842269 then dropRight(landNumSize, 3)
22852270 else if (contains(landNumSize, "XL"))
22862271 then dropRight(landNumSize, 2)
22872272 else dropRight(landNumSize, 1)
22882273 if (!(isDefined(parseInt(landNum))))
22892274 then throw(("Cannot parse land number from " + asset.name))
22902275 else {
22912276 let landAssetId = toBase58String(assetId)
22922277 let timeKey = keyStakedTimeByAssetId(landAssetId)
22932278 if (isDefined(getInteger(timeKey)))
22942279 then throw((("NFT " + asset.name) + " is already staked"))
22952280 else {
22962281 let d = split(asset.description, "_")
22972282 let terrainCounts = countTerrains(d[recTerrains])
22982283 let pieces = numPiecesBySize(d[recLandSize])
22992284 let landIndex = (pieces / SSIZE)
23002285 let props = updateProportions(terrainCounts, landIndex, 1)
23012286 let resByContKey = keyResTypesByContinent(d[recContinent])
23022287 let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
23032288 let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, 1), "_")
23042289 let landsKey = keyStakedLandsByOwner(address)
23052290 let landsStr = getString(landsKey)
23062291 let lands = if (isDefined(landsStr))
23072292 then split_51C(value(landsStr), "_")
23082293 else nil
23092294 if (containsElement(lands, landAssetId))
23102295 then throw(("Your staked lands already contain " + landAssetId))
23112296 else if ((size(lands) >= MAX_LANDS_STAKED_BY_USER))
23122297 then throw((("Your already staked max (" + toString(MAX_LANDS_STAKED_BY_USER)) + ") lands"))
23132298 else {
23142299 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
23152300 let piecesKey = keyStakedPiecesByOwner(address)
23162301 let oldPieces = valueOrElse(getInteger(piecesKey), 0)
23172302 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
23182303 $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)] ++ prologActions), wlgResult)
23192304 }
23202305 }
23212306 }
23222307 }
23232308 }
23242309 }
23252310 }
23262311
23272312
23282313
23292314 @Callable(i)
23302315 func unstakeLand (landAssetIdIn) = {
23312316 let prologActions = prolog(i)
23322317 if ((size(i.payments) != 0))
23332318 then throw("No payments required")
23342319 else {
23352320 let addr = toString(i.caller)
23362321 let c = checkClaimConditions(addr, claimModeDuck, landAssetIdIn)
23372322 let landAssetId = c._2
23382323 let d = c._3
23392324 let landsKey = keyStakedLandsByOwner(addr)
23402325 let terrainCounts = countTerrains(d[recTerrains])
23412326 let pieces = numPiecesBySize(d[recLandSize])
23422327 let landIndex = (pieces / SSIZE)
23432328 let props = updateProportions(terrainCounts, landIndex, -1)
23442329 let resByContKey = keyResTypesByContinent(d[recContinent])
23452330 let contProps = split(valueOrElse(getString(resByContKey), "0_0_0_0_0_0"), "_")
23462331 let updatedContProps = makeString(updateProportionsInternal(contProps, terrainCounts, landIndex, -1), "_")
23472332 let claimResult = claimAll(addr, landAssetId, pieces, claimModeDuck)
23482333 let lands = split_51C(valueOrElse(getString(landsKey), ""), "_")
23492334 let idx = indexOf(lands, landAssetId)
23502335 if (!(isDefined(idx)))
23512336 then throw(("Your staked lands don't contain " + landAssetId))
23522337 else {
23532338 let now = lastBlock.timestamp
23542339 let govReleaseTime = valueOrElse(getInteger(govContract, keyUserGwlReleaseTime(addr)), 0)
23552340 if ((govReleaseTime >= now))
23562341 then throw(("Your gWL are taking part in voting, cannot unstake until " + toString(govReleaseTime)))
23572342 else {
23582343 let arbReleaseTime = (valueOrElse(getInteger(wlgContract, keyLastArbTimeByUser(addr)), 0) + arbitrageDelay)
23592344 if ((arbReleaseTime > now))
23602345 then throw(("Your staked lands took part in arbitrage, cannot unstake until " + toString(arbReleaseTime)))
23612346 else {
23622347 let piecesKey = keyStakedPiecesByOwner(addr)
23632348 let stakedPieces = valueOrElse(getInteger(piecesKey), 0)
23642349 let newPieces = if ((pieces > stakedPieces))
23652350 then 0
23662351 else (stakedPieces - pieces)
23672352 let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [addr], nil)
23682353 $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))
23692354 then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
23702355 else DeleteEntry(landsKey), IntegerEntry(piecesKey, newPieces)] ++ prologActions), wlgResult)
23712356 }
23722357 }
23732358 }
23742359 }
23752360 }
23762361
23772362
23782363
23792364 @Callable(i)
23802365 func stakeDuck () = {
23812366 let prologActions = prolog(i)
23822367 if ((size(i.payments) != 1))
23832368 then throw("Exactly one payment required")
23842369 else {
23852370 let pmt = value(i.payments[0])
23862371 let assetId = value(pmt.assetId)
23872372 let address = toString(i.caller)
23882373 if ((pmt.amount != 1))
23892374 then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
23902375 else {
23912376 let asset = value(assetInfo(assetId))
23922377 if (if ((asset.issuer != incubatorAddr))
23932378 then (asset.issuer != breederAddr)
23942379 else false)
23952380 then throw((("Unknown issuer of " + DUCKPREFIX) + " token"))
23962381 else if (!(contains(asset.name, DUCKPREFIX)))
23972382 then throw((("Only NFT " + DUCKPREFIX) + " tokens are accepted"))
23982383 else {
23992384 let assetIdStr = toBase58String(assetId)
24002385 let timeKey = keyStakedTimeByAssetId(assetIdStr)
24012386 if (isDefined(getInteger(timeKey)))
24022387 then throw((("NFT " + asset.name) + " is already staked"))
24032388 else if (isDefined(getString(keyStakedDuckByOwner(address))))
24042389 then throw(("You already staked one duck: " + asset.name))
24052390 else {
24062391 let locKey = keyDuckLocation(assetIdStr)
24072392 let location = getString(locKey)
24082393 let bpKey = keyBackpackByDuck(assetIdStr)
24092394 let backpack = getString(bpKey)
24102395 let keyHealth = keyDuckHealth(assetIdStr)
24112396 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
24122397 let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
24132398 ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
24142399 then nil
24152400 else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
24162401 then nil
24172402 else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyHealth, curHealth)) ++ prologActions)))))
24182403 }
24192404 }
24202405 }
24212406 }
24222407 }
24232408
24242409
24252410
24262411 @Callable(i)
24272412 func unstakeDuck (assetIdStr) = {
24282413 let prologActions = prolog(i)
24292414 if ((size(i.payments) != 0))
24302415 then throw("No payments required")
24312416 else {
24322417 let assetId = fromBase58String(assetIdStr)
24332418 let address = toString(i.caller)
24342419 let asset = value(assetInfo(assetId))
24352420 let timeKey = keyStakedTimeByAssetId(assetIdStr)
24362421 if (!(isDefined(getInteger(timeKey))))
24372422 then throw((("NFT " + asset.name) + " is not staked"))
24382423 else if (!(isDefined(getString(keyStakedDuckByOwner(address)))))
24392424 then throw((("The duck " + asset.name) + " is not staked"))
24402425 else {
24412426 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetIdStr)), (("NFT " + asset.name) + " is orphaned"))
24422427 if ((owner != address))
24432428 then throw("Staked NFT is not yours")
24442429 else if (checkTournament(assetIdStr))
24452430 then throw("unstakeDuck_checkTournament")
24462431 else if (checkDelivery(assetIdStr))
24472432 then throw("unstakeDuck_checkDelivery")
24482433 else {
24492434 let keyHealth = keyDuckHealth(assetIdStr)
24502435 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(assetIdStr)), 0))
24512436 let health = valueOrElse(getInteger(keyHealth), maxHP)
24522437 if ((maxHP > health))
24532438 then throw((("Please heal your duck to " + toString(maxHP)) + "hp before unstaking"))
24542439 else ([ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address))] ++ prologActions)
24552440 }
24562441 }
24572442 }
24582443 }
24592444
24602445
24612446
24622447 @Callable(i)
24632448 func claimRes (amount,landAssetIdStr) = {
24642449 let prologActions = prolog(i)
24652450 if ((size(i.payments) != 0))
24662451 then throw("No payments required")
24672452 else {
24682453 let addr = toString(i.originCaller)
24692454 let result = claimResInternal(addr, amount, claimModeDuck, landAssetIdStr)
24702455 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
24712456 $Tuple2(((((result._1 ++ updateDuckStatsInternal(duckAssetId, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) ++ prologActions), result._3[bpIdxRes])
24722457 }
24732458 }
24742459
24752460
24762461
24772462 @Callable(i)
24782463 func claimResToWH (amount,landAssetIdStr) = {
24792464 let prologActions = prolog(i)
24802465 if ((size(i.payments) != 0))
24812466 then throw("No payments required")
24822467 else {
24832468 let addr = toString(i.originCaller)
24842469 let result = claimResInternal(addr, amount, claimModeWh, landAssetIdStr)
24852470 $Tuple2(((((result._1 ++ updateAccStatsInternal(addr, fraction(xpClaim, amount, MULT8))._1) :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) ++ prologActions), result._5[whIdxRes])
24862471 }
24872472 }
24882473
24892474
24902475
24912476 @Callable(i)
24922477 func flight (message,sig) = {
24932478 let prologActions = prologFlight(i)
24942479 if ((size(i.payments) != 0))
24952480 then throw("No payments required")
24962481 else {
24972482 let userAddr = toString(i.caller)
24982483 let f = flightCommon(userAddr, message, sig)
24992484 let newHP = f._1
25002485 let duckAssetId = f._2
25012486 let locKey = keyDuckLocation(duckAssetId)
25022487 let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
25032488 let newLocation = f._4
25042489 if ((newLocation == curLocation))
25052490 then throw("You can't fly to the same location")
25062491 else {
25072492 let newLoc = split(newLocation, "_")
25082493 let isTour = (newLoc[locIdxType] == "T")
25092494 let isDeliv = (newLoc[locIdxType] == "D")
25102495 let eqKey = keyDuckEquipment(duckAssetId)
25112496 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2512- let $t07046670563 = subtractEquipment(currentEq, f._5)
2513- let newEq = $t07046670563._1
2514- let shouldZeroBuffs = $t07046670563._2
2515- let $t07056673678 = if (!(onMission(tournamentContract, curLocation)))
2497+ let $t07008770184 = subtractEquipment(currentEq, f._5)
2498+ let newEq = $t07008770184._1
2499+ let shouldZeroBuffs = $t07008770184._2
2500+ let $t07018773299 = if (!(onMission(tournamentContract, curLocation)))
25162501 then if (!(isUsualLocation(newLocation)))
25172502 then cheatAttempt(curLocation, newLocation, 5)
25182503 else if ((newHP > 0))
25192504 then $Tuple2(newLocation, newHP)
25202505 else $Tuple2(curLocation, 0)
25212506 else if (isInTournament(tournamentContract, curLocation))
25222507 then if (!(isInTournament(tournamentContract, newLocation)))
25232508 then throw("Your duck is taking part in the tournament")
25242509 else {
25252510 let score = parseIntValue(newLoc[locIdxId])
25262511 let curLoc = split(curLocation, "_")
25272512 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
25282513 if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
25292514 then cheatAttempt(curLocation, newLocation, 7)
25302515 else if ((newHP > 0))
25312516 then {
25322517 let localBest = valueOrElse(getInteger(tournamentContract, keyBestResultByTourAndDuck(lastId, duckAssetId)), 0)
25332518 let updLocal = if ((score > localBest))
25342519 then invoke(tournamentContract, "saveDuckResult", [duckAssetId, score], nil)
25352520 else unit
25362521 if ((updLocal == updLocal))
25372522 then $Tuple2(newLocation, newHP)
25382523 else throw("Strict value is not equal to itself.")
25392524 }
25402525 else $Tuple2(curLocation, 0)
25412526 }
25422527 else if (!(isInDelivery(curLocation)))
25432528 then {
25442529 let savedLoc = asString(invoke(this, "autoExitDelivery", [duckAssetId, newHP, if (isDeliv)
25452530 then "10"
25462531 else "11", 0], nil))
25472532 if ((savedLoc == savedLoc))
25482533 then if (isDeliv)
25492534 then $Tuple2(savedLoc, newHP)
25502535 else if ((newHP > 0))
25512536 then $Tuple2(newLocation, newHP)
25522537 else $Tuple2(savedLoc, 0)
25532538 else throw("Strict value is not equal to itself.")
25542539 }
25552540 else if (!(isDeliv))
25562541 then throw("Your duck is taking part in delivery")
25572542 else if (!(isInDelivery(newLocation)))
25582543 then cheatAttempt(curLocation, newLocation, 13)
25592544 else {
25602545 let score = parseIntValue(newLoc[locIdxId])
25612546 let curLoc = split(curLocation, "_")
25622547 if ((score != (parseIntValue(curLoc[locIdxId]) + 1)))
25632548 then cheatAttempt(curLocation, newLocation, 14)
25642549 else if (if ((newHP > 0))
25652550 then (1 > score)
25662551 else false)
25672552 then $Tuple2(newLocation, newHP)
25682553 else {
25692554 let savedLoc = asString(invoke(this, "autoExitDelivery", [duckAssetId, newHP, "15-17", score], nil))
25702555 if ((savedLoc == savedLoc))
25712556 then $Tuple2(savedLoc, newHP)
25722557 else throw("Strict value is not equal to itself.")
25732558 }
25742559 }
2575- let locToSave = $t07056673678._1
2576- let hpToSave = $t07056673678._2
2560+ let locToSave = $t07018773299._1
2561+ let hpToSave = $t07018773299._2
25772562 $Tuple2(((([StringEntry(locKey, locToSave), StringEntry(eqKey, newEq), IntegerEntry(keyDuckHealth(duckAssetId), hpToSave)] ++ prologActions) ++ (if (shouldZeroBuffs)
25782563 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
25792564 else nil)) ++ updateDuckStatsInternal(duckAssetId, if ((newHP > 0))
25802565 then xpSuccessFlight
25812566 else xpFailFlight)._1), f._3)
25822567 }
25832568 }
25842569 }
25852570
25862571
25872572
25882573 @Callable(i)
25892574 func heal (quantityL1,quantityL2,quantityL3) = {
25902575 let prologActions = prolog(i)
25912576 if (if (if ((0 > quantityL1))
25922577 then true
25932578 else (0 > quantityL2))
25942579 then true
25952580 else (0 > quantityL3))
25962581 then throw("Quantity cannot be negative")
25972582 else {
25982583 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
25992584 if (checkTournament(duckAssetId))
26002585 then throw("heal_checkTournament")
26012586 else if (checkDelivery(duckAssetId))
26022587 then throw("heal_checkDelivery")
26032588 else {
26042589 let qts = [quantityL1, quantityL2, quantityL3]
26052590 let keyHealth = keyDuckHealth(duckAssetId)
26062591 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
26072592 let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
26082593 if ((oldHealth >= maxHP))
26092594 then throw((("HP should be < " + toString(maxHP)) + " to heal"))
26102595 else {
26112596 let bpKey = keyBackpackByDuck(duckAssetId)
26122597 let currentPack = getBackpack(bpKey)
26132598 let prodList = if ((currentPack[bpIdxProd] == ""))
26142599 then nil
26152600 else split_4C(currentPack[bpIdxProd], "_")
26162601 func iterateProd (acc,recipe) = {
26172602 let n = acc._2
26182603 let x = if ((size(prodList) > n))
26192604 then parseIntValue(prodList[n])
26202605 else 0
26212606 if ((3 > n))
26222607 then {
26232608 let q = qts[n]
26242609 if ((q > x))
26252610 then throw(((("You have only " + toString(x)) + " of ") + prodTypes[n]))
26262611 else $Tuple3((acc._1 :+ toString((x - q))), (n + 1), (acc._3 + (parseIntValue(split(recipe, "_")[rIdxEffect]) * q)))
26272612 }
26282613 else $Tuple3((acc._1 :+ toString(x)), (n + 1), acc._3)
26292614 }
26302615
26312616 let result = {
26322617 let $l = productionMatrix
26332618 let $s = size($l)
26342619 let $acc0 = $Tuple3(nil, 0, 0)
26352620 func $f0_1 ($a,$i) = if (($i >= $s))
26362621 then $a
26372622 else iterateProd($a, $l[$i])
26382623
26392624 func $f0_2 ($a,$i) = if (($i >= $s))
26402625 then $a
26412626 else throw("List size exceeds 50")
26422627
26432628 $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)
26442629 }
26452630 let newHealth = min([maxHP, (oldHealth + result._3)])
26462631 $Tuple2((([IntegerEntry(keyHealth, newHealth), StringEntry(bpKey, makeString_2C([currentPack[bpIdxLevel], currentPack[bpIdxRes], currentPack[bpIdxMat], makeString(result._1, "_")], ":"))] ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, (xpHeal * ((quantityL1 + quantityL2) + quantityL3)))._1), newHealth)
26472632 }
26482633 }
26492634 }
26502635 }
26512636
26522637
26532638
26542639 @Callable(i)
26552640 func healES () = {
26562641 let prologActions = prolog(i)
26572642 if ((size(i.payments) != 1))
26582643 then throw("Exactly one payment required")
26592644 else {
26602645 let pmt = value(i.payments[0])
26612646 if ((pmt.assetId != usdtAssetId))
26622647 then throw("Allowed USDT payment only!")
26632648 else {
26642649 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
26652650 if (checkTournament(duckAssetId))
26662651 then throw("healES_checkTournament")
26672652 else if (checkDelivery(duckAssetId))
26682653 then throw("healES_checkDelivery")
26692654 else {
26702655 let keyHealth = keyDuckHealth(duckAssetId)
26712656 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
26722657 let oldHealth = valueOrElse(getInteger(keyHealth), maxHP)
26732658 if ((oldHealth > 0))
26742659 then throw("HP should be 0 to call Emergency Service")
26752660 else {
26762661 let bpKey = keyBackpackByDuck(duckAssetId)
26772662 let currentPack = getBackpack(bpKey)
26782663 let prodList = if ((currentPack[bpIdxProd] == ""))
26792664 then nil
26802665 else split_4C(currentPack[bpIdxProd], "_")
26812666 let medKitAmount1 = if ((size(prodList) > 0))
26822667 then parseIntValue(prodList[0])
26832668 else 0
26842669 let medKitAmount2 = if ((size(prodList) > 1))
26852670 then parseIntValue(prodList[1])
26862671 else 0
26872672 let medKitAmount3 = if ((size(prodList) > 2))
26882673 then parseIntValue(prodList[2])
26892674 else 0
26902675 if (if (if ((medKitAmount1 > 0))
26912676 then true
26922677 else (medKitAmount2 > 0))
26932678 then true
26942679 else (medKitAmount3 > 0))
26952680 then throw("You have to use own Medical Kit")
26962681 else {
26972682 let existStr = getString(economyContract, keyEsWarehouse())
26982683 let existAmounts = if (isDefined(existStr))
26992684 then split_4C(value(existStr), "_")
27002685 else nil
27012686 let existAmount = if ((size(existAmounts) > 0))
27022687 then parseIntValue(existAmounts[0])
27032688 else 0
27042689 if ((0 >= existAmount))
27052690 then throw("There are no Medical Kits L1 at Emergency Service storage")
27062691 else {
27072692 let newHealth = (oldHealth + parseIntValue(split(productionMatrix[0], "_")[rIdxEffect]))
27082693 let newES = makeString([toString((existAmount - 1)), removeByIndex(existAmounts, 0)], "_")
27092694 let recipe = split(productionMatrix[0], "_")
27102695 let totalMat = getRecipeMaterials(recipe)
27112696 let sellPrice = fraction((totalMat * ESSELLCOEF), RESOURCEPRICEMIN, (MULT8 * PRODUCTPKGSIZE))
27122697 if ((pmt.amount != sellPrice))
27132698 then throw(("Payment attached should be " + toString(sellPrice)))
27142699 else {
27152700 let result = asString(invoke(economyContract, "updateEsStorage", [newES], [AttachedPayment(usdtAssetId, sellPrice)]))
27162701 $Tuple2(((prologActions :+ IntegerEntry(keyHealth, newHealth)) ++ updateDuckStatsInternal(duckAssetId, xpCallES)._1), result)
27172702 }
27182703 }
27192704 }
27202705 }
27212706 }
27222707 }
27232708 }
27242709 }
27252710
27262711
27272712
27282713 @Callable(i)
27292714 func updateBackpack (duckAssetId,newPack) = if ((i.caller != economyContract))
27302715 then throw("permission denied")
27312716 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack)], newPack)
27322717
27332718
27342719
27352720 @Callable(i)
27362721 func commitForRandom () = {
27372722 let prologActions = prolog(i)
27382723 let finishBlock = (height + randomDelay)
27392724 let addr = toString(i.caller)
27402725 $Tuple2(([IntegerEntry(keyCommit(addr), finishBlock)] ++ prologActions), finishBlock)
27412726 }
27422727
27432728
27442729
27452730 @Callable(i)
27462731 func buySLand () = {
27472732 let prologActions = prolog(i)
27482733 if ((size(i.payments) != 1))
27492734 then throw("Exactly one payment required")
27502735 else {
27512736 let pmt = value(i.payments[0])
27522737 if ((pmt.assetId != usdtAssetId))
27532738 then throw("Allowed USDT payment only!")
27542739 else if ((pmt.amount != EXPUSDT))
27552740 then throw(("Payment attached should be " + toString(EXPUSDT)))
27562741 else {
27572742 let result = expeditionInternal(i.caller, i.transactionId)
27582743 let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
27592744 $Tuple2((((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
27602745 }
27612746 }
27622747 }
27632748
27642749
27652750
27662751 @Callable(i)
27672752 func expedition (message,sig) = {
27682753 let prologActions = prolog(i)
27692754 if ((size(i.payments) != 0))
27702755 then throw("No payments required")
27712756 else {
27722757 let userAddr = toString(i.caller)
27732758 let f = flightCommon(userAddr, message, sig)
27742759 let duckAssetId = f._2
27752760 let keyHealth = keyDuckHealth(duckAssetId)
27762761 let bpKey = keyBackpackByDuck(duckAssetId)
27772762 let currentPack = getBackpack(bpKey)
27782763 let mList = split(currentPack[bpIdxMat], "_")
27792764 let newMat = makeString(subtractMaterials(true, mList, EXPMATERIALS), "_")
27802765 let eqKey = keyDuckEquipment(duckAssetId)
27812766 let currentEq = valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,")
2782- let $t08111881215 = subtractEquipment(currentEq, f._5)
2783- let newEq = $t08111881215._1
2784- let shouldZeroBuffs = $t08111881215._2
2767+ let $t08073980836 = subtractEquipment(currentEq, f._5)
2768+ let newEq = $t08073980836._1
2769+ let shouldZeroBuffs = $t08073980836._2
27852770 let e = expeditionInternal(i.caller, i.transactionId)
27862771 let id = e._2._1
27872772 let result = if ((0 >= f._1))
27882773 then $Tuple3([IntegerEntry(keyHealth, 0), StringEntry(eqKey, newEq)], "", 0)
27892774 else $Tuple3((e._1 ++ (if (shouldZeroBuffs)
27902775 then [StringEntry(keyDuckBuffs(duckAssetId), "0_0_0_0_0")]
27912776 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)
27922777 if (checkTournament(duckAssetId))
27932778 then throw("expedition_checkTournament")
27942779 else if (checkDelivery(duckAssetId))
27952780 then throw("expedition_checkDelivery")
27962781 else {
27972782 let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], nil))
27982783 $Tuple2(((result._1 ++ updateDuckStatsInternal(duckAssetId, xpNewSLand)._1) ++ prologActions), $Tuple3(result._2, result._3, acresResult))
27992784 }
28002785 }
28012786 }
28022787
28032788
28042789
28052790 @Callable(i)
28062791 func buySLandForAcres () = {
28072792 let prologActions = prolog(i)
28082793 if ((size(i.payments) != 1))
28092794 then throw("exactly 1 payment must be attached")
28102795 else {
28112796 let pmt = i.payments[0]
28122797 let amt = pmt.amount
28132798 if (if (!(isDefined(pmt.assetId)))
28142799 then true
28152800 else (value(pmt.assetId) != acresAssetId))
28162801 then throw("ACRES payments only!")
28172802 else if ((amt != S_COST_ACRES))
28182803 then throw(("Payment attached should be " + toString(S_COST_ACRES)))
28192804 else {
28202805 let result = expeditionInternal(i.caller, i.transactionId)
28212806 let acresResult = asInt(invoke(acresContract, "burnAcres", [S_COST_ACRES], [AttachedPayment(acresAssetId, amt)]))
28222807 $Tuple2(((result._1 ++ updateAccStatsInternal(toString(i.caller), xpNewSLand)._1) ++ prologActions), $Tuple2(result._2._1, acresResult))
28232808 }
28242809 }
28252810 }
28262811
28272812
28282813
28292814 @Callable(i)
28302815 func upgradeInfra (landAssetId) = {
28312816 let prologActions = prolog(i)
28322817 if ((size(i.payments) != 0))
28332818 then throw("No payments required")
28342819 else {
28352820 let result = upInfraCommon(true, i.caller, 0, landAssetId)
28362821 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
28372822 $Tuple2(((result._1 ++ prologActions) ++ updateDuckStatsInternal(duckAssetId, fraction(xpUpgradeInfra, result._3, MULT8))._1), result._2)
28382823 }
28392824 }
28402825
28412826
28422827
28432828 @Callable(i)
28442829 func activateArtifact (artName,landAssetIdOpt) = {
28452830 let prologActions = prolog(i)
28462831 if ((size(i.payments) != 0))
28472832 then throw("No payments required")
28482833 else {
28492834 let addr = toString(i.caller)
28502835 let result = match artName {
28512836 case _ =>
28522837 if (("PRESALE" == $match0))
28532838 then activatePresaleArt(addr, landAssetIdOpt)
28542839 else if (("ONBOARD" == $match0))
28552840 then activateOnboardArt(addr)
28562841 else throw("Unknown artifact")
28572842 }
28582843 (result ++ prologActions)
28592844 }
28602845 }
28612846
28622847
28632848
28642849 @Callable(i)
28652850 func mergeLands (landAssetIds) = {
28662851 let prologActions = prolog(i)
28672852 if ((size(i.payments) != 0))
28682853 then throw("No payments required")
28692854 else {
28702855 let result = mergeCommon(toString(i.caller), landAssetIds)
28712856 $Tuple2(((result._1 ++ prologActions) ++ updateAccStatsInternal(toString(i.caller), xpMerge)._1), result._2)
28722857 }
28732858 }
28742859
28752860
28762861
28772862 @Callable(i)
28782863 func cargoExchange (cargoListStr,landAssetId) = {
28792864 let prologActions = prolog(i)
28802865 if ((size(i.payments) != 0))
28812866 then throw("No payments required")
28822867 else {
28832868 let cargoParts = split_4C(cargoListStr, ":")
28842869 let addr = toString(i.originCaller)
28852870 let asset = value(assetInfo(fromBase58String(landAssetId)))
28862871 let timeKey = keyStakedTimeByAssetId(landAssetId)
28872872 if (!(isDefined(getInteger(timeKey))))
28882873 then throw((asset.name + " is not staked"))
28892874 else {
28902875 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
28912876 if ((owner != addr))
28922877 then throw((LANDPREFIX + " is not yours"))
28932878 else {
28942879 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
28952880 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
28962881 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
28972882 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
28982883 let loc = split(value(curLocation), "_")
28992884 if ((loc[locIdxType] != "L"))
29002885 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
29012886 else if ((loc[locIdxId] != landAssetId))
29022887 then throw(("Duck should be on the land " + landAssetId))
29032888 else {
29042889 let whKey = keyWarehouseByLand(landAssetId)
29052890 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
29062891 let bpKey = keyBackpackByDuck(duckAssetId)
29072892 let currentPack = getBackpack(bpKey)
29082893 let result = moveStuff(cargoParts, currentWh, currentPack)
29092894 let loft = split(currentWh[whIdxLOFT], "_")
29102895 let loftO = (parseIntValue(loft[volOccupied]) + result._7)
29112896 let loftF = (parseIntValue(loft[volFree]) - result._7)
29122897 ([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]], "_")], ":"))] ++ prologActions)
29132898 }
29142899 }
29152900 }
29162901 }
29172902 }
29182903
29192904
29202905
29212906 @Callable(i)
29222907 func saveWarehouse (whStr,landAssetId) = if ((i.caller != economyContract))
29232908 then throw("Access denied")
29242909 else {
29252910 let whKey = keyWarehouseByLand(landAssetId)
29262911 let wh = split_4C(whStr, ":")
29272912 if ((size(wh) != 5))
29282913 then throw("warehouse string should contain 4 ':' separators")
29292914 else {
29302915 let loftL = split(wh[whIdxLOFT], "_")[volLocked]
29312916 let loftO = getWarehouseOccupiedVol(wh)
29322917 let loftT = getWarehouseTotalVolume(wh[whIdxLevels])
29332918 let loftF = ((loftT - parseIntValue(loftL)) - loftO)
29342919 if ((0 > loftF))
29352920 then throw("Operation leads to negative free warehouse space")
29362921 else {
29372922 let newWhStr = makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], wh[whIdxProd], makeString([loftL, toString(loftO), toString(loftF), toString(loftT)], "_")], ":")
29382923 $Tuple2([StringEntry(whKey, newWhStr)], newWhStr)
29392924 }
29402925 }
29412926 }
29422927
29432928
29442929
29452930 @Callable(i)
29462931 func setCustomName (assetId,customName,type) = {
29472932 let prologActions = prolog(i)
29482933 if ((size(i.payments) != 1))
29492934 then throw("Exactly one payment required")
29502935 else {
29512936 let pmt = value(i.payments[0])
29522937 if ((pmt.assetId != usdtAssetId))
29532938 then throw("Allowed USDT payment only!")
29542939 else if ((pmt.amount != RENAMINGCOST))
29552940 then throw(("Payment should be " + toString(RENAMINGCOST)))
29562941 else if (contains(customName, "__"))
29572942 then throw(("Name should not contain '__': " + customName))
29582943 else if ((size(customName) > MAXNAMELEN))
29592944 then throw(("Name too long, maxLength=" + toString(MAXNAMELEN)))
29602945 else {
29612946 let addr = toString(i.originCaller)
29622947 let actions = match type {
29632948 case _ =>
29642949 if (("ACCOUNT" == $match0))
29652950 then {
29662951 let reverseKey = keyCustomNameToAddress(customName)
29672952 let nameOwner = getString(reverseKey)
29682953 if (isDefined(nameOwner))
29692954 then throw(("Name already registered: " + customName))
29702955 else {
29712956 let addrToNameKey = keyAddressToCustomName(addr)
29722957 let oldName = getString(addrToNameKey)
29732958 let freeOld = if (isDefined(oldName))
29742959 then [DeleteEntry(keyCustomNameToAddress(value(oldName)))]
29752960 else nil
29762961 (((freeOld :+ StringEntry(addrToNameKey, customName)) :+ StringEntry(reverseKey, addr)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
29772962 }
29782963 }
29792964 else if (("LAND" == $match0))
29802965 then {
29812966 let asset = value(assetInfo(fromBase58String(assetId)))
29822967 let timeKey = keyStakedTimeByAssetId(assetId)
29832968 if (!(isDefined(getInteger(timeKey))))
29842969 then throw((asset.name + " is not staked"))
29852970 else {
29862971 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
29872972 if ((owner != addr))
29882973 then throw((LANDPREFIX + " is not yours"))
29892974 else {
29902975 let reverseKey = keyLandCustomNameToAssetId(customName)
29912976 let nameOwner = getString(reverseKey)
29922977 if (isDefined(nameOwner))
29932978 then throw(("Name already registered: " + customName))
29942979 else {
29952980 let assetToNameKey = keyLandAssetIdToCustomName(assetId)
29962981 let oldName = getString(assetToNameKey)
29972982 let freeOld = if (isDefined(oldName))
29982983 then [DeleteEntry(keyLandCustomNameToAssetId(value(oldName)))]
29992984 else nil
30002985 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateAccStatsInternal(addr, xpCustomName)._1)
30012986 }
30022987 }
30032988 }
30042989 }
30052990 else if (("DUCK" == $match0))
30062991 then {
30072992 let asset = value(assetInfo(fromBase58String(assetId)))
30082993 let timeKey = keyStakedTimeByAssetId(assetId)
30092994 if (if (!(isDefined(getInteger(timeKey))))
30102995 then true
30112996 else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
30122997 then throw((asset.name + " is not staked"))
30132998 else {
30142999 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
30153000 if ((owner != addr))
30163001 then throw((DUCKPREFIX + " is not yours"))
30173002 else {
30183003 let reverseKey = keyDuckCustomNameToAssetId(customName)
30193004 let nameOwner = getString(reverseKey)
30203005 if (isDefined(nameOwner))
30213006 then throw(("Name already registered: " + customName))
30223007 else {
30233008 let assetToNameKey = keyDuckAssetIdToCustomName(assetId)
30243009 let oldName = getString(assetToNameKey)
30253010 let freeOld = if (isDefined(oldName))
30263011 then [DeleteEntry(keyDuckCustomNameToAssetId(value(oldName)))]
30273012 else nil
30283013 (((freeOld :+ StringEntry(assetToNameKey, customName)) :+ StringEntry(reverseKey, assetId)) ++ updateDuckStatsInternal(assetId, xpCustomName)._1)
30293014 }
30303015 }
30313016 }
30323017 }
30333018 else throw("Unknown entity type")
30343019 }
30353020 $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) ++ prologActions), 0)
30363021 }
30373022 }
30383023 }
30393024
30403025
30413026
30423027 @Callable(i)
30433028 func setReferrals (oldPlayer,newPlayer) = if ((i.callerPublicKey != pub))
30443029 then throw("Permission denied")
30453030 else {
30463031 let prologActions = prolog(i)
30473032 if ((size(i.payments) != 0))
30483033 then throw("No payments required")
30493034 else if (!(isDefined(addressFromString(oldPlayer))))
30503035 then throw(("Invalid address: " + oldPlayer))
30513036 else if (!(isDefined(addressFromString(newPlayer))))
30523037 then throw(("Invalid address: " + newPlayer))
30533038 else {
30543039 let oldsKey = keyOldies()
30553040 let olds = getString(oldsKey)
30563041 let oldies = if (isDefined(olds))
30573042 then split_4C(value(olds), "_")
30583043 else nil
30593044 if (containsElement(oldies, newPlayer))
30603045 then throw((newPlayer + " is not newbie (already has referrals)"))
30613046 else {
30623047 let refByKey = keyAddressRefBy(newPlayer)
30633048 let refBy = getString(refByKey)
30643049 if (if (isDefined(refBy))
30653050 then isDefined(addressFromString(value(refBy)))
30663051 else false)
30673052 then throw(((newPlayer + " already has refBy: ") + value(refBy)))
30683053 else {
30693054 let refsKey = keyAddressReferrals(oldPlayer)
30703055 let refs = getString(refsKey)
30713056 let refsArray = if (isDefined(refs))
30723057 then split_4C(value(refs), "_")
30733058 else nil
30743059 if (containsElement(refsArray, newPlayer))
30753060 then throw((((oldPlayer + " already contains ") + newPlayer) + " within referrals"))
30763061 else {
30773062 let newRefs = makeString_2C((refsArray :+ newPlayer), "_")
30783063 let newOlds = if (containsElement(oldies, oldPlayer))
30793064 then value(olds)
30803065 else makeString_2C((oldies :+ oldPlayer), "_")
30813066 $Tuple2(([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), StringEntry(oldsKey, newOlds)] ++ prologActions), 0)
30823067 }
30833068 }
30843069 }
30853070 }
30863071 }
30873072
30883073
30893074
30903075 @Callable(i)
30913076 func distributePoints (strength,accuracy,intellect,endurance,dexterity) = {
30923077 let prologActions = prolog(i)
30933078 if ((size(i.payments) != 0))
30943079 then throw("No payments required")
30953080 else {
30963081 let addr = toString(i.originCaller)
30973082 let virtWlgData = asAnyList(invoke(wlgContract, "checkWlgXpREADONLY", [addr], nil))
30983083 let virtWlgPoints = asInt(virtWlgData[1])
3099- let $t09683597225 = if ((0 >= virtWlgPoints))
3084+ let $t09645696846 = if ((0 >= virtWlgPoints))
31003085 then $Tuple2(0, nil)
31013086 else {
31023087 let deltaXP = asInt(invoke(wlgContract, "takeWlgXp", [addr], nil))
31033088 if ((deltaXP == deltaXP))
31043089 then $Tuple2(virtWlgPoints, [IntegerEntry(keyUserLevel(addr), asInt(virtWlgData[0])), IntegerEntry(keyUserXP(addr), asInt(virtWlgData[2]))])
31053090 else throw("Strict value is not equal to itself.")
31063091 }
3107- let wlgPoints = $t09683597225._1
3108- let wlgActions = $t09683597225._2
3092+ let wlgPoints = $t09645696846._1
3093+ let wlgActions = $t09645696846._2
31093094 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
31103095 let freeKeyAcc = keyUserFreePoints(addr)
31113096 let freePointsAcc = (valueOrElse(getInteger(freeKeyAcc), 0) + wlgPoints)
31123097 let freeKeyDuck = keyDuckFreePoints(duckAssetId)
31133098 let freePointsDuck = valueOrElse(getInteger(freeKeyDuck), 0)
31143099 let sumFree = (freePointsAcc + freePointsDuck)
31153100 let sumToDistribute = ((((strength + accuracy) + intellect) + endurance) + dexterity)
31163101 if ((sumToDistribute > sumFree))
31173102 then throw((("There are only " + toString(sumFree)) + " free points to distribute"))
31183103 else {
31193104 let charsKey = keyDuckChars(duckAssetId)
31203105 let chars = split(valueOrElse(getString(charsKey), "0_0_0_0_0"), "_")
31213106 let newAcc = (freePointsAcc - sumToDistribute)
31223107 $Tuple2((([IntegerEntry(freeKeyAcc, if ((0 > newAcc))
31233108 then 0
31243109 else newAcc), IntegerEntry(freeKeyDuck, if ((0 > newAcc))
31253110 then (freePointsDuck + newAcc)
31263111 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))], "_"))] ++ prologActions) ++ wlgActions), 0)
31273112 }
31283113 }
31293114 }
31303115
31313116
31323117
31333118 @Callable(i)
31343119 func splitByGlobalWeightsREADONLY (amount) = $Tuple2(nil, getNeededMaterials(amount))
31353120
31363121
31373122
31383123 @Callable(i)
31393124 func splitByGlobalAndLocalWeightsREADONLY (matAmount,resAmount,terrains) = {
31403125 let terrainCounts = countTerrains(terrains)
31413126 $Tuple2(nil, $Tuple2(getNeededMaterials(matAmount), distributeByWeights(resAmount, terrainCounts)))
31423127 }
31433128
31443129
31453130
31463131 @Callable(i)
31473132 func getBackpackREADONLY (duckAssetId) = $Tuple2(nil, makeString(getBackpack(keyBackpackByDuck(duckAssetId)), ":"))
31483133
31493134
31503135
31513136 @Callable(i)
31523137 func getWarehouseREADONLY (landAssetId) = {
31533138 let asset = value(assetInfo(fromBase58String(landAssetId)))
31543139 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
31553140 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
31563141 $Tuple2(nil, makeString_2C(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
31573142 }
31583143
31593144
31603145
31613146 @Callable(i)
31623147 func saveLastTx () = if (!(containsElement([wlgContract, economyContract, tournamentContract, acresContract], i.caller)))
31633148 then throw("Access denied")
31643149 else $Tuple2(prolog(i), 42)
31653150
31663151
31673152
31683153 @Callable(i)
31693154 func updateDuckStats (duckAssetId,deltaXP) = if ((i.caller != economyContract))
31703155 then throw("Access denied")
31713156 else updateDuckStatsInternal(duckAssetId, deltaXP)
31723157
31733158
31743159
31753160 @Callable(i)
31763161 func updateAccStats (addr,deltaXP) = if (!(containsElement([wlgContract, economyContract, acresContract], i.caller)))
31773162 then throw("Access denied")
31783163 else updateAccStatsInternal(addr, deltaXP)
31793164
31803165
31813166
31823167 @Callable(i)
31833168 func equipDuck (equipment) = {
31843169 let prologActions = prolog(i)
31853170 if ((size(i.payments) != 0))
31863171 then throw("No payments required")
31873172 else {
31883173 let addr = toString(i.originCaller)
31893174 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
31903175 if (checkTournament(duckAssetId))
31913176 then throw("equipDuck_checkTournament")
31923177 else if (checkDelivery(duckAssetId))
31933178 then throw("equipDuck_checkDelivery")
31943179 else {
31953180 let eqKey = keyDuckEquipment(duckAssetId)
31963181 let currentSegs = split(valueOrElse(getString(eqKey), ",;,_,;,_,;,_,;,_,;,_,;,"), "_")
31973182 let bpKey = keyBackpackByDuck(duckAssetId)
31983183 let currentPack = getBackpack(bpKey)
31993184 let newEq = split(equipment, "_")
32003185 if ((size(newEq) != NUMSEGMENTS))
32013186 then throw("Wrong equipment string")
32023187 else {
32033188 let tempProdB = dressB(currentSegs, prodStrToBytes(currentPack[bpIdxProd]), true, nil)
32043189 let segBpAux = split(newEq[segBackpack], ";")[1]
32053190 let buffEffect = if ((segBpAux == ""))
32063191 then 0
32073192 else {
32083193 let aux0 = split(segBpAux, ",")[0]
32093194 if ((aux0 == ""))
32103195 then 0
32113196 else {
32123197 let idxCnt = split(aux0, ":")
32133198 let idx = idxCnt[0]
32143199 let cnt = idxCnt[1]
32153200 if (if (if (if (if ((idx == "06"))
32163201 then true
32173202 else (idx == "07"))
32183203 then true
32193204 else (idx == "08"))
32203205 then (cnt != "")
32213206 else false)
32223207 then (parseIntValue(cnt) > 0)
32233208 else false)
32243209 then parseIntValue(split(productionMatrix[parseIntValue(idx)], "_")[rIdxEffect])
32253210 else 0
32263211 }
32273212 }
32283213 let stats = getDuckStats(this, duckAssetId, buffEffect, true)
32293214 let newProdB = dressB(newEq, tempProdB, false, stats)
32303215 let newProdStr = bytesToProdStr(newProdB)
32313216 $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])], "_"))] ++ prologActions), 0)
32323217 }
32333218 }
32343219 }
32353220 }
32363221
32373222
32383223
32393224 @Callable(i)
32403225 func fortificateLand (landAssetId,plan) = {
32413226 let prologActions = prolog(i)
32423227 if ((size(i.payments) != 0))
32433228 then throw("No payments required")
32443229 else {
32453230 let addr = toString(i.originCaller)
32463231 let duckAssetId = valueOrElse(getString(keyStakedDuckByOwner(addr)), "")
32473232 let duckStats = getDuckStats(this, duckAssetId, 0, false)
32483233 let fortKey = keyFortificationsByLand(landAssetId)
32493234 let currentForts = split(valueOrElse(getString(fortKey), ":0_15:0_18:0"), "_")
32503235 let asset = value(assetInfo(fromBase58String(landAssetId)))
32513236 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
32523237 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
32533238 let whKey = keyWarehouseByLand(landAssetId)
32543239 let wh = getWarehouse(whKey, landIndex, infraLevel)
32553240 let curLoft = split(wh[whIdxLOFT], "_")
32563241 let curO = parseIntValue(curLoft[volOccupied])
32573242 let curF = parseIntValue(curLoft[volFree])
32583243 let newForts = split(plan, "_")
3259- let $t0104063104178 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3260- let tempProdB = $t0104063104178._1
3261- let tempO = $t0104063104178._2
3262- let tempF = $t0104063104178._3
3263- let $t0104181104277 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3264- let newProdB = $t0104181104277._1
3265- let newO = $t0104181104277._2
3266- let newF = $t0104181104277._3
3244+ let $t0103684103799 = fortB(currentForts, prodStrToBytes(wh[whIdxProd]), curO, curF, true, nil)
3245+ let tempProdB = $t0103684103799._1
3246+ let tempO = $t0103684103799._2
3247+ let tempF = $t0103684103799._3
3248+ let $t0103802103898 = fortB(newForts, tempProdB, tempO, tempF, false, duckStats)
3249+ let newProdB = $t0103802103898._1
3250+ let newO = $t0103802103898._2
3251+ let newF = $t0103802103898._3
32673252 let newProdStr = bytesToProdStr(newProdB)
32683253 let newLoftStr = makeString([curLoft[volLocked], toString(newO), toString(newF), curLoft[volTotal]], "_")
32693254 $Tuple2(([StringEntry(fortKey, plan), StringEntry(whKey, makeString_2C([wh[whIdxLevels], wh[whIdxRes], wh[whIdxMat], newProdStr, newLoftStr], ":"))] ++ prologActions), 0)
32703255 }
32713256 }
32723257
32733258
32743259
32753260 @Callable(i)
32763261 func initDuckTourAttempt (duckAssetId) = if ((i.caller != tournamentContract))
32773262 then throw("Access denied")
32783263 else {
32793264 let keyHealth = keyDuckHealth(duckAssetId)
32803265 let maxHP = maxHealth(valueOrElse(getInteger(keyDuckLevel(duckAssetId)), 0))
32813266 let curHealth = valueOrElse(getInteger(keyHealth), maxHP)
32823267 let curLocKey = keyDuckLocation(duckAssetId)
32833268 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
32843269 let lastId = valueOrElse(getInteger(tournamentContract, lastTourIdKey), 0)
32853270 let tourLocation = (toString(lastId) + "_T_0")
32863271 $Tuple2([IntegerEntry(keySavedHealth(duckAssetId), curHealth), IntegerEntry(keyHealth, maxHP), StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, tourLocation)], tourLocation)
32873272 }
32883273
32893274
32903275
32913276 @Callable(i)
32923277 func breakAttempt () = {
32933278 let prologActions = prolog(i)
32943279 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
32953280 let curLocKey = keyDuckLocation(duckAssetId)
32963281 let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
32973282 if ((split(curLocation, "_")[locIdxType] != "T"))
32983283 then throw("Your duck is not in the tournament")
32993284 else {
33003285 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
33013286 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
33023287 $Tuple2(((prologActions :+ IntegerEntry(keyDuckHealth(duckAssetId), savedHealth)) :+ StringEntry(curLocKey, savedLocation)), curLocation)
33033288 }
33043289 }
33053290
33063291
33073292
33083293 @Callable(i)
33093294 func exitTournamentInternal (duckAssetId) = if ((i.caller != this))
33103295 then throw("Access denied")
33113296 else {
33123297 let savedHealth = getIntegerValue(keySavedHealth(duckAssetId))
33133298 let savedLocation = getStringValue(keySavedLocation(duckAssetId))
33143299 $Tuple2([IntegerEntry(keyDuckHealth(duckAssetId), savedHealth), StringEntry(keyDuckLocation(duckAssetId), savedLocation)], false)
33153300 }
33163301
33173302
33183303
33193304 @Callable(i)
33203305 func exitDeliveryInternal (duckAssetId) = if ((i.caller != this))
33213306 then throw("Access denied")
33223307 else {
33233308 let e = exitDeliveryCommon(duckAssetId, false, 0, 0)
33243309 $Tuple2((e._1 ++ e._2), false)
33253310 }
33263311
33273312
33283313
33293314 @Callable(i)
33303315 func autoExitDelivery (duckAssetId,newHP,reason,score) = if ((i.caller != this))
33313316 then throw("Access denied")
33323317 else {
33333318 let e = exitDeliveryCommon(duckAssetId, true, newHP, score)
33343319 $Tuple2(e._1, e._3)
33353320 }
33363321
33373322
33383323
33393324 @Callable(i)
33403325 func breakDelivery () = $Tuple2(prolog(i), "breakDelivery")
33413326
33423327
33433328
33443329 @Callable(i)
33453330 func prepareRobbery (message,sig) = {
33463331 let prologActions = prolog(i)
33473332 if (!(sigVerify_8Kb(message, sig, pub)))
33483333 then throw("signature does not match")
33493334 else if ((size(i.payments) != 1))
33503335 then throw("exactly 1 payment must be attached")
33513336 else {
33523337 let pmt = i.payments[0]
33533338 let wlgAmt = pmt.amount
33543339 if (if (!(isDefined(pmt.assetId)))
33553340 then true
33563341 else (value(pmt.assetId) != wlgAssetId))
33573342 then throw("WLGOLD payments only!")
33583343 else {
33593344 let parts = split(toUtf8String(message), "|")
3360- if ((size(parts) != 2))
3345+ if ((2 > size(parts)))
33613346 then throw("Wrong message format")
33623347 else {
3363- let duckAssetId = parts[0]
3364- if (checkTournament(duckAssetId))
3365- then throw("prepareRobbery_checkTournament")
3366- else if (checkDelivery(duckAssetId))
3367- then throw("prepareRobbery_checkDelivery")
3368- else {
3369- let robCost = getRobberyData(this, duckAssetId)._1
3370- if ((robCost > wlgAmt))
3371- then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
3348+ let txFromMsg = if ((size(parts) >= 2))
3349+ then parts[2]
3350+ else ""
3351+ let userAddr = toString(i.caller)
3352+ let lastTx = valueOrElse(getString(keyLastTxIdByUser(userAddr)), "")
3353+ if ((lastTx != txFromMsg))
3354+ then throw(((("Tx ids don't match! In state: " + lastTx) + ", in msg: ") + txFromMsg))
3355+ else {
3356+ let duckAssetId = parts[0]
3357+ if (checkTournament(duckAssetId))
3358+ then throw("prepareRobbery_checkTournament")
3359+ else if (checkDelivery(duckAssetId))
3360+ then throw("prepareRobbery_checkDelivery")
33723361 else {
3373- let candidates = split(parts[1], "_")
3374- let now = lastBlock.timestamp
3375- let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
3376- let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
3377- let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
3378- if (if ((duckState != duckIdxFree))
3379- then (landETA > now)
3380- else false)
3381- then throw(("You already started robbing, wait till " + toString(landETA)))
3362+ let robCost = getRobberyData(this, duckAssetId)._1
3363+ if ((robCost > wlgAmt))
3364+ then throw(((("Payment " + toString(wlgAmt)) + " < required ") + toString(robCost)))
33823365 else {
3383- func checker (acc,landAssetId) = {
3384- let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
3385- let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
3386- if ((state > size(landRobCooldowns)))
3387- then throw("Invalid state")
3388- else if ((now > cooldownETA))
3389- then {
3390- let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
3391- if ((0 >= stakedTime))
3392- then acc
3393- else {
3394- let a = value(assetInfo(fromBase58String(landAssetId)))
3395- let d = split(a.description, "_")
3396- let pieces = numPiecesBySize(d[recLandSize])
3397- let productivity = applyBonuses(landAssetId, pieces)
3398- let deltaTime = (now - stakedTime)
3399- let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
3400- if ((MIN_RES_TO_ROB > availRes))
3366+ let candidates = split(parts[1], "_")
3367+ let now = lastBlock.timestamp
3368+ let duckState = valueOrElse(getInteger(keyDuckRobberyState(duckAssetId)), 0)
3369+ let lockedLand = valueOrElse(getString(keyLockedLandByDuck(duckAssetId)), "")
3370+ let landETA = valueOrElse(getInteger(keyLandCooldownETA(lockedLand)), 0)
3371+ if (if ((duckState != duckIdxFree))
3372+ then (landETA > now)
3373+ else false)
3374+ then throw(("You already started robbing, wait till " + toString(landETA)))
3375+ else {
3376+ func checker (acc,landAssetId) = {
3377+ let state = valueOrElse(getInteger(keyLandRobberyState(landAssetId)), 0)
3378+ let cooldownETA = valueOrElse(getInteger(keyLandCooldownETA(landAssetId)), 0)
3379+ if ((state > size(landRobCooldowns)))
3380+ then throw("Invalid state")
3381+ else if ((now > cooldownETA))
3382+ then {
3383+ let stakedTime = valueOrElse(getInteger(keyStakedTimeByAssetId(landAssetId)), 0)
3384+ if ((0 >= stakedTime))
34013385 then acc
3402- else (acc :+ landAssetId)
3386+ else {
3387+ let a = value(assetInfo(fromBase58String(landAssetId)))
3388+ let d = split(a.description, "_")
3389+ let pieces = numPiecesBySize(d[recLandSize])
3390+ let productivity = applyBonuses(landAssetId, pieces)
3391+ let deltaTime = (now - stakedTime)
3392+ let availRes = fraction(deltaTime, (productivity * pieces), DAYMILLIS)
3393+ if ((MIN_RES_TO_ROB > availRes))
3394+ then acc
3395+ else (acc :+ landAssetId)
3396+ }
34033397 }
3398+ else acc
3399+ }
3400+
3401+ let filtered = {
3402+ let $l = candidates
3403+ let $s = size($l)
3404+ let $acc0 = nil
3405+ func $f0_1 ($a,$i) = if (($i >= $s))
3406+ then $a
3407+ else checker($a, $l[$i])
3408+
3409+ func $f0_2 ($a,$i) = if (($i >= $s))
3410+ then $a
3411+ else throw("List size exceeds 10")
3412+
3413+ $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)
3414+ }
3415+ if ((size(filtered) == 0))
3416+ then throw("No candidates for robbery")
3417+ else {
3418+ let rndIdx = getRandomNumber(size(filtered), message, sig)
3419+ let landAssetId = filtered[rndIdx]
3420+ $Tuple2(([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId)] ++ prologActions), landAssetId)
34043421 }
3405- else acc
3406- }
3407-
3408- let filtered = {
3409- let $l = candidates
3410- let $s = size($l)
3411- let $acc0 = nil
3412- func $f0_1 ($a,$i) = if (($i >= $s))
3413- then $a
3414- else checker($a, $l[$i])
3415-
3416- func $f0_2 ($a,$i) = if (($i >= $s))
3417- then $a
3418- else throw("List size exceeds 10")
3419-
3420- $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)
3421- }
3422- if ((size(filtered) == 0))
3423- then throw("No candidates for robbery")
3424- else {
3425- let rndIdx = getRandomNumber(size(filtered), height, (sig + i.transactionId))
3426- let landAssetId = filtered[rndIdx]
3427- $Tuple2(([IntegerEntry(keyLandRobberyState(landAssetId), robIdxLocked), IntegerEntry(keyLandCooldownETA(landAssetId), (now + landRobCooldowns[robIdxLocked])), IntegerEntry(keyDuckRobberyState(duckAssetId), duckIdxPreparing), StringEntry(keyLockedLandByDuck(duckAssetId), landAssetId)] ++ prologActions), landAssetId)
34283422 }
34293423 }
34303424 }
3431- }
3425+ }
34323426 }
34333427 }
34343428 }
34353429 }
34363430
34373431
34383432
34393433 @Callable(i)
34403434 func robLand (message,sig) = {
34413435 let prologActions = prolog(i)
34423436 if (!(sigVerify_8Kb(message, sig, pub)))
34433437 then throw("signature does not match")
34443438 else {
34453439 let userAddr = toString(i.caller)
34463440 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
34473441 let now = lastBlock.timestamp
34483442 $Tuple2((prologActions :+ IntegerEntry(keyLastRobberyTimeByDuck(duckAssetId), now)), 0)
34493443 }
34503444 }
34513445
34523446
34533447
34543448 @Callable(i)
3455-func acceptDelivery () = if (!(KS_ALLOW_DELIVERY))
3456- then throw("Delivery feature is turned off!")
3457- else {
3458- let prologActions = prolog(i)
3459- let userAddr = toString(i.caller)
3460- let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
3461- let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
3462- let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
3463- if ((MIN_USDT_FEE_DELIVERY > (fundTotal - lockedTotal)))
3464- then throw(((("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)) + ", locked=") + fixedPoint(lockedTotal, 6)))
3465- else {
3466- let now = lastBlock.timestamp
3467- let delayETA = valueOrElse(getInteger(keyDeliveryDelayByDuck(duckAssetId)), 0)
3468- if ((delayETA > now))
3469- then throw(("Delivery is forbidden for your duck until " + toString(delayETA)))
3470- else {
3471- let health = getIntegerValue(keyDuckHealth(duckAssetId))
3472- if ((0 >= health))
3473- then throw("You cannot accept delivery with zero health")
3474- else {
3475- let countKey = keyUserDeliveryCount(userAddr)
3476- let count = valueOrElse(getInteger(countKey), 0)
3477- let lastDay = valueOrElse(getInteger(keyUserLastDeliveryDay(userAddr)), 0)
3478- let today = (now / DAYMILLIS)
3479- let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(userAddr)), 0)
3480- let allowedDeliveries = (ALLOWED_FREE_DELIVERIES + (acres / ACRES_FOR_DELIVERY_ATTEMPT))
3481- if (if ((count >= allowedDeliveries))
3482- then (lastDay == today)
3483- else false)
3484- then throw((("You already used " + toString(allowedDeliveries)) + " delivery attempts for today"))
3485- else if (checkTournament(duckAssetId))
3486- then throw("acceptDelivery_checkTournament")
3487- else if (checkDelivery(duckAssetId))
3488- then throw("acceptDelivery_checkDelivery")
3489- else {
3490- let newLockedTotal = asInt(invoke(economyContract, "updateDeliveryLocked", [(lockedTotal + MIN_USDT_FEE_DELIVERY)], nil))
3491- let curLocKey = keyDuckLocation(duckAssetId)
3492- let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
3493- let deliveryLocation = (toString(now) + "_D_0")
3494- $Tuple2(([StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, deliveryLocation), IntegerEntry(countKey, if ((lastDay != today))
3495- then 0
3496- else count)] ++ prologActions), $Tuple2(deliveryLocation, newLockedTotal))
3497- }
3498- }
3499- }
3500- }
3501- }
3449+func acceptDelivery () = {
3450+ let prologActions = prolog(i)
3451+ let userAddr = toString(i.caller)
3452+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
3453+ let fundTotal = valueOrElse(getInteger(economyContract, deliveryFundKey), 0)
3454+ let lockedTotal = valueOrElse(getInteger(economyContract, deliveryLockedKey), 0)
3455+ if ((MIN_USDT_FEE_DELIVERY > (fundTotal - lockedTotal)))
3456+ then throw(((("Delivery is not available, fund=" + fixedPoint(fundTotal, 6)) + ", locked=") + fixedPoint(lockedTotal, 6)))
3457+ else {
3458+ let now = lastBlock.timestamp
3459+ let delayETA = valueOrElse(getInteger(keyDeliveryDelayByDuck(duckAssetId)), 0)
3460+ if ((delayETA > now))
3461+ then throw(("Delivery is forbidden for your duck until " + toString(delayETA)))
3462+ else {
3463+ let health = getIntegerValue(keyDuckHealth(duckAssetId))
3464+ if ((0 >= health))
3465+ then throw("You cannot accept delivery with zero health")
3466+ else {
3467+ let countKey = keyUserDeliveryCount(userAddr)
3468+ let count = valueOrElse(getInteger(countKey), 0)
3469+ let lastDay = valueOrElse(getInteger(keyUserLastDeliveryDay(userAddr)), 0)
3470+ let today = (now / DAYMILLIS)
3471+ let acres = valueOrElse(getInteger(acresContract, keyAcresStakedAmountByUser(userAddr)), 0)
3472+ let allowedDeliveries = (ALLOWED_FREE_DELIVERIES + (acres / ACRES_FOR_DELIVERY_ATTEMPT))
3473+ if (if ((count >= allowedDeliveries))
3474+ then (lastDay == today)
3475+ else false)
3476+ then throw((("You already used " + toString(allowedDeliveries)) + " delivery attempts for today"))
3477+ else if (checkTournament(duckAssetId))
3478+ then throw("acceptDelivery_checkTournament")
3479+ else if (checkDelivery(duckAssetId))
3480+ then throw("acceptDelivery_checkDelivery")
3481+ else {
3482+ let newLockedTotal = asInt(invoke(economyContract, "updateDeliveryLocked", [(lockedTotal + MIN_USDT_FEE_DELIVERY)], nil))
3483+ let curLocKey = keyDuckLocation(duckAssetId)
3484+ let curLocation = valueOrElse(getString(curLocKey), DEFAULTLOCATION)
3485+ let deliveryLocation = (toString(now) + "_D_0")
3486+ $Tuple2(([StringEntry(keySavedLocation(duckAssetId), curLocation), StringEntry(curLocKey, deliveryLocation), IntegerEntry(countKey, if ((lastDay != today))
3487+ then 0
3488+ else count)] ++ prologActions), $Tuple2(deliveryLocation, newLockedTotal))
3489+ }
3490+ }
3491+ }
3492+ }
3493+ }
35023494
35033495
35043496
35053497 @Callable(i)
35063498 func checkDeliveryCallback (duckAssetId) = if ((i.caller != tournamentContract))
35073499 then throw("Access denied")
35083500 else $Tuple2(nil, checkDelivery(duckAssetId))
35093501
35103502

github/deemru/w8io/3ef1775 
290.52 ms