tx · 8ZEdvgUApGJyayBBLykckYVwvowotejjpMVn5GnxwmwK

3N3nfqFcxXfd3T18V9icDdh58MJ9wQ2k2xx:  -0.01600000 Waves

2023.09.06 14:15 [2743441] smart account 3N3nfqFcxXfd3T18V9icDdh58MJ9wQ2k2xx > SELF 0.00000000 Waves

{ "type": 13, "id": "8ZEdvgUApGJyayBBLykckYVwvowotejjpMVn5GnxwmwK", "fee": 1600000, "feeAssetId": null, "timestamp": 1693998936511, "version": 2, "chainId": 84, "sender": "3N3nfqFcxXfd3T18V9icDdh58MJ9wQ2k2xx", "senderPublicKey": "UGqkWsCpv7xRVXkQRXyLd6pWPDtYGXmPip7FxSd1pAu", "proofs": [ "4W7sszk1BJjx7dXAtNBZQ25tnSbKvFGv9FKPvHiETPJTjbiiQxmDAaZA8ZRPPht18dgqZidrBewusMjF5EhJUAKk" ], "script": "base64:BgIkCAISBwoFAQEBAQESABIAEgQKAggBEgMKAQESAwoBARIDCgEBOQAPREVGQVVMVExPQ0FUSU9OAg9BZnJpY2FfRl9BZnJpY2EAD2xvY0lkeENvbnRpbmVudAAAAApsb2NJZHhUeXBlAAEBFGtleVN0YWtlZER1Y2tCeU93bmVyAQlvd25lckFkZHIJAKwCAgISc3Rha2VkRHVja0J5T3duZXJfBQlvd25lckFkZHIBD2tleUR1Y2tMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgINZHVja0xvY2F0aW9uXwULZHVja0Fzc2V0SWQADWxhc3RUb3VySWRLZXkCDiVzX19sYXN0VG91cklkARVrZXlUb3VyU3RhdGljRGF0YUJ5SWQBA3RJZAkArAICAhYlcyVkX190b3VyU3RhdGljRGF0YV9fCQCkAwEFA3RJZAEWa2V5VG91ckR5bmFtaWNEYXRhQnlJZAEDdElkCQCsAgICFyVzJWRfX3RvdXJEeW5hbWljRGF0YV9fCQCkAwEFA3RJZAETa2V5U2NvcmVCb2FyZEJ5VG91cgEDdElkCQCsAgICEiVzJWRfX3Njb3JlQm9hcmRfXwkApAMBBQN0SWQBEmtleVN1bVNjb3Jlc0J5VG91cgEDdElkCQCsAgICESVzJWRfX3N1bVNjb3Jlc19fCQCkAwEFA3RJZAEWa2V5VW5wYWlkUmV3YXJkc0J5VG91cgEDdElkCQCsAgICFSVzJWRfX3VucGFpZFJld2FyZHNfXwkApAMBBQN0SWQBG2tleUxhc3RSZWdpc3RlcmVkVG91ckJ5RHVjawELZHVja0Fzc2V0SWQJAKwCAgIgJXMlc19fbGFzdFJlZ2lzdGVyZWRUb3VyQnlEdWNrX18FC2R1Y2tBc3NldElkARxrZXlJc1JlZ2lzdGVyZWRCeVRvdXJBbmREdWNrAgN0SWQLZHVja0Fzc2V0SWQJALkJAgkAzAgCAiElcyVkJXNfX2lzUmVnaXN0ZXJlZEJ5VG91ckFuZER1Y2sJAMwIAgkApAMBBQN0SWQJAMwIAgULZHVja0Fzc2V0SWQFA25pbAICX18BGWtleUlzQXdhcmRlZEJ5VG91ckFuZER1Y2sCA3RJZAtkdWNrQXNzZXRJZAkAuQkCCQDMCAICHiVzJWQlc19faXNBd2FyZGVkQnlUb3VyQW5kRHVjawkAzAgCCQCkAwEFA3RJZAkAzAgCBQtkdWNrQXNzZXRJZAUDbmlsAgJfXwEba2V5TGFzdEF0dGVtcHRCeVRvdXJBbmREdWNrAgN0SWQLZHVja0Fzc2V0SWQJALkJAgkAzAgCAiAlcyVkJXNfX2xhc3RBdHRlbXB0QnlUb3VyQW5kRHVjawkAzAgCCQCkAwEFA3RJZAkAzAgCBQtkdWNrQXNzZXRJZAUDbmlsAgJfXwEaa2V5QmVzdFJlc3VsdEJ5VG91ckFuZER1Y2sCA3RJZAtkdWNrQXNzZXRJZAkAuQkCCQDMCAICHyVzJWQlc19fYmVzdFJlc3VsdEJ5VG91ckFuZER1Y2sJAMwIAgkApAMBBQN0SWQJAMwIAgULZHVja0Fzc2V0SWQFA25pbAICX18ACWlkeFN0YXRpYwAAAAppZHhEeW5hbWljAAEAE3RTdGF0aWNSZWdpc3RlckNvc3QAAgASdFN0YXRpY0F0dGVtcHRDb3N0AAMADHRTdGF0aWNTdGFydAAFAAp0U3RhdGljRW5kAAYAEHRTdGF0aWNOdW1HcmFuZHMABwAOdER5bmFtaWNTdGF0dXMAAQAPdER5bmFtaWNMZWFkZXJzAAIAEXREeW5hbWljV2luUmVzdWx0AAMAFXREeW5hbWljVG90YWxSZWdDb3VudAAEABV0RHluYW1pY1RvdGFsQXR0ZW1wdHMABQELZ2V0VG91ckRhdGECDHRvdXJDb250cmFjdAN0SWQEBnN0YXRpYwkAtQkCCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUMdG91ckNvbnRyYWN0CQEVa2V5VG91clN0YXRpY0RhdGFCeUlkAQUDdElkCQCsAgIJAKwCAgIZRXJyb3IgcmVhZGluZyB0b3VybmFtZW50IAkApAMBBQN0SWQCBSBkYXRhAgJfXwQHZHluYW1pYwkAvAkCCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUMdG91ckNvbnRyYWN0CQEWa2V5VG91ckR5bmFtaWNEYXRhQnlJZAEFA3RJZAkArAICCQCsAgICGUVycm9yIHJlYWRpbmcgdG91cm5hbWVudCAJAKQDAQUDdElkAgUgZGF0YQICX18JAMwIAgUGc3RhdGljCQDMCAIFB2R5bmFtaWMFA25pbAEOaXNJblRvdXJuYW1lbnQCDHRvdXJDb250cmFjdAhsb2NhdGlvbgQGbGFzdElkCQELdmFsdWVPckVsc2UCCQCaCAIFDHRvdXJDb250cmFjdAUNbGFzdFRvdXJJZEtleQAABANsb2MJALUJAgUIbG9jYXRpb24CAV8EA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEBXREYXRhCQELZ2V0VG91ckRhdGECBQx0b3VyQ29udHJhY3QFBmxhc3RJZAQGc3RhdGljCQCRAwIFBXREYXRhBQlpZHhTdGF0aWMEB2R5bmFtaWMJAJEDAgUFdERhdGEFCmlkeER5bmFtaWMDAwMJAAACCQCRAwIFA2xvYwUKbG9jSWR4VHlwZQIBVAkAAAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNsb2MFD2xvY0lkeENvbnRpbmVudAUGbGFzdElkBwkAAAIJAJEDAgUHZHluYW1pYwUOdER5bmFtaWNTdGF0dXMCCklOUFJPR1JFU1MHCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUKdFN0YXRpY0VuZAUDbm93BwAFY2hhaW4JAMkBAgkAygECCAUEdGhpcwVieXRlcwABAAEAFWRlZmF1bHRSZXN0QWRkcmVzc1N0cgQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAIjM1BRQ3V2RmJ2aDRMa1BVbnJuVTF6M2puYkExcDltM1dOaHYDCQAAAgEBVAUHJG1hdGNoMAIjM011bWtHR3p0Q0tBWHBXRHF4a2Rkb2ZxWFNVYnFRa3ZTSnkJAAIBAg1Vbmtub3duIGNoYWluAANTRVACAl9fAQ9nZXRTdHJpbmdPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFB2FkZHJlc3MJAMwIAgIBLgkAzAgCBQNrZXkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAARSWR4Q2ZnU3Rha2luZ0RhcHAAAQANSWR4Q2ZnV2xnRGFwcAAEAQprZXlSZXN0Q2ZnAAIOJXNfX3Jlc3RDb25maWcBDmtleVJlc3RBZGRyZXNzAAIMJXNfX3Jlc3RBZGRyARFyZWFkUmVzdENmZ09yRmFpbAEEcmVzdAkAvAkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUEcmVzdAkBCmtleVJlc3RDZmcABQNTRVABGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIHcmVzdENmZwNpZHgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFB3Jlc3RDZmcFA2lkeAkArAICAipSZXN0IGNmZyBkb2Vzbid0IGNvbnRhaW4gYWRkcmVzcyBhdCBpbmRleCAJAKQDAQUDaWR4AAxyZXN0Q29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBDmtleVJlc3RBZGRyZXNzAAUVZGVmYXVsdFJlc3RBZGRyZXNzU3RyAAdyZXN0Q2ZnCQERcmVhZFJlc3RDZmdPckZhaWwBBQxyZXN0Q29udHJhY3QAD3N0YWtpbmdDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFEUlkeENmZ1N0YWtpbmdEYXBwAAt3bGdDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFB3Jlc3RDZmcFDUlkeENmZ1dsZ0RhcHAADXdsZ0Fzc2V0SWRLZXkCC3dsZ19hc3NldElkAAp3bGdBc3NldElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJwIAgULd2xnQ29udHJhY3QFDXdsZ0Fzc2V0SWRLZXkCE05vdCBpbml0aWFsaXplZCB5ZXQBCGFzU3RyaW5nAQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAUBcwkAAgECGGZhaWwgdG8gY2FzdCBpbnRvIFN0cmluZwEFYXNJbnQBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIDSW50BAFuBQckbWF0Y2gwBQFuCQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AQpmaXhlZFBvaW50AgN2YWwIZGVjaW1hbHMEBnRlblBvdwkAbAYACgAABQhkZWNpbWFscwAAAAAFBERPV04EB2xvd1BhcnQJAKQDAQkAagIFA3ZhbAUGdGVuUG93BAZ6ZXJvZXMJALACAgkApAMBBQZ0ZW5Qb3cJAGQCAAEJALECAQUHbG93UGFydAkArAICCQCsAgIJAKwCAgkApAMBCQBpAgUDdmFsBQZ0ZW5Qb3cCAS4FBnplcm9lcwUHbG93UGFydAEEcGFkTAIDdmFsA2xlbgQEdmFsUwkApAMBBQN2YWwEBnplcm9lcwkAsAICCQCkAwEJAGwGAAoAAAkAZQIFA2xlbgkAsQIBBQR2YWxTAAAAAAUERE9XTgABCQCsAgIFBnplcm9lcwUEdmFsUwATTUFYVE9VUk5BTUVOVExFTkdUSACAmP/NAQAESE9VUgCA3dsBAAphZG1pbnNMaXN0CQDMCAIJAKUIAQUEdGhpcwkAzAgCBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAiMzUEVlMlJFTFVIQ0ZDQnNtU0NOY0JKOE4zVVJMVlFlbmRlNwMJAAACAQFUBQckbWF0Y2gwAiMzTXRCZ0pUYUx4UEIzQzdVSkQxVUU4cWprSHRoZkt2RlFZWQkAAgECDVVua25vd24gY2hhaW4FA25pbAEKc3RhdGljRGF0YQcEdHhJZAxyZWdpc3RlckNvc3QLYXR0ZW1wdENvc3QMY3JlYXRpb25UaW1lCXN0YXJ0VGltZQdlbmRUaW1lCW51bUdyYW5kcwkAuQkCCQDMCAICDiVzJWQlZCVkJWQlZCVkCQDMCAIFBHR4SWQJAMwIAgkApAMBBQxyZWdpc3RlckNvc3QJAMwIAgkApAMBBQthdHRlbXB0Q29zdAkAzAgCCQCkAwEFDGNyZWF0aW9uVGltZQkAzAgCCQCkAwEFCXN0YXJ0VGltZQkAzAgCCQCkAwEFB2VuZFRpbWUJAMwIAgkApAMBBQludW1HcmFuZHMFA25pbAUDU0VQAQtkeW5hbWljRGF0YQUGc3RhdHVzB2xlYWRlcnMJd2luUmVzdWx0CXRvdGFsUmVncw10b3RhbEF0dGVtcHRzCQC6CQIJAMwIAgIKJXMlcyVkJWQlZAkAzAgCBQZzdGF0dXMJAMwIAgUHbGVhZGVycwkAzAgCCQCkAwEFCXdpblJlc3VsdAkAzAgCCQCkAwEFCXRvdGFsUmVncwkAzAgCCQCkAwEFDXRvdGFsQXR0ZW1wdHMFA25pbAUDU0VQAQZwcm9sb2cACQEFYXNJbnQBCQD8BwQFD3N0YWtpbmdDb250cmFjdAIKc2F2ZUxhc3RUeAUDbmlsBQNuaWwBDGR1Y2tCeUNhbGxlcgEGY2FsbGVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPc3Rha2luZ0NvbnRyYWN0CQEUa2V5U3Rha2VkRHVja0J5T3duZXIBCQClCAEFBmNhbGxlcgIcWW91IGRvbid0IGhhdmUgYSBkdWNrIHN0YWtlZAcBaQEQY3JlYXRlVG91cm5hbWVudAUJc3RhcnRUaW1lB2VuZFRpbWUMcmVnaXN0ZXJDb3N0C2F0dGVtcHRDb3N0CW51bUdyYW5kcwQGY2FsbGVyCQClCAEIBQFpBmNhbGxlcgMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIFCmFkbWluc0xpc3QFBmNhbGxlcgkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAZsYXN0SWQJAJ8IAQUNbGFzdFRvdXJJZEtleQQDdElkAwkBCWlzRGVmaW5lZAEFBmxhc3RJZAQKbGFzdFRvdXJJZAkBBXZhbHVlAQUGbGFzdElkBAdkeW5hbWljCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFmtleVRvdXJEeW5hbWljRGF0YUJ5SWQBBQpsYXN0VG91cklkCQCsAgIJAKwCAgIZRXJyb3IgcmVhZGluZyB0b3VybmFtZW50IAkApAMBBQpsYXN0VG91cklkAgUgZGF0YQQGc3RhdHVzCQCRAwIJALUJAgUHZHluYW1pYwUDU0VQBQ50RHluYW1pY1N0YXR1cwMJAQIhPQIFBnN0YXR1cwIIQVJDSElWRUQJAAIBCQCsAgICLEN1cnJlbnQgdG91cm5lbWVudCBpcyBub3QgY29tcGxldGVkLCBzdGF0dXM9BQZzdGF0dXMJAGQCBQpsYXN0VG91cklkAAEAAQQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAMJAGYCBQNub3cFCXN0YXJ0VGltZQkAAgEJAKwCAgkArAICCQCsAgICCnN0YXJ0VGltZT0JAKQDAQUJc3RhcnRUaW1lAhAgPCBjcmVhdGlvblRpbWU9CQCkAwEFA25vdwMJAGYCBQlzdGFydFRpbWUFB2VuZFRpbWUJAAIBCQCsAgIJAKwCAgkArAICAghlbmRUaW1lPQkApAMBBQdlbmRUaW1lAg0gPCBzdGFydFRpbWU9CQCkAwEFCXN0YXJ0VGltZQMJAGYCCQBlAgUHZW5kVGltZQUJc3RhcnRUaW1lBRNNQVhUT1VSTkFNRU5UTEVOR1RICQACAQkArAICCQCsAgIJAKwCAgIfVG91cm5hbWVudCBwZXJpb2QgZXhjZWVkcyBtYXg6IAkApAMBCQBlAgUHZW5kVGltZQUJc3RhcnRUaW1lAgMgPiAJAKQDAQUTTUFYVE9VUk5BTUVOVExFTkdUSAMDCQBnAgAABQxyZWdpc3RlckNvc3QGCQBnAgAABQthdHRlbXB0Q29zdAkAAgEJAKwCAgkArAICCQCsAgICJENvc3Qgc2hvdWxkIGJlIHBvc2l0aXZlLCBidXQgcGFzc2VkIAkApAMBBQxyZWdpc3RlckNvc3QCBSBhbmQgCQCkAwEFC2F0dGVtcHRDb3N0AwkAZgIAAAUJbnVtR3JhbmRzCQACAQItTnVtYmVyIG9mIEdyYW5kIFByaXplcyBzaG91bGQgYmUgbm9uLW5lZ2F0aXZlCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFDWxhc3RUb3VySWRLZXkFA3RJZAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5VG91clN0YXRpY0RhdGFCeUlkAQUDdElkCQEKc3RhdGljRGF0YQcJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAUMcmVnaXN0ZXJDb3N0BQthdHRlbXB0Q29zdAUDbm93BQlzdGFydFRpbWUFB2VuZFRpbWUFCW51bUdyYW5kcwkAzAgCCQELU3RyaW5nRW50cnkCCQEWa2V5VG91ckR5bmFtaWNEYXRhQnlJZAEFA3RJZAkBC2R5bmFtaWNEYXRhBQIHQ1JFQVRFRAIBIAAAAAAAAAUDbmlsBQN0SWQBaQEIcmVnaXN0ZXIABAxwcm9sb2dSZXN1bHQJAQZwcm9sb2cAAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEBndsZ0FtdAgFA3BtdAZhbW91bnQECnBtdEFzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAggFA3BtdAdhc3NldElkAhVXTEdPTEQgcGF5bWVudHMgb25seSEDCQECIT0CBQpwbXRBc3NldElkBQp3bGdBc3NldElkCQACAQIVV0xHT0xEIHBheW1lbnRzIG9ubHkhBAZsYXN0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQ1sYXN0VG91cklkS2V5AhVObyBhY3RpdmUgdG91cm5hbWVudHMEA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEBXREYXRhCQELZ2V0VG91ckRhdGECBQR0aGlzBQZsYXN0SWQEBnN0YXRpYwkAkQMCBQV0RGF0YQUJaWR4U3RhdGljBAdkeW5hbWljCQCRAwIFBXREYXRhBQppZHhEeW5hbWljBAZzdGF0dXMJAJEDAgUHZHluYW1pYwUOdER5bmFtaWNTdGF0dXMDCQEBIQEDAwMJAAACBQZzdGF0dXMCB0NSRUFURUQJAGYCBQNub3cJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFDHRTdGF0aWNTdGFydAcJAGYCCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUKdFN0YXRpY0VuZAUESE9VUgUDbm93BwYDCQAAAgUGc3RhdHVzAgpJTlBST0dSRVNTCQBmAgkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFCnRTdGF0aWNFbmQFBEhPVVIFA25vdwcJAAIBAhNDYW5ub3QgcmVnaXN0ZXIgbm93BAdyZWdDb3N0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRN0U3RhdGljUmVnaXN0ZXJDb3N0AwkBAiE9AgUGd2xnQW10BQdyZWdDb3N0CQACAQkArAICCQCsAgICEE5lZWQgcGF5bWVudCBvZiAJAQpmaXhlZFBvaW50AgUHcmVnQ29zdAAIAgcgV0xHT0xEBAtkdWNrQXNzZXRJZAkBDGR1Y2tCeUNhbGxlcgEIBQFpDG9yaWdpbkNhbGxlcgQNb2xkU2NvcmVCb2FyZAkBC3ZhbHVlT3JFbHNlAgkAoggBCQETa2V5U2NvcmVCb2FyZEJ5VG91cgEFBmxhc3RJZAIAAwMJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBHGtleUlzUmVnaXN0ZXJlZEJ5VG91ckFuZER1Y2sCBQZsYXN0SWQFC2R1Y2tBc3NldElkBwYJAQhjb250YWlucwIFDW9sZFNjb3JlQm9hcmQFC2R1Y2tBc3NldElkCQACAQkArAICCQCsAgIJAKwCAgIKWW91ciBkdWNrIAULZHVja0Fzc2V0SWQCJSBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQgYXQgdG91cm5hbWVudCAJAKQDAQUGbGFzdElkBBJ1cGRhdGVkRHluYW1pY0RhdGEJAQtkeW5hbWljRGF0YQUCCklOUFJPR1JFU1MJAJEDAgUHZHluYW1pYwUPdER5bmFtaWNMZWFkZXJzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwURdER5bmFtaWNXaW5SZXN1bHQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbFJlZ0NvdW50AAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRV0RHluYW1pY1RvdGFsQXR0ZW1wdHMJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBG2tleUxhc3RSZWdpc3RlcmVkVG91ckJ5RHVjawEFC2R1Y2tBc3NldElkBQZsYXN0SWQJAMwIAgkBDEJvb2xlYW5FbnRyeQIJARxrZXlJc1JlZ2lzdGVyZWRCeVRvdXJBbmREdWNrAgUGbGFzdElkBQtkdWNrQXNzZXRJZAYJAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2tleVNjb3JlQm9hcmRCeVRvdXIBBQZsYXN0SWQDCQAAAgUNb2xkU2NvcmVCb2FyZAIACQCsAgIFC2R1Y2tBc3NldElkAgQ6MDAwCQCsAgIJAKwCAgkArAICBQ1vbGRTY29yZUJvYXJkAgFfBQtkdWNrQXNzZXRJZAIEOjAwMAkAzAgCCQELU3RyaW5nRW50cnkCCQEWa2V5VG91ckR5bmFtaWNEYXRhQnlJZAEFBmxhc3RJZAUSdXBkYXRlZER5bmFtaWNEYXRhBQNuaWwFDHByb2xvZ1Jlc3VsdAFpAQpuZXdBdHRlbXB0AAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAQLZHVja0Fzc2V0SWQJAQxkdWNrQnlDYWxsZXIBCAUBaQxvcmlnaW5DYWxsZXIEBmxhc3RJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFDWxhc3RUb3VySWRLZXkCFU5vIGFjdGl2ZSB0b3VybmFtZW50cwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFBHRoaXMFBmxhc3RJZAQGc3RhdGljCQCRAwIFBXREYXRhBQlpZHhTdGF0aWMEB2R5bmFtaWMJAJEDAgUFdERhdGEFCmlkeER5bmFtaWMEBnN0YXR1cwkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwMJAQEhAQMJAAACBQZzdGF0dXMCCklOUFJPR1JFU1MJAGYCCQBlAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUKdFN0YXRpY0VuZAUESE9VUgUDbm93BwkAAgECF0F0dGVtcHQgaXMgbm90IHBvc3NpYmxlAwkBASEBCQELdmFsdWVPckVsc2UCCQCgCAEJARxrZXlJc1JlZ2lzdGVyZWRCeVRvdXJBbmREdWNrAgUGbGFzdElkBQtkdWNrQXNzZXRJZAcJAAIBCQCsAgIJAKwCAgkArAICAgpZb3VyIGR1Y2sgBQtkdWNrQXNzZXRJZAIhIGlzIG5vdCByZWdpc3RlcmVkIGF0IHRvdXJuYW1lbnQgCQCkAwEFBmxhc3RJZAQTYXR0ZW1wdHNJdGVyYXRvcktleQkBG2tleUxhc3RBdHRlbXB0QnlUb3VyQW5kRHVjawIFBmxhc3RJZAULZHVja0Fzc2V0SWQEC2xhc3RBdHRlbXB0CQCfCAEFE2F0dGVtcHRzSXRlcmF0b3JLZXkECyR0MDYxMDQ2NzM2AwkBASEBCQEJaXNEZWZpbmVkAQULbGFzdEF0dGVtcHQJAJQKAgAAAAADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAiJleGFjdGx5IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQGd2xnQW10CAUDcG10BmFtb3VudAQKcG10QXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCAUDcG10B2Fzc2V0SWQCFVdMR09MRCBwYXltZW50cyBvbmx5IQMJAQIhPQIFCnBtdEFzc2V0SWQFCndsZ0Fzc2V0SWQJAAIBAhVXTEdPTEQgcGF5bWVudHMgb25seSEEB2F0dENvc3QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFEnRTdGF0aWNBdHRlbXB0Q29zdAMJAQIhPQIFBndsZ0FtdAUHYXR0Q29zdAkAAgEJAKwCAgkArAICAhBOZWVkIHBheW1lbnQgb2YgCQEKZml4ZWRQb2ludAIFB2F0dENvc3QACAIHIFdMR09MRAkAlAoCCQBkAgkBBXZhbHVlAQULbGFzdEF0dGVtcHQAAQABBA1wYXllZEF0dGVtcHRzCAULJHQwNjEwNDY3MzYCXzEECWluY3JlbWVudAgFCyR0MDYxMDQ2NzM2Al8yBBJ1cGRhdGVkRHluYW1pY0RhdGEJAQtkeW5hbWljRGF0YQUCCklOUFJPR1JFU1MJAJEDAgUHZHluYW1pYwUPdER5bmFtaWNMZWFkZXJzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwURdER5bmFtaWNXaW5SZXN1bHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRV0RHluYW1pY1RvdGFsUmVnQ291bnQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbEF0dGVtcHRzBQlpbmNyZW1lbnQEB3RvdXJMb2MJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhNpbml0RHVja1RvdXJBdHRlbXB0CQDMCAIFC2R1Y2tBc3NldElkBQNuaWwFA25pbAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRNhdHRlbXB0c0l0ZXJhdG9yS2V5BQ1wYXllZEF0dGVtcHRzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUGbGFzdElkBRJ1cGRhdGVkRHluYW1pY0RhdGEFA25pbAkAzAgCBQxwcm9sb2dSZXN1bHQJAMwIAgUNcGF5ZWRBdHRlbXB0cwkAzAgCBQd0b3VyTG9jBQNuaWwBaQEOc2F2ZUR1Y2tSZXN1bHQCC2R1Y2tBc3NldElkC2R1Y2tOZXdCZXN0AwkBAiE9AggFAWkGY2FsbGVyBQ9zdGFraW5nQ29udHJhY3QJAAIBAg1BY2Nlc3MgZGVuaWVkBAZsYXN0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQ1sYXN0VG91cklkS2V5AhVObyBhY3RpdmUgdG91cm5hbWVudHMEBXREYXRhCQELZ2V0VG91ckRhdGECBQR0aGlzBQZsYXN0SWQEBnN0YXRpYwkAkQMCBQV0RGF0YQUJaWR4U3RhdGljBAdkeW5hbWljCQCRAwIFBXREYXRhBQppZHhEeW5hbWljBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OBA1iZXN0UmVzdWx0S2V5CQEaa2V5QmVzdFJlc3VsdEJ5VG91ckFuZER1Y2sCBQZsYXN0SWQFC2R1Y2tBc3NldElkBAxzdW1TY29yZXNLZXkJARJrZXlTdW1TY29yZXNCeVRvdXIBBQZsYXN0SWQEDG9sZFN1bVNjb3JlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQxzdW1TY29yZXNLZXkAAAMJAQ5pc0luVG91cm5hbWVudAIFBHRoaXMFC2N1ckxvY2F0aW9uBAtkdWNrT2xkQmVzdAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ1iZXN0UmVzdWx0S2V5AAAECHNjb3JlS2V5CQETa2V5U2NvcmVCb2FyZEJ5VG91cgEFBmxhc3RJZAQNb2xkU2NvcmVCb2FyZAkBC3ZhbHVlT3JFbHNlAgkAoggBBQhzY29yZUtleQIABAskdDA4MjI5OTM5MAMJAGYCBQtkdWNrTmV3QmVzdAULZHVja09sZEJlc3QDCQEBIQEJAQhjb250YWlucwIFDW9sZFNjb3JlQm9hcmQFC2R1Y2tBc3NldElkCQACAQkArAICAhxzY29yZUJvYXJkIGRvZXMgbm90IGNvbnRhaW4gBQtkdWNrQXNzZXRJZAQHb2xkQmVzdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFEXREeW5hbWljV2luUmVzdWx0BAdsZWFkZXJzCQCRAwIFB2R5bmFtaWMFD3REeW5hbWljTGVhZGVycwQOb2xkTGVhZGVyc0xpc3QDAwkAAAIFB2xlYWRlcnMCAAYJAAACBQdsZWFkZXJzAgEgBQNuaWwJALwJAgUHbGVhZGVycwIBLAQObmV3TGVhZGVyc0xpc3QDCQBmAgULZHVja05ld0Jlc3QFB29sZEJlc3QJAMwIAgULZHVja0Fzc2V0SWQFA25pbAMDCQBmAgUHb2xkQmVzdAULZHVja05ld0Jlc3QGCQEPY29udGFpbnNFbGVtZW50AgUOb2xkTGVhZGVyc0xpc3QFC2R1Y2tBc3NldElkBQ5vbGRMZWFkZXJzTGlzdAkAzQgCBQ5vbGRMZWFkZXJzTGlzdAULZHVja0Fzc2V0SWQEEnVwZGF0ZWREeW5hbWljRGF0YQkBC2R5bmFtaWNEYXRhBQIKSU5QUk9HUkVTUwkAugkCBQ5uZXdMZWFkZXJzTGlzdAIBLAkAlgMBCQDMCAIFC2R1Y2tOZXdCZXN0CQDMCAIFB29sZEJlc3QFA25pbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxSZWdDb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxBdHRlbXB0cwQFcGFydHMJAL0JAgUNb2xkU2NvcmVCb2FyZAULZHVja0Fzc2V0SWQJAJUKAwkArAICCQCsAgIJAKwCAgkArAICCQCRAwIFBXBhcnRzAAAFC2R1Y2tBc3NldElkAgE6CQEEcGFkTAIFC2R1Y2tOZXdCZXN0AAMJALACAgkAkQMCBQVwYXJ0cwABAAQJAGUCCQBkAgUMb2xkU3VtU2NvcmVzBQtkdWNrTmV3QmVzdAULZHVja09sZEJlc3QJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFmtleVRvdXJEeW5hbWljRGF0YUJ5SWQBBQZsYXN0SWQFEnVwZGF0ZWREeW5hbWljRGF0YQUDbmlsCQCVCgMFDW9sZFNjb3JlQm9hcmQFDG9sZFN1bVNjb3JlcwUDbmlsBA1uZXdTY29yZUJvYXJkCAULJHQwODIyOTkzOTACXzEEDG5ld1N1bVNjb3JlcwgFCyR0MDgyMjk5MzkwAl8yBA1nbG9iYWxBY3Rpb25zCAULJHQwODIyOTkzOTACXzMJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1iZXN0UmVzdWx0S2V5CQCWAwEJAMwIAgULZHVja09sZEJlc3QJAMwIAgULZHVja05ld0Jlc3QFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUMc3VtU2NvcmVzS2V5BQxuZXdTdW1TY29yZXMJAMwIAgkBC1N0cmluZ0VudHJ5AgUIc2NvcmVLZXkFDW5ld1Njb3JlQm9hcmQFA25pbAUNZ2xvYmFsQWN0aW9ucwAACQCUCgIFA25pbAAAAWkBEXByb2Nlc3NUb3VybmFtZW50AQN0SWQEBmNhbGxlcgkApQgBCAUBaQZjYWxsZXIDCQEBIQEJAQ9jb250YWluc0VsZW1lbnQCBQphZG1pbnNMaXN0BQZjYWxsZXIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFBHRoaXMFA3RJZAQGc3RhdGljCQCRAwIFBXREYXRhBQlpZHhTdGF0aWMEB2R5bmFtaWMJAJEDAgUFdERhdGEFCmlkeER5bmFtaWMEBnN0YXR1cwkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwQNcmVnaXN0cmF0aW9ucwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxSZWdDb3VudAQMcGFpZEF0dGVtcHRzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbEF0dGVtcHRzBAdyZWdDb3N0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRN0U3RhdGljUmVnaXN0ZXJDb3N0BAdhdHRDb3N0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRJ0U3RhdGljQXR0ZW1wdENvc3QDCQAAAgUGc3RhdHVzAghBUkNISVZFRAkAAgEJAKwCAgkArAICAgtUb3VybmFtZW50IAkApAMBBQN0SWQCFCBpcyBhbHJlYWR5IEFSQ0hJVkVEAwMJAAACBQZzdGF0dXMCCklOUFJPR1JFU1MJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQNub3cHCQACAQkArAICCQCsAgICC1RvdXJuYW1lbnQgCQCkAwEFA3RJZAIQIGlzIG5vdCBvdmVyIHlldAQSdXBkYXRlZER5bmFtaWNEYXRhCQELZHluYW1pY0RhdGEFAgpQUk9DRVNTSU5HCQCRAwIFB2R5bmFtaWMFD3REeW5hbWljTGVhZGVycwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFEXREeW5hbWljV2luUmVzdWx0BQ1yZWdpc3RyYXRpb25zBQxwYWlkQXR0ZW1wdHMJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQEWa2V5VG91ckR5bmFtaWNEYXRhQnlJZAEFA3RJZAUSdXBkYXRlZER5bmFtaWNEYXRhCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5VW5wYWlkUmV3YXJkc0J5VG91cgEFA3RJZAkAaQIJAGQCCQBoAgUNcmVnaXN0cmF0aW9ucwUHcmVnQ29zdAkAaAIFDHBhaWRBdHRlbXB0cwUHYXR0Q29zdAACBQNuaWwAAAFpARBmaW5pc2hUb3VybmFtZW50AQN0SWQEBmNhbGxlcgkApQgBCAUBaQZjYWxsZXIDCQEBIQEJAQ9jb250YWluc0VsZW1lbnQCBQphZG1pbnNMaXN0BQZjYWxsZXIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFBHRoaXMFA3RJZAQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwQGc3RhdHVzCQCRAwIFB2R5bmFtaWMFDnREeW5hbWljU3RhdHVzAwkAAAIFBnN0YXR1cwIIQVJDSElWRUQJAAIBCQCsAgIJAKwCAgILVG91cm5hbWVudCAJAKQDAQUDdElkAhQgaXMgYWxyZWFkeSBBUkNISVZFRAQSdXBkYXRlZER5bmFtaWNEYXRhCQELZHluYW1pY0RhdGEFAghBUkNISVZFRAkAkQMCBQdkeW5hbWljBQ90RHluYW1pY0xlYWRlcnMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRF0RHluYW1pY1dpblJlc3VsdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxSZWdDb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxBdHRlbXB0cwkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUDdElkBRJ1cGRhdGVkRHluYW1pY0RhdGEFA25pbAAAAWkBCmNsYWltUHJpemUBA3RJZAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAV0RGF0YQkBC2dldFRvdXJEYXRhAgUEdGhpcwUDdElkBAZzdGF0aWMJAJEDAgUFdERhdGEFCWlkeFN0YXRpYwQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwQGc3RhdHVzCQCRAwIFB2R5bmFtaWMFDnREeW5hbWljU3RhdHVzAwkBAiE9AgUGc3RhdHVzAgpQUk9DRVNTSU5HCQACAQkArAICCQCsAgICC1RvdXJuYW1lbnQgCQCkAwEFA3RJZAISIGlzIG5vdCBQUk9DRVNTSU5HBA1yZWdpc3RyYXRpb25zCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbFJlZ0NvdW50BAxwYWlkQXR0ZW1wdHMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRV0RHluYW1pY1RvdGFsQXR0ZW1wdHMEB3JlZ0Nvc3QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFE3RTdGF0aWNSZWdpc3RlckNvc3QEB2F0dENvc3QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFEnRTdGF0aWNBdHRlbXB0Q29zdAQKYXdhcmRGdW5kcwkAaQIJAGQCCQBoAgUNcmVnaXN0cmF0aW9ucwUHcmVnQ29zdAkAaAIFDHBhaWRBdHRlbXB0cwUHYXR0Q29zdAACBAl1bnBhaWRLZXkJARZrZXlVbnBhaWRSZXdhcmRzQnlUb3VyAQUDdElkBAt1bnBhaWRGdW5kcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQl1bnBhaWRLZXkAAAQLZHVja0Fzc2V0SWQJAQxkdWNrQnlDYWxsZXIBCAUBaQxvcmlnaW5DYWxsZXIECnNjb3JlQm9hcmQJAQt2YWx1ZU9yRWxzZQIJAKIIAQkBE2tleVNjb3JlQm9hcmRCeVRvdXIBBQN0SWQCAAMJAQEhAQkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEca2V5SXNSZWdpc3RlcmVkQnlUb3VyQW5kRHVjawIFA3RJZAULZHVja0Fzc2V0SWQHCQACAQkArAICCQCsAgIJAKwCAgIKWW91ciBkdWNrIAULZHVja0Fzc2V0SWQCISBpcyBub3QgcmVnaXN0ZXJlZCBhdCB0b3VybmFtZW50IAkApAMBBQN0SWQEDWJlc3RSZXN1bHRLZXkJARprZXlCZXN0UmVzdWx0QnlUb3VyQW5kRHVjawIFA3RJZAULZHVja0Fzc2V0SWQECGR1Y2tCZXN0CQELdmFsdWVPckVsc2UCCQCfCAEFDWJlc3RSZXN1bHRLZXkAAAMJAAACBQhkdWNrQmVzdAAACQACAQIYWW91ciBkdWNrIGdvdCB6ZXJvIHNjb3JlBAphd2FyZGVkS2V5CQEZa2V5SXNBd2FyZGVkQnlUb3VyQW5kRHVjawIFA3RJZAULZHVja0Fzc2V0SWQDCQELdmFsdWVPckVsc2UCCQCgCAEFCmF3YXJkZWRLZXkHCQACAQkArAICCQCsAgIJAKwCAgIKWW91ciBkdWNrIAULZHVja0Fzc2V0SWQCIiBpcyBhbHJlYWR5IGF3YXJkZWQgYXQgdG91cm5hbWVudCAJAKQDAQUDdElkBAxzdW1TY29yZXNLZXkJARJrZXlTdW1TY29yZXNCeVRvdXIBBQN0SWQECXN1bVNjb3JlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQxzdW1TY29yZXNLZXkAAAQHbGVhZGVycwkAkQMCBQdkeW5hbWljBQ90RHluYW1pY0xlYWRlcnMEC2xlYWRlcnNMaXN0AwMJAAACBQdsZWFkZXJzAgAGCQAAAgUHbGVhZGVycwIBIAUDbmlsCQC8CQIFB2xlYWRlcnMCASwECm51bUxlYWRlcnMJAJADAQULbGVhZGVyc0xpc3QDCQAAAgUKbnVtTGVhZGVycwAACQACAQkArAICAhlObyBsZWFkZXJzIGF0IHRvdXJuYW1lbnQgCQCkAwEFA3RJZAQJbnVtR3JhbmRzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRB0U3RhdGljTnVtR3JhbmRzBAl3aW5SZXN1bHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRF0RHluYW1pY1dpblJlc3VsdAQPc3VtTGVhZGVyU2NvcmVzAwkAZgIFCm51bUxlYWRlcnMFCW51bUdyYW5kcwAAAwkBD2NvbnRhaW5zRWxlbWVudAIFC2xlYWRlcnNMaXN0BQtkdWNrQXNzZXRJZAkAAgECMEFzIG9uZSBvZiB3aW5uZXJzLCB5b3Ugd2lsbCBiZSBhd2FyZGVkIGJ5IGFkbWlucwkAaAIFCm51bUxlYWRlcnMFCXdpblJlc3VsdAQKeW91ckFtb3VudAkAlwMBCQDMCAIJAGsDBQhkdWNrQmVzdAUKYXdhcmRGdW5kcwkAZQIFCXN1bVNjb3JlcwUPc3VtTGVhZGVyU2NvcmVzCQDMCAIFC3VucGFpZEZ1bmRzBQNuaWwED25ld1VucGFpZEFtb3VudAkAZQIFC3VucGFpZEZ1bmRzBQp5b3VyQW1vdW50BBJ1cGRhdGVkRHluYW1pY0RhdGEJAQtkeW5hbWljRGF0YQUCCEFSQ0hJVkVECQCRAwIFB2R5bmFtaWMFD3REeW5hbWljTGVhZGVycwUJd2luUmVzdWx0BQ1yZWdpc3RyYXRpb25zBQxwYWlkQXR0ZW1wdHMEDWFyY2hpdmVBY3Rpb24DCQBnAgAABQ9uZXdVbnBhaWRBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFmtleVRvdXJEeW5hbWljRGF0YUJ5SWQBBQN0SWQFEnVwZGF0ZWREeW5hbWljRGF0YQUDbmlsBQNuaWwJAJQKAgkAzggCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUKeW91ckFtb3VudAUKd2xnQXNzZXRJZAkAzAgCCQEMQm9vbGVhbkVudHJ5AgUKYXdhcmRlZEtleQYJAMwIAgkBDEludGVnZXJFbnRyeQIFCXVucGFpZEtleQUPbmV3VW5wYWlkQW1vdW50BQNuaWwFDWFyY2hpdmVBY3Rpb24AAACeW1wF", "height": 2743441, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9cd9kgwP15GTNXrGwYWsftcYSCoRWkWkiPRpVYtqhCjo Next: BCacf5hMi9hLL11KHiSLFv2k2eMnq8Ujuszg7H8Az7AX Diff:
OldNewDifferences
2727 func keySumScoresByTour (tId) = ("%s%d__sumScores__" + toString(tId))
2828
2929
30+func keyUnpaidRewardsByTour (tId) = ("%s%d__unpaidRewards__" + toString(tId))
31+
32+
3033 func keyLastRegisteredTourByDuck (duckAssetId) = ("%s%s__lastRegisteredTourByDuck__" + duckAssetId)
3134
3235
3336 func keyIsRegisteredByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__isRegisteredByTourAndDuck", toString(tId), duckAssetId], "__")
37+
38+
39+func keyIsAwardedByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__isAwardedByTourAndDuck", toString(tId), duckAssetId], "__")
3440
3541
3642 func keyLastAttemptByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__lastAttemptByTourAndDuck", toString(tId), duckAssetId], "__")
5056 let tStaticStart = 5
5157
5258 let tStaticEnd = 6
59+
60+let tStaticNumGrands = 7
5361
5462 let tDynamicStatus = 1
5563
337345 let duckOldBest = valueOrElse(getInteger(bestResultKey), 0)
338346 let scoreKey = keyScoreBoardByTour(lastId)
339347 let oldScoreBoard = valueOrElse(getString(scoreKey), "")
340- let $t0959210753 = if ((duckNewBest > duckOldBest))
348+ let $t082299390 = if ((duckNewBest > duckOldBest))
341349 then if (!(contains(oldScoreBoard, duckAssetId)))
342350 then throw(("scoreBoard does not contain " + duckAssetId))
343351 else {
360368 $Tuple3(((((parts[0] + duckAssetId) + ":") + padL(duckNewBest, 3)) + drop(parts[1], 4)), ((oldSumScores + duckNewBest) - duckOldBest), [StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)])
361369 }
362370 else $Tuple3(oldScoreBoard, oldSumScores, nil)
363- let newScoreBoard = $t0959210753._1
364- let newSumScores = $t0959210753._2
365- let globalActions = $t0959210753._3
371+ let newScoreBoard = $t082299390._1
372+ let newSumScores = $t082299390._2
373+ let globalActions = $t082299390._3
366374 $Tuple2(([IntegerEntry(bestResultKey, max([duckOldBest, duckNewBest])), IntegerEntry(sumScoresKey, newSumScores), StringEntry(scoreKey, newScoreBoard)] ++ globalActions), 0)
367375 }
368376 else $Tuple2(nil, 0)
381389 let static = tData[idxStatic]
382390 let dynamic = tData[idxDynamic]
383391 let status = dynamic[tDynamicStatus]
392+ let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
393+ let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
394+ let regCost = parseIntValue(static[tStaticRegisterCost])
395+ let attCost = parseIntValue(static[tStaticAttemptCost])
384396 if ((status == "ARCHIVED"))
385397 then throw((("Tournament " + toString(tId)) + " is already ARCHIVED"))
386398 else if (if ((status == "INPROGRESS"))
388400 else false)
389401 then throw((("Tournament " + toString(tId)) + " is not over yet"))
390402 else {
391- let updatedDynamicData = dynamicData("PROCESSING", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), parseIntValue(dynamic[tDynamicTotalAttempts]))
392- $Tuple2([StringEntry(keyTourDynamicDataById(tId), updatedDynamicData)], 0)
403+ let updatedDynamicData = dynamicData("PROCESSING", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), registrations, paidAttempts)
404+ $Tuple2([StringEntry(keyTourDynamicDataById(tId), updatedDynamicData), IntegerEntry(keyUnpaidRewardsByTour(tId), (((registrations * regCost) + (paidAttempts * attCost)) / 2))], 0)
393405 }
394406 }
395407 }
415427 }
416428
417429
430+
431+@Callable(i)
432+func claimPrize (tId) = {
433+ let prologResult = prolog()
434+ if ((size(i.payments) != 0))
435+ then throw("No payments required")
436+ else {
437+ let tData = getTourData(this, tId)
438+ let static = tData[idxStatic]
439+ let dynamic = tData[idxDynamic]
440+ let status = dynamic[tDynamicStatus]
441+ if ((status != "PROCESSING"))
442+ then throw((("Tournament " + toString(tId)) + " is not PROCESSING"))
443+ else {
444+ let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
445+ let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
446+ let regCost = parseIntValue(static[tStaticRegisterCost])
447+ let attCost = parseIntValue(static[tStaticAttemptCost])
448+ let awardFunds = (((registrations * regCost) + (paidAttempts * attCost)) / 2)
449+ let unpaidKey = keyUnpaidRewardsByTour(tId)
450+ let unpaidFunds = valueOrElse(getInteger(unpaidKey), 0)
451+ let duckAssetId = duckByCaller(i.originCaller)
452+ let scoreBoard = valueOrElse(getString(keyScoreBoardByTour(tId)), "")
453+ if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(tId, duckAssetId)), false)))
454+ then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(tId)))
455+ else {
456+ let bestResultKey = keyBestResultByTourAndDuck(tId, duckAssetId)
457+ let duckBest = valueOrElse(getInteger(bestResultKey), 0)
458+ if ((duckBest == 0))
459+ then throw("Your duck got zero score")
460+ else {
461+ let awardedKey = keyIsAwardedByTourAndDuck(tId, duckAssetId)
462+ if (valueOrElse(getBoolean(awardedKey), false))
463+ then throw(((("Your duck " + duckAssetId) + " is already awarded at tournament ") + toString(tId)))
464+ else {
465+ let sumScoresKey = keySumScoresByTour(tId)
466+ let sumScores = valueOrElse(getInteger(sumScoresKey), 0)
467+ let leaders = dynamic[tDynamicLeaders]
468+ let leadersList = if (if ((leaders == ""))
469+ then true
470+ else (leaders == " "))
471+ then nil
472+ else split_4C(leaders, ",")
473+ let numLeaders = size(leadersList)
474+ if ((numLeaders == 0))
475+ then throw(("No leaders at tournament " + toString(tId)))
476+ else {
477+ let numGrands = parseIntValue(static[tStaticNumGrands])
478+ let winResult = parseIntValue(dynamic[tDynamicWinResult])
479+ let sumLeaderScores = if ((numLeaders > numGrands))
480+ then 0
481+ else if (containsElement(leadersList, duckAssetId))
482+ then throw("As one of winners, you will be awarded by admins")
483+ else (numLeaders * winResult)
484+ let yourAmount = min([fraction(duckBest, awardFunds, (sumScores - sumLeaderScores)), unpaidFunds])
485+ let newUnpaidAmount = (unpaidFunds - yourAmount)
486+ let updatedDynamicData = dynamicData("ARCHIVED", dynamic[tDynamicLeaders], winResult, registrations, paidAttempts)
487+ let archiveAction = if ((0 >= newUnpaidAmount))
488+ then [StringEntry(keyTourDynamicDataById(tId), updatedDynamicData)]
489+ else nil
490+ $Tuple2(([ScriptTransfer(i.caller, yourAmount, wlgAssetId), BooleanEntry(awardedKey, true), IntegerEntry(unpaidKey, newUnpaidAmount)] ++ archiveAction), 0)
491+ }
492+ }
493+ }
494+ }
495+ }
496+ }
497+ }
498+
499+
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let DEFAULTLOCATION = "Africa_F_Africa"
55
66 let locIdxContinent = 0
77
88 let locIdxType = 1
99
1010 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
1111
1212
1313 func keyDuckLocation (duckAssetId) = ("duckLocation_" + duckAssetId)
1414
1515
1616 let lastTourIdKey = "%s__lastTourId"
1717
1818 func keyTourStaticDataById (tId) = ("%s%d__tourStaticData__" + toString(tId))
1919
2020
2121 func keyTourDynamicDataById (tId) = ("%s%d__tourDynamicData__" + toString(tId))
2222
2323
2424 func keyScoreBoardByTour (tId) = ("%s%d__scoreBoard__" + toString(tId))
2525
2626
2727 func keySumScoresByTour (tId) = ("%s%d__sumScores__" + toString(tId))
2828
2929
30+func keyUnpaidRewardsByTour (tId) = ("%s%d__unpaidRewards__" + toString(tId))
31+
32+
3033 func keyLastRegisteredTourByDuck (duckAssetId) = ("%s%s__lastRegisteredTourByDuck__" + duckAssetId)
3134
3235
3336 func keyIsRegisteredByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__isRegisteredByTourAndDuck", toString(tId), duckAssetId], "__")
37+
38+
39+func keyIsAwardedByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__isAwardedByTourAndDuck", toString(tId), duckAssetId], "__")
3440
3541
3642 func keyLastAttemptByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__lastAttemptByTourAndDuck", toString(tId), duckAssetId], "__")
3743
3844
3945 func keyBestResultByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestResultByTourAndDuck", toString(tId), duckAssetId], "__")
4046
4147
4248 let idxStatic = 0
4349
4450 let idxDynamic = 1
4551
4652 let tStaticRegisterCost = 2
4753
4854 let tStaticAttemptCost = 3
4955
5056 let tStaticStart = 5
5157
5258 let tStaticEnd = 6
59+
60+let tStaticNumGrands = 7
5361
5462 let tDynamicStatus = 1
5563
5664 let tDynamicLeaders = 2
5765
5866 let tDynamicWinResult = 3
5967
6068 let tDynamicTotalRegCount = 4
6169
6270 let tDynamicTotalAttempts = 5
6371
6472 func getTourData (tourContract,tId) = {
6573 let static = split(valueOrErrorMessage(getString(tourContract, keyTourStaticDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
6674 let dynamic = split_4C(valueOrErrorMessage(getString(tourContract, keyTourDynamicDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
6775 [static, dynamic]
6876 }
6977
7078
7179 func isInTournament (tourContract,location) = {
7280 let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
7381 let loc = split(location, "_")
7482 let now = lastBlock.timestamp
7583 let tData = getTourData(tourContract, lastId)
7684 let static = tData[idxStatic]
7785 let dynamic = tData[idxDynamic]
7886 if (if (if ((loc[locIdxType] == "T"))
7987 then (parseIntValue(loc[locIdxContinent]) == lastId)
8088 else false)
8189 then (dynamic[tDynamicStatus] == "INPROGRESS")
8290 else false)
8391 then (parseIntValue(static[tStaticEnd]) > now)
8492 else false
8593 }
8694
8795
8896 let chain = take(drop(this.bytes, 1), 1)
8997
9098 let defaultRestAddressStr = match chain {
9199 case _ =>
92100 if ((base58'2W' == $match0))
93101 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
94102 else if ((base58'2T' == $match0))
95103 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
96104 else throw("Unknown chain")
97105 }
98106
99107 let SEP = "__"
100108
101109 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
102110
103111
104112 let IdxCfgStakingDapp = 1
105113
106114 let IdxCfgWlgDapp = 4
107115
108116 func keyRestCfg () = "%s__restConfig"
109117
110118
111119 func keyRestAddress () = "%s__restAddr"
112120
113121
114122 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
115123
116124
117125 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
118126
119127
120128 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
121129
122130 let restCfg = readRestCfgOrFail(restContract)
123131
124132 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
125133
126134 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
127135
128136 let wlgAssetIdKey = "wlg_assetId"
129137
130138 let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "Not initialized yet")
131139
132140 func asString (v) = match v {
133141 case s: String =>
134142 s
135143 case _ =>
136144 throw("fail to cast into String")
137145 }
138146
139147
140148 func asInt (v) = match v {
141149 case n: Int =>
142150 n
143151 case _ =>
144152 throw("fail to cast into Int")
145153 }
146154
147155
148156 func fixedPoint (val,decimals) = {
149157 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
150158 let lowPart = toString((val % tenPow))
151159 let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
152160 (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
153161 }
154162
155163
156164 func padL (val,len) = {
157165 let valS = toString(val)
158166 let zeroes = drop(toString(pow(10, 0, (len - size(valS)), 0, 0, DOWN)), 1)
159167 (zeroes + valS)
160168 }
161169
162170
163171 let MAXTOURNAMENTLENGTH = 432000000
164172
165173 let HOUR = 3600000
166174
167175 let adminsList = [toString(this), match chain {
168176 case _ =>
169177 if ((base58'2W' == $match0))
170178 then "3PEe2RELUHCFCBsmSCNcBJ8N3URLVQende7"
171179 else if ((base58'2T' == $match0))
172180 then "3MtBgJTaLxPB3C7UJD1UE8qjkHthfKvFQYY"
173181 else throw("Unknown chain")
174182 }]
175183
176184 func staticData (txId,registerCost,attemptCost,creationTime,startTime,endTime,numGrands) = makeString(["%s%d%d%d%d%d%d", txId, toString(registerCost), toString(attemptCost), toString(creationTime), toString(startTime), toString(endTime), toString(numGrands)], SEP)
177185
178186
179187 func dynamicData (status,leaders,winResult,totalRegs,totalAttempts) = makeString_2C(["%s%s%d%d%d", status, leaders, toString(winResult), toString(totalRegs), toString(totalAttempts)], SEP)
180188
181189
182190 func prolog () = asInt(invoke(stakingContract, "saveLastTx", nil, nil))
183191
184192
185193 func duckByCaller (caller) = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(caller))), "You don't have a duck staked")
186194
187195
188196 @Callable(i)
189197 func createTournament (startTime,endTime,registerCost,attemptCost,numGrands) = {
190198 let caller = toString(i.caller)
191199 if (!(containsElement(adminsList, caller)))
192200 then throw("Permission denied")
193201 else {
194202 let lastId = getInteger(lastTourIdKey)
195203 let tId = if (isDefined(lastId))
196204 then {
197205 let lastTourId = value(lastId)
198206 let dynamic = valueOrErrorMessage(getString(keyTourDynamicDataById(lastTourId)), (("Error reading tournament " + toString(lastTourId)) + " data"))
199207 let status = split(dynamic, SEP)[tDynamicStatus]
200208 if ((status != "ARCHIVED"))
201209 then throw(("Current tournement is not completed, status=" + status))
202210 else (lastTourId + 1)
203211 }
204212 else 1
205213 let now = lastBlock.timestamp
206214 if ((now > startTime))
207215 then throw(((("startTime=" + toString(startTime)) + " < creationTime=") + toString(now)))
208216 else if ((startTime > endTime))
209217 then throw(((("endTime=" + toString(endTime)) + " < startTime=") + toString(startTime)))
210218 else if (((endTime - startTime) > MAXTOURNAMENTLENGTH))
211219 then throw(((("Tournament period exceeds max: " + toString((endTime - startTime))) + " > ") + toString(MAXTOURNAMENTLENGTH)))
212220 else if (if ((0 >= registerCost))
213221 then true
214222 else (0 >= attemptCost))
215223 then throw(((("Cost should be positive, but passed " + toString(registerCost)) + " and ") + toString(attemptCost)))
216224 else if ((0 > numGrands))
217225 then throw("Number of Grand Prizes should be non-negative")
218226 else $Tuple2([IntegerEntry(lastTourIdKey, tId), StringEntry(keyTourStaticDataById(tId), staticData(toBase58String(i.transactionId), registerCost, attemptCost, now, startTime, endTime, numGrands)), StringEntry(keyTourDynamicDataById(tId), dynamicData("CREATED", " ", 0, 0, 0))], tId)
219227 }
220228 }
221229
222230
223231
224232 @Callable(i)
225233 func register () = {
226234 let prologResult = prolog()
227235 if ((size(i.payments) != 1))
228236 then throw("exactly 1 payment must be attached")
229237 else {
230238 let pmt = i.payments[0]
231239 let wlgAmt = pmt.amount
232240 let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WLGOLD payments only!")
233241 if ((pmtAssetId != wlgAssetId))
234242 then throw("WLGOLD payments only!")
235243 else {
236244 let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
237245 let now = lastBlock.timestamp
238246 let tData = getTourData(this, lastId)
239247 let static = tData[idxStatic]
240248 let dynamic = tData[idxDynamic]
241249 let status = dynamic[tDynamicStatus]
242250 if (!(if (if (if ((status == "CREATED"))
243251 then (now > parseIntValue(static[tStaticStart]))
244252 else false)
245253 then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
246254 else false)
247255 then true
248256 else if ((status == "INPROGRESS"))
249257 then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
250258 else false))
251259 then throw("Cannot register now")
252260 else {
253261 let regCost = parseIntValue(static[tStaticRegisterCost])
254262 if ((wlgAmt != regCost))
255263 then throw((("Need payment of " + fixedPoint(regCost, 8)) + " WLGOLD"))
256264 else {
257265 let duckAssetId = duckByCaller(i.originCaller)
258266 let oldScoreBoard = valueOrElse(getString(keyScoreBoardByTour(lastId)), "")
259267 if (if (valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false))
260268 then true
261269 else contains(oldScoreBoard, duckAssetId))
262270 then throw(((("Your duck " + duckAssetId) + " is already registered at tournament ") + toString(lastId)))
263271 else {
264272 let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), (parseIntValue(dynamic[tDynamicTotalRegCount]) + 1), parseIntValue(dynamic[tDynamicTotalAttempts]))
265273 $Tuple2([IntegerEntry(keyLastRegisteredTourByDuck(duckAssetId), lastId), BooleanEntry(keyIsRegisteredByTourAndDuck(lastId, duckAssetId), true), StringEntry(keyScoreBoardByTour(lastId), if ((oldScoreBoard == ""))
266274 then (duckAssetId + ":000")
267275 else (((oldScoreBoard + "_") + duckAssetId) + ":000")), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], prologResult)
268276 }
269277 }
270278 }
271279 }
272280 }
273281 }
274282
275283
276284
277285 @Callable(i)
278286 func newAttempt () = {
279287 let prologResult = prolog()
280288 let duckAssetId = duckByCaller(i.originCaller)
281289 let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
282290 let now = lastBlock.timestamp
283291 let tData = getTourData(this, lastId)
284292 let static = tData[idxStatic]
285293 let dynamic = tData[idxDynamic]
286294 let status = dynamic[tDynamicStatus]
287295 if (!(if ((status == "INPROGRESS"))
288296 then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
289297 else false))
290298 then throw("Attempt is not possible")
291299 else if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false)))
292300 then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(lastId)))
293301 else {
294302 let attemptsIteratorKey = keyLastAttemptByTourAndDuck(lastId, duckAssetId)
295303 let lastAttempt = getInteger(attemptsIteratorKey)
296304 let $t061046736 = if (!(isDefined(lastAttempt)))
297305 then $Tuple2(0, 0)
298306 else if ((size(i.payments) != 1))
299307 then throw("exactly 1 payment must be attached")
300308 else {
301309 let pmt = i.payments[0]
302310 let wlgAmt = pmt.amount
303311 let pmtAssetId = valueOrErrorMessage(pmt.assetId, "WLGOLD payments only!")
304312 if ((pmtAssetId != wlgAssetId))
305313 then throw("WLGOLD payments only!")
306314 else {
307315 let attCost = parseIntValue(static[tStaticAttemptCost])
308316 if ((wlgAmt != attCost))
309317 then throw((("Need payment of " + fixedPoint(attCost, 8)) + " WLGOLD"))
310318 else $Tuple2((value(lastAttempt) + 1), 1)
311319 }
312320 }
313321 let payedAttempts = $t061046736._1
314322 let increment = $t061046736._2
315323 let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), (parseIntValue(dynamic[tDynamicTotalAttempts]) + increment))
316324 let tourLoc = asString(invoke(stakingContract, "initDuckTourAttempt", [duckAssetId], nil))
317325 $Tuple2([IntegerEntry(attemptsIteratorKey, payedAttempts), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], [prologResult, payedAttempts, tourLoc])
318326 }
319327 }
320328
321329
322330
323331 @Callable(i)
324332 func saveDuckResult (duckAssetId,duckNewBest) = if ((i.caller != stakingContract))
325333 then throw("Access denied")
326334 else {
327335 let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
328336 let tData = getTourData(this, lastId)
329337 let static = tData[idxStatic]
330338 let dynamic = tData[idxDynamic]
331339 let curLocation = valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
332340 let bestResultKey = keyBestResultByTourAndDuck(lastId, duckAssetId)
333341 let sumScoresKey = keySumScoresByTour(lastId)
334342 let oldSumScores = valueOrElse(getInteger(sumScoresKey), 0)
335343 if (isInTournament(this, curLocation))
336344 then {
337345 let duckOldBest = valueOrElse(getInteger(bestResultKey), 0)
338346 let scoreKey = keyScoreBoardByTour(lastId)
339347 let oldScoreBoard = valueOrElse(getString(scoreKey), "")
340- let $t0959210753 = if ((duckNewBest > duckOldBest))
348+ let $t082299390 = if ((duckNewBest > duckOldBest))
341349 then if (!(contains(oldScoreBoard, duckAssetId)))
342350 then throw(("scoreBoard does not contain " + duckAssetId))
343351 else {
344352 let oldBest = parseIntValue(dynamic[tDynamicWinResult])
345353 let leaders = dynamic[tDynamicLeaders]
346354 let oldLeadersList = if (if ((leaders == ""))
347355 then true
348356 else (leaders == " "))
349357 then nil
350358 else split_4C(leaders, ",")
351359 let newLeadersList = if ((duckNewBest > oldBest))
352360 then [duckAssetId]
353361 else if (if ((oldBest > duckNewBest))
354362 then true
355363 else containsElement(oldLeadersList, duckAssetId))
356364 then oldLeadersList
357365 else (oldLeadersList :+ duckAssetId)
358366 let updatedDynamicData = dynamicData("INPROGRESS", makeString_2C(newLeadersList, ","), max([duckNewBest, oldBest]), parseIntValue(dynamic[tDynamicTotalRegCount]), parseIntValue(dynamic[tDynamicTotalAttempts]))
359367 let parts = split_51C(oldScoreBoard, duckAssetId)
360368 $Tuple3(((((parts[0] + duckAssetId) + ":") + padL(duckNewBest, 3)) + drop(parts[1], 4)), ((oldSumScores + duckNewBest) - duckOldBest), [StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)])
361369 }
362370 else $Tuple3(oldScoreBoard, oldSumScores, nil)
363- let newScoreBoard = $t0959210753._1
364- let newSumScores = $t0959210753._2
365- let globalActions = $t0959210753._3
371+ let newScoreBoard = $t082299390._1
372+ let newSumScores = $t082299390._2
373+ let globalActions = $t082299390._3
366374 $Tuple2(([IntegerEntry(bestResultKey, max([duckOldBest, duckNewBest])), IntegerEntry(sumScoresKey, newSumScores), StringEntry(scoreKey, newScoreBoard)] ++ globalActions), 0)
367375 }
368376 else $Tuple2(nil, 0)
369377 }
370378
371379
372380
373381 @Callable(i)
374382 func processTournament (tId) = {
375383 let caller = toString(i.caller)
376384 if (!(containsElement(adminsList, caller)))
377385 then throw("Permission denied")
378386 else {
379387 let now = lastBlock.timestamp
380388 let tData = getTourData(this, tId)
381389 let static = tData[idxStatic]
382390 let dynamic = tData[idxDynamic]
383391 let status = dynamic[tDynamicStatus]
392+ let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
393+ let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
394+ let regCost = parseIntValue(static[tStaticRegisterCost])
395+ let attCost = parseIntValue(static[tStaticAttemptCost])
384396 if ((status == "ARCHIVED"))
385397 then throw((("Tournament " + toString(tId)) + " is already ARCHIVED"))
386398 else if (if ((status == "INPROGRESS"))
387399 then (parseIntValue(static[tStaticEnd]) > now)
388400 else false)
389401 then throw((("Tournament " + toString(tId)) + " is not over yet"))
390402 else {
391- let updatedDynamicData = dynamicData("PROCESSING", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), parseIntValue(dynamic[tDynamicTotalAttempts]))
392- $Tuple2([StringEntry(keyTourDynamicDataById(tId), updatedDynamicData)], 0)
403+ let updatedDynamicData = dynamicData("PROCESSING", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), registrations, paidAttempts)
404+ $Tuple2([StringEntry(keyTourDynamicDataById(tId), updatedDynamicData), IntegerEntry(keyUnpaidRewardsByTour(tId), (((registrations * regCost) + (paidAttempts * attCost)) / 2))], 0)
393405 }
394406 }
395407 }
396408
397409
398410
399411 @Callable(i)
400412 func finishTournament (tId) = {
401413 let caller = toString(i.caller)
402414 if (!(containsElement(adminsList, caller)))
403415 then throw("Permission denied")
404416 else {
405417 let tData = getTourData(this, tId)
406418 let dynamic = tData[idxDynamic]
407419 let status = dynamic[tDynamicStatus]
408420 if ((status == "ARCHIVED"))
409421 then throw((("Tournament " + toString(tId)) + " is already ARCHIVED"))
410422 else {
411423 let updatedDynamicData = dynamicData("ARCHIVED", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), parseIntValue(dynamic[tDynamicTotalAttempts]))
412424 $Tuple2([StringEntry(keyTourDynamicDataById(tId), updatedDynamicData)], 0)
413425 }
414426 }
415427 }
416428
417429
430+
431+@Callable(i)
432+func claimPrize (tId) = {
433+ let prologResult = prolog()
434+ if ((size(i.payments) != 0))
435+ then throw("No payments required")
436+ else {
437+ let tData = getTourData(this, tId)
438+ let static = tData[idxStatic]
439+ let dynamic = tData[idxDynamic]
440+ let status = dynamic[tDynamicStatus]
441+ if ((status != "PROCESSING"))
442+ then throw((("Tournament " + toString(tId)) + " is not PROCESSING"))
443+ else {
444+ let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
445+ let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
446+ let regCost = parseIntValue(static[tStaticRegisterCost])
447+ let attCost = parseIntValue(static[tStaticAttemptCost])
448+ let awardFunds = (((registrations * regCost) + (paidAttempts * attCost)) / 2)
449+ let unpaidKey = keyUnpaidRewardsByTour(tId)
450+ let unpaidFunds = valueOrElse(getInteger(unpaidKey), 0)
451+ let duckAssetId = duckByCaller(i.originCaller)
452+ let scoreBoard = valueOrElse(getString(keyScoreBoardByTour(tId)), "")
453+ if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(tId, duckAssetId)), false)))
454+ then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(tId)))
455+ else {
456+ let bestResultKey = keyBestResultByTourAndDuck(tId, duckAssetId)
457+ let duckBest = valueOrElse(getInteger(bestResultKey), 0)
458+ if ((duckBest == 0))
459+ then throw("Your duck got zero score")
460+ else {
461+ let awardedKey = keyIsAwardedByTourAndDuck(tId, duckAssetId)
462+ if (valueOrElse(getBoolean(awardedKey), false))
463+ then throw(((("Your duck " + duckAssetId) + " is already awarded at tournament ") + toString(tId)))
464+ else {
465+ let sumScoresKey = keySumScoresByTour(tId)
466+ let sumScores = valueOrElse(getInteger(sumScoresKey), 0)
467+ let leaders = dynamic[tDynamicLeaders]
468+ let leadersList = if (if ((leaders == ""))
469+ then true
470+ else (leaders == " "))
471+ then nil
472+ else split_4C(leaders, ",")
473+ let numLeaders = size(leadersList)
474+ if ((numLeaders == 0))
475+ then throw(("No leaders at tournament " + toString(tId)))
476+ else {
477+ let numGrands = parseIntValue(static[tStaticNumGrands])
478+ let winResult = parseIntValue(dynamic[tDynamicWinResult])
479+ let sumLeaderScores = if ((numLeaders > numGrands))
480+ then 0
481+ else if (containsElement(leadersList, duckAssetId))
482+ then throw("As one of winners, you will be awarded by admins")
483+ else (numLeaders * winResult)
484+ let yourAmount = min([fraction(duckBest, awardFunds, (sumScores - sumLeaderScores)), unpaidFunds])
485+ let newUnpaidAmount = (unpaidFunds - yourAmount)
486+ let updatedDynamicData = dynamicData("ARCHIVED", dynamic[tDynamicLeaders], winResult, registrations, paidAttempts)
487+ let archiveAction = if ((0 >= newUnpaidAmount))
488+ then [StringEntry(keyTourDynamicDataById(tId), updatedDynamicData)]
489+ else nil
490+ $Tuple2(([ScriptTransfer(i.caller, yourAmount, wlgAssetId), BooleanEntry(awardedKey, true), IntegerEntry(unpaidKey, newUnpaidAmount)] ++ archiveAction), 0)
491+ }
492+ }
493+ }
494+ }
495+ }
496+ }
497+ }
498+
499+

github/deemru/w8io/169f3d6 
98.20 ms