tx · E6XGta71V4kKMuxfWhZ4pvm6jXWzU8MKpz7NhRyj939C

3PLncXtS1U83D6cQbFD3H8rBHPLgzxSFKZ1:  -0.03100000 Waves

2023.01.15 22:55 [3471996] smart account 3PLncXtS1U83D6cQbFD3H8rBHPLgzxSFKZ1 > SELF 0.00000000 Waves

{ "type": 13, "id": "E6XGta71V4kKMuxfWhZ4pvm6jXWzU8MKpz7NhRyj939C", "fee": 3100000, "feeAssetId": null, "timestamp": 1673812536082, "version": 2, "chainId": 87, "sender": "3PLncXtS1U83D6cQbFD3H8rBHPLgzxSFKZ1", "senderPublicKey": "BtDpFhgHQKHFVqYTMLReuZzqy94CRPSRkrYcSEVyjt4q", "proofs": [ "3mZdvcvif3zevpotmqGjUtAtWjp6LhMtELzvPX6PJyeCyghmySXYaDJzQ4bCDDVPxPrkwHRR9CHHwke2ZmpXWpp3" ], "script": "base64:BgJTCAISABIDCgEIEgASAwoBCBIECgIBCBIECgICAhIECgIBCBIECgIBARIECgIICBIECgICAhIECgICAhIDCgEIEgMKAQgSAwoBCBIDCgEYEgMKARhWAAVjaGFpbgkAsAkBCQDJAQIJAMoBAggFBHRoaXMFYnl0ZXMAAQABAAt1c2RuQXNzZXRJZAQHJG1hdGNoMAUFY2hhaW4DCQAAAgIBVwUHJG1hdGNoMAEgtiYpwwT1zlORpA5LdSQvZIxRsfrfr1QpvUjSHSqyqtEDCQAAAgIBVAUHJG1hdGNoMAEg93bq9/eDymXbbhPuAjvPWCmVqcHRjfJL2mzYHWKAyN4JAAIBAg1Vbmtub3duIGNoYWluAA1pbmN1YmF0b3JBZGRyBAckbWF0Y2gwBQVjaGFpbgMJAAACAgFXBQckbWF0Y2gwCQERQGV4dHJOYXRpdmUoMTA2MikBAiMzUEVrdFZ1eDJSaGNoU042M0RzRG80YjRtejRRcXpLU2VEdgMJAAACAgFUBQckbWF0Y2gwBQR0aGlzCQACAQINVW5rbm93biBjaGFpbgALYnJlZWRlckFkZHIEByRtYXRjaDAFBWNoYWluAwkAAAICAVcFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQRFZ1VTQ1SDdFaDVkbXROYm5STlJTdEd3VUxBN05ZNkhiAwkAAAICAVQFByRtYXRjaDAFBHRoaXMJAAIBAg1Vbmtub3duIGNoYWluAAtlY29ub215QWRkcgQHJG1hdGNoMAUFY2hhaW4DCQAAAgIBVwUHJG1hdGNoMAkBEUBleHRyTmF0aXZlKDEwNjIpAQIjM1Ayc2sxS25jU3hSYVpzOGI0Q1dHUHcyamt2dmF2NzR1NEQDCQAAAgIBVAUHJG1hdGNoMAkBEUBleHRyTmF0aXZlKDEwNjIpAQIjM044eTR3eFgzSkM0VGRyQ0pCWFgxNlNqV2Y2WDI1NmhyZXAJAAIBAg1Vbmtub3duIGNoYWluAANwdWIBIE9T4ho/VKjWnVJOEx1GJ1W9s1PzLHvJVFSw/0PBtBQoAAhIRUFMQ09TVACQTgAKTEFORFBSRUZJWAIETEFORAAKRFVDS1BSRUZJWAIERFVDSwAPREVGQVVMVExPQ0FUSU9OAg9BZnJpY2FfRl9BZnJpY2EABk5VTVJFUwAGAA9EQUlMWVJFU0JZUElFQ0UAgPjSAQAJREFZTUlMTElTAIC4mSkAEUZJVkVNSU5VVEVTTUlMTElTAOCnEgAQUkVTT1VSQ0VQUklDRU1JTgDV1gkAEUluZnJhVXBncmFkZUNvc3RTBAckbWF0Y2gwBQVjaGFpbgMJAAACAgFXBQckbWF0Y2gwAMbrwL8XAwkAAAICAVQFByRtYXRjaDAA8M2JHgkAAgECDVVua25vd24gY2hhaW4AFUluZnJhVXBncmFkZUNvc3RTVXNkbgQHJG1hdGNoMAUFY2hhaW4DCQAAAgIBVwUHJG1hdGNoMACAtIkTAwkAAAICAVQFByRtYXRjaDAAgLUYCQACAQINVW5rbm93biBjaGFpbgAMRVhQTUFURVJJQUxTBAckbWF0Y2gwBQVjaGFpbgMJAAACAgFXBQckbWF0Y2gwAMuA1bPLBAMJAAACAgFUBQckbWF0Y2gwAPGa8O8FCQACAQINVW5rbm93biBjaGFpbgAHRVhQVVNETgQHJG1hdGNoMAUFY2hhaW4DCQAAAgIBVwUHJG1hdGNoMACAlOvcAwMJAAACAgFUBQckbWF0Y2gwAICt4gQJAAIBAg1Vbmtub3duIGNoYWluAAVNVUxUNgDAhD0ABUZJVkVYCQC2AgEABQAHVFdFTlRZWAkAtgIBABQACFRXRU5UWTJYCQC2AgEJAGgCABQAFAAIVFdFTlRZM1gJALYCAQkAaAIJAGgCABQAFAAUAAhUV0VOVFk0WAkAtgIBCQBoAgkAaAIJAGgCABQAFAAUABQACFRXRU5UWTVYCQC2AgEJAGgCCQBoAgkAaAIJAGgCABQAFAAUABQAFAAIbWF0VHlwZXMJAMwIAgIERnVlbAkAzAgCAgVNZXRhbAkAzAgCAgVQbGFuawkAzAgCAgVHbGFzcwkAzAgCAgdQbGFzdGljCQDMCAICB1Byb3RlaW4FA25pbAAKY29udGluZW50cwkAzAgCAgRBc2lhCQDMCAICBkV1cm9wZQkAzAgCAghBbWVyaWNhcwkAzAgCAgdPY2VhbmlhCQDMCAICBkFmcmljYQUDbmlsAApBUlRQUkVTQUxFAgdQUkVTQUxFARJrZXlOZXh0RnJlZUxhbmROdW0AAgtuZXh0TGFuZE51bQEQa2V5TGFuZFRvQXNzZXRJZAEHbGFuZE51bQkArAICAgxsYW5kVG9Bc3NldF8FB2xhbmROdW0BCmtleU5mdE5hbWUCB2xhbmROdW0IbGFuZFNpemUJAKwCAgkArAICBQpMQU5EUFJFRklYBQdsYW5kTnVtBQhsYW5kU2l6ZQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQdhc3NldElkCQCsAgICCW5mdE93bmVyXwUHYXNzZXRJZAEQa2V5RHVja0lkVG9Pd25lcgEHYXNzZXRJZAkArAICAgpkdWNrT3duZXJfBQdhc3NldElkARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQdhc3NldElkCQCsAgICC3N0YWtlZFRpbWVfBQdhc3NldElkARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQdhc3NldElkCQCsAgICC2luZnJhTGV2ZWxfBQdhc3NldElkAR5rZXlJbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXICB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICAhxpbmZyYUxldmVsQnlBc3NldElkQW5kT3duZXJfBQdhc3NldElkAgFfBQlvd25lckFkZHIBH2tleVByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWQBB2Fzc2V0SWQJAKwCAgIUcHJlc2FsZUFydEFjdGl2YXRlZF8FB2Fzc2V0SWQBJ2tleVByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWRBbmRPd25lcgIHYXNzZXRJZAlvd25lckFkZHIJAKwCAgkArAICCQCsAgICJXByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWRBbmRPd25lcl8FB2Fzc2V0SWQCAV8FCW93bmVyQWRkcgEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBHR5cGUHYXNzZXRJZAkAuQkCCQDMCAICDWxhbmRBcnRTdGF0dXMJAMwIAgUEdHlwZQkAzAgCBQdhc3NldElkBQNuaWwCAV8BJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBHR5cGUHYXNzZXRJZAlvd25lckFkZHIJALkJAgkAzAgCAiJsYW5kQXJ0U3RhdHVzQnlUeXBlQXNzZXRJZEFuZE93bmVyCQDMCAIFBHR5cGUJAMwIAgUHYXNzZXRJZAkAzAgCBQlvd25lckFkZHIFA25pbAIBXwEUa2V5U3Rha2VkRHVja0J5T3duZXIBCW93bmVyQWRkcgkArAICAhJzdGFrZWREdWNrQnlPd25lcl8FCW93bmVyQWRkcgEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMHbmZ0VHlwZQdhc3NldElkCW93bmVyQWRkcgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICIHN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXJfBQduZnRUeXBlAgFfBQdhc3NldElkAgFfBQlvd25lckFkZHIBEWtleUxhbmROdW1Ub093bmVyAQdsYW5kTnVtCQCsAgICCmxhbmRPd25lcl8FB2xhbmROdW0BEWtleUJhY2twYWNrQnlEdWNrAQtkdWNrQXNzZXRJZAkArAICAgliYWNrUGFja18FC2R1Y2tBc3NldElkAQ9rZXlEdWNrTG9jYXRpb24BC2R1Y2tBc3NldElkCQCsAgICDWR1Y2tMb2NhdGlvbl8FC2R1Y2tBc3NldElkAQ1rZXlEdWNrSGVhbHRoAQtkdWNrQXNzZXRJZAkArAICAgtkdWNrSGVhbHRoXwULZHVja0Fzc2V0SWQBEWtleVJlc1Byb3BvcnRpb25zAAITcmVzVHlwZXNQcm9wb3J0aW9ucwAKcmVjTGFuZE51bQAAAAtyZWNMYW5kU2l6ZQABAAtyZWNUZXJyYWlucwACAAxyZWNDb250aW5lbnQAAwAPbG9jSWR4Q29udGluZW50AAAACmxvY0lkeFR5cGUAAQAIbG9jSWR4SWQAAgAKYnBJZHhMZXZlbAAAAAhicElkeFJlcwABAAhicElkeE1hdAACAAlicElkeFByb2QAAwEIYXNTdHJpbmcBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwBQFzCQACAQIYZmFpbCB0byBjYXN0IGludG8gU3RyaW5nARJnZXROZWVkZWRNYXRlcmlhbHMBBXRvdGFsBAVwcm9wcwkAtQkCCQEFdmFsdWUBCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACAV8DCQECIT0CCQCQAwEFBXByb3BzBQZOVU1SRVMJAAIBAhZXcm9uZyBwcm9wb3J0aW9ucyBkYXRhBAFyCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAACQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwABCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwACCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwADCQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAECQDMCAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVwcm9wcwAFBQNuaWwEA3N1bQkAZAIJAGQCCQBkAgkAZAIJAGQCCQCRAwIFAXIAAAkAkQMCBQFyAAEJAJEDAgUBcgACCQCRAwIFAXIAAwkAkQMCBQFyAAQJAJEDAgUBcgAFAwkAZwIAAAUDc3VtCQACAQIPTm8gbGFuZHMgc3Rha2VkBAVub3JtNgkAawMFBXRvdGFsBQVNVUxUNgUDc3VtCgEKbm9ybWFsaXplcgIDYWNjBGVsZW0JAM0IAgUDYWNjCQBrAwUEZWxlbQUFbm9ybTYFBU1VTFQ2CgACJGwFAXIKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCm5vcm1hbGl6ZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYBEXN1YnRyYWN0TWF0ZXJpYWxzAwxzaG91bGRVc2VNYXQDaGFzCXRvdGFsTmVlZAQEbmVlZAkBEmdldE5lZWRlZE1hdGVyaWFscwEFCXRvdGFsTmVlZAoBCnN1YnRyYWN0b3ICA2FjYwNpZHgEBnJlc3VsdAkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNoYXMFA2lkeAkAkQMCBQRuZWVkBQNpZHgDCQBmAgAABQZyZXN1bHQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIYTm90IGVub3VnaCBtYXRlcmlhbCBpZHg9CQCkAwEFA2lkeAILLCB5b3UgaGF2ZSAJAJEDAgUDaGFzBQNpZHgCCywgYnV0IG5lZWQgCQCkAwEJAJEDAgUEbmVlZAUDaWR4CQDNCAIFA2FjYwkApAMBBQZyZXN1bHQDBQxzaG91bGRVc2VNYXQKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQpzdWJ0cmFjdG9yAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGBQNoYXMBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECHByb3BMaXN0DXRlcnJhaW5Db3VudHMNbGFuZFNpemVJbmRleARzaWduAwkBAiE9AgkAkAMBBQhwcm9wTGlzdAUGTlVNUkVTCQACAQIWV3JvbmcgcHJvcG9ydGlvbnMgZGF0YQoBB3VwZGF0ZXICA2FjYwFpBAZyZXN1bHQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIcHJvcExpc3QFAWkJAGgCCQBoAgUEc2lnbgkAkQMCBQ10ZXJyYWluQ291bnRzBQFpBQ1sYW5kU2l6ZUluZGV4AwkAZgIAAAUGcmVzdWx0CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhZQYW5pYyEgUGllY2VzIG9mIHR5cGU9CQCkAwEFAWkCBywgc2lnbj0JAKQDAQUEc2lnbgIULCAgdGVycmFpbkNvdW50c1tpXT0JAKQDAQkAkQMCBQ10ZXJyYWluQ291bnRzBQFpAhAsIGxhbmRTaXplSW5kZXg9CQCkAwEFDWxhbmRTaXplSW5kZXgJAM0IAgUDYWNjCQCkAwEFBnJlc3VsdAQBcgoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB3VwZGF0ZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJALkJAgUBcgIBXwERdXBkYXRlUHJvcG9ydGlvbnMDDXRlcnJhaW5Db3VudHMNbGFuZFNpemVJbmRleARzaWduBAhwcm9wTGlzdAkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACCzBfMF8wXzBfMF8wAgFfCQEZdXBkYXRlUHJvcG9ydGlvbnNJbnRlcm5hbAQFCHByb3BMaXN0BQ10ZXJyYWluQ291bnRzBQ1sYW5kU2l6ZUluZGV4BQRzaWduAQ1jb3VudFRlcnJhaW5zAQh0ZXJyYWlucwkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFBAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBQgABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUMAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFEAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBRQABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUYAAQUDbmlsAQ9udW1QaWVjZXNCeVNpemUBCGxhbmRTaXplBAckbWF0Y2gwBQhsYW5kU2l6ZQMJAAACAgFTBQckbWF0Y2gwABkDCQAAAgIBTQUHJG1hdGNoMABkAwkAAAICAUwFByRtYXRjaDAA4QEDCQAAAgICWEwFByRtYXRjaDAAkAMDCQAAAgIDWFhMBQckbWF0Y2gwAPEECQACAQIRVW5rbm93biBsYW5kIHNpemUBDHN1Yk9uZUluTGlzdAMFYUxpc3QDaWR4BmFtb3VudAoBBnN1YmJlcgIDYWNjAWkJAM0IAgUDYWNjAwkAAAIFAWkFA2lkeAkApAMBCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWFMaXN0BQFpBQZhbW91bnQJAJEDAgUFYUxpc3QFAWkEAXIKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQZzdWJiZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJALkJAgUBcgIBXwEGYWRkUmVzBQpjdXJyZW50UmVzDXRlcnJhaW5Db3VudHMJZGVsdGFUaW1lDWxhbmRTaXplSW5kZXgXZGFpbHlCeVBpZWNlV2l0aEJvbnVzZXMKAQVhZGRlcgIDYWNjAWkECXJlc09mVHlwZQkAaAIJAGgCCQBrAwUJZGVsdGFUaW1lBRdkYWlseUJ5UGllY2VXaXRoQm9udXNlcwUJREFZTUlMTElTCQCRAwIFDXRlcnJhaW5Db3VudHMFAWkFDWxhbmRTaXplSW5kZXgJAM0IAgUDYWNjCQCkAwEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKY3VycmVudFJlcwUBaQUJcmVzT2ZUeXBlBAFyCgACJGwJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEFYWRkZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJALkJAgUBcgIBXwEDYWJzAQF4AwkAwAICBQF4CQC2AgEAAAUBeAkAvgIBBQF4AARmcmVxCQDMCAIJAMwIAgABCQDMCAIABAkAzAgCAAkJAMwIAgAKCQDMCAIADwUDbmlsCQDMCAIJAMwIAgAFCQDMCAIACAkAzAgCAA0JAMwIAgAOCQDMCAIADwUDbmlsCQDMCAIJAMwIAgAGCQDMCAIACQkAzAgCAA4JAMwIAgAPCQDMCAIAEAUDbmlsCQDMCAIJAMwIAgAECQDMCAIABwkAzAgCAAgJAMwIAgANCQDMCAIAEgUDbmlsCQDMCAIJAMwIAgABCQDMCAIABgkAzAgCAAcJAMwIAgAPCQDMCAIAEwUDbmlsBQNuaWwBB2dlbkNoYXICAW4FZnJlcXMEA3JlbQkAoAMBCQC7AgIFAW4FB1RXRU5UWVgEBmxldHRlcgMJAGYCCQCRAwIFBWZyZXFzAAAFA3JlbQIBQQMJAGYCCQCRAwIFBWZyZXFzAAEFA3JlbQIBQgMJAGYCCQCRAwIFBWZyZXFzAAIFA3JlbQIBQwMJAGYCCQCRAwIFBWZyZXFzAAMFA3JlbQIBRAMJAGYCCQCRAwIFBWZyZXFzAAQFA3JlbQIBRQIBRgUGbGV0dGVyAQtnZW5UZXJyYWlucwIEc2VlZAxjb250aW5lbnRJZHgEAWYJAJEDAgUEZnJlcQUMY29udGluZW50SWR4CgEQdGVycmFpbkdlbmVyYXRvcgIDYWNjBGVsZW0JAJQKAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIIBQNhY2MCXzEJAQdnZW5DaGFyAggFA2FjYwJfMgUBZgkBB2dlbkNoYXICCQC6AgIIBQNhY2MCXzIFB1RXRU5UWVgFAWYJAQdnZW5DaGFyAgkAugICCAUDYWNjAl8yBQhUV0VOVFkyWAUBZgkBB2dlbkNoYXICCQC6AgIIBQNhY2MCXzIFCFRXRU5UWTNYBQFmCQEHZ2VuQ2hhcgIJALoCAggFA2FjYwJfMgUIVFdFTlRZNFgFAWYJALoCAggFA2FjYwJfMgUIVFdFTlRZNVgEAXQKAAIkbAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgICAAkAugICBQRzZWVkBQVGSVZFWAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEQdGVycmFpbkdlbmVyYXRvcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUIBQF0Al8xAQtnZXRCYWNrcGFjawEFYnBLZXkEAXAJALUJAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQVicEtleQIaMDowXzBfMF8wXzBfMDowXzBfMF8wXzBfMDoCAToJAMwIAgkApAMBCQELdmFsdWVPckVsc2UCCQC2CQEJAJEDAgUBcAUKYnBJZHhMZXZlbAAACQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUBcAUIYnBJZHhSZXMCAV8FBk5VTVJFUwkAkQMCBQFwBQhicElkeFJlcwILMF8wXzBfMF8wXzAJAMwIAgMJAAACCQCQAwEJALUJAgkAkQMCBQFwBQhicElkeE1hdAIBXwUGTlVNUkVTCQCRAwIFAXAFCGJwSWR4TWF0AgswXzBfMF8wXzBfMAkAzAgCCQCRAwIFAXAFCWJwSWR4UHJvZAUDbmlsARBleHBlZGl0aW9uQ29tbW9uBQxzaG91bGRVc2VNYXQGY2FsbGVyBHR4SWQHbWVzc2FnZQNzaWcDCQEBIQEJAMQTAwUHbWVzc2FnZQUDc2lnBQNwdWIJAAIBAhhzaWduYXR1cmUgZG9lcyBub3QgbWF0Y2gEBXBhcnRzCQC1CQIJALAJAQUHbWVzc2FnZQIBOwQCaHAJALUJAgkAkQMCCQC1CQIJAJEDAgUFcGFydHMAAAIBfAAAAgFfBAVjdXJIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAAEBW5ld0hQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaHAAAQQKbG9jQW5kVGltZQkAtQkCCQCRAwIFBXBhcnRzAAECAToEDnRhcmdldExvY2F0aW9uCQC1CQIJAJEDAgUKbG9jQW5kVGltZQAAAgFfAwkBAiE9AgkAkQMCBQ50YXJnZXRMb2NhdGlvbgABAgFFCQACAQIrZXhwZWRpdGlvbiB0YXJnZXQgbG9jYXRpb24gdHlwZSBzaG91bGQgYmUgRQQEdGltZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCmxvY0FuZFRpbWUAAQMDCQBmAgUEdGltZQkAZAIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwYJAGYCCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFEUZJVkVNSU5VVEVTTUlMTElTBQR0aW1lCQACAQISc2lnbmF0dXJlIG91dGRhdGVkBAh1c2VyQWRkcgkApQgBBQZjYWxsZXIEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUIdXNlckFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQMb2xkRnJvbVN0YXRlCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aABkAwkBAiE9AgUMb2xkRnJvbVN0YXRlBQVjdXJIUAkAAgEJAKwCAgkArAICCQCsAgICCm9sZEhlYWx0aD0JAKQDAQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgAZAIvIGZyb20gc3RhdGUgZG9lcyBub3QgbWF0Y2ggb25lIGZyb20gZmxpZ2h0IGxvZz0JAKQDAQUFY3VySFADCQBnAgAABQVjdXJIUAkAAgECHllvdSBjYW4ndCBmbHkgd2l0aCB6ZXJvIGhlYWx0aAMJAGcCAAAFBW5ld0hQCQCUCgIJAM0IAgMJAQEhAQUMc2hvdWxkVXNlTWF0CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBmNhbGxlcgUHRVhQVVNETgULdXNkbkFzc2V0SWQFA25pbAUDbmlsCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoAAACAAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBW1MaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBAZuZXdNYXQJALkJAgkBEXN1YnRyYWN0TWF0ZXJpYWxzAwUMc2hvdWxkVXNlTWF0BQVtTGlzdAUMRVhQTUFURVJJQUxTAgFfBAZiaWdOdW0JAQNhYnMBCQCeAwEFBHR4SWQEB2ZyZWVOdW0JAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEmtleU5leHRGcmVlTGFuZE51bQAA9QMEB2xhbmROdW0JAKQDAQUHZnJlZU51bQQMY29udGluZW50SWR4CQCgAwEJALsCAgUGYmlnTnVtBQVGSVZFWAQIdGVycmFpbnMJAQtnZW5UZXJyYWlucwIFBmJpZ051bQUMY29udGluZW50SWR4BAljb250aW5lbnQJAJEDAgUKY29udGluZW50cwUMY29udGluZW50SWR4BAVpc3N1ZQkAwggFCQEKa2V5TmZ0TmFtZQIFB2xhbmROdW0CAVMJALkJAgkAzAgCBQdsYW5kTnVtCQDMCAICAVMJAMwIAgUIdGVycmFpbnMJAMwIAgUJY29udGluZW50BQNuaWwCAV8AAQAABwQHYXNzZXRJZAkAuAgBBQVpc3N1ZQQCaWQJANgEAQUHYXNzZXRJZAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFB2ZyZWVOdW0AAQkAzAgCBQVpc3N1ZQkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5TGFuZFRvQXNzZXRJZAEFB2xhbmROdW0FAmlkCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQJpZAUIdXNlckFkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQUIdXNlckFkZHIJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQUCaWQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIFAmlkBQh1c2VyQWRkcgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBmNhbGxlcgABBQdhc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAkAuQkCCQDMCAIFCWNvbnRpbmVudAkAzAgCAgFMCQDMCAIFAmlkBQNuaWwCAV8JAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUFbmV3SFAJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgUDbmlsBQJpZAEMYXBwbHlCb251c2VzAgtsYW5kQXNzZXRJZAZwaWVjZXMECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAlhcnRQaWVjZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQDCQELdmFsdWVPckVsc2UCCQCgCAEJAR9rZXlQcmVzYWxlQXJ0QWN0aXZhdGVkQnlBc3NldElkAQULbGFuZEFzc2V0SWQHBQZwaWVjZXMAAAkAZAIJAGQCBQ9EQUlMWVJFU0JZUElFQ0UJAGsDBQ9EQUlMWVJFU0JZUElFQ0UFCmluZnJhTGV2ZWwABAkAawMFD0RBSUxZUkVTQllQSUVDRQkAaAIFCWFydFBpZWNlcwADCQBoAgUGcGllY2VzABQBFGNoZWNrQ2xhaW1Db25kaXRpb25zAQRhZGRyBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFBGFkZHICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQEC2N1ckxvY2F0aW9uCQELdmFsdWVPckVsc2UCCQCiCAEJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OBANsb2MJALUJAgkBBXZhbHVlAQULY3VyTG9jYXRpb24CAV8DCQECIT0CCQCRAwIFA2xvYwUKbG9jSWR4VHlwZQIBTAkAAgEJAKwCAgkArAICAhZEdWNrIGxvY2F0aW9uIHR5cGUgaXMgCQCRAwIFA2xvYwUKbG9jSWR4VHlwZQIRLCBidXQgc2hvdWxkIGJlIEwEC2xhbmRBc3NldElkCQCRAwIFA2xvYwUIbG9jSWR4SWQEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFB3RpbWVLZXkJAKwCAgkArAICAhBZb3VyIGR1Y2sgaXMgb24gCAUFYXNzZXQEbmFtZQIVLCB3aGljaCBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8JAJYKBAULZHVja0Fzc2V0SWQFC2xhbmRBc3NldElkBQFkBQlzYXZlZFRpbWUBEGNsYWltUmVzSW50ZXJuYWwCBGFkZHIGYW1vdW50BAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMBBQRhZGRyBAhsYW5kU2l6ZQkAkQMCCAUBYwJfMwULcmVjTGFuZFNpemUEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCCAUBYwJfMwULcmVjVGVycmFpbnMECWRlbHRhVGltZQkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wCAUBYwJfNAMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEIBQFjAl80AgwsIGN1cnJlbnQgPSAJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEFCGxhbmRTaXplBBZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQEMYXBwbHlCb251c2VzAggFAWMCXzIFBnBpZWNlcwQIYXZhaWxSZXMJAGsDBQlkZWx0YVRpbWUJAGgCBRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBQZwaWVjZXMFCURBWU1JTExJUwMJAGYCBQZhbW91bnQFCGF2YWlsUmVzCQACAQkArAICCQCsAgIJAKwCAgIiTm90IGVub3VnaCByZXNvdXJjZXMsIGF2YWlsYWJsZSA9IAkApAMBBQhhdmFpbFJlcwIOLCByZXF1ZXN0ZWQgPSAJAKQDAQUGYW1vdW50BAxuZXdEZWx0YVRpbWUJAGsDCQBlAgUIYXZhaWxSZXMFBmFtb3VudAUJREFZTUlMTElTCQBoAgUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQUGcGllY2VzBAxuZXdUaW1lc3RhbXAJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUMbmV3RGVsdGFUaW1lBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQgFAWMCXzEEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQKY3VycmVudFJlcwkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwIBXwQFYnBSZXMJAQZhZGRSZXMFBQpjdXJyZW50UmVzBQ10ZXJyYWluQ291bnRzCQBlAgUJZGVsdGFUaW1lBQxuZXdEZWx0YVRpbWUJAGkCBQZwaWVjZXMAGQUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQkAlQoDCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEIBQFjAl8yBQxuZXdUaW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKTEFORFBSRUZJWAgFAWMCXzIFBGFkZHIFDG5ld1RpbWVzdGFtcAUDbmlsBQVicEtleQkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIFBWJwUmVzCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAQhjbGFpbUFsbAMEYWRkcgtsYW5kQXNzZXRJZAZwaWVjZXMEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBBXZhbHVlAQkAnwgBBQd0aW1lS2V5BAhhdmFpbFJlcwkAaAIJAGsDCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFCXNhdmVkVGltZQkBDGFwcGx5Qm9udXNlcwIFC2xhbmRBc3NldElkBQZwaWVjZXMFCURBWU1JTExJUwUGcGllY2VzCQEQY2xhaW1SZXNJbnRlcm5hbAIFBGFkZHIFCGF2YWlsUmVzAQ11cEluZnJhQ29tbW9uAwxzaG91bGRVc2VNYXQGY2FsbGVyDXBheW1lbnRBbW91bnQEBGFkZHIJAKUIAQUGY2FsbGVyBAFjCQEUY2hlY2tDbGFpbUNvbmRpdGlvbnMBBQRhZGRyBAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQIaW5mcmFLZXkJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQgFAWMCXzIECGN1ckxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEFCGluZnJhS2V5AAADCQBnAgUIY3VyTGV2ZWwAAwkAAgECJkN1cnJlbnRseSBtYXggaW5mcmFzdHJ1Y3R1cmUgbGV2ZWwgPSAzBAhuZXdMZXZlbAkAZAIFCGN1ckxldmVsAAEEBGNvc3QJAGsDBRVJbmZyYVVwZ3JhZGVDb3N0U1VzZG4JAGgCBQZwaWVjZXMFCG5ld0xldmVsABkDAwkBASEBBQxzaG91bGRVc2VNYXQJAQIhPQIFDXBheW1lbnRBbW91bnQFBGNvc3QHCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUEY29zdAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEIBQFjAl8xBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBW1MaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBAZuZXdNYXQJALkJAgkBEXN1YnRyYWN0TWF0ZXJpYWxzAwUMc2hvdWxkVXNlTWF0BQVtTGlzdAkAawMFEUluZnJhVXBncmFkZUNvc3RTCQBoAgUGcGllY2VzBQhuZXdMZXZlbAAZAgFfBAtjbGFpbVJlc3VsdAkBCGNsYWltQWxsAwUEYWRkcggFAWMCXzIFBnBpZWNlcwkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFCGluZnJhS2V5BQhuZXdMZXZlbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHmtleUluZnJhTGV2ZWxCeUFzc2V0SWRBbmRPd25lcgIIBQFjAl8yBQRhZGRyBQhuZXdMZXZlbAkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCCAULY2xhaW1SZXN1bHQCXzMFCGJwSWR4UmVzCQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgUDbmlsCAULY2xhaW1SZXN1bHQCXzEFCG5ld0xldmVsARJhY3RpdmF0ZVByZXNhbGVBcnQBBGFkZHIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwEFBGFkZHIEC2xhbmRBc3NldElkCAUBYwJfMgQNYWN0aXZhdGlvbktleQkBH2tleVByZXNhbGVBcnRBY3RpdmF0ZWRCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAMJAQt2YWx1ZU9yRWxzZQIJAKAIAQUNYWN0aXZhdGlvbktleQcJAAIBAiVQcmVzYWxlIGFydGlmYWN0IGlzIGFscmVhZHkgYWN0aXZhdGVkAwkAZgIJAQ1wYXJzZUludFZhbHVlAQkAkQMCCAUBYwJfMwUKcmVjTGFuZE51bQD0AwkAAgEJAKwCAgkArAICCQCsAgIFCkxBTkRQUkVGSVgCASAFC2xhbmRBc3NldElkAiUgaXMgbm90IGVsaWdpYmxlIGZvciBwcmVzYWxlIGFydGlmYWN0BAZwaWVjZXMJAQ9udW1QaWVjZXNCeVNpemUBCQCRAwIIBQFjAl8zBQtyZWNMYW5kU2l6ZQQLY2xhaW1SZXN1bHQJAQhjbGFpbUFsbAMFBGFkZHIFC2xhbmRBc3NldElkBQZwaWVjZXMJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCAULY2xhaW1SZXN1bHQCXzEJAQxCb29sZWFuRW50cnkCBQ1hY3RpdmF0aW9uS2V5BgkBDEJvb2xlYW5FbnRyeQIJASdrZXlQcmVzYWxlQXJ0QWN0aXZhdGVkQnlBc3NldElkQW5kT3duZXICBQtsYW5kQXNzZXRJZAUEYWRkcgYJAQxJbnRlZ2VyRW50cnkCCQEga2V5TGFuZEFydFN0YXR1c0J5VHlwZUFuZEFzc2V0SWQCBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAUGcGllY2VzCQEMSW50ZWdlckVudHJ5AgkBJWtleUxhbmRBcnRTdGF0dXNCeVR5cGVBc3NldElkQW5kT3duZXIDBQpBUlRQUkVTQUxFBQtsYW5kQXNzZXRJZAUEYWRkcgUGcGllY2VzCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzIJALkJAggFC2NsYWltUmVzdWx0Al8zAgE6AQ1tZXJnZUludGVybmFsBwtuZXdMYW5kU2l6ZQhuZXdMZXZlbAdmb3JtdWxhBGFkZHIMbGFuZEFzc2V0SWRzBHR4SWQHbmVlZE1hdAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkCgEKY2hlY2tNZXJnZQIDYWNjC2xhbmRBc3NldElkBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBAlzYXZlZFRpbWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQd0aW1lS2V5CQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAgwgaXMgb3JwaGFuZWQDCQECIT0CBQVvd25lcgUEYWRkcgkAAgEJAKwCAgUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8ECWNvbnRpbmVudAkAkQMCBQFkBQxyZWNDb250aW5lbnQDAwkBAiE9AggFA2FjYwJfMwIACQECIT0CCAUDYWNjAl8zBQljb250aW5lbnQHCQACAQIuTGFuZHMgc2hvdWxkIGJlIG9uIHRoZSBzYW1lIGNvbnRpbmVudCB0byBtZXJnZQQIbGFuZFNpemUJAJEDAgUBZAULcmVjTGFuZFNpemUEB3NpemVzSW4IBQNhY2MCXzEEAWkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAswkCBQdzaXplc0luBQhsYW5kU2l6ZQInWW91IGhhdmVuJ3QgcGFzc2VkIGFsbCB0aGUgbGFuZHMgbmVlZGVkBAhzaXplc091dAkArAICCQCvAgIFB3NpemVzSW4FAWkJALACAgUHc2l6ZXNJbgkAZAIFAWkAAQQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUEBGFydHMJAGQCCAUDYWNjAl8yCQELdmFsdWVPckVsc2UCCQCfCAEJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFC2xhbmRBc3NldElkAwkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEfa2V5UHJlc2FsZUFydEFjdGl2YXRlZEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBwUGcGllY2VzAAAECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAhyZXFMZXZlbAQHJG1hdGNoMAUIbGFuZFNpemUDCQAAAgIBUwUHJG1hdGNoMAADAwkAAAICAU0FByRtYXRjaDAABAMJAAACAgFMBQckbWF0Y2gwAAUDCQAAAgICWEwFByRtYXRjaDAABgkAAgECGk9ubHkgUywgTSwgTCwgWEwgY2FuIG1lcmdlAwkBAiE9AgUKaW5mcmFMZXZlbAUIcmVxTGV2ZWwJAAIBAiJBbGwgbGFuZHMgc2hvdWxkIGJlIG1heGVkIHRvIG1lcmdlBAdsYW5kTnVtCQCRAwIFAWQFCnJlY0xhbmROdW0EDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQJZGVsdGFUaW1lCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFCXNhdmVkVGltZQMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEFCXNhdmVkVGltZQIMLCBjdXJyZW50ID0gCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBBZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQEMYXBwbHlCb251c2VzAgULbGFuZEFzc2V0SWQFBnBpZWNlcwQFYnBSZXMJAQZhZGRSZXMFCQC1CQIIBQNhY2MCXzQCAV8FDXRlcnJhaW5Db3VudHMFCWRlbHRhVGltZQkAaQIFBnBpZWNlcwAZBRZkYWlseVByb2R1Y3Rpb25CeVBpZWNlBAVwcm9wcwkBGXVwZGF0ZVByb3BvcnRpb25zSW50ZXJuYWwECQC1CQIIBQNhY2MCXzYCAV8FDXRlcnJhaW5Db3VudHMJAGkCBQZwaWVjZXMAGQD///////////8BCQCYCgYFCHNpemVzT3V0BQRhcnRzBQljb250aW5lbnQFBWJwUmVzCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIIBQNhY2MCXzUJAQtEZWxldGVFbnRyeQEJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKTEFORFBSRUZJWAULbGFuZEFzc2V0SWQFBGFkZHIJAQtEZWxldGVFbnRyeQEJARBrZXlMYW5kVG9Bc3NldElkAQUHbGFuZE51bQkBC0RlbGV0ZUVudHJ5AQkBCmtleU5mdE5hbWUCBQdsYW5kTnVtBQhsYW5kU2l6ZQkBC0RlbGV0ZUVudHJ5AQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkCQELRGVsZXRlRW50cnkBCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkCQELRGVsZXRlRW50cnkBCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAgULbGFuZEFzc2V0SWQFBGFkZHIJAQtEZWxldGVFbnRyeQEJAR9rZXlQcmVzYWxlQXJ0QWN0aXZhdGVkQnlBc3NldElkAQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJASdrZXlQcmVzYWxlQXJ0QWN0aXZhdGVkQnlBc3NldElkQW5kT3duZXICBQtsYW5kQXNzZXRJZAUEYWRkcgkBC0RlbGV0ZUVudHJ5AQkBIGtleUxhbmRBcnRTdGF0dXNCeVR5cGVBbmRBc3NldElkAgUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQJAQtEZWxldGVFbnRyeQEJASVrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKQVJUUFJFU0FMRQULbGFuZEFzc2V0SWQFBGFkZHIJAQtEZWxldGVFbnRyeQEJARFrZXlMYW5kTnVtVG9Pd25lcgEFB2xhbmROdW0JAQRCdXJuAgkA2QQBBQtsYW5kQXNzZXRJZAABBQVwcm9wcwQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEB3Byb3BTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBEWtleVJlc1Byb3BvcnRpb25zAAILMF8wXzBfMF8wXzAEAXIKAAIkbAUMbGFuZEFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAmAoGBQdmb3JtdWxhAAACAAkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMFA25pbAUHcHJvcFN0cgoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEKY2hlY2tNZXJnZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEBAljb250aW5lbnQIBQFyAl8zBAxjb250aW5lbnRJZHgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQpjb250aW5lbnRzBQljb250aW5lbnQJAKwCAgITVW5rbm93biBjb250aW5lbnQ6IAUJY29udGluZW50BAh0ZXJyYWlucwkBC2dlblRlcnJhaW5zAgkBA2FicwEJAJ4DAQUEdHhJZAUMY29udGluZW50SWR4BAdmcmVlTnVtCQELdmFsdWVPckVsc2UCCQCfCAEJARJrZXlOZXh0RnJlZUxhbmROdW0AAPUDBApuZXdMYW5kTnVtCQCkAwEFB2ZyZWVOdW0EBWlzc3VlCQDCCAUJAQprZXlOZnROYW1lAgUKbmV3TGFuZE51bQULbmV3TGFuZFNpemUJALkJAgkAzAgCBQpuZXdMYW5kTnVtCQDMCAIFC25ld0xhbmRTaXplCQDMCAIFCHRlcnJhaW5zCQDMCAIFCWNvbnRpbmVudAUDbmlsAgFfAAEAAAcEB2Fzc2V0SWQJALgIAQUFaXNzdWUEDm5ld0xhbmRBc3NldElkCQDYBAEFB2Fzc2V0SWQEBm5ld01hdAkAuQkCCQERc3VidHJhY3RNYXRlcmlhbHMDCQBmAgUHbmVlZE1hdAAACQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBQduZWVkTWF0AgFfCQCUCgIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAgkAzQgCCQDNCAIJAM0IAggFAXICXzUJAQxJbnRlZ2VyRW50cnkCCQESa2V5TmV4dEZyZWVMYW5kTnVtAAkAZAIFB2ZyZWVOdW0AAQUFaXNzdWUJAQtTdHJpbmdFbnRyeQIJARBrZXlMYW5kVG9Bc3NldElkAQUKbmV3TGFuZE51bQUObmV3TGFuZEFzc2V0SWQJAQtTdHJpbmdFbnRyeQIJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQ5uZXdMYW5kQXNzZXRJZAUEYWRkcgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUKbmV3TGFuZE51bQUEYWRkcgkBDEludGVnZXJFbnRyeQIJASBrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQW5kQXNzZXRJZAIFCkFSVFBSRVNBTEUFDm5ld0xhbmRBc3NldElkCAUBcgJfMgkBDEludGVnZXJFbnRyeQIJASVrZXlMYW5kQXJ0U3RhdHVzQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKQVJUUFJFU0FMRQUObmV3TGFuZEFzc2V0SWQFBGFkZHIIBQFyAl8yCQEMSW50ZWdlckVudHJ5AgkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQ5uZXdMYW5kQXNzZXRJZAUIbmV3TGV2ZWwJAQxJbnRlZ2VyRW50cnkCCQEea2V5SW5mcmFMZXZlbEJ5QXNzZXRJZEFuZE93bmVyAgUObmV3TGFuZEFzc2V0SWQFBGFkZHIFCG5ld0xldmVsCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAggFAXICXzQJAMwIAgUGbmV3TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6CQELU3RyaW5nRW50cnkCCQERa2V5UmVzUHJvcG9ydGlvbnMACAUBcgJfNgkBC1N0cmluZ0VudHJ5AgkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQC5CQIJAMwIAgUJY29udGluZW50CQDMCAICAUwJAMwIAgUObmV3TGFuZEFzc2V0SWQFA25pbAIBXwkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUEYWRkcgABBQdhc3NldElkBQ5uZXdMYW5kQXNzZXRJZAEDczJtAwRhZGRyDGxhbmRBc3NldElkcwR0eElkCQENbWVyZ2VJbnRlcm5hbAcCAU0AAwIEU1NTUwUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkAAABA20ybAUEYWRkcgxsYW5kQXNzZXRJZHMEdHhJZAxzaG91bGRVc2VNYXQNcGF5bWVudEFtb3VudAQEY29zdAkAaAIFFUluZnJhVXBncmFkZUNvc3RTVXNkbgAEAwMJAQEhAQUMc2hvdWxkVXNlTWF0CQECIT0CBQ1wYXltZW50QW1vdW50BQRjb3N0BwkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFBGNvc3QJAQ1tZXJnZUludGVybmFsBwIBTAAEAgNTTU0FBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAkAaAIFEUluZnJhVXBncmFkZUNvc3RTAAQBBGwyeGwFBGFkZHIMbGFuZEFzc2V0SWRzBHR4SWQMc2hvdWxkVXNlTWF0DXBheW1lbnRBbW91bnQEBGNvc3QJAGgCBRVJbmZyYVVwZ3JhZGVDb3N0U1VzZG4ALwMDCQEBIQEFDHNob3VsZFVzZU1hdAkBAiE9AgUNcGF5bWVudEFtb3VudAUEY29zdAcJAAIBCQCsAgICG1BheW1lbnQgYXR0YWNoZWQgc2hvdWxkIGJlIAkApAMBBQRjb3N0CQENbWVyZ2VJbnRlcm5hbAcCAlhMAAUCBVNTU01MBQRhZGRyBQxsYW5kQXNzZXRJZHMFBHR4SWQJAGgCBRFJbmZyYVVwZ3JhZGVDb3N0UwAvAQZ4bDJ4eGwFBGFkZHIMbGFuZEFzc2V0SWRzBHR4SWQMc2hvdWxkVXNlTWF0DXBheW1lbnRBbW91bnQEBGNvc3QJAGgCBRVJbmZyYVVwZ3JhZGVDb3N0U1VzZG4ANgMDCQEBIQEFDHNob3VsZFVzZU1hdAkBAiE9AgUNcGF5bWVudEFtb3VudAUEY29zdAcJAAIBCQCsAgICG1BheW1lbnQgYXR0YWNoZWQgc2hvdWxkIGJlIAkApAMBBQRjb3N0CQENbWVyZ2VJbnRlcm5hbAcCA1hYTAAGAgNMWEwFBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAkAaAIFEUluZnJhVXBncmFkZUNvc3RTADYBC21lcmdlQ29tbW9uBQxzaG91bGRVc2VNYXQEYWRkcg1wYXltZW50QW1vdW50DGxhbmRBc3NldElkcwR0eElkBAttZXJnZVJlc3VsdAQHJG1hdGNoMAkAkAMBBQxsYW5kQXNzZXRJZHMDCQAAAgAEBQckbWF0Y2gwCQEDczJtAwUEYWRkcgUMbGFuZEFzc2V0SWRzBQR0eElkAwkAAAIAAwUHJG1hdGNoMAkBA20ybAUFBGFkZHIFDGxhbmRBc3NldElkcwUEdHhJZAUMc2hvdWxkVXNlTWF0BQ1wYXltZW50QW1vdW50AwkAAAIABQUHJG1hdGNoMAkBBGwyeGwFBQRhZGRyBQxsYW5kQXNzZXRJZHMFBHR4SWQFDHNob3VsZFVzZU1hdAUNcGF5bWVudEFtb3VudAMJAAACAAIFByRtYXRjaDAJAQZ4bDJ4eGwFBQRhZGRyBQxsYW5kQXNzZXRJZHMFBHR4SWQFDHNob3VsZFVzZU1hdAUNcGF5bWVudEFtb3VudAkAAgECDVVua25vd24gbWVyZ2UFC21lcmdlUmVzdWx0EAFpAQlzdGFrZUxhbmQABANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQHYXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAQIhPQIIBQNwbXQGYW1vdW50AAEJAAIBCQCsAgIJAKwCAgIETkZUIAUKTEFORFBSRUZJWAIkIHRva2VuIHNob3VsZCBiZSBhdHRhY2hlZCBhcyBwYXltZW50BAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkAwkBAiE9AggFBWFzc2V0Bmlzc3VlcgUEdGhpcwkAAgECF1Vua25vd24gaXNzdWVyIG9mIHRva2VuAwkBASEBCQEIY29udGFpbnMCCAUFYXNzZXQEbmFtZQUKTEFORFBSRUZJWAkAAgEJAKwCAgkArAICAglPbmx5IE5GVCAFCkxBTkRQUkVGSVgCFCB0b2tlbnMgYXJlIGFjY2VwdGVkBAtsYW5kTnVtU2l6ZQkAsAICCAUFYXNzZXQEbmFtZQAEBAdsYW5kTnVtAwkBCGNvbnRhaW5zAgULbGFuZE51bVNpemUCA1hYTAkAswICBQtsYW5kTnVtU2l6ZQADAwkBCGNvbnRhaW5zAgULbGFuZE51bVNpemUCAlhMCQCzAgIFC2xhbmROdW1TaXplAAIJALMCAgULbGFuZE51bVNpemUAAQQKbGFuZE51bUludAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEFB2xhbmROdW0JAKwCAgIeQ2Fubm90IHBhcnNlIGxhbmQgbnVtYmVyIGZyb20gCAUFYXNzZXQEbmFtZQQLbGFuZEFzc2V0SWQJANgEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAMJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCEiBpcyBhbHJlYWR5IHN0YWtlZAQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8EDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQFcHJvcHMJARF1cGRhdGVQcm9wb3J0aW9ucwMFDXRlcnJhaW5Db3VudHMJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQAZAAEJAMwIAgkBDEludGVnZXJFbnRyeQIFB3RpbWVLZXkIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQdhZGRyZXNzCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQFB2FkZHJlc3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5UmVzUHJvcG9ydGlvbnMABQVwcm9wcwUDbmlsAWkBC3Vuc3Rha2VMYW5kAQ5sYW5kQXNzZXRJZFN0cgMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJHVuc3Rha2UgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwQEYWRkcgkApQgBCAUBaQZjYWxsZXIEAWMJARRjaGVja0NsYWltQ29uZGl0aW9ucwEFBGFkZHIEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCCAUBYwJfMwULcmVjVGVycmFpbnMEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAggFAWMCXzMFC3JlY0xhbmRTaXplBAVwcm9wcwkBEXVwZGF0ZVByb3BvcnRpb25zAwUNdGVycmFpbkNvdW50cwkAaQIFBnBpZWNlcwAZAP///////////wEEC2NsYWltUmVzdWx0CQEIY2xhaW1BbGwDBQRhZGRyCAUBYwJfMgUGcGllY2VzCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgABCQDZBAEIBQFjAl8yCQDMCAIJAQtEZWxldGVFbnRyeQEJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQgFAWMCXzIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYCAUBYwJfMgUEYWRkcgkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5UmVzUHJvcG9ydGlvbnMABQVwcm9wcwkAzAgCCQELU3RyaW5nRW50cnkCCAULY2xhaW1SZXN1bHQCXzIJALkJAggFC2NsYWltUmVzdWx0Al8zAgE6BQNuaWwBaQEJc3Rha2VEdWNrAAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIDCQECIT0CCAUDcG10BmFtb3VudAABCQACAQkArAICCQCsAgICBE5GVCAFCkRVQ0tQUkVGSVgCJCB0b2tlbiBzaG91bGQgYmUgYXR0YWNoZWQgYXMgcGF5bWVudAQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMDCQECIT0CCAUFYXNzZXQGaXNzdWVyBQ1pbmN1YmF0b3JBZGRyCQECIT0CCAUFYXNzZXQGaXNzdWVyBQticmVlZGVyQWRkcgcJAAIBCQCsAgIJAKwCAgISVW5rbm93biBpc3N1ZXIgb2YgBQpEVUNLUFJFRklYAgYgdG9rZW4DCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpEVUNLUFJFRklYCQACAQkArAICCQCsAgICCU9ubHkgTkZUIAUKRFVDS1BSRUZJWAIUIHRva2VucyBhcmUgYWNjZXB0ZWQECmFzc2V0SWRTdHIJANgEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQphc3NldElkU3RyAwkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQISIGlzIGFscmVhZHkgc3Rha2VkAwkBCWlzRGVmaW5lZAEJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwkAAgEJAKwCAgIdWW91IGFscmVhZHkgc3Rha2VkIG9uZSBkdWNrOiAIBQVhc3NldARuYW1lBAZsb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQphc3NldElkU3RyBAhsb2NhdGlvbgkAoggBBQZsb2NLZXkECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQphc3NldElkU3RyBAZoZWFsdGgJAJ8IAQUJa2V5SGVhbHRoBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQUKYXNzZXRJZFN0cgQIYmFja3BhY2sJAKIIAQUFYnBLZXkJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUHdGltZUtleQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKRFVDS1BSRUZJWAkA2AQBBQdhc3NldElkBQdhZGRyZXNzCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5RHVja0lkVG9Pd25lcgEFCmFzc2V0SWRTdHIFB2FkZHJlc3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwUKYXNzZXRJZFN0cgUDbmlsAwkBCWlzRGVmaW5lZAEFCGxvY2F0aW9uBQNuaWwJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQZsb2NLZXkFD0RFRkFVTFRMT0NBVElPTgUDbmlsAwkBCWlzRGVmaW5lZAEFBmhlYWx0aAUDbmlsCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aABkBQNuaWwDCQEJaXNEZWZpbmVkAQUIYmFja3BhY2sFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQIaMDowXzBfMF8wXzBfMDowXzBfMF8wXzBfMDoFA25pbAFpAQt1bnN0YWtlRHVjawEKYXNzZXRJZFN0cgMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJHVuc3Rha2UgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwQHYXNzZXRJZAkA2QQBBQphc3NldElkU3RyBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQFYXNzZXQJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAMDCQECIT0CCAUFYXNzZXQGaXNzdWVyBQ1pbmN1YmF0b3JBZGRyCQECIT0CCAUFYXNzZXQGaXNzdWVyBQticmVlZGVyQWRkcgcJAAIBCQCsAgIJAKwCAgISVW5rbm93biBpc3N1ZXIgb2YgBQpEVUNLUFJFRklYAgYgdG9rZW4DCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpEVUNLUFJFRklYCQACAQkArAICCQCsAgICCU9ubHkgTkZUIAUKRFVDS1BSRUZJWAIXIHRva2VucyBjYW4gYmUgdW5zdGFrZWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQkA2AQBBQdhc3NldElkAwkBASEBCQEJaXNEZWZpbmVkAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQDCQEBIQEJAQlpc0RlZmluZWQBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzCQACAQkArAICCQCsAgICCVRoZSBkdWNrIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAVvd25lcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARBrZXlEdWNrSWRUb093bmVyAQkA2AQBBQdhc3NldElkCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDCBpcyBvcnBoYW5lZAMJAQIhPQIFBW93bmVyBQdhZGRyZXNzCQACAQIXU3Rha2VkIE5GVCBpcyBub3QgeW91cnMJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEFB2Fzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQUHdGltZUtleQkAzAgCCQELRGVsZXRlRW50cnkBCQEPa2V5RHVja0xvY2F0aW9uAQUKYXNzZXRJZFN0cgkAzAgCCQELRGVsZXRlRW50cnkBCQEQa2V5RHVja0lkVG9Pd25lcgEFCmFzc2V0SWRTdHIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpEVUNLUFJFRklYBQphc3NldElkU3RyBQdhZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MFA25pbAFpAQhjbGFpbVJlcwIGYW1vdW50DmxhbmRBc3NldElkU3RyAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIlY2xhaW1SZXMgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwQEYWRkcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEBnJlc3VsdAkBEGNsYWltUmVzSW50ZXJuYWwCBQRhZGRyBQZhbW91bnQJAJQKAgkAzQgCCAUGcmVzdWx0Al8xCQELU3RyaW5nRW50cnkCCAUGcmVzdWx0Al8yCQC5CQIIBQZyZXN1bHQCXzMCAToJAJEDAggFBnJlc3VsdAJfMwUIYnBJZHhSZXMBaQEGZmxpZ2h0AgdtZXNzYWdlA3NpZwMJAQEhAQkAxBMDBQdtZXNzYWdlBQNzaWcFA3B1YgkAAgECGHNpZ25hdHVyZSBkb2VzIG5vdCBtYXRjaAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECI2ZsaWdodCBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzBAVwYXJ0cwkAtQkCCQCwCQEFB21lc3NhZ2UCATsEAmhwCQC1CQIJAJEDAgkAtQkCCQCRAwIFBXBhcnRzAAACAXwAAAIBXwQFY3VySFAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJocAAABAVuZXdIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAEEDW5ld0xvY0FuZFRpbWUJALUJAgkAkQMCBQVwYXJ0cwABAgE6BAtuZXdMb2NhdGlvbgkAkQMCBQ1uZXdMb2NBbmRUaW1lAAAEBHRpbWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ1uZXdMb2NBbmRUaW1lAAEDAwkAZgIFBHRpbWUJAGQCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAURRklWRU1JTlVURVNNSUxMSVMGCQBmAgkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwUEdGltZQkAAgECEnNpZ25hdHVyZSBvdXRkYXRlZAQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEIBQFpBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBAxvbGRGcm9tU3RhdGUJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQDCQECIT0CBQxvbGRGcm9tU3RhdGUFBWN1ckhQCQACAQkArAICCQCsAgIJAKwCAgIKb2xkSGVhbHRoPQkApAMBCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aABkAi8gZnJvbSBzdGF0ZSBkb2VzIG5vdCBtYXRjaCBvbmUgZnJvbSBmbGlnaHQgbG9nPQkApAMBBQVjdXJIUAMJAGcCAAAFBWN1ckhQCQACAQIeWW91IGNhbid0IGZseSB3aXRoIHplcm8gaGVhbHRoBAZsb2NLZXkJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQUGbG9jS2V5BQ9ERUZBVUxUTE9DQVRJT04DCQAAAgULbmV3TG9jYXRpb24FC2N1ckxvY2F0aW9uCQACAQIiWW91IGNhbid0IGZseSB0byB0aGUgc2FtZSBsb2NhdGlvbgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBmxvY0tleQMJAGYCBQVuZXdIUAAABQtuZXdMb2NhdGlvbgULY3VyTG9jYXRpb24JAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAUFbmV3SFAFA25pbAUEdW5pdAFpAQlzZXRIZWFsdGgCBmhlYWx0aAtkdWNrQXNzZXRJZAMDCQBmAgAABQZoZWFsdGgGCQBmAgUGaGVhbHRoAGQJAAIBAhpIUCBzaG91bGQgYmUgd2l0aGluIDAuLjEwMAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAUGaGVhbHRoBQNuaWwBaQEEaGVhbAIHbWF0VHlwZQZhbW91bnQDAwkAZgIAAAUHbWF0VHlwZQYJAGcCBQdtYXRUeXBlBQZOVU1SRVMJAAIBCQCsAgICElVua25vd24gbWF0ZXJpYWw6IAkApAMBBQdtYXRUeXBlAwkAZwIAAAUGYW1vdW50CQACAQkArAICAhtBbW91bnQgc2hvdWxkIGJlIHBvc2l0aXZlISAJAKQDAQUGYW1vdW50BAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQECW9sZEhlYWx0aAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgAZAMJAGcCBQlvbGRIZWFsdGgAZAkAAgECGkhQIHNob3VsZCBiZSA8IDEwMCB0byBoZWFsBAVicEtleQkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQEC2N1cnJlbnRQYWNrCQELZ2V0QmFja3BhY2sBBQVicEtleQQFbUxpc3QJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQCAV8EDWN1cnJlbnRBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVtTGlzdAUHbWF0VHlwZQQLZGVsdGFIZWFsdGgJAJcDAQkAzAgCCQBpAgUGYW1vdW50BQhIRUFMQ09TVAkAzAgCCQBlAgBkBQlvbGRIZWFsdGgFA25pbAQLc3BlbmRBbW91bnQJAGgCBQtkZWx0YUhlYWx0aAUISEVBTENPU1QDCQBmAgULc3BlbmRBbW91bnQFDWN1cnJlbnRBbW91bnQJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIJWW91IG5lZWQgCQCkAwEFC3NwZW5kQW1vdW50AgQgb2YgCQCRAwIFCG1hdFR5cGVzBQdtYXRUeXBlAiQgdG8gaGVhbCwgYnV0IHlvdSBiYWNrcGFjayBjb250YWlucyAJAKQDAQUNY3VycmVudEFtb3VudAQGbmV3TWF0CQEMc3ViT25lSW5MaXN0AwUFbUxpc3QFB21hdFR5cGUFC3NwZW5kQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrZXlIZWFsdGgJAGQCBQlvbGRIZWFsdGgFC2RlbHRhSGVhbHRoCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeFJlcwkAzAgCBQZuZXdNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToFA25pbAFpAQ51cGRhdGVCYWNrcGFjawILZHVja0Fzc2V0SWQHbmV3UGFjawMJAQIhPQIIBQFpBmNhbGxlcgULZWNvbm9teUFkZHIJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBQduZXdQYWNrBQNuaWwFB25ld1BhY2sBaQENZXhwZWRpdGlvbkJ1eQIHbWVzc2FnZQNzaWcDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAULdXNkbkFzc2V0SWQJAAIBAhpBbGxvd2VkIFVTRE4gcGF5bWVudCBvbmx5IQMJAQIhPQIIBQNwbXQGYW1vdW50BQdFWFBVU0ROCQACAQkArAICAhtQYXltZW50IGF0dGFjaGVkIHNob3VsZCBiZSAJAKQDAQUHRVhQVVNETgQGcmVzdWx0CQEQZXhwZWRpdGlvbkNvbW1vbgUHCAUBaQZjYWxsZXIIBQFpDXRyYW5zYWN0aW9uSWQFB21lc3NhZ2UFA3NpZwkAlAoCCQDNCAIIBQZyZXN1bHQCXzEJAQ5TY3JpcHRUcmFuc2ZlcgMFC2Vjb25vbXlBZGRyCAUDcG10BmFtb3VudAULdXNkbkFzc2V0SWQIBQZyZXN1bHQCXzIBaQEKZXhwZWRpdGlvbgIHbWVzc2FnZQNzaWcDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAidleHBlZGl0aW9uIGRvZXNuJ3QgcmVxdWlyZSBhbnkgcGF5bWVudHMJARBleHBlZGl0aW9uQ29tbW9uBQYIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAUHbWVzc2FnZQUDc2lnAWkBDHVwZ3JhZGVJbmZyYQESbGFuZEFzc2V0SWRJZ25vcmVkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIzSW5mcmFzdHJ1Y3R1cmUgdXBncmFkZSBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzCQENdXBJbmZyYUNvbW1vbgMGCAUBaQZjYWxsZXIAAAFpARB1cGdyYWRlSW5mcmFVc2RuARJsYW5kQXNzZXRJZElnbm9yZWQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhxFeGFjdGx5IG9uZSBwYXltZW50IHJlcXVpcmVkBANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIIBQNwbXQHYXNzZXRJZAULdXNkbkFzc2V0SWQJAAIBAhpBbGxvd2VkIFVTRE4gcGF5bWVudCBvbmx5IQQGcmVzdWx0CQENdXBJbmZyYUNvbW1vbgMHCAUBaQZjYWxsZXIIBQNwbXQGYW1vdW50CQCUCgIJAM0IAggFBnJlc3VsdAJfMQkBDlNjcmlwdFRyYW5zZmVyAwULZWNvbm9teUFkZHIIBQNwbXQGYW1vdW50BQt1c2RuQXNzZXRJZAgFBnJlc3VsdAJfMgFpARBhY3RpdmF0ZUFydGlmYWN0AQdhcnROYW1lAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIwQXJ0aWZhY3QgYWN0aXZhdGlvbiBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzBAZyZXN1bHQEByRtYXRjaDAFB2FydE5hbWUDCQAAAgIHUFJFU0FMRQUHJG1hdGNoMAkBEmFjdGl2YXRlUHJlc2FsZUFydAEJAKUIAQgFAWkGY2FsbGVyCQACAQIQVW5rbm93biBhcnRpZmFjdAUGcmVzdWx0AWkBCm1lcmdlTGFuZHMBDGxhbmRBc3NldElkcwMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEXBlcm1pc3Npb24gZGVuaWVkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIqTGFuZHMgbWVyZ2luZyBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzCQELbWVyZ2VDb21tb24FBgkApQgBCAUBaQZjYWxsZXIAAAUMbGFuZEFzc2V0SWRzCAUBaQ10cmFuc2FjdGlvbklkAWkBDm1lcmdlTGFuZHNVc2RuAQxsYW5kQXNzZXRJZHMDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkBQt1c2RuQXNzZXRJZAkAAgECGkFsbG93ZWQgVVNETiBwYXltZW50IG9ubHkhBAZyZXN1bHQJAQttZXJnZUNvbW1vbgUHCQClCAEIBQFpBmNhbGxlcggFA3BtdAZhbW91bnQFDGxhbmRBc3NldElkcwgFAWkNdHJhbnNhY3Rpb25JZAkAlAoCCQDNCAIIBQZyZXN1bHQCXzEJAQ5TY3JpcHRUcmFuc2ZlcgMFC2Vjb25vbXlBZGRyCAUDcG10BmFtb3VudAULdXNkbkFzc2V0SWQIBQZyZXN1bHQCXzIAp6gufw==", "height": 3471996, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9oK4dAXom2dQLD8AQ3YJqf7Pj2NJdBTgBpXdUdC3Cwna Next: CP6igkuaWA8XiCzovPjpDDv9zthn8nuDcfFDC3FRZ9c1 Diff:
OldNewDifferences
6262 let InfraUpgradeCostS = match chain {
6363 case _ =>
6464 if (("W" == $match0))
65- then 18921595217
65+ then 6307198406
6666 else if (("T" == $match0))
67- then 189215952
67+ then 63071984
6868 else throw("Unknown chain")
6969 }
7070
7171 let InfraUpgradeCostSUsdn = match chain {
7272 case _ =>
7373 if (("W" == $match0))
74- then 120000000
74+ then 40000000
7575 else if (("T" == $match0))
76- then 1200000
76+ then 400000
7777 else throw("Unknown chain")
7878 }
7979
113113
114114 let continents = ["Asia", "Europe", "Americas", "Oceania", "Africa"]
115115
116+let ARTPRESALE = "PRESALE"
117+
116118 func keyNextFreeLandNum () = "nextLandNum"
117119
118120
141143
142144
143145 func keyPresaleArtActivatedByAssetIdAndOwner (assetId,ownerAddr) = ((("presaleArtActivatedByAssetIdAndOwner_" + assetId) + "_") + ownerAddr)
146+
147+
148+func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["landArtStatus", type, assetId], "_")
149+
150+
151+func keyLandArtStatusByTypeAssetIdAndOwner (type,assetId,ownerAddr) = makeString(["landArtStatusByTypeAssetIdAndOwner", type, assetId, ownerAddr], "_")
144152
145153
146154 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
252260 }
253261
254262
263+func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
264+ then throw("Wrong proportions data")
265+ else {
266+ func updater (acc,i) = {
267+ let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
268+ if ((0 > result))
269+ then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
270+ else (acc :+ toString(result))
271+ }
272+
273+ let r = {
274+ let $l = [0, 1, 2, 3, 4, 5]
275+ let $s = size($l)
276+ let $acc0 = nil
277+ func $f0_1 ($a,$i) = if (($i >= $s))
278+ then $a
279+ else updater($a, $l[$i])
280+
281+ func $f0_2 ($a,$i) = if (($i >= $s))
282+ then $a
283+ else throw("List size exceeds 6")
284+
285+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
286+ }
287+ makeString(r, "_")
288+ }
289+
290+
255291 func updateProportions (terrainCounts,landSizeIndex,sign) = {
256- let props = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
257- if ((size(props) != NUMRES))
258- then throw("Wrong proportions data")
259- else {
260- func updater (acc,i) = {
261- let result = (parseIntValue(props[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
262- if ((0 > result))
263- then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
264- else (acc :+ toString(result))
265- }
266-
267- let r = {
268- let $l = [0, 1, 2, 3, 4, 5]
269- let $s = size($l)
270- let $acc0 = nil
271- func $f0_1 ($a,$i) = if (($i >= $s))
272- then $a
273- else updater($a, $l[$i])
274-
275- func $f0_2 ($a,$i) = if (($i >= $s))
276- then $a
277- else throw("List size exceeds 6")
278-
279- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
280- }
281- makeString(r, "_")
282- }
292+ let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
293+ updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign)
283294 }
284295
285296
373384 }
374385
375386
387+func genTerrains (seed,continentIdx) = {
388+ let f = freq[continentIdx]
389+ 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))
390+
391+ let t = {
392+ let $l = [1, 2, 3, 4, 5]
393+ let $s = size($l)
394+ let $acc0 = $Tuple2("", (seed / FIVEX))
395+ func $f0_1 ($a,$i) = if (($i >= $s))
396+ then $a
397+ else terrainGenerator($a, $l[$i])
398+
399+ func $f0_2 ($a,$i) = if (($i >= $s))
400+ then $a
401+ else throw("List size exceeds 5")
402+
403+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
404+ }
405+ t._1
406+ }
407+
408+
376409 func getBackpack (bpKey) = {
377410 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
378411 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
422455 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), 501)
423456 let landNum = toString(freeNum)
424457 let continentIdx = toInt((bigNum % FIVEX))
425- let f = freq[continentIdx]
426- 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))
427-
428- let t = {
429- let $l = [1, 2, 3, 4, 5]
430- let $s = size($l)
431- let $acc0 = $Tuple2("", (bigNum / FIVEX))
432- func $f0_1 ($a,$i) = if (($i >= $s))
433- then $a
434- else terrainGenerator($a, $l[$i])
435-
436- func $f0_2 ($a,$i) = if (($i >= $s))
437- then $a
438- else throw("List size exceeds 5")
439-
440- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
441- }
458+ let terrains = genTerrains(bigNum, continentIdx)
442459 let continent = continents[continentIdx]
443- let issue = Issue(keyNftName(landNum, "S"), makeString([landNum, "S", t._1, continent], "_"), 1, 0, false)
460+ let issue = Issue(keyNftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
444461 let assetId = calculateAssetId(issue)
445462 let id = toBase58String(assetId)
446463 $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), StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", id], "_")), IntegerEntry(keyHealth, newHP), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))], id)
450467 }
451468
452469
453-func applyBonuses (landAssetId) = {
470+func applyBonuses (landAssetId,pieces) = {
454471 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
455- let presaleBonus = if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
456- then 3
457- else 0
458- ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, infraLevel, 4)) + fraction(DAILYRESBYPIECE, presaleBonus, 20))
472+ let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
473+ then pieces
474+ else 0)
475+ ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, infraLevel, 4)) + fraction(DAILYRESBYPIECE, (artPieces * 3), (pieces * 20)))
459476 }
460477
461478
469486 let landAssetId = loc[locIdxId]
470487 let asset = value(assetInfo(fromBase58String(landAssetId)))
471488 let timeKey = keyStakedTimeByAssetId(landAssetId)
472- let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
489+ let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Your duck is on " + asset.name) + ", which is not staked"))
473490 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
474491 if ((owner != addr))
475492 then throw((LANDPREFIX + " is not yours"))
490507 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", current = ") + toString(lastBlock.timestamp)))
491508 else {
492509 let pieces = numPiecesBySize(landSize)
493- let dailyProductionByPiece = applyBonuses(c._2)
510+ let dailyProductionByPiece = applyBonuses(c._2, pieces)
494511 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
495512 if ((amount > availRes))
496513 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
510527 func claimAll (addr,landAssetId,pieces) = {
511528 let timeKey = keyStakedTimeByAssetId(landAssetId)
512529 let savedTime = value(getInteger(timeKey))
513- let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId), DAYMILLIS) * pieces)
530+ let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
514531 claimResInternal(addr, availRes)
515532 }
516533
544561
545562 func activatePresaleArt (addr) = {
546563 let c = checkClaimConditions(addr)
547- let activationKey = keyPresaleArtActivatedByAssetId(c._2)
564+ let landAssetId = c._2
565+ let activationKey = keyPresaleArtActivatedByAssetId(landAssetId)
548566 if (valueOrElse(getBoolean(activationKey), false))
549567 then throw("Presale artifact is already activated")
550568 else if ((parseIntValue(c._3[recLandNum]) > 500))
551- then throw((((LANDPREFIX + " ") + c._2) + " is not eligible for presale artifact"))
569+ then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
552570 else {
553571 let pieces = numPiecesBySize(c._3[recLandSize])
554- let claimResult = claimAll(addr, c._2, pieces)
555- (((claimResult._1 :+ BooleanEntry(keyPresaleArtActivatedByAssetId(c._2), true)) :+ BooleanEntry(keyPresaleArtActivatedByAssetIdAndOwner(c._2, addr), true)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":")))
572+ let claimResult = claimAll(addr, landAssetId, pieces)
573+ (((((claimResult._1 :+ BooleanEntry(activationKey, true)) :+ BooleanEntry(keyPresaleArtActivatedByAssetIdAndOwner(landAssetId, addr), true)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId), pieces)) :+ IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, addr), pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":")))
556574 }
575+ }
576+
577+
578+func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,txId,needMat) = {
579+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
580+ func checkMerge (acc,landAssetId) = {
581+ let asset = value(assetInfo(fromBase58String(landAssetId)))
582+ let timeKey = keyStakedTimeByAssetId(landAssetId)
583+ let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
584+ let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
585+ if ((owner != addr))
586+ then throw((LANDPREFIX + " is not yours"))
587+ else {
588+ let d = split(asset.description, "_")
589+ let continent = d[recContinent]
590+ if (if ((acc._3 != ""))
591+ then (acc._3 != continent)
592+ else false)
593+ then throw("Lands should be on the same continent to merge")
594+ else {
595+ let landSize = d[recLandSize]
596+ let sizesIn = acc._1
597+ let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
598+ let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
599+ let pieces = numPiecesBySize(landSize)
600+ let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
601+ then pieces
602+ else 0))
603+ let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
604+ let reqLevel = match landSize {
605+ case _ =>
606+ if (("S" == $match0))
607+ then 3
608+ else if (("M" == $match0))
609+ then 4
610+ else if (("L" == $match0))
611+ then 5
612+ else if (("XL" == $match0))
613+ then 6
614+ else throw("Only S, M, L, XL can merge")
615+ }
616+ if ((infraLevel != reqLevel))
617+ then throw("All lands should be maxed to merge")
618+ else {
619+ let landNum = d[recLandNum]
620+ let terrainCounts = countTerrains(d[recTerrains])
621+ let deltaTime = (lastBlock.timestamp - savedTime)
622+ if ((0 > deltaTime))
623+ then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
624+ else {
625+ let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
626+ let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, (pieces / 25), dailyProductionByPiece)
627+ let props = updateProportionsInternal(split(acc._6, "_"), terrainCounts, (pieces / 25), -1)
628+ $Tuple6(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(keyPresaleArtActivatedByAssetId(landAssetId))) :+ DeleteEntry(keyPresaleArtActivatedByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, addr))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ Burn(fromBase58String(landAssetId), 1)), props)
629+ }
630+ }
631+ }
632+ }
633+ }
634+
635+ let bpKey = keyBackpackByDuck(duckAssetId)
636+ let currentPack = getBackpack(bpKey)
637+ let propStr = valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0")
638+ let r = {
639+ let $l = landAssetIds
640+ let $s = size($l)
641+ let $acc0 = $Tuple6(formula, 0, "", currentPack[bpIdxRes], nil, propStr)
642+ func $f0_1 ($a,$i) = if (($i >= $s))
643+ then $a
644+ else checkMerge($a, $l[$i])
645+
646+ func $f0_2 ($a,$i) = if (($i >= $s))
647+ then $a
648+ else throw("List size exceeds 4")
649+
650+ $f0_2($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4)
651+ }
652+ let continent = r._3
653+ let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
654+ let terrains = genTerrains(abs(toBigInt(txId)), continentIdx)
655+ let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), 501)
656+ let newLandNum = toString(freeNum)
657+ let issue = Issue(keyNftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
658+ let assetId = calculateAssetId(issue)
659+ let newLandAssetId = toBase58String(assetId)
660+ let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
661+ $Tuple2((((((((((((((r._5 :+ 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)
662+ }
663+
664+
665+func s2m (addr,landAssetIds,txId) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, txId, 0)
666+
667+
668+func m2l (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
669+ let cost = (InfraUpgradeCostSUsdn * 4)
670+ if (if (!(shouldUseMat))
671+ then (paymentAmount != cost)
672+ else false)
673+ then throw(("Payment attached should be " + toString(cost)))
674+ else mergeInternal("L", 4, "SMM", addr, landAssetIds, txId, (InfraUpgradeCostS * 4))
675+ }
676+
677+
678+func l2xl (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
679+ let cost = (InfraUpgradeCostSUsdn * 47)
680+ if (if (!(shouldUseMat))
681+ then (paymentAmount != cost)
682+ else false)
683+ then throw(("Payment attached should be " + toString(cost)))
684+ else mergeInternal("XL", 5, "SSSML", addr, landAssetIds, txId, (InfraUpgradeCostS * 47))
685+ }
686+
687+
688+func xl2xxl (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
689+ let cost = (InfraUpgradeCostSUsdn * 54)
690+ if (if (!(shouldUseMat))
691+ then (paymentAmount != cost)
692+ else false)
693+ then throw(("Payment attached should be " + toString(cost)))
694+ else mergeInternal("XXL", 6, "LXL", addr, landAssetIds, txId, (InfraUpgradeCostS * 54))
695+ }
696+
697+
698+func mergeCommon (shouldUseMat,addr,paymentAmount,landAssetIds,txId) = {
699+ let mergeResult = match size(landAssetIds) {
700+ case _ =>
701+ if ((4 == $match0))
702+ then s2m(addr, landAssetIds, txId)
703+ else if ((3 == $match0))
704+ then m2l(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
705+ else if ((5 == $match0))
706+ then l2xl(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
707+ else if ((2 == $match0))
708+ then xl2xxl(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
709+ else throw("Unknown merge")
710+ }
711+ mergeResult
557712 }
558713
559714
839994 }
840995
841996
997+
998+@Callable(i)
999+func mergeLands (landAssetIds) = if ((i.caller != this))
1000+ then throw("permission denied")
1001+ else if ((size(i.payments) != 0))
1002+ then throw("Lands merging doesn't require any payments")
1003+ else mergeCommon(true, toString(i.caller), 0, landAssetIds, i.transactionId)
1004+
1005+
1006+
1007+@Callable(i)
1008+func mergeLandsUsdn (landAssetIds) = if ((i.caller != this))
1009+ then throw("permission denied")
1010+ else if ((size(i.payments) != 1))
1011+ then throw("Exactly one payment required")
1012+ else {
1013+ let pmt = value(i.payments[0])
1014+ if ((pmt.assetId != usdnAssetId))
1015+ then throw("Allowed USDN payment only!")
1016+ else {
1017+ let result = mergeCommon(false, toString(i.caller), pmt.amount, landAssetIds, i.transactionId)
1018+ $Tuple2((result._1 :+ ScriptTransfer(economyAddr, pmt.amount, usdnAssetId)), result._2)
1019+ }
1020+ }
1021+
1022+
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let chain = toUtf8String(take(drop(this.bytes, 1), 1))
55
66 let usdnAssetId = match chain {
77 case _ =>
88 if (("W" == $match0))
99 then base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
1010 else if (("T" == $match0))
1111 then base58'HezsdQuRDtzksAYUy97gfhKy7Z1NW2uXYSHA3bgqenNZ'
1212 else throw("Unknown chain")
1313 }
1414
1515 let incubatorAddr = match chain {
1616 case _ =>
1717 if (("W" == $match0))
1818 then addressFromStringValue("3PEktVux2RhchSN63DsDo4b4mz4QqzKSeDv")
1919 else if (("T" == $match0))
2020 then this
2121 else throw("Unknown chain")
2222 }
2323
2424 let breederAddr = match chain {
2525 case _ =>
2626 if (("W" == $match0))
2727 then addressFromStringValue("3PDVuU45H7Eh5dmtNbnRNRStGwULA7NY6Hb")
2828 else if (("T" == $match0))
2929 then this
3030 else throw("Unknown chain")
3131 }
3232
3333 let economyAddr = match chain {
3434 case _ =>
3535 if (("W" == $match0))
3636 then addressFromStringValue("3P2sk1KncSxRaZs8b4CWGPw2jkvvav74u4D")
3737 else if (("T" == $match0))
3838 then addressFromStringValue("3N8y4wxX3JC4TdrCJBXX16SjWf6X256hrep")
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 DAILYRESBYPIECE = 3456000
5555
5656 let DAYMILLIS = 86400000
5757
5858 let FIVEMINUTESMILLIS = 300000
5959
6060 let RESOURCEPRICEMIN = 158549
6161
6262 let InfraUpgradeCostS = match chain {
6363 case _ =>
6464 if (("W" == $match0))
65- then 18921595217
65+ then 6307198406
6666 else if (("T" == $match0))
67- then 189215952
67+ then 63071984
6868 else throw("Unknown chain")
6969 }
7070
7171 let InfraUpgradeCostSUsdn = match chain {
7272 case _ =>
7373 if (("W" == $match0))
74- then 120000000
74+ then 40000000
7575 else if (("T" == $match0))
76- then 1200000
76+ then 400000
7777 else throw("Unknown chain")
7878 }
7979
8080 let EXPMATERIALS = match chain {
8181 case _ =>
8282 if (("W" == $match0))
8383 then 157679960139
8484 else if (("T" == $match0))
8585 then 1576799601
8686 else throw("Unknown chain")
8787 }
8888
8989 let EXPUSDN = match chain {
9090 case _ =>
9191 if (("W" == $match0))
9292 then 1000000000
9393 else if (("T" == $match0))
9494 then 10000000
9595 else throw("Unknown chain")
9696 }
9797
9898 let MULT6 = 1000000
9999
100100 let FIVEX = toBigInt(5)
101101
102102 let TWENTYX = toBigInt(20)
103103
104104 let TWENTY2X = toBigInt((20 * 20))
105105
106106 let TWENTY3X = toBigInt(((20 * 20) * 20))
107107
108108 let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
109109
110110 let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
111111
112112 let matTypes = ["Fuel", "Metal", "Plank", "Glass", "Plastic", "Protein"]
113113
114114 let continents = ["Asia", "Europe", "Americas", "Oceania", "Africa"]
115115
116+let ARTPRESALE = "PRESALE"
117+
116118 func keyNextFreeLandNum () = "nextLandNum"
117119
118120
119121 func keyLandToAssetId (landNum) = ("landToAsset_" + landNum)
120122
121123
122124 func keyNftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
123125
124126
125127 func keyLandAssetIdToOwner (assetId) = ("nftOwner_" + assetId)
126128
127129
128130 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
129131
130132
131133 func keyStakedTimeByAssetId (assetId) = ("stakedTime_" + assetId)
132134
133135
134136 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
135137
136138
137139 func keyInfraLevelByAssetIdAndOwner (assetId,ownerAddr) = ((("infraLevelByAssetIdAndOwner_" + assetId) + "_") + ownerAddr)
138140
139141
140142 func keyPresaleArtActivatedByAssetId (assetId) = ("presaleArtActivated_" + assetId)
141143
142144
143145 func keyPresaleArtActivatedByAssetIdAndOwner (assetId,ownerAddr) = ((("presaleArtActivatedByAssetIdAndOwner_" + assetId) + "_") + ownerAddr)
146+
147+
148+func keyLandArtStatusByTypeAndAssetId (type,assetId) = makeString(["landArtStatus", type, assetId], "_")
149+
150+
151+func keyLandArtStatusByTypeAssetIdAndOwner (type,assetId,ownerAddr) = makeString(["landArtStatusByTypeAssetIdAndOwner", type, assetId, ownerAddr], "_")
144152
145153
146154 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
147155
148156
149157 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("stakedTimeByTypeAssetIdAndOwner_" + nftType) + "_") + assetId) + "_") + ownerAddr)
150158
151159
152160 func keyLandNumToOwner (landNum) = ("landOwner_" + landNum)
153161
154162
155163 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
156164
157165
158166 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
159167
160168
161169 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
162170
163171
164172 func keyResProportions () = "resTypesProportions"
165173
166174
167175 let recLandNum = 0
168176
169177 let recLandSize = 1
170178
171179 let recTerrains = 2
172180
173181 let recContinent = 3
174182
175183 let locIdxContinent = 0
176184
177185 let locIdxType = 1
178186
179187 let locIdxId = 2
180188
181189 let bpIdxLevel = 0
182190
183191 let bpIdxRes = 1
184192
185193 let bpIdxMat = 2
186194
187195 let bpIdxProd = 3
188196
189197 func asString (v) = match v {
190198 case s: String =>
191199 s
192200 case _ =>
193201 throw("fail to cast into String")
194202 }
195203
196204
197205 func getNeededMaterials (total) = {
198206 let props = split(value(getString(keyResProportions())), "_")
199207 if ((size(props) != NUMRES))
200208 then throw("Wrong proportions data")
201209 else {
202210 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
203211 let sum = (((((r[0] + r[1]) + r[2]) + r[3]) + r[4]) + r[5])
204212 if ((0 >= sum))
205213 then throw("No lands staked")
206214 else {
207215 let norm6 = fraction(total, MULT6, sum)
208216 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
209217
210218 let $l = r
211219 let $s = size($l)
212220 let $acc0 = nil
213221 func $f0_1 ($a,$i) = if (($i >= $s))
214222 then $a
215223 else normalizer($a, $l[$i])
216224
217225 func $f0_2 ($a,$i) = if (($i >= $s))
218226 then $a
219227 else throw("List size exceeds 6")
220228
221229 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
222230 }
223231 }
224232 }
225233
226234
227235 func subtractMaterials (shouldUseMat,has,totalNeed) = {
228236 let need = getNeededMaterials(totalNeed)
229237 func subtractor (acc,idx) = {
230238 let result = (parseIntValue(has[idx]) - need[idx])
231239 if ((0 > result))
232240 then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
233241 else (acc :+ toString(result))
234242 }
235243
236244 if (shouldUseMat)
237245 then {
238246 let $l = [0, 1, 2, 3, 4, 5]
239247 let $s = size($l)
240248 let $acc0 = nil
241249 func $f0_1 ($a,$i) = if (($i >= $s))
242250 then $a
243251 else subtractor($a, $l[$i])
244252
245253 func $f0_2 ($a,$i) = if (($i >= $s))
246254 then $a
247255 else throw("List size exceeds 6")
248256
249257 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
250258 }
251259 else has
252260 }
253261
254262
263+func updateProportionsInternal (propList,terrainCounts,landSizeIndex,sign) = if ((size(propList) != NUMRES))
264+ then throw("Wrong proportions data")
265+ else {
266+ func updater (acc,i) = {
267+ let result = (parseIntValue(propList[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
268+ if ((0 > result))
269+ then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
270+ else (acc :+ toString(result))
271+ }
272+
273+ let r = {
274+ let $l = [0, 1, 2, 3, 4, 5]
275+ let $s = size($l)
276+ let $acc0 = nil
277+ func $f0_1 ($a,$i) = if (($i >= $s))
278+ then $a
279+ else updater($a, $l[$i])
280+
281+ func $f0_2 ($a,$i) = if (($i >= $s))
282+ then $a
283+ else throw("List size exceeds 6")
284+
285+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
286+ }
287+ makeString(r, "_")
288+ }
289+
290+
255291 func updateProportions (terrainCounts,landSizeIndex,sign) = {
256- let props = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
257- if ((size(props) != NUMRES))
258- then throw("Wrong proportions data")
259- else {
260- func updater (acc,i) = {
261- let result = (parseIntValue(props[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
262- if ((0 > result))
263- then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
264- else (acc :+ toString(result))
265- }
266-
267- let r = {
268- let $l = [0, 1, 2, 3, 4, 5]
269- let $s = size($l)
270- let $acc0 = nil
271- func $f0_1 ($a,$i) = if (($i >= $s))
272- then $a
273- else updater($a, $l[$i])
274-
275- func $f0_2 ($a,$i) = if (($i >= $s))
276- then $a
277- else throw("List size exceeds 6")
278-
279- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
280- }
281- makeString(r, "_")
282- }
292+ let propList = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
293+ updateProportionsInternal(propList, terrainCounts, landSizeIndex, sign)
283294 }
284295
285296
286297 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)]
287298
288299
289300 func numPiecesBySize (landSize) = match landSize {
290301 case _ =>
291302 if (("S" == $match0))
292303 then 25
293304 else if (("M" == $match0))
294305 then 100
295306 else if (("L" == $match0))
296307 then 225
297308 else if (("XL" == $match0))
298309 then 400
299310 else if (("XXL" == $match0))
300311 then 625
301312 else throw("Unknown land size")
302313 }
303314
304315
305316 func subOneInList (aList,idx,amount) = {
306317 func subber (acc,i) = (acc :+ (if ((i == idx))
307318 then toString((parseIntValue(aList[i]) - amount))
308319 else aList[i]))
309320
310321 let r = {
311322 let $l = [0, 1, 2, 3, 4, 5]
312323 let $s = size($l)
313324 let $acc0 = nil
314325 func $f0_1 ($a,$i) = if (($i >= $s))
315326 then $a
316327 else subber($a, $l[$i])
317328
318329 func $f0_2 ($a,$i) = if (($i >= $s))
319330 then $a
320331 else throw("List size exceeds 6")
321332
322333 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
323334 }
324335 makeString(r, "_")
325336 }
326337
327338
328339 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
329340 func adder (acc,i) = {
330341 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
331342 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
332343 }
333344
334345 let r = {
335346 let $l = [0, 1, 2, 3, 4, 5]
336347 let $s = size($l)
337348 let $acc0 = nil
338349 func $f0_1 ($a,$i) = if (($i >= $s))
339350 then $a
340351 else adder($a, $l[$i])
341352
342353 func $f0_2 ($a,$i) = if (($i >= $s))
343354 then $a
344355 else throw("List size exceeds 6")
345356
346357 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
347358 }
348359 makeString(r, "_")
349360 }
350361
351362
352363 func abs (x) = if ((x >= toBigInt(0)))
353364 then x
354365 else -(x)
355366
356367
357368 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]]
358369
359370 func genChar (n,freqs) = {
360371 let rem = toInt((n % TWENTYX))
361372 let letter = if ((freqs[0] > rem))
362373 then "A"
363374 else if ((freqs[1] > rem))
364375 then "B"
365376 else if ((freqs[2] > rem))
366377 then "C"
367378 else if ((freqs[3] > rem))
368379 then "D"
369380 else if ((freqs[4] > rem))
370381 then "E"
371382 else "F"
372383 letter
373384 }
374385
375386
387+func genTerrains (seed,continentIdx) = {
388+ let f = freq[continentIdx]
389+ 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))
390+
391+ let t = {
392+ let $l = [1, 2, 3, 4, 5]
393+ let $s = size($l)
394+ let $acc0 = $Tuple2("", (seed / FIVEX))
395+ func $f0_1 ($a,$i) = if (($i >= $s))
396+ then $a
397+ else terrainGenerator($a, $l[$i])
398+
399+ func $f0_2 ($a,$i) = if (($i >= $s))
400+ then $a
401+ else throw("List size exceeds 5")
402+
403+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
404+ }
405+ t._1
406+ }
407+
408+
376409 func getBackpack (bpKey) = {
377410 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
378411 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
379412 then p[bpIdxRes]
380413 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
381414 then p[bpIdxMat]
382415 else "0_0_0_0_0_0", p[bpIdxProd]]
383416 }
384417
385418
386419 func expeditionCommon (shouldUseMat,caller,txId,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
387420 then throw("signature does not match")
388421 else {
389422 let parts = split(toUtf8String(message), ";")
390423 let hp = split(split(parts[0], "|")[0], "_")
391424 let curHP = parseIntValue(hp[0])
392425 let newHP = parseIntValue(hp[1])
393426 let locAndTime = split(parts[1], ":")
394427 let targetLocation = split(locAndTime[0], "_")
395428 if ((targetLocation[1] != "E"))
396429 then throw("expedition target location type should be E")
397430 else {
398431 let time = parseIntValue(locAndTime[1])
399432 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
400433 then true
401434 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
402435 then throw("signature outdated")
403436 else {
404437 let userAddr = toString(caller)
405438 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
406439 let keyHealth = keyDuckHealth(duckAssetId)
407440 let oldFromState = valueOrElse(getInteger(keyHealth), 100)
408441 if ((oldFromState != curHP))
409442 then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
410443 else if ((0 >= curHP))
411444 then throw("You can't fly with zero health")
412445 else if ((0 >= newHP))
413446 then $Tuple2(((if (!(shouldUseMat))
414447 then [ScriptTransfer(caller, EXPUSDN, usdnAssetId)]
415448 else nil) :+ IntegerEntry(keyHealth, 0)), "")
416449 else {
417450 let bpKey = keyBackpackByDuck(duckAssetId)
418451 let currentPack = getBackpack(bpKey)
419452 let mList = split(currentPack[bpIdxMat], "_")
420453 let newMat = makeString(subtractMaterials(shouldUseMat, mList, EXPMATERIALS), "_")
421454 let bigNum = abs(toBigInt(txId))
422455 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), 501)
423456 let landNum = toString(freeNum)
424457 let continentIdx = toInt((bigNum % FIVEX))
425- let f = freq[continentIdx]
426- 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))
427-
428- let t = {
429- let $l = [1, 2, 3, 4, 5]
430- let $s = size($l)
431- let $acc0 = $Tuple2("", (bigNum / FIVEX))
432- func $f0_1 ($a,$i) = if (($i >= $s))
433- then $a
434- else terrainGenerator($a, $l[$i])
435-
436- func $f0_2 ($a,$i) = if (($i >= $s))
437- then $a
438- else throw("List size exceeds 5")
439-
440- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
441- }
458+ let terrains = genTerrains(bigNum, continentIdx)
442459 let continent = continents[continentIdx]
443- let issue = Issue(keyNftName(landNum, "S"), makeString([landNum, "S", t._1, continent], "_"), 1, 0, false)
460+ let issue = Issue(keyNftName(landNum, "S"), makeString([landNum, "S", terrains, continent], "_"), 1, 0, false)
444461 let assetId = calculateAssetId(issue)
445462 let id = toBase58String(assetId)
446463 $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), StringEntry(keyDuckLocation(duckAssetId), makeString([continent, "L", id], "_")), IntegerEntry(keyHealth, newHP), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))], id)
447464 }
448465 }
449466 }
450467 }
451468
452469
453-func applyBonuses (landAssetId) = {
470+func applyBonuses (landAssetId,pieces) = {
454471 let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
455- let presaleBonus = if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
456- then 3
457- else 0
458- ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, infraLevel, 4)) + fraction(DAILYRESBYPIECE, presaleBonus, 20))
472+ let artPieces = valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
473+ then pieces
474+ else 0)
475+ ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, infraLevel, 4)) + fraction(DAILYRESBYPIECE, (artPieces * 3), (pieces * 20)))
459476 }
460477
461478
462479 func checkClaimConditions (addr) = {
463480 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
464481 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
465482 let loc = split(value(curLocation), "_")
466483 if ((loc[locIdxType] != "L"))
467484 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
468485 else {
469486 let landAssetId = loc[locIdxId]
470487 let asset = value(assetInfo(fromBase58String(landAssetId)))
471488 let timeKey = keyStakedTimeByAssetId(landAssetId)
472- let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
489+ let savedTime = valueOrErrorMessage(getInteger(timeKey), (("Your duck is on " + asset.name) + ", which is not staked"))
473490 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
474491 if ((owner != addr))
475492 then throw((LANDPREFIX + " is not yours"))
476493 else {
477494 let d = split(asset.description, "_")
478495 $Tuple4(duckAssetId, landAssetId, d, savedTime)
479496 }
480497 }
481498 }
482499
483500
484501 func claimResInternal (addr,amount) = {
485502 let c = checkClaimConditions(addr)
486503 let landSize = c._3[recLandSize]
487504 let terrainCounts = countTerrains(c._3[recTerrains])
488505 let deltaTime = (lastBlock.timestamp - c._4)
489506 if ((0 > deltaTime))
490507 then throw(((("Saved timestamp is in future, saved = " + toString(c._4)) + ", current = ") + toString(lastBlock.timestamp)))
491508 else {
492509 let pieces = numPiecesBySize(landSize)
493- let dailyProductionByPiece = applyBonuses(c._2)
510+ let dailyProductionByPiece = applyBonuses(c._2, pieces)
494511 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
495512 if ((amount > availRes))
496513 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
497514 else {
498515 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
499516 let newTimestamp = (lastBlock.timestamp - newDeltaTime)
500517 let bpKey = keyBackpackByDuck(c._1)
501518 let currentPack = getBackpack(bpKey)
502519 let currentRes = split(currentPack[bpIdxRes], "_")
503520 let bpRes = addRes(currentRes, terrainCounts, (deltaTime - newDeltaTime), (pieces / 25), dailyProductionByPiece)
504521 $Tuple3([IntegerEntry(keyStakedTimeByAssetId(c._2), newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr), newTimestamp)], bpKey, [currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]])
505522 }
506523 }
507524 }
508525
509526
510527 func claimAll (addr,landAssetId,pieces) = {
511528 let timeKey = keyStakedTimeByAssetId(landAssetId)
512529 let savedTime = value(getInteger(timeKey))
513- let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId), DAYMILLIS) * pieces)
530+ let availRes = (fraction((lastBlock.timestamp - savedTime), applyBonuses(landAssetId, pieces), DAYMILLIS) * pieces)
514531 claimResInternal(addr, availRes)
515532 }
516533
517534
518535 func upInfraCommon (shouldUseMat,caller,paymentAmount) = {
519536 let addr = toString(caller)
520537 let c = checkClaimConditions(addr)
521538 let pieces = numPiecesBySize(c._3[recLandSize])
522539 let infraKey = keyInfraLevelByAssetId(c._2)
523540 let curLevel = valueOrElse(getInteger(infraKey), 0)
524541 if ((curLevel >= 3))
525542 then throw("Currently max infrastructure level = 3")
526543 else {
527544 let newLevel = (curLevel + 1)
528545 let cost = fraction(InfraUpgradeCostSUsdn, (pieces * newLevel), 25)
529546 if (if (!(shouldUseMat))
530547 then (paymentAmount != cost)
531548 else false)
532549 then throw(("Payment attached should be " + toString(cost)))
533550 else {
534551 let bpKey = keyBackpackByDuck(c._1)
535552 let currentPack = getBackpack(bpKey)
536553 let mList = split(currentPack[bpIdxMat], "_")
537554 let newMat = makeString(subtractMaterials(shouldUseMat, mList, fraction(InfraUpgradeCostS, (pieces * newLevel), 25)), "_")
538555 let claimResult = claimAll(addr, c._2, pieces)
539556 $Tuple2(([IntegerEntry(infraKey, newLevel), IntegerEntry(keyInfraLevelByAssetIdAndOwner(c._2, addr), newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], claimResult._3[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))] ++ claimResult._1), newLevel)
540557 }
541558 }
542559 }
543560
544561
545562 func activatePresaleArt (addr) = {
546563 let c = checkClaimConditions(addr)
547- let activationKey = keyPresaleArtActivatedByAssetId(c._2)
564+ let landAssetId = c._2
565+ let activationKey = keyPresaleArtActivatedByAssetId(landAssetId)
548566 if (valueOrElse(getBoolean(activationKey), false))
549567 then throw("Presale artifact is already activated")
550568 else if ((parseIntValue(c._3[recLandNum]) > 500))
551- then throw((((LANDPREFIX + " ") + c._2) + " is not eligible for presale artifact"))
569+ then throw((((LANDPREFIX + " ") + landAssetId) + " is not eligible for presale artifact"))
552570 else {
553571 let pieces = numPiecesBySize(c._3[recLandSize])
554- let claimResult = claimAll(addr, c._2, pieces)
555- (((claimResult._1 :+ BooleanEntry(keyPresaleArtActivatedByAssetId(c._2), true)) :+ BooleanEntry(keyPresaleArtActivatedByAssetIdAndOwner(c._2, addr), true)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":")))
572+ let claimResult = claimAll(addr, landAssetId, pieces)
573+ (((((claimResult._1 :+ BooleanEntry(activationKey, true)) :+ BooleanEntry(keyPresaleArtActivatedByAssetIdAndOwner(landAssetId, addr), true)) :+ IntegerEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId), pieces)) :+ IntegerEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, addr), pieces)) :+ StringEntry(claimResult._2, makeString(claimResult._3, ":")))
556574 }
575+ }
576+
577+
578+func mergeInternal (newLandSize,newLevel,formula,addr,landAssetIds,txId,needMat) = {
579+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
580+ func checkMerge (acc,landAssetId) = {
581+ let asset = value(assetInfo(fromBase58String(landAssetId)))
582+ let timeKey = keyStakedTimeByAssetId(landAssetId)
583+ let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
584+ let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
585+ if ((owner != addr))
586+ then throw((LANDPREFIX + " is not yours"))
587+ else {
588+ let d = split(asset.description, "_")
589+ let continent = d[recContinent]
590+ if (if ((acc._3 != ""))
591+ then (acc._3 != continent)
592+ else false)
593+ then throw("Lands should be on the same continent to merge")
594+ else {
595+ let landSize = d[recLandSize]
596+ let sizesIn = acc._1
597+ let i = valueOrErrorMessage(indexOf(sizesIn, landSize), "You haven't passed all the lands needed")
598+ let sizesOut = (take(sizesIn, i) + drop(sizesIn, (i + 1)))
599+ let pieces = numPiecesBySize(landSize)
600+ let arts = (acc._2 + valueOrElse(getInteger(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId)), if (valueOrElse(getBoolean(keyPresaleArtActivatedByAssetId(landAssetId)), false))
601+ then pieces
602+ else 0))
603+ let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
604+ let reqLevel = match landSize {
605+ case _ =>
606+ if (("S" == $match0))
607+ then 3
608+ else if (("M" == $match0))
609+ then 4
610+ else if (("L" == $match0))
611+ then 5
612+ else if (("XL" == $match0))
613+ then 6
614+ else throw("Only S, M, L, XL can merge")
615+ }
616+ if ((infraLevel != reqLevel))
617+ then throw("All lands should be maxed to merge")
618+ else {
619+ let landNum = d[recLandNum]
620+ let terrainCounts = countTerrains(d[recTerrains])
621+ let deltaTime = (lastBlock.timestamp - savedTime)
622+ if ((0 > deltaTime))
623+ then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
624+ else {
625+ let dailyProductionByPiece = applyBonuses(landAssetId, pieces)
626+ let bpRes = addRes(split(acc._4, "_"), terrainCounts, deltaTime, (pieces / 25), dailyProductionByPiece)
627+ let props = updateProportionsInternal(split(acc._6, "_"), terrainCounts, (pieces / 25), -1)
628+ $Tuple6(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(keyPresaleArtActivatedByAssetId(landAssetId))) :+ DeleteEntry(keyPresaleArtActivatedByAssetIdAndOwner(landAssetId, addr))) :+ DeleteEntry(keyLandArtStatusByTypeAndAssetId(ARTPRESALE, landAssetId))) :+ DeleteEntry(keyLandArtStatusByTypeAssetIdAndOwner(ARTPRESALE, landAssetId, addr))) :+ DeleteEntry(keyLandNumToOwner(landNum))) :+ Burn(fromBase58String(landAssetId), 1)), props)
629+ }
630+ }
631+ }
632+ }
633+ }
634+
635+ let bpKey = keyBackpackByDuck(duckAssetId)
636+ let currentPack = getBackpack(bpKey)
637+ let propStr = valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0")
638+ let r = {
639+ let $l = landAssetIds
640+ let $s = size($l)
641+ let $acc0 = $Tuple6(formula, 0, "", currentPack[bpIdxRes], nil, propStr)
642+ func $f0_1 ($a,$i) = if (($i >= $s))
643+ then $a
644+ else checkMerge($a, $l[$i])
645+
646+ func $f0_2 ($a,$i) = if (($i >= $s))
647+ then $a
648+ else throw("List size exceeds 4")
649+
650+ $f0_2($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4)
651+ }
652+ let continent = r._3
653+ let continentIdx = valueOrErrorMessage(indexOf(continents, continent), ("Unknown continent: " + continent))
654+ let terrains = genTerrains(abs(toBigInt(txId)), continentIdx)
655+ let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), 501)
656+ let newLandNum = toString(freeNum)
657+ let issue = Issue(keyNftName(newLandNum, newLandSize), makeString([newLandNum, newLandSize, terrains, continent], "_"), 1, 0, false)
658+ let assetId = calculateAssetId(issue)
659+ let newLandAssetId = toBase58String(assetId)
660+ let newMat = makeString(subtractMaterials((needMat > 0), split(currentPack[bpIdxMat], "_"), needMat), "_")
661+ $Tuple2((((((((((((((r._5 :+ 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)
662+ }
663+
664+
665+func s2m (addr,landAssetIds,txId) = mergeInternal("M", 3, "SSSS", addr, landAssetIds, txId, 0)
666+
667+
668+func m2l (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
669+ let cost = (InfraUpgradeCostSUsdn * 4)
670+ if (if (!(shouldUseMat))
671+ then (paymentAmount != cost)
672+ else false)
673+ then throw(("Payment attached should be " + toString(cost)))
674+ else mergeInternal("L", 4, "SMM", addr, landAssetIds, txId, (InfraUpgradeCostS * 4))
675+ }
676+
677+
678+func l2xl (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
679+ let cost = (InfraUpgradeCostSUsdn * 47)
680+ if (if (!(shouldUseMat))
681+ then (paymentAmount != cost)
682+ else false)
683+ then throw(("Payment attached should be " + toString(cost)))
684+ else mergeInternal("XL", 5, "SSSML", addr, landAssetIds, txId, (InfraUpgradeCostS * 47))
685+ }
686+
687+
688+func xl2xxl (addr,landAssetIds,txId,shouldUseMat,paymentAmount) = {
689+ let cost = (InfraUpgradeCostSUsdn * 54)
690+ if (if (!(shouldUseMat))
691+ then (paymentAmount != cost)
692+ else false)
693+ then throw(("Payment attached should be " + toString(cost)))
694+ else mergeInternal("XXL", 6, "LXL", addr, landAssetIds, txId, (InfraUpgradeCostS * 54))
695+ }
696+
697+
698+func mergeCommon (shouldUseMat,addr,paymentAmount,landAssetIds,txId) = {
699+ let mergeResult = match size(landAssetIds) {
700+ case _ =>
701+ if ((4 == $match0))
702+ then s2m(addr, landAssetIds, txId)
703+ else if ((3 == $match0))
704+ then m2l(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
705+ else if ((5 == $match0))
706+ then l2xl(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
707+ else if ((2 == $match0))
708+ then xl2xxl(addr, landAssetIds, txId, shouldUseMat, paymentAmount)
709+ else throw("Unknown merge")
710+ }
711+ mergeResult
557712 }
558713
559714
560715 @Callable(i)
561716 func stakeLand () = {
562717 let pmt = value(i.payments[0])
563718 let assetId = value(pmt.assetId)
564719 let address = toString(i.caller)
565720 if ((pmt.amount != 1))
566721 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
567722 else {
568723 let asset = value(assetInfo(assetId))
569724 if ((asset.issuer != this))
570725 then throw("Unknown issuer of token")
571726 else if (!(contains(asset.name, LANDPREFIX)))
572727 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
573728 else {
574729 let landNumSize = drop(asset.name, 4)
575730 let landNum = if (contains(landNumSize, "XXL"))
576731 then dropRight(landNumSize, 3)
577732 else if (contains(landNumSize, "XL"))
578733 then dropRight(landNumSize, 2)
579734 else dropRight(landNumSize, 1)
580735 let landNumInt = valueOrErrorMessage(parseInt(landNum), ("Cannot parse land number from " + asset.name))
581736 let landAssetId = toBase58String(assetId)
582737 let timeKey = keyStakedTimeByAssetId(landAssetId)
583738 if (isDefined(getInteger(timeKey)))
584739 then throw((("NFT " + asset.name) + " is already staked"))
585740 else {
586741 let d = split(asset.description, "_")
587742 let terrainCounts = countTerrains(d[recTerrains])
588743 let props = updateProportions(terrainCounts, (numPiecesBySize(d[recLandSize]) / 25), 1)
589744 [IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), StringEntry(keyResProportions(), props)]
590745 }
591746 }
592747 }
593748 }
594749
595750
596751
597752 @Callable(i)
598753 func unstakeLand (landAssetIdStr) = if ((size(i.payments) != 0))
599754 then throw("unstake doesn't require any payments")
600755 else {
601756 let addr = toString(i.caller)
602757 let c = checkClaimConditions(addr)
603758 let terrainCounts = countTerrains(c._3[recTerrains])
604759 let pieces = numPiecesBySize(c._3[recLandSize])
605760 let props = updateProportions(terrainCounts, (pieces / 25), -1)
606761 let claimResult = claimAll(addr, c._2, pieces)
607762 [ScriptTransfer(i.caller, 1, fromBase58String(c._2)), DeleteEntry(keyStakedTimeByAssetId(c._2)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, c._2, addr)), StringEntry(keyResProportions(), props), StringEntry(claimResult._2, makeString(claimResult._3, ":"))]
608763 }
609764
610765
611766
612767 @Callable(i)
613768 func stakeDuck () = {
614769 let pmt = value(i.payments[0])
615770 let assetId = value(pmt.assetId)
616771 let address = toString(i.caller)
617772 if ((pmt.amount != 1))
618773 then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
619774 else {
620775 let asset = value(assetInfo(assetId))
621776 if (if ((asset.issuer != incubatorAddr))
622777 then (asset.issuer != breederAddr)
623778 else false)
624779 then throw((("Unknown issuer of " + DUCKPREFIX) + " token"))
625780 else if (!(contains(asset.name, DUCKPREFIX)))
626781 then throw((("Only NFT " + DUCKPREFIX) + " tokens are accepted"))
627782 else {
628783 let assetIdStr = toBase58String(assetId)
629784 let timeKey = keyStakedTimeByAssetId(assetIdStr)
630785 if (isDefined(getInteger(timeKey)))
631786 then throw((("NFT " + asset.name) + " is already staked"))
632787 else if (isDefined(getString(keyStakedDuckByOwner(address))))
633788 then throw(("You already staked one duck: " + asset.name))
634789 else {
635790 let locKey = keyDuckLocation(assetIdStr)
636791 let location = getString(locKey)
637792 let keyHealth = keyDuckHealth(assetIdStr)
638793 let health = getInteger(keyHealth)
639794 let bpKey = keyBackpackByDuck(assetIdStr)
640795 let backpack = getString(bpKey)
641796 ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
642797 then nil
643798 else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(health))
644799 then nil
645800 else ([IntegerEntry(keyHealth, 100)] ++ (if (isDefined(backpack))
646801 then nil
647802 else [StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")]))))))
648803 }
649804 }
650805 }
651806 }
652807
653808
654809
655810 @Callable(i)
656811 func unstakeDuck (assetIdStr) = if ((size(i.payments) != 0))
657812 then throw("unstake doesn't require any payments")
658813 else {
659814 let assetId = fromBase58String(assetIdStr)
660815 let address = toString(i.caller)
661816 let asset = value(assetInfo(assetId))
662817 if (if ((asset.issuer != incubatorAddr))
663818 then (asset.issuer != breederAddr)
664819 else false)
665820 then throw((("Unknown issuer of " + DUCKPREFIX) + " token"))
666821 else if (!(contains(asset.name, DUCKPREFIX)))
667822 then throw((("Only NFT " + DUCKPREFIX) + " tokens can be unstaked"))
668823 else {
669824 let timeKey = keyStakedTimeByAssetId(toBase58String(assetId))
670825 if (!(isDefined(timeKey)))
671826 then throw((("NFT " + asset.name) + " is not staked"))
672827 else if (!(isDefined(keyStakedDuckByOwner(address))))
673828 then throw((("The duck " + asset.name) + " is not staked"))
674829 else {
675830 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(toBase58String(assetId))), (("NFT " + asset.name) + " is orphaned"))
676831 if ((owner != address))
677832 then throw("Staked NFT is not yours")
678833 else [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyDuckIdToOwner(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address))]
679834 }
680835 }
681836 }
682837
683838
684839
685840 @Callable(i)
686841 func claimRes (amount,landAssetIdStr) = if ((size(i.payments) != 0))
687842 then throw("claimRes doesn't require any payments")
688843 else {
689844 let addr = toString(i.originCaller)
690845 let result = claimResInternal(addr, amount)
691846 $Tuple2((result._1 :+ StringEntry(result._2, makeString(result._3, ":"))), result._3[bpIdxRes])
692847 }
693848
694849
695850
696851 @Callable(i)
697852 func flight (message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
698853 then throw("signature does not match")
699854 else if ((size(i.payments) != 0))
700855 then throw("flight doesn't require any payments")
701856 else {
702857 let parts = split(toUtf8String(message), ";")
703858 let hp = split(split(parts[0], "|")[0], "_")
704859 let curHP = parseIntValue(hp[0])
705860 let newHP = parseIntValue(hp[1])
706861 let newLocAndTime = split(parts[1], ":")
707862 let newLocation = newLocAndTime[0]
708863 let time = parseIntValue(newLocAndTime[1])
709864 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
710865 then true
711866 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
712867 then throw("signature outdated")
713868 else {
714869 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
715870 let keyHealth = keyDuckHealth(duckAssetId)
716871 let oldFromState = valueOrElse(getInteger(keyHealth), 100)
717872 if ((oldFromState != curHP))
718873 then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
719874 else if ((0 >= curHP))
720875 then throw("You can't fly with zero health")
721876 else {
722877 let locKey = keyDuckLocation(duckAssetId)
723878 let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
724879 if ((newLocation == curLocation))
725880 then throw("You can't fly to the same location")
726881 else $Tuple2([StringEntry(locKey, if ((newHP > 0))
727882 then newLocation
728883 else curLocation), IntegerEntry(keyHealth, newHP)], unit)
729884 }
730885 }
731886 }
732887
733888
734889
735890 @Callable(i)
736891 func setHealth (health,duckAssetId) = if (if ((0 > health))
737892 then true
738893 else (health > 100))
739894 then throw("HP should be within 0..100")
740895 else [IntegerEntry(keyDuckHealth(duckAssetId), health)]
741896
742897
743898
744899 @Callable(i)
745900 func heal (matType,amount) = if (if ((0 > matType))
746901 then true
747902 else (matType >= NUMRES))
748903 then throw(("Unknown material: " + toString(matType)))
749904 else if ((0 >= amount))
750905 then throw(("Amount should be positive! " + toString(amount)))
751906 else {
752907 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
753908 let keyHealth = keyDuckHealth(duckAssetId)
754909 let oldHealth = valueOrElse(getInteger(keyHealth), 100)
755910 if ((oldHealth >= 100))
756911 then throw("HP should be < 100 to heal")
757912 else {
758913 let bpKey = keyBackpackByDuck(duckAssetId)
759914 let currentPack = getBackpack(bpKey)
760915 let mList = split(currentPack[bpIdxMat], "_")
761916 let currentAmount = parseIntValue(mList[matType])
762917 let deltaHealth = min([(amount / HEALCOST), (100 - oldHealth)])
763918 let spendAmount = (deltaHealth * HEALCOST)
764919 if ((spendAmount > currentAmount))
765920 then throw(((((("You need " + toString(spendAmount)) + " of ") + matTypes[matType]) + " to heal, but you backpack contains ") + toString(currentAmount)))
766921 else {
767922 let newMat = subOneInList(mList, matType, spendAmount)
768923 [IntegerEntry(keyHealth, (oldHealth + deltaHealth)), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))]
769924 }
770925 }
771926 }
772927
773928
774929
775930 @Callable(i)
776931 func updateBackpack (duckAssetId,newPack) = if ((i.caller != economyAddr))
777932 then throw("permission denied")
778933 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack)], newPack)
779934
780935
781936
782937 @Callable(i)
783938 func expeditionBuy (message,sig) = if ((size(i.payments) != 1))
784939 then throw("Exactly one payment required")
785940 else {
786941 let pmt = value(i.payments[0])
787942 if ((pmt.assetId != usdnAssetId))
788943 then throw("Allowed USDN payment only!")
789944 else if ((pmt.amount != EXPUSDN))
790945 then throw(("Payment attached should be " + toString(EXPUSDN)))
791946 else {
792947 let result = expeditionCommon(false, i.caller, i.transactionId, message, sig)
793948 $Tuple2((result._1 :+ ScriptTransfer(economyAddr, pmt.amount, usdnAssetId)), result._2)
794949 }
795950 }
796951
797952
798953
799954 @Callable(i)
800955 func expedition (message,sig) = if ((size(i.payments) != 0))
801956 then throw("expedition doesn't require any payments")
802957 else expeditionCommon(true, i.caller, i.transactionId, message, sig)
803958
804959
805960
806961 @Callable(i)
807962 func upgradeInfra (landAssetIdIgnored) = if ((size(i.payments) != 0))
808963 then throw("Infrastructure upgrade doesn't require any payments")
809964 else upInfraCommon(true, i.caller, 0)
810965
811966
812967
813968 @Callable(i)
814969 func upgradeInfraUsdn (landAssetIdIgnored) = if ((size(i.payments) != 1))
815970 then throw("Exactly one payment required")
816971 else {
817972 let pmt = value(i.payments[0])
818973 if ((pmt.assetId != usdnAssetId))
819974 then throw("Allowed USDN payment only!")
820975 else {
821976 let result = upInfraCommon(false, i.caller, pmt.amount)
822977 $Tuple2((result._1 :+ ScriptTransfer(economyAddr, pmt.amount, usdnAssetId)), result._2)
823978 }
824979 }
825980
826981
827982
828983 @Callable(i)
829984 func activateArtifact (artName) = if ((size(i.payments) != 0))
830985 then throw("Artifact activation doesn't require any payments")
831986 else {
832987 let result = match artName {
833988 case _ =>
834989 if (("PRESALE" == $match0))
835990 then activatePresaleArt(toString(i.caller))
836991 else throw("Unknown artifact")
837992 }
838993 result
839994 }
840995
841996
997+
998+@Callable(i)
999+func mergeLands (landAssetIds) = if ((i.caller != this))
1000+ then throw("permission denied")
1001+ else if ((size(i.payments) != 0))
1002+ then throw("Lands merging doesn't require any payments")
1003+ else mergeCommon(true, toString(i.caller), 0, landAssetIds, i.transactionId)
1004+
1005+
1006+
1007+@Callable(i)
1008+func mergeLandsUsdn (landAssetIds) = if ((i.caller != this))
1009+ then throw("permission denied")
1010+ else if ((size(i.payments) != 1))
1011+ then throw("Exactly one payment required")
1012+ else {
1013+ let pmt = value(i.payments[0])
1014+ if ((pmt.assetId != usdnAssetId))
1015+ then throw("Allowed USDN payment only!")
1016+ else {
1017+ let result = mergeCommon(false, toString(i.caller), pmt.amount, landAssetIds, i.transactionId)
1018+ $Tuple2((result._1 :+ ScriptTransfer(economyAddr, pmt.amount, usdnAssetId)), result._2)
1019+ }
1020+ }
1021+
1022+

github/deemru/w8io/3ef1775 
116.29 ms