tx · 7DULw3wfLc9rHFBz31io411pyN33WkDEKpUs6dFXNCT4

3N3nfqFcxXfd3T18V9icDdh58MJ9wQ2k2xx:  -0.01700000 Waves

2023.11.23 20:24 [2856325] smart account 3N3nfqFcxXfd3T18V9icDdh58MJ9wQ2k2xx > SELF 0.00000000 Waves

{ "type": 13, "id": "7DULw3wfLc9rHFBz31io411pyN33WkDEKpUs6dFXNCT4", "fee": 1700000, "feeAssetId": null, "timestamp": 1700760307023, "version": 2, "chainId": 84, "sender": "3N3nfqFcxXfd3T18V9icDdh58MJ9wQ2k2xx", "senderPublicKey": "UGqkWsCpv7xRVXkQRXyLd6pWPDtYGXmPip7FxSd1pAu", "proofs": [ "218s9DWRRXgA9egDFtStgpoJWL1xpBvaRcmVTU82tYMn3UPoGtnkhc37i6xJ8FnHQVdm25xN2fY7k87ysvwbfT6p" ], "script": "base64:BgIhCAISCQoHAQEBAQEBCBIAEgASBAoCCAESAwoBARIDCgEBPAAPREVGQVVMVExPQ0FUSU9OAg9BZnJpY2FfRl9BZnJpY2EAD2xvY0lkeENvbnRpbmVudAAAAApsb2NJZHhUeXBlAAEBFGtleVN0YWtlZER1Y2tCeU93bmVyAQlvd25lckFkZHIJAKwCAgISc3Rha2VkRHVja0J5T3duZXJfBQlvd25lckFkZHIBD2tleUR1Y2tMb2NhdGlvbgELZHVja0Fzc2V0SWQJAKwCAgINZHVja0xvY2F0aW9uXwULZHVja0Fzc2V0SWQADWxhc3RUb3VySWRLZXkCDiVzX19sYXN0VG91cklkARVrZXlUb3VyU3RhdGljRGF0YUJ5SWQBA3RJZAkArAICAhYlcyVkX190b3VyU3RhdGljRGF0YV9fCQCkAwEFA3RJZAEWa2V5VG91ckR5bmFtaWNEYXRhQnlJZAEDdElkCQCsAgICFyVzJWRfX3RvdXJEeW5hbWljRGF0YV9fCQCkAwEFA3RJZAETa2V5U2NvcmVCb2FyZEJ5VG91cgEDdElkCQCsAgICEiVzJWRfX3Njb3JlQm9hcmRfXwkApAMBBQN0SWQBEmtleVN1bVNjb3Jlc0J5VG91cgEDdElkCQCsAgICESVzJWRfX3N1bVNjb3Jlc19fCQCkAwEFA3RJZAEWa2V5VW5wYWlkUmV3YXJkc0J5VG91cgEDdElkCQCsAgICFSVzJWRfX3VucGFpZFJld2FyZHNfXwkApAMBBQN0SWQBG2tleUxhc3RSZWdpc3RlcmVkVG91ckJ5RHVjawELZHVja0Fzc2V0SWQJAKwCAgIgJXMlc19fbGFzdFJlZ2lzdGVyZWRUb3VyQnlEdWNrX18FC2R1Y2tBc3NldElkARxrZXlJc1JlZ2lzdGVyZWRCeVRvdXJBbmREdWNrAgN0SWQLZHVja0Fzc2V0SWQJALkJAgkAzAgCAiElcyVkJXNfX2lzUmVnaXN0ZXJlZEJ5VG91ckFuZER1Y2sJAMwIAgkApAMBBQN0SWQJAMwIAgULZHVja0Fzc2V0SWQFA25pbAICX18BGWtleUlzQXdhcmRlZEJ5VG91ckFuZER1Y2sCA3RJZAtkdWNrQXNzZXRJZAkAuQkCCQDMCAICHiVzJWQlc19faXNBd2FyZGVkQnlUb3VyQW5kRHVjawkAzAgCCQCkAwEFA3RJZAkAzAgCBQtkdWNrQXNzZXRJZAUDbmlsAgJfXwEba2V5TGFzdEF0dGVtcHRCeVRvdXJBbmREdWNrAgN0SWQLZHVja0Fzc2V0SWQJALkJAgkAzAgCAiAlcyVkJXNfX2xhc3RBdHRlbXB0QnlUb3VyQW5kRHVjawkAzAgCCQCkAwEFA3RJZAkAzAgCBQtkdWNrQXNzZXRJZAUDbmlsAgJfXwEaa2V5QmVzdFJlc3VsdEJ5VG91ckFuZER1Y2sCA3RJZAtkdWNrQXNzZXRJZAkAuQkCCQDMCAICHyVzJWQlc19fYmVzdFJlc3VsdEJ5VG91ckFuZER1Y2sJAMwIAgkApAMBBQN0SWQJAMwIAgULZHVja0Fzc2V0SWQFA25pbAICX18BFmtleUJlc3RUeEJ5VG91ckFuZER1Y2sCA3RJZAtkdWNrQXNzZXRJZAkAuQkCCQDMCAICGyVzJWQlc19fYmVzdFR4QnlUb3VyQW5kRHVjawkAzAgCCQCkAwEFA3RJZAkAzAgCBQtkdWNrQXNzZXRJZAUDbmlsAgJfXwAJaWR4U3RhdGljAAAACmlkeER5bmFtaWMAAQATdFN0YXRpY1JlZ2lzdGVyQ29zdAACABJ0U3RhdGljQXR0ZW1wdENvc3QAAwAMdFN0YXRpY1N0YXJ0AAUACnRTdGF0aWNFbmQABgAQdFN0YXRpY051bUdyYW5kcwAHABB0U3RhdGljUHJpemVGdW5kAAgADHRTdGF0aWNBc3NldAAJAA50RHluYW1pY1N0YXR1cwABAA90RHluYW1pY0xlYWRlcnMAAgARdER5bmFtaWNXaW5SZXN1bHQAAwAVdER5bmFtaWNUb3RhbFJlZ0NvdW50AAQAFXREeW5hbWljVG90YWxBdHRlbXB0cwAFAQtnZXRUb3VyRGF0YQIMdG91ckNvbnRyYWN0A3RJZAQGc3RhdGljCQC1CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQx0b3VyQ29udHJhY3QJARVrZXlUb3VyU3RhdGljRGF0YUJ5SWQBBQN0SWQJAKwCAgkArAICAhlFcnJvciByZWFkaW5nIHRvdXJuYW1lbnQgCQCkAwEFA3RJZAIFIGRhdGECAl9fBAdkeW5hbWljCQC8CQIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQx0b3VyQ29udHJhY3QJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUDdElkCQCsAgIJAKwCAgIZRXJyb3IgcmVhZGluZyB0b3VybmFtZW50IAkApAMBBQN0SWQCBSBkYXRhAgJfXwkAzAgCBQZzdGF0aWMJAMwIAgUHZHluYW1pYwUDbmlsAQ5pc0luVG91cm5hbWVudAIMdG91ckNvbnRyYWN0CGxvY2F0aW9uBAZsYXN0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUMdG91ckNvbnRyYWN0BQ1sYXN0VG91cklkS2V5AAAEA2xvYwkAtQkCBQhsb2NhdGlvbgIBXwQDbm93CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFDHRvdXJDb250cmFjdAUGbGFzdElkBAZzdGF0aWMJAJEDAgUFdERhdGEFCWlkeFN0YXRpYwQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwMDAwkAAAIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFUCQAAAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2xvYwUPbG9jSWR4Q29udGluZW50BQZsYXN0SWQHCQAAAgkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwIKSU5QUk9HUkVTUwcJAGYCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQNub3cHAAVjaGFpbgkAyQECCQDKAQIIBQR0aGlzBWJ5dGVzAAEAAQAVZGVmYXVsdFJlc3RBZGRyZXNzU3RyBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAiMzUFFDdXZGYnZoNExrUFVucm5VMXozam5iQTFwOW0zV05odgMJAAACAQFUBQckbWF0Y2gwAiMzTXVta0dHenRDS0FYcFdEcXhrZGRvZnFYU1VicVFrdlNKeQkAAgECDVVua25vd24gY2hhaW4AA1NFUAICX18BD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAABFJZHhDZmdTdGFraW5nRGFwcAABAA1JZHhDZmdXbGdEYXBwAAQBCmtleVJlc3RDZmcAAg4lc19fcmVzdENvbmZpZwEOa2V5UmVzdEFkZHJlc3MAAgwlc19fcmVzdEFkZHIBEXJlYWRSZXN0Q2ZnT3JGYWlsAQRyZXN0CQC8CQIJAQ9nZXRTdHJpbmdPckZhaWwCBQRyZXN0CQEKa2V5UmVzdENmZwAFA1NFUAEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgdyZXN0Q2ZnA2lkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUHcmVzdENmZwUDaWR4CQCsAgICKlJlc3QgY2ZnIGRvZXNuJ3QgY29udGFpbiBhZGRyZXNzIGF0IGluZGV4IAkApAMBBQNpZHgADHJlc3RDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEOa2V5UmVzdEFkZHJlc3MABRVkZWZhdWx0UmVzdEFkZHJlc3NTdHIAB3Jlc3RDZmcJARFyZWFkUmVzdENmZ09yRmFpbAEFDHJlc3RDb250cmFjdAAPc3Rha2luZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwURSWR4Q2ZnU3Rha2luZ0RhcHAAC3dsZ0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUHcmVzdENmZwUNSWR4Q2ZnV2xnRGFwcAANd2xnQXNzZXRJZEtleQILd2xnX2Fzc2V0SWQACndsZ0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQt3bGdDb250cmFjdAUNd2xnQXNzZXRJZEtleQIYV0xHT0xEIGlzIG5vdCBpc3N1ZWQgeWV0AQhhc1N0cmluZwEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAFAXMJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBBWFzSW50AQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACA0ludAQBbgUHJG1hdGNoMAUBbgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEKZml4ZWRQb2ludAIDdmFsCGRlY2ltYWxzBAZ0ZW5Qb3cJAGwGAAoAAAUIZGVjaW1hbHMAAAAABQRET1dOBAdsb3dQYXJ0CQCkAwEJAGoCBQN2YWwFBnRlblBvdwQGemVyb2VzCQCwAgIJAKQDAQUGdGVuUG93CQBkAgABCQCxAgEFB2xvd1BhcnQJAKwCAgkArAICCQCsAgIJAKQDAQkAaQIFA3ZhbAUGdGVuUG93AgEuBQZ6ZXJvZXMFB2xvd1BhcnQBBHBhZEwCA3ZhbANsZW4EBHZhbFMJAKQDAQUDdmFsBAZ6ZXJvZXMJALACAgkApAMBCQBsBgAKAAAJAGUCBQNsZW4JALECAQUEdmFsUwAAAAAFBERPV04AAQkArAICBQZ6ZXJvZXMFBHZhbFMAE01BWFRPVVJOQU1FTlRMRU5HVEgAgMj96QQABEhPVVIAgN3bAQAKYWRtaW5zTGlzdAkAzAgCCQClCAEFBHRoaXMJAMwIAgQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAIjM1BFZTJSRUxVSENGQ0JzbVNDTmNCSjhOM1VSTFZRZW5kZTcDCQAAAgEBVAUHJG1hdGNoMAIjM010QmdKVGFMeFBCM0M3VUpEMVVFOHFqa0h0aGZLdkZRWVkJAAIBAg1Vbmtub3duIGNoYWluBQNuaWwBCnN0YXRpY0RhdGEJBHR4SWQMcmVnaXN0ZXJDb3N0C2F0dGVtcHRDb3N0DGNyZWF0aW9uVGltZQlzdGFydFRpbWUHZW5kVGltZQludW1HcmFuZHMJcHJpemVGdW5kCnByaXplQXNzZXQJALkJAgkAzAgCAhIlcyVkJWQlZCVkJWQlZCVkJXMJAMwIAgUEdHhJZAkAzAgCCQCkAwEFDHJlZ2lzdGVyQ29zdAkAzAgCCQCkAwEFC2F0dGVtcHRDb3N0CQDMCAIJAKQDAQUMY3JlYXRpb25UaW1lCQDMCAIJAKQDAQUJc3RhcnRUaW1lCQDMCAIJAKQDAQUHZW5kVGltZQkAzAgCCQCkAwEFCW51bUdyYW5kcwkAzAgCCQCkAwEFCXByaXplRnVuZAkAzAgCBQpwcml6ZUFzc2V0BQNuaWwFA1NFUAELZHluYW1pY0RhdGEFBnN0YXR1cwdsZWFkZXJzCXdpblJlc3VsdAl0b3RhbFJlZ3MNdG90YWxBdHRlbXB0cwkAugkCCQDMCAICCiVzJXMlZCVkJWQJAMwIAgUGc3RhdHVzCQDMCAIFB2xlYWRlcnMJAMwIAgkApAMBBQl3aW5SZXN1bHQJAMwIAgkApAMBBQl0b3RhbFJlZ3MJAMwIAgkApAMBBQ10b3RhbEF0dGVtcHRzBQNuaWwFA1NFUAEGcHJvbG9nAAkBBWFzSW50AQkA/QcEBQ9zdGFraW5nQ29udHJhY3QCCnNhdmVMYXN0VHgFA25pbAUDbmlsAQxkdWNrQnlDYWxsZXIBBmNhbGxlcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD3N0YWtpbmdDb250cmFjdAkBFGtleVN0YWtlZER1Y2tCeU93bmVyAQkApQgBBQZjYWxsZXICHFlvdSBkb24ndCBoYXZlIGEgZHVjayBzdGFrZWQGAWkBEGNyZWF0ZVRvdXJuYW1lbnQHCXN0YXJ0VGltZQdlbmRUaW1lDHJlZ2lzdGVyQ29zdAthdHRlbXB0Q29zdAludW1HcmFuZHMJcHJpemVGdW5kCnByaXplQXNzZXQEBmNhbGxlcgkApQgBCAUBaQZjYWxsZXIDCQEBIQEJAQ9jb250YWluc0VsZW1lbnQCBQphZG1pbnNMaXN0BQZjYWxsZXIJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQGbGFzdElkCQCfCAEFDWxhc3RUb3VySWRLZXkEA3RJZAMJAQlpc0RlZmluZWQBBQZsYXN0SWQECmxhc3RUb3VySWQJAQV2YWx1ZQEFBmxhc3RJZAQHZHluYW1pYwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUKbGFzdFRvdXJJZAkArAICCQCsAgICGUVycm9yIHJlYWRpbmcgdG91cm5hbWVudCAJAKQDAQUKbGFzdFRvdXJJZAIFIGRhdGEEBnN0YXR1cwkAkQMCCQC1CQIFB2R5bmFtaWMFA1NFUAUOdER5bmFtaWNTdGF0dXMDAwkBAiE9AgUGc3RhdHVzAghBUkNISVZFRAkBAiE9AgUGc3RhdHVzAgpQUk9DRVNTSU5HBwkAAgEJAKwCAgIsQ3VycmVudCB0b3VybmVtZW50IGlzIG5vdCBjb21wbGV0ZWQsIHN0YXR1cz0FBnN0YXR1cwkAZAIFCmxhc3RUb3VySWQAAQABBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wAwkAZgIFA25vdwUJc3RhcnRUaW1lCQACAQkArAICCQCsAgIJAKwCAgIKc3RhcnRUaW1lPQkApAMBBQlzdGFydFRpbWUCECA8IGNyZWF0aW9uVGltZT0JAKQDAQUDbm93AwkAZgIFCXN0YXJ0VGltZQUHZW5kVGltZQkAAgEJAKwCAgkArAICCQCsAgICCGVuZFRpbWU9CQCkAwEFB2VuZFRpbWUCDSA8IHN0YXJ0VGltZT0JAKQDAQUJc3RhcnRUaW1lAwkAZgIJAGUCBQdlbmRUaW1lBQlzdGFydFRpbWUFE01BWFRPVVJOQU1FTlRMRU5HVEgJAAIBCQCsAgIJAKwCAgkArAICAh9Ub3VybmFtZW50IHBlcmlvZCBleGNlZWRzIG1heDogCQCkAwEJAGUCBQdlbmRUaW1lBQlzdGFydFRpbWUCAyA+IAkApAMBBRNNQVhUT1VSTkFNRU5UTEVOR1RIAwMJAGYCAAAFDHJlZ2lzdGVyQ29zdAYJAGYCAAAFC2F0dGVtcHRDb3N0CQACAQkArAICCQCsAgIJAKwCAgIkQ29zdCBzaG91bGQgYmUgcG9zaXRpdmUsIGJ1dCBwYXNzZWQgCQCkAwEFDHJlZ2lzdGVyQ29zdAIFIGFuZCAJAKQDAQULYXR0ZW1wdENvc3QDCQBmAgAABQludW1HcmFuZHMJAAIBAi1OdW1iZXIgb2YgR3JhbmQgUHJpemVzIHNob3VsZCBiZSBub24tbmVnYXRpdmUDCQBmAgAABQlwcml6ZUZ1bmQJAAIBAiFQcml6ZSBGdW5kIHNob3VsZCBiZSBub24tbmVnYXRpdmUJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUNbGFzdFRvdXJJZEtleQUDdElkCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlUb3VyU3RhdGljRGF0YUJ5SWQBBQN0SWQJAQpzdGF0aWNEYXRhCQkA2AQBCAUBaQ10cmFuc2FjdGlvbklkBQxyZWdpc3RlckNvc3QFC2F0dGVtcHRDb3N0BQNub3cFCXN0YXJ0VGltZQUHZW5kVGltZQUJbnVtR3JhbmRzBQlwcml6ZUZ1bmQFCnByaXplQXNzZXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFmtleVRvdXJEeW5hbWljRGF0YUJ5SWQBBQN0SWQJAQtkeW5hbWljRGF0YQUCB0NSRUFURUQCASAAAAAAAAAFA25pbAUDdElkAWkBCHJlZ2lzdGVyAAQMcHJvbG9nUmVzdWx0CQEGcHJvbG9nAAMJAAACBQxwcm9sb2dSZXN1bHQFDHByb2xvZ1Jlc3VsdAQGbGFzdElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUNbGFzdFRvdXJJZEtleQIVTm8gYWN0aXZlIHRvdXJuYW1lbnRzBANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAV0RGF0YQkBC2dldFRvdXJEYXRhAgUEdGhpcwUGbGFzdElkBAZzdGF0aWMJAJEDAgUFdERhdGEFCWlkeFN0YXRpYwQHZHluYW1pYwkAkQMCBQV0RGF0YQUKaWR4RHluYW1pYwQGc3RhdHVzCQCRAwIFB2R5bmFtaWMFDnREeW5hbWljU3RhdHVzAwkBASEBAwMDCQAAAgUGc3RhdHVzAgdDUkVBVEVECQBmAgUDbm93CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQx0U3RhdGljU3RhcnQHCQBmAgkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFCnRTdGF0aWNFbmQFBEhPVVIFA25vdwcGAwkAAAIFBnN0YXR1cwIKSU5QUk9HUkVTUwkAZgIJAGUCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBQp0U3RhdGljRW5kBQRIT1VSBQNub3cHCQACAQITQ2Fubm90IHJlZ2lzdGVyIG5vdwQHcmVnQ29zdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUTdFN0YXRpY1JlZ2lzdGVyQ29zdAQHYXNzZXRJZAMJAGYCCQCQAwEFBnN0YXRpYwUMdFN0YXRpY0Fzc2V0CQDZBAEJAJEDAgUGc3RhdGljBQx0U3RhdGljQXNzZXQFCndsZ0Fzc2V0SWQEA25mbwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFB2Fzc2V0SWQCFk5vIGFzc2V0SW5mbyBhdmFpbGFibGUECWFzc2V0TmFtZQgFA25mbwRuYW1lBA1hc3NldERlY2ltYWxzCAUDbmZvCGRlY2ltYWxzBAZyZWdBbXQDCQBmAgUHcmVnQ29zdAAAAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAADAwkBASEBCQEJaXNEZWZpbmVkAQgFA3BtdAdhc3NldElkBgkBAiE9AgkBBXZhbHVlAQgFA3BtdAdhc3NldElkBQdhc3NldElkCQACAQkArAICBQlhc3NldE5hbWUCDyBwYXltZW50cyBvbmx5IQgFA3BtdAZhbW91bnQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAAAAwkBAiE9AgUGcmVnQW10BQdyZWdDb3N0CQACAQkArAICCQCsAgIJAKwCAgIQTmVlZCBwYXltZW50IG9mIAkBCmZpeGVkUG9pbnQCBQdyZWdDb3N0BQ1hc3NldERlY2ltYWxzAgEgBQlhc3NldE5hbWUEC2R1Y2tBc3NldElkCQEMZHVja0J5Q2FsbGVyAQgFAWkMb3JpZ2luQ2FsbGVyBAhzY29yZUtleQkBE2tleVNjb3JlQm9hcmRCeVRvdXIBBQZsYXN0SWQEDW9sZFNjb3JlQm9hcmQJAQt2YWx1ZU9yRWxzZQIJAKIIAQUIc2NvcmVLZXkCAAMDCQELdmFsdWVPckVsc2UCCQCgCAEJARxrZXlJc1JlZ2lzdGVyZWRCeVRvdXJBbmREdWNrAgUGbGFzdElkBQtkdWNrQXNzZXRJZAcGCQEIY29udGFpbnMCBQ1vbGRTY29yZUJvYXJkBQtkdWNrQXNzZXRJZAkAAgEJAKwCAgkArAICCQCsAgICCllvdXIgZHVjayAFC2R1Y2tBc3NldElkAiUgaXMgYWxyZWFkeSByZWdpc3RlcmVkIGF0IHRvdXJuYW1lbnQgCQCkAwEFBmxhc3RJZAQSdXBkYXRlZER5bmFtaWNEYXRhCQELZHluYW1pY0RhdGEFAgpJTlBST0dSRVNTCQCRAwIFB2R5bmFtaWMFD3REeW5hbWljTGVhZGVycwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFEXREeW5hbWljV2luUmVzdWx0CQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxSZWdDb3VudAABCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbEF0dGVtcHRzCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJARtrZXlMYXN0UmVnaXN0ZXJlZFRvdXJCeUR1Y2sBBQtkdWNrQXNzZXRJZAUGbGFzdElkCQDMCAIJAQxCb29sZWFuRW50cnkCCQEca2V5SXNSZWdpc3RlcmVkQnlUb3VyQW5kRHVjawIFBmxhc3RJZAULZHVja0Fzc2V0SWQGCQDMCAIJAQtTdHJpbmdFbnRyeQIFCHNjb3JlS2V5AwkAAAIFDW9sZFNjb3JlQm9hcmQCAAkArAICBQtkdWNrQXNzZXRJZAIEOjAwMAkArAICCQCsAgIJAKwCAgUNb2xkU2NvcmVCb2FyZAIBXwULZHVja0Fzc2V0SWQCBDowMDAJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFmtleVRvdXJEeW5hbWljRGF0YUJ5SWQBBQZsYXN0SWQFEnVwZGF0ZWREeW5hbWljRGF0YQUDbmlsBQxwcm9sb2dSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKbmV3QXR0ZW1wdAAEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwADCQAAAgUMcHJvbG9nUmVzdWx0BQxwcm9sb2dSZXN1bHQEC2R1Y2tBc3NldElkCQEMZHVja0J5Q2FsbGVyAQgFAWkMb3JpZ2luQ2FsbGVyBAZsYXN0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQ1sYXN0VG91cklkS2V5AhVObyBhY3RpdmUgdG91cm5hbWVudHMEA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEBXREYXRhCQELZ2V0VG91ckRhdGECBQR0aGlzBQZsYXN0SWQEBnN0YXRpYwkAkQMCBQV0RGF0YQUJaWR4U3RhdGljBAdkeW5hbWljCQCRAwIFBXREYXRhBQppZHhEeW5hbWljBAZzdGF0dXMJAJEDAgUHZHluYW1pYwUOdER5bmFtaWNTdGF0dXMDCQEBIQEDCQAAAgUGc3RhdHVzAgpJTlBST0dSRVNTCQBmAgkAZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFCnRTdGF0aWNFbmQFBEhPVVIFA25vdwcJAAIBAhdBdHRlbXB0IGlzIG5vdCBwb3NzaWJsZQMJAQEhAQkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEca2V5SXNSZWdpc3RlcmVkQnlUb3VyQW5kRHVjawIFBmxhc3RJZAULZHVja0Fzc2V0SWQHCQACAQkArAICCQCsAgIJAKwCAgIKWW91ciBkdWNrIAULZHVja0Fzc2V0SWQCISBpcyBub3QgcmVnaXN0ZXJlZCBhdCB0b3VybmFtZW50IAkApAMBBQZsYXN0SWQEE2F0dGVtcHRzSXRlcmF0b3JLZXkJARtrZXlMYXN0QXR0ZW1wdEJ5VG91ckFuZER1Y2sCBQZsYXN0SWQFC2R1Y2tBc3NldElkBAtsYXN0QXR0ZW1wdAkAnwgBBRNhdHRlbXB0c0l0ZXJhdG9yS2V5BAskdDA2NzQ5NzYxNAMJAQEhAQkBCWlzRGVmaW5lZAEFC2xhc3RBdHRlbXB0CQCUCgIAAAAAAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEB2Fzc2V0SWQDCQBmAgkAkAMBBQZzdGF0aWMFDHRTdGF0aWNBc3NldAkA2QQBCQCRAwIFBnN0YXRpYwUMdFN0YXRpY0Fzc2V0BQp3bGdBc3NldElkBANuZm8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQdhc3NldElkAhZObyBhc3NldEluZm8gYXZhaWxhYmxlBAlhc3NldE5hbWUIBQNuZm8EbmFtZQQNYXNzZXREZWNpbWFscwgFA25mbwhkZWNpbWFscwQDYW10CAUDcG10BmFtb3VudAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFB2Fzc2V0SWQJAAIBCQCsAgIFCWFzc2V0TmFtZQIPIHBheW1lbnRzIG9ubHkhBAdhdHRDb3N0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRJ0U3RhdGljQXR0ZW1wdENvc3QDCQECIT0CBQNhbXQFB2F0dENvc3QJAAIBCQCsAgIJAKwCAgkArAICAhBOZWVkIHBheW1lbnQgb2YgCQEKZml4ZWRQb2ludAIFB2F0dENvc3QFDWFzc2V0RGVjaW1hbHMCASAFCWFzc2V0TmFtZQkAlAoCCQBkAgkBBXZhbHVlAQULbGFzdEF0dGVtcHQAAQABBA1wYXllZEF0dGVtcHRzCAULJHQwNjc0OTc2MTQCXzEECWluY3JlbWVudAgFCyR0MDY3NDk3NjE0Al8yBBJ1cGRhdGVkRHluYW1pY0RhdGEJAQtkeW5hbWljRGF0YQUCCklOUFJPR1JFU1MJAJEDAgUHZHluYW1pYwUPdER5bmFtaWNMZWFkZXJzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwURdER5bmFtaWNXaW5SZXN1bHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRV0RHluYW1pY1RvdGFsUmVnQ291bnQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbEF0dGVtcHRzBQlpbmNyZW1lbnQEB3RvdXJMb2MJAQhhc1N0cmluZwEJAPwHBAUPc3Rha2luZ0NvbnRyYWN0AhNpbml0RHVja1RvdXJBdHRlbXB0CQDMCAIFC2R1Y2tBc3NldElkBQNuaWwFA25pbAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRNhdHRlbXB0c0l0ZXJhdG9yS2V5BQ1wYXllZEF0dGVtcHRzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUGbGFzdElkBRJ1cGRhdGVkRHluYW1pY0RhdGEFA25pbAkAzAgCBQxwcm9sb2dSZXN1bHQJAMwIAgUNcGF5ZWRBdHRlbXB0cwkAzAgCBQd0b3VyTG9jBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOc2F2ZUR1Y2tSZXN1bHQCC2R1Y2tBc3NldElkC2R1Y2tOZXdCZXN0AwkBAiE9AggFAWkGY2FsbGVyBQ9zdGFraW5nQ29udHJhY3QJAAIBAg1BY2Nlc3MgZGVuaWVkBAZsYXN0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQ1sYXN0VG91cklkS2V5AhVObyBhY3RpdmUgdG91cm5hbWVudHMEBXREYXRhCQELZ2V0VG91ckRhdGECBQR0aGlzBQZsYXN0SWQEBnN0YXRpYwkAkQMCBQV0RGF0YQUJaWR4U3RhdGljBAdkeW5hbWljCQCRAwIFBXREYXRhBQppZHhEeW5hbWljBAtjdXJMb2NhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OBA1iZXN0UmVzdWx0S2V5CQEaa2V5QmVzdFJlc3VsdEJ5VG91ckFuZER1Y2sCBQZsYXN0SWQFC2R1Y2tBc3NldElkBAxzdW1TY29yZXNLZXkJARJrZXlTdW1TY29yZXNCeVRvdXIBBQZsYXN0SWQEDG9sZFN1bVNjb3JlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQxzdW1TY29yZXNLZXkAAAMJAQ5pc0luVG91cm5hbWVudAIFBHRoaXMFC2N1ckxvY2F0aW9uBAtkdWNrT2xkQmVzdAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ1iZXN0UmVzdWx0S2V5AAAECHNjb3JlS2V5CQETa2V5U2NvcmVCb2FyZEJ5VG91cgEFBmxhc3RJZAQNb2xkU2NvcmVCb2FyZAkBC3ZhbHVlT3JFbHNlAgkAoggBBQhzY29yZUtleQIABAwkdDA5MTA3MTAyNjgDCQBmAgULZHVja05ld0Jlc3QFC2R1Y2tPbGRCZXN0AwkBASEBCQEIY29udGFpbnMCBQ1vbGRTY29yZUJvYXJkBQtkdWNrQXNzZXRJZAkAAgEJAKwCAgIcc2NvcmVCb2FyZCBkb2VzIG5vdCBjb250YWluIAULZHVja0Fzc2V0SWQEB29sZEJlc3QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRF0RHluYW1pY1dpblJlc3VsdAQHbGVhZGVycwkAkQMCBQdkeW5hbWljBQ90RHluYW1pY0xlYWRlcnMEDm9sZExlYWRlcnNMaXN0AwMJAAACBQdsZWFkZXJzAgAGCQAAAgUHbGVhZGVycwIBIAUDbmlsCQC8CQIFB2xlYWRlcnMCASwEDm5ld0xlYWRlcnNMaXN0AwkAZgIFC2R1Y2tOZXdCZXN0BQdvbGRCZXN0CQDMCAIFC2R1Y2tBc3NldElkBQNuaWwDAwkAZgIFB29sZEJlc3QFC2R1Y2tOZXdCZXN0BgkBD2NvbnRhaW5zRWxlbWVudAIFDm9sZExlYWRlcnNMaXN0BQtkdWNrQXNzZXRJZAUOb2xkTGVhZGVyc0xpc3QJAM0IAgUOb2xkTGVhZGVyc0xpc3QFC2R1Y2tBc3NldElkBBJ1cGRhdGVkRHluYW1pY0RhdGEJAQtkeW5hbWljRGF0YQUCCklOUFJPR1JFU1MJALoJAgUObmV3TGVhZGVyc0xpc3QCASwJAJYDAQkAzAgCBQtkdWNrTmV3QmVzdAkAzAgCBQdvbGRCZXN0BQNuaWwJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRV0RHluYW1pY1RvdGFsUmVnQ291bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRV0RHluYW1pY1RvdGFsQXR0ZW1wdHMEBXBhcnRzCQC9CQIFDW9sZFNjb3JlQm9hcmQFC2R1Y2tBc3NldElkCQCVCgMJAKwCAgkArAICCQCsAgIJAKwCAgkAkQMCBQVwYXJ0cwAABQtkdWNrQXNzZXRJZAIBOgkBBHBhZEwCBQtkdWNrTmV3QmVzdAADCQCwAgIJAJEDAgUFcGFydHMAAQAECQBlAgkAZAIFDG9sZFN1bVNjb3JlcwULZHVja05ld0Jlc3QFC2R1Y2tPbGRCZXN0CQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlUb3VyRHluYW1pY0RhdGFCeUlkAQUGbGFzdElkBRJ1cGRhdGVkRHluYW1pY0RhdGEFA25pbAkAlQoDBQ1vbGRTY29yZUJvYXJkBQxvbGRTdW1TY29yZXMFA25pbAQNbmV3U2NvcmVCb2FyZAgFDCR0MDkxMDcxMDI2OAJfMQQMbmV3U3VtU2NvcmVzCAUMJHQwOTEwNzEwMjY4Al8yBA1nbG9iYWxBY3Rpb25zCAUMJHQwOTEwNzEwMjY4Al8zCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUNYmVzdFJlc3VsdEtleQkAlgMBCQDMCAIFC2R1Y2tPbGRCZXN0CQDMCAIFC2R1Y2tOZXdCZXN0BQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIFDHN1bVNjb3Jlc0tleQUMbmV3U3VtU2NvcmVzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlCZXN0VHhCeVRvdXJBbmREdWNrAgUGbGFzdElkBQtkdWNrQXNzZXRJZAkA2AQBCAUBaQ10cmFuc2FjdGlvbklkCQDMCAIJAQtTdHJpbmdFbnRyeQIFCHNjb3JlS2V5BQ1uZXdTY29yZUJvYXJkBQNuaWwFDWdsb2JhbEFjdGlvbnMAAAkAlAoCBQNuaWwAAAFpARFwcm9jZXNzVG91cm5hbWVudAEDdElkBAZjYWxsZXIJAKUIAQgFAWkGY2FsbGVyAwkBASEBCQEPY29udGFpbnNFbGVtZW50AgUKYWRtaW5zTGlzdAUGY2FsbGVyCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEBXREYXRhCQELZ2V0VG91ckRhdGECBQR0aGlzBQN0SWQEBnN0YXRpYwkAkQMCBQV0RGF0YQUJaWR4U3RhdGljBAdkeW5hbWljCQCRAwIFBXREYXRhBQppZHhEeW5hbWljBAZzdGF0dXMJAJEDAgUHZHluYW1pYwUOdER5bmFtaWNTdGF0dXMEDXJlZ2lzdHJhdGlvbnMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRV0RHluYW1pY1RvdGFsUmVnQ291bnQEDHBhaWRBdHRlbXB0cwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxBdHRlbXB0cwQHcmVnQ29zdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUTdFN0YXRpY1JlZ2lzdGVyQ29zdAQHYXR0Q29zdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUSdFN0YXRpY0F0dGVtcHRDb3N0AwkAAAIFBnN0YXR1cwIIQVJDSElWRUQJAAIBCQCsAgIJAKwCAgILVG91cm5hbWVudCAJAKQDAQUDdElkAhQgaXMgYWxyZWFkeSBBUkNISVZFRAMDCQAAAgUGc3RhdHVzAgpJTlBST0dSRVNTCQBmAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUKdFN0YXRpY0VuZAUDbm93BwkAAgEJAKwCAgkArAICAgtUb3VybmFtZW50IAkApAMBBQN0SWQCECBpcyBub3Qgb3ZlciB5ZXQEEnVwZGF0ZWREeW5hbWljRGF0YQkBC2R5bmFtaWNEYXRhBQIKUFJPQ0VTU0lORwkAkQMCBQdkeW5hbWljBQ90RHluYW1pY0xlYWRlcnMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRF0RHluYW1pY1dpblJlc3VsdAUNcmVnaXN0cmF0aW9ucwUMcGFpZEF0dGVtcHRzBAlwcml6ZUZ1bmQDCQBmAgkAkAMBBQZzdGF0aWMFEHRTdGF0aWNQcml6ZUZ1bmQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdGF0aWMFEHRTdGF0aWNQcml6ZUZ1bmQAAAQGdW5wYWlkCQBkAgkAaQIJAGQCCQBoAgUNcmVnaXN0cmF0aW9ucwUHcmVnQ29zdAkAaAIFDHBhaWRBdHRlbXB0cwUHYXR0Q29zdAACBQlwcml6ZUZ1bmQJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQEWa2V5VG91ckR5bmFtaWNEYXRhQnlJZAEFA3RJZAUSdXBkYXRlZER5bmFtaWNEYXRhCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEWa2V5VW5wYWlkUmV3YXJkc0J5VG91cgEFA3RJZAUGdW5wYWlkBQNuaWwAAAFpAQpjbGFpbVByaXplAQN0SWQEDHByb2xvZ1Jlc3VsdAkBBnByb2xvZwADCQAAAgUMcHJvbG9nUmVzdWx0BQxwcm9sb2dSZXN1bHQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhRObyBwYXltZW50cyByZXF1aXJlZAQFdERhdGEJAQtnZXRUb3VyRGF0YQIFBHRoaXMFA3RJZAQGc3RhdGljCQCRAwIFBXREYXRhBQlpZHhTdGF0aWMEB2R5bmFtaWMJAJEDAgUFdERhdGEFCmlkeER5bmFtaWMEBnN0YXR1cwkAkQMCBQdkeW5hbWljBQ50RHluYW1pY1N0YXR1cwMJAQIhPQIFBnN0YXR1cwIKUFJPQ0VTU0lORwkAAgEJAKwCAgkArAICAgtUb3VybmFtZW50IAkApAMBBQN0SWQCEiBpcyBub3QgUFJPQ0VTU0lORwQNcmVnaXN0cmF0aW9ucwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFB2R5bmFtaWMFFXREeW5hbWljVG90YWxSZWdDb3VudAQMcGFpZEF0dGVtcHRzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHZHluYW1pYwUVdER5bmFtaWNUb3RhbEF0dGVtcHRzBAdyZWdDb3N0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRN0U3RhdGljUmVnaXN0ZXJDb3N0BAdhdHRDb3N0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRJ0U3RhdGljQXR0ZW1wdENvc3QECXByaXplRnVuZAMJAGYCCQCQAwEFBnN0YXRpYwUQdFN0YXRpY1ByaXplRnVuZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0YXRpYwUQdFN0YXRpY1ByaXplRnVuZAAABAphd2FyZEZ1bmRzCQBkAgkAaQIJAGQCCQBoAgUNcmVnaXN0cmF0aW9ucwUHcmVnQ29zdAkAaAIFDHBhaWRBdHRlbXB0cwUHYXR0Q29zdAACBQlwcml6ZUZ1bmQECXVucGFpZEtleQkBFmtleVVucGFpZFJld2FyZHNCeVRvdXIBBQN0SWQEC3VucGFpZEZ1bmRzCQELdmFsdWVPckVsc2UCCQCfCAEFCXVucGFpZEtleQAABAtkdWNrQXNzZXRJZAkBDGR1Y2tCeUNhbGxlcgEIBQFpDG9yaWdpbkNhbGxlcgMJAQEhAQkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEca2V5SXNSZWdpc3RlcmVkQnlUb3VyQW5kRHVjawIFA3RJZAULZHVja0Fzc2V0SWQHCQACAQkArAICCQCsAgIJAKwCAgIKWW91ciBkdWNrIAULZHVja0Fzc2V0SWQCISBpcyBub3QgcmVnaXN0ZXJlZCBhdCB0b3VybmFtZW50IAkApAMBBQN0SWQEDWJlc3RSZXN1bHRLZXkJARprZXlCZXN0UmVzdWx0QnlUb3VyQW5kRHVjawIFA3RJZAULZHVja0Fzc2V0SWQECGR1Y2tCZXN0CQELdmFsdWVPckVsc2UCCQCfCAEFDWJlc3RSZXN1bHRLZXkAAAMJAAACBQhkdWNrQmVzdAAACQACAQIYWW91ciBkdWNrIGdvdCB6ZXJvIHNjb3JlBAphd2FyZGVkS2V5CQEZa2V5SXNBd2FyZGVkQnlUb3VyQW5kRHVjawIFA3RJZAULZHVja0Fzc2V0SWQDCQELdmFsdWVPckVsc2UCCQCgCAEFCmF3YXJkZWRLZXkHCQACAQkArAICCQCsAgIJAKwCAgIKWW91ciBkdWNrIAULZHVja0Fzc2V0SWQCIiBpcyBhbHJlYWR5IGF3YXJkZWQgYXQgdG91cm5hbWVudCAJAKQDAQUDdElkBAxzdW1TY29yZXNLZXkJARJrZXlTdW1TY29yZXNCeVRvdXIBBQN0SWQECXN1bVNjb3JlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQxzdW1TY29yZXNLZXkAAAQHbGVhZGVycwkAkQMCBQdkeW5hbWljBQ90RHluYW1pY0xlYWRlcnMEC2xlYWRlcnNMaXN0AwMJAAACBQdsZWFkZXJzAgAGCQAAAgUHbGVhZGVycwIBIAUDbmlsCQC8CQIFB2xlYWRlcnMCASwECm51bUxlYWRlcnMJAJADAQULbGVhZGVyc0xpc3QDCQAAAgUKbnVtTGVhZGVycwAACQACAQkArAICAhlObyBsZWFkZXJzIGF0IHRvdXJuYW1lbnQgCQCkAwEFA3RJZAQJbnVtR3JhbmRzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RhdGljBRB0U3RhdGljTnVtR3JhbmRzBAl3aW5SZXN1bHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQdkeW5hbWljBRF0RHluYW1pY1dpblJlc3VsdAQPc3VtTGVhZGVyU2NvcmVzAwkAZgIFCm51bUxlYWRlcnMFCW51bUdyYW5kcwAAAwkBD2NvbnRhaW5zRWxlbWVudAIFC2xlYWRlcnNMaXN0BQtkdWNrQXNzZXRJZAkAAgECMEFzIG9uZSBvZiB3aW5uZXJzLCB5b3Ugd2lsbCBiZSBhd2FyZGVkIGJ5IGFkbWlucwkAaAIFCm51bUxlYWRlcnMFCXdpblJlc3VsdAQKeW91ckFtb3VudAkAlwMBCQDMCAIJAGsDBQhkdWNrQmVzdAUKYXdhcmRGdW5kcwkAZQIFCXN1bVNjb3JlcwUPc3VtTGVhZGVyU2NvcmVzCQDMCAIFC3VucGFpZEZ1bmRzBQNuaWwED25ld1VucGFpZEFtb3VudAkAZQIFC3VucGFpZEZ1bmRzBQp5b3VyQW1vdW50BBJ1cGRhdGVkRHluYW1pY0RhdGEJAQtkeW5hbWljRGF0YQUCCEFSQ0hJVkVECQCRAwIFB2R5bmFtaWMFD3REeW5hbWljTGVhZGVycwUJd2luUmVzdWx0BQ1yZWdpc3RyYXRpb25zBQxwYWlkQXR0ZW1wdHMEDWFyY2hpdmVBY3Rpb24DCQBnAgAABQ9uZXdVbnBhaWRBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFmtleVRvdXJEeW5hbWljRGF0YUJ5SWQBBQN0SWQFEnVwZGF0ZWREeW5hbWljRGF0YQUDbmlsBQNuaWwEB2Fzc2V0SWQDCQBmAgkAkAMBBQZzdGF0aWMFDHRTdGF0aWNBc3NldAkA2QQBCQCRAwIFBnN0YXRpYwUMdFN0YXRpY0Fzc2V0BQp3bGdBc3NldElkBANsb2MJALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9zdGFraW5nQ29udHJhY3QJAQ9rZXlEdWNrTG9jYXRpb24BBQtkdWNrQXNzZXRJZAUPREVGQVVMVExPQ0FUSU9OAgFfBAxicmVha0FjdGlvbnMDAwkAAAIJAJEDAgUDbG9jBQpsb2NJZHhUeXBlAgFUCQAAAgkAkQMCCQCRAwIJAQtnZXRUb3VyRGF0YQIFBHRoaXMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNsb2MFD2xvY0lkeENvbnRpbmVudAUKaWR4RHluYW1pYwUOdER5bmFtaWNTdGF0dXMCClBST0NFU1NJTkcHCQD8BwQFD3N0YWtpbmdDb250cmFjdAIUYnJlYWtBdHRlbXB0Q2FsbGJhY2sFA25pbAUDbmlsBQR1bml0CQCUCgIJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFCnlvdXJBbW91bnQFB2Fzc2V0SWQJAMwIAgkBDEJvb2xlYW5FbnRyeQIFCmF3YXJkZWRLZXkGCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQl1bnBhaWRLZXkFD25ld1VucGFpZEFtb3VudAUDbmlsBQ1hcmNoaXZlQWN0aW9uBQxicmVha0FjdGlvbnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4A3LbeLw==", "height": 2856325, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EbqdnZkud8gMSFxzk7VkShd3ueK5rto52aVPgKMwes6N Next: GMDENNUJ4RGF6CpPjrJ5Zr3c85fBWe3acXFGVD6m8PL1 Diff:
OldNewDifferences
160160 }
161161
162162
163-func asBoolean (v) = match v {
164- case s: Boolean =>
165- s
166- case _ =>
167- throw("fail to cast into Boolean")
168-}
169-
170-
171163 func fixedPoint (val,decimals) = {
172164 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
173165 let lowPart = toString((val % tenPow))
321313 if ((prologResult == prologResult))
322314 then {
323315 let duckAssetId = duckByCaller(i.originCaller)
324- let deliveryStatus = asBoolean(invoke(stakingContract, "checkDeliveryCallback", [duckAssetId], nil))
325- if (deliveryStatus)
326- then throw("newAttempt_checkDelivery")
327- else {
328- let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
329- let now = lastBlock.timestamp
330- let tData = getTourData(this, lastId)
331- let static = tData[idxStatic]
332- let dynamic = tData[idxDynamic]
333- let status = dynamic[tDynamicStatus]
334- if (!(if ((status == "INPROGRESS"))
335- then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
336- else false))
337- then throw("Attempt is not possible")
338- else if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false)))
339- then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(lastId)))
340- else {
341- let attemptsIteratorKey = keyLastAttemptByTourAndDuck(lastId, duckAssetId)
342- let lastAttempt = getInteger(attemptsIteratorKey)
343- let $t069177782 = if (!(isDefined(lastAttempt)))
344- then $Tuple2(0, 0)
345- else if ((size(i.payments) != 1))
346- then throw("exactly 1 payment must be attached")
316+ let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
317+ let now = lastBlock.timestamp
318+ let tData = getTourData(this, lastId)
319+ let static = tData[idxStatic]
320+ let dynamic = tData[idxDynamic]
321+ let status = dynamic[tDynamicStatus]
322+ if (!(if ((status == "INPROGRESS"))
323+ then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
324+ else false))
325+ then throw("Attempt is not possible")
326+ else if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false)))
327+ then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(lastId)))
328+ else {
329+ let attemptsIteratorKey = keyLastAttemptByTourAndDuck(lastId, duckAssetId)
330+ let lastAttempt = getInteger(attemptsIteratorKey)
331+ let $t067497614 = if (!(isDefined(lastAttempt)))
332+ then $Tuple2(0, 0)
333+ else if ((size(i.payments) != 1))
334+ then throw("exactly 1 payment must be attached")
335+ else {
336+ let pmt = i.payments[0]
337+ let assetId = if ((size(static) > tStaticAsset))
338+ then fromBase58String(static[tStaticAsset])
339+ else wlgAssetId
340+ let nfo = valueOrErrorMessage(assetInfo(assetId), "No assetInfo available")
341+ let assetName = nfo.name
342+ let assetDecimals = nfo.decimals
343+ let amt = pmt.amount
344+ if (if (!(isDefined(pmt.assetId)))
345+ then true
346+ else (value(pmt.assetId) != assetId))
347+ then throw((assetName + " payments only!"))
347348 else {
348- let pmt = i.payments[0]
349- let assetId = if ((size(static) > tStaticAsset))
350- then fromBase58String(static[tStaticAsset])
351- else wlgAssetId
352- let nfo = valueOrErrorMessage(assetInfo(assetId), "No assetInfo available")
353- let assetName = nfo.name
354- let assetDecimals = nfo.decimals
355- let amt = pmt.amount
356- if (if (!(isDefined(pmt.assetId)))
357- then true
358- else (value(pmt.assetId) != assetId))
359- then throw((assetName + " payments only!"))
360- else {
361- let attCost = parseIntValue(static[tStaticAttemptCost])
362- if ((amt != attCost))
363- then throw(((("Need payment of " + fixedPoint(attCost, assetDecimals)) + " ") + assetName))
364- else $Tuple2((value(lastAttempt) + 1), 1)
365- }
349+ let attCost = parseIntValue(static[tStaticAttemptCost])
350+ if ((amt != attCost))
351+ then throw(((("Need payment of " + fixedPoint(attCost, assetDecimals)) + " ") + assetName))
352+ else $Tuple2((value(lastAttempt) + 1), 1)
366353 }
367- let payedAttempts = $t069177782._1
368- let increment = $t069177782._2
369- let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), (parseIntValue(dynamic[tDynamicTotalAttempts]) + increment))
370- let tourLoc = asString(invoke(stakingContract, "initDuckTourAttempt", [duckAssetId], nil))
371- $Tuple2([IntegerEntry(attemptsIteratorKey, payedAttempts), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], [prologResult, payedAttempts, tourLoc])
372- }
373- }
354+ }
355+ let payedAttempts = $t067497614._1
356+ let increment = $t067497614._2
357+ let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), (parseIntValue(dynamic[tDynamicTotalAttempts]) + increment))
358+ let tourLoc = asString(invoke(stakingContract, "initDuckTourAttempt", [duckAssetId], nil))
359+ $Tuple2([IntegerEntry(attemptsIteratorKey, payedAttempts), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], [prologResult, payedAttempts, tourLoc])
360+ }
374361 }
375362 else throw("Strict value is not equal to itself.")
376363 }
394381 let duckOldBest = valueOrElse(getInteger(bestResultKey), 0)
395382 let scoreKey = keyScoreBoardByTour(lastId)
396383 let oldScoreBoard = valueOrElse(getString(scoreKey), "")
397- let $t0927510436 = if ((duckNewBest > duckOldBest))
384+ let $t0910710268 = if ((duckNewBest > duckOldBest))
398385 then if (!(contains(oldScoreBoard, duckAssetId)))
399386 then throw(("scoreBoard does not contain " + duckAssetId))
400387 else {
417404 $Tuple3(((((parts[0] + duckAssetId) + ":") + padL(duckNewBest, 3)) + drop(parts[1], 4)), ((oldSumScores + duckNewBest) - duckOldBest), [StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)])
418405 }
419406 else $Tuple3(oldScoreBoard, oldSumScores, nil)
420- let newScoreBoard = $t0927510436._1
421- let newSumScores = $t0927510436._2
422- let globalActions = $t0927510436._3
407+ let newScoreBoard = $t0910710268._1
408+ let newSumScores = $t0910710268._2
409+ let globalActions = $t0910710268._3
423410 $Tuple2(([IntegerEntry(bestResultKey, max([duckOldBest, duckNewBest])), IntegerEntry(sumScoresKey, newSumScores), StringEntry(keyBestTxByTourAndDuck(lastId, duckAssetId), toBase58String(i.transactionId)), StringEntry(scoreKey, newScoreBoard)] ++ globalActions), 0)
424411 }
425412 else $Tuple2(nil, 0)
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
3030 func keyUnpaidRewardsByTour (tId) = ("%s%d__unpaidRewards__" + toString(tId))
3131
3232
3333 func keyLastRegisteredTourByDuck (duckAssetId) = ("%s%s__lastRegisteredTourByDuck__" + duckAssetId)
3434
3535
3636 func keyIsRegisteredByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__isRegisteredByTourAndDuck", toString(tId), duckAssetId], "__")
3737
3838
3939 func keyIsAwardedByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__isAwardedByTourAndDuck", toString(tId), duckAssetId], "__")
4040
4141
4242 func keyLastAttemptByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__lastAttemptByTourAndDuck", toString(tId), duckAssetId], "__")
4343
4444
4545 func keyBestResultByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestResultByTourAndDuck", toString(tId), duckAssetId], "__")
4646
4747
4848 func keyBestTxByTourAndDuck (tId,duckAssetId) = makeString(["%s%d%s__bestTxByTourAndDuck", toString(tId), duckAssetId], "__")
4949
5050
5151 let idxStatic = 0
5252
5353 let idxDynamic = 1
5454
5555 let tStaticRegisterCost = 2
5656
5757 let tStaticAttemptCost = 3
5858
5959 let tStaticStart = 5
6060
6161 let tStaticEnd = 6
6262
6363 let tStaticNumGrands = 7
6464
6565 let tStaticPrizeFund = 8
6666
6767 let tStaticAsset = 9
6868
6969 let tDynamicStatus = 1
7070
7171 let tDynamicLeaders = 2
7272
7373 let tDynamicWinResult = 3
7474
7575 let tDynamicTotalRegCount = 4
7676
7777 let tDynamicTotalAttempts = 5
7878
7979 func getTourData (tourContract,tId) = {
8080 let static = split(valueOrErrorMessage(getString(tourContract, keyTourStaticDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
8181 let dynamic = split_4C(valueOrErrorMessage(getString(tourContract, keyTourDynamicDataById(tId)), (("Error reading tournament " + toString(tId)) + " data")), "__")
8282 [static, dynamic]
8383 }
8484
8585
8686 func isInTournament (tourContract,location) = {
8787 let lastId = valueOrElse(getInteger(tourContract, lastTourIdKey), 0)
8888 let loc = split(location, "_")
8989 let now = lastBlock.timestamp
9090 let tData = getTourData(tourContract, lastId)
9191 let static = tData[idxStatic]
9292 let dynamic = tData[idxDynamic]
9393 if (if (if ((loc[locIdxType] == "T"))
9494 then (parseIntValue(loc[locIdxContinent]) == lastId)
9595 else false)
9696 then (dynamic[tDynamicStatus] == "INPROGRESS")
9797 else false)
9898 then (parseIntValue(static[tStaticEnd]) > now)
9999 else false
100100 }
101101
102102
103103 let chain = take(drop(this.bytes, 1), 1)
104104
105105 let defaultRestAddressStr = match chain {
106106 case _ =>
107107 if ((base58'2W' == $match0))
108108 then "3PQCuvFbvh4LkPUnrnU1z3jnbA1p9m3WNhv"
109109 else if ((base58'2T' == $match0))
110110 then "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy"
111111 else throw("Unknown chain")
112112 }
113113
114114 let SEP = "__"
115115
116116 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
117117
118118
119119 let IdxCfgStakingDapp = 1
120120
121121 let IdxCfgWlgDapp = 4
122122
123123 func keyRestCfg () = "%s__restConfig"
124124
125125
126126 func keyRestAddress () = "%s__restAddr"
127127
128128
129129 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
130130
131131
132132 func getContractAddressOrFail (restCfg,idx) = valueOrErrorMessage(addressFromString(restCfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
133133
134134
135135 let restContract = addressFromStringValue(valueOrElse(getString(this, keyRestAddress()), defaultRestAddressStr))
136136
137137 let restCfg = readRestCfgOrFail(restContract)
138138
139139 let stakingContract = getContractAddressOrFail(restCfg, IdxCfgStakingDapp)
140140
141141 let wlgContract = getContractAddressOrFail(restCfg, IdxCfgWlgDapp)
142142
143143 let wlgAssetIdKey = "wlg_assetId"
144144
145145 let wlgAssetId = valueOrErrorMessage(getBinary(wlgContract, wlgAssetIdKey), "WLGOLD is not issued yet")
146146
147147 func asString (v) = match v {
148148 case s: String =>
149149 s
150150 case _ =>
151151 throw("fail to cast into String")
152152 }
153153
154154
155155 func asInt (v) = match v {
156156 case n: Int =>
157157 n
158158 case _ =>
159159 throw("fail to cast into Int")
160160 }
161161
162162
163-func asBoolean (v) = match v {
164- case s: Boolean =>
165- s
166- case _ =>
167- throw("fail to cast into Boolean")
168-}
169-
170-
171163 func fixedPoint (val,decimals) = {
172164 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
173165 let lowPart = toString((val % tenPow))
174166 let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
175167 (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
176168 }
177169
178170
179171 func padL (val,len) = {
180172 let valS = toString(val)
181173 let zeroes = drop(toString(pow(10, 0, (len - size(valS)), 0, 0, DOWN)), 1)
182174 (zeroes + valS)
183175 }
184176
185177
186178 let MAXTOURNAMENTLENGTH = 1296000000
187179
188180 let HOUR = 3600000
189181
190182 let adminsList = [toString(this), match chain {
191183 case _ =>
192184 if ((base58'2W' == $match0))
193185 then "3PEe2RELUHCFCBsmSCNcBJ8N3URLVQende7"
194186 else if ((base58'2T' == $match0))
195187 then "3MtBgJTaLxPB3C7UJD1UE8qjkHthfKvFQYY"
196188 else throw("Unknown chain")
197189 }]
198190
199191 func staticData (txId,registerCost,attemptCost,creationTime,startTime,endTime,numGrands,prizeFund,prizeAsset) = makeString(["%s%d%d%d%d%d%d%d%s", txId, toString(registerCost), toString(attemptCost), toString(creationTime), toString(startTime), toString(endTime), toString(numGrands), toString(prizeFund), prizeAsset], SEP)
200192
201193
202194 func dynamicData (status,leaders,winResult,totalRegs,totalAttempts) = makeString_2C(["%s%s%d%d%d", status, leaders, toString(winResult), toString(totalRegs), toString(totalAttempts)], SEP)
203195
204196
205197 func prolog () = asInt(reentrantInvoke(stakingContract, "saveLastTx", nil, nil))
206198
207199
208200 func duckByCaller (caller) = valueOrErrorMessage(getString(stakingContract, keyStakedDuckByOwner(toString(caller))), "You don't have a duck staked")
209201
210202
211203 @Callable(i)
212204 func createTournament (startTime,endTime,registerCost,attemptCost,numGrands,prizeFund,prizeAsset) = {
213205 let caller = toString(i.caller)
214206 if (!(containsElement(adminsList, caller)))
215207 then throw("Permission denied")
216208 else {
217209 let lastId = getInteger(lastTourIdKey)
218210 let tId = if (isDefined(lastId))
219211 then {
220212 let lastTourId = value(lastId)
221213 let dynamic = valueOrErrorMessage(getString(keyTourDynamicDataById(lastTourId)), (("Error reading tournament " + toString(lastTourId)) + " data"))
222214 let status = split(dynamic, SEP)[tDynamicStatus]
223215 if (if ((status != "ARCHIVED"))
224216 then (status != "PROCESSING")
225217 else false)
226218 then throw(("Current tournement is not completed, status=" + status))
227219 else (lastTourId + 1)
228220 }
229221 else 1
230222 let now = lastBlock.timestamp
231223 if ((now > startTime))
232224 then throw(((("startTime=" + toString(startTime)) + " < creationTime=") + toString(now)))
233225 else if ((startTime > endTime))
234226 then throw(((("endTime=" + toString(endTime)) + " < startTime=") + toString(startTime)))
235227 else if (((endTime - startTime) > MAXTOURNAMENTLENGTH))
236228 then throw(((("Tournament period exceeds max: " + toString((endTime - startTime))) + " > ") + toString(MAXTOURNAMENTLENGTH)))
237229 else if (if ((0 > registerCost))
238230 then true
239231 else (0 > attemptCost))
240232 then throw(((("Cost should be positive, but passed " + toString(registerCost)) + " and ") + toString(attemptCost)))
241233 else if ((0 > numGrands))
242234 then throw("Number of Grand Prizes should be non-negative")
243235 else if ((0 > prizeFund))
244236 then throw("Prize Fund should be non-negative")
245237 else $Tuple2([IntegerEntry(lastTourIdKey, tId), StringEntry(keyTourStaticDataById(tId), staticData(toBase58String(i.transactionId), registerCost, attemptCost, now, startTime, endTime, numGrands, prizeFund, prizeAsset)), StringEntry(keyTourDynamicDataById(tId), dynamicData("CREATED", " ", 0, 0, 0))], tId)
246238 }
247239 }
248240
249241
250242
251243 @Callable(i)
252244 func register () = {
253245 let prologResult = prolog()
254246 if ((prologResult == prologResult))
255247 then {
256248 let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
257249 let now = lastBlock.timestamp
258250 let tData = getTourData(this, lastId)
259251 let static = tData[idxStatic]
260252 let dynamic = tData[idxDynamic]
261253 let status = dynamic[tDynamicStatus]
262254 if (!(if (if (if ((status == "CREATED"))
263255 then (now > parseIntValue(static[tStaticStart]))
264256 else false)
265257 then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
266258 else false)
267259 then true
268260 else if ((status == "INPROGRESS"))
269261 then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
270262 else false))
271263 then throw("Cannot register now")
272264 else {
273265 let regCost = parseIntValue(static[tStaticRegisterCost])
274266 let assetId = if ((size(static) > tStaticAsset))
275267 then fromBase58String(static[tStaticAsset])
276268 else wlgAssetId
277269 let nfo = valueOrErrorMessage(assetInfo(assetId), "No assetInfo available")
278270 let assetName = nfo.name
279271 let assetDecimals = nfo.decimals
280272 let regAmt = if ((regCost > 0))
281273 then if ((size(i.payments) != 1))
282274 then throw("exactly 1 payment must be attached")
283275 else {
284276 let pmt = i.payments[0]
285277 if (if (!(isDefined(pmt.assetId)))
286278 then true
287279 else (value(pmt.assetId) != assetId))
288280 then throw((assetName + " payments only!"))
289281 else pmt.amount
290282 }
291283 else if ((size(i.payments) != 0))
292284 then throw("No payments required")
293285 else 0
294286 if ((regAmt != regCost))
295287 then throw(((("Need payment of " + fixedPoint(regCost, assetDecimals)) + " ") + assetName))
296288 else {
297289 let duckAssetId = duckByCaller(i.originCaller)
298290 let scoreKey = keyScoreBoardByTour(lastId)
299291 let oldScoreBoard = valueOrElse(getString(scoreKey), "")
300292 if (if (valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false))
301293 then true
302294 else contains(oldScoreBoard, duckAssetId))
303295 then throw(((("Your duck " + duckAssetId) + " is already registered at tournament ") + toString(lastId)))
304296 else {
305297 let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), (parseIntValue(dynamic[tDynamicTotalRegCount]) + 1), parseIntValue(dynamic[tDynamicTotalAttempts]))
306298 $Tuple2([IntegerEntry(keyLastRegisteredTourByDuck(duckAssetId), lastId), BooleanEntry(keyIsRegisteredByTourAndDuck(lastId, duckAssetId), true), StringEntry(scoreKey, if ((oldScoreBoard == ""))
307299 then (duckAssetId + ":000")
308300 else (((oldScoreBoard + "_") + duckAssetId) + ":000")), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], prologResult)
309301 }
310302 }
311303 }
312304 }
313305 else throw("Strict value is not equal to itself.")
314306 }
315307
316308
317309
318310 @Callable(i)
319311 func newAttempt () = {
320312 let prologResult = prolog()
321313 if ((prologResult == prologResult))
322314 then {
323315 let duckAssetId = duckByCaller(i.originCaller)
324- let deliveryStatus = asBoolean(invoke(stakingContract, "checkDeliveryCallback", [duckAssetId], nil))
325- if (deliveryStatus)
326- then throw("newAttempt_checkDelivery")
327- else {
328- let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
329- let now = lastBlock.timestamp
330- let tData = getTourData(this, lastId)
331- let static = tData[idxStatic]
332- let dynamic = tData[idxDynamic]
333- let status = dynamic[tDynamicStatus]
334- if (!(if ((status == "INPROGRESS"))
335- then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
336- else false))
337- then throw("Attempt is not possible")
338- else if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false)))
339- then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(lastId)))
340- else {
341- let attemptsIteratorKey = keyLastAttemptByTourAndDuck(lastId, duckAssetId)
342- let lastAttempt = getInteger(attemptsIteratorKey)
343- let $t069177782 = if (!(isDefined(lastAttempt)))
344- then $Tuple2(0, 0)
345- else if ((size(i.payments) != 1))
346- then throw("exactly 1 payment must be attached")
316+ let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
317+ let now = lastBlock.timestamp
318+ let tData = getTourData(this, lastId)
319+ let static = tData[idxStatic]
320+ let dynamic = tData[idxDynamic]
321+ let status = dynamic[tDynamicStatus]
322+ if (!(if ((status == "INPROGRESS"))
323+ then ((parseIntValue(static[tStaticEnd]) - HOUR) > now)
324+ else false))
325+ then throw("Attempt is not possible")
326+ else if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(lastId, duckAssetId)), false)))
327+ then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(lastId)))
328+ else {
329+ let attemptsIteratorKey = keyLastAttemptByTourAndDuck(lastId, duckAssetId)
330+ let lastAttempt = getInteger(attemptsIteratorKey)
331+ let $t067497614 = if (!(isDefined(lastAttempt)))
332+ then $Tuple2(0, 0)
333+ else if ((size(i.payments) != 1))
334+ then throw("exactly 1 payment must be attached")
335+ else {
336+ let pmt = i.payments[0]
337+ let assetId = if ((size(static) > tStaticAsset))
338+ then fromBase58String(static[tStaticAsset])
339+ else wlgAssetId
340+ let nfo = valueOrErrorMessage(assetInfo(assetId), "No assetInfo available")
341+ let assetName = nfo.name
342+ let assetDecimals = nfo.decimals
343+ let amt = pmt.amount
344+ if (if (!(isDefined(pmt.assetId)))
345+ then true
346+ else (value(pmt.assetId) != assetId))
347+ then throw((assetName + " payments only!"))
347348 else {
348- let pmt = i.payments[0]
349- let assetId = if ((size(static) > tStaticAsset))
350- then fromBase58String(static[tStaticAsset])
351- else wlgAssetId
352- let nfo = valueOrErrorMessage(assetInfo(assetId), "No assetInfo available")
353- let assetName = nfo.name
354- let assetDecimals = nfo.decimals
355- let amt = pmt.amount
356- if (if (!(isDefined(pmt.assetId)))
357- then true
358- else (value(pmt.assetId) != assetId))
359- then throw((assetName + " payments only!"))
360- else {
361- let attCost = parseIntValue(static[tStaticAttemptCost])
362- if ((amt != attCost))
363- then throw(((("Need payment of " + fixedPoint(attCost, assetDecimals)) + " ") + assetName))
364- else $Tuple2((value(lastAttempt) + 1), 1)
365- }
349+ let attCost = parseIntValue(static[tStaticAttemptCost])
350+ if ((amt != attCost))
351+ then throw(((("Need payment of " + fixedPoint(attCost, assetDecimals)) + " ") + assetName))
352+ else $Tuple2((value(lastAttempt) + 1), 1)
366353 }
367- let payedAttempts = $t069177782._1
368- let increment = $t069177782._2
369- let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), (parseIntValue(dynamic[tDynamicTotalAttempts]) + increment))
370- let tourLoc = asString(invoke(stakingContract, "initDuckTourAttempt", [duckAssetId], nil))
371- $Tuple2([IntegerEntry(attemptsIteratorKey, payedAttempts), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], [prologResult, payedAttempts, tourLoc])
372- }
373- }
354+ }
355+ let payedAttempts = $t067497614._1
356+ let increment = $t067497614._2
357+ let updatedDynamicData = dynamicData("INPROGRESS", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), parseIntValue(dynamic[tDynamicTotalRegCount]), (parseIntValue(dynamic[tDynamicTotalAttempts]) + increment))
358+ let tourLoc = asString(invoke(stakingContract, "initDuckTourAttempt", [duckAssetId], nil))
359+ $Tuple2([IntegerEntry(attemptsIteratorKey, payedAttempts), StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)], [prologResult, payedAttempts, tourLoc])
360+ }
374361 }
375362 else throw("Strict value is not equal to itself.")
376363 }
377364
378365
379366
380367 @Callable(i)
381368 func saveDuckResult (duckAssetId,duckNewBest) = if ((i.caller != stakingContract))
382369 then throw("Access denied")
383370 else {
384371 let lastId = valueOrErrorMessage(getInteger(lastTourIdKey), "No active tournaments")
385372 let tData = getTourData(this, lastId)
386373 let static = tData[idxStatic]
387374 let dynamic = tData[idxDynamic]
388375 let curLocation = valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION)
389376 let bestResultKey = keyBestResultByTourAndDuck(lastId, duckAssetId)
390377 let sumScoresKey = keySumScoresByTour(lastId)
391378 let oldSumScores = valueOrElse(getInteger(sumScoresKey), 0)
392379 if (isInTournament(this, curLocation))
393380 then {
394381 let duckOldBest = valueOrElse(getInteger(bestResultKey), 0)
395382 let scoreKey = keyScoreBoardByTour(lastId)
396383 let oldScoreBoard = valueOrElse(getString(scoreKey), "")
397- let $t0927510436 = if ((duckNewBest > duckOldBest))
384+ let $t0910710268 = if ((duckNewBest > duckOldBest))
398385 then if (!(contains(oldScoreBoard, duckAssetId)))
399386 then throw(("scoreBoard does not contain " + duckAssetId))
400387 else {
401388 let oldBest = parseIntValue(dynamic[tDynamicWinResult])
402389 let leaders = dynamic[tDynamicLeaders]
403390 let oldLeadersList = if (if ((leaders == ""))
404391 then true
405392 else (leaders == " "))
406393 then nil
407394 else split_4C(leaders, ",")
408395 let newLeadersList = if ((duckNewBest > oldBest))
409396 then [duckAssetId]
410397 else if (if ((oldBest > duckNewBest))
411398 then true
412399 else containsElement(oldLeadersList, duckAssetId))
413400 then oldLeadersList
414401 else (oldLeadersList :+ duckAssetId)
415402 let updatedDynamicData = dynamicData("INPROGRESS", makeString_2C(newLeadersList, ","), max([duckNewBest, oldBest]), parseIntValue(dynamic[tDynamicTotalRegCount]), parseIntValue(dynamic[tDynamicTotalAttempts]))
416403 let parts = split_51C(oldScoreBoard, duckAssetId)
417404 $Tuple3(((((parts[0] + duckAssetId) + ":") + padL(duckNewBest, 3)) + drop(parts[1], 4)), ((oldSumScores + duckNewBest) - duckOldBest), [StringEntry(keyTourDynamicDataById(lastId), updatedDynamicData)])
418405 }
419406 else $Tuple3(oldScoreBoard, oldSumScores, nil)
420- let newScoreBoard = $t0927510436._1
421- let newSumScores = $t0927510436._2
422- let globalActions = $t0927510436._3
407+ let newScoreBoard = $t0910710268._1
408+ let newSumScores = $t0910710268._2
409+ let globalActions = $t0910710268._3
423410 $Tuple2(([IntegerEntry(bestResultKey, max([duckOldBest, duckNewBest])), IntegerEntry(sumScoresKey, newSumScores), StringEntry(keyBestTxByTourAndDuck(lastId, duckAssetId), toBase58String(i.transactionId)), StringEntry(scoreKey, newScoreBoard)] ++ globalActions), 0)
424411 }
425412 else $Tuple2(nil, 0)
426413 }
427414
428415
429416
430417 @Callable(i)
431418 func processTournament (tId) = {
432419 let caller = toString(i.caller)
433420 if (!(containsElement(adminsList, caller)))
434421 then throw("Permission denied")
435422 else {
436423 let now = lastBlock.timestamp
437424 let tData = getTourData(this, tId)
438425 let static = tData[idxStatic]
439426 let dynamic = tData[idxDynamic]
440427 let status = dynamic[tDynamicStatus]
441428 let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
442429 let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
443430 let regCost = parseIntValue(static[tStaticRegisterCost])
444431 let attCost = parseIntValue(static[tStaticAttemptCost])
445432 if ((status == "ARCHIVED"))
446433 then throw((("Tournament " + toString(tId)) + " is already ARCHIVED"))
447434 else if (if ((status == "INPROGRESS"))
448435 then (parseIntValue(static[tStaticEnd]) > now)
449436 else false)
450437 then throw((("Tournament " + toString(tId)) + " is not over yet"))
451438 else {
452439 let updatedDynamicData = dynamicData("PROCESSING", dynamic[tDynamicLeaders], parseIntValue(dynamic[tDynamicWinResult]), registrations, paidAttempts)
453440 let prizeFund = if ((size(static) > tStaticPrizeFund))
454441 then parseIntValue(static[tStaticPrizeFund])
455442 else 0
456443 let unpaid = ((((registrations * regCost) + (paidAttempts * attCost)) / 2) + prizeFund)
457444 $Tuple2([StringEntry(keyTourDynamicDataById(tId), updatedDynamicData), IntegerEntry(keyUnpaidRewardsByTour(tId), unpaid)], 0)
458445 }
459446 }
460447 }
461448
462449
463450
464451 @Callable(i)
465452 func claimPrize (tId) = {
466453 let prologResult = prolog()
467454 if ((prologResult == prologResult))
468455 then if ((size(i.payments) != 0))
469456 then throw("No payments required")
470457 else {
471458 let tData = getTourData(this, tId)
472459 let static = tData[idxStatic]
473460 let dynamic = tData[idxDynamic]
474461 let status = dynamic[tDynamicStatus]
475462 if ((status != "PROCESSING"))
476463 then throw((("Tournament " + toString(tId)) + " is not PROCESSING"))
477464 else {
478465 let registrations = parseIntValue(dynamic[tDynamicTotalRegCount])
479466 let paidAttempts = parseIntValue(dynamic[tDynamicTotalAttempts])
480467 let regCost = parseIntValue(static[tStaticRegisterCost])
481468 let attCost = parseIntValue(static[tStaticAttemptCost])
482469 let prizeFund = if ((size(static) > tStaticPrizeFund))
483470 then parseIntValue(static[tStaticPrizeFund])
484471 else 0
485472 let awardFunds = ((((registrations * regCost) + (paidAttempts * attCost)) / 2) + prizeFund)
486473 let unpaidKey = keyUnpaidRewardsByTour(tId)
487474 let unpaidFunds = valueOrElse(getInteger(unpaidKey), 0)
488475 let duckAssetId = duckByCaller(i.originCaller)
489476 if (!(valueOrElse(getBoolean(keyIsRegisteredByTourAndDuck(tId, duckAssetId)), false)))
490477 then throw(((("Your duck " + duckAssetId) + " is not registered at tournament ") + toString(tId)))
491478 else {
492479 let bestResultKey = keyBestResultByTourAndDuck(tId, duckAssetId)
493480 let duckBest = valueOrElse(getInteger(bestResultKey), 0)
494481 if ((duckBest == 0))
495482 then throw("Your duck got zero score")
496483 else {
497484 let awardedKey = keyIsAwardedByTourAndDuck(tId, duckAssetId)
498485 if (valueOrElse(getBoolean(awardedKey), false))
499486 then throw(((("Your duck " + duckAssetId) + " is already awarded at tournament ") + toString(tId)))
500487 else {
501488 let sumScoresKey = keySumScoresByTour(tId)
502489 let sumScores = valueOrElse(getInteger(sumScoresKey), 0)
503490 let leaders = dynamic[tDynamicLeaders]
504491 let leadersList = if (if ((leaders == ""))
505492 then true
506493 else (leaders == " "))
507494 then nil
508495 else split_4C(leaders, ",")
509496 let numLeaders = size(leadersList)
510497 if ((numLeaders == 0))
511498 then throw(("No leaders at tournament " + toString(tId)))
512499 else {
513500 let numGrands = parseIntValue(static[tStaticNumGrands])
514501 let winResult = parseIntValue(dynamic[tDynamicWinResult])
515502 let sumLeaderScores = if ((numLeaders > numGrands))
516503 then 0
517504 else if (containsElement(leadersList, duckAssetId))
518505 then throw("As one of winners, you will be awarded by admins")
519506 else (numLeaders * winResult)
520507 let yourAmount = min([fraction(duckBest, awardFunds, (sumScores - sumLeaderScores)), unpaidFunds])
521508 let newUnpaidAmount = (unpaidFunds - yourAmount)
522509 let updatedDynamicData = dynamicData("ARCHIVED", dynamic[tDynamicLeaders], winResult, registrations, paidAttempts)
523510 let archiveAction = if ((0 >= newUnpaidAmount))
524511 then [StringEntry(keyTourDynamicDataById(tId), updatedDynamicData)]
525512 else nil
526513 let assetId = if ((size(static) > tStaticAsset))
527514 then fromBase58String(static[tStaticAsset])
528515 else wlgAssetId
529516 let loc = split(valueOrElse(getString(stakingContract, keyDuckLocation(duckAssetId)), DEFAULTLOCATION), "_")
530517 let breakActions = if (if ((loc[locIdxType] == "T"))
531518 then (getTourData(this, parseIntValue(loc[locIdxContinent]))[idxDynamic][tDynamicStatus] == "PROCESSING")
532519 else false)
533520 then invoke(stakingContract, "breakAttemptCallback", nil, nil)
534521 else unit
535522 $Tuple2(([ScriptTransfer(i.caller, yourAmount, assetId), BooleanEntry(awardedKey, true), IntegerEntry(unpaidKey, newUnpaidAmount)] ++ archiveAction), breakActions)
536523 }
537524 }
538525 }
539526 }
540527 }
541528 }
542529 else throw("Strict value is not equal to itself.")
543530 }
544531
545532

github/deemru/w8io/169f3d6 
133.00 ms