tx · G9cZG4s1GLBifyWweMPkziN9RE5V324pQQMCntsectAE

3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm:  -0.02500000 Waves

2023.01.03 00:53 [2387916] smart account 3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm > SELF 0.00000000 Waves

{ "type": 13, "id": "G9cZG4s1GLBifyWweMPkziN9RE5V324pQQMCntsectAE", "fee": 2500000, "feeAssetId": null, "timestamp": 1672696453840, "version": 2, "chainId": 84, "sender": "3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm", "senderPublicKey": "EVooykMNV691Venwp1dHUTBd7KWequzUcda57Wd3LQEX", "proofs": [ "5FKihqTfaeewXBaWqUhEouDAyaJGV6ir1eiWtaJy7BMnPaVe9u1PhVB54Mih37aFsNKc2ZV1WnP1N2v5Do8fFuFT" ], "script": "base64:BgJECAISABIDCgEIEgASAwoBCBIECgIBCBIECgICAhIECgIBCBIECgIBARIECgIICBIECgICAhIECgICAhIDCgEIEgMKAQhHAAVjaGFpbgkAsAkBCQDJAQIJAMoBAggFBHRoaXMFYnl0ZXMAAQABAAt1c2RuQXNzZXRJZAQHJG1hdGNoMAUFY2hhaW4DCQAAAgIBVwUHJG1hdGNoMAEgtiYpwwT1zlORpA5LdSQvZIxRsfrfr1QpvUjSHSqyqtEDCQAAAgIBVAUHJG1hdGNoMAEg93bq9/eDymXbbhPuAjvPWCmVqcHRjfJL2mzYHWKAyN4JAAIBAg1Vbmtub3duIGNoYWluAA1pbmN1YmF0b3JBZGRyBAckbWF0Y2gwBQVjaGFpbgMJAAACAgFXBQckbWF0Y2gwCQERQGV4dHJOYXRpdmUoMTA2MikBAiMzUEVrdFZ1eDJSaGNoU042M0RzRG80YjRtejRRcXpLU2VEdgMJAAACAgFUBQckbWF0Y2gwBQR0aGlzCQACAQINVW5rbm93biBjaGFpbgALYnJlZWRlckFkZHIEByRtYXRjaDAFBWNoYWluAwkAAAICAVcFByRtYXRjaDAJARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQRFZ1VTQ1SDdFaDVkbXROYm5STlJTdEd3VUxBN05ZNkhiAwkAAAICAVQFByRtYXRjaDAFBHRoaXMJAAIBAg1Vbmtub3duIGNoYWluAAtlY29ub215QWRkcgQHJG1hdGNoMAUFY2hhaW4DCQAAAgIBVwUHJG1hdGNoMAkBEUBleHRyTmF0aXZlKDEwNjIpAQIjM1Ayc2sxS25jU3hSYVpzOGI0Q1dHUHcyamt2dmF2NzR1NEQDCQAAAgIBVAUHJG1hdGNoMAkBEUBleHRyTmF0aXZlKDEwNjIpAQIjM044eTR3eFgzSkM0VGRyQ0pCWFgxNlNqV2Y2WDI1NmhyZXAJAAIBAg1Vbmtub3duIGNoYWluAANwdWIBIE9T4ho/VKjWnVJOEx1GJ1W9s1PzLHvJVFSw/0PBtBQoAAhIRUFMQ09TVACQTgAKTEFORFBSRUZJWAIETEFORAAKRFVDS1BSRUZJWAIERFVDSwAPREVGQVVMVExPQ0FUSU9OAg9BZnJpY2FfRl9BZnJpY2EABk5VTVJFUwAGAA9EQUlMWVJFU0JZUElFQ0UAgPjSAQAJREFZTUlMTElTAIC4mSkAEUZJVkVNSU5VVEVTTUlMTElTAOCnEgAQUkVTT1VSQ0VQUklDRU1JTgDV1gkAEUluZnJhVXBncmFkZUNvc3RTBAckbWF0Y2gwBQVjaGFpbgMJAAACAgFXBQckbWF0Y2gwANHCwr5GAwkAAAICAVQFByRtYXRjaDAA0OmcWgkAAgECDVVua25vd24gY2hhaW4AFUluZnJhVXBncmFkZUNvc3RTVXNkbgQHJG1hdGNoMAUFY2hhaW4DCQAAAgIBVwUHJG1hdGNoMACAnJw5AwkAAAICAVQFByRtYXRjaDAAgJ9JCQACAQINVW5rbm93biBjaGFpbgAMRVhQTUFURVJJQUxTBAckbWF0Y2gwBQVjaGFpbgMJAAACAgFXBQckbWF0Y2gwAMuA1bPLBAMJAAACAgFUBQckbWF0Y2gwAPGa8O8FCQACAQINVW5rbm93biBjaGFpbgAHRVhQVVNETgQHJG1hdGNoMAUFY2hhaW4DCQAAAgIBVwUHJG1hdGNoMACAlOvcAwMJAAACAgFUBQckbWF0Y2gwAICt4gQJAAIBAg1Vbmtub3duIGNoYWluAB1QcmVzYWxlQXJ0aWZhY3RBY3RpdmF0aW9uVGltZQQHJG1hdGNoMAUFY2hhaW4DCQAAAgIBVwUHJG1hdGNoMACAmLX12DADCQAAAgIBVAUHJG1hdGNoMACAuM/Q1zAJAAIBAg1Vbmtub3duIGNoYWluAAVNVUxUNgDAhD0ABUZJVkVYCQC2AgEABQAHVFdFTlRZWAkAtgIBABQACFRXRU5UWTJYCQC2AgEJAGgCABQAFAAIVFdFTlRZM1gJALYCAQkAaAIJAGgCABQAFAAUAAhUV0VOVFk0WAkAtgIBCQBoAgkAaAIJAGgCABQAFAAUABQACFRXRU5UWTVYCQC2AgEJAGgCCQBoAgkAaAIJAGgCABQAFAAUABQAFAAIbWF0VHlwZXMJAMwIAgIERnVlbAkAzAgCAgVNZXRhbAkAzAgCAgVQbGFuawkAzAgCAgVHbGFzcwkAzAgCAgdQbGFzdGljCQDMCAICB1Byb3RlaW4FA25pbAAKY29udGluZW50cwkAzAgCAgRBc2lhCQDMCAICBkV1cm9wZQkAzAgCAghBbWVyaWNhcwkAzAgCAgdPY2VhbmlhCQDMCAICBkFmcmljYQUDbmlsARJrZXlOZXh0RnJlZUxhbmROdW0AAgtuZXh0TGFuZE51bQEQa2V5TGFuZFRvQXNzZXRJZAEHbGFuZE51bQkArAICAgxsYW5kVG9Bc3NldF8FB2xhbmROdW0BCmtleU5mdE5hbWUCB2xhbmROdW0IbGFuZFNpemUJAKwCAgkArAICBQpMQU5EUFJFRklYBQdsYW5kTnVtBQhsYW5kU2l6ZQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQdhc3NldElkCQCsAgICCW5mdE93bmVyXwUHYXNzZXRJZAEQa2V5RHVja0lkVG9Pd25lcgEHYXNzZXRJZAkArAICAgpkdWNrT3duZXJfBQdhc3NldElkARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQdhc3NldElkCQCsAgICC3N0YWtlZFRpbWVfBQdhc3NldElkARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQdhc3NldElkCQCsAgICC2luZnJhTGV2ZWxfBQdhc3NldElkAR9rZXlwcmVzYWxlQXJ0QWN0aXZhdGVkQnlBc3NldElkAQdhc3NldElkCQCsAgICFHByZXNhbGVBcnRBY3RpdmF0ZWRfBQdhc3NldElkARRrZXlTdGFrZWREdWNrQnlPd25lcgEJb3duZXJBZGRyCQCsAgICEnN0YWtlZER1Y2tCeU93bmVyXwUJb3duZXJBZGRyASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwduZnRUeXBlB2Fzc2V0SWQJb3duZXJBZGRyCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIgc3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcl8FB25mdFR5cGUCAV8FB2Fzc2V0SWQCAV8FCW93bmVyQWRkcgERa2V5TGFuZE51bVRvT3duZXIBB2xhbmROdW0JAKwCAgIKbGFuZE93bmVyXwUHbGFuZE51bQERa2V5QmFja3BhY2tCeUR1Y2sBC2R1Y2tBc3NldElkCQCsAgICCWJhY2tQYWNrXwULZHVja0Fzc2V0SWQBD2tleUR1Y2tMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgINZHVja0xvY2F0aW9uXwULZHVja0Fzc2V0SWQBDWtleUR1Y2tIZWFsdGgBC2R1Y2tBc3NldElkCQCsAgICC2R1Y2tIZWFsdGhfBQtkdWNrQXNzZXRJZAERa2V5UmVzUHJvcG9ydGlvbnMAAhNyZXNUeXBlc1Byb3BvcnRpb25zAApyZWNMYW5kTnVtAAAAC3JlY0xhbmRTaXplAAEAC3JlY1RlcnJhaW5zAAIADHJlY0NvbnRpbmVudAADAA9sb2NJZHhDb250aW5lbnQAAAAKbG9jSWR4VHlwZQABAAhsb2NJZHhJZAACAApicElkeExldmVsAAAACGJwSWR4UmVzAAEACGJwSWR4TWF0AAIACWJwSWR4UHJvZAADAQhhc1N0cmluZwEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAFAXMJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBEmdldE5lZWRlZE1hdGVyaWFscwEFdG90YWwEBXByb3BzCQC1CQIJAQV2YWx1ZQEJAKIIAQkBEWtleVJlc1Byb3BvcnRpb25zAAIBXwMJAQIhPQIJAJADAQUFcHJvcHMFBk5VTVJFUwkAAgECFldyb25nIHByb3BvcnRpb25zIGRhdGEEAXIJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAAJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAEJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAIJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAMJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAQJAMwIAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBXByb3BzAAUFA25pbAQDc3VtCQBkAgkAZAIJAGQCCQBkAgkAZAIJAJEDAgUBcgAACQCRAwIFAXIAAQkAkQMCBQFyAAIJAJEDAgUBcgADCQCRAwIFAXIABAkAkQMCBQFyAAUDCQBnAgAABQNzdW0JAAIBAg9ObyBsYW5kcyBzdGFrZWQEBW5vcm02CQBrAwUFdG90YWwFBU1VTFQ2BQNzdW0KAQpub3JtYWxpemVyAgNhY2MEZWxlbQkAzQgCBQNhY2MJAGsDBQRlbGVtBQVub3JtNgUFTVVMVDYKAAIkbAUBcgoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEKbm9ybWFsaXplcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgERc3VidHJhY3RNYXRlcmlhbHMDDHNob3VsZFVzZU1hdANoYXMJdG90YWxOZWVkBARuZWVkCQESZ2V0TmVlZGVkTWF0ZXJpYWxzAQUJdG90YWxOZWVkCgEKc3VidHJhY3RvcgIDYWNjA2lkeAQGcmVzdWx0CQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2hhcwUDaWR4CQCRAwIFBG5lZWQFA2lkeAMJAGYCAAAFBnJlc3VsdAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhhOb3QgZW5vdWdoIG1hdGVyaWFsIGlkeD0JAKQDAQUDaWR4AgssIHlvdSBoYXZlIAkAkQMCBQNoYXMFA2lkeAILLCBidXQgbmVlZCAJAKQDAQkAkQMCBQRuZWVkBQNpZHgJAM0IAgUDYWNjCQCkAwEFBnJlc3VsdAMFDHNob3VsZFVzZU1hdAoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCnN1YnRyYWN0b3ICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYFA2hhcwERdXBkYXRlUHJvcG9ydGlvbnMDDXRlcnJhaW5Db3VudHMNbGFuZFNpemVJbmRleARzaWduBAVwcm9wcwkAtQkCCQELdmFsdWVPckVsc2UCCQCiCAEJARFrZXlSZXNQcm9wb3J0aW9ucwACCzBfMF8wXzBfMF8wAgFfAwkBAiE9AgkAkAMBBQVwcm9wcwUGTlVNUkVTCQACAQIWV3JvbmcgcHJvcG9ydGlvbnMgZGF0YQoBB3VwZGF0ZXICA2FjYwFpBAZyZXN1bHQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFcHJvcHMFAWkJAGgCCQBoAgUEc2lnbgkAkQMCBQ10ZXJyYWluQ291bnRzBQFpBQ1sYW5kU2l6ZUluZGV4AwkAZgIAAAUGcmVzdWx0CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhZQYW5pYyEgUGllY2VzIG9mIHR5cGU9CQCkAwEFAWkCBywgc2lnbj0JAKQDAQUEc2lnbgIULCAgdGVycmFpbkNvdW50c1tpXT0JAKQDAQkAkQMCBQ10ZXJyYWluQ291bnRzBQFpAhAsIGxhbmRTaXplSW5kZXg9CQCkAwEFDWxhbmRTaXplSW5kZXgJAM0IAgUDYWNjCQCkAwEFBnJlc3VsdAQBcgoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB3VwZGF0ZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJALkJAgUBcgIBXwENY291bnRUZXJyYWlucwEIdGVycmFpbnMJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBQQABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUIAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFDAAEJAMwIAgkAZQIJAJADAQkAtQkCBQh0ZXJyYWlucwIBRAABCQDMCAIJAGUCCQCQAwEJALUJAgUIdGVycmFpbnMCAUUAAQkAzAgCCQBlAgkAkAMBCQC1CQIFCHRlcnJhaW5zAgFGAAEFA25pbAEPbnVtUGllY2VzQnlTaXplAQhsYW5kU2l6ZQQHJG1hdGNoMAUIbGFuZFNpemUDCQAAAgIBUwUHJG1hdGNoMAAZAwkAAAICAU0FByRtYXRjaDAAZAMJAAACAgFMBQckbWF0Y2gwAOEBAwkAAAICAlhMBQckbWF0Y2gwAJADAwkAAAICA1hYTAUHJG1hdGNoMADxBAkAAgECEVVua25vd24gbGFuZCBzaXplAQxzdWJPbmVJbkxpc3QDBWFMaXN0A2lkeAZhbW91bnQKAQZzdWJiZXICA2FjYwFpCQDNCAIFA2FjYwMJAAACBQFpBQNpZHgJAKQDAQkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQVhTGlzdAUBaQUGYW1vdW50CQCRAwIFBWFMaXN0BQFpBAFyCgACJGwJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUFA25pbAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEGc3ViYmVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGCQC5CQIFAXICAV8BBmFkZFJlcwUKY3VycmVudFJlcw10ZXJyYWluQ291bnRzCWRlbHRhVGltZQ1sYW5kU2l6ZUluZGV4F2RhaWx5QnlQaWVjZVdpdGhCb251c2VzCgEFYWRkZXICA2FjYwFpBAlyZXNPZlR5cGUJAGgCCQBoAgkAawMFCWRlbHRhVGltZQUXZGFpbHlCeVBpZWNlV2l0aEJvbnVzZXMFCURBWU1JTExJUwkAkQMCBQ10ZXJyYWluQ291bnRzBQFpBQ1sYW5kU2l6ZUluZGV4CQDNCAIFA2FjYwkApAMBCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCmN1cnJlbnRSZXMFAWkFCXJlc09mVHlwZQQBcgoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBWFkZGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGCQC5CQIFAXICAV8BA2FicwEBeAMJAMACAgUBeAkAtgIBAAAFAXgJAL4CAQUBeAAEZnJlcQkAzAgCCQDMCAIAAQkAzAgCAAQJAMwIAgAJCQDMCAIACgkAzAgCAA8FA25pbAkAzAgCCQDMCAIABQkAzAgCAAgJAMwIAgANCQDMCAIADgkAzAgCAA8FA25pbAkAzAgCCQDMCAIABgkAzAgCAAkJAMwIAgAOCQDMCAIADwkAzAgCABAFA25pbAkAzAgCCQDMCAIABAkAzAgCAAcJAMwIAgAICQDMCAIADQkAzAgCABIFA25pbAkAzAgCCQDMCAIAAQkAzAgCAAYJAMwIAgAHCQDMCAIADwkAzAgCABMFA25pbAUDbmlsAQdnZW5DaGFyAgFuBWZyZXFzBANyZW0JAKADAQkAuwICBQFuBQdUV0VOVFlYBAZsZXR0ZXIDCQBmAgkAkQMCBQVmcmVxcwAABQNyZW0CAUEDCQBmAgkAkQMCBQVmcmVxcwABBQNyZW0CAUIDCQBmAgkAkQMCBQVmcmVxcwACBQNyZW0CAUMDCQBmAgkAkQMCBQVmcmVxcwADBQNyZW0CAUQDCQBmAgkAkQMCBQVmcmVxcwAEBQNyZW0CAUUCAUYFBmxldHRlcgELZ2V0QmFja3BhY2sBBWJwS2V5BAFwCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUFYnBLZXkCGjA6MF8wXzBfMF8wXzA6MF8wXzBfMF8wXzA6AgE6CQDMCAIJAKQDAQkBC3ZhbHVlT3JFbHNlAgkAtgkBCQCRAwIFAXAFCmJwSWR4TGV2ZWwAAAkAzAgCAwkAAAIJAJADAQkAtQkCCQCRAwIFAXAFCGJwSWR4UmVzAgFfBQZOVU1SRVMJAJEDAgUBcAUIYnBJZHhSZXMCCzBfMF8wXzBfMF8wCQDMCAIDCQAAAgkAkAMBCQC1CQIJAJEDAgUBcAUIYnBJZHhNYXQCAV8FBk5VTVJFUwkAkQMCBQFwBQhicElkeE1hdAILMF8wXzBfMF8wXzAJAMwIAgkAkQMCBQFwBQlicElkeFByb2QFA25pbAEQZXhwZWRpdGlvbkNvbW1vbgUMc2hvdWxkVXNlTWF0BmNhbGxlcgR0eElkB21lc3NhZ2UDc2lnAwkBASEBCQDEEwMFB21lc3NhZ2UFA3NpZwUDcHViCQACAQIYc2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoBAVwYXJ0cwkAtQkCCQCwCQEFB21lc3NhZ2UCATsEAmhwCQC1CQIJAJEDAgkAtQkCCQCRAwIFBXBhcnRzAAACAXwAAAIBXwQFY3VySFAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJocAAABAVuZXdIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAEECmxvY0FuZFRpbWUJALUJAgkAkQMCBQVwYXJ0cwABAgE6BA50YXJnZXRMb2NhdGlvbgkAtQkCCQCRAwIFCmxvY0FuZFRpbWUAAAIBXwMJAQIhPQIJAJEDAgUOdGFyZ2V0TG9jYXRpb24AAQIBRQkAAgECK2V4cGVkaXRpb24gdGFyZ2V0IGxvY2F0aW9uIHR5cGUgc2hvdWxkIGJlIEUEBHRpbWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpsb2NBbmRUaW1lAAEDAwkAZgIFBHRpbWUJAGQCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAURRklWRU1JTlVURVNNSUxMSVMGCQBmAgkAZQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwUEdGltZQkAAgECEnNpZ25hdHVyZSBvdXRkYXRlZAQIdXNlckFkZHIJAKUIAQUGY2FsbGVyBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFCHVzZXJBZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEDG9sZEZyb21TdGF0ZQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgAZAMJAQIhPQIFDG9sZEZyb21TdGF0ZQUFY3VySFAJAAIBCQCsAgIJAKwCAgkArAICAgpvbGRIZWFsdGg9CQCkAwEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQCLyBmcm9tIHN0YXRlIGRvZXMgbm90IG1hdGNoIG9uZSBmcm9tIGZsaWdodCBsb2c9CQCkAwEFBWN1ckhQAwkAZwIAAAUFY3VySFAJAAIBAh5Zb3UgY2FuJ3QgZmx5IHdpdGggemVybyBoZWFsdGgDCQBnAgAABQVuZXdIUAkAAgECK1lvdXIgZHVjayBoZWFsdGggaXMgemVybywgZXhwZWRpdGlvbiBmYWlsZWQEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAVtTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQGbmV3TWF0CQC5CQIJARFzdWJ0cmFjdE1hdGVyaWFscwMFDHNob3VsZFVzZU1hdAUFbUxpc3QFDEVYUE1BVEVSSUFMUwIBXwQGYmlnTnVtCQEDYWJzAQkAngMBBQR0eElkBAdmcmVlTnVtCQELdmFsdWVPckVsc2UCCQCfCAEJARJrZXlOZXh0RnJlZUxhbmROdW0AAPUDBAdsYW5kTnVtCQCkAwEFB2ZyZWVOdW0EDGNvbnRpbmVudElkeAkAoAMBCQC7AgIFBmJpZ051bQUFRklWRVgEAWYJAJEDAgUEZnJlcQUMY29udGluZW50SWR4CgEQdGVycmFpbkdlbmVyYXRvcgIDYWNjBGVsZW0JAJQKAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIIBQNhY2MCXzEJAQdnZW5DaGFyAggFA2FjYwJfMgUBZgkBB2dlbkNoYXICCQC6AgIIBQNhY2MCXzIFB1RXRU5UWVgFAWYJAQdnZW5DaGFyAgkAugICCAUDYWNjAl8yBQhUV0VOVFkyWAUBZgkBB2dlbkNoYXICCQC6AgIIBQNhY2MCXzIFCFRXRU5UWTNYBQFmCQEHZ2VuQ2hhcgIJALoCAggFA2FjYwJfMgUIVFdFTlRZNFgFAWYJALoCAggFA2FjYwJfMgUIVFdFTlRZNVgEAXQKAAIkbAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgICAAkAugICBQZiaWdOdW0FBUZJVkVYCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARB0ZXJyYWluR2VuZXJhdG9yAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQQJY29udGluZW50CQCRAwIFCmNvbnRpbmVudHMFDGNvbnRpbmVudElkeAQFaXNzdWUJAMIIBQkBCmtleU5mdE5hbWUCBQdsYW5kTnVtAgFTCQC5CQIJAMwIAgUHbGFuZE51bQkAzAgCAgFTCQDMCAIIBQF0Al8xCQDMCAIFCWNvbnRpbmVudAUDbmlsAgFfAAEAAAcEB2Fzc2V0SWQJALgIAQUFaXNzdWUEAmlkCQDYBAEFB2Fzc2V0SWQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmtleU5leHRGcmVlTGFuZE51bQAJAGQCBQdmcmVlTnVtAAEJAMwIAgUFaXNzdWUJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEGtleUxhbmRUb0Fzc2V0SWQBBQdsYW5kTnVtBQJpZAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQUCaWQFCHVzZXJBZGRyCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlMYW5kTnVtVG9Pd25lcgEFB2xhbmROdW0FCHVzZXJBZGRyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5SW5mcmFMZXZlbEJ5QXNzZXRJZAEFAmlkAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGY2FsbGVyAAEFB2Fzc2V0SWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkCQC5CQIJAMwIAgUJY29udGluZW50CQDMCAICAUwJAMwIAgUCaWQFA25pbAIBXwkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQVuZXdIUAkAzAgCCQELU3RyaW5nRW50cnkCBQVicEtleQkAuQkCCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCmJwSWR4TGV2ZWwJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMJAMwIAgUGbmV3TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6BQNuaWwFBHVuaXQBDGFwcGx5Qm9udXNlcwELbGFuZEFzc2V0SWQECmluZnJhTGV2ZWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAABAxwcmVzYWxlQm9udXMDCQELdmFsdWVPckVsc2UCCQCgCAEJAR9rZXlwcmVzYWxlQXJ0QWN0aXZhdGVkQnlBc3NldElkAQULbGFuZEFzc2V0SWQHAAMAAAkAZAIJAGQCBQ9EQUlMWVJFU0JZUElFQ0UJAGsDBQ9EQUlMWVJFU0JZUElFQ0UFCmluZnJhTGV2ZWwABAkAawMFD0RBSUxZUkVTQllQSUVDRQUMcHJlc2FsZUJvbnVzABQBCGNsYWltQWxsAgtsYW5kQXNzZXRJZAZwaWVjZXMEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQECXNhdmVkVGltZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFB3RpbWVLZXkJAKwCAgkArAICCQCsAgIFCkxBTkRQUkVGSVgCASAFC2xhbmRBc3NldElkAg4gaXMgbm90IHN0YWtlZAQJZGVsdGFUaW1lCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFCXNhdmVkVGltZQMJAGYCAAAFCWRlbHRhVGltZQkAAgEJAKwCAgkArAICCQCsAgICJlNhdmVkIHRpbWVzdGFtcCBpcyBpbiBmdXR1cmUsIHNhdmVkID0gCQCkAwEFCXNhdmVkVGltZQIMLCBjdXJyZW50ID0gCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBBZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQEMYXBwbHlCb251c2VzAQULbGFuZEFzc2V0SWQECGF2YWlsUmVzCQBoAgkAawMFCWRlbHRhVGltZQUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQUJREFZTUlMTElTBQZwaWVjZXMJAQhhc1N0cmluZwEJAPwHBAUEdGhpcwIIY2xhaW1SZXMJAMwIAgUIYXZhaWxSZXMJAMwIAgULbGFuZEFzc2V0SWQFA25pbAUDbmlsAQ11cEluZnJhQ29tbW9uAwxzaG91bGRVc2VNYXQGY2FsbGVyC2xhbmRBc3NldElkBARhZGRyCQClCAEFBmNhbGxlcgQIaW5mcmFLZXkJARZrZXlJbmZyYUxldmVsQnlBc3NldElkAQULbGFuZEFzc2V0SWQECGN1ckxldmVsCQELdmFsdWVPckVsc2UCCQCfCAEFCGluZnJhS2V5AAADCQBnAgUIY3VyTGV2ZWwAAwkAAgECJkN1cnJlbnRseSBtYXggaW5mcmFzdHJ1Y3R1cmUgbGV2ZWwgPSAzBAhuZXdMZXZlbAkAZAIFCGN1ckxldmVsAAEEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQDCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpMQU5EUFJFRklYCQACAQkArAICCQCsAgICBE5GVCAFCkxBTkRQUkVGSVgCICB0b2tlbiBzaG91bGQgYmUgcGFzc2VkIGFzIHBhcmFtBAVvd25lcgkBEUBleHRyTmF0aXZlKDEwNTgpAQkBFWtleUxhbmRBc3NldElkVG9Pd25lcgEFC2xhbmRBc3NldElkAwkBAiE9AgUFb3duZXIFBGFkZHIJAAIBCQCsAgIFCkxBTkRQUkVGSVgCDSBpcyBub3QgeW91cnMEAWQJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBAhsYW5kU2l6ZQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQUIbGFuZFNpemUEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUEYWRkcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04EA2xvYwkAtQkCCQEFdmFsdWUBBQtjdXJMb2NhdGlvbgIBXwMJAQIhPQIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFMCQACAQkArAICCQCsAgICFkR1Y2sgbG9jYXRpb24gdHlwZSBpcyAJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAhEsIGJ1dCBzaG91bGQgYmUgTAMJAQIhPQIJAJEDAgUDbG9jBQhsb2NJZHhJZAULbGFuZEFzc2V0SWQJAAIBCQCsAgIJAKwCAgkArAICAhREdWNrIGxvY2F0aW9uIGlkIGlzIAkAkQMCBQNsb2MFCGxvY0lkeElkAhAsIGJ1dCBzaG91bGQgYmUgBQtsYW5kQXNzZXRJZAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkEBW1MaXN0CQC1CQIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0AgFfBAZuZXdNYXQJALkJAgkBEXN1YnRyYWN0TWF0ZXJpYWxzAwUMc2hvdWxkVXNlTWF0BQVtTGlzdAkAawMFEUluZnJhVXBncmFkZUNvc3RTCQBoAgUGcGllY2VzBQhuZXdMZXZlbAAZAgFfBAZuZXdSZXMJAQhjbGFpbUFsbAIFC2xhbmRBc3NldElkBQZwaWVjZXMJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUIaW5mcmFLZXkFCG5ld0xldmVsCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCBQZuZXdSZXMJAMwIAgUGbmV3TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6BQNuaWwFCG5ld0xldmVsDQFpAQlzdGFrZUxhbmQABANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQHYXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAQIhPQIIBQNwbXQGYW1vdW50AAEJAAIBCQCsAgIJAKwCAgIETkZUIAUKTEFORFBSRUZJWAIkIHRva2VuIHNob3VsZCBiZSBhdHRhY2hlZCBhcyBwYXltZW50BAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkAwkBAiE9AggFBWFzc2V0Bmlzc3VlcgUEdGhpcwkAAgECF1Vua25vd24gaXNzdWVyIG9mIHRva2VuAwkBASEBCQEIY29udGFpbnMCCAUFYXNzZXQEbmFtZQUKTEFORFBSRUZJWAkAAgEJAKwCAgkArAICAglPbmx5IE5GVCAFCkxBTkRQUkVGSVgCFCB0b2tlbnMgYXJlIGFjY2VwdGVkBAtsYW5kTnVtU2l6ZQkAsAICCAUFYXNzZXQEbmFtZQAEBAdsYW5kTnVtAwkBCGNvbnRhaW5zAgULbGFuZE51bVNpemUCA1hYTAkAswICBQtsYW5kTnVtU2l6ZQADAwkBCGNvbnRhaW5zAgULbGFuZE51bVNpemUCAlhMCQCzAgIFC2xhbmROdW1TaXplAAIJALMCAgULbGFuZE51bVNpemUAAQQKbGFuZE51bUludAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEFB2xhbmROdW0JAKwCAgIeQ2Fubm90IHBhcnNlIGxhbmQgbnVtYmVyIGZyb20gCAUFYXNzZXQEbmFtZQQLbGFuZEFzc2V0SWQJANgEAQUHYXNzZXRJZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAMJAQlpc0RlZmluZWQBCQCfCAEFB3RpbWVLZXkJAAIBCQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCEiBpcyBhbHJlYWR5IHN0YWtlZAQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8EDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQFcHJvcHMJARF1cGRhdGVQcm9wb3J0aW9ucwMFDXRlcnJhaW5Db3VudHMJAGkCCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQAZAAEEDXByZXNhbGVBY3RpdmUDCQBnAgD0AwUKbGFuZE51bUludAkAZgIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBR1QcmVzYWxlQXJ0aWZhY3RBY3RpdmF0aW9uVGltZQcJAMwIAgkBDEludGVnZXJFbnRyeQIFB3RpbWVLZXkIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxCb29sZWFuRW50cnkCCQEfa2V5cHJlc2FsZUFydEFjdGl2YXRlZEJ5QXNzZXRJZAEFC2xhbmRBc3NldElkBQ1wcmVzYWxlQWN0aXZlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQdhZGRyZXNzCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQFB2FkZHJlc3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUxhbmROdW1Ub093bmVyAQUHbGFuZE51bQUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5UmVzUHJvcG9ydGlvbnMABQVwcm9wcwUDbmlsAWkBC3Vuc3Rha2VMYW5kAQtsYW5kQXNzZXRJZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJHVuc3Rha2UgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwQHYXNzZXRJZAkA2QQBBQtsYW5kQXNzZXRJZAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEBWFzc2V0CQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQDCQECIT0CCAUFYXNzZXQGaXNzdWVyBQR0aGlzCQACAQIXVW5rbm93biBpc3N1ZXIgb2YgdG9rZW4DCQEBIQEJAQhjb250YWlucwIIBQVhc3NldARuYW1lBQpMQU5EUFJFRklYCQACAQkArAICCQCsAgICCU9ubHkgTkZUIAUKTEFORFBSRUZJWAIXIHRva2VucyBjYW4gYmUgdW5zdGFrZWQEB3RpbWVLZXkJARZrZXlTdGFrZWRUaW1lQnlBc3NldElkAQULbGFuZEFzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQd0aW1lS2V5CQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEVa2V5TGFuZEFzc2V0SWRUb093bmVyAQULbGFuZEFzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFB2FkZHJlc3MJAAIBCQCsAgIJAKwCAgIHU3Rha2VkIAUKTEFORFBSRUZJWAINIGlzIG5vdCB5b3VycwQBZAkAtQkCCAUFYXNzZXQLZGVzY3JpcHRpb24CAV8EDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQGcGllY2VzCQEPbnVtUGllY2VzQnlTaXplAQkAkQMCBQFkBQtyZWNMYW5kU2l6ZQQFcHJvcHMJARF1cGRhdGVQcm9wb3J0aW9ucwMFDXRlcnJhaW5Db3VudHMJAGkCBQZwaWVjZXMAGQD///////////8BBAZuZXdSZXMJAQhjbGFpbUFsbAIFC2xhbmRBc3NldElkBQZwaWVjZXMEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQUHYWRkcmVzcwkArAICCQCsAgICEllvdSBjYW4ndCB1bnN0YWtlIAUKTEFORFBSRUZJWAIWIHdpdGhvdXQgYSBkdWNrIHN0YWtlZAQLY3VyTG9jYXRpb24JAQt2YWx1ZU9yRWxzZQIJAKIIAQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBQ9ERUZBVUxUTE9DQVRJT04EA2xvYwkAtQkCCQEFdmFsdWUBBQtjdXJMb2NhdGlvbgIBXwMJAQIhPQIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFMCQACAQkArAICCQCsAgICFkR1Y2sgbG9jYXRpb24gdHlwZSBpcyAJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAhEsIGJ1dCBzaG91bGQgYmUgTAMJAQIhPQIJAJEDAgUDbG9jBQhsb2NJZHhJZAULbGFuZEFzc2V0SWQJAAIBCQCsAgIJAKwCAgkArAICAhREdWNrIGxvY2F0aW9uIGlkIGlzIAkAkQMCBQNsb2MFCGxvY0lkeElkAhAsIGJ1dCBzaG91bGQgYmUgBQtsYW5kQXNzZXRJZAQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEFB2Fzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQUHdGltZUtleQkAzAgCCQELRGVsZXRlRW50cnkBCQEia2V5U3Rha2VkVGltZUJ5VHlwZUFzc2V0SWRBbmRPd25lcgMFCkxBTkRQUkVGSVgFC2xhbmRBc3NldElkBQdhZGRyZXNzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlSZXNQcm9wb3J0aW9ucwAFBXByb3BzCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5CQC5CQIJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUKYnBJZHhMZXZlbAkAzAgCBQZuZXdSZXMJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhNYXQJAMwIAgkAkQMCBQtjdXJyZW50UGFjawUJYnBJZHhQcm9kBQNuaWwCAToFA25pbAFpAQlzdGFrZUR1Y2sABANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQHYXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAQIhPQIIBQNwbXQGYW1vdW50AAEJAAIBCQCsAgIJAKwCAgIETkZUIAUKRFVDS1BSRUZJWAIkIHRva2VuIHNob3VsZCBiZSBhdHRhY2hlZCBhcyBwYXltZW50BAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkAwMJAQIhPQIIBQVhc3NldAZpc3N1ZXIFDWluY3ViYXRvckFkZHIJAQIhPQIIBQVhc3NldAZpc3N1ZXIFC2JyZWVkZXJBZGRyBwkAAgEJAKwCAgkArAICAhJVbmtub3duIGlzc3VlciBvZiAFCkRVQ0tQUkVGSVgCBiB0b2tlbgMJAQEhAQkBCGNvbnRhaW5zAggFBWFzc2V0BG5hbWUFCkRVQ0tQUkVGSVgJAAIBCQCsAgIJAKwCAgIJT25seSBORlQgBQpEVUNLUFJFRklYAhQgdG9rZW5zIGFyZSBhY2NlcHRlZAQKYXNzZXRJZFN0cgkA2AQBBQdhc3NldElkBAd0aW1lS2V5CQEWa2V5U3Rha2VkVGltZUJ5QXNzZXRJZAEFCmFzc2V0SWRTdHIDCQEJaXNEZWZpbmVkAQkAnwgBBQd0aW1lS2V5CQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAhIgaXMgYWxyZWFkeSBzdGFrZWQDCQEJaXNEZWZpbmVkAQkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzCQACAQkArAICAh1Zb3UgYWxyZWFkeSBzdGFrZWQgb25lIGR1Y2s6IAgFBWFzc2V0BG5hbWUEBmxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFCmFzc2V0SWRTdHIECGxvY2F0aW9uCQCiCAEFBmxvY0tleQQJa2V5SGVhbHRoCQENa2V5RHVja0hlYWx0aAEFCmFzc2V0SWRTdHIEBmhlYWx0aAkAnwgBBQlrZXlIZWFsdGgEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQphc3NldElkU3RyBAhiYWNrcGFjawkAoggBBQVicEtleQkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd0aW1lS2V5CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpEVUNLUFJFRklYCQDYBAEFB2Fzc2V0SWQFB2FkZHJlc3MIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQtTdHJpbmdFbnRyeQIJARBrZXlEdWNrSWRUb093bmVyAQUKYXNzZXRJZFN0cgUHYWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzBQphc3NldElkU3RyBQNuaWwDCQEJaXNEZWZpbmVkAQUIbG9jYXRpb24FA25pbAkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFBmxvY0tleQUPREVGQVVMVExPQ0FUSU9OBQNuaWwDCQEJaXNEZWZpbmVkAQUGaGVhbHRoBQNuaWwJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoAGQFA25pbAMJAQlpc0RlZmluZWQBBQhiYWNrcGFjawUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWJwS2V5AhowOjBfMF8wXzBfMF8wOjBfMF8wXzBfMF8wOgUDbmlsAWkBC3Vuc3Rha2VEdWNrAQphc3NldElkU3RyAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIkdW5zdGFrZSBkb2Vzbid0IHJlcXVpcmUgYW55IHBheW1lbnRzBAdhc3NldElkCQDZBAEFCmFzc2V0SWRTdHIEB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkAwMJAQIhPQIIBQVhc3NldAZpc3N1ZXIFDWluY3ViYXRvckFkZHIJAQIhPQIIBQVhc3NldAZpc3N1ZXIFC2JyZWVkZXJBZGRyBwkAAgEJAKwCAgkArAICAhJVbmtub3duIGlzc3VlciBvZiAFCkRVQ0tQUkVGSVgCBiB0b2tlbgMJAQEhAQkBCGNvbnRhaW5zAggFBWFzc2V0BG5hbWUFCkRVQ0tQUkVGSVgJAAIBCQCsAgIJAKwCAgIJT25seSBORlQgBQpEVUNLUFJFRklYAhcgdG9rZW5zIGNhbiBiZSB1bnN0YWtlZAQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBCQDYBAEFB2Fzc2V0SWQDCQEBIQEJAQlpc0RlZmluZWQBBQd0aW1lS2V5CQACAQkArAICCQCsAgICBE5GVCAIBQVhc3NldARuYW1lAg4gaXMgbm90IHN0YWtlZAMJAQEhAQkBCWlzRGVmaW5lZAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MJAAIBCQCsAgIJAKwCAgIJVGhlIGR1Y2sgCAUFYXNzZXQEbmFtZQIOIGlzIG5vdCBzdGFrZWQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBEGtleUR1Y2tJZFRvT3duZXIBCQDYBAEFB2Fzc2V0SWQJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIMIGlzIG9ycGhhbmVkAwkBAiE9AgUFb3duZXIFB2FkZHJlc3MJAAIBAhdTdGFrZWQgTkZUIGlzIG5vdCB5b3VycwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIAAQUHYXNzZXRJZAkAzAgCCQELRGVsZXRlRW50cnkBBQd0aW1lS2V5CQDMCAIJAQtEZWxldGVFbnRyeQEJAQ9rZXlEdWNrTG9jYXRpb24BBQphc3NldElkU3RyCQDMCAIJAQtEZWxldGVFbnRyeQEJASJrZXlTdGFrZWRUaW1lQnlUeXBlQXNzZXRJZEFuZE93bmVyAwUKRFVDS1BSRUZJWAUKYXNzZXRJZFN0cgUHYWRkcmVzcwkAzAgCCQELRGVsZXRlRW50cnkBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQdhZGRyZXNzBQNuaWwBaQEIY2xhaW1SZXMCBmFtb3VudAtsYW5kQXNzZXRJZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJWNsYWltUmVzIGRvZXNuJ3QgcmVxdWlyZSBhbnkgcGF5bWVudHMEBGFkZHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBCQDZBAEFC2xhbmRBc3NldElkAwkBASEBCQEIY29udGFpbnMCCAUFYXNzZXQEbmFtZQUKTEFORFBSRUZJWAkAAgEJAKwCAgkArAICAgRORlQgBQpMQU5EUFJFRklYAiAgdG9rZW4gc2hvdWxkIGJlIHBhc3NlZCBhcyBwYXJhbQQHdGltZUtleQkBFmtleVN0YWtlZFRpbWVCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAQFb3duZXIJARFAZXh0ck5hdGl2ZSgxMDU4KQEJARVrZXlMYW5kQXNzZXRJZFRvT3duZXIBBQtsYW5kQXNzZXRJZAMJAQIhPQIFBW93bmVyBQRhZGRyCQACAQkArAICBQpMQU5EUFJFRklYAg0gaXMgbm90IHlvdXJzBAFkCQC1CQIIBQVhc3NldAtkZXNjcmlwdGlvbgIBXwQIbGFuZFNpemUJAJEDAgUBZAULcmVjTGFuZFNpemUEDXRlcnJhaW5Db3VudHMJAQ1jb3VudFRlcnJhaW5zAQkAkQMCBQFkBQtyZWNUZXJyYWlucwQLZHVja0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQEUa2V5U3Rha2VkRHVja0J5T3duZXIBBQRhZGRyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBCQEPa2V5RHVja0xvY2F0aW9uAQULZHVja0Fzc2V0SWQFD0RFRkFVTFRMT0NBVElPTgQDbG9jCQC1CQIJAQV2YWx1ZQEFC2N1ckxvY2F0aW9uAgFfAwkBAiE9AgkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCAUwJAAIBCQCsAgIJAKwCAgIWRHVjayBsb2NhdGlvbiB0eXBlIGlzIAkAkQMCBQNsb2MFCmxvY0lkeFR5cGUCESwgYnV0IHNob3VsZCBiZSBMAwkBAiE9AgkAkQMCBQNsb2MFCGxvY0lkeElkBQtsYW5kQXNzZXRJZAkAAgEJAKwCAgkArAICCQCsAgICFER1Y2sgbG9jYXRpb24gaWQgaXMgCQCRAwIFA2xvYwUIbG9jSWR4SWQCECwgYnV0IHNob3VsZCBiZSAFC2xhbmRBc3NldElkBAlzYXZlZFRpbWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQd0aW1lS2V5CQCsAgIJAKwCAgIETkZUIAgFBWFzc2V0BG5hbWUCDiBpcyBub3Qgc3Rha2VkBAlkZWx0YVRpbWUJAGUCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUJc2F2ZWRUaW1lAwkAZgIAAAUJZGVsdGFUaW1lCQACAQkArAICCQCsAgIJAKwCAgImU2F2ZWQgdGltZXN0YW1wIGlzIGluIGZ1dHVyZSwgc2F2ZWQgPSAJAKQDAQUJc2F2ZWRUaW1lAgwsIGN1cnJlbnQgPSAJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAEBnBpZWNlcwkBD251bVBpZWNlc0J5U2l6ZQEFCGxhbmRTaXplBBZkYWlseVByb2R1Y3Rpb25CeVBpZWNlCQEMYXBwbHlCb251c2VzAQULbGFuZEFzc2V0SWQECGF2YWlsUmVzCQBrAwUJZGVsdGFUaW1lCQBoAgUWZGFpbHlQcm9kdWN0aW9uQnlQaWVjZQUGcGllY2VzBQlEQVlNSUxMSVMDCQBmAgUGYW1vdW50BQhhdmFpbFJlcwkAAgEJAKwCAgkArAICCQCsAgICIk5vdCBlbm91Z2ggcmVzb3VyY2VzLCBhdmFpbGFibGUgPSAJAKQDAQUIYXZhaWxSZXMCDiwgcmVxdWVzdGVkID0gCQCkAwEFBmFtb3VudAQMbmV3RGVsdGFUaW1lCQBrAwkAZQIFCGF2YWlsUmVzBQZhbW91bnQFCURBWU1JTExJUwkAaAIFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UFBnBpZWNlcwQMbmV3VGltZXN0YW1wCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFDG5ld0RlbHRhVGltZQQFYnBLZXkJARFrZXlCYWNrcGFja0J5RHVjawEFC2R1Y2tBc3NldElkBAtjdXJyZW50UGFjawkBC2dldEJhY2twYWNrAQUFYnBLZXkECmN1cnJlbnRSZXMJALUJAgkAkQMCBQtjdXJyZW50UGFjawUIYnBJZHhSZXMCAV8EBWJwUmVzCQEGYWRkUmVzBQUKY3VycmVudFJlcwUNdGVycmFpbkNvdW50cwkAZQIFCWRlbHRhVGltZQUMbmV3RGVsdGFUaW1lCQBpAgUGcGllY2VzABkFFmRhaWx5UHJvZHVjdGlvbkJ5UGllY2UEB25ld1BhY2sJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIFBWJwUmVzCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4TWF0CQDMCAIJAJEDAgULY3VycmVudFBhY2sFCWJwSWR4UHJvZAUDbmlsAgE6CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkFB25ld1BhY2sJAMwIAgkBDEludGVnZXJFbnRyeQIFB3RpbWVLZXkFDG5ld1RpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBImtleVN0YWtlZFRpbWVCeVR5cGVBc3NldElkQW5kT3duZXIDBQpMQU5EUFJFRklYBQtsYW5kQXNzZXRJZAUFb3duZXIFDG5ld1RpbWVzdGFtcAUDbmlsBQVicFJlcwFpAQZmbGlnaHQCB21lc3NhZ2UDc2lnAwkBASEBCQDEEwMFB21lc3NhZ2UFA3NpZwUDcHViCQACAQIYc2lnbmF0dXJlIGRvZXMgbm90IG1hdGNoAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIjZmxpZ2h0IGRvZXNuJ3QgcmVxdWlyZSBhbnkgcGF5bWVudHMEBXBhcnRzCQC1CQIJALAJAQUHbWVzc2FnZQIBOwQCaHAJALUJAgkAkQMCCQC1CQIJAJEDAgUFcGFydHMAAAIBfAAAAgFfBAVjdXJIUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmhwAAAEBW5ld0hQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCaHAAAQQNbmV3TG9jQW5kVGltZQkAtQkCCQCRAwIFBXBhcnRzAAECAToEC25ld0xvY2F0aW9uCQCRAwIFDW5ld0xvY0FuZFRpbWUAAAQEdGltZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDW5ld0xvY0FuZFRpbWUAAQMDCQBmAgUEdGltZQkAZAIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBRFGSVZFTUlOVVRFU01JTExJUwYJAGYCCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAFEUZJVkVNSU5VVEVTTUlMTElTBQR0aW1lCQACAQISc2lnbmF0dXJlIG91dGRhdGVkBAtkdWNrQXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARRrZXlTdGFrZWREdWNrQnlPd25lcgEJAKUIAQgFAWkGY2FsbGVyAhxZb3UgZG9uJ3QgaGF2ZSBhIGR1Y2sgc3Rha2VkBAlrZXlIZWFsdGgJAQ1rZXlEdWNrSGVhbHRoAQULZHVja0Fzc2V0SWQEDG9sZEZyb21TdGF0ZQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlrZXlIZWFsdGgAZAMJAQIhPQIFDG9sZEZyb21TdGF0ZQUFY3VySFAJAAIBCQCsAgIJAKwCAgkArAICAgpvbGRIZWFsdGg9CQCkAwEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJa2V5SGVhbHRoAGQCLyBmcm9tIHN0YXRlIGRvZXMgbm90IG1hdGNoIG9uZSBmcm9tIGZsaWdodCBsb2c9CQCkAwEFBWN1ckhQAwkAZwIAAAUFY3VySFAJAAIBAh5Zb3UgY2FuJ3QgZmx5IHdpdGggemVybyBoZWFsdGgEBmxvY0tleQkBD2tleUR1Y2tMb2NhdGlvbgEFC2R1Y2tBc3NldElkBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAoggBBQZsb2NLZXkFD0RFRkFVTFRMT0NBVElPTgMJAAACBQtuZXdMb2NhdGlvbgULY3VyTG9jYXRpb24JAAIBAiJZb3UgY2FuJ3QgZmx5IHRvIHRoZSBzYW1lIGxvY2F0aW9uCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUGbG9jS2V5AwkAZgIFBW5ld0hQAAAFC25ld0xvY2F0aW9uBQtjdXJMb2NhdGlvbgkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa2V5SGVhbHRoBQVuZXdIUAUDbmlsBQR1bml0AWkBCXNldEhlYWx0aAIGaGVhbHRoC2R1Y2tBc3NldElkAwMJAGYCAAAFBmhlYWx0aAYJAGYCBQZoZWFsdGgAZAkAAgECGkhQIHNob3VsZCBiZSB3aXRoaW4gMC4uMTAwCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQENa2V5RHVja0hlYWx0aAEFC2R1Y2tBc3NldElkBQZoZWFsdGgFA25pbAFpAQRoZWFsAgdtYXRUeXBlBmFtb3VudAMDCQBmAgAABQdtYXRUeXBlBgkAZwIFB21hdFR5cGUFBk5VTVJFUwkAAgEJAKwCAgISVW5rbm93biBtYXRlcmlhbDogCQCkAwEFB21hdFR5cGUDCQBnAgAABQZhbW91bnQJAAIBCQCsAgICG0Ftb3VudCBzaG91bGQgYmUgcG9zaXRpdmUhIAkApAMBBQZhbW91bnQEC2R1Y2tBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBCAUBaQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQECWtleUhlYWx0aAkBDWtleUR1Y2tIZWFsdGgBBQtkdWNrQXNzZXRJZAQJb2xkSGVhbHRoCQELdmFsdWVPckVsc2UCCQCfCAEFCWtleUhlYWx0aABkAwkAZwIFCW9sZEhlYWx0aABkCQACAQIaSFAgc2hvdWxkIGJlIDwgMTAwIHRvIGhlYWwEBWJwS2V5CQERa2V5QmFja3BhY2tCeUR1Y2sBBQtkdWNrQXNzZXRJZAQLY3VycmVudFBhY2sJAQtnZXRCYWNrcGFjawEFBWJwS2V5BAVtTGlzdAkAtQkCCQCRAwIFC2N1cnJlbnRQYWNrBQhicElkeE1hdAIBXwQNY3VycmVudEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBW1MaXN0BQdtYXRUeXBlBAtkZWx0YUhlYWx0aAkAlwMBCQDMCAIJAGkCBQZhbW91bnQFCEhFQUxDT1NUCQDMCAIJAGUCAGQFCW9sZEhlYWx0aAUDbmlsBAtzcGVuZEFtb3VudAkAaAIFC2RlbHRhSGVhbHRoBQhIRUFMQ09TVAMJAGYCBQtzcGVuZEFtb3VudAUNY3VycmVudEFtb3VudAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAglZb3UgbmVlZCAJAKQDAQULc3BlbmRBbW91bnQCBCBvZiAJAJEDAgUIbWF0VHlwZXMFB21hdFR5cGUCJCB0byBoZWFsLCBidXQgeW91IGJhY2twYWNrIGNvbnRhaW5zIAkApAMBBQ1jdXJyZW50QW1vdW50BAZuZXdNYXQJAQxzdWJPbmVJbkxpc3QDBQVtTGlzdAUHbWF0VHlwZQULc3BlbmRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtleUhlYWx0aAkAZAIFCW9sZEhlYWx0aAULZGVsdGFIZWFsdGgJAMwIAgkBC1N0cmluZ0VudHJ5AgUFYnBLZXkJALkJAgkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQpicElkeExldmVsCQDMCAIJAJEDAgULY3VycmVudFBhY2sFCGJwSWR4UmVzCQDMCAIFBm5ld01hdAkAzAgCCQCRAwIFC2N1cnJlbnRQYWNrBQlicElkeFByb2QFA25pbAIBOgUDbmlsAWkBDnVwZGF0ZUJhY2twYWNrAgtkdWNrQXNzZXRJZAduZXdQYWNrAwkBAiE9AggFAWkGY2FsbGVyBQtlY29ub215QWRkcgkAAgECEXBlcm1pc3Npb24gZGVuaWVkCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUJhY2twYWNrQnlEdWNrAQULZHVja0Fzc2V0SWQFB25ld1BhY2sFA25pbAUHbmV3UGFjawFpAQ1leHBlZGl0aW9uQnV5AgdtZXNzYWdlA3NpZwMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkBQt1c2RuQXNzZXRJZAkAAgECGkFsbG93ZWQgVVNETiBwYXltZW50IG9ubHkhAwkBAiE9AggFA3BtdAZhbW91bnQFB0VYUFVTRE4JAAIBCQCsAgICG1BheW1lbnQgYXR0YWNoZWQgc2hvdWxkIGJlIAkApAMBBQdFWFBVU0ROCQEQZXhwZWRpdGlvbkNvbW1vbgUHCAUBaQZjYWxsZXIIBQFpDXRyYW5zYWN0aW9uSWQFB21lc3NhZ2UFA3NpZwFpAQpleHBlZGl0aW9uAgdtZXNzYWdlA3NpZwMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJ2V4cGVkaXRpb24gZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwkBEGV4cGVkaXRpb25Db21tb24FBggFAWkGY2FsbGVyCAUBaQ10cmFuc2FjdGlvbklkBQdtZXNzYWdlBQNzaWcBaQEMdXBncmFkZUluZnJhAQtsYW5kQXNzZXRJZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECM0luZnJhc3RydWN0dXJlIHVwZ3JhZGUgZG9lc24ndCByZXF1aXJlIGFueSBwYXltZW50cwkBDXVwSW5mcmFDb21tb24DBggFAWkGY2FsbGVyBQtsYW5kQXNzZXRJZAFpARB1cGdyYWRlSW5mcmFVc2RuAQtsYW5kQXNzZXRJZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECHEV4YWN0bHkgb25lIHBheW1lbnQgcmVxdWlyZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAAwkBAiE9AggFA3BtdAdhc3NldElkBQt1c2RuQXNzZXRJZAkAAgECGkFsbG93ZWQgVVNETiBwYXltZW50IG9ubHkhBAhuZXdMZXZlbAkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBFmtleUluZnJhTGV2ZWxCeUFzc2V0SWQBBQtsYW5kQXNzZXRJZAAAAAEEBWFzc2V0CQEFdmFsdWUBCQDsBwEJANkEAQULbGFuZEFzc2V0SWQEAWQJALUJAggFBWFzc2V0C2Rlc2NyaXB0aW9uAgFfBARjb3N0CQBrAwUVSW5mcmFVcGdyYWRlQ29zdFNVc2RuCQBoAgkBD251bVBpZWNlc0J5U2l6ZQEJAJEDAgUBZAULcmVjTGFuZFNpemUFCG5ld0xldmVsABkDCQECIT0CCAUDcG10BmFtb3VudAUEY29zdAkAAgEJAKwCAgIbUGF5bWVudCBhdHRhY2hlZCBzaG91bGQgYmUgCQCkAwEFBGNvc3QJAQ11cEluZnJhQ29tbW9uAwcIBQFpBmNhbGxlcgULbGFuZEFzc2V0SWQAJs+0yw==", "height": 2387916, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 1W7obizLaGvWBdXZfEaubk2K6eiBT59GaidPXP8kUwC Next: CJACRGTxNDnou3rf6fDznfnV56vg6axnyif97kDzPyBr Diff:
OldNewDifferences
451451 }
452452
453453
454+func applyBonuses (landAssetId) = {
455+ let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
456+ let presaleBonus = if (valueOrElse(getBoolean(keypresaleArtActivatedByAssetId(landAssetId)), false))
457+ then 3
458+ else 0
459+ ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, infraLevel, 4)) + fraction(DAILYRESBYPIECE, presaleBonus, 20))
460+ }
461+
462+
463+func claimAll (landAssetId,pieces) = {
464+ let timeKey = keyStakedTimeByAssetId(landAssetId)
465+ let savedTime = valueOrErrorMessage(getInteger(timeKey), (((LANDPREFIX + " ") + landAssetId) + " is not staked"))
466+ let deltaTime = (lastBlock.timestamp - savedTime)
467+ if ((0 > deltaTime))
468+ then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
469+ else {
470+ let dailyProductionByPiece = applyBonuses(landAssetId)
471+ let availRes = (fraction(deltaTime, dailyProductionByPiece, DAYMILLIS) * pieces)
472+ asString(invoke(this, "claimRes", [availRes, landAssetId], nil))
473+ }
474+ }
475+
476+
454477 func upInfraCommon (shouldUseMat,caller,landAssetId) = {
455478 let addr = toString(caller)
456479 let infraKey = keyInfraLevelByAssetId(landAssetId)
463486 if (!(contains(asset.name, LANDPREFIX)))
464487 then throw((("NFT " + LANDPREFIX) + " token should be passed as param"))
465488 else {
466- let timeKey = keyStakedTimeByAssetId(landAssetId)
467489 let owner = getStringValue(keyLandAssetIdToOwner(landAssetId))
468490 if ((owner != addr))
469491 then throw((LANDPREFIX + " is not yours"))
483505 let currentPack = getBackpack(bpKey)
484506 let mList = split(currentPack[bpIdxMat], "_")
485507 let newMat = makeString(subtractMaterials(shouldUseMat, mList, fraction(InfraUpgradeCostS, (pieces * newLevel), 25)), "_")
486- let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
487- let deltaTime = (lastBlock.timestamp - savedTime)
488- if ((0 > deltaTime))
489- then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
490- else {
491- let availRes = (fraction(deltaTime, DAILYRESBYPIECE, DAYMILLIS) * pieces)
492- let newRes = asString(invoke(this, "claimRes", [availRes, landAssetId], nil))
493- $Tuple2([IntegerEntry(infraKey, newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], newRes, newMat, currentPack[bpIdxProd]], ":"))], newLevel)
494- }
508+ let newRes = claimAll(landAssetId, pieces)
509+ $Tuple2([IntegerEntry(infraKey, newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], newRes, newMat, currentPack[bpIdxProd]], ":"))], newLevel)
495510 }
496511 }
497512 }
498513 }
499- }
500-
501-
502-func applyBonuses (landAssetId) = {
503- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
504- let presaleBonus = if (valueOrElse(getBoolean(keypresaleArtActivatedByAssetId(landAssetId)), false))
505- then 3
506- else 0
507- ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, infraLevel, 4)) + fraction(DAILYRESBYPIECE, presaleBonus, 20))
508514 }
509515
510516
566572 else {
567573 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
568574 if ((owner != address))
569- then throw("Staked NFT is not yours")
575+ then throw((("Staked " + LANDPREFIX) + " is not yours"))
570576 else {
571577 let d = split(asset.description, "_")
572578 let terrainCounts = countTerrains(d[recTerrains])
573- let props = updateProportions(terrainCounts, (numPiecesBySize(d[recLandSize]) / 25), -1)
574-[ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address)), StringEntry(keyResProportions(), props)]
579+ let pieces = numPiecesBySize(d[recLandSize])
580+ let props = updateProportions(terrainCounts, (pieces / 25), -1)
581+ let newRes = claimAll(landAssetId, pieces)
582+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(address)), (("You can't unstake " + LANDPREFIX) + " without a duck staked"))
583+ let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
584+ let loc = split(value(curLocation), "_")
585+ if ((loc[locIdxType] != "L"))
586+ then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
587+ else if ((loc[locIdxId] != landAssetId))
588+ then throw(((("Duck location id is " + loc[locIdxId]) + ", but should be ") + landAssetId))
589+ else {
590+ let bpKey = keyBackpackByDuck(duckAssetId)
591+ let currentPack = getBackpack(bpKey)
592+[ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address)), StringEntry(keyResProportions(), props), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], newRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], ":"))]
593+ }
575594 }
576595 }
577596 }
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))
6565 then 18921595217
6666 else if (("T" == $match0))
6767 then 189215952
6868 else throw("Unknown chain")
6969 }
7070
7171 let InfraUpgradeCostSUsdn = match chain {
7272 case _ =>
7373 if (("W" == $match0))
7474 then 120000000
7575 else if (("T" == $match0))
7676 then 1200000
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 PresaleArtifactActivationTime = match chain {
9999 case _ =>
100100 if (("W" == $match0))
101101 then 1673136000000
102102 else if (("T" == $match0))
103103 then 1672790400000
104104 else throw("Unknown chain")
105105 }
106106
107107 let MULT6 = 1000000
108108
109109 let FIVEX = toBigInt(5)
110110
111111 let TWENTYX = toBigInt(20)
112112
113113 let TWENTY2X = toBigInt((20 * 20))
114114
115115 let TWENTY3X = toBigInt(((20 * 20) * 20))
116116
117117 let TWENTY4X = toBigInt((((20 * 20) * 20) * 20))
118118
119119 let TWENTY5X = toBigInt(((((20 * 20) * 20) * 20) * 20))
120120
121121 let matTypes = ["Fuel", "Metal", "Plank", "Glass", "Plastic", "Protein"]
122122
123123 let continents = ["Asia", "Europe", "Americas", "Oceania", "Africa"]
124124
125125 func keyNextFreeLandNum () = "nextLandNum"
126126
127127
128128 func keyLandToAssetId (landNum) = ("landToAsset_" + landNum)
129129
130130
131131 func keyNftName (landNum,landSize) = ((LANDPREFIX + landNum) + landSize)
132132
133133
134134 func keyLandAssetIdToOwner (assetId) = ("nftOwner_" + assetId)
135135
136136
137137 func keyDuckIdToOwner (assetId) = ("duckOwner_" + assetId)
138138
139139
140140 func keyStakedTimeByAssetId (assetId) = ("stakedTime_" + assetId)
141141
142142
143143 func keyInfraLevelByAssetId (assetId) = ("infraLevel_" + assetId)
144144
145145
146146 func keypresaleArtActivatedByAssetId (assetId) = ("presaleArtActivated_" + assetId)
147147
148148
149149 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
150150
151151
152152 func keyStakedTimeByTypeAssetIdAndOwner (nftType,assetId,ownerAddr) = ((((("stakedTimeByTypeAssetIdAndOwner_" + nftType) + "_") + assetId) + "_") + ownerAddr)
153153
154154
155155 func keyLandNumToOwner (landNum) = ("landOwner_" + landNum)
156156
157157
158158 func keyBackpackByDuck (duckAssetId) = ("backPack_" + duckAssetId)
159159
160160
161161 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
162162
163163
164164 func keyDuckHealth (duckAssetId) = ("duckHealth_" + duckAssetId)
165165
166166
167167 func keyResProportions () = "resTypesProportions"
168168
169169
170170 let recLandNum = 0
171171
172172 let recLandSize = 1
173173
174174 let recTerrains = 2
175175
176176 let recContinent = 3
177177
178178 let locIdxContinent = 0
179179
180180 let locIdxType = 1
181181
182182 let locIdxId = 2
183183
184184 let bpIdxLevel = 0
185185
186186 let bpIdxRes = 1
187187
188188 let bpIdxMat = 2
189189
190190 let bpIdxProd = 3
191191
192192 func asString (v) = match v {
193193 case s: String =>
194194 s
195195 case _ =>
196196 throw("fail to cast into String")
197197 }
198198
199199
200200 func getNeededMaterials (total) = {
201201 let props = split(value(getString(keyResProportions())), "_")
202202 if ((size(props) != NUMRES))
203203 then throw("Wrong proportions data")
204204 else {
205205 let r = [parseIntValue(props[0]), parseIntValue(props[1]), parseIntValue(props[2]), parseIntValue(props[3]), parseIntValue(props[4]), parseIntValue(props[5])]
206206 let sum = (((((r[0] + r[1]) + r[2]) + r[3]) + r[4]) + r[5])
207207 if ((0 >= sum))
208208 then throw("No lands staked")
209209 else {
210210 let norm6 = fraction(total, MULT6, sum)
211211 func normalizer (acc,elem) = (acc :+ fraction(elem, norm6, MULT6))
212212
213213 let $l = r
214214 let $s = size($l)
215215 let $acc0 = nil
216216 func $f0_1 ($a,$i) = if (($i >= $s))
217217 then $a
218218 else normalizer($a, $l[$i])
219219
220220 func $f0_2 ($a,$i) = if (($i >= $s))
221221 then $a
222222 else throw("List size exceeds 6")
223223
224224 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
225225 }
226226 }
227227 }
228228
229229
230230 func subtractMaterials (shouldUseMat,has,totalNeed) = {
231231 let need = getNeededMaterials(totalNeed)
232232 func subtractor (acc,idx) = {
233233 let result = (parseIntValue(has[idx]) - need[idx])
234234 if ((0 > result))
235235 then throw(((((("Not enough material idx=" + toString(idx)) + ", you have ") + has[idx]) + ", but need ") + toString(need[idx])))
236236 else (acc :+ toString(result))
237237 }
238238
239239 if (shouldUseMat)
240240 then {
241241 let $l = [0, 1, 2, 3, 4, 5]
242242 let $s = size($l)
243243 let $acc0 = nil
244244 func $f0_1 ($a,$i) = if (($i >= $s))
245245 then $a
246246 else subtractor($a, $l[$i])
247247
248248 func $f0_2 ($a,$i) = if (($i >= $s))
249249 then $a
250250 else throw("List size exceeds 6")
251251
252252 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
253253 }
254254 else has
255255 }
256256
257257
258258 func updateProportions (terrainCounts,landSizeIndex,sign) = {
259259 let props = split(valueOrElse(getString(keyResProportions()), "0_0_0_0_0_0"), "_")
260260 if ((size(props) != NUMRES))
261261 then throw("Wrong proportions data")
262262 else {
263263 func updater (acc,i) = {
264264 let result = (parseIntValue(props[i]) + ((sign * terrainCounts[i]) * landSizeIndex))
265265 if ((0 > result))
266266 then throw(((((((("Panic! Pieces of type=" + toString(i)) + ", sign=") + toString(sign)) + ", terrainCounts[i]=") + toString(terrainCounts[i])) + ", landSizeIndex=") + toString(landSizeIndex)))
267267 else (acc :+ toString(result))
268268 }
269269
270270 let r = {
271271 let $l = [0, 1, 2, 3, 4, 5]
272272 let $s = size($l)
273273 let $acc0 = nil
274274 func $f0_1 ($a,$i) = if (($i >= $s))
275275 then $a
276276 else updater($a, $l[$i])
277277
278278 func $f0_2 ($a,$i) = if (($i >= $s))
279279 then $a
280280 else throw("List size exceeds 6")
281281
282282 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
283283 }
284284 makeString(r, "_")
285285 }
286286 }
287287
288288
289289 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)]
290290
291291
292292 func numPiecesBySize (landSize) = match landSize {
293293 case _ =>
294294 if (("S" == $match0))
295295 then 25
296296 else if (("M" == $match0))
297297 then 100
298298 else if (("L" == $match0))
299299 then 225
300300 else if (("XL" == $match0))
301301 then 400
302302 else if (("XXL" == $match0))
303303 then 625
304304 else throw("Unknown land size")
305305 }
306306
307307
308308 func subOneInList (aList,idx,amount) = {
309309 func subber (acc,i) = (acc :+ (if ((i == idx))
310310 then toString((parseIntValue(aList[i]) - amount))
311311 else aList[i]))
312312
313313 let r = {
314314 let $l = [0, 1, 2, 3, 4, 5]
315315 let $s = size($l)
316316 let $acc0 = nil
317317 func $f0_1 ($a,$i) = if (($i >= $s))
318318 then $a
319319 else subber($a, $l[$i])
320320
321321 func $f0_2 ($a,$i) = if (($i >= $s))
322322 then $a
323323 else throw("List size exceeds 6")
324324
325325 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
326326 }
327327 makeString(r, "_")
328328 }
329329
330330
331331 func addRes (currentRes,terrainCounts,deltaTime,landSizeIndex,dailyByPieceWithBonuses) = {
332332 func adder (acc,i) = {
333333 let resOfType = ((fraction(deltaTime, dailyByPieceWithBonuses, DAYMILLIS) * terrainCounts[i]) * landSizeIndex)
334334 (acc :+ toString((parseIntValue(currentRes[i]) + resOfType)))
335335 }
336336
337337 let r = {
338338 let $l = [0, 1, 2, 3, 4, 5]
339339 let $s = size($l)
340340 let $acc0 = nil
341341 func $f0_1 ($a,$i) = if (($i >= $s))
342342 then $a
343343 else adder($a, $l[$i])
344344
345345 func $f0_2 ($a,$i) = if (($i >= $s))
346346 then $a
347347 else throw("List size exceeds 6")
348348
349349 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
350350 }
351351 makeString(r, "_")
352352 }
353353
354354
355355 func abs (x) = if ((x >= toBigInt(0)))
356356 then x
357357 else -(x)
358358
359359
360360 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]]
361361
362362 func genChar (n,freqs) = {
363363 let rem = toInt((n % TWENTYX))
364364 let letter = if ((freqs[0] > rem))
365365 then "A"
366366 else if ((freqs[1] > rem))
367367 then "B"
368368 else if ((freqs[2] > rem))
369369 then "C"
370370 else if ((freqs[3] > rem))
371371 then "D"
372372 else if ((freqs[4] > rem))
373373 then "E"
374374 else "F"
375375 letter
376376 }
377377
378378
379379 func getBackpack (bpKey) = {
380380 let p = split(valueOrElse(getString(bpKey), "0:0_0_0_0_0_0:0_0_0_0_0_0:"), ":")
381381 [toString(valueOrElse(parseInt(p[bpIdxLevel]), 0)), if ((size(split(p[bpIdxRes], "_")) == NUMRES))
382382 then p[bpIdxRes]
383383 else "0_0_0_0_0_0", if ((size(split(p[bpIdxMat], "_")) == NUMRES))
384384 then p[bpIdxMat]
385385 else "0_0_0_0_0_0", p[bpIdxProd]]
386386 }
387387
388388
389389 func expeditionCommon (shouldUseMat,caller,txId,message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
390390 then throw("signature does not match")
391391 else {
392392 let parts = split(toUtf8String(message), ";")
393393 let hp = split(split(parts[0], "|")[0], "_")
394394 let curHP = parseIntValue(hp[0])
395395 let newHP = parseIntValue(hp[1])
396396 let locAndTime = split(parts[1], ":")
397397 let targetLocation = split(locAndTime[0], "_")
398398 if ((targetLocation[1] != "E"))
399399 then throw("expedition target location type should be E")
400400 else {
401401 let time = parseIntValue(locAndTime[1])
402402 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
403403 then true
404404 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
405405 then throw("signature outdated")
406406 else {
407407 let userAddr = toString(caller)
408408 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(userAddr)), "You don't have a duck staked")
409409 let keyHealth = keyDuckHealth(duckAssetId)
410410 let oldFromState = valueOrElse(getInteger(keyHealth), 100)
411411 if ((oldFromState != curHP))
412412 then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
413413 else if ((0 >= curHP))
414414 then throw("You can't fly with zero health")
415415 else if ((0 >= newHP))
416416 then throw("Your duck health is zero, expedition failed")
417417 else {
418418 let bpKey = keyBackpackByDuck(duckAssetId)
419419 let currentPack = getBackpack(bpKey)
420420 let mList = split(currentPack[bpIdxMat], "_")
421421 let newMat = makeString(subtractMaterials(shouldUseMat, mList, EXPMATERIALS), "_")
422422 let bigNum = abs(toBigInt(txId))
423423 let freeNum = valueOrElse(getInteger(keyNextFreeLandNum()), 501)
424424 let landNum = toString(freeNum)
425425 let continentIdx = toInt((bigNum % FIVEX))
426426 let f = freq[continentIdx]
427427 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))
428428
429429 let t = {
430430 let $l = [1, 2, 3, 4, 5]
431431 let $s = size($l)
432432 let $acc0 = $Tuple2("", (bigNum / FIVEX))
433433 func $f0_1 ($a,$i) = if (($i >= $s))
434434 then $a
435435 else terrainGenerator($a, $l[$i])
436436
437437 func $f0_2 ($a,$i) = if (($i >= $s))
438438 then $a
439439 else throw("List size exceeds 5")
440440
441441 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
442442 }
443443 let continent = continents[continentIdx]
444444 let issue = Issue(keyNftName(landNum, "S"), makeString([landNum, "S", t._1, continent], "_"), 1, 0, false)
445445 let assetId = calculateAssetId(issue)
446446 let id = toBase58String(assetId)
447447 $Tuple2([IntegerEntry(keyNextFreeLandNum(), (freeNum + 1)), issue, StringEntry(keyLandToAssetId(landNum), id), StringEntry(keyLandAssetIdToOwner(id), userAddr), StringEntry(keyLandNumToOwner(landNum), userAddr), IntegerEntry(keyInfraLevelByAssetId(id), 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]], ":"))], unit)
448448 }
449449 }
450450 }
451451 }
452452
453453
454+func applyBonuses (landAssetId) = {
455+ let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
456+ let presaleBonus = if (valueOrElse(getBoolean(keypresaleArtActivatedByAssetId(landAssetId)), false))
457+ then 3
458+ else 0
459+ ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, infraLevel, 4)) + fraction(DAILYRESBYPIECE, presaleBonus, 20))
460+ }
461+
462+
463+func claimAll (landAssetId,pieces) = {
464+ let timeKey = keyStakedTimeByAssetId(landAssetId)
465+ let savedTime = valueOrErrorMessage(getInteger(timeKey), (((LANDPREFIX + " ") + landAssetId) + " is not staked"))
466+ let deltaTime = (lastBlock.timestamp - savedTime)
467+ if ((0 > deltaTime))
468+ then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
469+ else {
470+ let dailyProductionByPiece = applyBonuses(landAssetId)
471+ let availRes = (fraction(deltaTime, dailyProductionByPiece, DAYMILLIS) * pieces)
472+ asString(invoke(this, "claimRes", [availRes, landAssetId], nil))
473+ }
474+ }
475+
476+
454477 func upInfraCommon (shouldUseMat,caller,landAssetId) = {
455478 let addr = toString(caller)
456479 let infraKey = keyInfraLevelByAssetId(landAssetId)
457480 let curLevel = valueOrElse(getInteger(infraKey), 0)
458481 if ((curLevel >= 3))
459482 then throw("Currently max infrastructure level = 3")
460483 else {
461484 let newLevel = (curLevel + 1)
462485 let asset = value(assetInfo(fromBase58String(landAssetId)))
463486 if (!(contains(asset.name, LANDPREFIX)))
464487 then throw((("NFT " + LANDPREFIX) + " token should be passed as param"))
465488 else {
466- let timeKey = keyStakedTimeByAssetId(landAssetId)
467489 let owner = getStringValue(keyLandAssetIdToOwner(landAssetId))
468490 if ((owner != addr))
469491 then throw((LANDPREFIX + " is not yours"))
470492 else {
471493 let d = split(asset.description, "_")
472494 let landSize = d[recLandSize]
473495 let pieces = numPiecesBySize(landSize)
474496 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
475497 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
476498 let loc = split(value(curLocation), "_")
477499 if ((loc[locIdxType] != "L"))
478500 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
479501 else if ((loc[locIdxId] != landAssetId))
480502 then throw(((("Duck location id is " + loc[locIdxId]) + ", but should be ") + landAssetId))
481503 else {
482504 let bpKey = keyBackpackByDuck(duckAssetId)
483505 let currentPack = getBackpack(bpKey)
484506 let mList = split(currentPack[bpIdxMat], "_")
485507 let newMat = makeString(subtractMaterials(shouldUseMat, mList, fraction(InfraUpgradeCostS, (pieces * newLevel), 25)), "_")
486- let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
487- let deltaTime = (lastBlock.timestamp - savedTime)
488- if ((0 > deltaTime))
489- then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
490- else {
491- let availRes = (fraction(deltaTime, DAILYRESBYPIECE, DAYMILLIS) * pieces)
492- let newRes = asString(invoke(this, "claimRes", [availRes, landAssetId], nil))
493- $Tuple2([IntegerEntry(infraKey, newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], newRes, newMat, currentPack[bpIdxProd]], ":"))], newLevel)
494- }
508+ let newRes = claimAll(landAssetId, pieces)
509+ $Tuple2([IntegerEntry(infraKey, newLevel), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], newRes, newMat, currentPack[bpIdxProd]], ":"))], newLevel)
495510 }
496511 }
497512 }
498513 }
499- }
500-
501-
502-func applyBonuses (landAssetId) = {
503- let infraLevel = valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0)
504- let presaleBonus = if (valueOrElse(getBoolean(keypresaleArtActivatedByAssetId(landAssetId)), false))
505- then 3
506- else 0
507- ((DAILYRESBYPIECE + fraction(DAILYRESBYPIECE, infraLevel, 4)) + fraction(DAILYRESBYPIECE, presaleBonus, 20))
508514 }
509515
510516
511517 @Callable(i)
512518 func stakeLand () = {
513519 let pmt = value(i.payments[0])
514520 let assetId = value(pmt.assetId)
515521 let address = toString(i.caller)
516522 if ((pmt.amount != 1))
517523 then throw((("NFT " + LANDPREFIX) + " token should be attached as payment"))
518524 else {
519525 let asset = value(assetInfo(assetId))
520526 if ((asset.issuer != this))
521527 then throw("Unknown issuer of token")
522528 else if (!(contains(asset.name, LANDPREFIX)))
523529 then throw((("Only NFT " + LANDPREFIX) + " tokens are accepted"))
524530 else {
525531 let landNumSize = drop(asset.name, 4)
526532 let landNum = if (contains(landNumSize, "XXL"))
527533 then dropRight(landNumSize, 3)
528534 else if (contains(landNumSize, "XL"))
529535 then dropRight(landNumSize, 2)
530536 else dropRight(landNumSize, 1)
531537 let landNumInt = valueOrErrorMessage(parseInt(landNum), ("Cannot parse land number from " + asset.name))
532538 let landAssetId = toBase58String(assetId)
533539 let timeKey = keyStakedTimeByAssetId(landAssetId)
534540 if (isDefined(getInteger(timeKey)))
535541 then throw((("NFT " + asset.name) + " is already staked"))
536542 else {
537543 let d = split(asset.description, "_")
538544 let terrainCounts = countTerrains(d[recTerrains])
539545 let props = updateProportions(terrainCounts, (numPiecesBySize(d[recLandSize]) / 25), 1)
540546 let presaleActive = if ((500 >= landNumInt))
541547 then (lastBlock.timestamp > PresaleArtifactActivationTime)
542548 else false
543549 [IntegerEntry(timeKey, lastBlock.timestamp), BooleanEntry(keypresaleArtActivatedByAssetId(landAssetId), presaleActive), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address), lastBlock.timestamp), StringEntry(keyLandAssetIdToOwner(landAssetId), address), StringEntry(keyLandNumToOwner(landNum), address), StringEntry(keyResProportions(), props)]
544550 }
545551 }
546552 }
547553 }
548554
549555
550556
551557 @Callable(i)
552558 func unstakeLand (landAssetId) = if ((size(i.payments) != 0))
553559 then throw("unstake doesn't require any payments")
554560 else {
555561 let assetId = fromBase58String(landAssetId)
556562 let address = toString(i.caller)
557563 let asset = value(assetInfo(assetId))
558564 if ((asset.issuer != this))
559565 then throw("Unknown issuer of token")
560566 else if (!(contains(asset.name, LANDPREFIX)))
561567 then throw((("Only NFT " + LANDPREFIX) + " tokens can be unstaked"))
562568 else {
563569 let timeKey = keyStakedTimeByAssetId(landAssetId)
564570 if (!(isDefined(timeKey)))
565571 then throw((("NFT " + asset.name) + " is not staked"))
566572 else {
567573 let owner = valueOrErrorMessage(getString(keyLandAssetIdToOwner(landAssetId)), (("NFT " + asset.name) + " is orphaned"))
568574 if ((owner != address))
569- then throw("Staked NFT is not yours")
575+ then throw((("Staked " + LANDPREFIX) + " is not yours"))
570576 else {
571577 let d = split(asset.description, "_")
572578 let terrainCounts = countTerrains(d[recTerrains])
573- let props = updateProportions(terrainCounts, (numPiecesBySize(d[recLandSize]) / 25), -1)
574-[ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address)), StringEntry(keyResProportions(), props)]
579+ let pieces = numPiecesBySize(d[recLandSize])
580+ let props = updateProportions(terrainCounts, (pieces / 25), -1)
581+ let newRes = claimAll(landAssetId, pieces)
582+ let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(address)), (("You can't unstake " + LANDPREFIX) + " without a duck staked"))
583+ let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
584+ let loc = split(value(curLocation), "_")
585+ if ((loc[locIdxType] != "L"))
586+ then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
587+ else if ((loc[locIdxId] != landAssetId))
588+ then throw(((("Duck location id is " + loc[locIdxId]) + ", but should be ") + landAssetId))
589+ else {
590+ let bpKey = keyBackpackByDuck(duckAssetId)
591+ let currentPack = getBackpack(bpKey)
592+[ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, address)), StringEntry(keyResProportions(), props), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], newRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], ":"))]
593+ }
575594 }
576595 }
577596 }
578597 }
579598
580599
581600
582601 @Callable(i)
583602 func stakeDuck () = {
584603 let pmt = value(i.payments[0])
585604 let assetId = value(pmt.assetId)
586605 let address = toString(i.caller)
587606 if ((pmt.amount != 1))
588607 then throw((("NFT " + DUCKPREFIX) + " token should be attached as payment"))
589608 else {
590609 let asset = value(assetInfo(assetId))
591610 if (if ((asset.issuer != incubatorAddr))
592611 then (asset.issuer != breederAddr)
593612 else false)
594613 then throw((("Unknown issuer of " + DUCKPREFIX) + " token"))
595614 else if (!(contains(asset.name, DUCKPREFIX)))
596615 then throw((("Only NFT " + DUCKPREFIX) + " tokens are accepted"))
597616 else {
598617 let assetIdStr = toBase58String(assetId)
599618 let timeKey = keyStakedTimeByAssetId(assetIdStr)
600619 if (isDefined(getInteger(timeKey)))
601620 then throw((("NFT " + asset.name) + " is already staked"))
602621 else if (isDefined(getString(keyStakedDuckByOwner(address))))
603622 then throw(("You already staked one duck: " + asset.name))
604623 else {
605624 let locKey = keyDuckLocation(assetIdStr)
606625 let location = getString(locKey)
607626 let keyHealth = keyDuckHealth(assetIdStr)
608627 let health = getInteger(keyHealth)
609628 let bpKey = keyBackpackByDuck(assetIdStr)
610629 let backpack = getString(bpKey)
611630 ([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, toBase58String(assetId), address), lastBlock.timestamp), StringEntry(keyDuckIdToOwner(assetIdStr), address), StringEntry(keyStakedDuckByOwner(address), assetIdStr)] ++ (if (isDefined(location))
612631 then nil
613632 else ([StringEntry(locKey, DEFAULTLOCATION)] ++ (if (isDefined(health))
614633 then nil
615634 else ([IntegerEntry(keyHealth, 100)] ++ (if (isDefined(backpack))
616635 then nil
617636 else [StringEntry(bpKey, "0:0_0_0_0_0_0:0_0_0_0_0_0:")]))))))
618637 }
619638 }
620639 }
621640 }
622641
623642
624643
625644 @Callable(i)
626645 func unstakeDuck (assetIdStr) = if ((size(i.payments) != 0))
627646 then throw("unstake doesn't require any payments")
628647 else {
629648 let assetId = fromBase58String(assetIdStr)
630649 let address = toString(i.caller)
631650 let asset = value(assetInfo(assetId))
632651 if (if ((asset.issuer != incubatorAddr))
633652 then (asset.issuer != breederAddr)
634653 else false)
635654 then throw((("Unknown issuer of " + DUCKPREFIX) + " token"))
636655 else if (!(contains(asset.name, DUCKPREFIX)))
637656 then throw((("Only NFT " + DUCKPREFIX) + " tokens can be unstaked"))
638657 else {
639658 let timeKey = keyStakedTimeByAssetId(toBase58String(assetId))
640659 if (!(isDefined(timeKey)))
641660 then throw((("NFT " + asset.name) + " is not staked"))
642661 else if (!(isDefined(keyStakedDuckByOwner(address))))
643662 then throw((("The duck " + asset.name) + " is not staked"))
644663 else {
645664 let owner = valueOrErrorMessage(getString(keyDuckIdToOwner(toBase58String(assetId))), (("NFT " + asset.name) + " is orphaned"))
646665 if ((owner != address))
647666 then throw("Staked NFT is not yours")
648667 else [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(timeKey), DeleteEntry(keyDuckLocation(assetIdStr)), DeleteEntry(keyStakedTimeByTypeAssetIdAndOwner(DUCKPREFIX, assetIdStr, address)), DeleteEntry(keyStakedDuckByOwner(address))]
649668 }
650669 }
651670 }
652671
653672
654673
655674 @Callable(i)
656675 func claimRes (amount,landAssetId) = if ((size(i.payments) != 0))
657676 then throw("claimRes doesn't require any payments")
658677 else {
659678 let addr = toString(i.originCaller)
660679 let asset = value(assetInfo(fromBase58String(landAssetId)))
661680 if (!(contains(asset.name, LANDPREFIX)))
662681 then throw((("NFT " + LANDPREFIX) + " token should be passed as param"))
663682 else {
664683 let timeKey = keyStakedTimeByAssetId(landAssetId)
665684 let owner = getStringValue(keyLandAssetIdToOwner(landAssetId))
666685 if ((owner != addr))
667686 then throw((LANDPREFIX + " is not yours"))
668687 else {
669688 let d = split(asset.description, "_")
670689 let landSize = d[recLandSize]
671690 let terrainCounts = countTerrains(d[recTerrains])
672691 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(addr)), "You don't have a duck staked")
673692 let curLocation = valueOrElse(getString(keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
674693 let loc = split(value(curLocation), "_")
675694 if ((loc[locIdxType] != "L"))
676695 then throw((("Duck location type is " + loc[locIdxType]) + ", but should be L"))
677696 else if ((loc[locIdxId] != landAssetId))
678697 then throw(((("Duck location id is " + loc[locIdxId]) + ", but should be ") + landAssetId))
679698 else {
680699 let savedTime = valueOrErrorMessage(getInteger(timeKey), (("NFT " + asset.name) + " is not staked"))
681700 let deltaTime = (lastBlock.timestamp - savedTime)
682701 if ((0 > deltaTime))
683702 then throw(((("Saved timestamp is in future, saved = " + toString(savedTime)) + ", current = ") + toString(lastBlock.timestamp)))
684703 else {
685704 let pieces = numPiecesBySize(landSize)
686705 let dailyProductionByPiece = applyBonuses(landAssetId)
687706 let availRes = fraction(deltaTime, (dailyProductionByPiece * pieces), DAYMILLIS)
688707 if ((amount > availRes))
689708 then throw(((("Not enough resources, available = " + toString(availRes)) + ", requested = ") + toString(amount)))
690709 else {
691710 let newDeltaTime = fraction((availRes - amount), DAYMILLIS, (dailyProductionByPiece * pieces))
692711 let newTimestamp = (lastBlock.timestamp - newDeltaTime)
693712 let bpKey = keyBackpackByDuck(duckAssetId)
694713 let currentPack = getBackpack(bpKey)
695714 let currentRes = split(currentPack[bpIdxRes], "_")
696715 let bpRes = addRes(currentRes, terrainCounts, (deltaTime - newDeltaTime), (pieces / 25), dailyProductionByPiece)
697716 let newPack = makeString([currentPack[bpIdxLevel], bpRes, currentPack[bpIdxMat], currentPack[bpIdxProd]], ":")
698717 $Tuple2([StringEntry(bpKey, newPack), IntegerEntry(timeKey, newTimestamp), IntegerEntry(keyStakedTimeByTypeAssetIdAndOwner(LANDPREFIX, landAssetId, owner), newTimestamp)], bpRes)
699718 }
700719 }
701720 }
702721 }
703722 }
704723 }
705724
706725
707726
708727 @Callable(i)
709728 func flight (message,sig) = if (!(sigVerify_8Kb(message, sig, pub)))
710729 then throw("signature does not match")
711730 else if ((size(i.payments) != 0))
712731 then throw("flight doesn't require any payments")
713732 else {
714733 let parts = split(toUtf8String(message), ";")
715734 let hp = split(split(parts[0], "|")[0], "_")
716735 let curHP = parseIntValue(hp[0])
717736 let newHP = parseIntValue(hp[1])
718737 let newLocAndTime = split(parts[1], ":")
719738 let newLocation = newLocAndTime[0]
720739 let time = parseIntValue(newLocAndTime[1])
721740 if (if ((time > (lastBlock.timestamp + FIVEMINUTESMILLIS)))
722741 then true
723742 else ((lastBlock.timestamp - FIVEMINUTESMILLIS) > time))
724743 then throw("signature outdated")
725744 else {
726745 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
727746 let keyHealth = keyDuckHealth(duckAssetId)
728747 let oldFromState = valueOrElse(getInteger(keyHealth), 100)
729748 if ((oldFromState != curHP))
730749 then throw(((("oldHealth=" + toString(valueOrElse(getInteger(keyHealth), 100))) + " from state does not match one from flight log=") + toString(curHP)))
731750 else if ((0 >= curHP))
732751 then throw("You can't fly with zero health")
733752 else {
734753 let locKey = keyDuckLocation(duckAssetId)
735754 let curLocation = valueOrElse(getString(locKey), DEFAULTLOCATION)
736755 if ((newLocation == curLocation))
737756 then throw("You can't fly to the same location")
738757 else $Tuple2([StringEntry(locKey, if ((newHP > 0))
739758 then newLocation
740759 else curLocation), IntegerEntry(keyHealth, newHP)], unit)
741760 }
742761 }
743762 }
744763
745764
746765
747766 @Callable(i)
748767 func setHealth (health,duckAssetId) = if (if ((0 > health))
749768 then true
750769 else (health > 100))
751770 then throw("HP should be within 0..100")
752771 else [IntegerEntry(keyDuckHealth(duckAssetId), health)]
753772
754773
755774
756775 @Callable(i)
757776 func heal (matType,amount) = if (if ((0 > matType))
758777 then true
759778 else (matType >= NUMRES))
760779 then throw(("Unknown material: " + toString(matType)))
761780 else if ((0 >= amount))
762781 then throw(("Amount should be positive! " + toString(amount)))
763782 else {
764783 let duckAssetId = valueOrErrorMessage(getString(keyStakedDuckByOwner(toString(i.caller))), "You don't have a duck staked")
765784 let keyHealth = keyDuckHealth(duckAssetId)
766785 let oldHealth = valueOrElse(getInteger(keyHealth), 100)
767786 if ((oldHealth >= 100))
768787 then throw("HP should be < 100 to heal")
769788 else {
770789 let bpKey = keyBackpackByDuck(duckAssetId)
771790 let currentPack = getBackpack(bpKey)
772791 let mList = split(currentPack[bpIdxMat], "_")
773792 let currentAmount = parseIntValue(mList[matType])
774793 let deltaHealth = min([(amount / HEALCOST), (100 - oldHealth)])
775794 let spendAmount = (deltaHealth * HEALCOST)
776795 if ((spendAmount > currentAmount))
777796 then throw(((((("You need " + toString(spendAmount)) + " of ") + matTypes[matType]) + " to heal, but you backpack contains ") + toString(currentAmount)))
778797 else {
779798 let newMat = subOneInList(mList, matType, spendAmount)
780799 [IntegerEntry(keyHealth, (oldHealth + deltaHealth)), StringEntry(bpKey, makeString([currentPack[bpIdxLevel], currentPack[bpIdxRes], newMat, currentPack[bpIdxProd]], ":"))]
781800 }
782801 }
783802 }
784803
785804
786805
787806 @Callable(i)
788807 func updateBackpack (duckAssetId,newPack) = if ((i.caller != economyAddr))
789808 then throw("permission denied")
790809 else $Tuple2([StringEntry(keyBackpackByDuck(duckAssetId), newPack)], newPack)
791810
792811
793812
794813 @Callable(i)
795814 func expeditionBuy (message,sig) = if ((size(i.payments) != 1))
796815 then throw("Exactly one payment required")
797816 else {
798817 let pmt = value(i.payments[0])
799818 if ((pmt.assetId != usdnAssetId))
800819 then throw("Allowed USDN payment only!")
801820 else if ((pmt.amount != EXPUSDN))
802821 then throw(("Payment attached should be " + toString(EXPUSDN)))
803822 else expeditionCommon(false, i.caller, i.transactionId, message, sig)
804823 }
805824
806825
807826
808827 @Callable(i)
809828 func expedition (message,sig) = if ((size(i.payments) != 0))
810829 then throw("expedition doesn't require any payments")
811830 else expeditionCommon(true, i.caller, i.transactionId, message, sig)
812831
813832
814833
815834 @Callable(i)
816835 func upgradeInfra (landAssetId) = if ((size(i.payments) != 0))
817836 then throw("Infrastructure upgrade doesn't require any payments")
818837 else upInfraCommon(true, i.caller, landAssetId)
819838
820839
821840
822841 @Callable(i)
823842 func upgradeInfraUsdn (landAssetId) = if ((size(i.payments) != 1))
824843 then throw("Exactly one payment required")
825844 else {
826845 let pmt = value(i.payments[0])
827846 if ((pmt.assetId != usdnAssetId))
828847 then throw("Allowed USDN payment only!")
829848 else {
830849 let newLevel = (valueOrElse(getInteger(keyInfraLevelByAssetId(landAssetId)), 0) + 1)
831850 let asset = value(assetInfo(fromBase58String(landAssetId)))
832851 let d = split(asset.description, "_")
833852 let cost = fraction(InfraUpgradeCostSUsdn, (numPiecesBySize(d[recLandSize]) * newLevel), 25)
834853 if ((pmt.amount != cost))
835854 then throw(("Payment attached should be " + toString(cost)))
836855 else upInfraCommon(false, i.caller, landAssetId)
837856 }
838857 }
839858
840859

github/deemru/w8io/c3f4982 
83.37 ms