tx · 46NMsgGPqSZnJPP8ALBKddGu6wi288Q3axN2hs8iuHwc

3NBPx1Fciu3JQNEGZ21jSnTdutLNGGBUSXh:  -0.02500000 Waves

2024.11.25 15:14 [3386928] smart account 3NBPx1Fciu3JQNEGZ21jSnTdutLNGGBUSXh > SELF 0.00000000 Waves

{ "type": 13, "id": "46NMsgGPqSZnJPP8ALBKddGu6wi288Q3axN2hs8iuHwc", "fee": 2500000, "feeAssetId": null, "timestamp": 1732536899083, "version": 2, "chainId": 84, "sender": "3NBPx1Fciu3JQNEGZ21jSnTdutLNGGBUSXh", "senderPublicKey": "3QtfC1XbLZXdeawMDeSERy9vvjUmj1XYd2GFmrvx7pWQ", "proofs": [ "58oAsEer9QuxkwKSeQRdsDkvuiKHHcoBneW4Sov6zJo7A8DKPUickk7JAaHZKW7caJYosutPayiX7HMiURiKVoXf" ], "script": "base64:BgJECAISABIECgIICBIDCgEEEgMKAQESABIAEgMKAQESABIECgIIARIAEgMKAQgSAwoBCBIECgIIARIECgIIARIAEgMKAQhaAANTRVACAl9fAAVNVUxUNgDAhD0ABU1VTFQ3AICt4gQABU1VTFQ4AIDC1y8ACkRBWV9NSUxMSVMAgLiZKQAVVVNEVDJBQ1JFU19NVUxUSVBMSUVSAAoAE09ORV9QRVJDRU5UX0RJVklTT1IAZAAFY2hhaW4JAMkBAgkAygECCAUEdGhpcwVieXRlcwABAAEAC1dFRUtfQkxPQ0tTBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAOBOAwkAAAIBAVQFByRtYXRjaDAAtAEJAAIBAg1Vbmtub3duIGNoYWluAAt1c2R0QXNzZXRJZAQHJG1hdGNoMAUFY2hhaW4DCQAAAgEBVwUHJG1hdGNoMAEghNp6sggDP07Ru8qO7ouTvMmC3Qtd+geWqNQj+agP/7kDCQAAAgEBVAUHJG1hdGNoMAEgVbHYn3KHgu/l41uNrAWrZd6aQ6EvFrsF8xq3h6XxxRgJAAIBAg1Vbmtub3duIGNoYWluABZkZWZhdWx0UmVzdDJBZGRyZXNzU3RyBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAiMzUEZ3WXRhOGJpRXozMXpwZUZlNURKSzh3RTV0clNwUVZGOAMJAAACAQFUBQckbWF0Y2gwAiMzTjdVdVlhcjYyNjRQNThGQmhWV0tQUUFoNFl1YTJoZ25ndgkAAgECDVVua25vd24gY2hhaW4ADmFyYml0cmFnZURlbGF5BAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwBQpEQVlfTUlMTElTAwkAAAIBAVQFByRtYXRjaDAA4NQDCQACAQINVW5rbm93biBjaGFpbgAVb2xkU3Rha2luZ0NvbnRyYWN0U3RyBAckbWF0Y2gwBQVjaGFpbgMJAAACAQFXBQckbWF0Y2gwAiMzUExuY1h0UzFVODNENmNRYkZEM0g4ckJIUExnenhTRktaMQMJAAACAQFUBQckbWF0Y2gwAiMzTkRDeUJHNXE4NUp1YVJpaWdVZUV0YWlueWpDUVQzWHBabQkAAgECDVVua25vd24gY2hhaW4BD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAABBJZHhDZmdBY3JlczJEYXBwAAEADUlkeENmZ1dsZ0RhcHAAAgAUSWR4Q2ZnSW52ZXN0RnVuZERhcHAABQEKa2V5UmVzdENmZwACDiVzX19yZXN0Q29uZmlnAQ9rZXlSZXN0MkFkZHJlc3MAAg0lc19fcmVzdDJBZGRyARFyZWFkUmVzdENmZ09yRmFpbAEEcmVzdAkAvAkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUEcmVzdAkBCmtleVJlc3RDZmcABQNTRVABGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIIcmVzdDJDZmcDaWR4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQhyZXN0MkNmZwUDaWR4CQCsAgICKlJlc3QgY2ZnIGRvZXNuJ3QgY29udGFpbiBhZGRyZXNzIGF0IGluZGV4IAkApAMBBQNpZHgADXJlc3QyQ29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBD2tleVJlc3QyQWRkcmVzcwAFFmRlZmF1bHRSZXN0MkFkZHJlc3NTdHIACHJlc3QyQ2ZnCQERcmVhZFJlc3RDZmdPckZhaWwBBQ1yZXN0MkNvbnRyYWN0AA5hY3JlczJDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCHJlc3QyQ2ZnBRBJZHhDZmdBY3JlczJEYXBwAAt3bGdDb250cmFjdAkBGGdldENvbnRyYWN0QWRkcmVzc09yRmFpbAIFCHJlc3QyQ2ZnBQ1JZHhDZmdXbGdEYXBwABJpbnZlc3RGdW5kQ29udHJhY3QJARhnZXRDb250cmFjdEFkZHJlc3NPckZhaWwCBQhyZXN0MkNmZwUUSWR4Q2ZnSW52ZXN0RnVuZERhcHAAE29sZEFjcmVzQ29udHJhY3RLZXkCEG9sZEFjcmVzQ29udHJhY3QBCmtleUJsb2NrZWQAAhBjb250cmFjdHNCbG9ja2VkARVrZXlMYXN0V2Vla1R4SWRCeVVzZXIBBGFkZHIJAKwCAgITbGFzdFdlZWtUeElkQnlVc2VyXwUEYWRkcgEUa2V5Q3VyV2Vla1R4SWRCeVVzZXIBBGFkZHIJAKwCAgISY3VyV2Vla1R4SWRCeVVzZXJfBQRhZGRyABRhY3Jlc0lzc3VlZEFtb3VudEtleQIRYWNyZXNJc3N1ZWRBbW91bnQAD2FjcmVzQXNzZXRJZEtleQIMYWNyZXNBc3NldElkAAxhY3Jlc0Fzc2V0SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQ5hY3JlczJDb250cmFjdAUPYWNyZXNBc3NldElkS2V5AhdBQ1JFUyBpcyBub3QgaXNzdWVkIHlldAEYa2V5QWNyZXNTdGFrZWRUaW1lQnlVc2VyAQRhZGRyCQCsAgICFmFjcmVzU3Rha2VkVGltZUJ5VXNlcl8FBGFkZHIBFWtleVN0YWtlZExhbmRzQnlPd25lcgEJb3duZXJBZGRyCQCsAgICE3N0YWtlZExhbmRzQnlPd25lcl8FCW93bmVyQWRkcgEUa2V5U3Rha2VkRHVja0J5T3duZXIBCW93bmVyQWRkcgkArAICAhJzdGFrZWREdWNrQnlPd25lcl8FCW93bmVyQWRkcgEea2V5U3Rha2VkVGltZUJ5QXNzZXRJZEFuZE93bmVyAgdhc3NldElkBGFkZHIJAKwCAgkArAICCQCsAgICA3N0XwUHYXNzZXRJZAIBXwUEYWRkcgEUa2V5U3Rha2VkTkZUc0J5T3duZXIBCW93bmVyQWRkcgkArAICAhJzdGFrZWRORlRzQnlPd25lcl8FCW93bmVyQWRkcgEFYXNJbnQBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIDSW50BAFuBQckbWF0Y2gwBQFuCQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AQxhc1R1cGxlNUludHMBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACGShJbnQsIEludCwgSW50LCBJbnQsIEludCkEAXQFByRtYXRjaDAFAXQJAAIBAitmYWlsIHRvIGNhc3QgaW50byAoSW50LCBJbnQsIEludCwgSW50LCBJbnQpAQxhc1R1cGxlNEludHMBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACFChJbnQsIEludCwgSW50LCBJbnQpBAF0BQckbWF0Y2gwBQF0CQACAQImZmFpbCB0byBjYXN0IGludG8gKEludCwgSW50LCBJbnQsIEludCkBDGFzVHVwbGUzSW50cwEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIPKEludCwgSW50LCBJbnQpBAF0BQckbWF0Y2gwBQF0CQACAQIhZmFpbCB0byBjYXN0IGludG8gKEludCwgSW50LCBJbnQpAQxhc1R1cGxlMkludHMBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACCihJbnQsIEludCkEAXQFByRtYXRjaDAFAXQJAAIBAhxmYWlsIHRvIGNhc3QgaW50byAoSW50LCBJbnQpAQpmaXhlZFBvaW50AgN2YWwIZGVjaW1hbHMEBnRlblBvdwkAbAYACgAABQhkZWNpbWFscwAAAAAFBERPV04EB2xvd1BhcnQJAKQDAQkAagIFA3ZhbAUGdGVuUG93BAZ6ZXJvZXMJALACAgkApAMBBQZ0ZW5Qb3cJAGQCAAEJALECAQUHbG93UGFydAkArAICCQCsAgIJAKwCAgkApAMBCQBpAgUDdmFsBQZ0ZW5Qb3cCAS4FBnplcm9lcwUHbG93UGFydAADTTZfAMCEPQADTThfAIDC1y8AD3dsZ0lzc3VlZEFtdEtleQIQd2xnX2lzc3VlZEFtb3VudAAOemJJc3N1ZWRBbXRLZXkCEnpiaWxsX2lzc3VlZEFtb3VudAEXa2V5QWNyZXNTdGFrZWRBbXRCeVVzZXIBBGFkZHIJAKwCAgIYYWNyZXNTdGFrZWRBbW91bnRCeVVzZXJfBQRhZGRyARVrZXlGYXJtaW5nUG93ZXJCeVVzZXIBBGFkZHIJAKwCAgITZmFybWluZ1Bvd2VyQnlVc2VyXwUEYWRkcgASYWNyZXNTdGFrZFRvdGFsS2V5AhZhY3Jlc1N0YWtlZEFtb3VudFRvdGFsABR0b3RhbEZhcm1pbmdQb3dlcktleQIRdG90YWxGYXJtaW5nUG93ZXIAFUlkeER0eDNQZXJjQ29udmVyc2lvbgAAAAtNQVhfV0xfTkZUUwADAAxNQVhfQVJLX05GVFMAAQANQVJLX05GVF9CT05VUwCIJwAXTUFYX05GVFNfU1RBS0VEX0JZX1VTRVIABAARa2V5TmZ0VG90YWxJc3N1ZWQCDm5mdFRvdGFsSXNzdWVkARVrZXlOZnROdW1iZXJCeUFzc2V0SWQBB2Fzc2V0SWQJAKwCAgITbmZ0TnVtYmVyQnlBc3NldElkXwUHYXNzZXRJZAESa2V5VXNlcldsTmZ0TnVtYmVyAQRhZGRyCQCsAgICEHVzZXJXbE5mdE51bWJlcl8FBGFkZHIBE2tleVVzZXJBcmtOZnROdW1iZXIBBGFkZHIJAKwCAgIRdXNlckFya05mdE51bWJlcl8FBGFkZHIBEGtleVVzZXJGdWxsQm9udXMBBGFkZHIJAKwCAgIOdXNlckZ1bGxCb251c18FBGFkZHIACmxldmVsQWNyZXMJAMwIAgAACQDMCAIACgkAzAgCABQJAMwIAgAoCQDMCAIAUAkAzAgCAJYBCQDMCAIA+gEJAMwIAgCQAwkAzAgCALwFCQDMCAIA6AcFA25pbAEPZ2V0TGV2ZWxCeUFjcmVzAQVhY3JlcwQDYWNyCQBpAgkAZAIFBWFjcmVzAP/B1y8FA004XwoBB2NoZWNrZXICA2FjYwRpdGVtAwkAZwIFBGl0ZW0FA2FjcgUDYWNjCQBkAgUDYWNjAAEKAAIkbAUKbGV2ZWxBY3JlcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHY2hlY2tlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgEWZ2V0RmFybWluZ1Bvd2VyQnlBY3JlcwEFYWNyZXMJAGgCCQBoAgUFYWNyZXMAFAkAZAIJAQ9nZXRMZXZlbEJ5QWNyZXMBBQVhY3JlcwAEAR5nZXRGYXJtaW5nUG93ZXJCeUFjcmVzQW5kQm9udXMCBWFjcmVzBmJvbnVzNgQKbm90Qm9udXNlZAkBFmdldEZhcm1pbmdQb3dlckJ5QWNyZXMBBQVhY3JlcwkAlAoCCQBrAwUKbm90Qm9udXNlZAkAZAIFA002XwUGYm9udXM2BQNNNl8FCm5vdEJvbnVzZWQBGWtleUxhc3RXbGdUcmFkZVRpbWVCeVVzZXIBBGFkZHIJAKwCAgIQbGFzdEFyYlRpbWVVc2VyXwUEYWRkcgAUa2V5TGFzdEFjcmVzU2VsbFRpbWUCEWxhc3RBY3Jlc1NlbGxUaW1lABBrZXlMYXN0TGltaXRMZWZ0Ag1sYXN0TGltaXRMZWZ0AA9uZnREZXNjcmlwdGlvbnMJAMwIAgKXASwgImNvbGxlY3Rpb24iOiAiRGlnZ2luZyB0b29scyIsICJuYW1lIjogIkdvbGQgc2hvdmVsIiwgImRlc2NyaXB0aW9uIjogIlJld2FyZCBmb3IgZWFybHkgYmlyZHMiLCAicmFyZSI6ICJQcm9tbyIsICJib251cyI6IDMsICJib251c1R5cGUiOiAiRmFybVBvd2VyIn0JAMwIAgKRASwgImNvbGxlY3Rpb24iOiAiRGlnZ2luZyB0b29scyIsICJuYW1lIjogIlBpY2theGUiLCAiZGVzY3JpcHRpb24iOiAiSW5jcmVhc2VzIEZhcm1Qb3dlciIsICJyYXJlIjogIkNvbW1vbiIsICJib251cyI6IDEsICJib251c1R5cGUiOiAiRmFybVBvd2VyIn0FA25pbAAIbmZ0TmFtZXMJAMwIAgIJU0hPVkVMLVAzCQDMCAICClBJQ0tBWEUtQzEFA25pbAALY29udGVudEtleXMJAMwIAgIPY29udGVudFNob3ZlbFAzCQDMCAICEGNvbnRlbnRQaWNrYXhlQzEFA25pbAADVVJMAiEidXJsIjogImh0dHBzOi8vd2F2ZXNsYW5kcy5jb20iLCABBnByb2xvZwEBaQMDCQECIT0CCAUBaQxvcmlnaW5DYWxsZXIFDXJlc3QyQ29udHJhY3QJAQt2YWx1ZU9yRWxzZQIJAKAIAQkBCmtleUJsb2NrZWQABwcJAAIBAh9Db250cmFjdHMgYXJlIHVuZGVyIG1haW50ZW5hbmNlBARhZGRyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQEd2VlawkAaQIFBmhlaWdodAULV0VFS19CTE9DS1MEEmxhc3RXZWVrVHhJZEJ5VXNlcgkAoggBCQEVa2V5TGFzdFdlZWtUeElkQnlVc2VyAQUEYWRkcgQEdHhJZAkA2AQBCAUBaQ10cmFuc2FjdGlvbklkBAN3dHgJAKwCAgkArAICCQCkAwEFBHdlZWsCAV8FBHR4SWQDCQEJaXNEZWZpbmVkAQUSbGFzdFdlZWtUeElkQnlVc2VyBApsYXN0V2Vla1R4CQC1CQIJAQV2YWx1ZQEFEmxhc3RXZWVrVHhJZEJ5VXNlcgIBXwMJAAACCQCRAwIFCmxhc3RXZWVrVHgAAAkApAMBBQR3ZWVrCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlMYXN0V2Vla1R4SWRCeVVzZXIBBQRhZGRyBQN3dHgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFGtleUN1cldlZWtUeElkQnlVc2VyAQUEYWRkcgUDd3R4BQNuaWwDCQAAAgkAkQMCBQpsYXN0V2Vla1R4AAAJAKQDAQkAZQIFBHdlZWsAAQkAzAgCCQELU3RyaW5nRW50cnkCCQEUa2V5Q3VyV2Vla1R4SWRCeVVzZXIBBQRhZGRyBQN3dHgFA25pbAQRY3VyV2Vla1R4SWRCeVVzZXIJARFAZXh0ck5hdGl2ZSgxMDU4KQEJARVrZXlMYXN0V2Vla1R4SWRCeVVzZXIBBQRhZGRyBAljdXJXZWVrVHgJALUJAgURY3VyV2Vla1R4SWRCeVVzZXICAV8DCQAAAgkAkQMCBQljdXJXZWVrVHgAAAkApAMBBQR3ZWVrCQDMCAIJAQtTdHJpbmdFbnRyeQIJARRrZXlDdXJXZWVrVHhJZEJ5VXNlcgEFBGFkZHIFA3d0eAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVrZXlMYXN0V2Vla1R4SWRCeVVzZXIBBQRhZGRyBRFjdXJXZWVrVHhJZEJ5VXNlcgkAzAgCCQELU3RyaW5nRW50cnkCCQEUa2V5Q3VyV2Vla1R4SWRCeVVzZXIBBQRhZGRyBQN3dHgFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TGFzdFdlZWtUeElkQnlVc2VyAQUEYWRkcgUDd3R4CQDMCAIJAQtTdHJpbmdFbnRyeQIJARRrZXlDdXJXZWVrVHhJZEJ5VXNlcgEFBGFkZHIFA3d0eAUDbmlsARBpc3N1ZU5GVGludGVybmFsAghuZnRJbmRleARhZGRyAwkAZwIFCG5mdEluZGV4CQCQAwEFC2NvbnRlbnRLZXlzCQACAQIWbmZ0SW5kZXggb3V0IG9mIGJvdW5kcwQJbmZ0U2VyaWFsCQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBRFrZXlOZnRUb3RhbElzc3VlZAD///////////8BAAEEBWlzc3VlCQDCCAUJAJEDAgUIbmZ0TmFtZXMFCG5mdEluZGV4CQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAgF7BQNVUkwCDyJjb250ZW50S2V5IjogIgkAkQMCBQtjb250ZW50S2V5cwUIbmZ0SW5kZXgCDSIsICJudW1iZXIiOiAJAKQDAQUJbmZ0U2VyaWFsCQCRAwIFD25mdERlc2NyaXB0aW9ucwUIbmZ0SW5kZXgAAQAABwQKbmZ0QXNzZXRJZAkAuAgBBQVpc3N1ZQkAlAoCCQDMCAIFBWlzc3VlCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrZXlOZnRUb3RhbElzc3VlZAUJbmZ0U2VyaWFsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEVa2V5TmZ0TnVtYmVyQnlBc3NldElkAQkA2AQBBQpuZnRBc3NldElkBQluZnRTZXJpYWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUEYWRkcgABBQpuZnRBc3NldElkBQNuaWwFCm5mdEFzc2V0SWQBGXN0YWtlVW5zdGFrZUFjcmVzSW50ZXJuYWwDA2FtdAdhZGRyZXNzCmJvbnVzRGVsdGEDAwkAAAIFA2FtdAAACQAAAgUKYm9udXNEZWx0YQAABwkAAgECDU5vdGhpbmcgdG8gZG8ECXdsZ1Jlc3VsdAkA/AcEBQt3bGdDb250cmFjdAISb25TdGFrZVVuc3Rha2VMYW5kCQDMCAIFB2FkZHJlc3MFA25pbAUDbmlsAwkAAAIFCXdsZ1Jlc3VsdAUJd2xnUmVzdWx0BANub3cIBQlsYXN0QmxvY2sJdGltZXN0YW1wBAd0aW1lS2V5CQEYa2V5QWNyZXNTdGFrZWRUaW1lQnlVc2VyAQUHYWRkcmVzcwQJYW1vdW50S2V5CQEXa2V5QWNyZXNTdGFrZWRBbXRCeVVzZXIBBQdhZGRyZXNzBA5vbGRBY3Jlc0Ftb3VudAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQlhbW91bnRLZXkAAAMDCQBmAgAABQNhbXQJAGYCAAAJAGQCBQ5vbGRBY3Jlc0Ftb3VudAUDYW10BwkAAgEJAKwCAgkArAICCQCsAgICDllvdSBoYXZlIG9ubHkgCQEKZml4ZWRQb2ludAIFDm9sZEFjcmVzQW1vdW50AAgCICBBQ1JFUyBzdGFrZWQsIHRyaWVkIHRvIHVuc3Rha2UgCQEKZml4ZWRQb2ludAIJAQEtAQUDYW10AAgEDm5ld0FjcmVzQW1vdW50CQBkAgUOb2xkQWNyZXNBbW91bnQFA2FtdAQIb2xkVG90YWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUSYWNyZXNTdGFrZFRvdGFsS2V5AAAECXVzZXJGcEtleQkBFWtleUZhcm1pbmdQb3dlckJ5VXNlcgEFB2FkZHJlc3MEBW9sZEZwCQELdmFsdWVPckVsc2UCCQCfCAEFCXVzZXJGcEtleQAABAhib251c0tleQkBEGtleVVzZXJGdWxsQm9udXMBBQdhZGRyZXNzBAhvbGRCb251cwkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5hY3JlczJDb250cmFjdAUIYm9udXNLZXkAAAMDCQBmAgAABQpib251c0RlbHRhCQBmAgAACQBkAgUIb2xkQm9udXMFCmJvbnVzRGVsdGEHCQACAQkArAICCQCsAgIJAKwCAgkArAICAg5Zb3UgaGF2ZSBvbmx5IAkBCmZpeGVkUG9pbnQCBQhvbGRCb251cwAEAh4lIGJvbnVzLCBhbmQgdHJpZWQgdG8gdW5zdGFrZSAJAQpmaXhlZFBvaW50AgkBAS0BBQpib251c0RlbHRhAAQCASUECyR0MDU0Mjg1NTI3CQEeZ2V0RmFybWluZ1Bvd2VyQnlBY3Jlc0FuZEJvbnVzAgUObmV3QWNyZXNBbW91bnQJAGQCBQhvbGRCb251cwUKYm9udXNEZWx0YQQMbmV3Qm9udXNlZEZwCAULJHQwNTQyODU1MjcCXzEEB2lnbm9yZWQIBQskdDA1NDI4NTUyNwJfMgQKb2xkVG90YWxGcAkBC3ZhbHVlT3JFbHNlAgkAnwgBBRR0b3RhbEZhcm1pbmdQb3dlcktleQAABAxhY3Jlc0FjdGlvbnMDCQAAAgUDYW10AAAFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUJYW1vdW50S2V5BQ5uZXdBY3Jlc0Ftb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUSYWNyZXNTdGFrZFRvdGFsS2V5CQBkAgUIb2xkVG90YWwFA2FtdAUDbmlsCQCUCgIJAM0IAgkAzQgCCQDNCAIJAM0IAgUMYWNyZXNBY3Rpb25zCQEMSW50ZWdlckVudHJ5AgUHdGltZUtleQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAQxJbnRlZ2VyRW50cnkCBQl1c2VyRnBLZXkFDG5ld0JvbnVzZWRGcAkBDEludGVnZXJFbnRyeQIFFHRvdGFsRmFybWluZ1Bvd2VyS2V5CQBlAgkAZAIFCm9sZFRvdGFsRnAFDG5ld0JvbnVzZWRGcAUFb2xkRnAJAQxJbnRlZ2VyRW50cnkCBQhib251c0tleQkAZAIFCG9sZEJvbnVzBQpib251c0RlbHRhBQl3bGdSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BC2dldFdsZ1ByaWNlARV1c2R0QmFsYW5jZUNvcnJlY3Rpb24EDGlzc3VlZEFtb3VudAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFC3dsZ0NvbnRyYWN0BQ93bGdJc3N1ZWRBbXRLZXkCGFdMR09MRCBpcyBub3QgaXNzdWVkIHlldAQGd2xnVXNkCQDwBwIFC3dsZ0NvbnRyYWN0BQt1c2R0QXNzZXRJZAQJYWNyZXMyVXNkCQBlAgkA8AcCBQ5hY3JlczJDb250cmFjdAULdXNkdEFzc2V0SWQFFXVzZHRCYWxhbmNlQ29ycmVjdGlvbgQPaW52ZXN0RnVuZFRvdGFsCQBkAgkA8AcCBRJpbnZlc3RGdW5kQ29udHJhY3QFC3VzZHRBc3NldElkCQELdmFsdWVPckVsc2UCCQCaCAIFEmludmVzdEZ1bmRDb250cmFjdAUOemJJc3N1ZWRBbXRLZXkAAAQNdG90YWxGdW5kc1VzZAkAZAIJAGQCBQlhY3JlczJVc2QFBndsZ1VzZAUPaW52ZXN0RnVuZFRvdGFsCQBrAwUNdG90YWxGdW5kc1VzZAUFTVVMVDgFDGlzc3VlZEFtb3VudAERZ2V0U3dhcExpbWl0QWNyZXMABAZ3bGdVc2QJAPAHAgULd2xnQ29udHJhY3QFC3VzZHRBc3NldElkBAlhY3JlczJVc2QJAPAHAgUEdGhpcwULdXNkdEFzc2V0SWQED2ludmVzdEZ1bmRUb3RhbAkAZAIJAPAHAgUSaW52ZXN0RnVuZENvbnRyYWN0BQt1c2R0QXNzZXRJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBRJpbnZlc3RGdW5kQ29udHJhY3QFDnpiSXNzdWVkQW10S2V5AAAEDGRlZmF1bHRMaW1pdAkAaQIJAGQCCQBkAgUJYWNyZXMyVXNkBQZ3bGdVc2QFD2ludmVzdEZ1bmRUb3RhbAUTT05FX1BFUkNFTlRfRElWSVNPUgQNbGFzdExpbWl0TGVmdAkBC3ZhbHVlT3JFbHNlAgkAnwgBBRBrZXlMYXN0TGltaXRMZWZ0BQxkZWZhdWx0TGltaXQECGxhc3RUaW1lCQELdmFsdWVPckVsc2UCCQCfCAEFFGtleUxhc3RBY3Jlc1NlbGxUaW1lAAAEA25vdwgFCWxhc3RCbG9jawl0aW1lc3RhbXAEDGN1cnJlbnRMaW1pdAkAZAIFDWxhc3RMaW1pdExlZnQJAGsDBQxkZWZhdWx0TGltaXQJAGUCBQNub3cFCGxhc3RUaW1lBQpEQVlfTUlMTElTBA1saW1pdExlZnRVc2R0CQCXAwEJAMwIAgUMY3VycmVudExpbWl0CQDMCAIFDGRlZmF1bHRMaW1pdAUDbmlsCQCUCgIJAQxJbnRlZ2VyRW50cnkCBRRrZXlMYXN0QWNyZXNTZWxsVGltZQUDbm93BQ1saW1pdExlZnRVc2R0AAlhcmtPcmFjbGUJARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQSmdaNkFLMVdWQ3BkQ21FWnBlc0htYUt2clFEZFhHNW9nAAlpbmN1YmF0b3IJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUJYXJrT3JhY2xlAhdzdGF0aWNfaW5jdWJhdG9yQWRkcmVzcwIAAAdicmVlZGVyCQELdmFsdWVPckVsc2UCCQCdCAIFCWFya09yYWNsZQIVc3RhdGljX2JyZWVkZXJBZGRyZXNzAgAAD3R1cnRsZUluY3ViYXRvcgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQlhcmtPcmFjbGUCHXN0YXRpY190dXJ0bGVJbmN1YmF0b3JBZGRyZXNzAgAADXR1cnRsZUJyZWVkZXIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUJYXJrT3JhY2xlAhtzdGF0aWNfdHVydGxlQnJlZWRlckFkZHJlc3MCAAAPY2FuaW5lSW5jdWJhdG9yCQELdmFsdWVPckVsc2UCCQCdCAIFCWFya09yYWNsZQIdc3RhdGljX2NhbmluZUluY3ViYXRvckFkZHJlc3MCAAANY2FuaW5lQnJlZWRlcgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQlhcmtPcmFjbGUCG3N0YXRpY19jYW5pbmVCcmVlZGVyQWRkcmVzcwIAAA9mZWxpbmVJbmN1YmF0b3IJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUJYXJrT3JhY2xlAh1zdGF0aWNfZmVsaW5lSW5jdWJhdG9yQWRkcmVzcwIAAA1mZWxpbmVCcmVlZGVyCQELdmFsdWVPckVsc2UCCQCdCAIFCWFya09yYWNsZQIbc3RhdGljX2ZlbGluZUJyZWVkZXJBZGRyZXNzAgAADW11dGFudEJyZWVkZXIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUJYXJrT3JhY2xlAh1zdGF0aWNfbXV0YW50SW5jdWJhdG9yQWRkcmVzcwIAAQ9pc0Fya2ltYWxJc3N1ZWQBA25mbwQGaXNzdWVyCQClCAEIBQNuZm8GaXNzdWVyAwMDAwMDAwMJAAACBQZpc3N1ZXIFCWluY3ViYXRvcgYJAAACBQZpc3N1ZXIFB2JyZWVkZXIGCQAAAgUGaXNzdWVyBQ90dXJ0bGVJbmN1YmF0b3IGCQAAAgUGaXNzdWVyBQ10dXJ0bGVCcmVlZGVyBgkAAAIFBmlzc3VlcgUPY2FuaW5lSW5jdWJhdG9yBgkAAAIFBmlzc3VlcgUNY2FuaW5lQnJlZWRlcgYJAAACBQZpc3N1ZXIFD2ZlbGluZUluY3ViYXRvcgYJAAACBQZpc3N1ZXIFDWZlbGluZUJyZWVkZXIIBQNuZm8EbmFtZQMJAAACBQZpc3N1ZXIFDW11dGFudEJyZWVkZXIIBQNuZm8LZGVzY3JpcHRpb24CAAESYm9udXNCeURlc2NyaXB0aW9uAQVkZXNjcgMJAQEhAQkBCGNvbnRhaW5zAgUFZGVzY3ICGCJib251c1R5cGUiOiAiRmFybVBvd2VyIgkAAgECGE5GVCBpcyBub3Qgc3VwcG9ydGVkIHlldAQIYm9udXNTdHIJAJEDAgkAvAkCCQCRAwIJALwJAgUFZGVzY3ICCCJib251cyI6AAECASwAAAkAaAIJAQ1wYXJzZUludFZhbHVlAQkAsAICBQhib251c1N0cgkAZAIJAQt2YWx1ZU9yRWxzZQIJALcJAgUIYm9udXNTdHICASAA////////////AQABAJBOEAFpAQpzYXZlTGFzdFR4AAMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIJAMwIAgULd2xnQ29udHJhY3QFA25pbAgFAWkGY2FsbGVyCQACAQINQWNjZXNzIGRlbmllZAkAlAoCCQEGcHJvbG9nAQUBaQAqAWkBDWNvbnN0cnVjdG9yVjECCXJlc3QyQWRkcg5vbGRBY3JDb250cmFjdAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEVBlcm1pc3Npb24gZGVuaWVkBA5vbGRBY3JDb250QWRkcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUOb2xkQWNyQ29udHJhY3QJAMwIAgkBDEludGVnZXJFbnRyeQIFFGFjcmVzSXNzdWVkQW1vdW50S2V5CQERQGV4dHJOYXRpdmUoMTA1MCkCBQ5vbGRBY3JDb250QWRkcgUUYWNyZXNJc3N1ZWRBbW91bnRLZXkJAMwIAgkBC0JpbmFyeUVudHJ5AgUPYWNyZXNBc3NldElkS2V5CQERQGV4dHJOYXRpdmUoMTA1MikCBQ5vbGRBY3JDb250QWRkcgUPYWNyZXNBc3NldElkS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ9rZXlSZXN0MkFkZHJlc3MABQlyZXN0MkFkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgUTb2xkQWNyZXNDb250cmFjdEtleQUOb2xkQWNyQ29udHJhY3QFA25pbAFpAQpzZXRCbG9ja2VkAQlpc0Jsb2NrZWQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBCmtleUJsb2NrZWQABQlpc0Jsb2NrZWQFA25pbAFpAQx1bnN0YWtlQWNyZXMBBmFtb3VudAQNcHJvbG9nQWN0aW9ucwkBBnByb2xvZwEFAWkDCQBnAgAABQZhbW91bnQJAAIBAhlBbW91bnQgc2hvdWxkIGJlIHBvc2l0aXZlBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBA5hcmJSZWxlYXNlVGltZQkAZAIJAQt2YWx1ZU9yRWxzZQIJAJoIAgULd2xnQ29udHJhY3QJARlrZXlMYXN0V2xnVHJhZGVUaW1lQnlVc2VyAQUHYWRkcmVzcwAABQ5hcmJpdHJhZ2VEZWxheQMJAGYCBQ5hcmJSZWxlYXNlVGltZQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAAIBCQCsAgICLVlvdSB0cmFkZWQgc29tZSBXTEdPTEQsIGNhbm5vdCB1bnN0YWtlIHVudGlsIAkApAMBBQ5hcmJSZWxlYXNlVGltZQQNJHQwMTEwMjQxMTEwNAkBGXN0YWtlVW5zdGFrZUFjcmVzSW50ZXJuYWwDCQEBLQEFBmFtb3VudAUHYWRkcmVzcwAABAdhY3Rpb25zCAUNJHQwMTEwMjQxMTEwNAJfMQQQd2xnQ2xhaW1lZEFtb3VudAgFDSR0MDExMDI0MTExMDQCXzIJAJQKAgkAzggCCQDNCAIFB2FjdGlvbnMJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUGYW1vdW50BQxhY3Jlc0Fzc2V0SWQFDXByb2xvZ0FjdGlvbnMFEHdsZ0NsYWltZWRBbW91bnQBaQEKc3Rha2VBY3JlcwAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABANhbXQIBQNwbXQGYW1vdW50AwMJAQEhAQkBCWlzRGVmaW5lZAEIBQNwbXQHYXNzZXRJZAYJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAUMYWNyZXNBc3NldElkCQACAQIUQUNSRVMgcGF5bWVudHMgb25seSEEDSR0MDExNTU1MTE2MzEJARlzdGFrZVVuc3Rha2VBY3Jlc0ludGVybmFsAwUDYW10BQdhZGRyZXNzAAAEB2FjdGlvbnMIBQ0kdDAxMTU1NTExNjMxAl8xBBB3bGdDbGFpbWVkQW1vdW50CAUNJHQwMTE1NTUxMTYzMQJfMgkAlAoCCQDOCAIFB2FjdGlvbnMFDXByb2xvZ0FjdGlvbnMFEHdsZ0NsYWltZWRBbW91bnQBaQEIYnV5QWNyZXMABA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABAp1c2R0QW1vdW50CAUDcG10BmFtb3VudAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFC3VzZHRBc3NldElkCQACAQITVVNEVCBwYXltZW50cyBvbmx5IQMJAGYCBQVNVUxUNgUKdXNkdEFtb3VudAkAAgEJAKwCAgkArAICAhZNaW4gcGF5bWVudCBzaG91bGQgYmUgCQEKZml4ZWRQb2ludAIFBU1VTFQ2AAYCBSBVU0RUBAthY3Jlc0Ftb3VudAkAaAIFCnVzZHRBbW91bnQFFVVTRFQyQUNSRVNfTVVMVElQTElFUgQJd2xnQW1vdW50CQBrAwUKdXNkdEFtb3VudAUFTVVMVDgJAQtnZXRXbGdQcmljZQEFCnVzZHRBbW91bnQED29sZEFjcmVzQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUTb2xkQWNyZXNDb250cmFjdEtleQQDcmVxCQD8BwQFD29sZEFjcmVzQWRkcmVzcwIUcmVxdWVzdEFjcmVzQ2FsbGJhY2sJAMwIAgULYWNyZXNBbW91bnQFA25pbAUDbmlsAwkAAAIFA3JlcQUDcmVxBAl3bGdSZW1haW4JAQVhc0ludAEJAPwHBAULd2xnQ29udHJhY3QCCmJ1cm5XbGdvbGQJAMwIAgUJd2xnQW1vdW50BQNuaWwFA25pbAkAlAoCCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQthY3Jlc0Ftb3VudAUMYWNyZXNBc3NldElkBQNuaWwFDXByb2xvZ0FjdGlvbnMFCXdsZ1JlbWFpbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARBidXlBY3Jlc1JFQURPTkxZAQp1c2R0QW1vdW50BAthY3Jlc0Ftb3VudAkAaAIFCnVzZHRBbW91bnQFFVVTRFQyQUNSRVNfTVVMVElQTElFUgQJd2xnVG9CdXJuCQBrAwUKdXNkdEFtb3VudAUFTVVMVDgJAQtnZXRXbGdQcmljZQEFCnVzZHRBbW91bnQJAJQKAgUDbmlsCQDMCAIFC2FjcmVzQW1vdW50CQDMCAIFBU1VTFQ2CQDMCAIFC2FjcmVzQW1vdW50CQDMCAIFCXdsZ1RvQnVybgUDbmlsAWkBCXNlbGxBY3JlcwAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIiZXhhY3RseSAxIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEC2FjcmVzQW1vdW50CAUDcG10BmFtb3VudAMDCQEBIQEJAQlpc0RlZmluZWQBCAUDcG10B2Fzc2V0SWQGCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQFDGFjcmVzQXNzZXRJZAkAAgECFEFDUkVTIHBheW1lbnRzIG9ubHkhAwkAZgIFBU1VTFQ3BQthY3Jlc0Ftb3VudAkAAgEJAKwCAgkArAICAhZNaW4gcGF5bWVudCBzaG91bGQgYmUgCQEKZml4ZWRQb2ludAIFBU1VTFQ3AAgCBiBBQ1JFUwQEYWRkcgkApQgBCAUBaQZjYWxsZXIEDSR0MDEzNDg4MTM1MzYJARFnZXRTd2FwTGltaXRBY3JlcwAEC2xpbWl0QWN0aW9uCAUNJHQwMTM0ODgxMzUzNgJfMQQHbWF4VXNkdAgFDSR0MDEzNDg4MTM1MzYCXzIECG1heEFjcmVzCQBoAgUHbWF4VXNkdAUVVVNEVDJBQ1JFU19NVUxUSVBMSUVSAwkAZgIFC2FjcmVzQW1vdW50BQhtYXhBY3JlcwkAAgEJAKwCAgkArAICAhFZb3UgY2FuIHNlbGwgbWF4IAkBCmZpeGVkUG9pbnQCBQhtYXhBY3JlcwAIAgYgQUNSRVMECnVzZHRBbW91bnQJAGkCCQBpAgULYWNyZXNBbW91bnQFFVVTRFQyQUNSRVNfTVVMVElQTElFUgACCQCUCgIJAM4IAgkAzAgCBQtsaW1pdEFjdGlvbgkAzAgCCQEMSW50ZWdlckVudHJ5AgUQa2V5TGFzdExpbWl0TGVmdAkAZQIFB21heFVzZHQFCnVzZHRBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQp1c2R0QW1vdW50BQt1c2R0QXNzZXRJZAUDbmlsBQ1wcm9sb2dBY3Rpb25zBQp1c2R0QW1vdW50AWkBEXNlbGxBY3Jlc1JFQURPTkxZAgdhZGRyZXNzC2FjcmVzQW1vdW50BA0kdDAxNDAzMjE0MDgwCQERZ2V0U3dhcExpbWl0QWNyZXMABAtsaW1pdEFjdGlvbggFDSR0MDE0MDMyMTQwODACXzEEB21heFVzZHQIBQ0kdDAxNDAzMjE0MDgwAl8yBAp1c2R0QW1vdW50CQBpAgkAaQIFC2FjcmVzQW1vdW50BRVVU0RUMkFDUkVTX01VTFRJUExJRVIAAgkAlAoCBQNuaWwJAMwIAgUKdXNkdEFtb3VudAkAzAgCBQVNVUxUNwkAzAgCCQBoAgUHbWF4VXNkdAUVVVNEVDJBQ1JFU19NVUxUSVBMSUVSCQDMCAIAAAUDbmlsAWkBEGNvbnZlcnRPbGRTdGFrZXMAAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIUVGVtcG9yYXJpbHkgZGlzYWJsZWQEB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwAACQACAQIUTm8gcGF5bWVudHMgcmVxdWlyZWQED29sZEFjcmVzQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUTb2xkQWNyZXNDb250cmFjdEtleQQGYW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFD29sZEFjcmVzQWRkcmVzcwkBF2tleUFjcmVzU3Rha2VkQW10QnlVc2VyAQUHYWRkcmVzcwAABAlnb3RBY3JlczADCQBmAgUGYW1vdW50AAAJAQxhc1R1cGxlMkludHMBCQD8BwQFD29sZEFjcmVzQWRkcmVzcwIUdW5zdGFrZUFjcmVzQ2FsbGJhY2sJAMwIAgUGYW1vdW50CQDMCAIFB2FkZHJlc3MFA25pbAUDbmlsCQCUCgIAAAAABBFvbGRTdGFraW5nQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUVb2xkU3Rha2luZ0NvbnRyYWN0U3RyBAhsYW5kc1N0cgkAnQgCBRFvbGRTdGFraW5nQWRkcmVzcwkBFWtleVN0YWtlZExhbmRzQnlPd25lcgEFB2FkZHJlc3MEC2xhbmRzUmVzdWx0AwkBCWlzRGVmaW5lZAEFCGxhbmRzU3RyBAVsYW5kcwkAvQkCCQEFdmFsdWUBBQhsYW5kc1N0cgIBXwoBB29uZUxhbmQCA2FjYwtsYW5kQXNzZXRJZAMJAAACBQtsYW5kQXNzZXRJZAIACQACAQIXbGFuZEFzc2V0SWQgaXMgcmVxdWlyZWQEAXIJAQxhc1R1cGxlNUludHMBCQD8BwQFEW9sZFN0YWtpbmdBZGRyZXNzAhN1bnN0YWtlTGFuZENhbGxiYWNrCQDMCAIFC2xhbmRBc3NldElkCQDMCAIFB2FkZHJlc3MFA25pbAUDbmlsCQCWCgQJAGQCCAUDYWNjAl8xCAUBcgJfMQkAZAIIBQNhY2MCXzIIBQFyAl8yCQBkAggFA2FjYwJfMwgFAXICXzMJAGQCCAUDYWNjAl80CAUBcgJfNAQCcnIKAAIkbAUFbGFuZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQAAAAAAAAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHb25lTGFuZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIVTGlzdCBzaXplIGV4Y2VlZHMgMTAwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgAzADQANQA2ADcAOAA5ADoAOwA8AD0APgA/AEAAQQBCAEMARABFAEYARwBIAEkASgBLAEwATQBOAE8AUABRAFIAUwBUAFUAVgBXAFgAWQBaAFsAXABdAF4AXwBgAGEAYgBjAGQECGZpbmFsaXplCQD8BwQFEW9sZFN0YWtpbmdBZGRyZXNzAhx1bnN0YWtlTGFuZHNGaW5hbGl6ZUNhbGxiYWNrCQDMCAIFB2FkZHJlc3MFA25pbAUDbmlsAwkAAAIFCGZpbmFsaXplBQhmaW5hbGl6ZQQDcmVxCQD8BwQFD29sZEFjcmVzQWRkcmVzcwIUcmVxdWVzdEFjcmVzQ2FsbGJhY2sJAMwIAgkAZAIJAGQCCQBkAggFAnJyAl8xCAUCcnICXzIIBQJycgJfMwgFAnJyAl80BQNuaWwFA25pbAMJAAACBQNyZXEFA3JlcQQNJHQwMTU5NTIxNjAzMgkBEGlzc3VlTkZUaW50ZXJuYWwCBRVJZHhEdHgzUGVyY0NvbnZlcnNpb24IBQFpBmNhbGxlcgQKbmZ0QWN0aW9ucwgFDSR0MDE1OTUyMTYwMzICXzEECm5mdEFzc2V0SWQIBQ0kdDAxNTk1MjE2MDMyAl8yCQCXCgUIBQJycgJfMQgFAnJyAl8yCAUCcnICXzMIBQJycgJfNAUKbmZ0QWN0aW9ucwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlwoFAAAAAAAAAAAFA25pbAQLZHVja0Fzc2V0SWQJAQt2YWx1ZU9yRWxzZQIJAJ0IAgURb2xkU3Rha2luZ0FkZHJlc3MJARRrZXlTdGFrZWREdWNrQnlPd25lcgEFB2FkZHJlc3MCAAQKZHVja1Jlc3VsdAMJAQIhPQIFC2R1Y2tBc3NldElkAgAJAQxhc1R1cGxlM0ludHMBCQD8BwQFEW9sZFN0YWtpbmdBZGRyZXNzAhN1bnN0YWtlRHVja0NhbGxiYWNrCQDMCAIFC2R1Y2tBc3NldElkCQDMCAIFB2FkZHJlc3MFA25pbAUDbmlsCQCVCgMAAAAAAAAEAXgJARlzdGFrZVVuc3Rha2VBY3Jlc0ludGVybmFsAwkAZAIJAGQCCQBkAgkAZAIJAGQCCQBkAgkAZAIIBQlnb3RBY3JlczACXzEIBQtsYW5kc1Jlc3VsdAJfMQgFC2xhbmRzUmVzdWx0Al8yCAULbGFuZHNSZXN1bHQCXzMIBQtsYW5kc1Jlc3VsdAJfNAgFCmR1Y2tSZXN1bHQCXzEIBQpkdWNrUmVzdWx0Al8yCAUKZHVja1Jlc3VsdAJfMwUHYWRkcmVzcwAACQCUCgIJAM4IAggFC2xhbmRzUmVzdWx0Al81CAUBeAJfMQgFAXgCXzIBaQEUdW5zdGFrZUxhbmRzUkVBRE9OTFkBB2FkZHJlc3MEEW9sZFN0YWtpbmdBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBRVvbGRTdGFraW5nQ29udHJhY3RTdHIECGxhbmRzU3RyCQCdCAIFEW9sZFN0YWtpbmdBZGRyZXNzCQEVa2V5U3Rha2VkTGFuZHNCeU93bmVyAQUHYWRkcmVzcwQLbGFuZHNSZXN1bHQDCQEJaXNEZWZpbmVkAQUIbGFuZHNTdHIEBWxhbmRzCQC9CQIJAQV2YWx1ZQEFCGxhbmRzU3RyAgFfCgEHb25lTGFuZAIDYWNjC2xhbmRBc3NldElkAwkAAAIFC2xhbmRBc3NldElkAgAJAAIBAhdsYW5kQXNzZXRJZCBpcyByZXF1aXJlZAQBcgkBDGFzVHVwbGU0SW50cwEJAPwHBAURb2xkU3Rha2luZ0FkZHJlc3MCE3Vuc3Rha2VMYW5kUkVBRE9OTFkJAMwIAgULbGFuZEFzc2V0SWQJAMwIAgUHYWRkcmVzcwUDbmlsBQNuaWwJAJYKBAkAZAIIBQNhY2MCXzEIBQFyAl8xCQBkAggFA2FjYwJfMggFAXICXzIJAGQCCAUDYWNjAl8zCAUBcgJfMwkAZAIIBQNhY2MCXzQIBQFyAl80CgACJGwFBWxhbmRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlgoEAAAAAAAAAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB29uZUxhbmQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFUxpc3Qgc2l6ZSBleGNlZWRzIDEwMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAGIAYwBkCQCWCgQAAAAAAAAAAAkAlAoCBQNuaWwFC2xhbmRzUmVzdWx0AWkBEnN0YWtlQWNyZXNDYWxsYmFjawEEYWRkcgMJAQIhPQIIBQFpBmNhbGxlcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUVb2xkU3Rha2luZ0NvbnRyYWN0U3RyCQACAQIRUGVybWlzc2lvbiBkZW5pZWQJARlzdGFrZVVuc3Rha2VBY3Jlc0ludGVybmFsAwgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFBGFkZHIAAAFpARpzaW11bGF0ZVN0YWtlQWNyZXNSRUFET05MWQIHYWRkcmVzcwthZGRlZEFtb3VudAQJYW1vdW50S2V5CQEXa2V5QWNyZXNTdGFrZWRBbXRCeVVzZXIBBQdhZGRyZXNzBA5uZXdBY3Jlc0Ftb3VudAkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJYW1vdW50S2V5AAAFC2FkZGVkQW1vdW50BAhvbGRUb3RhbAkBC3ZhbHVlT3JFbHNlAgkAnwgBBRJhY3Jlc1N0YWtkVG90YWxLZXkAAAQJdXNlckZwS2V5CQEVa2V5RmFybWluZ1Bvd2VyQnlVc2VyAQUHYWRkcmVzcwQFb2xkRnAJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUJdXNlckZwS2V5AAAECXVzZXJCb251cwkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5hY3JlczJDb250cmFjdAkBEGtleVVzZXJGdWxsQm9udXMBBQdhZGRyZXNzAAAEDSR0MDE4MTk3MTgyODQJAR5nZXRGYXJtaW5nUG93ZXJCeUFjcmVzQW5kQm9udXMCBQ5uZXdBY3Jlc0Ftb3VudAUJdXNlckJvbnVzBAxuZXdCb251c2VkRnAIBQ0kdDAxODE5NzE4Mjg0Al8xBAdpZ25vcmVkCAUNJHQwMTgxOTcxODI4NAJfMgQKb2xkVG90YWxGcAkBC3ZhbHVlT3JFbHNlAgkAnwgBBRR0b3RhbEZhcm1pbmdQb3dlcktleQAABApuZXdUb3RhbEZwCQBlAgkAZAIFCm9sZFRvdGFsRnAFDG5ld0JvbnVzZWRGcAUFb2xkRnAJAJQKAgUDbmlsCQDMCAIFBW9sZEZwCQDMCAIFDG5ld0JvbnVzZWRGcAkAzAgCBQpvbGRUb3RhbEZwCQDMCAIFCm5ld1RvdGFsRnAFA25pbAFpAQhpc3N1ZU5GVAIKZm9yQWRkcmVzcwhuZnRJbmRleAMJAQIhPQIIBQFpBmNhbGxlcgULd2xnQ29udHJhY3QJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAkBEGlzc3VlTkZUaW50ZXJuYWwCBQhuZnRJbmRleAkBEUBleHRyTmF0aXZlKDEwNjIpAQUKZm9yQWRkcmVzcwFpAQhzdGFrZU5GVAAEDXByb2xvZ0FjdGlvbnMJAQZwcm9sb2cBBQFpAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIcRXhhY3RseSBvbmUgcGF5bWVudCByZXF1aXJlZAQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCAUDcG10BmFtb3VudAABCQACAQInTkZUIHRva2VuIHNob3VsZCBiZSBhdHRhY2hlZCBhcyBwYXltZW50BAdhc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQEBWFzc2V0CQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQECmFzc2V0SWRTdHIJANgEAQUHYXNzZXRJZAQEYWRkcgkApQgBCAUBaQZjYWxsZXIEB25mdHNLZXkJARRrZXlTdGFrZWRORlRzQnlPd25lcgEFBGFkZHIEB25mdHNTdHIJAKIIAQUHbmZ0c0tleQQEbmZ0cwMJAQlpc0RlZmluZWQBBQduZnRzU3RyCQC8CQIJAQV2YWx1ZQEFB25mdHNTdHICAV8FA25pbAMJAQ9jb250YWluc0VsZW1lbnQCBQRuZnRzBQphc3NldElkU3RyCQACAQkArAICAiJZb3VyIHN0YWtlZCBsYW5kcyBhbHJlYWR5IGNvbnRhaW4gBQphc3NldElkU3RyAwkAZwIJAJADAQUEbmZ0cwUXTUFYX05GVFNfU1RBS0VEX0JZX1VTRVIJAAIBCQCsAgIJAKwCAgIZWW91ciBhbHJlYWR5IHN0YWtlZCBtYXggKAkApAMBBRdNQVhfTkZUU19TVEFLRURfQllfVVNFUgIGKSBORlRzBApsaXN0QWN0aW9uCQELU3RyaW5nRW50cnkCBQduZnRzS2V5CQC6CQIJAM0IAgUEbmZ0cwUKYXNzZXRJZFN0cgIBXwQEaXNXTAkAAAIIBQVhc3NldAZpc3N1ZXIFBHRoaXMDBQRpc1dMBAt3bE5mdE51bWJlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQESa2V5VXNlcldsTmZ0TnVtYmVyAQUEYWRkcgAAAwkAZwIFC3dsTmZ0TnVtYmVyBQtNQVhfV0xfTkZUUwkAAgEJAKwCAgkArAICAhJZb3UgY2FuIHN0YWtlIG1heCAJAKQDAQULTUFYX1dMX05GVFMCEyBvZiBXYXZlc0xhbmRzIE5GVHMECGJvbnVzVmFsCQESYm9udXNCeURlc2NyaXB0aW9uAQkBBXZhbHVlAQgFBWFzc2V0C2Rlc2NyaXB0aW9uBA0kdDAyMDA1MjIwMTMwCQEZc3Rha2VVbnN0YWtlQWNyZXNJbnRlcm5hbAMAAAUEYWRkcgUIYm9udXNWYWwEB2FjdGlvbnMIBQ0kdDAyMDA1MjIwMTMwAl8xBBB3bGdDbGFpbWVkQW1vdW50CAUNJHQwMjAwNTIyMDEzMAJfMgkAlAoCCQDOCAIJAM0IAgkAzQgCCQDNCAIFB2FjdGlvbnMFCmxpc3RBY3Rpb24JAQxJbnRlZ2VyRW50cnkCCQESa2V5VXNlcldsTmZ0TnVtYmVyAQUEYWRkcgkAZAIFC3dsTmZ0TnVtYmVyAAEJAQxJbnRlZ2VyRW50cnkCCQEea2V5U3Rha2VkVGltZUJ5QXNzZXRJZEFuZE93bmVyAgUKYXNzZXRJZFN0cgUEYWRkcggFCWxhc3RCbG9jawl0aW1lc3RhbXAFDXByb2xvZ0FjdGlvbnMFEHdsZ0NsYWltZWRBbW91bnQEC2Fya2ltYWxOYW1lCQEPaXNBcmtpbWFsSXNzdWVkAQUFYXNzZXQDCQAAAgULYXJraW1hbE5hbWUCAAkAAgECNE9ubHkgV2F2ZXNMYW5kcyBhbmQgQXJraW1hbHMgTkZUIHRva2VucyBhcmUgYWNjZXB0ZWQEDGFya05mdE51bWJlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQETa2V5VXNlckFya05mdE51bWJlcgEFBGFkZHIAAAMJAGcCBQxhcmtOZnROdW1iZXIFDE1BWF9BUktfTkZUUwkAAgEJAKwCAgkArAICAhJZb3UgY2FuIHN0YWtlIG1heCAJAKQDAQUMTUFYX0FSS19ORlRTAhEgb2YgQXJraW1hbHMgTkZUcwQNJHQwMjA3NzIyMDg1NQkBGXN0YWtlVW5zdGFrZUFjcmVzSW50ZXJuYWwDAAAFBGFkZHIFDUFSS19ORlRfQk9OVVMEB2FjdGlvbnMIBQ0kdDAyMDc3MjIwODU1Al8xBBB3bGdDbGFpbWVkQW1vdW50CAUNJHQwMjA3NzIyMDg1NQJfMgkAlAoCCQDOCAIJAM0IAgkAzQgCCQDNCAIFB2FjdGlvbnMFCmxpc3RBY3Rpb24JAQxJbnRlZ2VyRW50cnkCCQETa2V5VXNlckFya05mdE51bWJlcgEFBGFkZHIJAGQCBQxhcmtOZnROdW1iZXIAAQkBDEludGVnZXJFbnRyeQIJAR5rZXlTdGFrZWRUaW1lQnlBc3NldElkQW5kT3duZXICBQphc3NldElkU3RyBQRhZGRyCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUNcHJvbG9nQWN0aW9ucwUQd2xnQ2xhaW1lZEFtb3VudAFpAQp1bnN0YWtlTkZUAQphc3NldElkU3RyBA1wcm9sb2dBY3Rpb25zCQEGcHJvbG9nAQUBaQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECFE5vIHBheW1lbnRzIHJlcXVpcmVkBAdhc3NldElkCQDZBAEFCmFzc2V0SWRTdHIEBGFkZHIJAKUIAQgFAWkGY2FsbGVyBAVhc3NldAkBBXZhbHVlAQkA7AcBBQdhc3NldElkBAd0aW1lS2V5CQEea2V5U3Rha2VkVGltZUJ5QXNzZXRJZEFuZE93bmVyAgUKYXNzZXRJZFN0cgUEYWRkcgMJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUHdGltZUtleQkAAgEJAKwCAgkArAICAgRORlQgCAUFYXNzZXQEbmFtZQIVIGlzIG5vdCBzdGFrZWQgYnkgeW91BAduZnRzS2V5CQEUa2V5U3Rha2VkTkZUc0J5T3duZXIBBQRhZGRyBARuZnRzCQC8CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUHbmZ0c0tleQIAAgFfBANpZHgJAM8IAgUEbmZ0cwUKYXNzZXRJZFN0cgMJAQEhAQkBCWlzRGVmaW5lZAEFA2lkeAkAAgEJAKwCAgIfWW91ciBzdGFrZWQgTkZUcyBkb24ndCBjb250YWluIAUKYXNzZXRJZFN0cgQKbGlzdEFjdGlvbgMJAGYCCQCQAwEFBG5mdHMAAQkBC1N0cmluZ0VudHJ5AgUHbmZ0c0tleQkAugkCCQDRCAIFBG5mdHMJAQV2YWx1ZQEFA2lkeAIBXwkBC0RlbGV0ZUVudHJ5AQUHbmZ0c0tleQQEaXNXTAkAAAIIBQVhc3NldAZpc3N1ZXIFBHRoaXMDBQRpc1dMBAt3bE5mdE51bWJlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQESa2V5VXNlcldsTmZ0TnVtYmVyAQUEYWRkcgAABAhib251c1ZhbAkBEmJvbnVzQnlEZXNjcmlwdGlvbgEJAQV2YWx1ZQEIBQVhc3NldAtkZXNjcmlwdGlvbgQNJHQwMjIxNjgyMjI0NwkBGXN0YWtlVW5zdGFrZUFjcmVzSW50ZXJuYWwDAAAFBGFkZHIJAQEtAQUIYm9udXNWYWwEB2FjdGlvbnMIBQ0kdDAyMjE2ODIyMjQ3Al8xBBB3bGdDbGFpbWVkQW1vdW50CAUNJHQwMjIxNjgyMjI0NwJfMgkAlAoCCQDOCAIJAM0IAgkAzQgCCQDNCAIFB2FjdGlvbnMFCmxpc3RBY3Rpb24JAQxJbnRlZ2VyRW50cnkCCQESa2V5VXNlcldsTmZ0TnVtYmVyAQUEYWRkcgkAZQIFC3dsTmZ0TnVtYmVyAAEJAQtEZWxldGVFbnRyeQEJAR5rZXlTdGFrZWRUaW1lQnlBc3NldElkQW5kT3duZXICCQDYBAEFB2Fzc2V0SWQFBGFkZHIFDXByb2xvZ0FjdGlvbnMFEHdsZ0NsYWltZWRBbW91bnQEC2Fya2ltYWxOYW1lCQEPaXNBcmtpbWFsSXNzdWVkAQUFYXNzZXQDCQAAAgULYXJraW1hbE5hbWUCAAkAAgECNE9ubHkgV2F2ZXNMYW5kcyBhbmQgQXJraW1hbHMgTkZUIHRva2VucyBhcmUgYWNjZXB0ZWQEDGFya05mdE51bWJlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQETa2V5VXNlckFya05mdE51bWJlcgEFBGFkZHIAAAQNJHQwMjI3NjAyMjg0NAkBGXN0YWtlVW5zdGFrZUFjcmVzSW50ZXJuYWwDAAAFBGFkZHIJAQEtAQUNQVJLX05GVF9CT05VUwQHYWN0aW9ucwgFDSR0MDIyNzYwMjI4NDQCXzEEEHdsZ0NsYWltZWRBbW91bnQIBQ0kdDAyMjc2MDIyODQ0Al8yCQCUCgIJAM4IAgkAzQgCCQDNCAIJAM0IAgUHYWN0aW9ucwUKbGlzdEFjdGlvbgkBDEludGVnZXJFbnRyeQIJARNrZXlVc2VyQXJrTmZ0TnVtYmVyAQUEYWRkcgkAZQIFDGFya05mdE51bWJlcgABCQELRGVsZXRlRW50cnkBCQEea2V5U3Rha2VkVGltZUJ5QXNzZXRJZEFuZE93bmVyAgkA2AQBBQdhc3NldElkBQRhZGRyBQ1wcm9sb2dBY3Rpb25zBRB3bGdDbGFpbWVkQW1vdW50AKq2tJ4=", "height": 3386928, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 69ijjqwnaVAFbMg3p2DPdCsmaPxyrwckkiXVT62PFWmv Next: 2C6DWP1ZvbN5KeNym6RcL48zZpGVBp7DutgdY6PzTHk9 Diff:
OldNewDifferences
1616 let ONE_PERCENT_DIVISOR = 100
1717
1818 let chain = take(drop(this.bytes, 1), 1)
19+
20+let WEEK_BLOCKS = match chain {
21+ case _ =>
22+ if ((base58'2W' == $match0))
23+ then 10080
24+ else if ((base58'2T' == $match0))
25+ then 180
26+ else throw("Unknown chain")
27+}
1928
2029 let usdtAssetId = match chain {
2130 case _ =>
110119 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
111120
112121
122+func keyStakedTimeByAssetIdAndOwner (assetId,addr) = ((("st_" + assetId) + "_") + addr)
123+
124+
125+func keyStakedNFTsByOwner (ownerAddr) = ("stakedNFTsByOwner_" + ownerAddr)
126+
127+
113128 func asInt (v) = match v {
114129 case n: Int =>
115130 n
158173 }
159174
160175
176+let M6_ = 1000000
177+
161178 let M8_ = 100000000
162-
163-let WEEK_BLOCKS = 10080
164179
165180 let wlgIssuedAmtKey = "wlg_issuedAmount"
166181
177192 let totalFarmingPowerKey = "totalFarmingPower"
178193
179194 let IdxDtx3PercConversion = 0
195+
196+let MAX_WL_NFTS = 3
197+
198+let MAX_ARK_NFTS = 1
199+
200+let ARK_NFT_BONUS = 5000
201+
202+let MAX_NFTS_STAKED_BY_USER = 4
203+
204+let keyNftTotalIssued = "nftTotalIssued"
205+
206+func keyNftNumberByAssetId (assetId) = ("nftNumberByAssetId_" + assetId)
207+
208+
209+func keyUserWlNftNumber (addr) = ("userWlNftNumber_" + addr)
210+
211+
212+func keyUserArkNftNumber (addr) = ("userArkNftNumber_" + addr)
213+
214+
215+func keyUserFullBonus (addr) = ("userFullBonus_" + addr)
216+
180217
181218 let levelAcres = [0, 10, 20, 40, 80, 150, 250, 400, 700, 1000]
182219
204241 func getFarmingPowerByAcres (acres) = ((acres * 20) * (getLevelByAcres(acres) + 4))
205242
206243
207-let keyNftTotalIssued = "nftTotalIssued"
208-
209-func keyNftNumberByAssetId (assetId) = ("nftNumberByAssetId_" + assetId)
244+func getFarmingPowerByAcresAndBonus (acres,bonus6) = {
245+ let notBonused = getFarmingPowerByAcres(acres)
246+ $Tuple2(fraction(notBonused, (M6_ + bonus6), M6_), notBonused)
247+ }
210248
211249
212250 func keyLastWlgTradeTimeByUser (addr) = ("lastArbTimeUser_" + addr)
216254
217255 let keyLastLimitLeft = "lastLimitLeft"
218256
219-let nftDescriptions = [", \"name\": \"Gold shovel\", \"description\": \"Reward for early birds\", \"rare\": \"Promo\", \"bonus\": 3, \"bonusType\": \"FarmPower\"}", ", \"name\": \"Pickaxe\", \"description\": \"Increases FarmPower\", \"rare\": \"Common\", \"bonus\": 1, \"bonusType\": \"FarmPower\"}"]
257+let nftDescriptions = [", \"collection\": \"Digging tools\", \"name\": \"Gold shovel\", \"description\": \"Reward for early birds\", \"rare\": \"Promo\", \"bonus\": 3, \"bonusType\": \"FarmPower\"}", ", \"collection\": \"Digging tools\", \"name\": \"Pickaxe\", \"description\": \"Increases FarmPower\", \"rare\": \"Common\", \"bonus\": 1, \"bonusType\": \"FarmPower\"}"]
220258
221259 let nftNames = ["SHOVEL-P3", "PICKAXE-C1"]
222260
263301 }
264302
265303
266-func stakeUnstakeAcresInternal (amt,address) = {
267- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
268- if ((wlgResult == wlgResult))
269- then {
270- let now = lastBlock.timestamp
271- let timeKey = keyAcresStakedTimeByUser(address)
272- let amountKey = keyAcresStakedAmtByUser(address)
273- let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
274- if (if ((0 > amt))
275- then (0 > (oldAcresAmount + amt))
276- else false)
277- then throw(((("You have only " + fixedPoint(oldAcresAmount, 8)) + " ACRES staked, tried to unstake ") + fixedPoint(-(amt), 8)))
278- else {
279- let newAcresAmount = (oldAcresAmount + amt)
280- let oldTotal = valueOrElse(getInteger(acresStakdTotalKey), 0)
281- let userFpKey = keyFarmingPowerByUser(address)
282- let oldFp = valueOrElse(getInteger(userFpKey), 0)
283- let newFp = getFarmingPowerByAcres(newAcresAmount)
284- let oldTotalFp = valueOrElse(getInteger(totalFarmingPowerKey), 0)
285- $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(amountKey, newAcresAmount), IntegerEntry(acresStakdTotalKey, (oldTotal + amt)), IntegerEntry(userFpKey, newFp), IntegerEntry(totalFarmingPowerKey, ((oldTotalFp - oldFp) + newFp))], wlgResult)
286- }
287- }
288- else throw("Strict value is not equal to itself.")
289- }
304+func stakeUnstakeAcresInternal (amt,address,bonusDelta) = if (if ((amt == 0))
305+ then (bonusDelta == 0)
306+ else false)
307+ then throw("Nothing to do")
308+ else {
309+ let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
310+ if ((wlgResult == wlgResult))
311+ then {
312+ let now = lastBlock.timestamp
313+ let timeKey = keyAcresStakedTimeByUser(address)
314+ let amountKey = keyAcresStakedAmtByUser(address)
315+ let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
316+ if (if ((0 > amt))
317+ then (0 > (oldAcresAmount + amt))
318+ else false)
319+ then throw(((("You have only " + fixedPoint(oldAcresAmount, 8)) + " ACRES staked, tried to unstake ") + fixedPoint(-(amt), 8)))
320+ else {
321+ let newAcresAmount = (oldAcresAmount + amt)
322+ let oldTotal = valueOrElse(getInteger(acresStakdTotalKey), 0)
323+ let userFpKey = keyFarmingPowerByUser(address)
324+ let oldFp = valueOrElse(getInteger(userFpKey), 0)
325+ let bonusKey = keyUserFullBonus(address)
326+ let oldBonus = valueOrElse(getInteger(acres2Contract, bonusKey), 0)
327+ if (if ((0 > bonusDelta))
328+ then (0 > (oldBonus + bonusDelta))
329+ else false)
330+ then throw((((("You have only " + fixedPoint(oldBonus, 4)) + "% bonus, and tried to unstake ") + fixedPoint(-(bonusDelta), 4)) + "%"))
331+ else {
332+ let $t054285527 = getFarmingPowerByAcresAndBonus(newAcresAmount, (oldBonus + bonusDelta))
333+ let newBonusedFp = $t054285527._1
334+ let ignored = $t054285527._2
335+ let oldTotalFp = valueOrElse(getInteger(totalFarmingPowerKey), 0)
336+ let acresActions = if ((amt == 0))
337+ then nil
338+ else [IntegerEntry(amountKey, newAcresAmount), IntegerEntry(acresStakdTotalKey, (oldTotal + amt))]
339+ $Tuple2(((((acresActions :+ IntegerEntry(timeKey, lastBlock.timestamp)) :+ IntegerEntry(userFpKey, newBonusedFp)) :+ IntegerEntry(totalFarmingPowerKey, ((oldTotalFp + newBonusedFp) - oldFp))) :+ IntegerEntry(bonusKey, (oldBonus + bonusDelta))), wlgResult)
340+ }
341+ }
342+ }
343+ else throw("Strict value is not equal to itself.")
344+ }
290345
291346
292347 func getWlgPrice (usdtBalanceCorrection) = {
311366 let limitLeftUsdt = min([currentLimit, defaultLimit])
312367 $Tuple2(IntegerEntry(keyLastAcresSellTime, now), limitLeftUsdt)
313368 }
369+
370+
371+let arkOracle = addressFromStringValue("3PJgZ6AK1WVCpdCmEZpesHmaKvrQDdXG5og")
372+
373+let incubator = valueOrElse(getString(arkOracle, "static_incubatorAddress"), "")
374+
375+let breeder = valueOrElse(getString(arkOracle, "static_breederAddress"), "")
376+
377+let turtleIncubator = valueOrElse(getString(arkOracle, "static_turtleIncubatorAddress"), "")
378+
379+let turtleBreeder = valueOrElse(getString(arkOracle, "static_turtleBreederAddress"), "")
380+
381+let canineIncubator = valueOrElse(getString(arkOracle, "static_canineIncubatorAddress"), "")
382+
383+let canineBreeder = valueOrElse(getString(arkOracle, "static_canineBreederAddress"), "")
384+
385+let felineIncubator = valueOrElse(getString(arkOracle, "static_felineIncubatorAddress"), "")
386+
387+let felineBreeder = valueOrElse(getString(arkOracle, "static_felineBreederAddress"), "")
388+
389+let mutantBreeder = valueOrElse(getString(arkOracle, "static_mutantIncubatorAddress"), "")
390+
391+func isArkimalIssued (nfo) = {
392+ let issuer = toString(nfo.issuer)
393+ if (if (if (if (if (if (if (if ((issuer == incubator))
394+ then true
395+ else (issuer == breeder))
396+ then true
397+ else (issuer == turtleIncubator))
398+ then true
399+ else (issuer == turtleBreeder))
400+ then true
401+ else (issuer == canineIncubator))
402+ then true
403+ else (issuer == canineBreeder))
404+ then true
405+ else (issuer == felineIncubator))
406+ then true
407+ else (issuer == felineBreeder))
408+ then nfo.name
409+ else if ((issuer == mutantBreeder))
410+ then nfo.description
411+ else ""
412+ }
413+
414+
415+func bonusByDescription (descr) = if (!(contains(descr, "\"bonusType\": \"FarmPower\"")))
416+ then throw("NFT is not supported yet")
417+ else {
418+ let bonusStr = split_4C(split_4C(descr, "\"bonus\":")[1], ",")[0]
419+ (parseIntValue(drop(bonusStr, (valueOrElse(lastIndexOf(bonusStr, " "), -1) + 1))) * 10000)
420+ }
314421
315422
316423 @Callable(i)
351458 if ((arbReleaseTime > lastBlock.timestamp))
352459 then throw(("You traded some WLGOLD, cannot unstake until " + toString(arbReleaseTime)))
353460 else {
354- let $t074207497 = stakeUnstakeAcresInternal(-(amount), address)
355- let actions = $t074207497._1
356- let wlgClaimedAmount = $t074207497._2
461+ let $t01102411104 = stakeUnstakeAcresInternal(-(amount), address, 0)
462+ let actions = $t01102411104._1
463+ let wlgClaimedAmount = $t01102411104._2
357464 $Tuple2(((actions :+ ScriptTransfer(i.caller, amount, acresAssetId)) ++ prologActions), wlgClaimedAmount)
358465 }
359466 }
376483 else (value(pmt.assetId) != acresAssetId))
377484 then throw("ACRES payments only!")
378485 else {
379- let $t079488021 = stakeUnstakeAcresInternal(amt, address)
380- let actions = $t079488021._1
381- let wlgClaimedAmount = $t079488021._2
486+ let $t01155511631 = stakeUnstakeAcresInternal(amt, address, 0)
487+ let actions = $t01155511631._1
488+ let wlgClaimedAmount = $t01155511631._2
382489 $Tuple2((actions ++ prologActions), wlgClaimedAmount)
383490 }
384491 }
442549 then throw((("Min payment should be " + fixedPoint(MULT7, 8)) + " ACRES"))
443550 else {
444551 let addr = toString(i.caller)
445- let $t098789926 = getSwapLimitAcres()
446- let limitAction = $t098789926._1
447- let maxUsdt = $t098789926._2
552+ let $t01348813536 = getSwapLimitAcres()
553+ let limitAction = $t01348813536._1
554+ let maxUsdt = $t01348813536._2
448555 let maxAcres = (maxUsdt * USDT2ACRES_MULTIPLIER)
449556 if ((acresAmount > maxAcres))
450557 then throw((("You can sell max " + fixedPoint(maxAcres, 8)) + " ACRES"))
460567
461568 @Callable(i)
462569 func sellAcresREADONLY (address,acresAmount) = {
463- let $t01042210470 = getSwapLimitAcres()
464- let limitAction = $t01042210470._1
465- let maxUsdt = $t01042210470._2
570+ let $t01403214080 = getSwapLimitAcres()
571+ let limitAction = $t01403214080._1
572+ let maxUsdt = $t01403214080._2
466573 let usdtAmount = ((acresAmount / USDT2ACRES_MULTIPLIER) / 2)
467574 $Tuple2(nil, [usdtAmount, MULT7, (maxUsdt * USDT2ACRES_MULTIPLIER), 0])
468575 }
514621 let req = invoke(oldAcresAddress, "requestAcresCallback", [(((rr._1 + rr._2) + rr._3) + rr._4)], nil)
515622 if ((req == req))
516623 then {
517- let $t01234212422 = issueNFTinternal(IdxDtx3PercConversion, i.caller)
518- let nftActions = $t01234212422._1
519- let nftAssetId = $t01234212422._2
624+ let $t01595216032 = issueNFTinternal(IdxDtx3PercConversion, i.caller)
625+ let nftActions = $t01595216032._1
626+ let nftAssetId = $t01595216032._2
520627 $Tuple5(rr._1, rr._2, rr._3, rr._4, nftActions)
521628 }
522629 else throw("Strict value is not equal to itself.")
528635 let duckResult = if ((duckAssetId != ""))
529636 then asTuple3Ints(invoke(oldStakingAddress, "unstakeDuckCallback", [duckAssetId, address], nil))
530637 else $Tuple3(0, 0, 0)
531- let x = stakeUnstakeAcresInternal((((((((gotAcres0._1 + landsResult._1) + landsResult._2) + landsResult._3) + landsResult._4) + duckResult._1) + duckResult._2) + duckResult._3), address)
638+ let x = stakeUnstakeAcresInternal((((((((gotAcres0._1 + landsResult._1) + landsResult._2) + landsResult._3) + landsResult._4) + duckResult._1) + duckResult._2) + duckResult._3), address, 0)
532639 $Tuple2((landsResult._5 ++ x._1), x._2)
533640 }
534641 }
571678 @Callable(i)
572679 func stakeAcresCallback (addr) = if ((i.caller != addressFromStringValue(oldStakingContractStr)))
573680 then throw("Permission denied")
574- else stakeUnstakeAcresInternal(i.payments[0].amount, addr)
681+ else stakeUnstakeAcresInternal(i.payments[0].amount, addr, 0)
575682
576683
577684
582689 let oldTotal = valueOrElse(getInteger(acresStakdTotalKey), 0)
583690 let userFpKey = keyFarmingPowerByUser(address)
584691 let oldFp = valueOrElse(getInteger(userFpKey), 0)
585- let newFp = getFarmingPowerByAcres(newAcresAmount)
692+ let userBonus = valueOrElse(getInteger(acres2Contract, keyUserFullBonus(address)), 0)
693+ let $t01819718284 = getFarmingPowerByAcresAndBonus(newAcresAmount, userBonus)
694+ let newBonusedFp = $t01819718284._1
695+ let ignored = $t01819718284._2
586696 let oldTotalFp = valueOrElse(getInteger(totalFarmingPowerKey), 0)
587- let newTotalFp = ((oldTotalFp - oldFp) + newFp)
588- $Tuple2(nil, [oldFp, newFp, oldTotalFp, newTotalFp])
697+ let newTotalFp = ((oldTotalFp + newBonusedFp) - oldFp)
698+ $Tuple2(nil, [oldFp, newBonusedFp, oldTotalFp, newTotalFp])
589699 }
590700
591701
596706 else issueNFTinternal(nftIndex, addressFromStringValue(forAddress))
597707
598708
709+
710+@Callable(i)
711+func stakeNFT () = {
712+ let prologActions = prolog(i)
713+ if ((size(i.payments) != 1))
714+ then throw("Exactly one payment required")
715+ else {
716+ let pmt = value(i.payments[0])
717+ if ((pmt.amount != 1))
718+ then throw("NFT token should be attached as payment")
719+ else {
720+ let assetId = value(pmt.assetId)
721+ let asset = value(assetInfo(assetId))
722+ let assetIdStr = toBase58String(assetId)
723+ let addr = toString(i.caller)
724+ let nftsKey = keyStakedNFTsByOwner(addr)
725+ let nftsStr = getString(nftsKey)
726+ let nfts = if (isDefined(nftsStr))
727+ then split_4C(value(nftsStr), "_")
728+ else nil
729+ if (containsElement(nfts, assetIdStr))
730+ then throw(("Your staked lands already contain " + assetIdStr))
731+ else if ((size(nfts) >= MAX_NFTS_STAKED_BY_USER))
732+ then throw((("Your already staked max (" + toString(MAX_NFTS_STAKED_BY_USER)) + ") NFTs"))
733+ else {
734+ let listAction = StringEntry(nftsKey, makeString_2C((nfts :+ assetIdStr), "_"))
735+ let isWL = (asset.issuer == this)
736+ if (isWL)
737+ then {
738+ let wlNftNumber = valueOrElse(getInteger(keyUserWlNftNumber(addr)), 0)
739+ if ((wlNftNumber >= MAX_WL_NFTS))
740+ then throw((("You can stake max " + toString(MAX_WL_NFTS)) + " of WavesLands NFTs"))
741+ else {
742+ let bonusVal = bonusByDescription(value(asset.description))
743+ let $t02005220130 = stakeUnstakeAcresInternal(0, addr, bonusVal)
744+ let actions = $t02005220130._1
745+ let wlgClaimedAmount = $t02005220130._2
746+ $Tuple2(((((actions :+ listAction) :+ IntegerEntry(keyUserWlNftNumber(addr), (wlNftNumber + 1))) :+ IntegerEntry(keyStakedTimeByAssetIdAndOwner(assetIdStr, addr), lastBlock.timestamp)) ++ prologActions), wlgClaimedAmount)
747+ }
748+ }
749+ else {
750+ let arkimalName = isArkimalIssued(asset)
751+ if ((arkimalName == ""))
752+ then throw("Only WavesLands and Arkimals NFT tokens are accepted")
753+ else {
754+ let arkNftNumber = valueOrElse(getInteger(keyUserArkNftNumber(addr)), 0)
755+ if ((arkNftNumber >= MAX_ARK_NFTS))
756+ then throw((("You can stake max " + toString(MAX_ARK_NFTS)) + " of Arkimals NFTs"))
757+ else {
758+ let $t02077220855 = stakeUnstakeAcresInternal(0, addr, ARK_NFT_BONUS)
759+ let actions = $t02077220855._1
760+ let wlgClaimedAmount = $t02077220855._2
761+ $Tuple2(((((actions :+ listAction) :+ IntegerEntry(keyUserArkNftNumber(addr), (arkNftNumber + 1))) :+ IntegerEntry(keyStakedTimeByAssetIdAndOwner(assetIdStr, addr), lastBlock.timestamp)) ++ prologActions), wlgClaimedAmount)
762+ }
763+ }
764+ }
765+ }
766+ }
767+ }
768+ }
769+
770+
771+
772+@Callable(i)
773+func unstakeNFT (assetIdStr) = {
774+ let prologActions = prolog(i)
775+ if ((size(i.payments) != 0))
776+ then throw("No payments required")
777+ else {
778+ let assetId = fromBase58String(assetIdStr)
779+ let addr = toString(i.caller)
780+ let asset = value(assetInfo(assetId))
781+ let timeKey = keyStakedTimeByAssetIdAndOwner(assetIdStr, addr)
782+ if (!(isDefined(getInteger(timeKey))))
783+ then throw((("NFT " + asset.name) + " is not staked by you"))
784+ else {
785+ let nftsKey = keyStakedNFTsByOwner(addr)
786+ let nfts = split_4C(valueOrElse(getString(nftsKey), ""), "_")
787+ let idx = indexOf(nfts, assetIdStr)
788+ if (!(isDefined(idx)))
789+ then throw(("Your staked NFTs don't contain " + assetIdStr))
790+ else {
791+ let listAction = if ((size(nfts) > 1))
792+ then StringEntry(nftsKey, makeString_2C(removeByIndex(nfts, value(idx)), "_"))
793+ else DeleteEntry(nftsKey)
794+ let isWL = (asset.issuer == this)
795+ if (isWL)
796+ then {
797+ let wlNftNumber = valueOrElse(getInteger(keyUserWlNftNumber(addr)), 0)
798+ let bonusVal = bonusByDescription(value(asset.description))
799+ let $t02216822247 = stakeUnstakeAcresInternal(0, addr, -(bonusVal))
800+ let actions = $t02216822247._1
801+ let wlgClaimedAmount = $t02216822247._2
802+ $Tuple2(((((actions :+ listAction) :+ IntegerEntry(keyUserWlNftNumber(addr), (wlNftNumber - 1))) :+ DeleteEntry(keyStakedTimeByAssetIdAndOwner(toBase58String(assetId), addr))) ++ prologActions), wlgClaimedAmount)
803+ }
804+ else {
805+ let arkimalName = isArkimalIssued(asset)
806+ if ((arkimalName == ""))
807+ then throw("Only WavesLands and Arkimals NFT tokens are accepted")
808+ else {
809+ let arkNftNumber = valueOrElse(getInteger(keyUserArkNftNumber(addr)), 0)
810+ let $t02276022844 = stakeUnstakeAcresInternal(0, addr, -(ARK_NFT_BONUS))
811+ let actions = $t02276022844._1
812+ let wlgClaimedAmount = $t02276022844._2
813+ $Tuple2(((((actions :+ listAction) :+ IntegerEntry(keyUserArkNftNumber(addr), (arkNftNumber - 1))) :+ DeleteEntry(keyStakedTimeByAssetIdAndOwner(toBase58String(assetId), addr))) ++ prologActions), wlgClaimedAmount)
814+ }
815+ }
816+ }
817+ }
818+ }
819+ }
820+
821+
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
66 let MULT6 = 1000000
77
88 let MULT7 = 10000000
99
1010 let MULT8 = 100000000
1111
1212 let DAY_MILLIS = 86400000
1313
1414 let USDT2ACRES_MULTIPLIER = 10
1515
1616 let ONE_PERCENT_DIVISOR = 100
1717
1818 let chain = take(drop(this.bytes, 1), 1)
19+
20+let WEEK_BLOCKS = match chain {
21+ case _ =>
22+ if ((base58'2W' == $match0))
23+ then 10080
24+ else if ((base58'2T' == $match0))
25+ then 180
26+ else throw("Unknown chain")
27+}
1928
2029 let usdtAssetId = match chain {
2130 case _ =>
2231 if ((base58'2W' == $match0))
2332 then base58'9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi'
2433 else if ((base58'2T' == $match0))
2534 then base58'6mWwf9mZBjVgkC54idpyaZLQfAosD914wT8fGf2iiY63'
2635 else throw("Unknown chain")
2736 }
2837
2938 let defaultRest2AddressStr = match chain {
3039 case _ =>
3140 if ((base58'2W' == $match0))
3241 then "3PFwYta8biEz31zpeFe5DJK8wE5trSpQVF8"
3342 else if ((base58'2T' == $match0))
3443 then "3N7UuYar6264P58FBhVWKPQAh4Yua2hgngv"
3544 else throw("Unknown chain")
3645 }
3746
3847 let arbitrageDelay = match chain {
3948 case _ =>
4049 if ((base58'2W' == $match0))
4150 then DAY_MILLIS
4251 else if ((base58'2T' == $match0))
4352 then 60000
4453 else throw("Unknown chain")
4554 }
4655
4756 let oldStakingContractStr = match chain {
4857 case _ =>
4958 if ((base58'2W' == $match0))
5059 then "3PLncXtS1U83D6cQbFD3H8rBHPLgzxSFKZ1"
5160 else if ((base58'2T' == $match0))
5261 then "3NDCyBG5q85JuaRiigUeEtainyjCQT3XpZm"
5362 else throw("Unknown chain")
5463 }
5564
5665 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
5766
5867
5968 let IdxCfgAcres2Dapp = 1
6069
6170 let IdxCfgWlgDapp = 2
6271
6372 let IdxCfgInvestFundDapp = 5
6473
6574 func keyRestCfg () = "%s__restConfig"
6675
6776
6877 func keyRest2Address () = "%s__rest2Addr"
6978
7079
7180 func readRestCfgOrFail (rest) = split_4C(getStringOrFail(rest, keyRestCfg()), SEP)
7281
7382
7483 func getContractAddressOrFail (rest2Cfg,idx) = valueOrErrorMessage(addressFromString(rest2Cfg[idx]), ("Rest cfg doesn't contain address at index " + toString(idx)))
7584
7685
7786 let rest2Contract = addressFromStringValue(valueOrElse(getString(this, keyRest2Address()), defaultRest2AddressStr))
7887
7988 let rest2Cfg = readRestCfgOrFail(rest2Contract)
8089
8190 let acres2Contract = getContractAddressOrFail(rest2Cfg, IdxCfgAcres2Dapp)
8291
8392 let wlgContract = getContractAddressOrFail(rest2Cfg, IdxCfgWlgDapp)
8493
8594 let investFundContract = getContractAddressOrFail(rest2Cfg, IdxCfgInvestFundDapp)
8695
8796 let oldAcresContractKey = "oldAcresContract"
8897
8998 func keyBlocked () = "contractsBlocked"
9099
91100
92101 func keyLastWeekTxIdByUser (addr) = ("lastWeekTxIdByUser_" + addr)
93102
94103
95104 func keyCurWeekTxIdByUser (addr) = ("curWeekTxIdByUser_" + addr)
96105
97106
98107 let acresIssuedAmountKey = "acresIssuedAmount"
99108
100109 let acresAssetIdKey = "acresAssetId"
101110
102111 let acresAssetId = valueOrErrorMessage(getBinary(acres2Contract, acresAssetIdKey), "ACRES is not issued yet")
103112
104113 func keyAcresStakedTimeByUser (addr) = ("acresStakedTimeByUser_" + addr)
105114
106115
107116 func keyStakedLandsByOwner (ownerAddr) = ("stakedLandsByOwner_" + ownerAddr)
108117
109118
110119 func keyStakedDuckByOwner (ownerAddr) = ("stakedDuckByOwner_" + ownerAddr)
111120
112121
122+func keyStakedTimeByAssetIdAndOwner (assetId,addr) = ((("st_" + assetId) + "_") + addr)
123+
124+
125+func keyStakedNFTsByOwner (ownerAddr) = ("stakedNFTsByOwner_" + ownerAddr)
126+
127+
113128 func asInt (v) = match v {
114129 case n: Int =>
115130 n
116131 case _ =>
117132 throw("fail to cast into Int")
118133 }
119134
120135
121136 func asTuple5Ints (val) = match val {
122137 case t: (Int, Int, Int, Int, Int) =>
123138 t
124139 case _ =>
125140 throw("fail to cast into (Int, Int, Int, Int, Int)")
126141 }
127142
128143
129144 func asTuple4Ints (val) = match val {
130145 case t: (Int, Int, Int, Int) =>
131146 t
132147 case _ =>
133148 throw("fail to cast into (Int, Int, Int, Int)")
134149 }
135150
136151
137152 func asTuple3Ints (val) = match val {
138153 case t: (Int, Int, Int) =>
139154 t
140155 case _ =>
141156 throw("fail to cast into (Int, Int, Int)")
142157 }
143158
144159
145160 func asTuple2Ints (val) = match val {
146161 case t: (Int, Int) =>
147162 t
148163 case _ =>
149164 throw("fail to cast into (Int, Int)")
150165 }
151166
152167
153168 func fixedPoint (val,decimals) = {
154169 let tenPow = pow(10, 0, decimals, 0, 0, DOWN)
155170 let lowPart = toString((val % tenPow))
156171 let zeroes = drop(toString(tenPow), (1 + size(lowPart)))
157172 (((toString((val / tenPow)) + ".") + zeroes) + lowPart)
158173 }
159174
160175
176+let M6_ = 1000000
177+
161178 let M8_ = 100000000
162-
163-let WEEK_BLOCKS = 10080
164179
165180 let wlgIssuedAmtKey = "wlg_issuedAmount"
166181
167182 let zbIssuedAmtKey = "zbill_issuedAmount"
168183
169184 func keyAcresStakedAmtByUser (addr) = ("acresStakedAmountByUser_" + addr)
170185
171186
172187 func keyFarmingPowerByUser (addr) = ("farmingPowerByUser_" + addr)
173188
174189
175190 let acresStakdTotalKey = "acresStakedAmountTotal"
176191
177192 let totalFarmingPowerKey = "totalFarmingPower"
178193
179194 let IdxDtx3PercConversion = 0
195+
196+let MAX_WL_NFTS = 3
197+
198+let MAX_ARK_NFTS = 1
199+
200+let ARK_NFT_BONUS = 5000
201+
202+let MAX_NFTS_STAKED_BY_USER = 4
203+
204+let keyNftTotalIssued = "nftTotalIssued"
205+
206+func keyNftNumberByAssetId (assetId) = ("nftNumberByAssetId_" + assetId)
207+
208+
209+func keyUserWlNftNumber (addr) = ("userWlNftNumber_" + addr)
210+
211+
212+func keyUserArkNftNumber (addr) = ("userArkNftNumber_" + addr)
213+
214+
215+func keyUserFullBonus (addr) = ("userFullBonus_" + addr)
216+
180217
181218 let levelAcres = [0, 10, 20, 40, 80, 150, 250, 400, 700, 1000]
182219
183220 func getLevelByAcres (acres) = {
184221 let acr = ((acres + 99999999) / M8_)
185222 func checker (acc,item) = if ((item >= acr))
186223 then acc
187224 else (acc + 1)
188225
189226 let $l = levelAcres
190227 let $s = size($l)
191228 let $acc0 = 0
192229 func $f0_1 ($a,$i) = if (($i >= $s))
193230 then $a
194231 else checker($a, $l[$i])
195232
196233 func $f0_2 ($a,$i) = if (($i >= $s))
197234 then $a
198235 else throw("List size exceeds 10")
199236
200237 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
201238 }
202239
203240
204241 func getFarmingPowerByAcres (acres) = ((acres * 20) * (getLevelByAcres(acres) + 4))
205242
206243
207-let keyNftTotalIssued = "nftTotalIssued"
208-
209-func keyNftNumberByAssetId (assetId) = ("nftNumberByAssetId_" + assetId)
244+func getFarmingPowerByAcresAndBonus (acres,bonus6) = {
245+ let notBonused = getFarmingPowerByAcres(acres)
246+ $Tuple2(fraction(notBonused, (M6_ + bonus6), M6_), notBonused)
247+ }
210248
211249
212250 func keyLastWlgTradeTimeByUser (addr) = ("lastArbTimeUser_" + addr)
213251
214252
215253 let keyLastAcresSellTime = "lastAcresSellTime"
216254
217255 let keyLastLimitLeft = "lastLimitLeft"
218256
219-let nftDescriptions = [", \"name\": \"Gold shovel\", \"description\": \"Reward for early birds\", \"rare\": \"Promo\", \"bonus\": 3, \"bonusType\": \"FarmPower\"}", ", \"name\": \"Pickaxe\", \"description\": \"Increases FarmPower\", \"rare\": \"Common\", \"bonus\": 1, \"bonusType\": \"FarmPower\"}"]
257+let nftDescriptions = [", \"collection\": \"Digging tools\", \"name\": \"Gold shovel\", \"description\": \"Reward for early birds\", \"rare\": \"Promo\", \"bonus\": 3, \"bonusType\": \"FarmPower\"}", ", \"collection\": \"Digging tools\", \"name\": \"Pickaxe\", \"description\": \"Increases FarmPower\", \"rare\": \"Common\", \"bonus\": 1, \"bonusType\": \"FarmPower\"}"]
220258
221259 let nftNames = ["SHOVEL-P3", "PICKAXE-C1"]
222260
223261 let contentKeys = ["contentShovelP3", "contentPickaxeC1"]
224262
225263 let URL = "\"url\": \"https://waveslands.com\", "
226264
227265 func prolog (i) = if (if ((i.originCaller != rest2Contract))
228266 then valueOrElse(getBoolean(keyBlocked()), false)
229267 else false)
230268 then throw("Contracts are under maintenance")
231269 else {
232270 let addr = toString(i.originCaller)
233271 let week = (height / WEEK_BLOCKS)
234272 let lastWeekTxIdByUser = getString(keyLastWeekTxIdByUser(addr))
235273 let txId = toBase58String(i.transactionId)
236274 let wtx = ((toString(week) + "_") + txId)
237275 if (isDefined(lastWeekTxIdByUser))
238276 then {
239277 let lastWeekTx = split(value(lastWeekTxIdByUser), "_")
240278 if ((lastWeekTx[0] == toString(week)))
241279 then [StringEntry(keyLastWeekTxIdByUser(addr), wtx), StringEntry(keyCurWeekTxIdByUser(addr), wtx)]
242280 else if ((lastWeekTx[0] == toString((week - 1))))
243281 then [StringEntry(keyCurWeekTxIdByUser(addr), wtx)]
244282 else {
245283 let curWeekTxIdByUser = getStringValue(keyLastWeekTxIdByUser(addr))
246284 let curWeekTx = split(curWeekTxIdByUser, "_")
247285 if ((curWeekTx[0] == toString(week)))
248286 then [StringEntry(keyCurWeekTxIdByUser(addr), wtx)]
249287 else [StringEntry(keyLastWeekTxIdByUser(addr), curWeekTxIdByUser), StringEntry(keyCurWeekTxIdByUser(addr), wtx)]
250288 }
251289 }
252290 else [StringEntry(keyLastWeekTxIdByUser(addr), wtx), StringEntry(keyCurWeekTxIdByUser(addr), wtx)]
253291 }
254292
255293
256294 func issueNFTinternal (nftIndex,addr) = if ((nftIndex >= size(contentKeys)))
257295 then throw("nftIndex out of bounds")
258296 else {
259297 let nftSerial = (valueOrElse(getInteger(keyNftTotalIssued), -1) + 1)
260298 let issue = Issue(nftNames[nftIndex], (((((("{" + URL) + "\"contentKey\": \"") + contentKeys[nftIndex]) + "\", \"number\": ") + toString(nftSerial)) + nftDescriptions[nftIndex]), 1, 0, false)
261299 let nftAssetId = calculateAssetId(issue)
262300 $Tuple2([issue, IntegerEntry(keyNftTotalIssued, nftSerial), IntegerEntry(keyNftNumberByAssetId(toBase58String(nftAssetId)), nftSerial), ScriptTransfer(addr, 1, nftAssetId)], nftAssetId)
263301 }
264302
265303
266-func stakeUnstakeAcresInternal (amt,address) = {
267- let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
268- if ((wlgResult == wlgResult))
269- then {
270- let now = lastBlock.timestamp
271- let timeKey = keyAcresStakedTimeByUser(address)
272- let amountKey = keyAcresStakedAmtByUser(address)
273- let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
274- if (if ((0 > amt))
275- then (0 > (oldAcresAmount + amt))
276- else false)
277- then throw(((("You have only " + fixedPoint(oldAcresAmount, 8)) + " ACRES staked, tried to unstake ") + fixedPoint(-(amt), 8)))
278- else {
279- let newAcresAmount = (oldAcresAmount + amt)
280- let oldTotal = valueOrElse(getInteger(acresStakdTotalKey), 0)
281- let userFpKey = keyFarmingPowerByUser(address)
282- let oldFp = valueOrElse(getInteger(userFpKey), 0)
283- let newFp = getFarmingPowerByAcres(newAcresAmount)
284- let oldTotalFp = valueOrElse(getInteger(totalFarmingPowerKey), 0)
285- $Tuple2([IntegerEntry(timeKey, lastBlock.timestamp), IntegerEntry(amountKey, newAcresAmount), IntegerEntry(acresStakdTotalKey, (oldTotal + amt)), IntegerEntry(userFpKey, newFp), IntegerEntry(totalFarmingPowerKey, ((oldTotalFp - oldFp) + newFp))], wlgResult)
286- }
287- }
288- else throw("Strict value is not equal to itself.")
289- }
304+func stakeUnstakeAcresInternal (amt,address,bonusDelta) = if (if ((amt == 0))
305+ then (bonusDelta == 0)
306+ else false)
307+ then throw("Nothing to do")
308+ else {
309+ let wlgResult = invoke(wlgContract, "onStakeUnstakeLand", [address], nil)
310+ if ((wlgResult == wlgResult))
311+ then {
312+ let now = lastBlock.timestamp
313+ let timeKey = keyAcresStakedTimeByUser(address)
314+ let amountKey = keyAcresStakedAmtByUser(address)
315+ let oldAcresAmount = valueOrElse(getInteger(amountKey), 0)
316+ if (if ((0 > amt))
317+ then (0 > (oldAcresAmount + amt))
318+ else false)
319+ then throw(((("You have only " + fixedPoint(oldAcresAmount, 8)) + " ACRES staked, tried to unstake ") + fixedPoint(-(amt), 8)))
320+ else {
321+ let newAcresAmount = (oldAcresAmount + amt)
322+ let oldTotal = valueOrElse(getInteger(acresStakdTotalKey), 0)
323+ let userFpKey = keyFarmingPowerByUser(address)
324+ let oldFp = valueOrElse(getInteger(userFpKey), 0)
325+ let bonusKey = keyUserFullBonus(address)
326+ let oldBonus = valueOrElse(getInteger(acres2Contract, bonusKey), 0)
327+ if (if ((0 > bonusDelta))
328+ then (0 > (oldBonus + bonusDelta))
329+ else false)
330+ then throw((((("You have only " + fixedPoint(oldBonus, 4)) + "% bonus, and tried to unstake ") + fixedPoint(-(bonusDelta), 4)) + "%"))
331+ else {
332+ let $t054285527 = getFarmingPowerByAcresAndBonus(newAcresAmount, (oldBonus + bonusDelta))
333+ let newBonusedFp = $t054285527._1
334+ let ignored = $t054285527._2
335+ let oldTotalFp = valueOrElse(getInteger(totalFarmingPowerKey), 0)
336+ let acresActions = if ((amt == 0))
337+ then nil
338+ else [IntegerEntry(amountKey, newAcresAmount), IntegerEntry(acresStakdTotalKey, (oldTotal + amt))]
339+ $Tuple2(((((acresActions :+ IntegerEntry(timeKey, lastBlock.timestamp)) :+ IntegerEntry(userFpKey, newBonusedFp)) :+ IntegerEntry(totalFarmingPowerKey, ((oldTotalFp + newBonusedFp) - oldFp))) :+ IntegerEntry(bonusKey, (oldBonus + bonusDelta))), wlgResult)
340+ }
341+ }
342+ }
343+ else throw("Strict value is not equal to itself.")
344+ }
290345
291346
292347 func getWlgPrice (usdtBalanceCorrection) = {
293348 let issuedAmount = valueOrErrorMessage(getInteger(wlgContract, wlgIssuedAmtKey), "WLGOLD is not issued yet")
294349 let wlgUsd = assetBalance(wlgContract, usdtAssetId)
295350 let acres2Usd = (assetBalance(acres2Contract, usdtAssetId) - usdtBalanceCorrection)
296351 let investFundTotal = (assetBalance(investFundContract, usdtAssetId) + valueOrElse(getInteger(investFundContract, zbIssuedAmtKey), 0))
297352 let totalFundsUsd = ((acres2Usd + wlgUsd) + investFundTotal)
298353 fraction(totalFundsUsd, MULT8, issuedAmount)
299354 }
300355
301356
302357 func getSwapLimitAcres () = {
303358 let wlgUsd = assetBalance(wlgContract, usdtAssetId)
304359 let acres2Usd = assetBalance(this, usdtAssetId)
305360 let investFundTotal = (assetBalance(investFundContract, usdtAssetId) + valueOrElse(getInteger(investFundContract, zbIssuedAmtKey), 0))
306361 let defaultLimit = (((acres2Usd + wlgUsd) + investFundTotal) / ONE_PERCENT_DIVISOR)
307362 let lastLimitLeft = valueOrElse(getInteger(keyLastLimitLeft), defaultLimit)
308363 let lastTime = valueOrElse(getInteger(keyLastAcresSellTime), 0)
309364 let now = lastBlock.timestamp
310365 let currentLimit = (lastLimitLeft + fraction(defaultLimit, (now - lastTime), DAY_MILLIS))
311366 let limitLeftUsdt = min([currentLimit, defaultLimit])
312367 $Tuple2(IntegerEntry(keyLastAcresSellTime, now), limitLeftUsdt)
313368 }
369+
370+
371+let arkOracle = addressFromStringValue("3PJgZ6AK1WVCpdCmEZpesHmaKvrQDdXG5og")
372+
373+let incubator = valueOrElse(getString(arkOracle, "static_incubatorAddress"), "")
374+
375+let breeder = valueOrElse(getString(arkOracle, "static_breederAddress"), "")
376+
377+let turtleIncubator = valueOrElse(getString(arkOracle, "static_turtleIncubatorAddress"), "")
378+
379+let turtleBreeder = valueOrElse(getString(arkOracle, "static_turtleBreederAddress"), "")
380+
381+let canineIncubator = valueOrElse(getString(arkOracle, "static_canineIncubatorAddress"), "")
382+
383+let canineBreeder = valueOrElse(getString(arkOracle, "static_canineBreederAddress"), "")
384+
385+let felineIncubator = valueOrElse(getString(arkOracle, "static_felineIncubatorAddress"), "")
386+
387+let felineBreeder = valueOrElse(getString(arkOracle, "static_felineBreederAddress"), "")
388+
389+let mutantBreeder = valueOrElse(getString(arkOracle, "static_mutantIncubatorAddress"), "")
390+
391+func isArkimalIssued (nfo) = {
392+ let issuer = toString(nfo.issuer)
393+ if (if (if (if (if (if (if (if ((issuer == incubator))
394+ then true
395+ else (issuer == breeder))
396+ then true
397+ else (issuer == turtleIncubator))
398+ then true
399+ else (issuer == turtleBreeder))
400+ then true
401+ else (issuer == canineIncubator))
402+ then true
403+ else (issuer == canineBreeder))
404+ then true
405+ else (issuer == felineIncubator))
406+ then true
407+ else (issuer == felineBreeder))
408+ then nfo.name
409+ else if ((issuer == mutantBreeder))
410+ then nfo.description
411+ else ""
412+ }
413+
414+
415+func bonusByDescription (descr) = if (!(contains(descr, "\"bonusType\": \"FarmPower\"")))
416+ then throw("NFT is not supported yet")
417+ else {
418+ let bonusStr = split_4C(split_4C(descr, "\"bonus\":")[1], ",")[0]
419+ (parseIntValue(drop(bonusStr, (valueOrElse(lastIndexOf(bonusStr, " "), -1) + 1))) * 10000)
420+ }
314421
315422
316423 @Callable(i)
317424 func saveLastTx () = if (!(containsElement([wlgContract], i.caller)))
318425 then throw("Access denied")
319426 else $Tuple2(prolog(i), 42)
320427
321428
322429
323430 @Callable(i)
324431 func constructorV1 (rest2Addr,oldAcrContract) = if ((i.caller != this))
325432 then throw("Permission denied")
326433 else {
327434 let oldAcrContAddr = addressFromStringValue(oldAcrContract)
328435 [IntegerEntry(acresIssuedAmountKey, getIntegerValue(oldAcrContAddr, acresIssuedAmountKey)), BinaryEntry(acresAssetIdKey, getBinaryValue(oldAcrContAddr, acresAssetIdKey)), StringEntry(keyRest2Address(), rest2Addr), StringEntry(oldAcresContractKey, oldAcrContract)]
329436 }
330437
331438
332439
333440 @Callable(i)
334441 func setBlocked (isBlocked) = if ((i.caller != this))
335442 then throw("permission denied")
336443 else [BooleanEntry(keyBlocked(), isBlocked)]
337444
338445
339446
340447 @Callable(i)
341448 func unstakeAcres (amount) = {
342449 let prologActions = prolog(i)
343450 if ((0 >= amount))
344451 then throw("Amount should be positive")
345452 else {
346453 let address = toString(i.caller)
347454 if ((size(i.payments) != 0))
348455 then throw("No payments required")
349456 else {
350457 let arbReleaseTime = (valueOrElse(getInteger(wlgContract, keyLastWlgTradeTimeByUser(address)), 0) + arbitrageDelay)
351458 if ((arbReleaseTime > lastBlock.timestamp))
352459 then throw(("You traded some WLGOLD, cannot unstake until " + toString(arbReleaseTime)))
353460 else {
354- let $t074207497 = stakeUnstakeAcresInternal(-(amount), address)
355- let actions = $t074207497._1
356- let wlgClaimedAmount = $t074207497._2
461+ let $t01102411104 = stakeUnstakeAcresInternal(-(amount), address, 0)
462+ let actions = $t01102411104._1
463+ let wlgClaimedAmount = $t01102411104._2
357464 $Tuple2(((actions :+ ScriptTransfer(i.caller, amount, acresAssetId)) ++ prologActions), wlgClaimedAmount)
358465 }
359466 }
360467 }
361468 }
362469
363470
364471
365472 @Callable(i)
366473 func stakeAcres () = {
367474 let prologActions = prolog(i)
368475 let address = toString(i.caller)
369476 if ((size(i.payments) != 1))
370477 then throw("exactly 1 payment must be attached")
371478 else {
372479 let pmt = i.payments[0]
373480 let amt = pmt.amount
374481 if (if (!(isDefined(pmt.assetId)))
375482 then true
376483 else (value(pmt.assetId) != acresAssetId))
377484 then throw("ACRES payments only!")
378485 else {
379- let $t079488021 = stakeUnstakeAcresInternal(amt, address)
380- let actions = $t079488021._1
381- let wlgClaimedAmount = $t079488021._2
486+ let $t01155511631 = stakeUnstakeAcresInternal(amt, address, 0)
487+ let actions = $t01155511631._1
488+ let wlgClaimedAmount = $t01155511631._2
382489 $Tuple2((actions ++ prologActions), wlgClaimedAmount)
383490 }
384491 }
385492 }
386493
387494
388495
389496 @Callable(i)
390497 func buyAcres () = {
391498 let prologActions = prolog(i)
392499 if ((size(i.payments) != 1))
393500 then throw("exactly 1 payment must be attached")
394501 else {
395502 let pmt = i.payments[0]
396503 let usdtAmount = pmt.amount
397504 if (if (!(isDefined(pmt.assetId)))
398505 then true
399506 else (value(pmt.assetId) != usdtAssetId))
400507 then throw("USDT payments only!")
401508 else if ((MULT6 > usdtAmount))
402509 then throw((("Min payment should be " + fixedPoint(MULT6, 6)) + " USDT"))
403510 else {
404511 let acresAmount = (usdtAmount * USDT2ACRES_MULTIPLIER)
405512 let wlgAmount = fraction(usdtAmount, MULT8, getWlgPrice(usdtAmount))
406513 let oldAcresAddress = addressFromStringValue(getStringValue(oldAcresContractKey))
407514 let req = invoke(oldAcresAddress, "requestAcresCallback", [acresAmount], nil)
408515 if ((req == req))
409516 then {
410517 let wlgRemain = asInt(invoke(wlgContract, "burnWlgold", [wlgAmount], nil))
411518 $Tuple2(([ScriptTransfer(i.caller, acresAmount, acresAssetId)] ++ prologActions), wlgRemain)
412519 }
413520 else throw("Strict value is not equal to itself.")
414521 }
415522 }
416523 }
417524
418525
419526
420527 @Callable(i)
421528 func buyAcresREADONLY (usdtAmount) = {
422529 let acresAmount = (usdtAmount * USDT2ACRES_MULTIPLIER)
423530 let wlgToBurn = fraction(usdtAmount, MULT8, getWlgPrice(usdtAmount))
424531 $Tuple2(nil, [acresAmount, MULT6, acresAmount, wlgToBurn])
425532 }
426533
427534
428535
429536 @Callable(i)
430537 func sellAcres () = {
431538 let prologActions = prolog(i)
432539 if ((size(i.payments) != 1))
433540 then throw("exactly 1 payment must be attached")
434541 else {
435542 let pmt = i.payments[0]
436543 let acresAmount = pmt.amount
437544 if (if (!(isDefined(pmt.assetId)))
438545 then true
439546 else (value(pmt.assetId) != acresAssetId))
440547 then throw("ACRES payments only!")
441548 else if ((MULT7 > acresAmount))
442549 then throw((("Min payment should be " + fixedPoint(MULT7, 8)) + " ACRES"))
443550 else {
444551 let addr = toString(i.caller)
445- let $t098789926 = getSwapLimitAcres()
446- let limitAction = $t098789926._1
447- let maxUsdt = $t098789926._2
552+ let $t01348813536 = getSwapLimitAcres()
553+ let limitAction = $t01348813536._1
554+ let maxUsdt = $t01348813536._2
448555 let maxAcres = (maxUsdt * USDT2ACRES_MULTIPLIER)
449556 if ((acresAmount > maxAcres))
450557 then throw((("You can sell max " + fixedPoint(maxAcres, 8)) + " ACRES"))
451558 else {
452559 let usdtAmount = ((acresAmount / USDT2ACRES_MULTIPLIER) / 2)
453560 $Tuple2(([limitAction, IntegerEntry(keyLastLimitLeft, (maxUsdt - usdtAmount)), ScriptTransfer(i.caller, usdtAmount, usdtAssetId)] ++ prologActions), usdtAmount)
454561 }
455562 }
456563 }
457564 }
458565
459566
460567
461568 @Callable(i)
462569 func sellAcresREADONLY (address,acresAmount) = {
463- let $t01042210470 = getSwapLimitAcres()
464- let limitAction = $t01042210470._1
465- let maxUsdt = $t01042210470._2
570+ let $t01403214080 = getSwapLimitAcres()
571+ let limitAction = $t01403214080._1
572+ let maxUsdt = $t01403214080._2
466573 let usdtAmount = ((acresAmount / USDT2ACRES_MULTIPLIER) / 2)
467574 $Tuple2(nil, [usdtAmount, MULT7, (maxUsdt * USDT2ACRES_MULTIPLIER), 0])
468575 }
469576
470577
471578
472579 @Callable(i)
473580 func convertOldStakes () = if ((i.caller != this))
474581 then throw("Temporarily disabled")
475582 else {
476583 let address = toString(i.caller)
477584 if ((size(i.payments) != 0))
478585 then throw("No payments required")
479586 else {
480587 let oldAcresAddress = addressFromStringValue(getStringValue(oldAcresContractKey))
481588 let amount = valueOrElse(getInteger(oldAcresAddress, keyAcresStakedAmtByUser(address)), 0)
482589 let gotAcres0 = if ((amount > 0))
483590 then asTuple2Ints(invoke(oldAcresAddress, "unstakeAcresCallback", [amount, address], nil))
484591 else $Tuple2(0, 0)
485592 let oldStakingAddress = addressFromStringValue(oldStakingContractStr)
486593 let landsStr = getString(oldStakingAddress, keyStakedLandsByOwner(address))
487594 let landsResult = if (isDefined(landsStr))
488595 then {
489596 let lands = split_51C(value(landsStr), "_")
490597 func oneLand (acc,landAssetId) = if ((landAssetId == ""))
491598 then throw("landAssetId is required")
492599 else {
493600 let r = asTuple5Ints(invoke(oldStakingAddress, "unstakeLandCallback", [landAssetId, address], nil))
494601 $Tuple4((acc._1 + r._1), (acc._2 + r._2), (acc._3 + r._3), (acc._4 + r._4))
495602 }
496603
497604 let rr = {
498605 let $l = lands
499606 let $s = size($l)
500607 let $acc0 = $Tuple4(0, 0, 0, 0)
501608 func $f0_1 ($a,$i) = if (($i >= $s))
502609 then $a
503610 else oneLand($a, $l[$i])
504611
505612 func $f0_2 ($a,$i) = if (($i >= $s))
506613 then $a
507614 else throw("List size exceeds 100")
508615
509616 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100)
510617 }
511618 let finalize = invoke(oldStakingAddress, "unstakeLandsFinalizeCallback", [address], nil)
512619 if ((finalize == finalize))
513620 then {
514621 let req = invoke(oldAcresAddress, "requestAcresCallback", [(((rr._1 + rr._2) + rr._3) + rr._4)], nil)
515622 if ((req == req))
516623 then {
517- let $t01234212422 = issueNFTinternal(IdxDtx3PercConversion, i.caller)
518- let nftActions = $t01234212422._1
519- let nftAssetId = $t01234212422._2
624+ let $t01595216032 = issueNFTinternal(IdxDtx3PercConversion, i.caller)
625+ let nftActions = $t01595216032._1
626+ let nftAssetId = $t01595216032._2
520627 $Tuple5(rr._1, rr._2, rr._3, rr._4, nftActions)
521628 }
522629 else throw("Strict value is not equal to itself.")
523630 }
524631 else throw("Strict value is not equal to itself.")
525632 }
526633 else $Tuple5(0, 0, 0, 0, nil)
527634 let duckAssetId = valueOrElse(getString(oldStakingAddress, keyStakedDuckByOwner(address)), "")
528635 let duckResult = if ((duckAssetId != ""))
529636 then asTuple3Ints(invoke(oldStakingAddress, "unstakeDuckCallback", [duckAssetId, address], nil))
530637 else $Tuple3(0, 0, 0)
531- let x = stakeUnstakeAcresInternal((((((((gotAcres0._1 + landsResult._1) + landsResult._2) + landsResult._3) + landsResult._4) + duckResult._1) + duckResult._2) + duckResult._3), address)
638+ let x = stakeUnstakeAcresInternal((((((((gotAcres0._1 + landsResult._1) + landsResult._2) + landsResult._3) + landsResult._4) + duckResult._1) + duckResult._2) + duckResult._3), address, 0)
532639 $Tuple2((landsResult._5 ++ x._1), x._2)
533640 }
534641 }
535642
536643
537644
538645 @Callable(i)
539646 func unstakeLandsREADONLY (address) = {
540647 let oldStakingAddress = addressFromStringValue(oldStakingContractStr)
541648 let landsStr = getString(oldStakingAddress, keyStakedLandsByOwner(address))
542649 let landsResult = if (isDefined(landsStr))
543650 then {
544651 let lands = split_51C(value(landsStr), "_")
545652 func oneLand (acc,landAssetId) = if ((landAssetId == ""))
546653 then throw("landAssetId is required")
547654 else {
548655 let r = asTuple4Ints(invoke(oldStakingAddress, "unstakeLandREADONLY", [landAssetId, address], nil))
549656 $Tuple4((acc._1 + r._1), (acc._2 + r._2), (acc._3 + r._3), (acc._4 + r._4))
550657 }
551658
552659 let $l = lands
553660 let $s = size($l)
554661 let $acc0 = $Tuple4(0, 0, 0, 0)
555662 func $f0_1 ($a,$i) = if (($i >= $s))
556663 then $a
557664 else oneLand($a, $l[$i])
558665
559666 func $f0_2 ($a,$i) = if (($i >= $s))
560667 then $a
561668 else throw("List size exceeds 100")
562669
563670 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100)
564671 }
565672 else $Tuple4(0, 0, 0, 0)
566673 $Tuple2(nil, landsResult)
567674 }
568675
569676
570677
571678 @Callable(i)
572679 func stakeAcresCallback (addr) = if ((i.caller != addressFromStringValue(oldStakingContractStr)))
573680 then throw("Permission denied")
574- else stakeUnstakeAcresInternal(i.payments[0].amount, addr)
681+ else stakeUnstakeAcresInternal(i.payments[0].amount, addr, 0)
575682
576683
577684
578685 @Callable(i)
579686 func simulateStakeAcresREADONLY (address,addedAmount) = {
580687 let amountKey = keyAcresStakedAmtByUser(address)
581688 let newAcresAmount = (valueOrElse(getInteger(amountKey), 0) + addedAmount)
582689 let oldTotal = valueOrElse(getInteger(acresStakdTotalKey), 0)
583690 let userFpKey = keyFarmingPowerByUser(address)
584691 let oldFp = valueOrElse(getInteger(userFpKey), 0)
585- let newFp = getFarmingPowerByAcres(newAcresAmount)
692+ let userBonus = valueOrElse(getInteger(acres2Contract, keyUserFullBonus(address)), 0)
693+ let $t01819718284 = getFarmingPowerByAcresAndBonus(newAcresAmount, userBonus)
694+ let newBonusedFp = $t01819718284._1
695+ let ignored = $t01819718284._2
586696 let oldTotalFp = valueOrElse(getInteger(totalFarmingPowerKey), 0)
587- let newTotalFp = ((oldTotalFp - oldFp) + newFp)
588- $Tuple2(nil, [oldFp, newFp, oldTotalFp, newTotalFp])
697+ let newTotalFp = ((oldTotalFp + newBonusedFp) - oldFp)
698+ $Tuple2(nil, [oldFp, newBonusedFp, oldTotalFp, newTotalFp])
589699 }
590700
591701
592702
593703 @Callable(i)
594704 func issueNFT (forAddress,nftIndex) = if ((i.caller != wlgContract))
595705 then throw("Permission denied")
596706 else issueNFTinternal(nftIndex, addressFromStringValue(forAddress))
597707
598708
709+
710+@Callable(i)
711+func stakeNFT () = {
712+ let prologActions = prolog(i)
713+ if ((size(i.payments) != 1))
714+ then throw("Exactly one payment required")
715+ else {
716+ let pmt = value(i.payments[0])
717+ if ((pmt.amount != 1))
718+ then throw("NFT token should be attached as payment")
719+ else {
720+ let assetId = value(pmt.assetId)
721+ let asset = value(assetInfo(assetId))
722+ let assetIdStr = toBase58String(assetId)
723+ let addr = toString(i.caller)
724+ let nftsKey = keyStakedNFTsByOwner(addr)
725+ let nftsStr = getString(nftsKey)
726+ let nfts = if (isDefined(nftsStr))
727+ then split_4C(value(nftsStr), "_")
728+ else nil
729+ if (containsElement(nfts, assetIdStr))
730+ then throw(("Your staked lands already contain " + assetIdStr))
731+ else if ((size(nfts) >= MAX_NFTS_STAKED_BY_USER))
732+ then throw((("Your already staked max (" + toString(MAX_NFTS_STAKED_BY_USER)) + ") NFTs"))
733+ else {
734+ let listAction = StringEntry(nftsKey, makeString_2C((nfts :+ assetIdStr), "_"))
735+ let isWL = (asset.issuer == this)
736+ if (isWL)
737+ then {
738+ let wlNftNumber = valueOrElse(getInteger(keyUserWlNftNumber(addr)), 0)
739+ if ((wlNftNumber >= MAX_WL_NFTS))
740+ then throw((("You can stake max " + toString(MAX_WL_NFTS)) + " of WavesLands NFTs"))
741+ else {
742+ let bonusVal = bonusByDescription(value(asset.description))
743+ let $t02005220130 = stakeUnstakeAcresInternal(0, addr, bonusVal)
744+ let actions = $t02005220130._1
745+ let wlgClaimedAmount = $t02005220130._2
746+ $Tuple2(((((actions :+ listAction) :+ IntegerEntry(keyUserWlNftNumber(addr), (wlNftNumber + 1))) :+ IntegerEntry(keyStakedTimeByAssetIdAndOwner(assetIdStr, addr), lastBlock.timestamp)) ++ prologActions), wlgClaimedAmount)
747+ }
748+ }
749+ else {
750+ let arkimalName = isArkimalIssued(asset)
751+ if ((arkimalName == ""))
752+ then throw("Only WavesLands and Arkimals NFT tokens are accepted")
753+ else {
754+ let arkNftNumber = valueOrElse(getInteger(keyUserArkNftNumber(addr)), 0)
755+ if ((arkNftNumber >= MAX_ARK_NFTS))
756+ then throw((("You can stake max " + toString(MAX_ARK_NFTS)) + " of Arkimals NFTs"))
757+ else {
758+ let $t02077220855 = stakeUnstakeAcresInternal(0, addr, ARK_NFT_BONUS)
759+ let actions = $t02077220855._1
760+ let wlgClaimedAmount = $t02077220855._2
761+ $Tuple2(((((actions :+ listAction) :+ IntegerEntry(keyUserArkNftNumber(addr), (arkNftNumber + 1))) :+ IntegerEntry(keyStakedTimeByAssetIdAndOwner(assetIdStr, addr), lastBlock.timestamp)) ++ prologActions), wlgClaimedAmount)
762+ }
763+ }
764+ }
765+ }
766+ }
767+ }
768+ }
769+
770+
771+
772+@Callable(i)
773+func unstakeNFT (assetIdStr) = {
774+ let prologActions = prolog(i)
775+ if ((size(i.payments) != 0))
776+ then throw("No payments required")
777+ else {
778+ let assetId = fromBase58String(assetIdStr)
779+ let addr = toString(i.caller)
780+ let asset = value(assetInfo(assetId))
781+ let timeKey = keyStakedTimeByAssetIdAndOwner(assetIdStr, addr)
782+ if (!(isDefined(getInteger(timeKey))))
783+ then throw((("NFT " + asset.name) + " is not staked by you"))
784+ else {
785+ let nftsKey = keyStakedNFTsByOwner(addr)
786+ let nfts = split_4C(valueOrElse(getString(nftsKey), ""), "_")
787+ let idx = indexOf(nfts, assetIdStr)
788+ if (!(isDefined(idx)))
789+ then throw(("Your staked NFTs don't contain " + assetIdStr))
790+ else {
791+ let listAction = if ((size(nfts) > 1))
792+ then StringEntry(nftsKey, makeString_2C(removeByIndex(nfts, value(idx)), "_"))
793+ else DeleteEntry(nftsKey)
794+ let isWL = (asset.issuer == this)
795+ if (isWL)
796+ then {
797+ let wlNftNumber = valueOrElse(getInteger(keyUserWlNftNumber(addr)), 0)
798+ let bonusVal = bonusByDescription(value(asset.description))
799+ let $t02216822247 = stakeUnstakeAcresInternal(0, addr, -(bonusVal))
800+ let actions = $t02216822247._1
801+ let wlgClaimedAmount = $t02216822247._2
802+ $Tuple2(((((actions :+ listAction) :+ IntegerEntry(keyUserWlNftNumber(addr), (wlNftNumber - 1))) :+ DeleteEntry(keyStakedTimeByAssetIdAndOwner(toBase58String(assetId), addr))) ++ prologActions), wlgClaimedAmount)
803+ }
804+ else {
805+ let arkimalName = isArkimalIssued(asset)
806+ if ((arkimalName == ""))
807+ then throw("Only WavesLands and Arkimals NFT tokens are accepted")
808+ else {
809+ let arkNftNumber = valueOrElse(getInteger(keyUserArkNftNumber(addr)), 0)
810+ let $t02276022844 = stakeUnstakeAcresInternal(0, addr, -(ARK_NFT_BONUS))
811+ let actions = $t02276022844._1
812+ let wlgClaimedAmount = $t02276022844._2
813+ $Tuple2(((((actions :+ listAction) :+ IntegerEntry(keyUserArkNftNumber(addr), (arkNftNumber - 1))) :+ DeleteEntry(keyStakedTimeByAssetIdAndOwner(toBase58String(assetId), addr))) ++ prologActions), wlgClaimedAmount)
814+ }
815+ }
816+ }
817+ }
818+ }
819+ }
820+
821+

github/deemru/w8io/026f985 
581.69 ms