2022.07.01 17:23 [3186298] smart account 3PPNhHYkkEy13gRWDCaruQyhNbX2GrjYSyV > SELF 0.00000000 Waves

{ "type": 13, "id": "CZcrtfFeTizUNMrJyehCJsEBVCQ24EbSCyXfr7dAZs53", "fee": 2900000, "feeAssetId": null, "timestamp": 1656685413514, "version": 1, "sender": "3PPNhHYkkEy13gRWDCaruQyhNbX2GrjYSyV", "senderPublicKey": "EAtbDa63mS5omrvW7Pfr7DKWEVLuReJtu72vfiBLRXsx", "proofs": [ "4TdgEqh83T89EHFbkmZPhANbyrB6Q4sBdcnGEUmdVriv5fvUUgQzSh9QksGczZYwWUdbi8Vvmj9NmHNTK7Enfkt9" ], "script": "base64:BgI3CAISAwoBCBIDCgEIEgMKAQgSABIAEgQKAggBEgMKAQgSBAoCCAgSBAoCCAgSAwoBCBIECgIICF0ABlNDQUxFOAAIAAVNVUxUOACAwtcvAAdTQ0FMRTE4ABIABk1VTFQxOAkAtgIBAICAkLu61q3wDQADU0VQAgJfXwAOUE9PTFdFSUdIVE1VTFQFBU1VTFQ4AAp6ZXJvQmlnSW50CQC2AgEAAAAJb25lQmlnSW50CQC2AgEAAQEJYXNBbnlMaXN0AQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAglMaXN0W0FueV0ECnZhbEFueUx5c3QFByRtYXRjaDAFCnZhbEFueUx5c3QJAAIBAhtmYWlsIHRvIGNhc3QgaW50byBMaXN0W0FueV0BBWFzSW50AQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgNJbnQEBnZhbEludAUHJG1hdGNoMAUGdmFsSW50CQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AQhhc1N0cmluZwEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAZ2YWxTdHIFByRtYXRjaDAFBnZhbFN0cgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEMYXNCeXRlVmVjdG9yAQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAZ2YWxCaW4FByRtYXRjaDAFBnZhbEJpbgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEPZ2V0U3RyaW5nT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFB2FkZHJlc3MFA2tleQkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUDa2V5Ag8gaXMgbm90IGRlZmluZWQBGGdldFN0cmluZ0J5QWRkcmVzc09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAKwCAgkArAICCQCsAgIJAKwCAgIKbWFuZGF0b3J5IAkApQgBBQdhZGRyZXNzAgEuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEMZ2V0SW50T3JaZXJvAgdhZGRyZXNzA2tleQkBC3ZhbHVlT3JFbHNlAgkAmggCBQdhZGRyZXNzBQNrZXkAAAEPZ2V0SW50T3JEZWZhdWx0AwdhZGRyZXNzA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCaCAIFB2FkZHJlc3MFA2tleQUKZGVmYXVsdFZhbAEMZ2V0SW50T3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFB2FkZHJlc3MFA2tleQkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUDa2V5Ag8gaXMgbm90IGRlZmluZWQBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CB2FkZHJlc3MDa2V5CQEFdmFsdWUBCQCoAwEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUHYWRkcmVzcwUDa2V5AgEwARxnZXRCaWdJbnRGcm9tU3RyaW5nT3JEZWZhdWx0AwdhZGRyZXNzA2tleQpkZWZhdWx0VmFsBAckbWF0Y2gwCQCdCAIFB2FkZHJlc3MFA2tleQMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJAQV2YWx1ZQEJAKgDAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQpkZWZhdWx0VmFsCQACAQILTWF0Y2ggZXJyb3IBBXRvWDE4AgdvcmlnVmFsDW9yaWdTY2FsZU11bHQJALwCAwkAtgIBBQdvcmlnVmFsBQZNVUxUMTgJALYCAQUNb3JpZ1NjYWxlTXVsdAEHZnJvbVgxOAIDdmFsD3Jlc3VsdFNjYWxlTXVsdAkAoAMBCQC8AgMFA3ZhbAkAtgIBBQ9yZXN1bHRTY2FsZU11bHQFBk1VTFQxOAERa2V5RmFjdG9yeUFkZHJlc3MAAhwlcyVzX19jb25maWdfX2ZhY3RvcnlBZGRyZXNzARlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0AAIaJXNfX3ZvdGluZ0VtaXNzaW9uQ29udHJhY3QAGElkeEZhY3RvcnlDZmdTdGFraW5nRGFwcAABABlJZHhGYWN0b3J5Q2ZnQm9vc3RpbmdEYXBwAAIAFElkeEZhY3RvcnlDZmdJZG9EYXBwAAMAFUlkeEZhY3RvcnlDZmdUZWFtRGFwcAAEABlJZHhGYWN0b3J5Q2ZnRW1pc3Npb25EYXBwAAUAFUlkeEZhY3RvcnlDZmdSZXN0RGFwcAAGABlJZHhGYWN0b3J5Q2ZnU2xpcHBhZ2VEYXBwAAcBDWtleUZhY3RvcnlDZmcAAhElc19fZmFjdG9yeUNvbmZpZwETa2V5TWFuYWdlclB1YmxpY0tleQACFCVzX19tYW5hZ2VyUHVibGljS2V5ARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEWa2V5U3RhYmxlUG9vbEFkZG9uQWRkcgACFyVzX19zdGFibGVQb29sQWRkb25BZGRyARprZXlGYWN0b3J5THAyQXNzZXRzTWFwcGluZwEKbHBBc3NldFN0cgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQpscEFzc2V0U3RyCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQNTRVABEGtleUZhY3RvcnlMcExpc3QAAhAlc19fbHBUb2tlbnNMaXN0ASZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwEKbHBBc3NldFN0cgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQpscEFzc2V0U3RyCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQNTRVABFGtleUZhY3RvcnlQb29sV2VpZ2h0AQ9jb250cmFjdEFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICCnBvb2xXZWlnaHQJAMwIAgUPY29udHJhY3RBZGRyZXNzBQNuaWwFA1NFUAEKcmVhZExwTGlzdAEHZmFjdG9yeQkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFB2ZhY3RvcnkJARBrZXlGYWN0b3J5THBMaXN0AAIABQNTRVABFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsAQdmYWN0b3J5CQC1CQIJARhnZXRTdHJpbmdCeUFkZHJlc3NPckZhaWwCBQdmYWN0b3J5CQENa2V5RmFjdG9yeUNmZwAFA1NFUAEYZ2V0Qm9vc3RpbmdBZGRyZXNzT3JGYWlsAQpmYWN0b3J5Q2ZnCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFCmZhY3RvcnlDZmcFGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHABGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRlJZHhGYWN0b3J5Q2ZnRW1pc3Npb25EYXBwARdnZXRTdGFraW5nQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHABHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAACGyVzJXNfX3JhdGVQZXJCbG9ja19fY3VycmVudAEha2V5RW1pc3Npb25SYXRlUGVyQmxvY2tNYXhDdXJyZW50AAIeJXMlc19fcmF0ZVBlckJsb2NrTWF4X19jdXJyZW50ARVrZXlFbWlzc2lvblN0YXJ0QmxvY2sAAholcyVzX19lbWlzc2lvbl9fc3RhcnRCbG9jawEba2V5RW1pc3Npb25EdXJhdGlvbkluQmxvY2tzAAIYJXMlc19fZW1pc3Npb25fX2R1cmF0aW9uARNrZXlFbWlzc2lvbkVuZEJsb2NrAAIYJXMlc19fZW1pc3Npb25fX2VuZEJsb2NrAQ9rZXlTdGFrZWRCeVVzZXICDnVzZXJBZGRyZXNzU3RyDGxwQXNzZXRJZFN0cgkAuQkCCQDMCAICDiVzJXMlc19fc3Rha2VkCQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIFDGxwQXNzZXRJZFN0cgUDbmlsBQNTRVABDmtleVN0YWtlZFRvdGFsAQxscEFzc2V0SWRTdHIJAKwCAgIXJXMlcyVzX19zdGFrZWRfX3RvdGFsX18FDGxwQXNzZXRJZFN0cgEQa2V5Q2xhaW1lZEJ5VXNlcgIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyCQC5CQIJAMwIAgIPJXMlcyVzX19jbGFpbWVkCQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIFDGxwQXNzZXRJZFN0cgUDbmlsBQNTRVABGWtleUNsYWltZWRCeVVzZXJNaW5SZXdhcmQCDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cgkAuQkCCQDMCAICGCVzJXMlc19fY2xhaW1lZE1pblJld2FyZAkAzAgCBQ51c2VyQWRkcmVzc1N0cgkAzAgCBQxscEFzc2V0SWRTdHIFA25pbAUDU0VQARtrZXlDbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmQCDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cgkAuQkCCQDMCAICGiVzJXMlc19fY2xhaW1lZEJvb3N0UmV3YXJkCQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIFDGxwQXNzZXRJZFN0cgUDbmlsBQNTRVABD2tleUNsYWltZWRUb3RhbAEMbHBBc3NldElkU3RyCQC5CQIJAMwIAgIWJXMlcyVzX19jbGFpbWVkX190b3RhbAkAzAgCBQxscEFzc2V0SWRTdHIFA25pbAUDU0VQAQpyZWFkU3Rha2VkAQNrZXkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUDa2V5AAABFWtleUxhc3RUb3RhbExwQmFsYW5jZQEJbHBBc3NldElkCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCAgV0b3RhbAkAzAgCAgNiYWwFA25pbAUDU0VQARRrZXlMYXN0VXNlckxwQmFsYW5jZQIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCAgNiYWwFA25pbAUDU0VQARlrZXlUb3RhbExwQmFsYW5jZUludGVncmFsAQlscEFzc2V0SWQJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAICBXRvdGFsCQDMCAICBmJhbElOVAUDbmlsBQNTRVABGGtleVVzZXJMcEJhbGFuY2VJbnRlZ3JhbAIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCAgZiYWxJTlQFA25pbAUDU0VQASZrZXlUb3RhbExwQmFsYW5jZUludGVncmFsTGFzdFVwZEhlaWdodAEJbHBBc3NldElkCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCAgV0b3RhbAkAzAgCAgdsYXN0VXBkBQNuaWwFA1NFUAEla2V5VXNlckxwQmFsYW5jZUludGVncmFsTGFzdFVwZEhlaWdodAIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCAgdsYXN0VXBkBQNuaWwFA1NFUAESa2V5V3hQZXJMcEludGVncmFsAQlscEFzc2V0SWQJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQlscEFzc2V0SWQJAMwIAgIGY29tbW9uCQDMCAICBWxwSW50BQNuaWwFA1NFUAEfa2V5V3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodAEJbHBBc3NldElkCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAICBmNvbW1vbgkAzAgCAgZscEludEgFA25pbAUDU0VQARBrZXlXeFRvQ2xhaW1Vc2VyAglscEFzc2V0SWQLdXNlckFkZHJlc3MJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQlscEFzc2V0SWQJAMwIAgULdXNlckFkZHJlc3MJAMwIAgIFbHBJbnQFA25pbAUDU0VQASNrZXlXeFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodAIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAICBmxwSW50SAUDbmlsBQNTRVABCmtleVd4UGVyTHABCWxwQXNzZXRJZAkAuQkCCQDMCAICAiVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCAgd3eFBlckxwBQNuaWwFA1NFUAENa2V5V3hQZXJMcFgxOAEJbHBBc3NldElkCQC5CQIJAMwIAgICJXMJAMwIAgUJbHBBc3NldElkCQDMCAICCnd4UGVyTHBYMTgFA25pbAUDU0VQARprZXlXeFBlckxwSW50ZWdyYWxVc2VyTGFzdAIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAICBXVJbnRMBQNuaWwFA1NFUAEZa2V5T3BlcmF0aW9uSGlzdG9yeVJlY29yZAMEdHlwZQt1c2VyQWRkcmVzcwZ0eElkNTgJALkJAgkAzAgCAhElcyVzJXMlc19faGlzdG9yeQkAzAgCBQR0eXBlCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFBnR4SWQ1OAUDbmlsBQNTRVABE2Zvcm1hdEhpc3RvcnlSZWNvcmQEC3VzZXJBZGRyZXNzCWxwQXNzZXRJZAR0eXBlBmFtb3VudAkAuQkCCQDMCAICDCVzJXMlcyVkJWQlZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCBQlscEFzc2V0SWQJAMwIAgUEdHlwZQkAzAgCCQCkAwEFBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUGYW1vdW50BQNuaWwFA1NFUAEVT3BlcmF0aW9uSGlzdG9yeUVudHJ5BQR0eXBlC3VzZXJBZGRyZXNzCWxwQXNzZXRJZAZhbW91bnQEdHhJZAkBC1N0cmluZ0VudHJ5AgkBGWtleU9wZXJhdGlvbkhpc3RvcnlSZWNvcmQDBQR0eXBlBQt1c2VyQWRkcmVzcwkA2AQBBQR0eElkCQETZm9ybWF0SGlzdG9yeVJlY29yZAQFC3VzZXJBZGRyZXNzBQlscEFzc2V0SWQFBHR5cGUFBmFtb3VudAAOZmFjdG9yeUFkZHJlc3MJAQ9nZXRTdHJpbmdPckZhaWwCBQR0aGlzCQERa2V5RmFjdG9yeUFkZHJlc3MAAA9mYWN0b3J5Q29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDmZhY3RvcnlBZGRyZXNzAApmYWN0b3J5Q2ZnCQEUcmVhZEZhY3RvcnlDZmdPckZhaWwBBQ9mYWN0b3J5Q29udHJhY3QAEGVtaXNzaW9uQ29udHJhY3QJARhnZXRFbWlzc2lvbkFkZHJlc3NPckZhaWwBBQpmYWN0b3J5Q2ZnABBib29zdGluZ0NvbnRyYWN0CQEYZ2V0Qm9vc3RpbmdBZGRyZXNzT3JGYWlsAQUKZmFjdG9yeUNmZwELa2V5TmV4dFVzZXIBCWxwQXNzZXRJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAICCG5leHRVc2VyBQNuaWwFA1NFUAEQZ2V0VXNlcnNMaXN0TmFtZQEJbHBBc3NldElkCQC5CQIJAMwIAgIFdXNlcnMJAMwIAgUJbHBBc3NldElkBQNuaWwFA1NFUAELa2V5TGlzdEhlYWQBCGxpc3ROYW1lCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCGxpc3ROYW1lCQDMCAICBGhlYWQFA25pbAUDU0VQAQtrZXlMaXN0U2l6ZQEIbGlzdE5hbWUJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUIbGlzdE5hbWUJAMwIAgIEc2l6ZQUDbmlsBQNTRVABC2tleUxpc3RQcmV2AghsaXN0TmFtZQJpZAkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFCGxpc3ROYW1lCQDMCAIFAmlkCQDMCAICBHByZXYFA25pbAUDU0VQAQtrZXlMaXN0TmV4dAIIbGlzdE5hbWUCaWQJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQhsaXN0TmFtZQkAzAgCBQJpZAkAzAgCAgRuZXh0BQNuaWwFA1NFUAEMY29udGFpbnNOb2RlAghsaXN0TmFtZQJpZAQKaGVhZE9yVW5pdAkAnQgCBQR0aGlzCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQQKcHJldk9yVW5pdAkAnQgCBQR0aGlzCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQUCaWQECm5leHRPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3ROZXh0AgUIbGlzdE5hbWUFAmlkAwMJAAACBQJpZAkBC3ZhbHVlT3JFbHNlAgUKaGVhZE9yVW5pdAIABgkBAiE9AgUKcHJldk9yVW5pdAUEdW5pdAYJAQIhPQIFCm5leHRPclVuaXQFBHVuaXQBEWluc2VydE5vZGVBY3Rpb25zAghsaXN0TmFtZQJpZAQKaGVhZE9yVW5pdAkAnQgCBQR0aGlzCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQQIbGlzdFNpemUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBC2tleUxpc3RTaXplAQUIbGlzdE5hbWUAAAQJY2hlY2tOb2RlAwkBASEBCQEMY29udGFpbnNOb2RlAgUIbGlzdE5hbWUFAmlkBgkAAgECC05vZGUgZXhpc3RzAwkAAAIFCWNoZWNrTm9kZQUJY2hlY2tOb2RlCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBC2tleUxpc3RTaXplAQUIbGlzdE5hbWUJAGQCBQhsaXN0U2l6ZQABBQNuaWwDCQECIT0CBQpoZWFkT3JVbml0BQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lBQJpZAkBBXZhbHVlAQUKaGVhZE9yVW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQkBBXZhbHVlAQUKaGVhZE9yVW5pdAUCaWQFA25pbAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQtrZXlMaXN0SGVhZAEFCGxpc3ROYW1lBQJpZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuARFkZWxldGVOb2RlQWN0aW9ucwIIbGlzdE5hbWUCaWQECmhlYWRPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3RIZWFkAQUIbGlzdE5hbWUECGxpc3RTaXplCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQtrZXlMaXN0U2l6ZQEFCGxpc3ROYW1lAAAECnByZXZPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUFAmlkBApuZXh0T3JVbml0CQCdCAIFBHRoaXMJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lBQJpZAkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQELa2V5TGlzdFNpemUBBQhsaXN0TmFtZQkAZQIFCGxpc3RTaXplAAEFA25pbAMDCQECIT0CBQpwcmV2T3JVbml0BQR1bml0CQECIT0CBQpuZXh0T3JVbml0BQR1bml0BwkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdE5leHQCBQhsaXN0TmFtZQkBBXZhbHVlAQUKcHJldk9yVW5pdAkBBXZhbHVlAQUKbmV4dE9yVW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQkBBXZhbHVlAQUKbmV4dE9yVW5pdAkBBXZhbHVlAQUKcHJldk9yVW5pdAkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQUCaWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleUxpc3ROZXh0AgUIbGlzdE5hbWUFAmlkBQNuaWwDCQECIT0CBQpuZXh0T3JVbml0BQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQtrZXlMaXN0SGVhZAEFCGxpc3ROYW1lCQEFdmFsdWUBBQpuZXh0T3JVbml0CQDMCAIJAQtEZWxldGVFbnRyeQEJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lBQJpZAkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQkBBXZhbHVlAQUKbmV4dE9yVW5pdAUDbmlsAwkBAiE9AgUKcHJldk9yVW5pdAUEdW5pdAkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQUCaWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleUxpc3ROZXh0AgUIbGlzdE5hbWUJAQV2YWx1ZQEFCnByZXZPclVuaXQFA25pbAMJAAACBQJpZAkBC3ZhbHVlT3JFbHNlAgUKaGVhZE9yVW5pdAIACQDMCAIJAQtEZWxldGVFbnRyeQEJAQtrZXlMaXN0SGVhZAEFCGxpc3ROYW1lBQNuaWwJAAIBCQCsAgIJAKwCAgkArAICAg5pbnZhbGlkIG5vZGU6IAUIbGlzdE5hbWUCAS4FAmlkARtjYWxjV3hQZXJMcEludGVncmFsVXNlckxhc3QEDHN0YWtlZEJ5VXNlciZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybxJ3eFBlckxwSW50ZWdyYWxOZXcad3hQZXJMcEludGVncmFsVXNlckxhc3RLRVkDAwkAAAIFJnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0T3JaZXJvBQp6ZXJvQmlnSW50CQC/AgIFDHN0YWtlZEJ5VXNlcgUKemVyb0JpZ0ludAcFCnplcm9CaWdJbnQDCQAAAgUMc3Rha2VkQnlVc2VyBQp6ZXJvQmlnSW50BRJ3eFBlckxwSW50ZWdyYWxOZXcDAwkAvwICBSZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybwUKemVyb0JpZ0ludAkAvwICBQxzdGFrZWRCeVVzZXIFCnplcm9CaWdJbnQHCQEFdmFsdWUBCQCoAwEJAQ9nZXRTdHJpbmdPckZhaWwCBQR0aGlzBRp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdEtFWQkAAgECLWNhbGNXeFBlckxwSW50ZWdyYWxVc2VyTGFzdDogdW5leHBlY3RlZCBzdGF0ZQEUcmVmcmVzaFBvb2xJTlRFR1JBTFMDDGxwQXNzZXRJZFN0cg5wb29sQWRkcmVzc1N0cg1scERlbHRhQW1vdW50BA5zdGFrZWRUb3RhbEtFWQkBDmtleVN0YWtlZFRvdGFsAQUMbHBBc3NldElkU3RyBAtzdGFrZWRUb3RhbAkAtgIBCQEKcmVhZFN0YWtlZAEFDnN0YWtlZFRvdGFsS0VZBBJub25aZXJvU3Rha2VkVG90YWwDCQAAAgULc3Rha2VkVG90YWwFCnplcm9CaWdJbnQFCW9uZUJpZ0ludAULc3Rha2VkVG90YWwECnBvb2xXZWlnaHQJARFAZXh0ck5hdGl2ZSgxMDUwKQIFD2ZhY3RvcnlDb250cmFjdAkBFGtleUZhY3RvcnlQb29sV2VpZ2h0AQUOcG9vbEFkZHJlc3NTdHIEEmVtaXNzaW9uU3RhcnRCbG9jawkBDGdldEludE9yRmFpbAIFEGVtaXNzaW9uQ29udHJhY3QJARVrZXlFbWlzc2lvblN0YXJ0QmxvY2sABAVNVUxUMwDoBwQUd3hFbWlzc2lvblBlckJsb2NrWDMJAGgCCQEMZ2V0SW50T3JGYWlsAgUQZW1pc3Npb25Db250cmFjdAkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAFBU1VTFQzBBhwb29sV3hFbWlzc2lvblBlckJsb2NrWDMJAGsDBRR3eEVtaXNzaW9uUGVyQmxvY2tYMwUKcG9vbFdlaWdodAkAaAIFDlBPT0xXRUlHSFRNVUxUAAMEEnd4UGVyTHBJbnRlZ3JhbEtFWQkBEmtleVd4UGVyTHBJbnRlZ3JhbAEFDGxwQXNzZXRJZFN0cgQfd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodEtFWQkBH2tleVd4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHQBBQxscEFzc2V0SWRTdHIECnd4UGVyTHBLRVkJAQprZXlXeFBlckxwAQUMbHBBc3NldElkU3RyBBx3eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0CQEPZ2V0SW50T3JEZWZhdWx0AwUEdGhpcwUfd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodEtFWQUSZW1pc3Npb25TdGFydEJsb2NrBA93eFBlckxwSW50ZWdyYWwJARlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvAgUEdGhpcwUSd3hQZXJMcEludGVncmFsS0VZBA93eFBlckxwT3JaZXJvWDMAAAQCZGgJAJYDAQkAzAgCCQBlAgUGaGVpZ2h0BRx3eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0CQDMCAIAAAUDbmlsBAl3eFBlckxwWDMDCQECIT0CBQ93eFBlckxwT3JaZXJvWDMAAAkAtgIBBQ93eFBlckxwT3JaZXJvWDMJALwCAwkAtgIBBRhwb29sV3hFbWlzc2lvblBlckJsb2NrWDMJALYCAQUFTVVMVDgFEm5vblplcm9TdGFrZWRUb3RhbAQOc3Rha2VkVG90YWxOZXcJALcCAgULc3Rha2VkVG90YWwJALYCAQUNbHBEZWx0YUFtb3VudAQVbm9uWmVyb1N0YWtlZFRvdGFsTmV3AwkAAAIFDnN0YWtlZFRvdGFsTmV3BQp6ZXJvQmlnSW50BQlvbmVCaWdJbnQFDnN0YWtlZFRvdGFsTmV3BBJ3eFBlckxwSW50ZWdyYWxOZXcJALcCAgUPd3hQZXJMcEludGVncmFsCQC5AgIFCXd4UGVyTHBYMwkAtgIBBQJkaAQMd3hQZXJMcFgzTmV3CQC6AgIJALYCAQUYcG9vbFd4RW1pc3Npb25QZXJCbG9ja1gzBRVub25aZXJvU3Rha2VkVG90YWxOZXcEH3d4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHROZXcFBmhlaWdodAQFZGVidWcJALkJAgkAzAgCCQCmAwEFEnd4UGVyTHBJbnRlZ3JhbE5ldwkAzAgCCQCkAwEFAmRoCQDMCAIJAKYDAQUJd3hQZXJMcFgzCQDMCAIJAKYDAQULc3Rha2VkVG90YWwJAMwIAgkApAMBBRhwb29sV3hFbWlzc2lvblBlckJsb2NrWDMJAMwIAgkApAMBBRR3eEVtaXNzaW9uUGVyQmxvY2tYMwkAzAgCCQCkAwEFCnBvb2xXZWlnaHQFA25pbAICOjoJAJUKAwUSd3hQZXJMcEludGVncmFsTmV3CQDMCAIJAQtTdHJpbmdFbnRyeQIFEnd4UGVyTHBJbnRlZ3JhbEtFWQkApgMBBRJ3eFBlckxwSW50ZWdyYWxOZXcJAMwIAgkBDEludGVnZXJFbnRyeQIFH3d4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHRLRVkFH3d4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHROZXcJAMwIAgkBC1N0cmluZ0VudHJ5AgUKd3hQZXJMcEtFWQkApgMBBQx3eFBlckxwWDNOZXcFA25pbAUFZGVidWcBEHJlZnJlc2hJTlRFR1JBTFMEDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cg5wb29sQWRkcmVzc1N0cg1scERlbHRhQW1vdW50BA0kdDAxNDIxNzE0MzM5CQEUcmVmcmVzaFBvb2xJTlRFR1JBTFMDBQxscEFzc2V0SWRTdHIFDnBvb2xBZGRyZXNzU3RyBQ1scERlbHRhQW1vdW50BBJ3eFBlckxwSW50ZWdyYWxOZXcIBQ0kdDAxNDIxNzE0MzM5Al8xBBFwb29sSW50ZWdyYWxTVEFURQgFDSR0MDE0MjE3MTQzMzkCXzIECXBvb2xERUJVRwgFDSR0MDE0MjE3MTQzMzkCXzMEBU1VTFQzAOgHBA9zdGFrZWRCeVVzZXJLRVkJAQ9rZXlTdGFrZWRCeVVzZXICBQ51c2VyQWRkcmVzc1N0cgUMbHBBc3NldElkU3RyBAxzdGFrZWRCeVVzZXIJAQpyZWFkU3Rha2VkAQUPc3Rha2VkQnlVc2VyS0VZBBB3eFRvQ2xhaW1Vc2VyS0VZCQEQa2V5V3hUb0NsYWltVXNlcgIFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIEI3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0S0VZCQEja2V5V3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHQCBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBBp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdEtFWQkBGmtleVd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0AgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQNd3hUb0NsYWltVXNlcgkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBRB3eFRvQ2xhaW1Vc2VyS0VZBCZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybwkBDGdldEludE9yWmVybwIFBHRoaXMFI3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0S0VZBBd3eFBlckxwSW50ZWdyYWxVc2VyTGFzdAkBG2NhbGNXeFBlckxwSW50ZWdyYWxVc2VyTGFzdAQJALYCAQUMc3Rha2VkQnlVc2VyCQC2AgEFJnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0T3JaZXJvBRJ3eFBlckxwSW50ZWdyYWxOZXcFGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0S0VZBAZNVUxUMTEJAGgCBQVNVUxUOAUFTVVMVDMEEHd4VG9DbGFpbVVzZXJOZXcJAJgDAQkAzAgCCQC3AgIFDXd4VG9DbGFpbVVzZXIJALwCAwkAuAICBRJ3eFBlckxwSW50ZWdyYWxOZXcFF3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0CQC2AgEFDHN0YWtlZEJ5VXNlcgkAtgIBBQZNVUxUMTEJAMwIAgUKemVyb0JpZ0ludAUDbmlsBBp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdE5ldwUSd3hQZXJMcEludGVncmFsTmV3BCN3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE5ldwUGaGVpZ2h0BAVkZWJ1ZwkAuQkCCQDMCAIJAKYDAQUNd3hUb0NsYWltVXNlcgkAzAgCCQCmAwEFF3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0CQDMCAIJAKQDAQUMc3Rha2VkQnlVc2VyCQDMCAIFCXBvb2xERUJVRwkAzAgCCQCkAwEFBmhlaWdodAUDbmlsAgI6OgkAlQoDBRB3eFRvQ2xhaW1Vc2VyTmV3CQDOCAIFEXBvb2xJbnRlZ3JhbFNUQVRFCQDMCAIJAQtTdHJpbmdFbnRyeQIFEHd4VG9DbGFpbVVzZXJLRVkJAKYDAQUQd3hUb0NsYWltVXNlck5ldwkAzAgCCQEMSW50ZWdlckVudHJ5AgUjd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRLRVkFI3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0TmV3CQDMCAIJAQtTdHJpbmdFbnRyeQIFGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0S0VZCQCmAwEFGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0TmV3BQNuaWwFBWRlYnVnARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAQHJG1hdGNoMAkAoggBCQETa2V5TWFuYWdlclB1YmxpY0tleQADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAR1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdAAEByRtYXRjaDAJAKIIAQkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJANkEAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IAFXBlcm1pc3Npb25EZW5pZWRFcnJvcgkAAgECEVBlcm1pc3Npb24gZGVuaWVkAQhtdXN0VGhpcwEBaQMJAAACCAUBaQZjYWxsZXIFBHRoaXMGBRVwZXJtaXNzaW9uRGVuaWVkRXJyb3IBC211c3RNYW5hZ2VyAQFpBAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDADCQAAAggFAWkPY2FsbGVyUHVibGljS2V5BQJwawYFFXBlcm1pc3Npb25EZW5pZWRFcnJvcgMJAAECBQckbWF0Y2gwAgRVbml0AwkAAAIIBQFpBmNhbGxlcgUEdGhpcwYFFXBlcm1pc3Npb25EZW5pZWRFcnJvcgkAAgECC01hdGNoIGVycm9yCwFpAQtjb25zdHJ1Y3RvcgERZmFjdG9yeUFkZHJlc3NTdHIEC2NoZWNrQ2FsbGVyCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5RmFjdG9yeUFkZHJlc3MABRFmYWN0b3J5QWRkcmVzc1N0cgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDWNvbnN0cnVjdG9yVjIBFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QEBWNoZWtzCQDMCAIJAQttdXN0TWFuYWdlcgEFAWkJAMwIAgMJAQIhPQIJAKYIAQUWdm90aW5nRW1pc3Npb25Db250cmFjdAUEdW5pdAYCKGludmFsaWQgdm90aW5nIGVtaXNzaW9uIGNvbnRyYWN0IGFkZHJlc3MFA25pbAMJAAACBQVjaGVrcwUFY2hla3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBGWtleVZvdGluZ0VtaXNzaW9uQ29udHJhY3QABRZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKc2V0TWFuYWdlcgEXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkEC2NoZWNrQ2FsbGVyCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQDZBAEFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AwkAAAIFFWNoZWNrTWFuYWdlclB1YmxpY0tleQUVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIJARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQAFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOY29uZmlybU1hbmFnZXIABAJwbQkBHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0AAQFaGFzUE0DCQEJaXNEZWZpbmVkAQUCcG0GCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFBWhhc1BNBQVoYXNQTQQHY2hlY2tQTQMJAAACCAUBaQ9jYWxsZXJQdWJsaWNLZXkJAQV2YWx1ZQEFAnBtBgkAAgECG1lvdSBhcmUgbm90IHBlbmRpbmcgbWFuYWdlcgMJAAACBQdjaGVja1BNBQdjaGVja1BNCQDMCAIJAQtTdHJpbmdFbnRyeQIJARNrZXlNYW5hZ2VyUHVibGljS2V5AAkA2AQBCQEFdmFsdWUBBQJwbQkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEFc3Rha2UAAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQI0aW52YWxpZCBwYXltZW50IC0gZXhhY3Qgb25lIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAECWxwQXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAxscEFzc2V0SWRTdHIJANgEAQUJbHBBc3NldElkBAZhbW91bnQIBQNwbXQGYW1vdW50BA5wb29sQWRkcmVzc1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD2ZhY3RvcnlDb250cmFjdAkBGmtleUZhY3RvcnlMcDJBc3NldHNNYXBwaW5nAQUMbHBBc3NldElkU3RyCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUMbHBBc3NldElkU3RyBAljYWxsZXJTdHIJAKUIAQgFAWkGY2FsbGVyBA51c2VyQWRkcmVzc1N0cgMJAAACBQljYWxsZXJTdHIFDnBvb2xBZGRyZXNzU3RyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgUJY2FsbGVyU3RyBA9zdGFrZWRCeVVzZXJLRVkJAQ9rZXlTdGFrZWRCeVVzZXICBQ51c2VyQWRkcmVzc1N0cgUMbHBBc3NldElkU3RyBA5zdGFrZWRUb3RhbEtFWQkBDmtleVN0YWtlZFRvdGFsAQUMbHBBc3NldElkU3RyBAxzdGFrZWRCeVVzZXIJAQpyZWFkU3Rha2VkAQUPc3Rha2VkQnlVc2VyS0VZBAtzdGFrZWRUb3RhbAkBCnJlYWRTdGFrZWQBBQ5zdGFrZWRUb3RhbEtFWQQNJHQwMTg3NzUxODg5MgkBEHJlZnJlc2hJTlRFR1JBTFMEBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBQ5wb29sQWRkcmVzc1N0cgUGYW1vdW50BBB3eFRvQ2xhaW1Vc2VyTmV3CAUNJHQwMTg3NzUxODg5MgJfMQQNaW50ZWdyYWxTVEFURQgFDSR0MDE4Nzc1MTg4OTICXzIEBWRlYnVnCAUNJHQwMTg3NzUxODg5MgJfMwQIbGlzdE5hbWUJARBnZXRVc2Vyc0xpc3ROYW1lAQUMbHBBc3NldElkU3RyBAtsaXN0QWN0aW9ucwMJAQxjb250YWluc05vZGUCBQhsaXN0TmFtZQUOdXNlckFkZHJlc3NTdHIFA25pbAkBEWluc2VydE5vZGVBY3Rpb25zAgUIbGlzdE5hbWUFDnVzZXJBZGRyZXNzU3RyCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUPc3Rha2VkQnlVc2VyS0VZCQBkAgUMc3Rha2VkQnlVc2VyBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFDnN0YWtlZFRvdGFsS0VZCQBkAgULc3Rha2VkVG90YWwFBmFtb3VudAkAzAgCCQEVT3BlcmF0aW9uSGlzdG9yeUVudHJ5BQIFc3Rha2UFDnVzZXJBZGRyZXNzU3RyBQxscEFzc2V0SWRTdHIFBmFtb3VudAgFAWkNdHJhbnNhY3Rpb25JZAUDbmlsBQ1pbnRlZ3JhbFNUQVRFBQtsaXN0QWN0aW9ucwFpAQd1bnN0YWtlAgxscEFzc2V0SWRTdHIGYW1vdW50BAlscEFzc2V0SWQJANkEAQUMbHBBc3NldElkU3RyBA5wb29sQWRkcmVzc1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD2ZhY3RvcnlDb250cmFjdAkBGmtleUZhY3RvcnlMcDJBc3NldHNNYXBwaW5nAQUMbHBBc3NldElkU3RyCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUMbHBBc3NldElkU3RyBAlwb29sQWRkb24JAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBFmtleVN0YWJsZVBvb2xBZGRvbkFkZHIABQ5wb29sQWRkcmVzc1N0cgQJY2FsbGVyU3RyCQClCAEIBQFpBmNhbGxlcgQOdXNlckFkZHJlc3NTdHIDAwkAAAIFCWNhbGxlclN0cgUOcG9vbEFkZHJlc3NTdHIGCQAAAgUJY2FsbGVyU3RyBQlwb29sQWRkb24JAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBQljYWxsZXJTdHIED3N0YWtlZEJ5VXNlcktFWQkBD2tleVN0YWtlZEJ5VXNlcgIFDnVzZXJBZGRyZXNzU3RyBQxscEFzc2V0SWRTdHIEDnN0YWtlZFRvdGFsS0VZCQEOa2V5U3Rha2VkVG90YWwBBQxscEFzc2V0SWRTdHIEDHN0YWtlZEJ5VXNlcgkBCnJlYWRTdGFrZWQBBQ9zdGFrZWRCeVVzZXJLRVkEC3N0YWtlZFRvdGFsCQEKcmVhZFN0YWtlZAEFDnN0YWtlZFRvdGFsS0VZBA1pbnRlZ3JhbFNUQVRFCAkBEHJlZnJlc2hJTlRFR1JBTFMEBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBQ5wb29sQWRkcmVzc1N0cgkBAS0BBQZhbW91bnQCXzIECGxpc3ROYW1lCQEQZ2V0VXNlcnNMaXN0TmFtZQEFDGxwQXNzZXRJZFN0cgQLbGlzdEFjdGlvbnMDAwkBDGNvbnRhaW5zTm9kZQIFCGxpc3ROYW1lBQ51c2VyQWRkcmVzc1N0cgkAAAIFBmFtb3VudAUMc3Rha2VkQnlVc2VyBwkBEWRlbGV0ZU5vZGVBY3Rpb25zAgUIbGlzdE5hbWUFDnVzZXJBZGRyZXNzU3RyBQNuaWwEDWNsYWltZWRCeVVzZXIJARlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvAgUEdGhpcwkBEGtleUNsYWltZWRCeVVzZXICBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBAtwb29sQWRkcmVzcwkBGGdldFN0cmluZ0J5QWRkcmVzc09yRmFpbAIFD2ZhY3RvcnlDb250cmFjdAkBJmtleUZhY3RvcnlMcEFzc2V0VG9Qb29sQ29udHJhY3RBZGRyZXNzAQUMbHBBc3NldElkU3RyBBB3eFRvQ2xhaW1Vc2VyTmV3CAkBEHJlZnJlc2hJTlRFR1JBTFMEBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBQtwb29sQWRkcmVzcwAAAl8xBBBhdmFpbGFibGVUb0NsYWltCQC4AgIFEHd4VG9DbGFpbVVzZXJOZXcFDWNsYWltZWRCeVVzZXIEAXIDCQC/AgIFEGF2YWlsYWJsZVRvQ2xhaW0FCnplcm9CaWdJbnQJAPwHBAUEdGhpcwIPY2xhaW1XeElOVEVSTkFMCQDMCAIFDGxwQXNzZXRJZFN0cgkAzAgCBQ51c2VyQWRkcmVzc1N0cgUDbmlsBQNuaWwFBHVuaXQDCQAAAgUBcgUBcgMJAGYCBQZhbW91bnQFDHN0YWtlZEJ5VXNlcgkAAgECJHBhc3NlZCBhbW91bnQgaXMgbGVzcyB0aGVuIGF2YWlsYWJsZQkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFD3N0YWtlZEJ5VXNlcktFWQkAZQIFDHN0YWtlZEJ5VXNlcgUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5zdGFrZWRUb3RhbEtFWQkAZQIFC3N0YWtlZFRvdGFsBQZhbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQZhbW91bnQFCWxwQXNzZXRJZAkAzAgCCQEVT3BlcmF0aW9uSGlzdG9yeUVudHJ5BQIHdW5zdGFrZQUOdXNlckFkZHJlc3NTdHIFDGxwQXNzZXRJZFN0cgUGYW1vdW50CAUBaQ10cmFuc2FjdGlvbklkBQNuaWwFDWludGVncmFsU1RBVEUFC2xpc3RBY3Rpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBB2NsYWltV3gBDGxwQXNzZXRJZFN0cgQOdXNlckFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyBAZyZXN1bHQJAPwHBAUEdGhpcwIPY2xhaW1XeElOVEVSTkFMCQDMCAIFDGxwQXNzZXRJZFN0cgkAzAgCBQ51c2VyQWRkcmVzc1N0cgUDbmlsBQNuaWwJAJQKAgUDbmlsBQZyZXN1bHQBaQEPY2xhaW1XeElOVEVSTkFMAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIEC2NoZWNrQ2FsbGVyCQEIbXVzdFRoaXMBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQLdXNlckFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQ51c2VyQWRkcmVzc1N0cgIlY2xhaW1XeElOVEVSTkFMOiBpbnZhbGlkIHVzZXIgYWRkcmVzcwQOcG9vbEFkZHJlc3NTdHIJARhnZXRTdHJpbmdCeUFkZHJlc3NPckZhaWwCBQ9mYWN0b3J5Q29udHJhY3QJASZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwEFDGxwQXNzZXRJZFN0cgQQY2xhaW1lZEJ5VXNlcktFWQkBEGtleUNsYWltZWRCeVVzZXICBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBA9jbGFpbWVkVG90YWxLRVkJAQ9rZXlDbGFpbWVkVG90YWwBBQxscEFzc2V0SWRTdHIEGWNsYWltZWRCeVVzZXJNaW5SZXdhcmRLRVkJARlrZXlDbGFpbWVkQnlVc2VyTWluUmV3YXJkAgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQbY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkS0VZCQEba2V5Q2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkAgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQNY2xhaW1lZEJ5VXNlcgkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBRBjbGFpbWVkQnlVc2VyS0VZBBZjbGFpbWVkQnlVc2VyTWluUmV3YXJkCQEZZ2V0QmlnSW50RnJvbVN0cmluZ09yWmVybwIFBHRoaXMFGWNsYWltZWRCeVVzZXJNaW5SZXdhcmRLRVkEGGNsYWltZWRCeVVzZXJCb29zdFJld2FyZAkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBRtjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmRLRVkEDGNsYWltZWRUb3RhbAkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBQ9jbGFpbWVkVG90YWxLRVkEDSR0MDIyNTkxMjI3MDMJARByZWZyZXNoSU5URUdSQUxTBAUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgUOcG9vbEFkZHJlc3NTdHIAAAQQd3hUb0NsYWltVXNlck5ldwgFDSR0MDIyNTkxMjI3MDMCXzEEDWludGVncmFsU1RBVEUIBQ0kdDAyMjU5MTIyNzAzAl8yBAVkZWJ1ZwgFDSR0MDIyNTkxMjI3MDMCXzMEEGF2YWlsYWJsZVRvQ2xhaW0JAJgDAQkAzAgCCQC4AgIFEHd4VG9DbGFpbVVzZXJOZXcFDWNsYWltZWRCeVVzZXIJAMwIAgUKemVyb0JpZ0ludAUDbmlsAwkAwAICBQp6ZXJvQmlnSW50BRBhdmFpbGFibGVUb0NsYWltCQACAQIQbm90aGluZyB0byBjbGFpbQQSd3hBbW91bnRCb29zdFRvdGFsCQCWAwEJAMwIAgkBBWFzSW50AQkAkQMCCQEJYXNBbnlMaXN0AQkA/AcEBRBib29zdGluZ0NvbnRyYWN0AgxjbGFpbVd4Qm9vc3QJAMwIAgUMbHBBc3NldElkU3RyCQDMCAIFDnVzZXJBZGRyZXNzU3RyBQNuaWwFA25pbAAACQDMCAIAAAUDbmlsBA1taW5SZXdhcmRQYXJ0BRBhdmFpbGFibGVUb0NsYWltBA9ib29zdFJld2FyZFBhcnQJAJkDAQkAzAgCCQC5AgIFDW1pblJld2FyZFBhcnQJALYCAQACCQDMCAIJALYCAQUSd3hBbW91bnRCb29zdFRvdGFsBQNuaWwECXd4QXNzZXRJZAkBDGFzQnl0ZVZlY3RvcgEJAJEDAgkBCWFzQW55TGlzdAEJAPwHBAUQZW1pc3Npb25Db250cmFjdAIEZW1pdAkAzAgCCQCgAwEFDW1pblJld2FyZFBhcnQFA25pbAUDbmlsAAAECWVtaXRCb29zdAkBCWFzQW55TGlzdAEJAPwHBAUQZW1pc3Npb25Db250cmFjdAIEZW1pdAkAzAgCCQCgAwEFD2Jvb3N0UmV3YXJkUGFydAUDbmlsBQNuaWwDCQAAAgUJZW1pdEJvb3N0BQllbWl0Qm9vc3QEEmNsYWltZWRCeVVzZXJWYWx1ZQkAtwICBQ1jbGFpbWVkQnlVc2VyBRBhdmFpbGFibGVUb0NsYWltBB5jbGFpbWVkQnlVc2VyTWluUmV3YXJkUGx1c1BhcnQJALcCAgUWY2xhaW1lZEJ5VXNlck1pblJld2FyZAUNbWluUmV3YXJkUGFydAQrY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkUGx1c0Jvb3N0UmV3YXJkUGFydAkAtwICBRZjbGFpbWVkQnlVc2VyTWluUmV3YXJkBQ1taW5SZXdhcmRQYXJ0BCBjbGFpbWVkVG90YWxQbHVzQXZhaWxhYmxlVG9DbGFpbQkAtwICBRZjbGFpbWVkQnlVc2VyTWluUmV3YXJkBQ1taW5SZXdhcmRQYXJ0CQDMCAIJAQtTdHJpbmdFbnRyeQIFEGNsYWltZWRCeVVzZXJLRVkJAKYDAQUSY2xhaW1lZEJ5VXNlclZhbHVlCQDMCAIJAQtTdHJpbmdFbnRyeQIFGWNsYWltZWRCeVVzZXJNaW5SZXdhcmRLRVkJAKYDAQUeY2xhaW1lZEJ5VXNlck1pblJld2FyZFBsdXNQYXJ0CQDMCAIJAQtTdHJpbmdFbnRyeQIFG2NsYWltZWRCeVVzZXJCb29zdFJld2FyZEtFWQkApgMBBStjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmRQbHVzQm9vc3RSZXdhcmRQYXJ0CQDMCAIJAQtTdHJpbmdFbnRyeQIFD2NsYWltZWRUb3RhbEtFWQkApgMBBSBjbGFpbWVkVG90YWxQbHVzQXZhaWxhYmxlVG9DbGFpbQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQt1c2VyQWRkcmVzcwkAoAMBBQ1taW5SZXdhcmRQYXJ0BQl3eEFzc2V0SWQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MJAKADAQUPYm9vc3RSZXdhcmRQYXJ0BQl3eEFzc2V0SWQJAMwIAgkBFU9wZXJhdGlvbkhpc3RvcnlFbnRyeQUCBWNsYWltBQ51c2VyQWRkcmVzc1N0cgUMbHBBc3NldElkU3RyCQCgAwEFEGF2YWlsYWJsZVRvQ2xhaW0IBQFpDXRyYW5zYWN0aW9uSWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ9jbGFpbVd4UkVBRE9OTFkCDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cgQPc3Rha2VkQnlVc2VyS0VZCQEPa2V5U3Rha2VkQnlVc2VyAgUOdXNlckFkZHJlc3NTdHIFDGxwQXNzZXRJZFN0cgQOc3Rha2VkVG90YWxLRVkJAQ5rZXlTdGFrZWRUb3RhbAEFDGxwQXNzZXRJZFN0cgQQY2xhaW1lZEJ5VXNlcktFWQkBEGtleUNsYWltZWRCeVVzZXICBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBAxzdGFrZWRCeVVzZXIJAQpyZWFkU3Rha2VkAQUPc3Rha2VkQnlVc2VyS0VZBAtzdGFrZWRUb3RhbAkBCnJlYWRTdGFrZWQBBQ5zdGFrZWRUb3RhbEtFWQQNY2xhaW1lZEJ5VXNlcgkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBRBjbGFpbWVkQnlVc2VyS0VZBA5wb29sQWRkcmVzc1N0cgkBGGdldFN0cmluZ0J5QWRkcmVzc09yRmFpbAIFD2ZhY3RvcnlDb250cmFjdAkBJmtleUZhY3RvcnlMcEFzc2V0VG9Qb29sQ29udHJhY3RBZGRyZXNzAQUMbHBBc3NldElkU3RyBApwb29sV2VpZ2h0CQERQGV4dHJOYXRpdmUoMTA1MCkCBQ9mYWN0b3J5Q29udHJhY3QJARRrZXlGYWN0b3J5UG9vbFdlaWdodAEFDnBvb2xBZGRyZXNzU3RyBBJ3eEVtaXNzaW9uUGVyQmxvY2sJAQxnZXRJbnRPckZhaWwCBRBlbWlzc2lvbkNvbnRyYWN0CQEea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAQSZW1pc3Npb25TdGFydEJsb2NrCQEMZ2V0SW50T3JGYWlsAgUQZW1pc3Npb25Db250cmFjdAkBFWtleUVtaXNzaW9uU3RhcnRCbG9jawAEDHBhc3NlZEJsb2NrcwMJAGYCBRJlbWlzc2lvblN0YXJ0QmxvY2sFBmhlaWdodAAACQBlAgUGaGVpZ2h0BRJlbWlzc2lvblN0YXJ0QmxvY2sEDnBvb2xXeEVtaXNzaW9uCQBrAwkAaAIFEnd4RW1pc3Npb25QZXJCbG9jawUMcGFzc2VkQmxvY2tzBQpwb29sV2VpZ2h0BQ5QT09MV0VJR0hUTVVMVAQMdXNlcld4UmV3YXJkCQBrAwUOcG9vbFd4RW1pc3Npb24FDHN0YWtlZEJ5VXNlcgULc3Rha2VkVG90YWwEDSR0MDI1MzQ1MjU0NTcJARByZWZyZXNoSU5URUdSQUxTBAUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgUOcG9vbEFkZHJlc3NTdHIAAAQQd3hUb0NsYWltVXNlck5ldwgFDSR0MDI1MzQ1MjU0NTcCXzEEDWludGVncmFsU1RBVEUIBQ0kdDAyNTM0NTI1NDU3Al8yBAVkZWJ1ZwgFDSR0MDI1MzQ1MjU0NTcCXzMEEGF2YWlsYWJsZVRvQ2xhaW0JAJgDAQkAzAgCCQC4AgIFEHd4VG9DbGFpbVVzZXJOZXcFDWNsYWltZWRCeVVzZXIJAMwIAgUKemVyb0JpZ0ludAUDbmlsBA5ib29zdEludlJlc3VsdAkBCWFzQW55TGlzdAEJAPwHBAUQYm9vc3RpbmdDb250cmFjdAIUY2xhaW1XeEJvb3N0UkVBRE9OTFkJAMwIAgUMbHBBc3NldElkU3RyCQDMCAIFDnVzZXJBZGRyZXNzU3RyBQNuaWwFA25pbAQSd3hBbW91bnRCb29zdFRvdGFsCQCWAwEJAMwIAgkBBWFzSW50AQkAkQMCBQ5ib29zdEludlJlc3VsdAAACQDMCAIAAAUDbmlsBApib29zdERlYnVnCQEIYXNTdHJpbmcBCQCRAwIFDmJvb3N0SW52UmVzdWx0AAEEDW1pblJld2FyZFBhcnQFEGF2YWlsYWJsZVRvQ2xhaW0ED2Jvb3N0UmV3YXJkUGFydAkAmQMBCQDMCAIJALkCAgUNbWluUmV3YXJkUGFydAkAtgIBAAIJAMwIAgkAtgIBBRJ3eEFtb3VudEJvb3N0VG90YWwFA25pbAQLdG90YWxSZXdhcmQJALcCAgUNbWluUmV3YXJkUGFydAUPYm9vc3RSZXdhcmRQYXJ0CQCUCgIFA25pbAkAuQkCCQDMCAICDiVzJXMlZCVkJWQlZCVzCQDMCAIFDGxwQXNzZXRJZFN0cgkAzAgCBQ51c2VyQWRkcmVzc1N0cgkAzAgCCQCmAwEFC3RvdGFsUmV3YXJkCQDMCAIJAKYDAQUNY2xhaW1lZEJ5VXNlcgkAzAgCCQCmAwEFDW1pblJld2FyZFBhcnQJAMwIAgkApgMBBQ9ib29zdFJld2FyZFBhcnQJAMwIAgIEc29vbgUDbmlsBQNTRVABaQESdXNlcnNMaXN0VHJhdmVyc2FsAQlscEFzc2V0SWQEC2NoZWNrQ2FsbGVyAwkAAAIJANgEAQgIBQFpBmNhbGxlcgVieXRlcwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEZa2V5Vm90aW5nRW1pc3Npb25Db250cmFjdAACAAYJAQttdXN0TWFuYWdlcgEFAWkDCQAAAgULY2hlY2tDYWxsZXIFC2NoZWNrQ2FsbGVyBAhsaXN0TmFtZQkBEGdldFVzZXJzTGlzdE5hbWUBBQlscEFzc2V0SWQECnVzZXJPclVuaXQJAKIIAQkBC2tleU5leHRVc2VyAQUJbHBBc3NldElkBApoZWFkT3JVbml0CQCiCAEJAQtrZXlMaXN0SGVhZAEFCGxpc3ROYW1lBAckbWF0Y2gwBQp1c2VyT3JVbml0AwkAAQIFByRtYXRjaDACBFVuaXQEByRtYXRjaDEFCmhlYWRPclVuaXQDCQABAgUHJG1hdGNoMQIEVW5pdAkAlAoCBQNuaWwHAwkAAQIFByRtYXRjaDECBlN0cmluZwQEaGVhZAUHJG1hdGNoMQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQtrZXlOZXh0VXNlcgEFCWxwQXNzZXRJZAUEaGVhZAUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFByRtYXRjaDACBlN0cmluZwQLdXNlckFkZHJlc3MFByRtYXRjaDAEDWNsYWltZWRCeVVzZXIJARlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvAgUEdGhpcwkBEGtleUNsYWltZWRCeVVzZXICBQlscEFzc2V0SWQFC3VzZXJBZGRyZXNzBAtwb29sQWRkcmVzcwkBGGdldFN0cmluZ0J5QWRkcmVzc09yRmFpbAIFD2ZhY3RvcnlDb250cmFjdAkBJmtleUZhY3RvcnlMcEFzc2V0VG9Qb29sQ29udHJhY3RBZGRyZXNzAQUJbHBBc3NldElkBBB3eFRvQ2xhaW1Vc2VyTmV3CAkBEHJlZnJlc2hJTlRFR1JBTFMEBQlscEFzc2V0SWQFC3VzZXJBZGRyZXNzBQtwb29sQWRkcmVzcwAAAl8xBBBhdmFpbGFibGVUb0NsYWltCQC4AgIFEHd4VG9DbGFpbVVzZXJOZXcFDWNsYWltZWRCeVVzZXIEAXIDCQC/AgIFEGF2YWlsYWJsZVRvQ2xhaW0FCnplcm9CaWdJbnQJAPwHBAUEdGhpcwIPY2xhaW1XeElOVEVSTkFMCQDMCAIFCWxwQXNzZXRJZAkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNuaWwFBHVuaXQDCQAAAgUBcgUBcgQObmV4dFVzZXJPclVuaXQJAKIIAQkBC2tleUxpc3ROZXh0AgUIbGlzdE5hbWUFC3VzZXJBZGRyZXNzBAckbWF0Y2gxBQ5uZXh0VXNlck9yVW5pdAMJAAECBQckbWF0Y2gxAgRVbml0CQCUCgIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleU5leHRVc2VyAQUJbHBBc3NldElkBQNuaWwHAwkAAQIFByRtYXRjaDECBlN0cmluZwQIbmV4dFVzZXIFByRtYXRjaDEJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TmV4dFVzZXIBBQlscEFzc2V0SWQFCG5leHRVc2VyBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAgtNYXRjaCBlcnJvcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ5vbk1vZGlmeVdlaWdodAIMbHBBc3NldElkU3RyDnBvb2xBZGRyZXNzU3RyAwkBAiE9AggFAWkGY2FsbGVyBQ9mYWN0b3J5Q29udHJhY3QJAAIBAhJwZXJtaXNzaW9ucyBkZW5pZWQEDSR0MDI3NzU3Mjc4NjcJARRyZWZyZXNoUG9vbElOVEVHUkFMUwMFDGxwQXNzZXRJZFN0cgUOcG9vbEFkZHJlc3NTdHIAAAQSd3hQZXJMcEludGVncmFsTmV3CAUNJHQwMjc3NTcyNzg2NwJfMQQRcG9vbEludGVncmFsU1RBVEUIBQ0kdDAyNzc1NzI3ODY3Al8yBAlwb29sREVCVUcIBQ0kdDAyNzc1NzI3ODY3Al8zBRFwb29sSW50ZWdyYWxTVEFURQECdHgBBnZlcmlmeQAED3RhcmdldFB1YmxpY0tleQQHJG1hdGNoMAkBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQAAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwBQJwawMJAAECBQckbWF0Y2gwAgRVbml0CAUCdHgPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAFD3RhcmdldFB1YmxpY0tlebjp794=", "chainId": 87, "height": 3186298, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: J1ajzbG7DxsCgSLbjF9RTmFWSPL6GdTbUYEUf7RVwqHP Next: 9eNhBqHcXEAaq623Q6YdieYmzjfqswNHUZvYrPxPHkmC Diff:
OldNewDifferences
615615 let minRewardPart = availableToClaim
616616 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
617617 let totalReward = (minRewardPart + boostRewardPart)
618- $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), ((((debug + "::") + toString(userWxReward)) + "::BOOST::") + boostDebug)], SEP))
618+ $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), "soon"], SEP))
619619 }
620620
621621
674674 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
675675 then throw("permissions denied")
676676 else {
677- let $t02780827918 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
678- let wxPerLpIntegralNew = $t02780827918._1
679- let poolIntegralSTATE = $t02780827918._2
680- let poolDEBUG = $t02780827918._3
677+ let $t02775727867 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
678+ let wxPerLpIntegralNew = $t02775727867._1
679+ let poolIntegralSTATE = $t02775727867._2
680+ let poolDEBUG = $t02775727867._3
681681 poolIntegralSTATE
682682 }
683683
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SCALE8 = 8
55
66 let MULT8 = 100000000
77
88 let SCALE18 = 18
99
1010 let MULT18 = toBigInt(1000000000000000000)
1111
1212 let SEP = "__"
1313
1414 let POOLWEIGHTMULT = MULT8
1515
1616 let zeroBigInt = toBigInt(0)
1717
1818 let oneBigInt = toBigInt(1)
1919
2020 func asAnyList (val) = match val {
2121 case valAnyLyst: List[Any] =>
2222 valAnyLyst
2323 case _ =>
2424 throw("fail to cast into List[Any]")
2525 }
2626
2727
2828 func asInt (val) = match val {
2929 case valInt: Int =>
3030 valInt
3131 case _ =>
3232 throw("fail to cast into Int")
3333 }
3434
3535
3636 func asString (val) = match val {
3737 case valStr: String =>
3838 valStr
3939 case _ =>
4040 throw("fail to cast into Int")
4141 }
4242
4343
4444 func asByteVector (val) = match val {
4545 case valBin: ByteVector =>
4646 valBin
4747 case _ =>
4848 throw("fail to cast into Int")
4949 }
5050
5151
5252 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
5353
5454
5555 func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
5656
5757
5858 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
5959
6060
6161 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
6262
6363
6464 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
6565
6666
6767 func getBigIntFromStringOrZero (address,key) = value(parseBigInt(valueOrElse(getString(address, key), "0")))
6868
6969
7070 func getBigIntFromStringOrDefault (address,key,defaultVal) = match getString(address, key) {
7171 case s: String =>
7272 value(parseBigInt(s))
7373 case _: Unit =>
7474 defaultVal
7575 case _ =>
7676 throw("Match error")
7777 }
7878
7979
8080 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
8181
8282
8383 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
8484
8585
8686 func keyFactoryAddress () = "%s%s__config__factoryAddress"
8787
8888
8989 func keyVotingEmissionContract () = "%s__votingEmissionContract"
9090
9191
9292 let IdxFactoryCfgStakingDapp = 1
9393
9494 let IdxFactoryCfgBoostingDapp = 2
9595
9696 let IdxFactoryCfgIdoDapp = 3
9797
9898 let IdxFactoryCfgTeamDapp = 4
9999
100100 let IdxFactoryCfgEmissionDapp = 5
101101
102102 let IdxFactoryCfgRestDapp = 6
103103
104104 let IdxFactoryCfgSlippageDapp = 7
105105
106106 func keyFactoryCfg () = "%s__factoryConfig"
107107
108108
109109 func keyManagerPublicKey () = "%s__managerPublicKey"
110110
111111
112112 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
113113
114114
115115 func keyStablePoolAddonAddr () = "%s__stablePoolAddonAddr"
116116
117117
118118 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
119119
120120
121121 func keyFactoryLpList () = "%s__lpTokensList"
122122
123123
124124 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
125125
126126
127127 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
128128
129129
130130 func readLpList (factory) = split(valueOrElse(getString(factory, keyFactoryLpList()), ""), SEP)
131131
132132
133133 func readFactoryCfgOrFail (factory) = split(getStringByAddressOrFail(factory, keyFactoryCfg()), SEP)
134134
135135
136136 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
137137
138138
139139 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
140140
141141
142142 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
143143
144144
145145 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
146146
147147
148148 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
149149
150150
151151 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
152152
153153
154154 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
155155
156156
157157 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
158158
159159
160160 func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP)
161161
162162
163163 func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr)
164164
165165
166166 func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP)
167167
168168
169169 func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP)
170170
171171
172172 func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP)
173173
174174
175175 func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed__total", lpAssetIdStr], SEP)
176176
177177
178178 func readStaked (key) = valueOrElse(getInteger(this, key), 0)
179179
180180
181181 func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP)
182182
183183
184184 func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP)
185185
186186
187187 func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP)
188188
189189
190190 func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP)
191191
192192
193193 func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP)
194194
195195
196196 func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP)
197197
198198
199199 func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP)
200200
201201
202202 func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP)
203203
204204
205205 func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP)
206206
207207
208208 func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP)
209209
210210
211211 func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP)
212212
213213
214214 func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP)
215215
216216
217217 func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP)
218218
219219
220220 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
221221
222222
223223 func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
224224
225225
226226 func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
227227
228228
229229 let factoryAddress = getStringOrFail(this, keyFactoryAddress())
230230
231231 let factoryContract = addressFromStringValue(factoryAddress)
232232
233233 let factoryCfg = readFactoryCfgOrFail(factoryContract)
234234
235235 let emissionContract = getEmissionAddressOrFail(factoryCfg)
236236
237237 let boostingContract = getBoostingAddressOrFail(factoryCfg)
238238
239239 func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
240240
241241
242242 func getUsersListName (lpAssetId) = makeString(["users", lpAssetId], SEP)
243243
244244
245245 func keyListHead (listName) = makeString(["%s%s%s", listName, "head"], SEP)
246246
247247
248248 func keyListSize (listName) = makeString(["%s%s%s", listName, "size"], SEP)
249249
250250
251251 func keyListPrev (listName,id) = makeString(["%s%s%s%s", listName, id, "prev"], SEP)
252252
253253
254254 func keyListNext (listName,id) = makeString(["%s%s%s%s", listName, id, "next"], SEP)
255255
256256
257257 func containsNode (listName,id) = {
258258 let headOrUnit = getString(this, keyListHead(listName))
259259 let prevOrUnit = getString(this, keyListPrev(listName, id))
260260 let nextOrUnit = getString(this, keyListNext(listName, id))
261261 if (if ((id == valueOrElse(headOrUnit, "")))
262262 then true
263263 else (prevOrUnit != unit))
264264 then true
265265 else (nextOrUnit != unit)
266266 }
267267
268268
269269 func insertNodeActions (listName,id) = {
270270 let headOrUnit = getString(this, keyListHead(listName))
271271 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
272272 let checkNode = if (!(containsNode(listName, id)))
273273 then true
274274 else throw("Node exists")
275275 if ((checkNode == checkNode))
276276 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
277277 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
278278 else nil)) ++ [StringEntry(keyListHead(listName), id)])
279279 else throw("Strict value is not equal to itself.")
280280 }
281281
282282
283283 func deleteNodeActions (listName,id) = {
284284 let headOrUnit = getString(this, keyListHead(listName))
285285 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
286286 let prevOrUnit = getString(this, keyListPrev(listName, id))
287287 let nextOrUnit = getString(this, keyListNext(listName, id))
288288 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
289289 then (nextOrUnit != unit)
290290 else false)
291291 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
292292 else if ((nextOrUnit != unit))
293293 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
294294 else if ((prevOrUnit != unit))
295295 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
296296 else if ((id == valueOrElse(headOrUnit, "")))
297297 then [DeleteEntry(keyListHead(listName))]
298298 else throw(((("invalid node: " + listName) + ".") + id))))
299299 }
300300
301301
302302 func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == zeroBigInt))
303303 then (stakedByUser > zeroBigInt)
304304 else false)
305305 then zeroBigInt
306306 else if ((stakedByUser == zeroBigInt))
307307 then wxPerLpIntegralNew
308308 else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > zeroBigInt))
309309 then (stakedByUser > zeroBigInt)
310310 else false)
311311 then value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY)))
312312 else throw("calcWxPerLpIntegralUserLast: unexpected state")
313313
314314
315315 func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = {
316316 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
317317 let stakedTotal = toBigInt(readStaked(stakedTotalKEY))
318318 let nonZeroStakedTotal = if ((stakedTotal == zeroBigInt))
319319 then oneBigInt
320320 else stakedTotal
321321 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
322322 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
323323 let MULT3 = 1000
324324 let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
325325 let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3))
326326 let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
327327 let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
328328 let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
329329 let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock)
330330 let wxPerLpIntegral = getBigIntFromStringOrZero(this, wxPerLpIntegralKEY)
331331 let wxPerLpOrZeroX3 = 0
332332 let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0])
333333 let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0))
334334 then toBigInt(wxPerLpOrZeroX3)
335335 else fraction(toBigInt(poolWxEmissionPerBlockX3), toBigInt(MULT8), nonZeroStakedTotal)
336336 let stakedTotalNew = (stakedTotal + toBigInt(lpDeltaAmount))
337337 let nonZeroStakedTotalNew = if ((stakedTotalNew == zeroBigInt))
338338 then oneBigInt
339339 else stakedTotalNew
340340 let wxPerLpIntegralNew = (wxPerLpIntegral + (wxPerLpX3 * toBigInt(dh)))
341341 let wxPerLpX3New = (toBigInt(poolWxEmissionPerBlockX3) / nonZeroStakedTotalNew)
342342 let wxPerLpIntegralLastUpdHeightNew = height
343343 let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::")
344344 $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), StringEntry(wxPerLpKEY, toString(wxPerLpX3New))], debug)
345345 }
346346
347347
348348 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
349349 let $t01421714339 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
350350 let wxPerLpIntegralNew = $t01421714339._1
351351 let poolIntegralSTATE = $t01421714339._2
352352 let poolDEBUG = $t01421714339._3
353353 let MULT3 = 1000
354354 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
355355 let stakedByUser = readStaked(stakedByUserKEY)
356356 let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
357357 let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr)
358358 let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr)
359359 let wxToClaimUser = getBigIntFromStringOrZero(this, wxToClaimUserKEY)
360360 let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY)
361361 let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY)
362362 let MULT11 = (MULT8 * MULT3)
363363 let wxToClaimUserNew = max([(wxToClaimUser + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11))), zeroBigInt])
364364 let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew
365365 let wxPerLpIntegralUserLastUpdHeightNew = height
366366 let debug = makeString([toString(wxToClaimUser), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::")
367367 $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug)
368368 }
369369
370370
371371 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
372372 case s: String =>
373373 fromBase58String(s)
374374 case _: Unit =>
375375 unit
376376 case _ =>
377377 throw("Match error")
378378 }
379379
380380
381381 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
382382 case s: String =>
383383 fromBase58String(s)
384384 case _: Unit =>
385385 unit
386386 case _ =>
387387 throw("Match error")
388388 }
389389
390390
391391 let permissionDeniedError = throw("Permission denied")
392392
393393 func mustThis (i) = if ((i.caller == this))
394394 then true
395395 else permissionDeniedError
396396
397397
398398 func mustManager (i) = match managerPublicKeyOrUnit() {
399399 case pk: ByteVector =>
400400 if ((i.callerPublicKey == pk))
401401 then true
402402 else permissionDeniedError
403403 case _: Unit =>
404404 if ((i.caller == this))
405405 then true
406406 else permissionDeniedError
407407 case _ =>
408408 throw("Match error")
409409 }
410410
411411
412412 @Callable(i)
413413 func constructor (factoryAddressStr) = {
414414 let checkCaller = mustManager(i)
415415 if ((checkCaller == checkCaller))
416416 then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
417417 else throw("Strict value is not equal to itself.")
418418 }
419419
420420
421421
422422 @Callable(i)
423423 func constructorV2 (votingEmissionContract) = {
424424 let cheks = [mustManager(i), if ((addressFromString(votingEmissionContract) != unit))
425425 then true
426426 else "invalid voting emission contract address"]
427427 if ((cheks == cheks))
428428 then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)]
429429 else throw("Strict value is not equal to itself.")
430430 }
431431
432432
433433
434434 @Callable(i)
435435 func setManager (pendingManagerPublicKey) = {
436436 let checkCaller = mustManager(i)
437437 if ((checkCaller == checkCaller))
438438 then {
439439 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
440440 if ((checkManagerPublicKey == checkManagerPublicKey))
441441 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
442442 else throw("Strict value is not equal to itself.")
443443 }
444444 else throw("Strict value is not equal to itself.")
445445 }
446446
447447
448448
449449 @Callable(i)
450450 func confirmManager () = {
451451 let pm = pendingManagerPublicKeyOrUnit()
452452 let hasPM = if (isDefined(pm))
453453 then true
454454 else throw("No pending manager")
455455 if ((hasPM == hasPM))
456456 then {
457457 let checkPM = if ((i.callerPublicKey == value(pm)))
458458 then true
459459 else throw("You are not pending manager")
460460 if ((checkPM == checkPM))
461461 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
462462 else throw("Strict value is not equal to itself.")
463463 }
464464 else throw("Strict value is not equal to itself.")
465465 }
466466
467467
468468
469469 @Callable(i)
470470 func stake () = if ((size(i.payments) != 1))
471471 then throw("invalid payment - exact one payment must be attached")
472472 else {
473473 let pmt = i.payments[0]
474474 let lpAssetId = value(pmt.assetId)
475475 let lpAssetIdStr = toBase58String(lpAssetId)
476476 let amount = pmt.amount
477477 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
478478 let callerStr = toString(i.caller)
479479 let userAddressStr = if ((callerStr == poolAddressStr))
480480 then toString(i.originCaller)
481481 else callerStr
482482 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
483483 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
484484 let stakedByUser = readStaked(stakedByUserKEY)
485485 let stakedTotal = readStaked(stakedTotalKEY)
486486 let $t01877518892 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
487487 let wxToClaimUserNew = $t01877518892._1
488488 let integralSTATE = $t01877518892._2
489489 let debug = $t01877518892._3
490490 let listName = getUsersListName(lpAssetIdStr)
491491 let listActions = if (containsNode(listName, userAddressStr))
492492 then nil
493493 else insertNodeActions(listName, userAddressStr)
494494 (([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
495495 }
496496
497497
498498
499499 @Callable(i)
500500 func unstake (lpAssetIdStr,amount) = {
501501 let lpAssetId = fromBase58String(lpAssetIdStr)
502502 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
503503 let poolAddon = valueOrElse(getString(this, keyStablePoolAddonAddr()), poolAddressStr)
504504 let callerStr = toString(i.caller)
505505 let userAddressStr = if (if ((callerStr == poolAddressStr))
506506 then true
507507 else (callerStr == poolAddon))
508508 then toString(i.originCaller)
509509 else callerStr
510510 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
511511 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
512512 let stakedByUser = readStaked(stakedByUserKEY)
513513 let stakedTotal = readStaked(stakedTotalKEY)
514514 let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
515515 let listName = getUsersListName(lpAssetIdStr)
516516 let listActions = if (if (containsNode(listName, userAddressStr))
517517 then (amount == stakedByUser)
518518 else false)
519519 then deleteNodeActions(listName, userAddressStr)
520520 else nil
521521 let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetIdStr, userAddressStr))
522522 let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
523523 let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddress, 0)._1
524524 let availableToClaim = (wxToClaimUserNew - claimedByUser)
525525 let r = if ((availableToClaim > zeroBigInt))
526526 then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
527527 else unit
528528 if ((r == r))
529529 then if ((amount > stakedByUser))
530530 then throw("passed amount is less then available")
531531 else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
532532 else throw("Strict value is not equal to itself.")
533533 }
534534
535535
536536
537537 @Callable(i)
538538 func claimWx (lpAssetIdStr) = {
539539 let userAddressStr = toString(i.caller)
540540 let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
541541 $Tuple2(nil, result)
542542 }
543543
544544
545545
546546 @Callable(i)
547547 func claimWxINTERNAL (lpAssetIdStr,userAddressStr) = {
548548 let checkCaller = mustThis(i)
549549 if ((checkCaller == checkCaller))
550550 then {
551551 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), "claimWxINTERNAL: invalid user address")
552552 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
553553 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
554554 let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
555555 let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
556556 let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
557557 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
558558 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
559559 let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
560560 let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
561561 let $t02259122703 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
562562 let wxToClaimUserNew = $t02259122703._1
563563 let integralSTATE = $t02259122703._2
564564 let debug = $t02259122703._3
565565 let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
566566 if ((zeroBigInt >= availableToClaim))
567567 then throw("nothing to claim")
568568 else {
569569 let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
570570 let minRewardPart = availableToClaim
571571 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
572572 let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
573573 let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
574574 if ((emitBoost == emitBoost))
575575 then {
576576 let claimedByUserValue = (claimedByUser + availableToClaim)
577577 let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
578578 let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserMinReward + minRewardPart)
579579 let claimedTotalPlusAvailableToClaim = (claimedByUserMinReward + minRewardPart)
580580 [StringEntry(claimedByUserKEY, toString(claimedByUserValue)), StringEntry(claimedByUserMinRewardKEY, toString(claimedByUserMinRewardPlusPart)), StringEntry(claimedByUserBoostRewardKEY, toString(claimedByUserBoostRewardPlusBoostRewardPart)), StringEntry(claimedTotalKEY, toString(claimedTotalPlusAvailableToClaim)), ScriptTransfer(userAddress, toInt(minRewardPart), wxAssetId), ScriptTransfer(userAddress, toInt(boostRewardPart), wxAssetId), OperationHistoryEntry("claim", userAddressStr, lpAssetIdStr, toInt(availableToClaim), i.transactionId)]
581581 }
582582 else throw("Strict value is not equal to itself.")
583583 }
584584 }
585585 else throw("Strict value is not equal to itself.")
586586 }
587587
588588
589589
590590 @Callable(i)
591591 func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
592592 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
593593 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
594594 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
595595 let stakedByUser = readStaked(stakedByUserKEY)
596596 let stakedTotal = readStaked(stakedTotalKEY)
597597 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
598598 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
599599 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
600600 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
601601 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
602602 let passedBlocks = if ((emissionStartBlock > height))
603603 then 0
604604 else (height - emissionStartBlock)
605605 let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
606606 let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
607607 let $t02534525457 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
608608 let wxToClaimUserNew = $t02534525457._1
609609 let integralSTATE = $t02534525457._2
610610 let debug = $t02534525457._3
611611 let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
612612 let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
613613 let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
614614 let boostDebug = asString(boostInvResult[1])
615615 let minRewardPart = availableToClaim
616616 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
617617 let totalReward = (minRewardPart + boostRewardPart)
618- $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), ((((debug + "::") + toString(userWxReward)) + "::BOOST::") + boostDebug)], SEP))
618+ $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), "soon"], SEP))
619619 }
620620
621621
622622
623623 @Callable(i)
624624 func usersListTraversal (lpAssetId) = {
625625 let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), "")))
626626 then true
627627 else mustManager(i)
628628 if ((checkCaller == checkCaller))
629629 then {
630630 let listName = getUsersListName(lpAssetId)
631631 let userOrUnit = getString(keyNextUser(lpAssetId))
632632 let headOrUnit = getString(keyListHead(listName))
633633 match userOrUnit {
634634 case _: Unit =>
635635 match headOrUnit {
636636 case _: Unit =>
637637 $Tuple2(nil, false)
638638 case head: String =>
639639 $Tuple2([StringEntry(keyNextUser(lpAssetId), head)], true)
640640 case _ =>
641641 throw("Match error")
642642 }
643643 case userAddress: String =>
644644 let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetId, userAddress))
645645 let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId))
646646 let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1
647647 let availableToClaim = (wxToClaimUserNew - claimedByUser)
648648 let r = if ((availableToClaim > zeroBigInt))
649649 then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress], nil)
650650 else unit
651651 if ((r == r))
652652 then {
653653 let nextUserOrUnit = getString(keyListNext(listName, userAddress))
654654 match nextUserOrUnit {
655655 case _: Unit =>
656656 $Tuple2([DeleteEntry(keyNextUser(lpAssetId))], false)
657657 case nextUser: String =>
658658 $Tuple2([StringEntry(keyNextUser(lpAssetId), nextUser)], true)
659659 case _ =>
660660 throw("Match error")
661661 }
662662 }
663663 else throw("Strict value is not equal to itself.")
664664 case _ =>
665665 throw("Match error")
666666 }
667667 }
668668 else throw("Strict value is not equal to itself.")
669669 }
670670
671671
672672
673673 @Callable(i)
674674 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
675675 then throw("permissions denied")
676676 else {
677- let $t02780827918 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
678- let wxPerLpIntegralNew = $t02780827918._1
679- let poolIntegralSTATE = $t02780827918._2
680- let poolDEBUG = $t02780827918._3
677+ let $t02775727867 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
678+ let wxPerLpIntegralNew = $t02775727867._1
679+ let poolIntegralSTATE = $t02775727867._2
680+ let poolDEBUG = $t02775727867._3
681681 poolIntegralSTATE
682682 }
683683
684684
685685 @Verifier(tx)
686686 func verify () = {
687687 let targetPublicKey = match managerPublicKeyOrUnit() {
688688 case pk: ByteVector =>
689689 pk
690690 case _: Unit =>
691691 tx.senderPublicKey
692692 case _ =>
693693 throw("Match error")
694694 }
695695 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
696696 }
697697

github/deemru/w8io/786bc32 
87.68 ms