tx · AsabePkJnfKi5sgTSiQWTc6vpHT77UFK5TEFkJT7tF5R

3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm:  -0.05400000 Waves

2023.05.13 15:09 [2576151] smart account 3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm > SELF 0.00000000 Waves

{ "type": 13, "id": "AsabePkJnfKi5sgTSiQWTc6vpHT77UFK5TEFkJT7tF5R", "fee": 5400000, "feeAssetId": null, "timestamp": 1683979784683, "version": 2, "chainId": 84, "sender": "3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm", "senderPublicKey": "EVooykMNV691Venwp1dHUTBd7KWequzUcda57Wd3LQEX", "proofs": [ "B4zQKLoXqv7RWXRSr2h1cWMywCTqN83prftrU3Etd5a8tHgHjXesAxLDT1i1MXeovc9g9Ak8fnpHiXrC2Z9iceN" ], "script": "base64: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bWVyaWNhcwkAzAgCAgdPY2VhbmlhCQDMCAICBkFmcmljYQUDbmlsAApBUlRQUkVTQUxFAgdQUkVTQUxFAA9QUkVTQUxFTlVNTEFORFMA9AMBD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAQxnZXRJbnRPckVsc2UCA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFA2tleQUKZGVmYXVsdFZhbAARSWR4Q2ZnU3Rha2luZ0RhcHAAAQARSWR4Q2ZnRWNvbm9teURhcHAAAgAUSWR4Q2ZnR292ZXJuYW5jZURhcHAAAwEKa2V5UmVzdENmZwACDiVzX19yZXN0Q29uZmlnAQ5rZXlSZXN0QWRkcmVzcwACDCVzX19yZXN0QWRkcgERcmVhZFJlc3RDZmdPckZhaWwBBHJlc3QJALwJAgkBD2dldFN0cmluZ09yRmFpbAIFBHJlc3QJAQprZXlSZXN0Q2ZnAAUDU0VQARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCB3Jlc3RDZmcDaWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQdyZXN0Q2ZnBQNpZHgJAKwCAgIqUmVzdCBjZmcgZG9lc24ndCBjb250YWluIGFkZHJlc3MgYXQgaW5kZXggCQCkAwEFA2lkeAAMcmVzdENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJAQ5rZXlSZXN0QWRkcmVzcwAFFWRlZmF1bHRSZXN0QWRkcmVzc1N0cgAHcmVzdENmZwkBEXJlYWRSZXN0Q2ZnT3JGYWlsAQUMcmVzdENvbnRyYWN0AA9lY29ub215Q29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBRFJZHhDZmdFY29ub215RGFwcAALZ292Q29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQdyZXN0Q2ZnBRRJZHhDZmdHb3Zlcm5hbmNlRGFwcAERa2V5TGFzdFR4SWRCeVVzZXIBBGFkZHIJAKwCAgIPbGFzdFR4SWRCeVVzZXJfBQRhZGRyARJrZXlOZXh0RnJlZUxhbmROdW0AAgtuZXh0TGFuZE51bQEQa2V5TGFuZFRvQXNzZXRJZAEHbGFuZE51bQkArAICAgxsYW5kVG9Bc3NldF8FB2xhbmROdW0BCmtleU5mdE5hbWUCB2xhbmROdW0IbGFuZFNpemUJAKwCAgkArAICBQpMQU5EUFJFRklYBQdsYW5kTnVtBQhsYW5kU2l6ZQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQdhc3NldElkCQCsAgICCW5mdE93bmVyXwUHYXNzZXRJZAEaa2V5TGFuZEFzc2V0SWRUb0N1c3RvbU5hbWUBB2Fzc2V0SWQJAKwCAgIYbGFuZEN1c3RvbU5hbWVCeUFzc2V0SWRfBQdhc3NldElkARprZXlEdWNrQXNzZXRJZFRvQ3VzdG9tTmFtZQEHYXNzZXRJZAkArAICAhhkdWNrQ3VzdG9tTmFtZUJ5QXNzZXRJZF8FB2Fzc2V0SWQBFmtleUFkZHJlc3NUb0N1c3RvbU5hbWUBBGFkZHIJAKwCAgIYYWNjb3VudEN1c3RvbU5hbWVCeUFkZHJfBQRhZGRyARprZXlMYW5kQ3VzdG9tTmFtZVRvQXNzZXRJZAEEbmFtZQkArAICAhFsYW5kQnlDdXN0b21OYW1lXwUEbmFtZQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBBG5hbWUJAKwCAgIRZHVja0J5Q3VzdG9tTmFtZV8FBG5hbWUBFmtleUN1c3RvbU5hbWVUb0FkZHJlc3MBBG5hbWUJAKwCAgIUYWNjb3VudEJ5Q3VzdG9tTmFtZV8FBG5hbWUBD2tleUFkZHJlc3NSZWZCeQEEYWRkcgkArAICAglhY2NSZWZCeV8FBGFkZHIBE2tleUFkZHJlc3NSZWZlcnJhbHMBBGFkZHIJAKwCAgINYWNjUmVmZXJyYWxzXwUEYWRkcgEQa2V5RHVja0lkVG9Pd25lcgEHYXNzZXRJZAkArAICAgpkdWNrT3duZXJfBQdhc3NldElkARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQdhc3NldElkCQCsAgICC3N0YWtlZFRpbWVfBQdhc3NldElkARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQdhc3NldElkCQCsAgICC2luZnJhTGV2ZWxfBQdhc3NldElkAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICAhxpbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXJfBQdhc3NldElkAgFfBQlvd25lckFkZHIBH2tleVByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWQBB2Fzc2V0SWQJAKwCAgIUcHJlc2FsZUFydEFjdGl2YXRlZF8FB2Fzc2V0SWQBJ2tleVByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWRBbmRPd25lcgIHYXNzZXRJZAlvd25lckFkZHIJAKwCAgkArAICCQCsAgICJXByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWRBbmRPd25lcl8FB2Fzc2V0SWQCAV8FCW93bmVyQWRkcgEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBHR5cGUHYXNzZXRJZAkAuQkCCQDMCAICDWxhbmRBcnRTdGF0dXMJAMwIAgUEdHlwZQkAzAgCBQdhc3NldElkBQNuaWwCAV8BJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBHR5cGUHYXNzZXRJZAlvd25lckFkZHIJALkJAgkAzAgCAiJsYW5kQXJ0U3RhdHVzQnlUeXBlQXNzZXRJZEFuZE93bmVyCQDMCAIFBHR5cGUJAMwIAgUHYXNzZXRJZAkAzAgCBQlvd25lckFkZHIFA25pbAIBXwEUa2V5U3Rha2VkRHVja0J5T3duZXIBCW93bmVyQWRkcgkArAICAhJzdGFrZWREdWNrQnlPd25lcl8FCW93bmVyQWRkcgEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMHbmZ0VHlwZQdhc3NldElkCW93bmVyQWRkcgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICIHN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXJfBQduZnRUeXBlAgFfBQdhc3NldElkAgFfBQlvd25lckFkZHIBEWtleUxhbmROdW1Ub093bmVyAQdsYW5kTnVtCQCsAgICCmxhbmRPd25lcl8FB2xhbmROdW0BEWtleUJhY2twYWNrQnlEdWNrAQtkdWNrQXNzZXRJZAkArAICAgliYWNrUGFja18FC2R1Y2tBc3NldElkARJrZXlXYXJlaG91c2VCeUxhbmQBC2xhbmRBc3NldElkCQCsAgICCndhcmVIb3VzZV8FC2xhbmRBc3NldElkAQ9rZXlEdWNrTG9jYXRpb24BC2R1Y2tBc3NldElkCQCsAgICDWR1Y2tMb2NhdGlvbl8FC2R1Y2tBc3NldElkAQ1rZXlEdWNrSGVhbHRoAQtkdWNrQXNzZXRJZAkArAICAgtkdWNrSGVhbHRoXwULZHVja0Fzc2V0SWQBEWtleVJlc1Byb3BvcnRpb25zAAITcmVzVHlwZXNQcm9wb3J0aW9ucwEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQlvd25lckFkZHIJAKwCAgITc3Rha2VkTGFuZHNCeU93bmVyXwUJb3duZXJBZGRyAQprZXlCbG9ja2VkAAIQY29udHJhY3RzQmxvY2tlZAEVa2V5VXNlckd3bFJlbGVhc2VUaW1lAQh1c2VyQWRkcgkArAICAholcyVzX191c2VyR3dsUmVsZWFzZVRpbWVfXwUIdXNlckFkZHIACnJlY0xhbmROdW0AAAALcmVjTGFuZFNpemUAAQALcmVjVGVycmFpbnMAAgAMcmVjQ29udGluZW50AAMAD2xvY0lkeENvbnRpbmVudAAAAApsb2NJZHhUeXBlAAEACGxvY0lkeElkAAIACmJwSWR4TGV2ZWwAAAAIYnBJZHhSZXMAAQAIYnBJZHhNYXQAAgAJYnBJZHhQcm9kAAMACHdoSWR4Vm9sAAAACHdoSWR4UmVzAAEACHdoSWR4TWF0AAIACXdoSWR4UHJvZAADAA53aElkeExvY2tlZFZvbAAEAAtjbGFpbU1vZGVXaAAAAA1jbGFpbU1vZGVEdWNrAAEAE2NsYWltTW9kZVdoVGhlbkR1Y2sAAgEIYXNTdHJpbmcBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwBQFzCQACAQIYZmFpbCB0byBjYXN0IGludG8gU3RyaW5nARNkaXN0cmlidXRlQnlXZWlnaHRzAgV0b3RhbAd3ZWlnaHRzBANzdW0JAGQCCQBkAgkAZAIJAGQCCQBkAgkAkQMCBQd3ZWlnaHRzAAAJAJEDAgUHd2VpZ2h0cwABCQCRAwIFB3dlaWdodHMAAgkAkQMCBQd3ZWlnaHRzAAMJAJEDAgUHd2VpZ2h0cwAECQCRAwIFB3dlaWdodHMABQMJAGcCAAAFA3N1bQkAAgECEFplcm8gd2VpZ2h0cyBzdW0EBW5vcm02CQBrAwUFdG90YWwFBU1VTFQ2BQNzdW0KAQpub3JtYWxpemVyAgNhY2MEZWxlbQkAzQgCBQNhY2MJAGsDBQRlbGVtBQVub3JtNgUFTVVMVDYKAAIkbAUHd2VpZ2h0cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEKbm9ybWFsaXplcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgESZ2V0TmVlZGVkTWF0ZXJpYWxzAQV0b3RhbAQFcHJvcHMJALUJAgkBBXZhbHVlAQkAoggBCQERa2V5UmVzUHJvcG9ydGlvbnMAAgFfAwkBAiE9AgkAkAMBBQVwcm9wcwUGTlVNUkVTCQACAQIWV3JvbmcgcHJvcG9ydGlvbnMgZGF0YQQBcgkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMAAAkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMAAQkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMAAgkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMAAwkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMABAkAzAgCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMABQUDbmlsCQETZGlzdHJpYnV0ZUJ5V2VpZ2h0cwIFBXRvdGFsBQFyARFzdWJ0cmFjdE1hdGVyaWFscwMMc2hvdWxkVXNlTWF0A2hhcwl0b3RhbE5lZWQEBG5lZWQJARJnZXROZWVkZWRNYXRlcmlhbHMBBQl0b3RhbE5lZWQKAQpzdWJ0cmFjdG9yAgNhY2MDaWR4BAZyZXN1bHQJAGUCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDaGFzBQNpZHgJAJEDAgUEbmVlZAUDaWR4AwkAZgIAAAUGcmVzdWx0CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICGE5vdCBlbm91Z2ggbWF0ZXJpYWwgaWR4PQkApAMBBQNpZHgCCywgeW91IGhhdmUgCQCRAwIFA2hhcwUDaWR4AgssIGJ1dCBuZWVkIAkApAMBCQCRAwIFBG5lZWQFA2lkeAkAzQgCBQNhY2MJAKQDAQUGcmVzdWx0AwUMc2hvdWxkVXNlTWF0CgACJGwJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEKc3VidHJhY3RvcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgUDaGFzARl1cGRhdGVQcm9wb3J0aW9uc0ludGVybmFsBAhwcm9wTGlzdA10ZXJyYWluQ291bnRzDWxhbmRTaXplSW5kZXgEc2lnbgMJAQIhPQIJAJADAQUIcHJvcExpc3QFBk5VTVJFUwkAAgECFldyb25nIHByb3BvcnRpb25zIGRhdGEKAQd1cGRhdGVyAgNhY2MBaQQGcmVzdWx0CQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCHByb3BMaXN0BQFpCQBoAgkAaAIFBHNpZ24JAJEDAgUNdGVycmFpbkNvdW50cwUBaQUNbGFuZFNpemVJbmRleAMJAGYCAAAFBnJlc3VsdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIWUGFuaWMhIFBpZWNlcyBvZiB0eXBlPQkApAMBBQFpAgcsIHNpZ249CQCkAwEFBHNpZ24CFCwgIHRlcnJhaW5Db3VudHNbaV09CQCkAwEJAJEDAgUNdGVycmFpbkNvdW50cwUBaQIQLCBsYW5kU2l6ZUluZGV4PQkApAMBBQ1sYW5kU2l6ZUluZGV4CQDNCAIFA2FjYwkApAMBBQZyZXN1bHQEAXIKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQd1cGRhdGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGCQC5CQIFAXICAV8BEXVwZGF0ZVByb3BvcnRpb25zAw10ZXJyYWluQ291bnRzDWxhbmRTaXplSW5kZXgEc2lnbgQIcHJvcExpc3QJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBCQERa2V5UmVzUHJvcG9ydGlvbnMAAgswXzBfMF8wXzBfMAIBXwkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwEBQhwcm9wTGlzdAUNdGVycmFpbkNvdW50cwUNbGFuZFNpemVJbmRleAUEc2lnbgENY291bnRUZXJyYWlucwEIdGVycmFpbnMJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBQQABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUIAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFDAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBRAABCQDMCAIJAGUCCQCQAwEJALUJAgUI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aFJlcw5jdXJyZW50UGFja1JlcwpyZXNUb0NsYWltC3doU3BhY2VMZWZ0BA5yZXNMaXN0VG9DbGFpbQgFCnJlc1RvQ2xhaW0CXzEEDHJlc0FtVG9DbGFpbQgFCnJlc1RvQ2xhaW0CXzIDCQAAAgUMcmVzQW1Ub0NsYWltAAAJAJQKAgkAuQkCBQxjdXJyZW50V2hSZXMCAV8JALkJAgUOY3VycmVudFBhY2tSZXMCAV8DCQBnAgULd2hTcGFjZUxlZnQFDHJlc0FtVG9DbGFpbQoBCGFkZExpc3RzAgNhY2MBaQkAzQgCBQNhY2MJAKQDAQkAZAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQxjdXJyZW50V2hSZXMFAWkJAJEDAgUOcmVzTGlzdFRvQ2xhaW0FAWkEAXIKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhhZGRMaXN0cwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgkAlAoCCQC5CQIFAXICAV8JALkJAgUOY3VycmVudFBhY2tSZXMCAV8KAQxhZGRQYXJ0TGlzdHMCA2FjYwFpBAZ3aFBhcnQJAGsDCQCRAwIFDnJlc0xpc3RUb0NsYWltBQFpBQt3aFNwYWNlTGVmdAUMcmVzQW1Ub0NsYWltCQCUCgIJAM0IAggFA2FjYwJfMQkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDGN1cnJlbnRXaFJlcwUBaQUGd2hQYXJ0CQDNCAIIBQNhY2MCXzIJAKQDAQkAZQIJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUOY3VycmVudFBhY2tSZXMFAWkJAJEDAgUOcmVzTGlzdFRvQ2xhaW0FAWkFBndoUGFydAQBcgoAAiRs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MF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIBCW1vdmVTdHVmZgMKY2FyZ29QYXJ0cwljdXJyZW50V2gLY3VycmVudFBhY2sDCQECIT0CCQCQAwEFCmNhcmdvUGFydHMAAwkAAgECNGNhcmdvTGlzdFN0ciBzaG91bGQgY29udGFpbiBleGFjdGx5IDIgJzonIHNlcGFyYXRvcnMECHJlc1BhcnRzCQC1CQIJAJEDAgUKY2FyZ29QYXJ0cwAAAgFfBAhtYXRQYXJ0cwkAtQkCCQCRAwIFCmNhcmdvUGFydHMAAQIBXwQJcHJvZFBhcnRzAwkAAAIJAJEDAgUKY2FyZ29QYXJ0cwACAgAFA25pbAkAtQkCCQCRAwIFCmNhcmdvUGFydHMAAgIBXwMJAQIhPQIJAJADAQUIcmVzUGFydHMFBk5VTVJFUwkAAgECIEFsbCA2IHJlc291cmNlcyBzaG91bGQgYmUgcGFzc2VkAwkBAiE9AgkAkAMBBQhtYXRQYXJ0cwUGTlVNUkVTCQACAQIgQWxsIDYgbWF0ZXJpYWxzIHNob3VsZCBiZSBwYXNzZWQEDGN1cnJXaFJlc1ZvbAkBGWdldFdhcmVob3VzZUN1cnJSZXNWb2x1bWUBBQljdXJyZW50V2gEDGN1cnJXaE1hdFZvbAkBGWdldFdhcmVob3VzZUN1cnJNYXRWb2x1bWUBBQljdXJyZW50V2gEDmN1cnJXaEdvb2RzVm9sCQEbZ2V0V2FyZWhvdXNlQ3Vyckdvb2RzVm9sdW1lAQUJY3VycmVudFdoBA9jdXJyV2hMb2NrZWRWb2wJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQljdXJyZW50V2gFDndoSWR4TG9ja2VkVm9sBAt3aFNwYWNlTGVmdAkAZQIJAGUCCQBlAgkAZQIJARJnZXRXYXJlaG91c2VWb2x1bWUBCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhWb2wFDGN1cnJXaFJlc1ZvbAUMY3VycldoTWF0Vm9sBQ5jdXJyV2hHb29kc1ZvbAUPY3VycldoTG9ja2VkVm9sBAljdXJyV2hSZXMJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBAljdXJyV2hNYXQJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4TWF0AgFfBApjdXJyV2hQcm9kAwkAAAIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAAUDbmlsCQC1CQIJAJEDAgUJY3VycmVudFdoBQl3aElkeFByb2QCAV8EDmN1cnJlbnRQYWNrUmVzCQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAgFfBA5jdXJyZW50UGFja01hdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQPY3VycmVudFBhY2tQcm9kAwkAAAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAIABQNuaWwJALUJAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kAgFfCgEDbXZSAgNhY2MEaXRlbQQBaQgFA2FjYwJfMQQCYW0JAQ1wYXJzZUludFZhbHVlAQUEaXRlbQQDd2hyCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUJY3VycldoUmVzBQFpBANicHIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5jdXJyZW50UGFja1JlcwUBaQMJAAACBQJhbQAACQCWCgQJAGQCBQFpAAEJAM0IAggFA2FjYwJfMgkAkQMCBQljdXJyV2hSZXMFAWkJAM0IAggFA2FjYwJfMwkAkQMCBQ5jdXJyZW50UGFja1JlcwUBaQgFA2FjYwJfNAMJAGYCBQJhbQAAAwkAZgIFAmFtBQNicHIJAAIBCQCsAgIJAKwCAgkArAICCQCsAgICEEF0dGVtcHQgdG8gdGFrZSAFBGl0ZW0CGSBmcm9tIGJhY2twYWNrLCBidXQgb25seSAJAKQDAQUD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CQDMCAIFCHRlcnJhaW5zCQDMCAIFCWNvbnRpbmVudAUDbmlsAgFfAAEAAAcEB2Fzc2V0SWQJALgIAQUFaXNzdWUEAmlkCQDYBAEFB2Fzc2V0SWQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmtleU5leHRGcmVlTGFuZE51bQAJAGQCBQdmcmVlTnVtAAEJAMwIAgUFaXNzdWUJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleUxhbmRUb0Fzc2V0SWQBBQdsYW5kTnVtBQJpZAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQUCaWQFCHVzZXJBZGRyCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlMYW5kTnVtVG9Pd25lcgEFB2xhbmROdW0FCHVzZXJBZGRyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFAmlkAAAJAMwIAgkBDEludGVnZXJFbnRyeQIJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQJpZAUIdXNlckFkZHIAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZjYWxsZXIAAQUHYXNzZXRJZAUDbmlsCQCUCgIFAmlkBQljb250aW5lbnQBEGV4cGVkaXRpb25Db21tb24FDHNob3VsZFVzZU1hdAZjYWxsZXIEdHhJZAdtZXNzYWdlA3NpZwMJAQEhAQkAxBMDBQdtZXNzYWdlBQNzaWcFA3B1YgkAAgECGHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaAQFcGFydHMJALUJAgkAsAkBBQdtZXNzYWdlAgE7BAJocAkAtQkCCQCRAwIJALUJAgkAkQMCBQVwYXJ0cwAAAgF8AAACAV8EBWN1ckhQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaHAAAAQFbmV3SFAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJocAABBApsb2NBbmRUaW1lCQC1CQIJAJEDAgUFcGFydHMAAQIBOgQOdGFyZ2V0TG9jYXRpb24JALUJAgkAkQMCBQpsb2NBbmRUaW1lAAACAV8DCQECIT0CCQCRAwIFDnRhcmdldExvY2F0aW9uAAECAUUJAAIBAitleHBlZGl0aW9uIHRhcmdldCBsb2NhdGlvbiB0eXBlIHNob3VsZCBiZSBFBAR0aW1lCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKbG9jQW5kVGltZQABAwMJAGYCBQR0aW1lCQBkAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFEUZJVkVNSU5VVEVTTUlMTElTBgkAZgIJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAURRklWRU1JTlVURVNNSUxMSVMFBHRpbWUJAAIBAhJzaWduYXR1cmUgb3V0ZGF0ZWQECHVzZXJBZGRyCQClCAEFBmNhbGxlcgQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQh1c2VyQWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAxvbGRGcm9tU3RhdGUJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQDCQECIT0CBQxvbGRGcm9tU3RhdGUFBWN1ckhQCQACAQkArAICCQCsAgIJAKwCAgIKb2xkSGVhbHRoPQkApAMBCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aABkAi8gZnJvbSBzdGF0ZSBkb2VzIG5vdCBtYXRjaCBvbmUgZnJvbSBmbGlnaHQgbG9nPQkApAMBBQVjdXJIUAMJAGcCAAAFBWN1ckhQCQACAQIeWW91IGNhbid0IGZseSB3aXRoIHplcm8gaGVhbHRoAwkAZwIAAAUFbmV3SFAJAJQKAgkAzQgCAwkBASEBBQxzaG91bGRVc2VNYXQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyBQdFWFBVU0RUBQt1c2R0QXNzZXRJZAUDbmlsBQNuaWwJAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgAAAIABAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQFbUxpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8EBm5ld01hdAkAuQkCCQERc3VidHJhY3RNYXRlcmlhbHMDBQxzaG91bGRVc2VNYXQFBW1MaXN0BQxFWFBNQVRFUklBTFMCAV8EAWUJARJleHBlZGl0aW9uSW50ZXJuYWwCBQZjYWxsZXIFBHR4SWQEAmlkCAgFAWUCXzICXzEJAJQKAgkAzQgCCQDNCAIJAM0IAggFAWUCXzEJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAuQkCCQDMCAIICAUBZQJfMgJfMgkAzAgCAgFMCQDMCAIFAmlkBQNuaWwCAV8JAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgFBW5ld0hQCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAMwIAgUGbmV3TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6BQJpZAEMYXBwbHlCb251c2VzAgtsYW5kQXNzZXRJZAZwaWVjZXMECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAlhcnRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQDCQELdmFsdWVPckVsc2UCCQCgCAEJAR9rZXlQcmVzYWxlQXJ0QWN0aXZhdGVkQnlBc3NldElkAQULbGFuZEFzc2V0SWQHBQZwaWVjZXMAAAQEYWRkNgkAaQIFCmluZnJhTGV2ZWwABgQEYWRkNwkAaQIFCmluZnJhTGV2ZWwABwkAZAIJAGQCBQ9EQUlMWVJFU0JZUElFQ0UJAGsDBQ9EQUlMWVJFU0JZUElFQ0UJAGQCCQBkAgUKaW5mcmFMZXZlbAUEYWRkNgkAaAIAAgUEYWRkNwAFCQBrAwUPREFJTFlSRVNCWVBJRUNFBQlhcnRQaWVjZXMJAGgCBQZwaWVjZXMABQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBGFkZHIJY2xhaW1Nb2RlDWxhbmRBc3NldElkSW4EDSR0MDI0NDI5MjQ5NjgDCQAAAgUJY2xhaW1Nb2RlBQtjbGFpbU1vZGVXaAkAlAoCBQ1sYW5kQXNzZXRJZEluCQELdmFsdWVPckVsc2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMCQCUCgIJAJEDAgUDbG9jBQhsb2NJZHhJZAULZHVja0Fzc2V0SWQEC2xhbmRBc3NldElkCAUNJHQwMjQ0MjkyNDk2OAJfMQQGZHVja0lkCAUNJHQwMjQ0MjkyNDk2OAJfMgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQtsYW5kQXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAQJc2F2ZWRUaW1lCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUHdGltZUtleQkArAICCQCsAgICBUxhbmQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAFkCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwkAlgoEBQZkdWNrSWQFC2xhbmRBc3NldElkBQFkBQlzYXZlZFRpbWUBEGNsYWltUmVzSW50ZXJuYWwEBGFkZHIGYW1vdW50CWNsYWltTW9kZQ1sYW5kQXNzZXRJZEluAwkAZgIAAAUGYW1vdW50CQACAQIPTmVnYXRpdmUgYW1vdW50BAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMDBQRhZGRyBQljbGFpbU1vZGUFDWxhbmRBc3NldElkSW4ECGxhbmRTaXplCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQNdGVycmFpbkNvdW50cwkBDWNvdW50VGVycmFpbnMBCQCRAwIIBQFjAl8zBQtyZWNUZXJyYWlucwQJZGVsdGFUaW1lCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAIBQFjAl80AwkAZgIAAAUJZGVsdGFUaW1lCQACAQkArAICCQCsAgIJAKwCAgImU2F2ZWQgdGltZXN0YW1wIGlzIGluIGZ1dHVyZSwgc2F2ZWQgPSAJAKQDAQgFAWMCXzQCDCwgY3VycmVudCA9IAkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUEFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQxhcHBseUJvbnVzZXMCCAUBYwJfMgUGcGllY2VzBAhhdmFpbFJlcwkAawMFCWRlbHRhVGltZQkAaAIFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UFBnBpZWNlcwUJREFZTUlMTElTAwkAZgIFBmFtb3VudAUIYXZhaWxSZXMJAAIBCQCsAgIJAKwCAgkArAICAiJOb3QgZW5vdWdoIHJlc291cmNlcywgYXZhaWxhYmxlID0gCQCkAwEFCGF2YWlsUmVzAg4sIHJlcXVlc3RlZCA9IAkApAMBBQZhbW91bnQEDG5ld0RlbHRhVGltZQkAawMJAGUCBQhhdmFpbFJlcwUGYW1vdW50BQlEQVlNSUxMSVMJAGgCBRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBQZwaWVjZXMEDG5ld1RpbWVzdGFtcAkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQxuZXdEZWx0YVRpbWUECWxhbmRJbmRleAkAaQIFBnBpZWNlcwUFU1NJWkUECnJlc1RvQ2xhaW0JAQl2aXJ0Q2xhaW0EBQ10ZXJyYWluQ291bnRzCQBlAgUJZGVsdGFUaW1lBQxuZXdEZWx0YVRpbWUFCWxhbmRJbmRleAUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBCAUBYwJfMgQKaW5mcmFMZXZlbAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEIBQFjAl8yAAAECWN1cnJlbnRXaAkBDGdldFdhcmVob3VzZQMFBXdoS2V5BQlsYW5kSW5kZXgFCmluZnJhTGV2ZWwEDGN1cnJXaFJlc1ZvbAkBGWdldFdhcmVob3VzZUN1cnJSZXNWb2x1bWUBBQljdXJyZW50V2gEDGN1cnJXaE1hdFZvbAkBGWdldFdhcmVob3VzZUN1cnJNYXRWb2x1bWUBBQljdXJyZW50V2gEDmN1cnJXaEdvb2RzVm9sCQEbZ2V0V2FyZWhvdXNlQ3Vyckdvb2RzVm9sdW1lAQUJY3VycmVudFdoBA9jdXJyV2hMb2NrZWRWb2wJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQljdXJyZW50V2gFDndoSWR4TG9ja2VkVm9sBAt3aFNwYWNlTGVmdAkAZQIJAGUCCQBlAgkAZQIJARJnZXRXYXJlaG91c2VWb2x1bWUBCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhWb2wFDGN1cnJXaFJlc1ZvbAUMY3VycldoTWF0Vm9sBQ5jdXJyV2hHb29kc1ZvbAUPY3VycldoTG9ja2VkVm9sAwMJAAACBQljbGFpbU1vZGUFC2NsYWltTW9kZVdoCQBmAgUGYW1vdW50BQt3aFNwYWNlTGVmdAcJAAIBCQCsAgIJAKwCAgIFT25seSAJAKQDAQULd2hTcGFjZUxlZnQCGCBzcGFjZSBsZWZ0IGluIHdhcmVob3VzZQQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEIBQFjAl8xBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEDmN1cnJlbnRQYWNrUmVzCQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAgFfBAxjdXJyZW50V2hSZXMJALUJAgkAkQMCBQljdXJyZW50V2gFCHdoSWR4UmVzAgFfBA0kdDAyNzYxNjI4MTE5AwkAAAIFCWNsYWltTW9kZQULY2xhaW1Nb2RlV2gJAJQKAgkBBmFkZFJlcwUFDGN1cnJlbnRXaFJlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzAwkAAAIFCWNsYWltTW9kZQUNY2xhaW1Nb2RlRHVjawkAlAoCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhSZXMJAQZhZGRSZXMFBQ5jdXJyZW50UGFja1JlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lBQlsYW5kSW5kZXgFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UJAQ1kaXN0cmlidXRlUmVzBAUMY3VycmVudFdoUmVzBQ5jdXJyZW50UGFja1JlcwUKcmVzVG9DbGFpbQULd2hTcGFjZUxlZnQEBXdoUmVzCAUNJHQwMjc2MTYyODExOQJfMQQFYnBSZXMIBQ0kdDAyNzYxNjI4MTE5Al8yCQCXCgUJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQgFAWMCXzIFDG5ld1RpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYCAUBYwJfMgUEYWRkcgUMbmV3VGltZXN0YW1wBQNuaWwFBWJwS2V5CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgUFYnBSZXMJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwFBXdoS2V5CQDMCAIJAJEDAgUJY3VycmVudFdoBQh3aElkeFZvbAkAzAgCBQV3aFJlcwkAzAgCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhNYXQJAMwIAgkAkQMCBQljdXJyZW50V2gFCXdoSWR4UHJvZAkAzAgCCQCRAwIFCWN1cnJlbnRXaAUOd2hJZHhMb2NrZWRWb2wFA25pbAEIY2xhaW1BbGwEBGFkZHILbGFuZEFzc2V0SWQGcGllY2VzCWNsYWltTW9kZQQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAQJc2F2ZWRUaW1lCQEFdmFsdWUBCQCfCAEFB3RpbWVLZXkECGF2YWlsUmVzCQBoAgkAawMJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUJc2F2ZWRUaW1lCQEMYXBwbHlCb251c2VzAgULbGFuZEFzc2V0SWQFBnBpZWNlcwUJREFZTUlMTElTBQZwaWVjZXMJARBjbGFpbVJlc0ludGVybmFsBAUEYWRkcgUIYXZhaWxSZXMFCWNsYWltTW9kZQULbGFuZEFzc2V0SWQBDXVwSW5mcmFDb21tb24EDHNob3VsZFVzZU1hdAZjYWxsZXINcGF5bWVudEFtb3VudAtsYW5kQXNzZXRJZAQEYWRkcgkApQgBBQZjYWxsZXIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFE2NsYWltTW9kZVdoVGhlbkR1Y2sFC2xhbmRBc3NldElkBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQIaW5mcmFLZXkJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQgFAWMCXzIECGN1ckxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEFCGluZnJhS2V5AAADCQBnAgUIY3VyTGV2ZWwAAwkAAgECJkN1cnJlbnRseSBtYXggaW5mcmFzdHJ1Y3R1cmUgbGV2ZWwgPSAzBAhuZXdMZXZlbAkAZAIFCGN1ckxldmVsAAEEBGNvc3QJAGsDBRVJbmZyYVVwZ3JhZGVDb3N0U1VzZHQJAGgCBQZwaWVjZXMFCG5ld0xldmVsBQVTU0laRQMDCQEBIQEFDHNob3VsZFVzZU1hdAkBAiE9AgUNcGF5bWVudEFtb3VudAUEY29zdAcJAAIBCQCsAgICG1BheW1lbnQgYXR0YWNoZWQgc2hvdWxkIGJlIAkApAMBBQRjb3N0BAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQgFAWMCXzEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQFbUxpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8EBm5ld01hdAkAuQkCCQERc3VidHJhY3RNYXRlcmlhbHMDBQxzaG91bGRVc2VNYXQFBW1MaXN0CQBrAwURSW5mcmFVcGdyYWRlQ29zdFMJAGgCBQZwaWVjZXMFCG5ld0xldmVsBQVTU0laRQIBXwQLY2xhaW1SZXN1bHQJAQhjbGFpbUFsbAQFBGFkZHIIBQFjAl8yBQZwaWVjZXMFE2NsYWltTW9kZVdoVGhlbkR1Y2sEBndoRGF0YQgFC2NsYWltUmVzdWx0Al81BApuZXdWb2xEYXRhCQC5CQIJAMwIAgkAkQMCCQC1CQIJAJEDAgUGd2hEYXRhBQh3aElkeFZvbAIBXwAACQDMCAIJAKQDAQUIbmV3TGV2ZWwFA25pbAIBXwkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFCGluZnJhS2V5BQhuZXdMZXZlbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIIBQFjAl8yBQRhZGRyBQhuZXdMZXZlbAkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCCAULY2xhaW1SZXN1bHQCXzMFCGJwSWR4UmVzCQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgkAzAgCCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzQJALkJAgkAzAgCBQpuZXdWb2xEYXRhCQDMCAIJAJEDAgUGd2hEYXRhBQh3aElkeFJlcwkAzAgCCQCRAwIFBndoRGF0YQUId2hJZHhNYXQJAMwIAgkAkQMCBQZ3aERhdGEFCXdoSWR4UHJvZAkAzAgCCQCRAwIFBndoRGF0YQUOd2hJZHhMb2NrZWRWb2wFA25pbAIBOgUDbmlsCAULY2xhaW1SZXN1bHQCXzEFCG5ld0xldmVsARJhY3RpdmF0ZVByZXNhbGVBcnQCBGFkZHINbGFuZEFzc2V0SWRJbgQBYwkBFGNoZWNrQ2xhaW1Db25kaXRpb25zAwUEYWRkcgUTY2xhaW1Nb2RlV2hUaGVuRHVjawUNbGFuZEFzc2V0SWRJbgQLbGFuZEFzc2V0SWQIBQFjAl8yBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQNYWN0aXZhdGlvbktleQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQDCQBmAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ1hY3RpdmF0aW9uS2V5AwkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEfa2V5UHJlc2FsZUFydEFjdGl2YXRlZEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBwUGcGllY2VzAAAAAAkAAgECJVByZXNhbGUgYXJ0aWZhY3QgaXMgYWxyZWFkeSBhY3RpdmF0ZWQDCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIIBQFjAl8zBQpyZWNMYW5kTnVtBQ9QUkVTQUxFTlVNTEFORFMJAAIBCQCsAgIJAKwCAgkArAICBQpMQU5EUFJFRklYAgEgBQtsYW5kQXNzZXRJZAIlIGlzIG5vdCBlbGlnaWJsZSBmb3IgcHJlc2FsZSBhcnRpZmFjdAQLY2xhaW1SZXN1bHQJAQhjbGFpbUFsbAQFBGFkZHIFC2xhbmRBc3NldElkBQZwaWVjZXMFE2NsYWltTW9kZVdoVGhlbkR1Y2sJAM0IAgkAzQgCCQDNCAIJAM0IAggFC2NsYWltUmVzdWx0Al8xCQEMSW50ZWdlckVudHJ5AgUNYWN0aXZhdGlvbktleQUGcGllY2VzCQEMSW50ZWdlckVudHJ5AgkBJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAUEYWRkcgUGcGllY2VzCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzIJALkJAggFC2NsYWltUmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzQJALkJAggFC2NsYWltUmVzdWx0Al81AgE6AQ1tZXJnZUludGVybmFsBwtuZXdMYW5kU2l6ZQhuZXdMZXZlbAdmb3JtdWxhBGFkZHIMbGFuZEFzc2V0SWRzBHR4SWQHbmVlZE1hdAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkCgEKY2hlY2tNZXJnZQIDYWNjC2xhbmRBc3NldElkBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBAlzYXZlZFRpbWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQd0aW1lS2V5CQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8ECWNvbnRpbmVudAkAkQMCBQFkBQxyZWNDb250aW5lbnQDAwkBAiE9AggFA2FjYwJfMwIACQECIT0CCAUDYWNjAl8zBQljb250aW5lbnQHCQACAQIuTGFuZHMgc2hvdWxkIGJlIG9uIHRoZSBzYW1lIGNvbnRpbmVudCB0byBtZXJnZQQIbGFuZFNpemUJAJEDAgUBZAULcmVjTGFuZFNpemUEB3NpemVzSW4IBQNhY2MCXzEEAWkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAswkCBQdzaXplc0luBQhsYW5kU2l6ZQInWW91IGhhdmVuJ3QgcGFzc2VkIGFsbCB0aGUgbGFuZHMgbmVlZGVkBAhzaXplc091dAkArAICCQCvAgIFB3NpemVzSW4FAWkJALACAgUHc2l6ZXNJbgkAZAIFAWkAAQQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUEBGFydHMJAGQCCAUDYWNjAl8yCQELdmFsdWVPckVsc2UCCQCfCAEJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkAwkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEfa2V5UHJlc2FsZUFydEFjdGl2YXRlZEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBwUGcGllY2VzAAAECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAhyZXFMZXZlbAQHJG1hdGNoMAUIbGFuZFNpemUDCQAAAgIBUwUHJG1hdGNoMAADAwkAAAICAU0FByRtYXRjaDAABAMJAAACAgFMBQckbWF0Y2gwAAUDCQAAAgICWEwFByRtYXRjaDAABgkAAgECGk9ubHkgUywgTSwgTCwgWEwgY2FuIG1lcmdlAwkBAiE9AgUKaW5mcmFMZXZlbAUIcmVxTGV2ZWwJAAIBAiJBbGwgbGFuZHMgc2hvdWxkIGJlIG1heGVkIHRvIG1lcmdlBAdsYW5kTnVtCQCRAwIFAWQFCnJlY0xhbmROdW0EDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQJZGVsdGFUaW1lCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFCXNhdmVkVGltZQMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEFCXNhdmVkVGltZQIMLCBjdXJyZW50ID0gCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBBZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQEMYXBwbHlCb251c2VzAgULbGFuZEFzc2V0SWQFBnBpZWNlcwQJbGFuZEluZGV4CQBpAgUGcGllY2VzBQVTU0laRQQFYnBSZXMJAQZhZGRSZXMFCQC1CQIIBQNhY2MCXzQCAV8FDXRlcnJhaW5Db3VudHMFCWRlbHRhVGltZQUJbGFuZEluZGV4BRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBAVwcm9wcwkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECQC1CQIIBQNhY2MCXzYCAV8FDXRlcnJhaW5Db3VudHMFCWxhbmRJbmRleAD///////////8BBAVsYW5kcwgFA2FjYwJfNwQDaWR4CQDPCAIFBWxhbmRzBQtsYW5kQXNzZXRJZAMJAQEhAQkBCWlzRGVmaW5lZAEFA2lkeAkAAgEJAKwCAgIgWW91ciBzdGFrZWQgbGFuZHMgZG9uJ3QgY29udGFpbiAFC2xhbmRBc3NldElkBAljdXN0b21LZXkJARprZXlMYW5kQXNzZXRJZFRvQ3VzdG9tTmFtZQEFC2xhbmRBc3NldElkBApjdXN0b21OYW1lCQELdmFsdWVPckVsc2UCCQCiCAEFCWN1c3RvbUtleQIACQCZCgcFCHNpemVzT3V0BQRhcnRzBQljb250aW5lbnQFBWJwUmVzCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAggFA2FjYwJfNQkBC0RlbGV0ZUVudHJ5AQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBEGtleUxhbmRUb0Fzc2V0SWQBBQdsYW5kTnVtCQELRGVsZXRlRW50cnkBCQEKa2V5TmZ0TmFtZQIFB2xhbmROdW0FCGxhbmRTaXplCQELRGVsZXRlRW50cnkBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJASVrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQFBGFkZHIJAQtEZWxldGVFbnRyeQEJARFrZXlMYW5kTnVtVG9Pd25lcgEFB2xhbmROdW0JAQtEZWxldGVFbnRyeQEJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAkBC0RlbGV0ZUVudHJ5AQUJY3VzdG9tS2V5CQELRGVsZXRlRW50cnkBCQEaa2V5TGFuZEN1c3RvbU5hbWVUb0Fzc2V0SWQBBQpjdXN0b21OYW1lCQEEQnVybgIJANkEAQULbGFuZEFzc2V0SWQAAQUFcHJvcHMJANEIAgUFbGFuZHMJAQV2YWx1ZQEFA2lkeAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEB3Byb3BTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBEWtleVJlc1Byb3BvcnRpb25zAAILMF8wXzBfMF8wXzAECGxhbmRzS2V5CQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUEYWRkcgQIbGFuZHNTdHIJAKIIAQUIbGFuZHNLZXkEB2xhbmRzSW4DCQEJaXNEZWZpbmVkAQUIbGFuZHNTdHIJAL0JAgkBBXZhbHVlAQUIbGFuZHNTdHICAV8FA25pbAQBcgoAAiRsBQxsYW5kQXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCZCgcFB2Zvcm11bGEAAAIACQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwUDbmlsBQdwcm9wU3RyBQdsYW5kc0luCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpjaGVja01lcmdlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQQJY29udGluZW50CAUBcgJfMwQMY29udGluZW50SWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgUKY29udGluZW50cwUJY29udGluZW50CQCsAgICE1Vua25vd24gY29udGluZW50OiAFCWNvbnRpbmVudAQIdGVycmFpbnMJAQtnZW5UZXJyYWlucwIJAQNhYnMBCQCeAwEFBHR4SWQFDGNvbnRpbmVudElkeAQHZnJlZU51bQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFD1BSRVNBTEVOVU1MQU5EUwABBApuZXdMYW5kTnVtCQCkAwEFB2ZyZWVOdW0EBWlzc3VlCQDCCAUJAQprZXlOZnROYW1lAgUKbmV3TGFuZE51bQULbmV3TGFuZFNpemUJALkJAgkAzAgCBQpuZXdMYW5kTnVtCQDMCAIFC25ld0xhbmRTaXplCQDMCAIFCHRlcnJhaW5zCQDMCAIFCWNvbnRpbmVudAUDbmlsAgFfAAEAAAcEB2Fzc2V0SWQJALgIAQUFaXNzdWUEDm5ld0xhbmRBc3NldElkCQDYBAEFB2Fzc2V0SWQEBm5ld01hdAkAuQkCCQERc3VidHJhY3RNYXRlcmlhbHMDCQBmAgUHbmVlZE1hdAAACQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBQduZWVkTWF0AgFfCQCUCgIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCAUBcgJfNQMJAGYCCQCQAwEIBQFyAl83AAAJAQtTdHJpbmdFbnRyeQIFCGxhbmRzS2V5CQC7CQIIBQFyAl83AgFfCQELRGVsZXRlRW50cnkBBQhsYW5kc0tleQkBDEludGVnZXJFbnRyeQIJARJrZXlOZXh0RnJlZUxhbmROdW0ACQBkAgUHZnJlZU51bQABBQVpc3N1ZQkBC1N0cmluZ0VudHJ5AgkBEGtleUxhbmRUb0Fzc2V0SWQBBQpuZXdMYW5kTnVtBQ5uZXdMYW5kQXNzZXRJZAkBC1N0cmluZ0VudHJ5AgkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFDm5ld0xhbmRBc3NldElkBQRhZGRyCQELU3RyaW5nRW50cnkCCQERa2V5TGFuZE51bVRvT3duZXIBBQpuZXdMYW5kTnVtBQRhZGRyCQEMSW50ZWdlckVudHJ5AgkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQUObmV3TGFuZEFzc2V0SWQIBQFyAl8yCQEMSW50ZWdlckVudHJ5AgkBJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBQpBUlRQUkVTQUxFBQ5uZXdMYW5kQXNzZXRJZAUEYWRkcggFAXICXzIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFDm5ld0xhbmRBc3NldElkBQhuZXdMZXZlbAkBDEludGVnZXJFbnRyeQIJAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICBQ5uZXdMYW5kQXNzZXRJZAUEYWRkcgUIbmV3TGV2ZWwJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCAUBcgJfNAkAzAgCBQZuZXdNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToJAQtTdHJpbmdFbnRyeQIJARFrZXlSZXNQcm9wb3J0aW9ucwAIBQFyAl82CQELU3RyaW5nRW50cnkCCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQJALkJAgkAzAgCBQljb250aW5lbnQJAMwIAgIBTAkAzAgCBQ5uZXdMYW5kQXNzZXRJZAUDbmlsAgFfCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQRhZGRyAAEFB2Fzc2V0SWQFDm5ld0xhbmRBc3NldElkAQNzMm0DBGFkZHIMbGFuZEFzc2V0SWRzBHR4SWQJAQ1tZXJnZUludGVybmFsBwIBTQADAgRTU1NTBQRhZGRyBQxsYW5kQXNzZXRJZHMFBHR4SWQAAAEDbTJsBQRhZGRyDGxhbmRBc3NldElkcwR0eElkDHNob3VsZFVzZU1hdA1wYXltZW50QW1vdW50BARjb3N0CQBoAgUVSW5mcmFVcGdyYWRlQ29zdFNVc2R0AAQDAwkBASEBBQxzaG91bGRVc2VNYXQJAQIhPQIFDXBheW1lbnRBbW91bnQFBGNvc3QHCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUEY29zdAkBDW1lcmdlSW50ZXJuYWwHAgFMAAQCA1NNTQUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkCQBoAgURSW5mcmFVcGdyYWRlQ29zdFMABAEEbDJ4bAUEYWRkcgxsYW5kQXNzZXRJZHMEdHhJZAxzaG91bGRVc2VNYXQNcGF5bWVudEFtb3VudAQEY29zdAkAaAIFFUluZnJhVXBncmFkZUNvc3RTVXNkdAAvAwMJAQEhAQUMc2hvdWxkVXNlTWF0CQECIT0CBQ1wYXltZW50QW1vdW50BQRjb3N0BwkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFBGNvc3QJAQ1tZXJnZUludGVybmFsBwICWEwABQIFU1NTTUwFBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAkAaAIFEUluZnJhVXBncmFkZUNvc3RTAC8BBnhsMnh4bAUEYWRkcgxsYW5kQXNzZXRJZHMEdHhJZAxzaG91bGRVc2VNYXQNcGF5bWVudEFtb3VudAQEY29zdAkAaAIFFUluZnJhVXBncmFkZUNvc3RTVXNkdAA2AwMJAQEhAQUMc2hvdWxkVXNlTWF0CQECIT0CBQ1wYXltZW50QW1vdW50BQRjb3N0BwkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFBGNvc3QJAQ1tZXJnZUludGVybmFsBwIDWFhMAAYCA0xYTAUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkCQBoAgURSW5mcmFVcGdyYWRlQ29zdFMANgELbWVyZ2VDb21tb24FDHNob3VsZFVzZU1hdARhZGRyDXBheW1lbnRBbW91bnQMbGFuZEFzc2V0SWRzBHR4SWQEC21lcmdlUmVzdWx0BAckbWF0Y2gwCQCQAwEFDGxhbmRBc3NldElkcwMJAAACAAQFByRtYXRjaDAJAQNzMm0DBQRhZGRyBQxsYW5kQXNzZXRJZHMFBHR4SWQDCQAAAgADBQckbWF0Y2gwCQEDbTJsBQUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkBQxzaG91bGRVc2VNYXQFDXBheW1lbnRBbW91bnQDCQAAAgAFBQckbWF0Y2gwCQEEbDJ4bAUFBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAUMc2hvdWxkVXNlTWF0BQ1wYXltZW50QW1vdW50AwkAAAIAAgUHJG1hdGNoMAkBBnhsMnh4bAUFBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAUMc2hvdWxkVXNlTWF0BQ1wYXltZW50QW1vdW50CQACAQINVW5rbm93biBtZXJnZQULbWVyZ2VSZXN1bHQBBnByb2xvZwEBaQMDCQECIT0CCAUBaQxvcmlnaW5DYWxsZXIFDHJlc3RDb250cmFjdAkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEKa2V5QmxvY2tlZAAHBwkAAgECH0NvbnRyYWN0cyBhcmUgdW5kZXIgbWFpbnRlbmFuY2UJAQtTdHJpbmdFbnRyeQIJARFrZXlMYXN0VHhJZEJ5VXNlcgEJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQcAWkBDWNvbnN0cnVjdG9yVjEBCHJlc3RBZGRyAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIRUGVybWlzc2lvbiBkZW5pZWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDmtleVJlc3RBZGRyZXNzAAUIcmVzdEFkZHIFA25pbAFpAQpzZXRCbG9ja2VkAQlpc0Jsb2NrZWQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBCmtleUJsb2NrZWQABQlpc0Jsb2NrZWQFA25pbAFpAQlzdGFrZUxhbmQABAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkxBTkRQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMJAQIhPQIIBQVhc3NldAZpc3N1ZXIFBHRoaXMJAAIBAhdVbmtub3duIGlzc3VlciBvZiB0b2tlbgMJAQEhAQkBCGNvbnRhaW5zAggFBWFzc2V0BG5hbWUFCkxBTkRQUkVGSVgJAAIBCQCsAgIJAKwCAgIJT25seSBORlQgBQpMQU5EUFJFRklYAhQgdG9rZW5zIGFyZSBhY2NlcHRlZAQLbGFuZE51bVNpemUJALACAggFBWFzc2V0BG5hbWUABAQHbGFuZE51bQMJAQhjb250YWlucwIFC2xhbmROdW1TaXplAgNYWEwJALMCAgULbGFuZE51bVNpemUAAwMJAQhjb250YWlucwIFC2xhbmROdW1TaXplAgJYTAkAswICBQtsYW5kTnVtU2l6ZQACCQCzAgIFC2xhbmROdW1TaXplAAEDCQEBIQEJAQlpc0RlZmluZWQBCQC2CQEFB2xhbmROdW0JAAIBCQCsAgICHkNhbm5vdCBwYXJzZSBsYW5kIG51bWJlciBmcm9tIAgFBWFzc2V0BG5hbWUEC2xhbmRBc3NldElkCQDYBAEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQDCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAhIgaXMgYWxyZWFkeSBzdGFrZWQEAWQJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAgUBZAULcmVjVGVycmFpbnMEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgUBZAULcmVjTGFuZFNpemUEBXByb3BzCQERdXBkYXRlUHJvcG9ydGlvbnMDBQ10ZXJyYWluQ291bnRzCQBpAgUGcGllY2VzBQVTU0laRQABBAlhcnRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQDCQELdmFsdWVPckVsc2UCCQCgCAEJAR9rZXlQcmVzYWxlQXJ0QWN0aXZhdGVkQnlBc3NldElkAQULbGFuZEFzc2V0SWQHBQZwaWVjZXMAAAQIbGFuZHNTdHIJAKIIAQkBFWtleVN0YWtlZExhbmRzQnlPd25lcgEFB2FkZHJlc3MEBWxhbmRzAwkBCWlzRGVmaW5lZAEFCGxhbmRzU3RyCQC9CQIJAQV2YWx1ZQEFCGxhbmRzU3RyAgFfBQNuaWwDCQEPY29udGFpbnNFbGVtZW50AgUFbGFuZHMFC2xhbmRBc3NldElkCQACAQkArAICAiJZb3VyIHN0YWtlZCBsYW5kcyBhbHJlYWR5IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgUHdGltZUtleQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKTEFORFBSRUZJWAULbGFuZEFzc2V0SWQFB2FkZHJlc3MIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQdhZGRyZXNzCQC7CQIJAM0IAgUFbGFuZHMFC2xhbmRBc3NldElkAgFfCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5TGFuZE51bVRvT3duZXIBBQdsYW5kTnVtBQdhZGRyZXNzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEla2V5TGFuZEFydFN0YXR1c0J5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkBQdhZGRyZXNzBQlhcnRQaWVjZXMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAUFcHJvcHMJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwBaQELdW5zdGFrZUxhbmQBDWxhbmRBc3NldElkSW4EDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQEYWRkcgkApQgBCAUBaQZjYWxsZXIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwMFBGFkZHIFDWNsYWltTW9kZUR1Y2sFDWxhbmRBc3NldElkSW4EC2xhbmRBc3NldElkCAUBYwJfMgQIbGFuZHNLZXkJARVrZXlTdGFrZWRMYW5kc0J5T3duZXIBBQRhZGRyBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEJAJEDAggFAWMCXzMFC3JlY1RlcnJhaW5zBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQFcHJvcHMJARF1cGRhdGVQcm9wb3J0aW9ucwMFDXRlcnJhaW5Db3VudHMJAGkCBQZwaWVjZXMFBVNTSVpFAP///////////wEEC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwEBQRhZGRyBQtsYW5kQXNzZXRJZAUGcGllY2VzBQ1jbGFpbU1vZGVEdWNrBAVsYW5kcwkAvQkCCQELdmFsdWVPckVsc2UCCQCiCAEFCGxhbmRzS2V5AgACAV8EA2lkeAkAzwgCBQVsYW5kcwULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQNpZHgJAAIBCQCsAgICIFlvdXIgc3Rha2VkIGxhbmRzIGRvbid0IGNvbnRhaW4gBQtsYW5kQXNzZXRJZAQBdAgJAQV2YWx1ZQEJAO0HAQUGaGVpZ2h0CXRpbWVzdGFtcAQLcmVsZWFzZVRpbWUJAQt2YWx1ZU9yRWxzZQIJAJoIAgULZ292Q29udHJhY3QJARVrZXlVc2VyR3dsUmVsZWFzZVRpbWUBBQRhZGRyAAADCQBnAgULcmVsZWFzZVRpbWUFAXQJAAIBCQCsAgICOVlvdXIgZ1dMIGFyZSB0YWtpbmcgcGFydCBpbiB2b3RpbmcsIGNhbm5vdCB1bnN0YWtlIHVudGlsIAkApAMBBQtyZWxlYXNlVGltZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIAAQkA2QQBBQtsYW5kQXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBCQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKTEFORFBSRUZJWAULbGFuZEFzc2V0SWQFBGFkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleVJlc1Byb3BvcnRpb25zAAUFcHJvcHMJAMwIAgkBC1N0cmluZ0VudHJ5AggFC2NsYWltUmVzdWx0Al8yCQC5CQIIBQtjbGFpbVJlc3VsdAJfMwIBOgkAzAgCAwkAZgIJAJADAQUFbGFuZHMAAQkBC1N0cmluZ0VudHJ5AgUIbGFuZHNLZXkJALsJAgkA0QgCBQVsYW5kcwkBBXZhbHVlAQUDaWR4AgFfCQELRGVsZXRlRW50cnkBBQhsYW5kc0tleQkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAFpAQlzdGFrZUR1Y2sABAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkRVQ0tQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMDCQECIT0CCAUFYXNzZXQGaXNzdWVyBQ1pbmN1YmF0b3JBZGRyCQECIT0CCAUFYXNzZXQGaXNzdWVyBQticmVlZGVyQWRkcgcJAAIBCQCsAgIJAKwCAgISVW5rbm93biBpc3N1ZXIgb2YgBQpEVUNLUFJFRklYAgYgdG9rZW4DCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpEVUNLUFJFRklYCQACAQkArAICCQCsAgICCU9ubHkgTkZUIAUKRFVDS1BSRUZJWAIUIHRva2VucyBhcmUgYWNjZXB0ZWQECmFzc2V0SWRTdHIJANgEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQphc3NldElkU3RyAwkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQISIGlzIGFscmVhZHkgc3Rha2VkAwkBCWlzRGVmaW5lZAEJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwkAAgEJAKwCAgIdWW91IGFscmVhZHkgc3Rha2VkIG9uZSBkdWNrOiAIBQVhc3NldARuYW1lBAZsb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQphc3NldElkU3RyBAhsb2NhdGlvbgkAoggBBQZsb2NLZXkEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQphc3NldElkU3RyBAhiYWNrcGFjawkAoggBBQVicEtleQkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd0aW1lS2V5CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpEVUNLUFJFRklYCQDYBAEFB2Fzc2V0SWQFB2FkZHJlc3MIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBrZXlEdWNrSWRUb093bmVyAQUKYXNzZXRJZFN0cgUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzBQphc3NldElkU3RyBQNuaWwDCQEJaXNEZWZpbmVkAQUIbG9jYXRpb24FA25pbAkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBmxvY0tleQUPREVGQVVMVExPQ0FUSU9OBQNuaWwDCQEJaXNEZWZpbmVkAQUIYmFja3BhY2sFA25pbAkAzQgCCQDNCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkCGjA6MF8wXzBfMF8wXzA6MF8wXzBfMF8wXzA6BQNuaWwJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFCmFzc2V0SWRTdHIAZAUMcHJvbG9nQWN0aW9uAWkBC3Vuc3Rha2VEdWNrAQphc3NldElkU3RyBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEBWFzc2V0CQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQkA2AQBBQdhc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAMJAQEhAQkBCWlzRGVmaW5lZAEJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwkAAgEJAKwCAgkArAICAglUaGUgZHVjayAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEQa2V5RHVja0lkVG9Pd25lcgEJANgEAQUHYXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUHYWRkcmVzcwkAAgECF1N0YWtlZCBORlQgaXMgbm90IHlvdXJzBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQUKYXNzZXRJZFN0cgQGaGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aABkAwkBAiE9AgUGaGVhbHRoAGQJAAIBAiZQbGVhc2UgaGVhbCB5b3VyIGR1Y2sgYmVmb3JlIHVuc3Rha2luZwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIAAQUHYXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBBQd0aW1lS2V5CQDMCAIJAQtEZWxldGVFbnRyeQEFCWtleUhlYWx0aAkAzAgCCQELRGVsZXRlRW50cnkBCQEPa2V5RHVja0xvY2F0aW9uAQUKYXNzZXRJZFN0cgkAzAgCCQELRGVsZXRlRW50cnkBCQEQa2V5RHVja0lkVG9Pd25lcgEFCmFzc2V0SWRTdHIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpEVUNLUFJFRklYBQphc3NldElkU3RyBQdhZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwBaQEIY2xhaW1SZXMCBmFtb3VudA5sYW5kQXNzZXRJZFN0cgQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQGcmVzdWx0CQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFBmFtb3VudAUNY2xhaW1Nb2RlRHVjawUObGFuZEFzc2V0SWRTdHIJAJQKAgkAzQgCCQDNCAIJAM0IAggFBnJlc3VsdAJfMQkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfMgkAuQkCCAUGcmVzdWx0Al8zAgE6CQELU3RyaW5nRW50cnkCCAUGcmVzdWx0Al80CQC5CQIIBQZyZXN1bHQCXzUCAToFDHByb2xvZ0FjdGlvbgkAkQMCCAUGcmVzdWx0Al8zBQhicElkeFJlcwFpAQxjbGFpbVJlc1RvV0gCBmFtb3VudA5sYW5kQXNzZXRJZFN0cgQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQGcmVzdWx0CQEQY2xhaW1SZXNJbnRlcm5hbAQFBGFkZHIFBmFtb3VudAULY2xhaW1Nb2RlV2gFDmxhbmRBc3NldElkU3RyCQCUCgIJAM0IAgkAzQgCCQDNCAIIBQZyZXN1bHQCXzEJAQtTdHJpbmdFbnRyeQIIBQZyZXN1bHQCXzIJALkJAggFBnJlc3VsdAJfMwIBOgkBC1N0cmluZ0VudHJ5AggFBnJlc3VsdAJfNAkAuQkCCAUGcmVzdWx0Al81AgE6BQxwcm9sb2dBY3Rpb24JAJEDAggFBnJlc3VsdAJfNQUId2hJZHhSZXMBaQEGZmxpZ2h0AgdtZXNzYWdlA3NpZwQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQEhAQkAxBMDBQdtZXNzYWdlBQNzaWcFA3B1YgkAAgECGHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAVwYXJ0cwkAtQkCCQCwCQEFB21lc3NhZ2UCATsEAmhwCQC1CQIJAJEDAgkAtQkCCQCRAwIFBXBhcnRzAAACAXwAAAIBXwQFY3VySFAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJocAAABAVuZXdIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAEEDW5ld0xvY0FuZFRpbWUJALUJAgkAkQMCBQVwYXJ0cwABAgE6BAtuZXdMb2NhdGlvbgkAkQMCBQ1uZXdMb2NBbmRUaW1lAAAEBHRpbWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ1uZXdMb2NBbmRUaW1lAAEDAwkAZgIFBHRpbWUJAGQCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAURRklWRU1JTlVURVNNSUxMSVMGCQBmAgkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwUEdGltZQkAAgECEnNpZ25hdHVyZSBvdXRkYXRlZAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAxvbGRGcm9tU3RhdGUJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQDCQECIT0CBQxvbGRGcm9tU3RhdGUFBWN1ckhQCQACAQkArAICCQCsAgIJAKwCAgIKb2xkSGVhbHRoPQkApAMBCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aABkAi8gZnJvbSBzdGF0ZSBkb2VzIG5vdCBtYXRjaCBvbmUgZnJvbSBmbGlnaHQgbG9nPQkApAMBBQVjdXJIUAMJAGcCAAAFBWN1ckhQCQACAQIeWW91IGNhbid0IGZseSB3aXRoIHplcm8gaGVhbHRoBAZsb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUGbG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04DCQAAAgULbmV3TG9jYXRpb24FC2N1ckxvY2F0aW9uCQACAQIiWW91IGNhbid0IGZseSB0byB0aGUgc2FtZSBsb2NhdGlvbgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBmxvY0tleQMJAGYCBQVuZXdIUAAABQtuZXdMb2NhdGlvbgULY3VyTG9jYXRpb24JAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUFbmV3SFAJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwFBHVuaXQBaQEJc2V0SGVhbHRoAgZoZWFsdGgLZHVja0Fzc2V0SWQEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDAwkAZgIAAAUGaGVhbHRoBgkAZgIFBmhlYWx0aABkCQACAQIaSFAgc2hvdWxkIGJlIHdpdGhpbiAwLi4xMDAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQFBmhlYWx0aAkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAFpAQRoZWFsAgdtYXRUeXBlBmFtb3VudAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMDCQBmAgAABQdtYXRUeXBlBgkAZwIFB21hdFR5cGUFBk5VTVJFUwkAAgEJAKwCAgISVW5rbm93biBtYXRlcmlhbDogCQCkAwEFB21hdFR5cGUDCQBnAgAABQZhbW91bnQJAAIBCQCsAgICG0Ftb3VudCBzaG91bGQgYmUgcG9zaXRpdmUhIAkApAMBBQZhbW91bnQEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQJb2xkSGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aABkAwkAZwIFCW9sZEhlYWx0aABkCQACAQIaSFAgc2hvdWxkIGJlIDwgMTAwIHRvIGhlYWwEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAVtTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQNY3VycmVudEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBW1MaXN0BQdtYXRUeXBlBAtkZWx0YUhlYWx0aAkAlwMBCQDMCAIJAGkCBQZhbW91bnQFCEhFQUxDT1NUCQDMCAIJAGUCAGQFCW9sZEhlYWx0aAUDbmlsBAtzcGVuZEFtb3VudAkAaAIFC2RlbHRhSGVhbHRoBQhIRUFMQ09TVAMJAGYCBQtzcGVuZEFtb3VudAUNY3VycmVudEFtb3VudAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAglZb3UgbmVlZCAJAKQDAQULc3BlbmRBbW91bnQCBCBvZiAJAJEDAgUIbWF0VHlwZXMFB21hdFR5cGUCJCB0byBoZWFsLCBidXQgeW91IGJhY2twYWNrIGNvbnRhaW5zIAkApAMBBQ1jdXJyZW50QW1vdW50BAZuZXdNYXQJAQxzdWJPbmVJbkxpc3QDBQVtTGlzdAUHbWF0VHlwZQULc3BlbmRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAkAZAIFCW9sZEhlYWx0aAULZGVsdGFIZWFsdGgJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAFpAQ51cGRhdGVCYWNrcGFjawILZHVja0Fzc2V0SWQHbmV3UGFjawQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIIBQFpBmNhbGxlcgUPZWNvbm9teUNvbnRyYWN0CQACAQIRcGVybWlzc2lvbiBkZW5pZWQJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAUHbmV3UGFjawkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAUHbmV3UGFjawFpAQhidXlTTGFuZAAEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhpBbGxvd2VkIFVTRFQgcGF5bWVudCBvbmx5IQMJAQIhPQIIBQNwbXQGYW1vdW50BQdFWFBVU0RUCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUHRVhQVVNEVAQGcmVzdWx0CQESZXhwZWRpdGlvbkludGVybmFsAggFAWkGY2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkCQCUCgIJAM0IAgkAzQgCCAUGcmVzdWx0Al8xCQEOU2NyaXB0VHJhbnNmZXIDBQ9lY29ub215Q29udHJhY3QIBQNwbXQGYW1vdW50BQt1c2R0QXNzZXRJZAUMcHJvbG9nQWN0aW9uCAgFBnJlc3VsdAJfMgJfMQFpAQpleHBlZGl0aW9uAgdtZXNzYWdlA3NpZwQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAZyZXN1bHQJARBleHBlZGl0aW9uQ29tbW9uBQYIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAUHbWVzc2FnZQUDc2lnCQCUCgIJAM0IAggFBnJlc3VsdAJfMQUMcHJvbG9nQWN0aW9uCAUGcmVzdWx0Al8yAWkBDHVwZ3JhZGVJbmZyYQELbGFuZEFzc2V0SWQEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQGcmVzdWx0CQENdXBJbmZyYUNvbW1vbgQGCAUBaQZjYWxsZXIAAAULbGFuZEFzc2V0SWQJAJQKAgkAzQgCCAUGcmVzdWx0Al8xBQxwcm9sb2dBY3Rpb24IBQZyZXN1bHQCXzIBaQEQdXBncmFkZUluZnJhVXNkdAELbGFuZEFzc2V0SWQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECGkFsbG93ZWQgVVNEVCBwYXltZW50IG9ubHkhBAZyZXN1bHQJAQ11cEluZnJhQ29tbW9uBAcIBQFpBmNhbGxlcggFA3BtdAZhbW91bnQFC2xhbmRBc3NldElkCQCUCgIJAM0IAgkAzQgCCAUGcmVzdWx0Al8xCQEOU2NyaXB0VHJhbnNmZXIDBQ9lY29ub215Q29udHJhY3QIBQNwbXQGYW1vdW50BQt1c2R0QXNzZXRJZAUMcHJvbG9nQWN0aW9uCAUGcmVzdWx0Al8yAWkBEGFjdGl2YXRlQXJ0aWZhY3QCB2FydE5hbWULbGFuZEFzc2V0SWQEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQGcmVzdWx0BAckbWF0Y2gwBQdhcnROYW1lAwkAAAICB1BSRVNBTEUFByRtYXRjaDAJARJhY3RpdmF0ZVByZXNhbGVBcnQCCQClCAEIBQFpBmNhbGxlcgULbGFuZEFzc2V0SWQJAAIBAhBVbmtub3duIGFydGlmYWN0CQDNCAIFBnJlc3VsdAUMcHJvbG9nQWN0aW9uAWkBCm1lcmdlTGFuZHMBDGxhbmRBc3NldElkcwQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAZyZXN1bHQJAQttZXJnZUNvbW1vbgUGCQClCAEIBQFpBmNhbGxlcgAABQxsYW5kQXNzZXRJZHMIBQFpDXRyYW5zYWN0aW9uSWQJAJQKAgkAzQgCCAUGcmVzdWx0Al8xBQxwcm9sb2dBY3Rpb24IBQZyZXN1bHQCXzIBaQEObWVyZ2VMYW5kc1VzZHQBDGxhbmRBc3NldElkcwQMcHJvbG9nQWN0aW9uCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkBQt1c2R0QXNzZXRJZAkAAgECGkFsbG93ZWQgVVNEVCBwYXltZW50IG9ubHkhBAZyZXN1bHQJAQttZXJnZUNvbW1vbgUHCQClCAEIBQFpBmNhbGxlcggFA3BtdAZhbW91bnQFDGxhbmRBc3NldElkcwgFAWkNdHJhbnNhY3Rpb25JZAkAlAoCCQDNCAIJAM0IAggFBnJlc3VsdAJfMQkBDlNjcmlwdFRyYW5zZmVyAwUPZWNvbm9teUNvbnRyYWN0CAUDcG10BmFtb3VudAULdXNkdEFzc2V0SWQFDHByb2xvZ0FjdGlvbggFBnJlc3VsdAJfMgFpAQ1jYXJnb0V4Y2hhbmdlAgxjYXJnb0xpc3RTdHILbGFuZEFzc2V0SWQEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQKY2FyZ29QYXJ0cwkAvAkCBQxjYXJnb0xpc3RTdHICAToEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwULcmVjTGFuZFNpemUFBVNTSVpFBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMAwkBAiE9AgkAkQMCBQNsb2MFCGxvY0lkeElkBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgIbRHVjayBzaG91bGQgYmUgb24gdGhlIGxhbmQgBQtsYW5kQXNzZXRJZAQFd2hLZXkJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAQJY3VycmVudFdoCQEMZ2V0V2FyZWhvdXNlAwUFd2hLZXkFCWxhbmRJbmRleAUKaW5mcmFMZXZlbAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBnJlc3VsdAkBCW1vdmVTdHVmZgMFCmNhcmdvUGFydHMFCWN1cnJlbnRXaAULY3VycmVudFBhY2sJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIIBQZyZXN1bHQCXzQJAMwIAggFBnJlc3VsdAJfNQkAzAgCCAUGcmVzdWx0Al82BQNuaWwCAToJAMwIAgkBC1N0cmluZ0VudHJ5AgUFd2hLZXkJALkJAgkAzAgCCQCRAwIFCWN1cnJlbnRXaAUId2hJZHhWb2wJAMwIAggFBnJlc3VsdAJfMQkAzAgCCAUGcmVzdWx0Al8yCQDMCAIIBQZyZXN1bHQCXzMJAMwIAgkAkQMCBQljdXJyZW50V2gFDndoSWR4TG9ja2VkVm9sBQNuaWwCAToJAMwIAgUMcHJvbG9nQWN0aW9uBQNuaWwBaQENc2F2ZVdhcmVob3VzZQIFd2hTdHILbGFuZEFzc2V0SWQEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCAUBaQZjYWxsZXIFD2Vjb25vbXlDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEBXdoS2V5CQESa2V5V2FyZWhvdXNlQnlMYW5kAQULbGFuZEFzc2V0SWQDCQECIT0CCQCQAwEJALwJAgUFd2hTdHICAToABQkAAgECMHdhcmVob3VzZSBzdHJpbmcgc2hvdWxkIGNvbnRhaW4gNCAnOicgc2VwYXJhdG9ycwkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBXdoS2V5BQV3aFN0cgkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAUFd2hTdHIBaQEWcmVwbGFjZUJvb2xlYW5BcnRpZmFjdAELbGFuZEFzc2V0SWQDCQECIT0CCAUBaQZjYWxsZXIFDHJlc3RDb250cmFjdAkAAgECDUFjY2VzcyBkZW5pZWQEB2Jvb2xLZXkJAR9rZXlQcmVzYWxlQXJ0QWN0aXZhdGVkQnlBc3NldElkAQULbGFuZEFzc2V0SWQEBmludEtleQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQEB2Jvb2xBcnQJAKAIAQUHYm9vbEtleQMJAQlpc0RlZmluZWQBBQdib29sQXJ0BAFkCQC1CQIICQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQLZGVzY3JpcHRpb24CAV8EBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgUBZAULcmVjTGFuZFNpemUECWFydFBpZWNlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQZpbnRLZXkFBnBpZWNlcwQFb3duZXIJAKIIAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkBAxvd25lclJlY29yZHMDCQEJaXNEZWZpbmVkAQUFb3duZXIJAMwIAgkBDEludGVnZXJFbnRyeQIJASVrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQJAQV2YWx1ZQEFBW93bmVyBQlhcnRQaWVjZXMJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBJ2tleVByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWRBbmRPd25lcgIFC2xhbmRBc3NldElkCQEFdmFsdWUBBQVvd25lcgUDbmlsBQNuaWwDCQEFdmFsdWUBBQdib29sQXJ0CQCUCgIJAM0IAgkAzQgCBQxvd25lclJlY29yZHMJAQxJbnRlZ2VyRW50cnkCBQZpbnRLZXkFCWFydFBpZWNlcwkBC0RlbGV0ZUVudHJ5AQUHYm9vbEtleQACCQCUCgIJAMwIAgkBC0RlbGV0ZUVudHJ5AQUHYm9vbEtleQUDbmlsAAEJAJQKAgUDbmlsAAABaQENc2V0Q3VzdG9tTmFtZQMHYXNzZXRJZApjdXN0b21OYW1lBHR5cGUEDHByb2xvZ0FjdGlvbgkBBnByb2xvZwEFAWkDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAULdXNkdEFzc2V0SWQJAAIBAhpBbGxvd2VkIFVTRFQgcGF5bWVudCBvbmx5IQMJAQIhPQIIBQNwbXQGYW1vdW50BQxSRU5BTUlOR0NPU1QJAAIBCQCsAgICElBheW1lbnQgc2hvdWxkIGJlIAkApAMBBQxSRU5BTUlOR0NPU1QDCQEIY29udGFpbnMCBQpjdXN0b21OYW1lAgJfXwkAAgEJAKwCAgIeTmFtZSBzaG91bGQgbm90IGNvbnRhaW4gJ19fJzogBQpjdXN0b21OYW1lBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQHYWN0aW9ucwQHJG1hdGNoMAUEdHlwZQMJAAACAgdBQ0NPVU5UBQckbWF0Y2gwBApyZXZlcnNlS2V5CQEWa2V5Q3VzdG9tTmFtZVRvQWRkcmVzcwEFCmN1c3RvbU5hbWUEB29sZE5hbWUJAKIIAQUKcmV2ZXJzZUtleQMJAQlpc0RlZmluZWQBBQdvbGROYW1lCQACAQkArAICAhlOYW1lIGFscmVhZHkgcmVnaXN0ZXJlZDogBQpjdXN0b21OYW1lCQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlBZGRyZXNzVG9DdXN0b21OYW1lAQUEYWRkcgUKY3VzdG9tTmFtZQkAzAgCCQELU3RyaW5nRW50cnkCBQpyZXZlcnNlS2V5BQRhZGRyBQNuaWwDCQAAAgIETEFORAUHJG1hdGNoMAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFB2Fzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQUHYXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQKcmV2ZXJzZUtleQkBGmtleUxhbmRDdXN0b21OYW1lVG9Bc3NldElkAQUKY3VzdG9tTmFtZQQHb2xkTmFtZQkAoggBBQpyZXZlcnNlS2V5AwkBCWlzRGVmaW5lZAEFB29sZE5hbWUJAAIBCQCsAgICGU5hbWUgYWxyZWFkeSByZWdpc3RlcmVkOiAFCmN1c3RvbU5hbWUJAMwIAgkBC1N0cmluZ0VudHJ5AgkBGmtleUxhbmRBc3NldElkVG9DdXN0b21OYW1lAQUHYXNzZXRJZAUKY3VzdG9tTmFtZQkAzAgCCQELU3RyaW5nRW50cnkCBQpyZXZlcnNlS2V5BQdhc3NldElkBQNuaWwDCQAAAgIERFVDSwUHJG1hdGNoMAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQkA2QQBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFB2Fzc2V0SWQDAwkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5BgkBASEBCQEJaXNEZWZpbmVkAQkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyCQACAQkArAICCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBEGtleUR1Y2tJZFRvT3duZXIBBQdhc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpEVUNLUFJFRklYAg0gaXMgbm90IHlvdXJzBApyZXZlcnNlS2V5CQEaa2V5RHVja0N1c3RvbU5hbWVUb0Fzc2V0SWQBBQpjdXN0b21OYW1lBAdvbGROYW1lCQCiCAEFCnJldmVyc2VLZXkDCQEJaXNEZWZpbmVkAQUHb2xkTmFtZQkAAgEJAKwCAgIZTmFtZSBhbHJlYWR5IHJlZ2lzdGVyZWQ6IAUKY3VzdG9tTmFtZQkAzAgCCQELU3RyaW5nRW50cnkCCQEaa2V5RHVja0Fzc2V0SWRUb0N1c3RvbU5hbWUBBQdhc3NldElkBQpjdXN0b21OYW1lCQDMCAIJAQtTdHJpbmdFbnRyeQIFCnJldmVyc2VLZXkFB2Fzc2V0SWQFA25pbAkAAgECE1Vua25vd24gZW50aXR5IHR5cGUJAJQKAgkAzQgCCQDNCAIFB2FjdGlvbnMJAQ5TY3JpcHRUcmFuc2ZlcgMFD2Vjb25vbXlDb250cmFjdAgFA3BtdAZhbW91bnQFC3VzZHRBc3NldElkBQxwcm9sb2dBY3Rpb24AAAFpAQxzZXRSZWZlcnJhbHMCCW9sZFBsYXllcgluZXdQbGF5ZXIDCQECIT0CCAUBaQ9jYWxsZXJQdWJsaWNLZXkFA3B1YgkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAxwcm9sb2dBY3Rpb24JAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQDCQEBIQEJAQlpc0RlZmluZWQBCQCmCAEFCW9sZFBsYXllcgkAAgEJAKwCAgIRSW52YWxpZCBhZGRyZXNzOiAFCW9sZFBsYXllcgMJAQEhAQkBCWlzRGVmaW5lZAEJAKYIAQUJbmV3UGxheWVyCQACAQkArAICAhFJbnZhbGlkIGFkZHJlc3M6IAUJbmV3UGxheWVyBAhyZWZCeUtleQkBD2tleUFkZHJlc3NSZWZCeQEFCW5ld1BsYXllcgQFcmVmQnkJAKIIAQUIcmVmQnlLZXkDAwkBCWlzRGVmaW5lZAEFBXJlZkJ5CQEJaXNEZWZpbmVkAQkApggBCQEFdmFsdWUBBQVyZWZCeQcJAAIBCQCsAgIJAKwCAgUJbmV3UGxheWVyAhQgYWxyZWFkeSBoYXMgcmVmQnk6IAkBBXZhbHVlAQUFcmVmQnkEB3JlZnNLZXkJARNrZXlBZGRyZXNzUmVmZXJyYWxzAQUJb2xkUGxheWVyBARyZWZzCQCiCAEFB3JlZnNLZXkECXJlZnNBcnJheQkAvAkCCQEFdmFsdWUBBQRyZWZzAgFfAwMJAQlpc0RlZmluZWQBBQRyZWZzCQEPY29udGFpbnNFbGVtZW50AgUJcmVmc0FycmF5BQluZXdQbGF5ZXIHCQACAQkArAICCQCsAgIJAKwCAgUJb2xkUGxheWVyAhIgYWxyZWFkeSBjb250YWlucyAFCW5ld1BsYXllcgIRIHdpdGhpbiByZWZlcnJhbHMEB25ld1JlZnMJALoJAgkAzQgCBQlyZWZzQXJyYXkFCW5ld1BsYXllcgIBXwkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFCHJlZkJ5S2V5BQlvbGRQbGF5ZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgUHcmVmc0tleQUHbmV3UmVmcwkAzAgCBQxwcm9sb2dBY3Rpb24FA25pbAAAAWkBHHNwbGl0QnlHbG9iYWxXZWlnaHRzUkVBRE9OTFkBBmFtb3VudAkAlAoCBQNuaWwJARJnZXROZWVkZWRNYXRlcmlhbHMBBQZhbW91bnQBaQEkc3BsaXRCeUdsb2JhbEFuZExvY2FsV2VpZ2h0c1JFQURPTkxZAwltYXRBbW91bnQJcmVzQW1vdW50CHRlcnJhaW5zBA10ZXJyYWluQ291bnRzCQENY291bnRUZXJyYWlucwEFCHRlcnJhaW5zCQCUCgIFA25pbAkAlAoCCQESZ2V0TmVlZGVkTWF0ZXJpYWxzAQUJbWF0QW1vdW50CQETZGlzdHJpYnV0ZUJ5V2VpZ2h0cwIFCXJlc0Ftb3VudAUNdGVycmFpbkNvdW50cwFpARNnZXRCYWNrcGFja1JFQURPTkxZAQtkdWNrQXNzZXRJZAkAlAoCBQNuaWwJALkJAgkBC2dldEJhY2twYWNrAQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQCAToBaQEUZ2V0V2FyZWhvdXNlUkVBRE9OTFkBC2xhbmRBc3NldElkBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAlsYW5kSW5kZXgJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwULcmVjTGFuZFNpemUFBVNTSVpFBAppbmZyYUxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQAAAkAlAoCBQNuaWwJALoJAgkBDGdldFdhcmVob3VzZQMJARJrZXlXYXJlaG91c2VCeUxhbmQBBQtsYW5kQXNzZXRJZAUJbGFuZEluZGV4BQppbmZyYUxldmVsAgE6AD1+oTY=", "height": 2576151, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EEiAuCrw1SWfGCj8zRHjsE82c7qpTdwx8mjuXdsdStbv Next: 5UBaXJb32pQdA5iMLVy7TkPTQ4TuJX7uUgK9WMxqgbgf Diff:
OldNewDifferences
16621662
16631663
16641664 @Callable(i)
1665-func setCustomName (assetId,customName,type) = if ((i.caller != this))
1666- then throw("Permission denied")
1667- else {
1668- let prologAction = prolog(i)
1669- if ((size(i.payments) != 1))
1670- then throw("Exactly one payment required")
1671- else {
1672- let pmt = value(i.payments[0])
1673- if ((pmt.assetId != usdtAssetId))
1674- then throw("Allowed USDT payment only!")
1675- else if ((pmt.amount != RENAMINGCOST))
1676- then throw(("Payment should be " + toString(RENAMINGCOST)))
1677- else if (contains(customName, "__"))
1678- then throw(("Name should not contain '__': " + customName))
1679- else {
1680- let addr = toString(i.originCaller)
1681- let actions = match type {
1682- case _ =>
1683- if (("ACCOUNT" == $match0))
1665+func setCustomName (assetId,customName,type) = {
1666+ let prologAction = prolog(i)
1667+ if ((size(i.payments) != 1))
1668+ then throw("Exactly one payment required")
1669+ else {
1670+ let pmt = value(i.payments[0])
1671+ if ((pmt.assetId != usdtAssetId))
1672+ then throw("Allowed USDT payment only!")
1673+ else if ((pmt.amount != RENAMINGCOST))
1674+ then throw(("Payment should be " + toString(RENAMINGCOST)))
1675+ else if (contains(customName, "__"))
1676+ then throw(("Name should not contain '__': " + customName))
1677+ else {
1678+ let addr = toString(i.originCaller)
1679+ let actions = match type {
1680+ case _ =>
1681+ if (("ACCOUNT" == $match0))
1682+ then {
1683+ let reverseKey = keyCustomNameToAddress(customName)
1684+ let oldName = getString(reverseKey)
1685+ if (isDefined(oldName))
1686+ then throw(("Name already registered: " + customName))
1687+ else [StringEntry(keyAddressToCustomName(addr), customName), StringEntry(reverseKey, addr)]
1688+ }
1689+ else if (("LAND" == $match0))
16841690 then {
1685- let reverseKey = keyCustomNameToAddress(customName)
1686- let oldName = getString(reverseKey)
1687- if (isDefined(oldName))
1688- then throw(("Name already registered: " + customName))
1689- else [StringEntry(keyAddressToCustomName(addr), customName), StringEntry(reverseKey, addr)]
1691+ let asset = value(assetInfo(fromBase58String(assetId)))
1692+ let timeKey = keyStakedTimeByAssetId(assetId)
1693+ if (!(isDefined(getInteger(timeKey))))
1694+ then throw((asset.name + " is not staked"))
1695+ else {
1696+ let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
1697+ if ((owner != addr))
1698+ then throw((LANDPREFIX + " is not yours"))
1699+ else {
1700+ let reverseKey = keyLandCustomNameToAssetId(customName)
1701+ let oldName = getString(reverseKey)
1702+ if (isDefined(oldName))
1703+ then throw(("Name already registered: " + customName))
1704+ else [StringEntry(keyLandAssetIdToCustomName(assetId), customName), StringEntry(reverseKey, assetId)]
1705+ }
1706+ }
16901707 }
1691- else if (("LAND" == $match0))
1708+ else if (("DUCK" == $match0))
16921709 then {
16931710 let asset = value(assetInfo(fromBase58String(assetId)))
16941711 let timeKey = keyStakedTimeByAssetId(assetId)
1695- if (!(isDefined(getInteger(timeKey))))
1712+ if (if (!(isDefined(getInteger(timeKey))))
1713+ then true
1714+ else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
16961715 then throw((asset.name + " is not staked"))
16971716 else {
1698- let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
1717+ let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
16991718 if ((owner != addr))
1700- then throw((LANDPREFIX + " is not yours"))
1719+ then throw((DUCKPREFIX + " is not yours"))
17011720 else {
1702- let reverseKey = keyLandCustomNameToAssetId(customName)
1721+ let reverseKey = keyDuckCustomNameToAssetId(customName)
17031722 let oldName = getString(reverseKey)
17041723 if (isDefined(oldName))
17051724 then throw(("Name already registered: " + customName))
1706- else [StringEntry(keyLandAssetIdToCustomName(assetId), customName), StringEntry(reverseKey, assetId)]
1725+ else [StringEntry(keyDuckAssetIdToCustomName(assetId), customName), StringEntry(reverseKey, assetId)]
17071726 }
17081727 }
17091728 }
1710- else if (("DUCK" == $match0))
1711- then {
1712- let asset = value(assetInfo(fromBase58String(assetId)))
1713- let timeKey = keyStakedTimeByAssetId(assetId)
1714- if (if (!(isDefined(getInteger(timeKey))))
1715- then true
1716- else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
1717- then throw((asset.name + " is not staked"))
1718- else {
1719- let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
1720- if ((owner != addr))
1721- then throw((DUCKPREFIX + " is not yours"))
1722- else {
1723- let reverseKey = keyDuckCustomNameToAssetId(customName)
1724- let oldName = getString(reverseKey)
1725- if (isDefined(oldName))
1726- then throw(("Name already registered: " + customName))
1727- else [StringEntry(keyDuckAssetIdToCustomName(assetId), customName), StringEntry(reverseKey, assetId)]
1728- }
1729- }
1730- }
1731- else throw("Unknown entity type")
1732- }
1733- $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), 0)
1734- }
1735- }
1736- }
1729+ else throw("Unknown entity type")
1730+ }
1731+ $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), 0)
1732+ }
1733+ }
1734+ }
17371735
17381736
17391737
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let chain = take(drop(this.bytes, 1), 1)
55
66 let usdtAssetId = match chain {
77 case _ =>
88 if ((base58'2W' == $match0))
99 then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
1010 else if ((base58'2T' == $match0))
1111 then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
1212 else throw("Unknown chain")
1313 }
1414
1515 let incubatorAddr = match chain {
1616 case _ =>
1717 if ((base58'2W' == $match0))
1818 then addressFromStringValue("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
1919 else if ((base58'2T' == $match0))
2020 then this
2121 else throw("Unknown chain")
2222 }
2323
2424 let breederAddr = match chain {
2525 case _ =>
2626 if ((base58'2W' == $match0))
2727 then addressFromStringValue("3PDVuU45H7Eh5dmtNbnRNRStGwULA7NY6Hb")
2828 else if ((base58'2T' == $match0))
2929 then this
3030 else throw("Unknown chain")
3131 }
3232
3333 let defaultRestAddressStr = match chain {
3434 case _ =>
3535 if ((base58'2W' == $match0))
3636 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
3737 else if ((base58'2T' == $match0))
3838 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
3939 else throw("Unknown chain")
4040 }
4141
4242 let pub = base58'6LfPuKJjLgekmncBhMg2LZyMTNVzZBccXR28ySXm9uXD'
4343
4444 let HEALCOST = 10000
4545
4646 let LANDPREFIX = "LAND"
4747
4848 let DUCKPREFIX = "DUCK"
4949
5050 let DEFAULTLOCATION = "Africa_F_Africa"
5151
5252 let NUMRES = 6
5353
5454 let SSIZE = 25
5555
5656 let MSIZE = 100
5757
5858 let LSIZE = 225
5959
6060 let XLSIZE = 400
6161
6262 let XXLSIZE = 625
6363
6464 let DAILYRESBYPIECE = 3456000
6565
6666 let DAYMILLIS = 86400000
6767
6868 let FIVEMINUTESMILLIS = 300000
6969
7070 let RESOURCEPRICEMIN = 39637
7171
7272 let WHMULTIPLIER = 10000000000
7373
7474 let RENAMINGCOST = 5000000
7575
7676 let InfraUpgradeCostS = match chain {
7777 case _ =>
7878 if ((base58'2W' == $match0))
7979 then 10000000000
8080 else if ((base58'2T' == $match0))
8181 then 100000000
8282 else throw("Unknown chain")
8383 }
8484
8585 let InfraUpgradeCostSUsdt = match chain {
8686 case _ =>
8787 if ((base58'2W' == $match0))
8888 then 10000000
8989 else if ((base58'2T' == $match0))
9090 then 10000000
9191 else throw("Unknown chain")
9292 }
9393
9494 let EXPMATERIALS = match chain {
9595 case _ =>
9696 if ((base58'2W' == $match0))
9797 then 252289527462
9898 else if ((base58'2T' == $match0))
9999 then 2522895274
100100 else throw("Unknown chain")
101101 }
102102
103103 let EXPUSDT = match chain {
104104 case _ =>
105105 if ((base58'2W' == $match0))
106106 then 250000000
107107 else if ((base58'2T' == $match0))
108108 then 250000000
109109 else throw("Unknown chain")
110110 }
111111
112112 let SEP = "__"
113113
114114 let MULT6 = 1000000
115115
116116 let FIVEX = toBigInt(5)
117117
118118 let TWENTYX = toBigInt(20)
119119
120120 let TWENTY2X = toBigInt((20 * 20))
121121
122122 let TWENTY3X = toBigInt(((20 * 20) * 20))
123123
124124 let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
125125
126126 let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
127127
128128 let matTypes = ["Fuel", "Metal", "Plank", "Glass", "Plastic", "Protein"]
129129
130130 let continents = ["Asia", "Europe", "Americas", "Oceania", "Africa"]
131131
132132 let ARTPRESALE = "PRESALE"
133133
134134 let PRESALENUMLANDS = 500
135135
136136 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
137137
138138
139139 func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
140140
141141
142142 let IdxCfgStakingDapp = 1
143143
144144 let IdxCfgEconomyDapp = 2
145145
146146 let IdxCfgGovernanceDapp = 3
147147
148148 func keyRestCfg () = "%s__restConfig"
149149
150150
151151 func keyRestAddress () = "%s__restAddr"
152152
153153
154154 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
155155
156156
157157 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
158158
159159
160160 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
161161
162162 let restCfg = readRestCfgOrFail(restContract)
163163
164164 let economyContract = getContractAddressOrFail(restCfg, IdxCfgEconomyDapp)
165165
166166 let govContract = getContractAddressOrFail(restCfg, IdxCfgGovernanceDapp)
167167
168168 func keyLastTxIdByUser (addr) = ("lastTxIdByUser_" + addr)
169169
170170
171171 func keyNextFreeLandNum () = "nextLandNum"
172172
173173
174174 func keyLandToAssetId (landNum) = ("landToAsset_" + landNum)
175175
176176
177177 func keyNftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
178178
179179
180180 func keyLandAssetIdToOwner (assetId) = ("nftOwner_" + assetId)
181181
182182
183183 func keyLandAssetIdToCustomName (assetId) = ("landCustomNameByAssetId_" + assetId)
184184
185185
186186 func keyDuckAssetIdToCustomName (assetId) = ("duckCustomNameByAssetId_" + assetId)
187187
188188
189189 func keyAddressToCustomName (addr) = ("accountCustomNameByAddr_" + addr)
190190
191191
192192 func keyLandCustomNameToAssetId (name) = ("landByCustomName_" + name)
193193
194194
195195 func keyDuckCustomNameToAssetId (name) = ("duckByCustomName_" + name)
196196
197197
198198 func keyCustomNameToAddress (name) = ("accountByCustomName_" + name)
199199
200200
201201 func keyAddressRefBy (addr) = ("accRefBy_" + addr)
202202
203203
204204 func keyAddressReferrals (addr) = ("accReferrals_" + addr)
205205
206206
207207 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
208208
209209
210210 func keyStakedTimeByAssetId (assetId) = ("stakedTime_" + assetId)
211211
212212
213213 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
214214
215215
216216 func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("infraLevelByAssetIdAndOwner_" + assetId) + "_") + ownerAddr)
217217
218218
219219 func keyPresaleArtActivatedByAssetId (assetId) = ("presaleArtActivated_" + assetId)
220220
221221
222222 func keyPresaleArtActivatedByAssetIdAndOwner (assetId,ownerAddr) = ((("presaleArtActivatedByAssetIdAndOwner_" + assetId) + "_") + ownerAddr)
223223
224224
225225 func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["landArtStatus", type, assetId], "_")
226226
227227
228228 func keyLandArtStatusByTypeAssetIdAndOwner (type,assetId,ownerAddr) = makeString(["landArtStatusByTypeAssetIdAndOwner", type, assetId, ownerAddr], "_")
229229
230230
231231 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
232232
233233
234234 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("stakedTimeByTypeAssetIdAndOwner_" + nftType) + "_") + assetId) + "_") + ownerAddr)
235235
236236
237237 func keyLandNumToOwner (landNum) = ("landOwner_" + landNum)
238238
239239
240240 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
241241
242242
243243 func keyWarehouseByLand (landAssetId) = ("wareHouse_" + landAssetId)
244244
245245
246246 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
247247
248248
249249 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
250250
251251
252252 func keyResProportions () = "resTypesProportions"
253253
254254
255255 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
256256
257257
258258 func keyBlocked () = "contractsBlocked"
259259
260260
261261 func keyUserGwlReleaseTime (userAddr) = ("%s%s__userGwlReleaseTime__" + userAddr)
262262
263263
264264 let recLandNum = 0
265265
266266 let recLandSize = 1
267267
268268 let recTerrains = 2
269269
270270 let recContinent = 3
271271
272272 let locIdxContinent = 0
273273
274274 let locIdxType = 1
275275
276276 let locIdxId = 2
277277
278278 let bpIdxLevel = 0
279279
280280 let bpIdxRes = 1
281281
282282 let bpIdxMat = 2
283283
284284 let bpIdxProd = 3
285285
286286 let whIdxVol = 0
287287
288288 let whIdxRes = 1
289289
290290 let whIdxMat = 2
291291
292292 let whIdxProd = 3
293293
294294 let whIdxLockedVol = 4
295295
296296 let claimModeWh = 0
297297
298298 let claimModeDuck = 1
299299
300300 let claimModeWhThenDuck = 2
301301
302302 func asString (v) = match v {
303303 case s: String =>
304304 s
305305 case _ =>
306306 throw("fail to cast into String")
307307 }
308308
309309
310310 func distributeByWeights (total,weights) = {
311311 let sum = (((((weights[0] + weights[1]) + weights[2]) + weights[3]) + weights[4]) + weights[5])
312312 if ((0 >= sum))
313313 then throw("Zero weights sum")
314314 else {
315315 let norm6 = fraction(total, MULT6, sum)
316316 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
317317
318318 let $l = weights
319319 let $s = size($l)
320320 let $acc0 = nil
321321 func $f0_1 ($a,$i) = if (($i >= $s))
322322 then $a
323323 else normalizer($a, $l[$i])
324324
325325 func $f0_2 ($a,$i) = if (($i >= $s))
326326 then $a
327327 else throw("List size exceeds 6")
328328
329329 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
330330 }
331331 }
332332
333333
334334 func getNeededMaterials (total) = {
335335 let props = split(value(getString(keyResProportions())), "_")
336336 if ((size(props) != NUMRES))
337337 then throw("Wrong proportions data")
338338 else {
339339 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
340340 distributeByWeights(total, r)
341341 }
342342 }
343343
344344
345345 func subtractMaterials (shouldUseMat,has,totalNeed) = {
346346 let need = getNeededMaterials(totalNeed)
347347 func subtractor (acc,idx) = {
348348 let result = (parseIntValue(has[idx]) - need[idx])
349349 if ((0 > result))
350350 then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
351351 else (acc :+ toString(result))
352352 }
353353
354354 if (shouldUseMat)
355355 then {
356356 let $l = [0, 1, 2, 3, 4, 5]
357357 let $s = size($l)
358358 let $acc0 = nil
359359 func $f0_1 ($a,$i) = if (($i >= $s))
360360 then $a
361361 else subtractor($a, $l[$i])
362362
363363 func $f0_2 ($a,$i) = if (($i >= $s))
364364 then $a
365365 else throw("List size exceeds 6")
366366
367367 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
368368 }
369369 else has
370370 }
371371
372372
373373 func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
374374 then throw("Wrong proportions data")
375375 else {
376376 func updater (acc,i) = {
377377 let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
378378 if ((0 > result))
379379 then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
380380 else (acc :+ toString(result))
381381 }
382382
383383 let r = {
384384 let $l = [0, 1, 2, 3, 4, 5]
385385 let $s = size($l)
386386 let $acc0 = nil
387387 func $f0_1 ($a,$i) = if (($i >= $s))
388388 then $a
389389 else updater($a, $l[$i])
390390
391391 func $f0_2 ($a,$i) = if (($i >= $s))
392392 then $a
393393 else throw("List size exceeds 6")
394394
395395 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
396396 }
397397 makeString(r, "_")
398398 }
399399
400400
401401 func updateProportions (terrainCounts,landSizeIndex,sign) = {
402402 let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
403403 updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign)
404404 }
405405
406406
407407 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)]
408408
409409
410410 func numPiecesBySize (landSize) = match landSize {
411411 case _ =>
412412 if (("S" == $match0))
413413 then SSIZE
414414 else if (("M" == $match0))
415415 then MSIZE
416416 else if (("L" == $match0))
417417 then LSIZE
418418 else if (("XL" == $match0))
419419 then XLSIZE
420420 else if (("XXL" == $match0))
421421 then XXLSIZE
422422 else throw("Unknown land size")
423423 }
424424
425425
426426 func subOneInList (aList,idx,amount) = {
427427 func subber (acc,i) = (acc :+ (if ((i == idx))
428428 then toString((parseIntValue(aList[i]) - amount))
429429 else aList[i]))
430430
431431 let r = {
432432 let $l = [0, 1, 2, 3, 4, 5]
433433 let $s = size($l)
434434 let $acc0 = nil
435435 func $f0_1 ($a,$i) = if (($i >= $s))
436436 then $a
437437 else subber($a, $l[$i])
438438
439439 func $f0_2 ($a,$i) = if (($i >= $s))
440440 then $a
441441 else throw("List size exceeds 6")
442442
443443 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
444444 }
445445 makeString(r, "_")
446446 }
447447
448448
449449 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
450450 func adder (acc,i) = {
451451 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
452452 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
453453 }
454454
455455 let r = {
456456 let $l = [0, 1, 2, 3, 4, 5]
457457 let $s = size($l)
458458 let $acc0 = nil
459459 func $f0_1 ($a,$i) = if (($i >= $s))
460460 then $a
461461 else adder($a, $l[$i])
462462
463463 func $f0_2 ($a,$i) = if (($i >= $s))
464464 then $a
465465 else throw("List size exceeds 6")
466466
467467 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
468468 }
469469 makeString(r, "_")
470470 }
471471
472472
473473 func virtClaim (terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
474474 func adder (acc,i) = {
475475 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
476476 $Tuple2((acc._1 :+ resOfType), (acc._2 + resOfType))
477477 }
478478
479479 let $l = [0, 1, 2, 3, 4, 5]
480480 let $s = size($l)
481481 let $acc0 = $Tuple2(nil, 0)
482482 func $f0_1 ($a,$i) = if (($i >= $s))
483483 then $a
484484 else adder($a, $l[$i])
485485
486486 func $f0_2 ($a,$i) = if (($i >= $s))
487487 then $a
488488 else throw("List size exceeds 6")
489489
490490 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
491491 }
492492
493493
494494 func distributeRes (currentWhRes,currentPackRes,resToClaim,whSpaceLeft) = {
495495 let resListToClaim = resToClaim._1
496496 let resAmToClaim = resToClaim._2
497497 if ((resAmToClaim == 0))
498498 then $Tuple2(makeString(currentWhRes, "_"), makeString(currentPackRes, "_"))
499499 else if ((whSpaceLeft >= resAmToClaim))
500500 then {
501501 func addLists (acc,i) = (acc :+ toString((parseIntValue(currentWhRes[i]) + resListToClaim[i])))
502502
503503 let r = {
504504 let $l = [0, 1, 2, 3, 4, 5]
505505 let $s = size($l)
506506 let $acc0 = nil
507507 func $f0_1 ($a,$i) = if (($i >= $s))
508508 then $a
509509 else addLists($a, $l[$i])
510510
511511 func $f0_2 ($a,$i) = if (($i >= $s))
512512 then $a
513513 else throw("List size exceeds 6")
514514
515515 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
516516 }
517517 $Tuple2(makeString(r, "_"), makeString(currentPackRes, "_"))
518518 }
519519 else {
520520 func addPartLists (acc,i) = {
521521 let whPart = fraction(resListToClaim[i], whSpaceLeft, resAmToClaim)
522522 $Tuple2((acc._1 :+ toString((parseIntValue(currentWhRes[i]) + whPart))), (acc._2 :+ toString(((parseIntValue(currentPackRes[i]) + resListToClaim[i]) - whPart))))
523523 }
524524
525525 let r = {
526526 let $l = [0, 1, 2, 3, 4, 5]
527527 let $s = size($l)
528528 let $acc0 = $Tuple2(nil, nil)
529529 func $f0_1 ($a,$i) = if (($i >= $s))
530530 then $a
531531 else addPartLists($a, $l[$i])
532532
533533 func $f0_2 ($a,$i) = if (($i >= $s))
534534 then $a
535535 else throw("List size exceeds 6")
536536
537537 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
538538 }
539539 $Tuple2(makeString(r._1, "_"), makeString(r._2, "_"))
540540 }
541541 }
542542
543543
544544 func abs (x) = if ((x >= toBigInt(0)))
545545 then x
546546 else -(x)
547547
548548
549549 let freq = [[1, 4, 9, 10, 15], [5, 8, 13, 14, 15], [6, 9, 14, 15, 16], [4, 7, 8, 13, 18], [1, 6, 7, 15, 19]]
550550
551551 func genChar (n,freqs) = {
552552 let rem = toInt((n % TWENTYX))
553553 let letter = if ((freqs[0] > rem))
554554 then "A"
555555 else if ((freqs[1] > rem))
556556 then "B"
557557 else if ((freqs[2] > rem))
558558 then "C"
559559 else if ((freqs[3] > rem))
560560 then "D"
561561 else if ((freqs[4] > rem))
562562 then "E"
563563 else "F"
564564 letter
565565 }
566566
567567
568568 func genTerrains (seed,continentIdx) = {
569569 let f = freq[continentIdx]
570570 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))
571571
572572 let t = {
573573 let $l = [1, 2, 3, 4, 5]
574574 let $s = size($l)
575575 let $acc0 = $Tuple2("", (seed / FIVEX))
576576 func $f0_1 ($a,$i) = if (($i >= $s))
577577 then $a
578578 else terrainGenerator($a, $l[$i])
579579
580580 func $f0_2 ($a,$i) = if (($i >= $s))
581581 then $a
582582 else throw("List size exceeds 5")
583583
584584 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
585585 }
586586 t._1
587587 }
588588
589589
590590 func getBackpack (bpKey) = {
591591 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
592592 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
593593 then p[bpIdxRes]
594594 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
595595 then p[bpIdxMat]
596596 else "0_0_0_0_0_0", p[bpIdxProd]]
597597 }
598598
599599
600600 func getWarehouseVolume (volPrefix) = {
601601 let parts = split(volPrefix, "_")
602602 ((WHMULTIPLIER * (parseIntValue(parts[1]) + 1)) * parseIntValue(parts[0]))
603603 }
604604
605605
606606 func getWarehouse (whKey,landIndex,infraLevel) = {
607607 let volPrefix = ((toString(landIndex) + "_") + toString(infraLevel))
608608 let p = split(valueOrElse(getString(whKey), (volPrefix + ":0_0_0_0_0_0:0_0_0_0_0_0::0")), ":")
609609 [p[whIdxVol], if ((size(split(p[whIdxRes], "_")) == NUMRES))
610610 then p[whIdxRes]
611611 else "0_0_0_0_0_0", if ((size(split(p[whIdxMat], "_")) == NUMRES))
612612 then p[whIdxMat]
613613 else "0_0_0_0_0_0", p[whIdxProd], if ((5 > size(p)))
614614 then "0"
615615 else p[whIdxLockedVol]]
616616 }
617617
618618
619619 func getWarehouseCurrResVolume (currentWh) = {
620620 func sum (acc,item) = (acc + parseIntValue(item))
621621
622622 let $l = split(currentWh[whIdxRes], "_")
623623 let $s = size($l)
624624 let $acc0 = 0
625625 func $f0_1 ($a,$i) = if (($i >= $s))
626626 then $a
627627 else sum($a, $l[$i])
628628
629629 func $f0_2 ($a,$i) = if (($i >= $s))
630630 then $a
631631 else throw("List size exceeds 6")
632632
633633 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
634634 }
635635
636636
637637 func getWarehouseCurrMatVolume (currentWh) = {
638638 func sum (acc,item) = (acc + parseIntValue(item))
639639
640640 let $l = split(currentWh[whIdxMat], "_")
641641 let $s = size($l)
642642 let $acc0 = 0
643643 func $f0_1 ($a,$i) = if (($i >= $s))
644644 then $a
645645 else sum($a, $l[$i])
646646
647647 func $f0_2 ($a,$i) = if (($i >= $s))
648648 then $a
649649 else throw("List size exceeds 6")
650650
651651 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
652652 }
653653
654654
655655 func getWarehouseCurrGoodsVolume (currentWh) = {
656656 let goods = currentWh[whIdxProd]
657657 if ((goods == ""))
658658 then 0
659659 else {
660660 func sum (acc,item) = (acc + parseIntValue(item))
661661
662662 let $l = split_4C(goods, "_")
663663 let $s = size($l)
664664 let $acc0 = 0
665665 func $f0_1 ($a,$i) = if (($i >= $s))
666666 then $a
667667 else sum($a, $l[$i])
668668
669669 func $f0_2 ($a,$i) = if (($i >= $s))
670670 then $a
671671 else throw("List size exceeds 50")
672672
673673 $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)
674674 }
675675 }
676676
677677
678678 func moveStuff (cargoParts,currentWh,currentPack) = if ((size(cargoParts) != 3))
679679 then throw("cargoListStr should contain exactly 2 ':' separators")
680680 else {
681681 let resParts = split(cargoParts[0], "_")
682682 let matParts = split(cargoParts[1], "_")
683683 let prodParts = if ((cargoParts[2] == ""))
684684 then nil
685685 else split(cargoParts[2], "_")
686686 if ((size(resParts) != NUMRES))
687687 then throw("All 6 resources should be passed")
688688 else if ((size(matParts) != NUMRES))
689689 then throw("All 6 materials should be passed")
690690 else {
691691 let currWhResVol = getWarehouseCurrResVolume(currentWh)
692692 let currWhMatVol = getWarehouseCurrMatVolume(currentWh)
693693 let currWhGoodsVol = getWarehouseCurrGoodsVolume(currentWh)
694694 let currWhLockedVol = parseIntValue(currentWh[whIdxLockedVol])
695695 let whSpaceLeft = ((((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol) - currWhLockedVol)
696696 let currWhRes = split(currentWh[whIdxRes], "_")
697697 let currWhMat = split(currentWh[whIdxMat], "_")
698698 let currWhProd = if ((currentWh[whIdxProd] == ""))
699699 then nil
700700 else split(currentWh[whIdxProd], "_")
701701 let currentPackRes = split(currentPack[bpIdxRes], "_")
702702 let currentPackMat = split(currentPack[bpIdxMat], "_")
703703 let currentPackProd = if ((currentPack[bpIdxProd] == ""))
704704 then nil
705705 else split(currentPack[bpIdxProd], "_")
706706 func mvR (acc,item) = {
707707 let i = acc._1
708708 let am = parseIntValue(item)
709709 let whr = parseIntValue(currWhRes[i])
710710 let bpr = parseIntValue(currentPackRes[i])
711711 if ((am == 0))
712712 then $Tuple4((i + 1), (acc._2 :+ currWhRes[i]), (acc._3 :+ currentPackRes[i]), acc._4)
713713 else if ((am > 0))
714714 then if ((am > bpr))
715715 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpr)) + " available"))
716716 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
717717 else if ((-(am) > whr))
718718 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whr)) + " available"))
719719 else $Tuple4((i + 1), (acc._2 :+ toString((whr + am))), (acc._3 :+ toString((bpr - am))), (acc._4 + am))
720720 }
721721
722722 let r = {
723723 let $l = resParts
724724 let $s = size($l)
725725 let $acc0 = $Tuple4(0, nil, nil, 0)
726726 func $f0_1 ($a,$i) = if (($i >= $s))
727727 then $a
728728 else mvR($a, $l[$i])
729729
730730 func $f0_2 ($a,$i) = if (($i >= $s))
731731 then $a
732732 else throw("List size exceeds 6")
733733
734734 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
735735 }
736736 func mvM (acc,item) = {
737737 let i = acc._1
738738 let am = parseIntValue(item)
739739 let whm = parseIntValue(currWhMat[i])
740740 let bpm = parseIntValue(currentPackMat[i])
741741 if ((am == 0))
742742 then $Tuple4((i + 1), (acc._2 :+ currWhMat[i]), (acc._3 :+ currentPackMat[i]), acc._4)
743743 else if ((am > 0))
744744 then if ((am > bpm))
745745 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpm)) + " available"))
746746 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
747747 else if ((-(am) > whm))
748748 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whm)) + " available"))
749749 else $Tuple4((i + 1), (acc._2 :+ toString((whm + am))), (acc._3 :+ toString((bpm - am))), (acc._4 + am))
750750 }
751751
752752 let m = {
753753 let $l = matParts
754754 let $s = size($l)
755755 let $acc0 = $Tuple4(0, nil, nil, r._4)
756756 func $f1_1 ($a,$i) = if (($i >= $s))
757757 then $a
758758 else mvM($a, $l[$i])
759759
760760 func $f1_2 ($a,$i) = if (($i >= $s))
761761 then $a
762762 else throw("List size exceeds 6")
763763
764764 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
765765 }
766766 func mvP (acc,item) = {
767767 let i = acc._1
768768 let am = parseIntValue(item)
769769 let whp = parseIntValue(currWhProd[i])
770770 let bpp = parseIntValue(currentPackProd[i])
771771 if ((am == 0))
772772 then $Tuple4((i + 1), (acc._2 :+ currWhProd[i]), (acc._3 :+ currentPackProd[i]), acc._4)
773773 else if ((am > 0))
774774 then if ((am > bpp))
775775 then throw((((("Attempt to take " + item) + " from backpack, but only ") + toString(bpp)) + " available"))
776776 else $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + am))
777777 else if ((-(am) > whp))
778778 then throw((((("Attempt to take " + toString(-(am))) + " from warehouse, but only ") + toString(whp)) + " available"))
779779 else $Tuple4((i + 1), (acc._2 :+ toString((whp + am))), (acc._3 :+ toString((bpp - am))), (acc._4 + am))
780780 }
781781
782782 let p = {
783783 let $l = prodParts
784784 let $s = size($l)
785785 let $acc0 = $Tuple4(0, nil, nil, m._4)
786786 func $f2_1 ($a,$i) = if (($i >= $s))
787787 then $a
788788 else mvP($a, $l[$i])
789789
790790 func $f2_2 ($a,$i) = if (($i >= $s))
791791 then $a
792792 else throw("List size exceeds 50")
793793
794794 $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)
795795 }
796796 let volSaldo = p._4
797797 if ((volSaldo > whSpaceLeft))
798798 then throw((((("Attempt to put total " + toString(volSaldo)) + " stuff, but only ") + toString(whSpaceLeft)) + " warehouse space left"))
799799 else $Tuple6(makeString(r._2, "_"), makeString(m._2, "_"), makeString(p._2, "_"), makeString(r._3, "_"), makeString(m._3, "_"), makeString(p._3, "_"))
800800 }
801801 }
802802
803803
804804 func expeditionInternal (caller,txId) = {
805805 let userAddr = toString(caller)
806806 let bigNum = abs(toBigInt(txId))
807807 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
808808 let landNum = toString(freeNum)
809809 let continentIdx = toInt((bigNum % FIVEX))
810810 let terrains = genTerrains(bigNum, continentIdx)
811811 let continent = continents[continentIdx]
812812 let issue = Issue(keyNftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
813813 let assetId = calculateAssetId(issue)
814814 let id = toBase58String(assetId)
815815 $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))
816816 }
817817
818818
819819 func expeditionCommon (shouldUseMat,caller,txId,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
820820 then throw("signature does not match")
821821 else {
822822 let parts = split(toUtf8String(message), ";")
823823 let hp = split(split(parts[0], "|")[0], "_")
824824 let curHP = parseIntValue(hp[0])
825825 let newHP = parseIntValue(hp[1])
826826 let locAndTime = split(parts[1], ":")
827827 let targetLocation = split(locAndTime[0], "_")
828828 if ((targetLocation[1] != "E"))
829829 then throw("expedition target location type should be E")
830830 else {
831831 let time = parseIntValue(locAndTime[1])
832832 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
833833 then true
834834 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
835835 then throw("signature outdated")
836836 else {
837837 let userAddr = toString(caller)
838838 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
839839 let keyHealth = keyDuckHealth(duckAssetId)
840840 let oldFromState = valueOrElse(getInteger(keyHealth), 100)
841841 if ((oldFromState != curHP))
842842 then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
843843 else if ((0 >= curHP))
844844 then throw("You can't fly with zero health")
845845 else if ((0 >= newHP))
846846 then $Tuple2(((if (!(shouldUseMat))
847847 then [ScriptTransfer(caller, EXPUSDT, usdtAssetId)]
848848 else nil) :+ IntegerEntry(keyHealth, 0)), "")
849849 else {
850850 let bpKey = keyBackpackByDuck(duckAssetId)
851851 let currentPack = getBackpack(bpKey)
852852 let mList = split(currentPack[bpIdxMat], "_")
853853 let newMat = makeString(subtractMaterials(shouldUseMat, mList, EXPMATERIALS), "_")
854854 let e = expeditionInternal(caller, txId)
855855 let id = e._2._1
856856 $Tuple2((((e._1 :+ StringEntry(keyDuckLocation(duckAssetId), makeString([e._2._2, "L", id], "_"))) :+ IntegerEntry(keyHealth, newHP)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))), id)
857857 }
858858 }
859859 }
860860 }
861861
862862
863863 func applyBonuses (landAssetId,pieces) = {
864864 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
865865 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
866866 then pieces
867867 else 0)
868868 let add6 = (infraLevel / 6)
869869 let add7 = (infraLevel / 7)
870870 ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, ((infraLevel + add6) + (2 * add7)), 5)) + fraction(DAILYRESBYPIECE, artPieces, (pieces * 5)))
871871 }
872872
873873
874874 func checkClaimConditions (addr,claimMode,landAssetIdIn) = {
875875 let $t02442924968 = if ((claimMode == claimModeWh))
876876 then $Tuple2(landAssetIdIn, valueOrElse(getString(keyStakedDuckByOwner(addr)), ""))
877877 else {
878878 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
879879 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
880880 let loc = split(value(curLocation), "_")
881881 if ((loc[locIdxType] != "L"))
882882 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
883883 else $Tuple2(loc[locIdxId], duckAssetId)
884884 }
885885 let landAssetId = $t02442924968._1
886886 let duckId = $t02442924968._2
887887 let asset = value(assetInfo(fromBase58String(landAssetId)))
888888 let timeKey = keyStakedTimeByAssetId(landAssetId)
889889 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Land " + asset.name) + " is not staked"))
890890 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
891891 if ((owner != addr))
892892 then throw((LANDPREFIX + " is not yours"))
893893 else {
894894 let d = split(asset.description, "_")
895895 $Tuple4(duckId, landAssetId, d, savedTime)
896896 }
897897 }
898898
899899
900900 func claimResInternal (addr,amount,claimMode,landAssetIdIn) = if ((0 > amount))
901901 then throw("Negative amount")
902902 else {
903903 let c = checkClaimConditions(addr, claimMode, landAssetIdIn)
904904 let landSize = c._3[recLandSize]
905905 let terrainCounts = countTerrains(c._3[recTerrains])
906906 let deltaTime = (lastBlock.timestamp - c._4)
907907 if ((0 > deltaTime))
908908 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", current = ") + toString(lastBlock.timestamp)))
909909 else {
910910 let pieces = numPiecesBySize(landSize)
911911 let dailyProductionByPiece = applyBonuses(c._2, pieces)
912912 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
913913 if ((amount > availRes))
914914 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
915915 else {
916916 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
917917 let newTimestamp = (lastBlock.timestamp - newDeltaTime)
918918 let landIndex = (pieces / SSIZE)
919919 let resToClaim = virtClaim(terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece)
920920 let whKey = keyWarehouseByLand(c._2)
921921 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(c._2)), 0)
922922 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
923923 let currWhResVol = getWarehouseCurrResVolume(currentWh)
924924 let currWhMatVol = getWarehouseCurrMatVolume(currentWh)
925925 let currWhGoodsVol = getWarehouseCurrGoodsVolume(currentWh)
926926 let currWhLockedVol = parseIntValue(currentWh[whIdxLockedVol])
927927 let whSpaceLeft = ((((getWarehouseVolume(currentWh[whIdxVol]) - currWhResVol) - currWhMatVol) - currWhGoodsVol) - currWhLockedVol)
928928 if (if ((claimMode == claimModeWh))
929929 then (amount > whSpaceLeft)
930930 else false)
931931 then throw((("Only " + toString(whSpaceLeft)) + " space left in warehouse"))
932932 else {
933933 let bpKey = keyBackpackByDuck(c._1)
934934 let currentPack = getBackpack(bpKey)
935935 let currentPackRes = split(currentPack[bpIdxRes], "_")
936936 let currentWhRes = split(currentWh[whIdxRes], "_")
937937 let $t02761628119 = if ((claimMode == claimModeWh))
938938 then $Tuple2(addRes(currentWhRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece), currentPack[bpIdxRes])
939939 else if ((claimMode == claimModeDuck))
940940 then $Tuple2(currentWh[whIdxRes], addRes(currentPackRes, terrainCounts, (deltaTime - newDeltaTime), landIndex, dailyProductionByPiece))
941941 else distributeRes(currentWhRes, currentPackRes, resToClaim, whSpaceLeft)
942942 let whRes = $t02761628119._1
943943 let bpRes = $t02761628119._2
944944 $Tuple5([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], whKey, [currentWh[whIdxVol], whRes, currentWh[whIdxMat], currentWh[whIdxProd], currentWh[whIdxLockedVol]])
945945 }
946946 }
947947 }
948948 }
949949
950950
951951 func claimAll (addr,landAssetId,pieces,claimMode) = {
952952 let timeKey = keyStakedTimeByAssetId(landAssetId)
953953 let savedTime = value(getInteger(timeKey))
954954 let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
955955 claimResInternal(addr, availRes, claimMode, landAssetId)
956956 }
957957
958958
959959 func upInfraCommon (shouldUseMat,caller,paymentAmount,landAssetId) = {
960960 let addr = toString(caller)
961961 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetId)
962962 let pieces = numPiecesBySize(c._3[recLandSize])
963963 let infraKey = keyInfraLevelByAssetId(c._2)
964964 let curLevel = valueOrElse(getInteger(infraKey), 0)
965965 if ((curLevel >= 3))
966966 then throw("Currently max infrastructure level = 3")
967967 else {
968968 let newLevel = (curLevel + 1)
969969 let cost = fraction(InfraUpgradeCostSUsdt, (pieces * newLevel), SSIZE)
970970 if (if (!(shouldUseMat))
971971 then (paymentAmount != cost)
972972 else false)
973973 then throw(("Payment attached should be " + toString(cost)))
974974 else {
975975 let bpKey = keyBackpackByDuck(c._1)
976976 let currentPack = getBackpack(bpKey)
977977 let mList = split(currentPack[bpIdxMat], "_")
978978 let newMat = makeString(subtractMaterials(shouldUseMat, mList, fraction(InfraUpgradeCostS, (pieces * newLevel), SSIZE)), "_")
979979 let claimResult = claimAll(addr, c._2, pieces, claimModeWhThenDuck)
980980 let whData = claimResult._5
981981 let newVolData = makeString([split(whData[whIdxVol], "_")[0], toString(newLevel)], "_")
982982 $Tuple2(([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], whData[whIdxLockedVol]], ":"))] ++ claimResult._1), newLevel)
983983 }
984984 }
985985 }
986986
987987
988988 func activatePresaleArt (addr,landAssetIdIn) = {
989989 let c = checkClaimConditions(addr, claimModeWhThenDuck, landAssetIdIn)
990990 let landAssetId = c._2
991991 let pieces = numPiecesBySize(c._3[recLandSize])
992992 let activationKey = keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)
993993 if ((valueOrElse(getInteger(activationKey), if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
994994 then pieces
995995 else 0) > 0))
996996 then throw("Presale artifact is already activated")
997997 else if ((parseIntValue(c._3[recLandNum]) > PRESALENUMLANDS))
998998 then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
999999 else {
10001000 let claimResult = claimAll(addr, landAssetId, pieces, claimModeWhThenDuck)
10011001 ((((claimResult._1 :+ IntegerEntry(activationKey, pieces)) :+ IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, addr), pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":"))) :+ StringEntry(claimResult._4, makeString(claimResult._5, ":")))
10021002 }
10031003 }
10041004
10051005
10061006 func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,txId,needMat) = {
10071007 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
10081008 func checkMerge (acc,landAssetId) = {
10091009 let asset = value(assetInfo(fromBase58String(landAssetId)))
10101010 let timeKey = keyStakedTimeByAssetId(landAssetId)
10111011 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
10121012 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
10131013 if ((owner != addr))
10141014 then throw((LANDPREFIX + " is not yours"))
10151015 else {
10161016 let d = split(asset.description, "_")
10171017 let continent = d[recContinent]
10181018 if (if ((acc._3 != ""))
10191019 then (acc._3 != continent)
10201020 else false)
10211021 then throw("Lands should be on the same continent to merge")
10221022 else {
10231023 let landSize = d[recLandSize]
10241024 let sizesIn = acc._1
10251025 let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
10261026 let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
10271027 let pieces = numPiecesBySize(landSize)
10281028 let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
10291029 then pieces
10301030 else 0))
10311031 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
10321032 let reqLevel = match landSize {
10331033 case _ =>
10341034 if (("S" == $match0))
10351035 then 3
10361036 else if (("M" == $match0))
10371037 then 4
10381038 else if (("L" == $match0))
10391039 then 5
10401040 else if (("XL" == $match0))
10411041 then 6
10421042 else throw("Only S, M, L, XL can merge")
10431043 }
10441044 if ((infraLevel != reqLevel))
10451045 then throw("All lands should be maxed to merge")
10461046 else {
10471047 let landNum = d[recLandNum]
10481048 let terrainCounts = countTerrains(d[recTerrains])
10491049 let deltaTime = (lastBlock.timestamp - savedTime)
10501050 if ((0 > deltaTime))
10511051 then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
10521052 else {
10531053 let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
10541054 let landIndex = (pieces / SSIZE)
10551055 let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, landIndex, dailyProductionByPiece)
10561056 let props = updateProportionsInternal(split(acc._6, "_"), terrainCounts, landIndex, -1)
10571057 let lands = acc._7
10581058 let idx = indexOf(lands, landAssetId)
10591059 if (!(isDefined(idx)))
10601060 then throw(("Your staked lands don't contain " + landAssetId))
10611061 else {
10621062 let customKey = keyLandAssetIdToCustomName(landAssetId)
10631063 let customName = valueOrElse(getString(customKey), "")
10641064 $Tuple7(sizesOut, arts, continent, bpRes, ((((((((((((((acc._5 :+ DeleteEntry(keyStakedTimeByAssetId(landAssetId))) :+ DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr))) :+ DeleteEntry(keyLandToAssetId(landNum))) :+ DeleteEntry(keyNftName(landNum, landSize))) :+ DeleteEntry(keyLandAssetIdToOwner(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetId(landAssetId))) :+ DeleteEntry(keyInfraLevelByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, addr))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ DeleteEntry(keyWarehouseByLand(landAssetId))) :+ DeleteEntry(customKey)) :+ DeleteEntry(keyLandCustomNameToAssetId(customName))) :+ Burn(fromBase58String(landAssetId), 1)), props, removeByIndex(lands, value(idx)))
10651065 }
10661066 }
10671067 }
10681068 }
10691069 }
10701070 }
10711071
10721072 let bpKey = keyBackpackByDuck(duckAssetId)
10731073 let currentPack = getBackpack(bpKey)
10741074 let propStr = valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0")
10751075 let landsKey = keyStakedLandsByOwner(addr)
10761076 let landsStr = getString(landsKey)
10771077 let landsIn = if (isDefined(landsStr))
10781078 then split_51C(value(landsStr), "_")
10791079 else nil
10801080 let r = {
10811081 let $l = landAssetIds
10821082 let $s = size($l)
10831083 let $acc0 = $Tuple7(formula, 0, "", currentPack[bpIdxRes], nil, propStr, landsIn)
10841084 func $f0_1 ($a,$i) = if (($i >= $s))
10851085 then $a
10861086 else checkMerge($a, $l[$i])
10871087
10881088 func $f0_2 ($a,$i) = if (($i >= $s))
10891089 then $a
10901090 else throw("List size exceeds 5")
10911091
10921092 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
10931093 }
10941094 let continent = r._3
10951095 let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
10961096 let terrains = genTerrains(abs(toBigInt(txId)), continentIdx)
10971097 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), (PRESALENUMLANDS + 1))
10981098 let newLandNum = toString(freeNum)
10991099 let issue = Issue(keyNftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
11001100 let assetId = calculateAssetId(issue)
11011101 let newLandAssetId = toBase58String(assetId)
11021102 let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
11031103 $Tuple2(((((((((((((((r._5 :+ (if ((size(r._7) > 0))
11041104 then StringEntry(landsKey, makeString_11C(r._7, "_"))
11051105 else DeleteEntry(landsKey))) :+ IntegerEntry(keyNextFreeLandNum(), (freeNum + 1))) :+ issue) :+ StringEntry(keyLandToAssetId(newLandNum), newLandAssetId)) :+ StringEntry(keyLandAssetIdToOwner(newLandAssetId), addr)) :+ StringEntry(keyLandNumToOwner(newLandNum), addr)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, newLandAssetId), r._2)) :+ IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, newLandAssetId, addr), r._2)) :+ IntegerEntry(keyInfraLevelByAssetId(newLandAssetId), newLevel)) :+ IntegerEntry(keyInfraLevelByAssetIdAndOwner(newLandAssetId, addr), newLevel)) :+ StringEntry(bpKey, makeString([currentPack[bpIdxLevel], r._4, newMat, currentPack[bpIdxProd]], ":"))) :+ StringEntry(keyResProportions(), r._6)) :+ StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", newLandAssetId], "_"))) :+ ScriptTransfer(addressFromStringValue(addr), 1, assetId)), newLandAssetId)
11061106 }
11071107
11081108
11091109 func s2m (addr,landAssetIds,txId) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, txId, 0)
11101110
11111111
11121112 func m2l (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
11131113 let cost = (InfraUpgradeCostSUsdt * 4)
11141114 if (if (!(shouldUseMat))
11151115 then (paymentAmount != cost)
11161116 else false)
11171117 then throw(("Payment attached should be " + toString(cost)))
11181118 else mergeInternal("L", 4, "SMM", addr, landAssetIds, txId, (InfraUpgradeCostS * 4))
11191119 }
11201120
11211121
11221122 func l2xl (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
11231123 let cost = (InfraUpgradeCostSUsdt * 47)
11241124 if (if (!(shouldUseMat))
11251125 then (paymentAmount != cost)
11261126 else false)
11271127 then throw(("Payment attached should be " + toString(cost)))
11281128 else mergeInternal("XL", 5, "SSSML", addr, landAssetIds, txId, (InfraUpgradeCostS * 47))
11291129 }
11301130
11311131
11321132 func xl2xxl (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
11331133 let cost = (InfraUpgradeCostSUsdt * 54)
11341134 if (if (!(shouldUseMat))
11351135 then (paymentAmount != cost)
11361136 else false)
11371137 then throw(("Payment attached should be " + toString(cost)))
11381138 else mergeInternal("XXL", 6, "LXL", addr, landAssetIds, txId, (InfraUpgradeCostS * 54))
11391139 }
11401140
11411141
11421142 func mergeCommon (shouldUseMat,addr,paymentAmount,landAssetIds,txId) = {
11431143 let mergeResult = match size(landAssetIds) {
11441144 case _ =>
11451145 if ((4 == $match0))
11461146 then s2m(addr, landAssetIds, txId)
11471147 else if ((3 == $match0))
11481148 then m2l(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
11491149 else if ((5 == $match0))
11501150 then l2xl(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
11511151 else if ((2 == $match0))
11521152 then xl2xxl(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
11531153 else throw("Unknown merge")
11541154 }
11551155 mergeResult
11561156 }
11571157
11581158
11591159 func prolog (i) = if (if ((i.originCaller != restContract))
11601160 then valueOrElse(getBoolean(keyBlocked()), false)
11611161 else false)
11621162 then throw("Contracts are under maintenance")
11631163 else StringEntry(keyLastTxIdByUser(toString(i.originCaller)), toBase58String(i.transactionId))
11641164
11651165
11661166 @Callable(i)
11671167 func constructorV1 (restAddr) = if ((i.caller != this))
11681168 then throw("Permission denied")
11691169 else [StringEntry(keyRestAddress(), restAddr)]
11701170
11711171
11721172
11731173 @Callable(i)
11741174 func setBlocked (isBlocked) = if ((i.caller != this))
11751175 then throw("permission denied")
11761176 else [BooleanEntry(keyBlocked(), isBlocked)]
11771177
11781178
11791179
11801180 @Callable(i)
11811181 func stakeLand () = {
11821182 let prologAction = prolog(i)
11831183 if ((size(i.payments) != 1))
11841184 then throw("Exactly one payment required")
11851185 else {
11861186 let pmt = value(i.payments[0])
11871187 let assetId = value(pmt.assetId)
11881188 let address = toString(i.caller)
11891189 if ((pmt.amount != 1))
11901190 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
11911191 else {
11921192 let asset = value(assetInfo(assetId))
11931193 if ((asset.issuer != this))
11941194 then throw("Unknown issuer of token")
11951195 else if (!(contains(asset.name, LANDPREFIX)))
11961196 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
11971197 else {
11981198 let landNumSize = drop(asset.name, 4)
11991199 let landNum = if (contains(landNumSize, "XXL"))
12001200 then dropRight(landNumSize, 3)
12011201 else if (contains(landNumSize, "XL"))
12021202 then dropRight(landNumSize, 2)
12031203 else dropRight(landNumSize, 1)
12041204 if (!(isDefined(parseInt(landNum))))
12051205 then throw(("Cannot parse land number from " + asset.name))
12061206 else {
12071207 let landAssetId = toBase58String(assetId)
12081208 let timeKey = keyStakedTimeByAssetId(landAssetId)
12091209 if (isDefined(getInteger(timeKey)))
12101210 then throw((("NFT " + asset.name) + " is already staked"))
12111211 else {
12121212 let d = split(asset.description, "_")
12131213 let terrainCounts = countTerrains(d[recTerrains])
12141214 let pieces = numPiecesBySize(d[recLandSize])
12151215 let props = updateProportions(terrainCounts, (pieces / SSIZE), 1)
12161216 let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
12171217 then pieces
12181218 else 0)
12191219 let landsStr = getString(keyStakedLandsByOwner(address))
12201220 let lands = if (isDefined(landsStr))
12211221 then split_51C(value(landsStr), "_")
12221222 else nil
12231223 if (containsElement(lands, landAssetId))
12241224 then throw(("Your staked lands already contain " + landAssetId))
12251225 else [IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(keyStakedLandsByOwner(address), makeString_11C((lands :+ landAssetId), "_")), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, address), artPieces), StringEntry(keyResProportions(), props), prologAction]
12261226 }
12271227 }
12281228 }
12291229 }
12301230 }
12311231 }
12321232
12331233
12341234
12351235 @Callable(i)
12361236 func unstakeLand (landAssetIdIn) = {
12371237 let prologAction = prolog(i)
12381238 if ((size(i.payments) != 0))
12391239 then throw("No payments required")
12401240 else {
12411241 let addr = toString(i.caller)
12421242 let c = checkClaimConditions(addr, claimModeDuck, landAssetIdIn)
12431243 let landAssetId = c._2
12441244 let landsKey = keyStakedLandsByOwner(addr)
12451245 let terrainCounts = countTerrains(c._3[recTerrains])
12461246 let pieces = numPiecesBySize(c._3[recLandSize])
12471247 let props = updateProportions(terrainCounts, (pieces / SSIZE), -1)
12481248 let claimResult = claimAll(addr, landAssetId, pieces, claimModeDuck)
12491249 let lands = split_51C(valueOrElse(getString(landsKey), ""), "_")
12501250 let idx = indexOf(lands, landAssetId)
12511251 if (!(isDefined(idx)))
12521252 then throw(("Your staked lands don't contain " + landAssetId))
12531253 else {
12541254 let t = value(blockInfoByHeight(height)).timestamp
12551255 let releaseTime = valueOrElse(getInteger(govContract, keyUserGwlReleaseTime(addr)), 0)
12561256 if ((releaseTime >= t))
12571257 then throw(("Your gWL are taking part in voting, cannot unstake until " + toString(releaseTime)))
12581258 else [ScriptTransfer(i.caller, 1, fromBase58String(landAssetId)), DeleteEntry(keyStakedTimeByAssetId(landAssetId)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, addr)), StringEntry(keyResProportions(), props), StringEntry(claimResult._2, makeString(claimResult._3, ":")), if ((size(lands) > 1))
12591259 then StringEntry(landsKey, makeString_11C(removeByIndex(lands, value(idx)), "_"))
12601260 else DeleteEntry(landsKey), prologAction]
12611261 }
12621262 }
12631263 }
12641264
12651265
12661266
12671267 @Callable(i)
12681268 func stakeDuck () = {
12691269 let prologAction = prolog(i)
12701270 if ((size(i.payments) != 1))
12711271 then throw("Exactly one payment required")
12721272 else {
12731273 let pmt = value(i.payments[0])
12741274 let assetId = value(pmt.assetId)
12751275 let address = toString(i.caller)
12761276 if ((pmt.amount != 1))
12771277 then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
12781278 else {
12791279 let asset = value(assetInfo(assetId))
12801280 if (if ((asset.issuer != incubatorAddr))
12811281 then (asset.issuer != breederAddr)
12821282 else false)
12831283 then throw((("Unknown issuer of " + DUCKPREFIX) + " token"))
12841284 else if (!(contains(asset.name, DUCKPREFIX)))
12851285 then throw((("Only NFT " + DUCKPREFIX) + " tokens are accepted"))
12861286 else {
12871287 let assetIdStr = toBase58String(assetId)
12881288 let timeKey = keyStakedTimeByAssetId(assetIdStr)
12891289 if (isDefined(getInteger(timeKey)))
12901290 then throw((("NFT " + asset.name) + " is already staked"))
12911291 else if (isDefined(getString(keyStakedDuckByOwner(address))))
12921292 then throw(("You already staked one duck: " + asset.name))
12931293 else {
12941294 let locKey = keyDuckLocation(assetIdStr)
12951295 let location = getString(locKey)
12961296 let bpKey = keyBackpackByDuck(assetIdStr)
12971297 let backpack = getString(bpKey)
12981298 ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
12991299 then nil
13001300 else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(backpack))
13011301 then nil
13021302 else (([StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")] :+ IntegerEntry(keyDuckHealth(assetIdStr), 100)) :+ prologAction)))))
13031303 }
13041304 }
13051305 }
13061306 }
13071307 }
13081308
13091309
13101310
13111311 @Callable(i)
13121312 func unstakeDuck (assetIdStr) = {
13131313 let prologAction = prolog(i)
13141314 if ((size(i.payments) != 0))
13151315 then throw("No payments required")
13161316 else {
13171317 let assetId = fromBase58String(assetIdStr)
13181318 let address = toString(i.caller)
13191319 let asset = value(assetInfo(assetId))
13201320 let timeKey = keyStakedTimeByAssetId(toBase58String(assetId))
13211321 if (!(isDefined(getInteger(timeKey))))
13221322 then throw((("NFT " + asset.name) + " is not staked"))
13231323 else if (!(isDefined(getString(keyStakedDuckByOwner(address)))))
13241324 then throw((("The duck " + asset.name) + " is not staked"))
13251325 else {
13261326 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(toBase58String(assetId))), (("NFT " + asset.name) + " is orphaned"))
13271327 if ((owner != address))
13281328 then throw("Staked NFT is not yours")
13291329 else {
13301330 let keyHealth = keyDuckHealth(assetIdStr)
13311331 let health = valueOrElse(getInteger(keyHealth), 100)
13321332 if ((health != 100))
13331333 then throw("Please heal your duck before unstaking")
13341334 else [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyHealth), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address)), prologAction]
13351335 }
13361336 }
13371337 }
13381338 }
13391339
13401340
13411341
13421342 @Callable(i)
13431343 func claimRes (amount,landAssetIdStr) = {
13441344 let prologAction = prolog(i)
13451345 if ((size(i.payments) != 0))
13461346 then throw("No payments required")
13471347 else {
13481348 let addr = toString(i.originCaller)
13491349 let result = claimResInternal(addr, amount, claimModeDuck, landAssetIdStr)
13501350 $Tuple2((((result._1 :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._3[bpIdxRes])
13511351 }
13521352 }
13531353
13541354
13551355
13561356 @Callable(i)
13571357 func claimResToWH (amount,landAssetIdStr) = {
13581358 let prologAction = prolog(i)
13591359 if ((size(i.payments) != 0))
13601360 then throw("No payments required")
13611361 else {
13621362 let addr = toString(i.originCaller)
13631363 let result = claimResInternal(addr, amount, claimModeWh, landAssetIdStr)
13641364 $Tuple2((((result._1 :+ StringEntry(result._2, makeString(result._3, ":"))) :+ StringEntry(result._4, makeString(result._5, ":"))) :+ prologAction), result._5[whIdxRes])
13651365 }
13661366 }
13671367
13681368
13691369
13701370 @Callable(i)
13711371 func flight (message,sig) = {
13721372 let prologAction = prolog(i)
13731373 if (!(sigVerify_8Kb(message, sig, pub)))
13741374 then throw("signature does not match")
13751375 else if ((size(i.payments) != 0))
13761376 then throw("No payments required")
13771377 else {
13781378 let parts = split(toUtf8String(message), ";")
13791379 let hp = split(split(parts[0], "|")[0], "_")
13801380 let curHP = parseIntValue(hp[0])
13811381 let newHP = parseIntValue(hp[1])
13821382 let newLocAndTime = split(parts[1], ":")
13831383 let newLocation = newLocAndTime[0]
13841384 let time = parseIntValue(newLocAndTime[1])
13851385 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
13861386 then true
13871387 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
13881388 then throw("signature outdated")
13891389 else {
13901390 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
13911391 let keyHealth = keyDuckHealth(duckAssetId)
13921392 let oldFromState = valueOrElse(getInteger(keyHealth), 100)
13931393 if ((oldFromState != curHP))
13941394 then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
13951395 else if ((0 >= curHP))
13961396 then throw("You can't fly with zero health")
13971397 else {
13981398 let locKey = keyDuckLocation(duckAssetId)
13991399 let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
14001400 if ((newLocation == curLocation))
14011401 then throw("You can't fly to the same location")
14021402 else $Tuple2([StringEntry(locKey, if ((newHP > 0))
14031403 then newLocation
14041404 else curLocation), IntegerEntry(keyHealth, newHP), prologAction], unit)
14051405 }
14061406 }
14071407 }
14081408 }
14091409
14101410
14111411
14121412 @Callable(i)
14131413 func setHealth (health,duckAssetId) = {
14141414 let prologAction = prolog(i)
14151415 if (if ((0 > health))
14161416 then true
14171417 else (health > 100))
14181418 then throw("HP should be within 0..100")
14191419 else [IntegerEntry(keyDuckHealth(duckAssetId), health), prologAction]
14201420 }
14211421
14221422
14231423
14241424 @Callable(i)
14251425 func heal (matType,amount) = {
14261426 let prologAction = prolog(i)
14271427 if (if ((0 > matType))
14281428 then true
14291429 else (matType >= NUMRES))
14301430 then throw(("Unknown material: " + toString(matType)))
14311431 else if ((0 >= amount))
14321432 then throw(("Amount should be positive! " + toString(amount)))
14331433 else {
14341434 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
14351435 let keyHealth = keyDuckHealth(duckAssetId)
14361436 let oldHealth = valueOrElse(getInteger(keyHealth), 100)
14371437 if ((oldHealth >= 100))
14381438 then throw("HP should be < 100 to heal")
14391439 else {
14401440 let bpKey = keyBackpackByDuck(duckAssetId)
14411441 let currentPack = getBackpack(bpKey)
14421442 let mList = split(currentPack[bpIdxMat], "_")
14431443 let currentAmount = parseIntValue(mList[matType])
14441444 let deltaHealth = min([(amount / HEALCOST), (100 - oldHealth)])
14451445 let spendAmount = (deltaHealth * HEALCOST)
14461446 if ((spendAmount > currentAmount))
14471447 then throw(((((("You need " + toString(spendAmount)) + " of ") + matTypes[matType]) + " to heal, but you backpack contains ") + toString(currentAmount)))
14481448 else {
14491449 let newMat = subOneInList(mList, matType, spendAmount)
14501450 [IntegerEntry(keyHealth, (oldHealth + deltaHealth)), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":")), prologAction]
14511451 }
14521452 }
14531453 }
14541454 }
14551455
14561456
14571457
14581458 @Callable(i)
14591459 func updateBackpack (duckAssetId,newPack) = {
14601460 let prologAction = prolog(i)
14611461 if ((i.caller != economyContract))
14621462 then throw("permission denied")
14631463 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack), prologAction], newPack)
14641464 }
14651465
14661466
14671467
14681468 @Callable(i)
14691469 func buySLand () = {
14701470 let prologAction = prolog(i)
14711471 if ((size(i.payments) != 1))
14721472 then throw("Exactly one payment required")
14731473 else {
14741474 let pmt = value(i.payments[0])
14751475 if ((pmt.assetId != usdtAssetId))
14761476 then throw("Allowed USDT payment only!")
14771477 else if ((pmt.amount != EXPUSDT))
14781478 then throw(("Payment attached should be " + toString(EXPUSDT)))
14791479 else {
14801480 let result = expeditionInternal(i.caller, i.transactionId)
14811481 $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), result._2._1)
14821482 }
14831483 }
14841484 }
14851485
14861486
14871487
14881488 @Callable(i)
14891489 func expedition (message,sig) = {
14901490 let prologAction = prolog(i)
14911491 if ((size(i.payments) != 0))
14921492 then throw("No payments required")
14931493 else {
14941494 let result = expeditionCommon(true, i.caller, i.transactionId, message, sig)
14951495 $Tuple2((result._1 :+ prologAction), result._2)
14961496 }
14971497 }
14981498
14991499
15001500
15011501 @Callable(i)
15021502 func upgradeInfra (landAssetId) = {
15031503 let prologAction = prolog(i)
15041504 if ((size(i.payments) != 0))
15051505 then throw("No payments required")
15061506 else {
15071507 let result = upInfraCommon(true, i.caller, 0, landAssetId)
15081508 $Tuple2((result._1 :+ prologAction), result._2)
15091509 }
15101510 }
15111511
15121512
15131513
15141514 @Callable(i)
15151515 func upgradeInfraUsdt (landAssetId) = if ((i.caller != this))
15161516 then throw("Permission denied")
15171517 else {
15181518 let prologAction = prolog(i)
15191519 if ((size(i.payments) != 1))
15201520 then throw("Exactly one payment required")
15211521 else {
15221522 let pmt = value(i.payments[0])
15231523 if ((pmt.assetId != usdtAssetId))
15241524 then throw("Allowed USDT payment only!")
15251525 else {
15261526 let result = upInfraCommon(false, i.caller, pmt.amount, landAssetId)
15271527 $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), result._2)
15281528 }
15291529 }
15301530 }
15311531
15321532
15331533
15341534 @Callable(i)
15351535 func activateArtifact (artName,landAssetId) = {
15361536 let prologAction = prolog(i)
15371537 if ((size(i.payments) != 0))
15381538 then throw("No payments required")
15391539 else {
15401540 let result = match artName {
15411541 case _ =>
15421542 if (("PRESALE" == $match0))
15431543 then activatePresaleArt(toString(i.caller), landAssetId)
15441544 else throw("Unknown artifact")
15451545 }
15461546 (result :+ prologAction)
15471547 }
15481548 }
15491549
15501550
15511551
15521552 @Callable(i)
15531553 func mergeLands (landAssetIds) = {
15541554 let prologAction = prolog(i)
15551555 if ((size(i.payments) != 0))
15561556 then throw("No payments required")
15571557 else {
15581558 let result = mergeCommon(true, toString(i.caller), 0, landAssetIds, i.transactionId)
15591559 $Tuple2((result._1 :+ prologAction), result._2)
15601560 }
15611561 }
15621562
15631563
15641564
15651565 @Callable(i)
15661566 func mergeLandsUsdt (landAssetIds) = {
15671567 let prologAction = prolog(i)
15681568 if ((size(i.payments) != 1))
15691569 then throw("Exactly one payment required")
15701570 else {
15711571 let pmt = value(i.payments[0])
15721572 if ((pmt.assetId != usdtAssetId))
15731573 then throw("Allowed USDT payment only!")
15741574 else {
15751575 let result = mergeCommon(false, toString(i.caller), pmt.amount, landAssetIds, i.transactionId)
15761576 $Tuple2(((result._1 :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), result._2)
15771577 }
15781578 }
15791579 }
15801580
15811581
15821582
15831583 @Callable(i)
15841584 func cargoExchange (cargoListStr,landAssetId) = {
15851585 let prologAction = prolog(i)
15861586 if ((size(i.payments) != 0))
15871587 then throw("No payments required")
15881588 else {
15891589 let cargoParts = split_4C(cargoListStr, ":")
15901590 let addr = toString(i.originCaller)
15911591 let asset = value(assetInfo(fromBase58String(landAssetId)))
15921592 let timeKey = keyStakedTimeByAssetId(landAssetId)
15931593 if (!(isDefined(getInteger(timeKey))))
15941594 then throw((asset.name + " is not staked"))
15951595 else {
15961596 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
15971597 if ((owner != addr))
15981598 then throw((LANDPREFIX + " is not yours"))
15991599 else {
16001600 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
16011601 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
16021602 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
16031603 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
16041604 let loc = split(value(curLocation), "_")
16051605 if ((loc[locIdxType] != "L"))
16061606 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
16071607 else if ((loc[locIdxId] != landAssetId))
16081608 then throw(("Duck should be on the land " + landAssetId))
16091609 else {
16101610 let whKey = keyWarehouseByLand(landAssetId)
16111611 let currentWh = getWarehouse(whKey, landIndex, infraLevel)
16121612 let bpKey = keyBackpackByDuck(duckAssetId)
16131613 let currentPack = getBackpack(bpKey)
16141614 let result = moveStuff(cargoParts, currentWh, currentPack)
16151615 [StringEntry(bpKey, makeString([currentPack[bpIdxLevel], result._4, result._5, result._6], ":")), StringEntry(whKey, makeString([currentWh[whIdxVol], result._1, result._2, result._3, currentWh[whIdxLockedVol]], ":")), prologAction]
16161616 }
16171617 }
16181618 }
16191619 }
16201620 }
16211621
16221622
16231623
16241624 @Callable(i)
16251625 func saveWarehouse (whStr,landAssetId) = {
16261626 let prologAction = prolog(i)
16271627 if ((i.caller != economyContract))
16281628 then throw("Access denied")
16291629 else {
16301630 let whKey = keyWarehouseByLand(landAssetId)
16311631 if ((size(split_4C(whStr, ":")) != 5))
16321632 then throw("warehouse string should contain 4 ':' separators")
16331633 else $Tuple2([StringEntry(whKey, whStr), prologAction], whStr)
16341634 }
16351635 }
16361636
16371637
16381638
16391639 @Callable(i)
16401640 func replaceBooleanArtifact (landAssetId) = if ((i.caller != restContract))
16411641 then throw("Access denied")
16421642 else {
16431643 let boolKey = keyPresaleArtActivatedByAssetId(landAssetId)
16441644 let intKey = keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)
16451645 let boolArt = getBoolean(boolKey)
16461646 if (isDefined(boolArt))
16471647 then {
16481648 let d = split(value(assetInfo(fromBase58String(landAssetId))).description, "_")
16491649 let pieces = numPiecesBySize(d[recLandSize])
16501650 let artPieces = valueOrElse(getInteger(intKey), pieces)
16511651 let owner = getString(keyLandAssetIdToOwner(landAssetId))
16521652 let ownerRecords = if (isDefined(owner))
16531653 then [IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, value(owner)), artPieces), DeleteEntry(keyPresaleArtActivatedByAssetIdAndOwner(landAssetId, value(owner)))]
16541654 else nil
16551655 if (value(boolArt))
16561656 then $Tuple2(((ownerRecords :+ IntegerEntry(intKey, artPieces)) :+ DeleteEntry(boolKey)), 2)
16571657 else $Tuple2([DeleteEntry(boolKey)], 1)
16581658 }
16591659 else $Tuple2(nil, 0)
16601660 }
16611661
16621662
16631663
16641664 @Callable(i)
1665-func setCustomName (assetId,customName,type) = if ((i.caller != this))
1666- then throw("Permission denied")
1667- else {
1668- let prologAction = prolog(i)
1669- if ((size(i.payments) != 1))
1670- then throw("Exactly one payment required")
1671- else {
1672- let pmt = value(i.payments[0])
1673- if ((pmt.assetId != usdtAssetId))
1674- then throw("Allowed USDT payment only!")
1675- else if ((pmt.amount != RENAMINGCOST))
1676- then throw(("Payment should be " + toString(RENAMINGCOST)))
1677- else if (contains(customName, "__"))
1678- then throw(("Name should not contain '__': " + customName))
1679- else {
1680- let addr = toString(i.originCaller)
1681- let actions = match type {
1682- case _ =>
1683- if (("ACCOUNT" == $match0))
1665+func setCustomName (assetId,customName,type) = {
1666+ let prologAction = prolog(i)
1667+ if ((size(i.payments) != 1))
1668+ then throw("Exactly one payment required")
1669+ else {
1670+ let pmt = value(i.payments[0])
1671+ if ((pmt.assetId != usdtAssetId))
1672+ then throw("Allowed USDT payment only!")
1673+ else if ((pmt.amount != RENAMINGCOST))
1674+ then throw(("Payment should be " + toString(RENAMINGCOST)))
1675+ else if (contains(customName, "__"))
1676+ then throw(("Name should not contain '__': " + customName))
1677+ else {
1678+ let addr = toString(i.originCaller)
1679+ let actions = match type {
1680+ case _ =>
1681+ if (("ACCOUNT" == $match0))
1682+ then {
1683+ let reverseKey = keyCustomNameToAddress(customName)
1684+ let oldName = getString(reverseKey)
1685+ if (isDefined(oldName))
1686+ then throw(("Name already registered: " + customName))
1687+ else [StringEntry(keyAddressToCustomName(addr), customName), StringEntry(reverseKey, addr)]
1688+ }
1689+ else if (("LAND" == $match0))
16841690 then {
1685- let reverseKey = keyCustomNameToAddress(customName)
1686- let oldName = getString(reverseKey)
1687- if (isDefined(oldName))
1688- then throw(("Name already registered: " + customName))
1689- else [StringEntry(keyAddressToCustomName(addr), customName), StringEntry(reverseKey, addr)]
1691+ let asset = value(assetInfo(fromBase58String(assetId)))
1692+ let timeKey = keyStakedTimeByAssetId(assetId)
1693+ if (!(isDefined(getInteger(timeKey))))
1694+ then throw((asset.name + " is not staked"))
1695+ else {
1696+ let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
1697+ if ((owner != addr))
1698+ then throw((LANDPREFIX + " is not yours"))
1699+ else {
1700+ let reverseKey = keyLandCustomNameToAssetId(customName)
1701+ let oldName = getString(reverseKey)
1702+ if (isDefined(oldName))
1703+ then throw(("Name already registered: " + customName))
1704+ else [StringEntry(keyLandAssetIdToCustomName(assetId), customName), StringEntry(reverseKey, assetId)]
1705+ }
1706+ }
16901707 }
1691- else if (("LAND" == $match0))
1708+ else if (("DUCK" == $match0))
16921709 then {
16931710 let asset = value(assetInfo(fromBase58String(assetId)))
16941711 let timeKey = keyStakedTimeByAssetId(assetId)
1695- if (!(isDefined(getInteger(timeKey))))
1712+ if (if (!(isDefined(getInteger(timeKey))))
1713+ then true
1714+ else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
16961715 then throw((asset.name + " is not staked"))
16971716 else {
1698- let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
1717+ let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
16991718 if ((owner != addr))
1700- then throw((LANDPREFIX + " is not yours"))
1719+ then throw((DUCKPREFIX + " is not yours"))
17011720 else {
1702- let reverseKey = keyLandCustomNameToAssetId(customName)
1721+ let reverseKey = keyDuckCustomNameToAssetId(customName)
17031722 let oldName = getString(reverseKey)
17041723 if (isDefined(oldName))
17051724 then throw(("Name already registered: " + customName))
1706- else [StringEntry(keyLandAssetIdToCustomName(assetId), customName), StringEntry(reverseKey, assetId)]
1725+ else [StringEntry(keyDuckAssetIdToCustomName(assetId), customName), StringEntry(reverseKey, assetId)]
17071726 }
17081727 }
17091728 }
1710- else if (("DUCK" == $match0))
1711- then {
1712- let asset = value(assetInfo(fromBase58String(assetId)))
1713- let timeKey = keyStakedTimeByAssetId(assetId)
1714- if (if (!(isDefined(getInteger(timeKey))))
1715- then true
1716- else !(isDefined(getString(keyStakedDuckByOwner(addr)))))
1717- then throw((asset.name + " is not staked"))
1718- else {
1719- let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(assetId)), (("NFT " + asset.name) + " is orphaned"))
1720- if ((owner != addr))
1721- then throw((DUCKPREFIX + " is not yours"))
1722- else {
1723- let reverseKey = keyDuckCustomNameToAssetId(customName)
1724- let oldName = getString(reverseKey)
1725- if (isDefined(oldName))
1726- then throw(("Name already registered: " + customName))
1727- else [StringEntry(keyDuckAssetIdToCustomName(assetId), customName), StringEntry(reverseKey, assetId)]
1728- }
1729- }
1730- }
1731- else throw("Unknown entity type")
1732- }
1733- $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), 0)
1734- }
1735- }
1736- }
1729+ else throw("Unknown entity type")
1730+ }
1731+ $Tuple2(((actions :+ ScriptTransfer(economyContract, pmt.amount, usdtAssetId)) :+ prologAction), 0)
1732+ }
1733+ }
1734+ }
17371735
17381736
17391737
17401738 @Callable(i)
17411739 func setReferrals (oldPlayer,newPlayer) = if ((i.callerPublicKey != pub))
17421740 then throw("Permission denied")
17431741 else {
17441742 let prologAction = prolog(i)
17451743 if ((size(i.payments) != 0))
17461744 then throw("No payments required")
17471745 else if (!(isDefined(addressFromString(oldPlayer))))
17481746 then throw(("Invalid address: " + oldPlayer))
17491747 else if (!(isDefined(addressFromString(newPlayer))))
17501748 then throw(("Invalid address: " + newPlayer))
17511749 else {
17521750 let refByKey = keyAddressRefBy(newPlayer)
17531751 let refBy = getString(refByKey)
17541752 if (if (isDefined(refBy))
17551753 then isDefined(addressFromString(value(refBy)))
17561754 else false)
17571755 then throw(((newPlayer + " already has refBy: ") + value(refBy)))
17581756 else {
17591757 let refsKey = keyAddressReferrals(oldPlayer)
17601758 let refs = getString(refsKey)
17611759 let refsArray = split_4C(value(refs), "_")
17621760 if (if (isDefined(refs))
17631761 then containsElement(refsArray, newPlayer)
17641762 else false)
17651763 then throw((((oldPlayer + " already contains ") + newPlayer) + " within referrals"))
17661764 else {
17671765 let newRefs = makeString_2C((refsArray :+ newPlayer), "_")
17681766 $Tuple2([StringEntry(refByKey, oldPlayer), StringEntry(refsKey, newRefs), prologAction], 0)
17691767 }
17701768 }
17711769 }
17721770 }
17731771
17741772
17751773
17761774 @Callable(i)
17771775 func splitByGlobalWeightsREADONLY (amount) = $Tuple2(nil, getNeededMaterials(amount))
17781776
17791777
17801778
17811779 @Callable(i)
17821780 func splitByGlobalAndLocalWeightsREADONLY (matAmount,resAmount,terrains) = {
17831781 let terrainCounts = countTerrains(terrains)
17841782 $Tuple2(nil, $Tuple2(getNeededMaterials(matAmount), distributeByWeights(resAmount, terrainCounts)))
17851783 }
17861784
17871785
17881786
17891787 @Callable(i)
17901788 func getBackpackREADONLY (duckAssetId) = $Tuple2(nil, makeString(getBackpack(keyBackpackByDuck(duckAssetId)), ":"))
17911789
17921790
17931791
17941792 @Callable(i)
17951793 func getWarehouseREADONLY (landAssetId) = {
17961794 let asset = value(assetInfo(fromBase58String(landAssetId)))
17971795 let landIndex = (numPiecesBySize(split(asset.description, "_")[recLandSize]) / SSIZE)
17981796 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
17991797 $Tuple2(nil, makeString_2C(getWarehouse(keyWarehouseByLand(landAssetId), landIndex, infraLevel), ":"))
18001798 }
18011799
18021800

github/deemru/w8io/6500d08 
427.75 ms