tx · 68THTkLDDbGHpz1pgyhY8mirMCL2AvA7EFDeW1RPsUhb

3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy:  -0.02900000 Waves

2022.07.26 10:59 [2156499] smart account 3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy > SELF 0.00000000 Waves

{ "type": 13, "id": "68THTkLDDbGHpz1pgyhY8mirMCL2AvA7EFDeW1RPsUhb", "fee": 2900000, "feeAssetId": null, "timestamp": 1658822393482, "version": 1, "sender": "3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy", "senderPublicKey": "9W33iCCNfmFxUbiC6XZcH5x7f6xfwC7Jb3BoExT5q2PV", "proofs": [ "3GAGyXUhcx1xeXbL1k9Xs8JQsyTMSNAwniN9y3WG2rw9cnQKR7YYeoH6UCbN7imHzP7QQuhAwjgLnNKpx8wigKXG" ], "script": "base64:BgJACAISCAoGCAgBAQEIEgUKAwEIAhIDCgEBEgMKAQESBAoCCAgSBAoCCAgSAwoBCBIDCgEIEgQKAggBEgMKAQgSAGoAA1NFUAICX18ABlNDQUxFOAAIAAVNVUxUOACAwtcvAA5QT09MV0VJR0hUTVVMVAUFTVVMVDgBBHN0cmYCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEDaW96AgdhZGRyZXNzA2tleQkBC3ZhbHVlT3JFbHNlAgkAmggCBQdhZGRyZXNzBQNrZXkAAAEDaW9kAwdhZGRyZXNzA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCaCAIFB2FkZHJlc3MFA2tleQUKZGVmYXVsdFZhbAEDaW9mAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFB2FkZHJlc3MFA2tleQkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUDa2V5Ag8gaXMgbm90IGRlZmluZWQBA2FicwEDdmFsAwkAZgIAAAUDdmFsCQEBLQEFA3ZhbAUDdmFsAQNhYWwBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACCUxpc3RbQW55XQQKdmFsQW55THlzdAUHJG1hdGNoMAUKdmFsQW55THlzdAkAAgECG2ZhaWwgdG8gY2FzdCBpbnRvIExpc3RbQW55XQECYWkBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACA0ludAQGdmFsSW50BQckbWF0Y2gwBQZ2YWxJbnQJAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBG2tleVJlZmVycmFsc0NvbnRyYWN0QWRkcmVzcwAJALkJAgkAzAgCAgQlcyVzCQDMCAICBmNvbmZpZwkAzAgCAhhyZWZlcnJhbHNDb250cmFjdEFkZHJlc3MFA25pbAUDU0VQAB5yZWZlcnJhbHNDb250cmFjdEFkZHJlc3NPckZhaWwJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQRzdHJmAgUEdGhpcwkBG2tleVJlZmVycmFsc0NvbnRyYWN0QWRkcmVzcwAAFmtleVJlZmVycmFsUHJvZ3JhbU5hbWUJALkJAgkAzAgCAgQlcyVzCQDMCAICCHJlZmVycmFsCQDMCAICC3Byb2dyYW1OYW1lBQNuaWwFA1NFUAAacmVmZXJyYWxQcm9ncmFtTmFtZURlZmF1bHQCBnd4bG9jawATcmVmZXJyYWxQcm9ncmFtTmFtZQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBRZrZXlSZWZlcnJhbFByb2dyYW1OYW1lBRpyZWZlcnJhbFByb2dyYW1OYW1lRGVmYXVsdAERa2V5RmFjdG9yeUFkZHJlc3MAAhwlcyVzX19jb25maWdfX2ZhY3RvcnlBZGRyZXNzABhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHAAAQAZSWR4RmFjdG9yeUNmZ0Jvb3N0aW5nRGFwcAACABRJZHhGYWN0b3J5Q2ZnSWRvRGFwcAADABVJZHhGYWN0b3J5Q2ZnVGVhbURhcHAABAAZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcAAFABVJZHhGYWN0b3J5Q2ZnUmVzdERhcHAABgAZSWR4RmFjdG9yeUNmZ1NsaXBwYWdlRGFwcAAHABRJZHhGYWN0b3J5Q2ZnRGFvRGFwcAAIABpJZHhGYWN0b3J5Q2ZnTWFya2V0aW5nRGFwcAAJABpJZHhGYWN0b3J5Q2ZnR3d4UmV3YXJkRGFwcAAKABZJZHhGYWN0b3J5Q2ZnQmlyZHNEYXBwAAsBDWtleUZhY3RvcnlDZmcAAhElc19fZmFjdG9yeUNvbmZpZwEaa2V5RmFjdG9yeUxwMkFzc2V0c01hcHBpbmcBCmxwQXNzZXRTdHIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUKbHBBc3NldFN0cgkAzAgCAh5tYXBwaW5nc19fbHBBc3NldDJQb29sQ29udHJhY3QFA25pbAUDU0VQARBrZXlGYWN0b3J5THBMaXN0AAIQJXNfX2xwVG9rZW5zTGlzdAEma2V5RmFjdG9yeUxwQXNzZXRUb1Bvb2xDb250cmFjdEFkZHJlc3MBCmxwQXNzZXRTdHIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUKbHBBc3NldFN0cgkAzAgCAh5tYXBwaW5nc19fbHBBc3NldDJQb29sQ29udHJhY3QFA25pbAUDU0VQARRrZXlGYWN0b3J5UG9vbFdlaWdodAEPY29udHJhY3RBZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgpwb29sV2VpZ2h0CQDMCAIFD2NvbnRyYWN0QWRkcmVzcwUDbmlsBQNTRVABG2tleUZhY3RvcnlQb29sV2VpZ2h0SGlzdG9yeQILcG9vbEFkZHJlc3MDbnVtCQCsAgIJAKwCAgkArAICAhIlcyVzX19wb29sV2VpZ2h0X18FC3Bvb2xBZGRyZXNzAgJfXwkApAMBBQNudW0BGHJlYWRGYWN0b3J5QWRkcmVzc09yRmFpbAAJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQRzdHJmAgUEdGhpcwkBEWtleUZhY3RvcnlBZGRyZXNzAAEKcmVhZExwTGlzdAAJALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCCQEYcmVhZEZhY3RvcnlBZGRyZXNzT3JGYWlsAAkBEGtleUZhY3RvcnlMcExpc3QAAgAFA1NFUAEUcmVhZEZhY3RvcnlDZmdPckZhaWwBB2ZhY3RvcnkJALUJAgkBBHN0cmYCBQdmYWN0b3J5CQENa2V5RmFjdG9yeUNmZwAFA1NFUAEYZ2V0Qm9vc3RpbmdBZGRyZXNzT3JGYWlsAQpmYWN0b3J5Q2ZnCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFCmZhY3RvcnlDZmcFGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHABGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRlJZHhGYWN0b3J5Q2ZnRW1pc3Npb25EYXBwARdnZXRTdGFraW5nQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHABGWdldEd3eFJld2FyZEFkZHJlc3NPckZhaWwBCmZhY3RvcnlDZmcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUKZmFjdG9yeUNmZwUaSWR4RmFjdG9yeUNmZ0d3eFJld2FyZERhcHABE2tleU1hbmFnZXJQdWJsaWNLZXkAAhQlc19fbWFuYWdlclB1YmxpY0tleQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAhslc19fcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAACGyVzJXNfX3JhdGVQZXJCbG9ja19fY3VycmVudAEha2V5RW1pc3Npb25SYXRlUGVyQmxvY2tNYXhDdXJyZW50AAIeJXMlc19fcmF0ZVBlckJsb2NrTWF4X19jdXJyZW50ARVrZXlFbWlzc2lvblN0YXJ0QmxvY2sAAholcyVzX19lbWlzc2lvbl9fc3RhcnRCbG9jawEba2V5RW1pc3Npb25EdXJhdGlvbkluQmxvY2tzAAIYJXMlc19fZW1pc3Npb25fX2R1cmF0aW9uARNrZXlFbWlzc2lvbkVuZEJsb2NrAAIYJXMlc19fZW1pc3Npb25fX2VuZEJsb2NrAQ1rZXlOZXh0UGVyaW9kAAIOJXNfX25leHRQZXJpb2QBH2tleUd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQAAiglcyVzX19nd3hSZXdhcmRFbWlzc2lvblBhcnRfX3N0YXJ0SGVpZ2h0AA1JZHhDZmdBc3NldElkAAEAE0lkeENmZ01pbkxvY2tBbW91bnQAAgAVSWR4Q2ZnTWluTG9ja0R1cmF0aW9uAAMAFUlkeENmZ01heExvY2tEdXJhdGlvbgAEABJJZHhDZmdNYXRoQ29udHJhY3QABQEJa2V5Q29uZmlnAAIKJXNfX2NvbmZpZwEVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAkAtQkCCQEEc3RyZgIFBHRoaXMJAQlrZXlDb25maWcABQNTRVABDWZvcm1hdENvbmZpZ1MFB2Fzc2V0SWQNbWluTG9ja0Ftb3VudA9taW5Mb2NrRHVyYXRpb24PbWF4TG9ja0R1cmF0aW9uDG1hdGhDb250cmFjdAkAuQkCCQDMCAICCCVzJWQlZCVkCQDMCAIFB2Fzc2V0SWQJAMwIAgUNbWluTG9ja0Ftb3VudAkAzAgCBQ9taW5Mb2NrRHVyYXRpb24JAMwIAgUPbWF4TG9ja0R1cmF0aW9uCQDMCAIFDG1hdGhDb250cmFjdAUDbmlsBQNTRVABDGZvcm1hdENvbmZpZwUHYXNzZXRJZA1taW5Mb2NrQW1vdW50D21pbkxvY2tEdXJhdGlvbg9tYXhMb2NrRHVyYXRpb24MbWF0aENvbnRyYWN0CQENZm9ybWF0Q29uZmlnUwUFB2Fzc2V0SWQJAKQDAQUNbWluTG9ja0Ftb3VudAkApAMBBQ9taW5Mb2NrRHVyYXRpb24JAKQDAQUPbWF4TG9ja0R1cmF0aW9uBQxtYXRoQ29udHJhY3QBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQABAckbWF0Y2gwCQCiCAEJARNrZXlNYW5hZ2VyUHVibGljS2V5AAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJANkEAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0AAQHJG1hdGNoMAkAoggBCQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgELbXVzdE1hbmFnZXIBAWkEAnBkCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEByRtYXRjaDAJARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACCAUBaQ9jYWxsZXJQdWJsaWNLZXkFAnBrBgUCcGQDCQABAgUHJG1hdGNoMAIEVW5pdAMJAAACCAUBaQZjYWxsZXIFBHRoaXMGBQJwZAkAAgECC01hdGNoIGVycm9yAA5JZHhMb2NrVXNlck51bQABAA1JZHhMb2NrQW1vdW50AAIADElkeExvY2tTdGFydAADAA9JZHhMb2NrRHVyYXRpb24ABAANSWR4TG9ja1BhcmFtSwAFAA1JZHhMb2NrUGFyYW1CAAYBE2tleUxvY2tQYXJhbXNSZWNvcmQBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIKJXMlc19fbG9jawkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAQt1c2VyQWRkcmVzcwkAtQkCCQEEc3RyZgIFBHRoaXMJARNrZXlMb2NrUGFyYW1zUmVjb3JkAQULdXNlckFkZHJlc3MFA1NFUAEXZm9ybWF0TG9ja1BhcmFtc1JlY29yZFMIB3VzZXJOdW0GYW1vdW50BXN0YXJ0CGR1cmF0aW9uBnBhcmFtSwZwYXJhbUIQbGFzdFVwZFRpbWVzdGFtcAlnd3hBbW91bnQJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIFB3VzZXJOdW0JAMwIAgUGYW1vdW50CQDMCAIFBXN0YXJ0CQDMCAIFCGR1cmF0aW9uCQDMCAIFBnBhcmFtSwkAzAgCBQZwYXJhbUIJAMwIAgUQbGFzdFVwZFRpbWVzdGFtcAkAzAgCBQlnd3hBbW91bnQFA25pbAUDU0VQARZmb3JtYXRMb2NrUGFyYW1zUmVjb3JkBwd1c2VyTnVtBmFtb3VudAVzdGFydAhkdXJhdGlvbgZwYXJhbUsGcGFyYW1CCWd3eEFtb3VudAkBF2Zvcm1hdExvY2tQYXJhbXNSZWNvcmRTCAUHdXNlck51bQkApAMBBQZhbW91bnQJAKQDAQUFc3RhcnQJAKQDAQUIZHVyYXRpb24JAKQDAQUGcGFyYW1LCQCkAwEFBnBhcmFtQgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkApAMBBQlnd3hBbW91bnQBDmtleU5leHRVc2VyTnVtAAIPJXNfX25leHRVc2VyTnVtARJrZXlVc2VyMk51bU1hcHBpbmcBC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIZJXMlcyVzX19tYXBwaW5nX191c2VyMm51bQkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABEmtleU51bTJVc2VyTWFwcGluZwEDbnVtCQC5CQIJAMwIAgIZJXMlcyVzX19tYXBwaW5nX19udW0ydXNlcgkAzAgCBQNudW0FA25pbAUDU0VQARZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AQd1c2VyTnVtCQC5CQIJAMwIAgIWJXMlZCVzX19wYXJhbUJ5VXNlck51bQkAzAgCBQd1c2VyTnVtCQDMCAICBmFtb3VudAUDbmlsBQNTRVABFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBB3VzZXJOdW0JALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFB3VzZXJOdW0JAMwIAgIFc3RhcnQFA25pbAUDU0VQARRrZXlMb2NrUGFyYW1EdXJhdGlvbgEHdXNlck51bQkAuQkCCQDMCAICFiVzJWQlc19fcGFyYW1CeVVzZXJOdW0JAMwIAgUHdXNlck51bQkAzAgCAghkdXJhdGlvbgUDbmlsBQNTRVABDWtleUxvY2tQYXJhbUsBB3VzZXJOdW0JALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFB3VzZXJOdW0JAMwIAgIBawUDbmlsBQNTRVABDWtleUxvY2tQYXJhbUIBB3VzZXJOdW0JALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFB3VzZXJOdW0JAMwIAgIBYgUDbmlsBQNTRVABFWtleUxvY2tQYXJhbUJ5UGVyaW9kSwIHdXNlck51bQZwZXJpb2QJALkJAgkAzAgCAhclcyVkJXMlZF9fcGFyYW1CeVBlcmlvZAkAzAgCBQd1c2VyTnVtCQDMCAICAWsJAMwIAgUGcGVyaW9kBQNuaWwFA1NFUAEVa2V5TG9ja1BhcmFtQnlQZXJpb2RCAgd1c2VyTnVtBnBlcmlvZAkAuQkCCQDMCAICFyVzJWQlcyVkX19wYXJhbUJ5UGVyaW9kCQDMCAIFB3VzZXJOdW0JAMwIAgIBYgkAzAgCBQZwZXJpb2QFA25pbAUDU0VQARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAACHiVzJXNfX3N0YXRzX19hY3RpdmVUb3RhbExvY2tlZAEga2V5U3RhdHNMb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MAAiUlcyVzX19zdGF0c19fbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzARJrZXlTdGF0c0xvY2tzQ291bnQAAhclcyVzX19zdGF0c19fbG9ja3NDb3VudAESa2V5U3RhdHNVc2Vyc0NvdW50AAIdJXMlc19fc3RhdHNfX2FjdGl2ZVVzZXJzQ291bnQBIGtleVVzZXJCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMAQd1c2VyTnVtCQC5CQIJAMwIAgIeJXMlZF9fdXNlckJvb3N0RW1pc3Npb25MYXN0SW50CQDMCAIFB3VzZXJOdW0FA25pbAUDU0VQASJrZXlVc2VyTHBCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMAgd1c2VyTnVtCWxwQXNzZXRJZAkAuQkCCQDMCAICHiVzJWRfX3VzZXJCb29zdEVtaXNzaW9uTGFzdEludAkAzAgCBQd1c2VyTnVtCQDMCAIFCWxwQXNzZXRJZAUDbmlsBQNTRVABF2tleVVzZXJNYXhCb29zdElOVEVHUkFMAQd1c2VyTnVtCQC5CQIJAMwIAgIRJXMlZF9fbWF4Qm9vc3RJbnQJAMwIAgUHdXNlck51bQUDbmlsBQNTRVABGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAACGCVzJXNfX21heEJvb3N0SW50X190b3RhbAEha2V5VXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsAQd1c2VyTnVtCQC5CQIJAMwIAgIkJXMlZF9fdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsCQDMCAIFB3VzZXJOdW0FA25pbAUDU0VQARNrZXlVc2VyQm9vc3RDbGFpbWVkAQd1c2VyTnVtCQC5CQIJAMwIAgIWJXMlZF9fdXNlckJvb3N0Q2xhaW1lZAkAzAgCBQd1c2VyTnVtBQNuaWwFA1NFUAERa2V5VG90YWxDYWNoZWRHd3gAAhYlcyVzX19nd3hDYWNoZWRfX3RvdGFsAA9mYWN0b3J5Q29udHJhY3QJARhyZWFkRmFjdG9yeUFkZHJlc3NPckZhaWwAAApmYWN0b3J5Q2ZnCQEUcmVhZEZhY3RvcnlDZmdPckZhaWwBBQ9mYWN0b3J5Q29udHJhY3QAEGVtaXNzaW9uQ29udHJhY3QJARhnZXRFbWlzc2lvbkFkZHJlc3NPckZhaWwBBQpmYWN0b3J5Q2ZnAA9zdGFraW5nQ29udHJhY3QJARdnZXRTdGFraW5nQWRkcmVzc09yRmFpbAEFCmZhY3RvcnlDZmcAEWd3eFJld2FyZENvbnRyYWN0CQEZZ2V0R3d4UmV3YXJkQWRkcmVzc09yRmFpbAEFCmZhY3RvcnlDZmcBDEhpc3RvcnlFbnRyeQgEdHlwZQR1c2VyBmFtb3VudAlsb2NrU3RhcnQIZHVyYXRpb24BawFiAWkECmhpc3RvcnlLRVkJALkJAgkAzAgCAhElcyVzJXMlc19faGlzdG9yeQkAzAgCBQR0eXBlCQDMCAIFBHVzZXIJAMwIAgkA2AQBCAUBaQ10cmFuc2FjdGlvbklkBQNuaWwFA1NFUAQLaGlzdG9yeURBVEEJALkJAgkAzAgCAg4lZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBQZhbW91bnQJAMwIAgkApAMBBQlsb2NrU3RhcnQJAMwIAgkApAMBBQhkdXJhdGlvbgkAzAgCCQCkAwEFAWsJAMwIAgkApAMBBQFiBQNuaWwFA1NFUAkBC1N0cmluZ0VudHJ5AgUKaGlzdG9yeUtFWQULaGlzdG9yeURBVEEBClN0YXRzRW50cnkEDnRvdGFsTG9ja2VkSW5jC2R1cmF0aW9uSW5jDGxvY2tDb3VudEluYw11c2Vyc0NvdW50SW5jBBtsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3NLRVkJASBrZXlTdGF0c0xvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwAEDWxvY2tzQ291bnRLRVkJARJrZXlTdGF0c0xvY2tzQ291bnQABA11c2Vyc0NvdW50S0VZCQESa2V5U3RhdHNVc2Vyc0NvdW50AAQOdG90YWxBbW91bnRLRVkJARdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudAAEGGxvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwkBA2lvegIFBHRoaXMFG2xvY2tzRHVyYXRpb25TdW1JbkJsb2Nrc0tFWQQKbG9ja3NDb3VudAkBA2lvegIFBHRoaXMFDWxvY2tzQ291bnRLRVkECnVzZXJzQ291bnQJAQNpb3oCBQR0aGlzBQ11c2Vyc0NvdW50S0VZBAt0b3RhbEFtb3VudAkBA2lvegIFBHRoaXMFDnRvdGFsQW1vdW50S0VZCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRtsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3NLRVkJAGQCBRhsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MFC2R1cmF0aW9uSW5jCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1sb2Nrc0NvdW50S0VZCQBkAgUKbG9ja3NDb3VudAUMbG9ja0NvdW50SW5jCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ11c2Vyc0NvdW50S0VZCQBkAgUKdXNlcnNDb3VudAUNdXNlcnNDb3VudEluYwkAzAgCCQEMSW50ZWdlckVudHJ5AgUOdG90YWxBbW91bnRLRVkJAGQCBQt0b3RhbEFtb3VudAUOdG90YWxMb2NrZWRJbmMFA25pbAENY2FsY0d3eEFtb3VudAMEa1JhdwRiUmF3AWgEBVNDQUxFAOgHCQBpAgkAZAIJAGgCBQRrUmF3BQFoBQRiUmF3BQVTQ0FMRQEPTG9ja1BhcmFtc0VudHJ5CAt1c2VyQWRkcmVzcwd1c2VyTnVtBmFtb3VudAVzdGFydAhkdXJhdGlvbgFrAWIGcGVyaW9kBA11c2VyQW1vdW50S0VZCQEWa2V5TG9ja1BhcmFtVXNlckFtb3VudAEFB3VzZXJOdW0EDXN0YXJ0QmxvY2tLRVkJARZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAQUHdXNlck51bQQLZHVyYXRpb25LRVkJARRrZXlMb2NrUGFyYW1EdXJhdGlvbgEFB3VzZXJOdW0EBGtLRVkJAQ1rZXlMb2NrUGFyYW1LAQUHdXNlck51bQQEYktFWQkBDWtleUxvY2tQYXJhbUIBBQd1c2VyTnVtBAxrQnlQZXJpb2RLRVkJARVrZXlMb2NrUGFyYW1CeVBlcmlvZEsCBQd1c2VyTnVtBQZwZXJpb2QEDGJCeVBlcmlvZEtFWQkBFWtleUxvY2tQYXJhbUJ5UGVyaW9kQgIFB3VzZXJOdW0FBnBlcmlvZAQJZ3d4QW1vdW50CQENY2FsY0d3eEFtb3VudAMFAWsFAWIFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUNdXNlckFtb3VudEtFWQUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1zdGFydEJsb2NrS0VZBQVzdGFydAkAzAgCCQEMSW50ZWdlckVudHJ5AgULZHVyYXRpb25LRVkFCGR1cmF0aW9uCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQRrS0VZBQFrCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQRiS0VZBQFiCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQxrQnlQZXJpb2RLRVkFAWsJAMwIAgkBDEludGVnZXJFbnRyeQIFDGJCeVBlcmlvZEtFWQUBYgkAzAgCCQELU3RyaW5nRW50cnkCCQETa2V5TG9ja1BhcmFtc1JlY29yZAEFC3VzZXJBZGRyZXNzCQEWZm9ybWF0TG9ja1BhcmFtc1JlY29yZAcFB3VzZXJOdW0FBmFtb3VudAUFc3RhcnQFCGR1cmF0aW9uBQFrBQFiBQlnd3hBbW91bnQFA25pbAEiZXh0cmFjdE9wdGlvbmFsUGF5bWVudEFtb3VudE9yRmFpbAIBaQ9leHBlY3RlZEFzc2V0SWQDCQBmAgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIbb25seSBvbmUgcGF5bWVudCBpcyBhbGxvd2VkAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAAAABANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAUPZXhwZWN0ZWRBc3NldElkCQACAQIbaW52YWxpZCBhc3NldCBpZCBpbiBwYXltZW50CAUDcG10BmFtb3VudAEZY2FsY1VzZXJHd3hBbW91bnRBdEhlaWdodAILdXNlckFkZHJlc3MMdGFyZ2V0SGVpZ2h0BAVFTVBUWQIFZW1wdHkEEnVzZXIyTnVtTWFwcGluZ0tFWQkBEmtleVVzZXIyTnVtTWFwcGluZwEFC3VzZXJBZGRyZXNzBAd1c2VyTnVtCQELdmFsdWVPckVsc2UCCQCiCAEFEnVzZXIyTnVtTWFwcGluZ0tFWQUFRU1QVFkEAWsJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDWtleUxvY2tQYXJhbUsBBQd1c2VyTnVtAAAEAWIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBDWtleUxvY2tQYXJhbUIBBQd1c2VyTnVtAAAEDWd3eEFtb3VudENhbGMJAQ1jYWxjR3d4QW1vdW50AwUBawUBYgUMdGFyZ2V0SGVpZ2h0BAlnd3hBbW91bnQDCQBmAgAABQ1nd3hBbW91bnRDYWxjAAAFDWd3eEFtb3VudENhbGMFCWd3eEFtb3VudAEUY2FsY0N1cnJlbnRHd3hBbW91bnQBC3VzZXJBZGRyZXNzCQEZY2FsY1VzZXJHd3hBbW91bnRBdEhlaWdodAIFC3VzZXJBZGRyZXNzBQZoZWlnaHQBFGludGVybmFsQ2xhaW1XeEJvb3N0AwxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIIcmVhZE9ubHkEBUVNUFRZAgVFTVBUWQQRdXNlclJlY29yZE9yRW1wdHkJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBE2tleUxvY2tQYXJhbXNSZWNvcmQBBQ51c2VyQWRkcmVzc1N0cgUFRU1QVFkDCQAAAgURdXNlclJlY29yZE9yRW1wdHkFBUVNUFRZCQCVCgMAAAUDbmlsAhV1c2VyUmVjb3JkOjppczo6ZW1wdHkED3VzZXJSZWNvcmRBcnJheQkAtQkCBRF1c2VyUmVjb3JkT3JFbXB0eQUDU0VQBAp1c2VyTnVtU3RyCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUOSWR4TG9ja1VzZXJOdW0EHGd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQJAQt2YWx1ZU9yRWxzZQIJAJoIAgURZ3d4UmV3YXJkQ29udHJhY3QJAR9rZXlHd3hSZXdhcmRFbWlzc2lvblN0YXJ0SGVpZ2h0AAAABAhFTVBUWVNUUgIFZW1wdHkEDSR0MDEzODcwMTQ0MzgDCQECIT0CBQxscEFzc2V0SWRTdHIFCEVNUFRZU1RSBA5wb29sQWRkcmVzc1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD2ZhY3RvcnlDb250cmFjdAkBGmtleUZhY3RvcnlMcDJBc3NldHNNYXBwaW5nAQUMbHBBc3NldElkU3RyCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUMbHBBc3NldElkU3RyBANwdzEJARFAZXh0ck5hdGl2ZSgxMDUwKQIFD2ZhY3RvcnlDb250cmFjdAkBFGtleUZhY3RvcnlQb29sV2VpZ2h0AQUOcG9vbEFkZHJlc3NTdHIEA3B3MAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ9mYWN0b3J5Q29udHJhY3QJARtrZXlGYWN0b3J5UG9vbFdlaWdodEhpc3RvcnkCBQ5wb29sQWRkcmVzc1N0cgAABQNwdzEJAJQKAgUDcHcwBQNwdzEDBQhyZWFkT25seQkAlAoCAAAAAAkAAgEJAKwCAgIobm90IHJlYWRvbmx5IG1vZGU6IHVuc3VwcG9ydGVkIGxwIGFzc2V0IAUMbHBBc3NldElkU3RyBAtwb29sV2VpZ2h0MAgFDSR0MDEzODcwMTQ0MzgCXzEEC3Bvb2xXZWlnaHQxCAUNJHQwMTM4NzAxNDQzOAJfMgQSd3hFbWlzc2lvblBlckJsb2NrCQEDaW9mAgUQZW1pc3Npb25Db250cmFjdAkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAEDWVtaXNzaW9uU3RhcnQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQEVa2V5RW1pc3Npb25TdGFydEJsb2NrAAQLZW1pc3Npb25FbmQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQETa2V5RW1pc3Npb25FbmRCbG9jawAEAWgDCQBmAgUGaGVpZ2h0BQtlbWlzc2lvbkVuZAULZW1pc3Npb25FbmQFBmhlaWdodAQCZGgJAJYDAQkAzAgCCQBlAgUBaAUNZW1pc3Npb25TdGFydAkAzAgCAAAFA25pbAQidXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQkBImtleVVzZXJMcEJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwCBQp1c2VyTnVtU3RyBQxscEFzc2V0SWRTdHIEIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEga2V5VXNlckJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwBBQp1c2VyTnVtU3RyBB11c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBSJ1c2VyTHBCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEDaW96AgUEdGhpcwUgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkEFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAaQIJAGgCCQBoAgUSd3hFbWlzc2lvblBlckJsb2NrBQJkaAACAAMEGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAGUCBRVib29zdEVtaXNzaW9uSW50ZWdyYWwFHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsBAN1ZGgJAGsDBRl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsAAMJAGgCAAIFEnd4RW1pc3Npb25QZXJCbG9jawQGdUxhc3RICQBlAgUBaAUDdWRoBAR1ZGgwCQCWAwEJAMwIAgkAZQIFHGd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQFBnVMYXN0SAkAzAgCAAAFA25pbAQEdWRoMQkAZQIJAGUCBQFoBQZ1TGFzdEgFBHVkaDADAwMJAGYCAAAFBnVMYXN0SAYJAGYCAAAFBHVkaDEGCQBnAgkBA2FicwEJAGUCCQBkAgUEdWRoMAUEdWRoMQUDdWRoAAEJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICFmludmFsaWQgdWRoIGNhbGM6IHVkaD0JAKQDAQUDdWRoAgggdUxhc3RIPQkApAMBBQZ1TGFzdEgCBiB1ZGgwPQkApAMBBQR1ZGgwAgYgdWRoMT0JAKQDAQUEdWRoMQMJAGYCAAAFGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAAIBAhJ3cm9uZyBjYWxjdWxhdGlvbnMEF3VzZXJNYXhCb29zdEludGVncmFsS0VZCQEXa2V5VXNlck1heEJvb3N0SU5URUdSQUwBBQp1c2VyTnVtU3RyBBh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkJARhrZXlUb3RhbE1heEJvb3N0SU5URUdSQUwABA91c2VyTWF4Qm9vc3RJbnQJAQNpb3oCBQR0aGlzBRd1c2VyTWF4Qm9vc3RJbnRlZ3JhbEtFWQQQdG90YWxNYXhCb29zdEludAkBA2lvegIFBHRoaXMFGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQQRdG90YWxDYWNoZWRHd3hLRVkJARFrZXlUb3RhbENhY2hlZEd3eAAEDnRvdGFsQ2FjaGVkR3d4CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFEXRvdGFsQ2FjaGVkR3d4S0VZAAAEC3VzZXJDdXJyR3d4CQEUY2FsY0N1cnJlbnRHd3hBbW91bnQBBQ51c2VyQWRkcmVzc1N0cgQhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZCQEha2V5VXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsAQUKdXNlck51bVN0cgQedXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsCQEDaW96AgUEdGhpcwUhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZBBp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAMJAAACBQN1ZGgAAAAACQBrAwUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAUEdWRoMAUDdWRoBBp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQMJAAACBQN1ZGgAAAAACQBrAwUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAUEdWRoMQUDdWRoBB5wb29sVXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbDAJAGsDBRp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAULcG9vbFdlaWdodDAFDlBPT0xXRUlHSFRNVUxUBB5wb29sVXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbDEJAGsDBRp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQULcG9vbFdlaWdodDEFDlBPT0xXRUlHSFRNVUxUBCJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcwAwkAAAIFDnRvdGFsQ2FjaGVkR3d4AAAAAAkAawMFHnBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAULdXNlckN1cnJHd3gFDnRvdGFsQ2FjaGVkR3d4BCJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcxAwkAAAIFDnRvdGFsQ2FjaGVkR3d4AAAAAAkAawMFHnBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQULdXNlckN1cnJHd3gFDnRvdGFsQ2FjaGVkR3d4BCF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcJAGQCBSJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcwBSJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcxBBN1c2VyQm9vc3RDbGFpbWVkS0VZCQETa2V5VXNlckJvb3N0Q2xhaW1lZAEFCnVzZXJOdW1TdHIEEHVzZXJCb29zdENsYWltZWQJAQNpb3oCBQR0aGlzBRN1c2VyQm9vc3RDbGFpbWVkS0VZBBJ1c2VyQm9vc3RBdmFpbGFibGUJAGUCBSF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcFEHVzZXJCb29zdENsYWltZWQECWRhdGFTdGF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUidXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQUVYm9vc3RFbWlzc2lvbkludGVncmFsBQNuaWwEBWRlYnVnCQC5CQIJAMwIAgkApAMBBR11c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbAkAzAgCCQCkAwEFGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAMwIAgkApAMBBRB1c2VyQm9vc3RDbGFpbWVkCQDMCAIJAKQDAQUSdXNlckJvb3N0QXZhaWxhYmxlCQDMCAIJAKQDAQULcG9vbFdlaWdodDAJAMwIAgkApAMBBQtwb29sV2VpZ2h0MQkAzAgCCQCkAwEFAWgJAMwIAgkApAMBBQN1ZGgJAMwIAgkApAMBBQZ1TGFzdEgJAMwIAgkApAMBBQR1ZGgwCQDMCAIJAKQDAQUEdWRoMQkAzAgCCQCkAwEFC3VzZXJDdXJyR3d4CQDMCAIJAKQDAQUOdG90YWxDYWNoZWRHd3gFA25pbAIBOgkAlQoDBSF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcFCWRhdGFTdGF0ZQUFZGVidWcLAWkBC2NvbnN0cnVjdG9yBhFmYWN0b3J5QWRkcmVzc1N0cg5sb2NrQXNzZXRJZFN0cg1taW5Mb2NrQW1vdW50C21pbkR1cmF0aW9uC21heER1cmF0aW9uDG1hdGhDb250cmFjdAQLY2hlY2tDYWxsZXIJAQttdXN0TWFuYWdlcgEFAWkDCQAAAgULY2hlY2tDYWxsZXIFC2NoZWNrQ2FsbGVyCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ5rZXlOZXh0VXNlck51bQAAAAkAzAgCCQELU3RyaW5nRW50cnkCCQEJa2V5Q29uZmlnAAkBDGZvcm1hdENvbmZpZwUFDmxvY2tBc3NldElkU3RyBQ1taW5Mb2NrQW1vdW50BQttaW5EdXJhdGlvbgULbWF4RHVyYXRpb24FDG1hdGhDb250cmFjdAkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5RmFjdG9yeUFkZHJlc3MABRFmYWN0b3J5QWRkcmVzc1N0cgUDbmlsCQEKU3RhdHNFbnRyeQQAAAAAAAAAAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQdsb2NrUmVmAwhkdXJhdGlvbg9yZWZlcnJlckFkZHJlc3MJc2lnbmF0dXJlBAdsb2NrSW52CQD8BwQFBHRoaXMCBGxvY2sJAMwIAgUIZHVyYXRpb24FA25pbAgFAWkIcGF5bWVudHMDCQAAAgUHbG9ja0ludgUHbG9ja0ludgQPcmVmZXJyYWxBZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQGcmVmSW52AwMJAAACBQ9yZWZlcnJlckFkZHJlc3MCAAYJAAACBQlzaWduYXR1cmUBAAUEdW5pdAkA/AcEBR5yZWZlcnJhbHNDb250cmFjdEFkZHJlc3NPckZhaWwCCmNyZWF0ZVBhaXIJAMwIAgUTcmVmZXJyYWxQcm9ncmFtTmFtZQkAzAgCBQ9yZWZlcnJlckFkZHJlc3MJAMwIAgUPcmVmZXJyYWxBZGRyZXNzCQDMCAIFCXNpZ25hdHVyZQUDbmlsBQNuaWwDCQAAAgUGcmVmSW52BQZyZWZJbnYJAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBGxvY2sBCGR1cmF0aW9uBAhjZmdBcnJheQkBFXJlYWRDb25maWdBcnJheU9yRmFpbAAECmFzc2V0SWRTdHIJAJEDAgUIY2ZnQXJyYXkFDUlkeENmZ0Fzc2V0SWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQNbWluTG9ja0Ftb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRNJZHhDZmdNaW5Mb2NrQW1vdW50BA9taW5Mb2NrRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUVSWR4Q2ZnTWluTG9ja0R1cmF0aW9uBA9tYXhMb2NrRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uBAxtYXRoQ29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ01hdGhDb250cmFjdAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECNGludmFsaWQgcGF5bWVudCAtIGV4YWN0IG9uZSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABAlwbXRBbW91bnQIBQNwbXQGYW1vdW50AwkBAiE9AgUHYXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkCQACAQkArAICCQCsAgICHmludmFsaWQgYXNzZXQgaXMgaW4gcGF5bWVudCAtIAUKYXNzZXRJZFN0cgIMIGlzIGV4cGVjdGVkBA5uZXh0VXNlck51bUtFWQkBDmtleU5leHRVc2VyTnVtAAQOdXNlckFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyBA51c2VySXNFeGlzdGluZwkBCWlzRGVmaW5lZAEJAKIIAQkBEmtleVVzZXIyTnVtTWFwcGluZwEFDnVzZXJBZGRyZXNzU3RyBAp1c2VyTnVtU3RyAwUOdXNlcklzRXhpc3RpbmcJAQV2YWx1ZQEJAKIIAQkBEmtleVVzZXIyTnVtTWFwcGluZwEFDnVzZXJBZGRyZXNzU3RyCQCkAwEJAQNpb2YCBQR0aGlzBQ5uZXh0VXNlck51bUtFWQQHdXNlck51bQkBDXBhcnNlSW50VmFsdWUBBQp1c2VyTnVtU3RyBAlsb2NrU3RhcnQFBmhlaWdodAQNc3RhcnRCbG9ja0tFWQkBFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sBBQp1c2VyTnVtU3RyBAtkdXJhdGlvbktFWQkBFGtleUxvY2tQYXJhbUR1cmF0aW9uAQUKdXNlck51bVN0cgQNdXNlckFtb3VudEtFWQkBFmtleUxvY2tQYXJhbVVzZXJBbW91bnQBBQp1c2VyTnVtU3RyAwkAZgIFDW1pbkxvY2tBbW91bnQFCXBtdEFtb3VudAkAAgEJAKwCAgIiYW1vdW50IGlzIGxlc3MgdGhlbiBtaW5Mb2NrQW1vdW50PQkApAMBBQ1taW5Mb2NrQW1vdW50AwkAZgIFD21pbkxvY2tEdXJhdGlvbgUIZHVyYXRpb24JAAIBCQCsAgICLXBhc3NlZCBkdXJhdGlvbiBpcyBsZXNzIHRoZW4gbWluTG9ja0R1cmF0aW9uPQkApAMBBQ9taW5Mb2NrRHVyYXRpb24DCQBmAgUIZHVyYXRpb24FD21heExvY2tEdXJhdGlvbgkAAgEJAKwCAgIwcGFzc2VkIGR1cmF0aW9uIGlzIGdyZWF0ZXIgdGhlbiBtYXhMb2NrRHVyYXRpb249CQCkAwEFD21heExvY2tEdXJhdGlvbgMDBQ51c2VySXNFeGlzdGluZwkAZwIJAGQCCQEDaW9mAgUEdGhpcwUNc3RhcnRCbG9ja0tFWQkBA2lvZgIFBHRoaXMFC2R1cmF0aW9uS0VZBQlsb2NrU3RhcnQHCQACAQI2dGhlcmUgaXMgYW4gYWN0aXZlIGxvY2sgLSBjb25zaWRlciB0byB1c2UgaW5jcmVhc2VMb2NrAwkAZgIJAQNpb3oCBQR0aGlzBQ11c2VyQW1vdW50S0VZAAAJAAIBCQCsAgICNHRoZXJlIGFyZSBsb2NrZWQgV1hzIC0gY29uc2lkZXIgdG8gdXNlIGluY3JlYXNlTG9jayAFDXVzZXJBbW91bnRLRVkEB2NvZWZmWDgJAGsDBQhkdXJhdGlvbgUFTVVMVDgFD21heExvY2tEdXJhdGlvbgQOZ1d4QW1vdW50U3RhcnQJAGsDBQlwbXRBbW91bnQFB2NvZWZmWDgFBU1VTFQ4BBNnV3hQYXJhbXNSZXN1bHRMaXN0CQEDYWFsAQkA/AcEBQxtYXRoQ29udHJhY3QCFWNhbGNHd3hQYXJhbXNSRUFET05MWQkAzAgCBQ5nV3hBbW91bnRTdGFydAkAzAgCBQlsb2NrU3RhcnQJAMwIAgUIZHVyYXRpb24FA25pbAUDbmlsBAFrCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAQBYgkBAmFpAQkAkQMCBRNnV3hQYXJhbXNSZXN1bHRMaXN0AAEEBnBlcmlvZAkApAMBCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAgQSd3hFbWlzc2lvblBlckJsb2NrCQEDaW9mAgUQZW1pc3Npb25Db250cmFjdAkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAEDWVtaXNzaW9uU3RhcnQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQEVa2V5RW1pc3Npb25TdGFydEJsb2NrAAQLZW1pc3Npb25FbmQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQETa2V5RW1pc3Npb25FbmRCbG9jawAEAWgDCQBmAgUGaGVpZ2h0BQtlbWlzc2lvbkVuZAULZW1pc3Npb25FbmQFBmhlaWdodAQCZGgJAJYDAQkAzAgCCQBlAgUBaAUNZW1pc3Npb25TdGFydAkAzAgCAAAFA25pbAQgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJASBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAEFCnVzZXJOdW1TdHIEFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAaQIJAGgCCQBoAgUSd3hFbWlzc2lvblBlckJsb2NrBQJkaAACAAMEF3VzZXJNYXhCb29zdEludGVncmFsS0VZCQEXa2V5VXNlck1heEJvb3N0SU5URUdSQUwBBQp1c2VyTnVtU3RyBBh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkJARhrZXlUb3RhbE1heEJvb3N0SU5URUdSQUwABA91c2VyTWF4Qm9vc3RJbnQJAGkCCQBoAgUOZ1d4QW1vdW50U3RhcnQFCGR1cmF0aW9uAAIEEHRvdGFsTWF4Qm9vc3RJbnQJAQNpb3oCBQR0aGlzBRh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkEEXRvdGFsQ2FjaGVkR3d4S0VZCQERa2V5VG90YWxDYWNoZWRHd3gABA50b3RhbENhY2hlZEd3eAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRF0b3RhbENhY2hlZEd3eEtFWQAABANhcnIDBQ51c2VySXNFeGlzdGluZwUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5uZXh0VXNlck51bUtFWQkAZAIFB3VzZXJOdW0AAQkAzAgCCQELU3RyaW5nRW50cnkCCQESa2V5VXNlcjJOdW1NYXBwaW5nAQUOdXNlckFkZHJlc3NTdHIFCnVzZXJOdW1TdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEmtleU51bTJVc2VyTWFwcGluZwEFCnVzZXJOdW1TdHIFDnVzZXJBZGRyZXNzU3RyBQNuaWwJAM4IAgkAzQgCCQDOCAIJAM4IAgUDYXJyCQEPTG9ja1BhcmFtc0VudHJ5CAUOdXNlckFkZHJlc3NTdHIFCnVzZXJOdW1TdHIFCXBtdEFtb3VudAUJbG9ja1N0YXJ0BQhkdXJhdGlvbgUBawUBYgUGcGVyaW9kCQEKU3RhdHNFbnRyeQQFCXBtdEFtb3VudAUIZHVyYXRpb24AAQMFDnVzZXJJc0V4aXN0aW5nAAAAAQkBDEhpc3RvcnlFbnRyeQgCBGxvY2sFDnVzZXJBZGRyZXNzU3RyBQlwbXRBbW91bnQFCWxvY2tTdGFydAUIZHVyYXRpb24FAWsFAWIFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIFIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZBRVib29zdEVtaXNzaW9uSW50ZWdyYWwJAMwIAgkBDEludGVnZXJFbnRyeQIFEXRvdGFsQ2FjaGVkR3d4S0VZCQBkAgUOdG90YWxDYWNoZWRHd3gFDmdXeEFtb3VudFN0YXJ0BQNuaWwBaQEMaW5jcmVhc2VMb2NrAQ1kZWx0YUR1cmF0aW9uBAhjZmdBcnJheQkBFXJlYWRDb25maWdBcnJheU9yRmFpbAAECmFzc2V0SWRTdHIJAJEDAgUIY2ZnQXJyYXkFDUlkeENmZ0Fzc2V0SWQEB2Fzc2V0SWQJANkEAQUKYXNzZXRJZFN0cgQPbWluTG9ja0R1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFFUlkeENmZ01pbkxvY2tEdXJhdGlvbgQPbWF4TG9ja0R1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFFUlkeENmZ01heExvY2tEdXJhdGlvbgQMbWF0aENvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFCGNmZ0FycmF5BRJJZHhDZmdNYXRoQ29udHJhY3QECXBtdEFtb3VudAkBImV4dHJhY3RPcHRpb25hbFBheW1lbnRBbW91bnRPckZhaWwCBQFpBQdhc3NldElkBA51c2VyQWRkcmVzc1N0cgkApQgBCAUBaQZjYWxsZXIED3VzZXJSZWNvcmRBcnJheQkBGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAQUOdXNlckFkZHJlc3NTdHIECnVzZXJOdW1TdHIJAJEDAgUPdXNlclJlY29yZEFycmF5BQ5JZHhMb2NrVXNlck51bQQKdXNlckFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUNSWR4TG9ja0Ftb3VudAQJbG9ja1N0YXJ0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdXNlclJlY29yZEFycmF5BQxJZHhMb2NrU3RhcnQEDGxvY2tEdXJhdGlvbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUPSWR4TG9ja0R1cmF0aW9uBAdsb2NrRW5kCQBkAgUJbG9ja1N0YXJ0BQxsb2NrRHVyYXRpb24EEXJlbWFpbmluZ0R1cmF0aW9uCQCWAwEJAMwIAgkAZQIFB2xvY2tFbmQFBmhlaWdodAkAzAgCAAAFA25pbAQNdXNlckFtb3VudE5ldwkAZAIFCnVzZXJBbW91bnQFCXBtdEFtb3VudAQPbG9ja0R1cmF0aW9uTmV3CQBkAgURcmVtYWluaW5nRHVyYXRpb24FDWRlbHRhRHVyYXRpb24DCQBmAgAABQ1kZWx0YUR1cmF0aW9uCQACAQIaZHVyYXRpb24gaXMgbGVzcyB0aGVuIHplcm8DCQBmAgUPbWluTG9ja0R1cmF0aW9uBQ9sb2NrRHVyYXRpb25OZXcJAAIBCQCsAgICLWxvY2tEdXJhdGlvbk5ldyBpcyBsZXNzIHRoZW4gbWluTG9ja0R1cmF0aW9uPQkApAMBBQ9taW5Mb2NrRHVyYXRpb24DCQBmAgUPbG9ja0R1cmF0aW9uTmV3BQ9tYXhMb2NrRHVyYXRpb24JAAIBCQCsAgICRGRlbHRhRHVyYXRpb24gKyBleGlzdGVkTG9ja0R1cmF0aW9uIGlzIGdyZWF0ZXIgdGhlbiBtYXhMb2NrRHVyYXRpb249CQCkAwEFD21heExvY2tEdXJhdGlvbgQHY29lZmZYOAkAawMFD2xvY2tEdXJhdGlvbk5ldwUFTVVMVDgFD21heExvY2tEdXJhdGlvbgQOZ1d4QW1vdW50U3RhcnQJAGsDBQ11c2VyQW1vdW50TmV3BQdjb2VmZlg4BQVNVUxUOAQMbG9ja1N0YXJ0TmV3BQZoZWlnaHQEE2dXeFBhcmFtc1Jlc3VsdExpc3QJAQNhYWwBCQD8BwQFDG1hdGhDb250cmFjdAIVY2FsY0d3eFBhcmFtc1JFQURPTkxZCQDMCAIFDmdXeEFtb3VudFN0YXJ0CQDMCAIFDGxvY2tTdGFydE5ldwkAzAgCBQ9sb2NrRHVyYXRpb25OZXcFA25pbAUDbmlsBAFrCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAQBYgkBAmFpAQkAkQMCBRNnV3hQYXJhbXNSZXN1bHRMaXN0AAEEBnBlcmlvZAkApAMBCQECYWkBCQCRAwIFE2dXeFBhcmFtc1Jlc3VsdExpc3QAAgQSd3hFbWlzc2lvblBlckJsb2NrCQEDaW9mAgUQZW1pc3Npb25Db250cmFjdAkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAEDWVtaXNzaW9uU3RhcnQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQEVa2V5RW1pc3Npb25TdGFydEJsb2NrAAQLZW1pc3Npb25FbmQJAQNpb2YCBRBlbWlzc2lvbkNvbnRyYWN0CQETa2V5RW1pc3Npb25FbmRCbG9jawAEAWgDCQBmAgUGaGVpZ2h0BQtlbWlzc2lvbkVuZAULZW1pc3Npb25FbmQFBmhlaWdodAQCZGgJAJYDAQkAzAgCCQBlAgUBaAUNZW1pc3Npb25TdGFydAkAzAgCAAAFA25pbAQgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJASBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAEFCnVzZXJOdW1TdHIEHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsCQEDaW96AgUEdGhpcwUgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkEFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAaQIJAGgCCQBoAgUSd3hFbWlzc2lvblBlckJsb2NrBQJkaAACAAMEGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAGUCBRVib29zdEVtaXNzaW9uSW50ZWdyYWwFHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsAwkAZgIAAAUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAAgECEndyb25nIGNhbGN1bGF0aW9ucwQXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkJARdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTAEFCnVzZXJOdW1TdHIEGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAAED3VzZXJNYXhCb29zdEludAkBA2lvegIFBHRoaXMFF3VzZXJNYXhCb29zdEludGVncmFsS0VZBBB0b3RhbE1heEJvb3N0SW50CQEDaW96AgUEdGhpcwUYdG90YWxNYXhCb29zdEludGVncmFsS0VZBAtjdXJyVXNlckd3eAkBFGNhbGNDdXJyZW50R3d4QW1vdW50AQUOdXNlckFkZHJlc3NTdHIEB2d3eERpZmYJAGUCBQ5nV3hBbW91bnRTdGFydAULY3VyclVzZXJHd3gDCQBmAgAABQdnd3hEaWZmCQACAQkArAICAhhnd3hEaWZmIGlzIGxlc3MgdGhlbiAwOiAJAKQDAQUHZ3d4RGlmZgQRdG90YWxDYWNoZWRHd3hLRVkJARFrZXlUb3RhbENhY2hlZEd3eAAEDnRvdGFsQ2FjaGVkR3d4CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFEXRvdGFsQ2FjaGVkR3d4S0VZAAAEIXVzZXJCb29zdEF2YWxhaWJsZVRvQ2xhaW1Ub3RhbEtFWQkBIWtleVVzZXJCb29zdEF2YWxhaWJsZVRvQ2xhaW1Ub3RhbAEFCnVzZXJOdW1TdHIEHnVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbAkBA2lvegIFBHRoaXMFIXVzZXJCb29zdEF2YWxhaWJsZVRvQ2xhaW1Ub3RhbEtFWQQhdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsTmV3CQBrAwUZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAULY3VyclVzZXJHd3gFDnRvdGFsQ2FjaGVkR3d4BBJ1c2VyTWF4Qm9vc3RJbnROZXcJAGkCCQBoAgUOZ1d4QW1vdW50U3RhcnQFD2xvY2tEdXJhdGlvbk5ldwACBBhyZW1haW5pbmdVc2VyTWF4Qm9vc3RJbnQJAGkCCQBoAgULY3VyclVzZXJHd3gFEXJlbWFpbmluZ0R1cmF0aW9uAAIEE3VzZXJNYXhCb29zdEludERpZmYJAGUCBRJ1c2VyTWF4Qm9vc3RJbnROZXcFGHJlbWFpbmluZ1VzZXJNYXhCb29zdEludAkAzggCCQDNCAIJAM4IAgkBD0xvY2tQYXJhbXNFbnRyeQgFDnVzZXJBZGRyZXNzU3RyBQp1c2VyTnVtU3RyBQ11c2VyQW1vdW50TmV3BQxsb2NrU3RhcnROZXcFD2xvY2tEdXJhdGlvbk5ldwUBawUBYgUGcGVyaW9kCQEKU3RhdHNFbnRyeQQFCXBtdEFtb3VudAUNZGVsdGFEdXJhdGlvbgAAAAAJAQxIaXN0b3J5RW50cnkIAgRsb2NrBQ51c2VyQWRkcmVzc1N0cgUJcG10QW1vdW50BQlsb2NrU3RhcnQFD2xvY2tEdXJhdGlvbk5ldwUBawUBYgUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgURdG90YWxDYWNoZWRHd3hLRVkJAGQCBQ50b3RhbENhY2hlZEd3eAUHZ3d4RGlmZgUDbmlsAWkBDGNsYWltV3hCb29zdAIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyAwkBAiE9AgUPc3Rha2luZ0NvbnRyYWN0CAUBaQZjYWxsZXIJAAIBAhJwZXJtaXNzaW9ucyBkZW5pZWQEDSR0MDI4MDYyMjgxNjQJARRpbnRlcm5hbENsYWltV3hCb29zdAMFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIHBBJ1c2VyQm9vc3RBdmFpbGFibGUIBQ0kdDAyODA2MjI4MTY0Al8xBAlkYXRhU3RhdGUIBQ0kdDAyODA2MjI4MTY0Al8yBAVkZWJ1ZwgFDSR0MDI4MDYyMjgxNjQCXzMJAJQKAgUJZGF0YVN0YXRlCQDMCAIFEnVzZXJCb29zdEF2YWlsYWJsZQUDbmlsAWkBFGNsYWltV3hCb29zdFJFQURPTkxZAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIEDSR0MDI4Mjk2MjgzOTcJARRpbnRlcm5hbENsYWltV3hCb29zdAMFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIGBBJ1c2VyQm9vc3RBdmFpbGFibGUIBQ0kdDAyODI5NjI4Mzk3Al8xBAlkYXRhU3RhdGUIBQ0kdDAyODI5NjI4Mzk3Al8yBAVkZWJ1ZwgFDSR0MDI4Mjk2MjgzOTcCXzMJAJQKAgUDbmlsCQDMCAIFEnVzZXJCb29zdEF2YWlsYWJsZQkAzAgCBQVkZWJ1ZwUDbmlsAWkBBnVubG9jawELdXNlckFkZHJlc3MED3VzZXJSZWNvcmRBcnJheQkBGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAQULdXNlckFkZHJlc3MECnVzZXJOdW1TdHIJAJEDAgUPdXNlclJlY29yZEFycmF5BQ5JZHhMb2NrVXNlck51bQQKdXNlckFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUNSWR4TG9ja0Ftb3VudAQJbG9ja1N0YXJ0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdXNlclJlY29yZEFycmF5BQxJZHhMb2NrU3RhcnQEDGxvY2tEdXJhdGlvbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3VzZXJSZWNvcmRBcnJheQUPSWR4TG9ja0R1cmF0aW9uBAdsb2NrRW5kCQBkAgUJbG9ja1N0YXJ0BQxsb2NrRHVyYXRpb24ECGNmZ0FycmF5CQEVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAQHYXNzZXRJZAkA2QQBCQCRAwIFCGNmZ0FycmF5BQ1JZHhDZmdBc3NldElkBAxtYXRoQ29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ01hdGhDb250cmFjdAMJAGcCBQdsb2NrRW5kBQZoZWlnaHQJAAIBCQCsAgIJAKwCAgIFd2FpdCAJAKQDAQUHbG9ja0VuZAIKIHRvIHVubG9jawMJAGcCAAAFCnVzZXJBbW91bnQJAAIBAhFub3RoaW5nIHRvIHVubG9jawQGcGVyaW9kCQELdmFsdWVPckVsc2UCCQCaCAIFDG1hdGhDb250cmFjdAkBDWtleU5leHRQZXJpb2QAAAAJAM0IAgkAzQgCCQDOCAIJAQ9Mb2NrUGFyYW1zRW50cnkIBQt1c2VyQWRkcmVzcwUKdXNlck51bVN0cgAABQlsb2NrU3RhcnQFDGxvY2tEdXJhdGlvbgAAAAAJAKQDAQUGcGVyaW9kCQEKU3RhdHNFbnRyeQQJAQEtAQUKdXNlckFtb3VudAAAAAAA////////////AQkBDEhpc3RvcnlFbnRyeQgCBnVubG9jawULdXNlckFkZHJlc3MFCnVzZXJBbW91bnQFCWxvY2tTdGFydAUMbG9ja0R1cmF0aW9uAAAAAAUBaQkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQULdXNlckFkZHJlc3MFCnVzZXJBbW91bnQFB2Fzc2V0SWQBaQETZ3d4VXNlckluZm9SRUFET05MWQELdXNlckFkZHJlc3MECWd3eEFtb3VudAkBFGNhbGNDdXJyZW50R3d4QW1vdW50AQULdXNlckFkZHJlc3MJAJQKAgUDbmlsCQDMCAIFCWd3eEFtb3VudAUDbmlsAWkBIGdldFVzZXJHd3hBbW91bnRBdEhlaWdodFJFQURPTkxZAgt1c2VyQWRkcmVzcwx0YXJnZXRIZWlnaHQECWd3eEFtb3VudAkBGWNhbGNVc2VyR3d4QW1vdW50QXRIZWlnaHQCBQt1c2VyQWRkcmVzcwUMdGFyZ2V0SGVpZ2h0CQCUCgIFA25pbAUJZ3d4QW1vdW50AWkBCnNldE1hbmFnZXIBF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BAtjaGVja0NhbGxlcgkBC211c3RNYW5hZ2VyAQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIEFWNoZWNrTWFuYWdlclB1YmxpY0tleQkA2QQBBRdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQMJAAACBRVjaGVja01hbmFnZXJQdWJsaWNLZXkFFWNoZWNrTWFuYWdlclB1YmxpY0tleQkAzAgCCQELU3RyaW5nRW50cnkCCQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkABRdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDmNvbmZpcm1NYW5hZ2VyAAQCcG0JAR1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdAAEBWhhc1BNAwkBCWlzRGVmaW5lZAEFAnBtBgkAAgECEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAACBQVoYXNQTQUFaGFzUE0EB2NoZWNrUE0DCQAAAggFAWkPY2FsbGVyUHVibGljS2V5CQEFdmFsdWUBBQJwbQYJAAIBAhtZb3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAgUHY2hlY2tQTQUHY2hlY2tQTQkAzAgCCQELU3RyaW5nRW50cnkCCQETa2V5TWFuYWdlclB1YmxpY0tleQAJANgEAQkBBXZhbHVlAQUCcG0JAMwIAgkBC0RlbGV0ZUVudHJ5AQkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAQPdGFyZ2V0UHVibGljS2V5BAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDAFAnBrAwkAAQIFByRtYXRjaDACBFVuaXQIBQJ0eA9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUPdGFyZ2V0UHVibGljS2V554ICEA==", "chainId": 84, "height": 2156499, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 4qAyQdNa4gyufRQxkRkH6EAA6PW9GRtGt6jn14A1NbNy Next: 8GSPM6h6gqDSXK5jUruTiL5fLqUZokWPnwrvT4MsJYxQ Diff:
OldNewDifferences
4141 throw("fail to cast into Int")
4242 }
4343
44+
45+func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
46+
47+
48+let referralsContractAddressOrFail = addressFromStringValue(strf(this, keyReferralsContractAddress()))
49+
50+let keyReferralProgramName = makeString(["%s%s", "referral", "programName"], SEP)
51+
52+let referralProgramNameDefault = "wxlock"
53+
54+let referralProgramName = valueOrElse(getString(this, keyReferralProgramName), referralProgramNameDefault)
4455
4556 func keyFactoryAddress () = "%s%s__config__factoryAddress"
4657
367378 let userNumStr = userRecordArray[IdxLockUserNum]
368379 let gwxRewardEmissionStartHeight = valueOrElse(getInteger(gwxRewardContract, keyGwxRewardEmissionStartHeight()), 0)
369380 let EMPTYSTR = "empty"
370- let $t01316713735 = if ((lpAssetIdStr != EMPTYSTR))
381+ let $t01387014438 = if ((lpAssetIdStr != EMPTYSTR))
371382 then {
372383 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
373384 let pw1 = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
377388 else if (readOnly)
378389 then $Tuple2(0, 0)
379390 else throw(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
380- let poolWeight0 = $t01316713735._1
381- let poolWeight1 = $t01316713735._2
391+ let poolWeight0 = $t01387014438._1
392+ let poolWeight1 = $t01387014438._2
382393 let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
383394 let emissionStart = iof(emissionContract, keyEmissionStartBlock())
384395 let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
444455 let checkCaller = mustManager(i)
445456 if ((checkCaller == checkCaller))
446457 then ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
458+ else throw("Strict value is not equal to itself.")
459+ }
460+
461+
462+
463+@Callable(i)
464+func lockRef (duration,referrerAddress,signature) = {
465+ let lockInv = invoke(this, "lock", [duration], i.payments)
466+ if ((lockInv == lockInv))
467+ then {
468+ let referralAddress = toString(i.caller)
469+ let refInv = if (if ((referrerAddress == ""))
470+ then true
471+ else (signature == base58''))
472+ then unit
473+ else invoke(referralsContractAddressOrFail, "createPair", [referralProgramName, referrerAddress, referralAddress, signature], nil)
474+ if ((refInv == refInv))
475+ then $Tuple2(nil, unit)
476+ else throw("Strict value is not equal to itself.")
477+ }
447478 else throw("Strict value is not equal to itself.")
448479 }
449480
600631 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
601632 then throw("permissions denied")
602633 else {
603- let $t02692227024 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
604- let userBoostAvailable = $t02692227024._1
605- let dataState = $t02692227024._2
606- let debug = $t02692227024._3
634+ let $t02806228164 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
635+ let userBoostAvailable = $t02806228164._1
636+ let dataState = $t02806228164._2
637+ let debug = $t02806228164._3
607638 $Tuple2(dataState, [userBoostAvailable])
608639 }
609640
611642
612643 @Callable(i)
613644 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
614- let $t02715627257 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
615- let userBoostAvailable = $t02715627257._1
616- let dataState = $t02715627257._2
617- let debug = $t02715627257._3
645+ let $t02829628397 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
646+ let userBoostAvailable = $t02829628397._1
647+ let dataState = $t02829628397._2
648+ let debug = $t02829628397._3
618649 $Tuple2(nil, [userBoostAvailable, debug])
619650 }
620651
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
66 let SCALE8 = 8
77
88 let MULT8 = 100000000
99
1010 let POOLWEIGHTMULT = MULT8
1111
1212 func strf (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
1313
1414
1515 func ioz (address,key) = valueOrElse(getInteger(address, key), 0)
1616
1717
1818 func iod (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
1919
2020
2121 func iof (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
2222
2323
2424 func abs (val) = if ((0 > val))
2525 then -(val)
2626 else val
2727
2828
2929 func aal (val) = match val {
3030 case valAnyLyst: List[Any] =>
3131 valAnyLyst
3232 case _ =>
3333 throw("fail to cast into List[Any]")
3434 }
3535
3636
3737 func ai (val) = match val {
3838 case valInt: Int =>
3939 valInt
4040 case _ =>
4141 throw("fail to cast into Int")
4242 }
4343
44+
45+func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
46+
47+
48+let referralsContractAddressOrFail = addressFromStringValue(strf(this, keyReferralsContractAddress()))
49+
50+let keyReferralProgramName = makeString(["%s%s", "referral", "programName"], SEP)
51+
52+let referralProgramNameDefault = "wxlock"
53+
54+let referralProgramName = valueOrElse(getString(this, keyReferralProgramName), referralProgramNameDefault)
4455
4556 func keyFactoryAddress () = "%s%s__config__factoryAddress"
4657
4758
4859 let IdxFactoryCfgStakingDapp = 1
4960
5061 let IdxFactoryCfgBoostingDapp = 2
5162
5263 let IdxFactoryCfgIdoDapp = 3
5364
5465 let IdxFactoryCfgTeamDapp = 4
5566
5667 let IdxFactoryCfgEmissionDapp = 5
5768
5869 let IdxFactoryCfgRestDapp = 6
5970
6071 let IdxFactoryCfgSlippageDapp = 7
6172
6273 let IdxFactoryCfgDaoDapp = 8
6374
6475 let IdxFactoryCfgMarketingDapp = 9
6576
6677 let IdxFactoryCfgGwxRewardDapp = 10
6778
6879 let IdxFactoryCfgBirdsDapp = 11
6980
7081 func keyFactoryCfg () = "%s__factoryConfig"
7182
7283
7384 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
7485
7586
7687 func keyFactoryLpList () = "%s__lpTokensList"
7788
7889
7990 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
8091
8192
8293 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
8394
8495
8596 func keyFactoryPoolWeightHistory (poolAddress,num) = ((("%s%s__poolWeight__" + poolAddress) + "__") + toString(num))
8697
8798
8899 func readFactoryAddressOrFail () = addressFromStringValue(strf(this, keyFactoryAddress()))
89100
90101
91102 func readLpList () = split(valueOrElse(getString(readFactoryAddressOrFail(), keyFactoryLpList()), ""), SEP)
92103
93104
94105 func readFactoryCfgOrFail (factory) = split(strf(factory, keyFactoryCfg()), SEP)
95106
96107
97108 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
98109
99110
100111 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
101112
102113
103114 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
104115
105116
106117 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
107118
108119
109120 func keyManagerPublicKey () = "%s__managerPublicKey"
110121
111122
112123 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
113124
114125
115126 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
116127
117128
118129 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
119130
120131
121132 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
122133
123134
124135 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
125136
126137
127138 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
128139
129140
130141 func keyNextPeriod () = "%s__nextPeriod"
131142
132143
133144 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
134145
135146
136147 let IdxCfgAssetId = 1
137148
138149 let IdxCfgMinLockAmount = 2
139150
140151 let IdxCfgMinLockDuration = 3
141152
142153 let IdxCfgMaxLockDuration = 4
143154
144155 let IdxCfgMathContract = 5
145156
146157 func keyConfig () = "%s__config"
147158
148159
149160 func readConfigArrayOrFail () = split(strf(this, keyConfig()), SEP)
150161
151162
152163 func formatConfigS (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = makeString(["%s%d%d%d", assetId, minLockAmount, minLockDuration, maxLockDuration, mathContract], SEP)
153164
154165
155166 func formatConfig (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = formatConfigS(assetId, toString(minLockAmount), toString(minLockDuration), toString(maxLockDuration), mathContract)
156167
157168
158169 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
159170 case s: String =>
160171 fromBase58String(s)
161172 case _: Unit =>
162173 unit
163174 case _ =>
164175 throw("Match error")
165176 }
166177
167178
168179 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
169180 case s: String =>
170181 fromBase58String(s)
171182 case _: Unit =>
172183 unit
173184 case _ =>
174185 throw("Match error")
175186 }
176187
177188
178189 func mustManager (i) = {
179190 let pd = throw("Permission denied")
180191 match managerPublicKeyOrUnit() {
181192 case pk: ByteVector =>
182193 if ((i.callerPublicKey == pk))
183194 then true
184195 else pd
185196 case _: Unit =>
186197 if ((i.caller == this))
187198 then true
188199 else pd
189200 case _ =>
190201 throw("Match error")
191202 }
192203 }
193204
194205
195206 let IdxLockUserNum = 1
196207
197208 let IdxLockAmount = 2
198209
199210 let IdxLockStart = 3
200211
201212 let IdxLockDuration = 4
202213
203214 let IdxLockParamK = 5
204215
205216 let IdxLockParamB = 6
206217
207218 func keyLockParamsRecord (userAddress) = makeString(["%s%s__lock", userAddress], SEP)
208219
209220
210221 func readLockParamsRecordOrFail (userAddress) = split(strf(this, keyLockParamsRecord(userAddress)), SEP)
211222
212223
213224 func formatLockParamsRecordS (userNum,amount,start,duration,paramK,paramB,lastUpdTimestamp,gwxAmount) = makeString(["%d%d%d%d%d%d%d%d", userNum, amount, start, duration, paramK, paramB, lastUpdTimestamp, gwxAmount], SEP)
214225
215226
216227 func formatLockParamsRecord (userNum,amount,start,duration,paramK,paramB,gwxAmount) = formatLockParamsRecordS(userNum, toString(amount), toString(start), toString(duration), toString(paramK), toString(paramB), toString(lastBlock.timestamp), toString(gwxAmount))
217228
218229
219230 func keyNextUserNum () = "%s__nextUserNum"
220231
221232
222233 func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", userAddress], SEP)
223234
224235
225236 func keyNum2UserMapping (num) = makeString(["%s%s%s__mapping__num2user", num], SEP)
226237
227238
228239 func keyLockParamUserAmount (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "amount"], SEP)
229240
230241
231242 func keyLockParamStartBlock (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "start"], SEP)
232243
233244
234245 func keyLockParamDuration (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "duration"], SEP)
235246
236247
237248 func keyLockParamK (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "k"], SEP)
238249
239250
240251 func keyLockParamB (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "b"], SEP)
241252
242253
243254 func keyLockParamByPeriodK (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "k", period], SEP)
244255
245256
246257 func keyLockParamByPeriodB (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "b", period], SEP)
247258
248259
249260 func keyLockParamTotalAmount () = "%s%s__stats__activeTotalLocked"
250261
251262
252263 func keyStatsLocksDurationSumInBlocks () = "%s%s__stats__locksDurationSumInBlocks"
253264
254265
255266 func keyStatsLocksCount () = "%s%s__stats__locksCount"
256267
257268
258269 func keyStatsUsersCount () = "%s%s__stats__activeUsersCount"
259270
260271
261272 func keyUserBoostEmissionLastINTEGRAL (userNum) = makeString(["%s%d__userBoostEmissionLastInt", userNum], SEP)
262273
263274
264275 func keyUserLpBoostEmissionLastINTEGRAL (userNum,lpAssetId) = makeString(["%s%d__userBoostEmissionLastInt", userNum, lpAssetId], SEP)
265276
266277
267278 func keyUserMaxBoostINTEGRAL (userNum) = makeString(["%s%d__maxBoostInt", userNum], SEP)
268279
269280
270281 func keyTotalMaxBoostINTEGRAL () = "%s%s__maxBoostInt__total"
271282
272283
273284 func keyUserBoostAvalaibleToClaimTotal (userNum) = makeString(["%s%d__userBoostAvaliableToClaimTotal", userNum], SEP)
274285
275286
276287 func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", userNum], SEP)
277288
278289
279290 func keyTotalCachedGwx () = "%s%s__gwxCached__total"
280291
281292
282293 let factoryContract = readFactoryAddressOrFail()
283294
284295 let factoryCfg = readFactoryCfgOrFail(factoryContract)
285296
286297 let emissionContract = getEmissionAddressOrFail(factoryCfg)
287298
288299 let stakingContract = getStakingAddressOrFail(factoryCfg)
289300
290301 let gwxRewardContract = getGwxRewardAddressOrFail(factoryCfg)
291302
292303 func HistoryEntry (type,user,amount,lockStart,duration,k,b,i) = {
293304 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
294305 let historyDATA = makeString(["%d%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(amount), toString(lockStart), toString(duration), toString(k), toString(b)], SEP)
295306 StringEntry(historyKEY, historyDATA)
296307 }
297308
298309
299310 func StatsEntry (totalLockedInc,durationInc,lockCountInc,usersCountInc) = {
300311 let locksDurationSumInBlocksKEY = keyStatsLocksDurationSumInBlocks()
301312 let locksCountKEY = keyStatsLocksCount()
302313 let usersCountKEY = keyStatsUsersCount()
303314 let totalAmountKEY = keyLockParamTotalAmount()
304315 let locksDurationSumInBlocks = ioz(this, locksDurationSumInBlocksKEY)
305316 let locksCount = ioz(this, locksCountKEY)
306317 let usersCount = ioz(this, usersCountKEY)
307318 let totalAmount = ioz(this, totalAmountKEY)
308319 [IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
309320 }
310321
311322
312323 func calcGwxAmount (kRaw,bRaw,h) = {
313324 let SCALE = 1000
314325 (((kRaw * h) + bRaw) / SCALE)
315326 }
316327
317328
318329 func LockParamsEntry (userAddress,userNum,amount,start,duration,k,b,period) = {
319330 let userAmountKEY = keyLockParamUserAmount(userNum)
320331 let startBlockKEY = keyLockParamStartBlock(userNum)
321332 let durationKEY = keyLockParamDuration(userNum)
322333 let kKEY = keyLockParamK(userNum)
323334 let bKEY = keyLockParamB(userNum)
324335 let kByPeriodKEY = keyLockParamByPeriodK(userNum, period)
325336 let bByPeriodKEY = keyLockParamByPeriodB(userNum, period)
326337 let gwxAmount = calcGwxAmount(k, b, height)
327338 [IntegerEntry(userAmountKEY, amount), IntegerEntry(startBlockKEY, start), IntegerEntry(durationKEY, duration), IntegerEntry(kKEY, k), IntegerEntry(bKEY, b), IntegerEntry(kByPeriodKEY, k), IntegerEntry(bByPeriodKEY, b), StringEntry(keyLockParamsRecord(userAddress), formatLockParamsRecord(userNum, amount, start, duration, k, b, gwxAmount))]
328339 }
329340
330341
331342 func extractOptionalPaymentAmountOrFail (i,expectedAssetId) = if ((size(i.payments) > 1))
332343 then throw("only one payment is allowed")
333344 else if ((size(i.payments) == 0))
334345 then 0
335346 else {
336347 let pmt = i.payments[0]
337348 if ((value(pmt.assetId) != expectedAssetId))
338349 then throw("invalid asset id in payment")
339350 else pmt.amount
340351 }
341352
342353
343354 func calcUserGwxAmountAtHeight (userAddress,targetHeight) = {
344355 let EMPTY = "empty"
345356 let user2NumMappingKEY = keyUser2NumMapping(userAddress)
346357 let userNum = valueOrElse(getString(user2NumMappingKEY), EMPTY)
347358 let k = valueOrElse(getInteger(keyLockParamK(userNum)), 0)
348359 let b = valueOrElse(getInteger(keyLockParamB(userNum)), 0)
349360 let gwxAmountCalc = calcGwxAmount(k, b, targetHeight)
350361 let gwxAmount = if ((0 > gwxAmountCalc))
351362 then 0
352363 else gwxAmountCalc
353364 gwxAmount
354365 }
355366
356367
357368 func calcCurrentGwxAmount (userAddress) = calcUserGwxAmountAtHeight(userAddress, height)
358369
359370
360371 func internalClaimWxBoost (lpAssetIdStr,userAddressStr,readOnly) = {
361372 let EMPTY = "EMPTY"
362373 let userRecordOrEmpty = valueOrElse(getString(this, keyLockParamsRecord(userAddressStr)), EMPTY)
363374 if ((userRecordOrEmpty == EMPTY))
364375 then $Tuple3(0, nil, "userRecord::is::empty")
365376 else {
366377 let userRecordArray = split(userRecordOrEmpty, SEP)
367378 let userNumStr = userRecordArray[IdxLockUserNum]
368379 let gwxRewardEmissionStartHeight = valueOrElse(getInteger(gwxRewardContract, keyGwxRewardEmissionStartHeight()), 0)
369380 let EMPTYSTR = "empty"
370- let $t01316713735 = if ((lpAssetIdStr != EMPTYSTR))
381+ let $t01387014438 = if ((lpAssetIdStr != EMPTYSTR))
371382 then {
372383 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
373384 let pw1 = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
374385 let pw0 = valueOrElse(getInteger(factoryContract, keyFactoryPoolWeightHistory(poolAddressStr, 0)), pw1)
375386 $Tuple2(pw0, pw1)
376387 }
377388 else if (readOnly)
378389 then $Tuple2(0, 0)
379390 else throw(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
380- let poolWeight0 = $t01316713735._1
381- let poolWeight1 = $t01316713735._2
391+ let poolWeight0 = $t01387014438._1
392+ let poolWeight1 = $t01387014438._2
382393 let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
383394 let emissionStart = iof(emissionContract, keyEmissionStartBlock())
384395 let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
385396 let h = if ((height > emissionEnd))
386397 then emissionEnd
387398 else height
388399 let dh = max([(h - emissionStart), 0])
389400 let userLpBoostEmissionLastIntegralKEY = keyUserLpBoostEmissionLastINTEGRAL(userNumStr, lpAssetIdStr)
390401 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
391402 let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), ioz(this, userBoostEmissionLastIntegralKEY))
392403 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
393404 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
394405 let udh = fraction(userBoostEmissionIntegral, 3, (2 * wxEmissionPerBlock))
395406 let uLastH = (h - udh)
396407 let udh0 = max([(gwxRewardEmissionStartHeight - uLastH), 0])
397408 let udh1 = ((h - uLastH) - udh0)
398409 if (if (if ((0 > uLastH))
399410 then true
400411 else (0 > udh1))
401412 then true
402413 else (abs(((udh0 + udh1) - udh)) >= 1))
403414 then throw(((((((("invalid udh calc: udh=" + toString(udh)) + " uLastH=") + toString(uLastH)) + " udh0=") + toString(udh0)) + " udh1=") + toString(udh1)))
404415 else if ((0 > userBoostEmissionIntegral))
405416 then throw("wrong calculations")
406417 else {
407418 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
408419 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
409420 let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
410421 let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
411422 let totalCachedGwxKEY = keyTotalCachedGwx()
412423 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
413424 let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
414425 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
415426 let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
416427 let userBoostEmissionIntegral0 = if ((udh == 0))
417428 then 0
418429 else fraction(userBoostEmissionIntegral, udh0, udh)
419430 let userBoostEmissionIntegral1 = if ((udh == 0))
420431 then 0
421432 else fraction(userBoostEmissionIntegral, udh1, udh)
422433 let poolUserBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral0, poolWeight0, POOLWEIGHTMULT)
423434 let poolUserBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral1, poolWeight1, POOLWEIGHTMULT)
424435 let userBoostAvaliableToClaimTotalNew0 = if ((totalCachedGwx == 0))
425436 then 0
426437 else fraction(poolUserBoostEmissionIntegral0, userCurrGwx, totalCachedGwx)
427438 let userBoostAvaliableToClaimTotalNew1 = if ((totalCachedGwx == 0))
428439 then 0
429440 else fraction(poolUserBoostEmissionIntegral1, userCurrGwx, totalCachedGwx)
430441 let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotalNew0 + userBoostAvaliableToClaimTotalNew1)
431442 let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
432443 let userBoostClaimed = ioz(this, userBoostClaimedKEY)
433444 let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
434445 let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
435446 let debug = makeString([toString(userBoostEmissionLastIntegral), toString(userBoostEmissionIntegral), toString(userBoostClaimed), toString(userBoostAvailable), toString(poolWeight0), toString(poolWeight1), toString(h), toString(udh), toString(uLastH), toString(udh0), toString(udh1), toString(userCurrGwx), toString(totalCachedGwx)], ":")
436447 $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
437448 }
438449 }
439450 }
440451
441452
442453 @Callable(i)
443454 func constructor (factoryAddressStr,lockAssetIdStr,minLockAmount,minDuration,maxDuration,mathContract) = {
444455 let checkCaller = mustManager(i)
445456 if ((checkCaller == checkCaller))
446457 then ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
458+ else throw("Strict value is not equal to itself.")
459+ }
460+
461+
462+
463+@Callable(i)
464+func lockRef (duration,referrerAddress,signature) = {
465+ let lockInv = invoke(this, "lock", [duration], i.payments)
466+ if ((lockInv == lockInv))
467+ then {
468+ let referralAddress = toString(i.caller)
469+ let refInv = if (if ((referrerAddress == ""))
470+ then true
471+ else (signature == base58''))
472+ then unit
473+ else invoke(referralsContractAddressOrFail, "createPair", [referralProgramName, referrerAddress, referralAddress, signature], nil)
474+ if ((refInv == refInv))
475+ then $Tuple2(nil, unit)
476+ else throw("Strict value is not equal to itself.")
477+ }
447478 else throw("Strict value is not equal to itself.")
448479 }
449480
450481
451482
452483 @Callable(i)
453484 func lock (duration) = {
454485 let cfgArray = readConfigArrayOrFail()
455486 let assetIdStr = cfgArray[IdxCfgAssetId]
456487 let assetId = fromBase58String(assetIdStr)
457488 let minLockAmount = parseIntValue(cfgArray[IdxCfgMinLockAmount])
458489 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
459490 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
460491 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
461492 if ((size(i.payments) != 1))
462493 then throw("invalid payment - exact one payment must be attached")
463494 else {
464495 let pmt = i.payments[0]
465496 let pmtAmount = pmt.amount
466497 if ((assetId != value(pmt.assetId)))
467498 then throw((("invalid asset is in payment - " + assetIdStr) + " is expected"))
468499 else {
469500 let nextUserNumKEY = keyNextUserNum()
470501 let userAddressStr = toString(i.caller)
471502 let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
472503 let userNumStr = if (userIsExisting)
473504 then value(getString(keyUser2NumMapping(userAddressStr)))
474505 else toString(iof(this, nextUserNumKEY))
475506 let userNum = parseIntValue(userNumStr)
476507 let lockStart = height
477508 let startBlockKEY = keyLockParamStartBlock(userNumStr)
478509 let durationKEY = keyLockParamDuration(userNumStr)
479510 let userAmountKEY = keyLockParamUserAmount(userNumStr)
480511 if ((minLockAmount > pmtAmount))
481512 then throw(("amount is less then minLockAmount=" + toString(minLockAmount)))
482513 else if ((minLockDuration > duration))
483514 then throw(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
484515 else if ((duration > maxLockDuration))
485516 then throw(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
486517 else if (if (userIsExisting)
487518 then ((iof(this, startBlockKEY) + iof(this, durationKEY)) >= lockStart)
488519 else false)
489520 then throw("there is an active lock - consider to use increaseLock")
490521 else if ((ioz(this, userAmountKEY) > 0))
491522 then throw(("there are locked WXs - consider to use increaseLock " + userAmountKEY))
492523 else {
493524 let coeffX8 = fraction(duration, MULT8, maxLockDuration)
494525 let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
495526 let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
496527 let k = ai(gWxParamsResultList[0])
497528 let b = ai(gWxParamsResultList[1])
498529 let period = toString(ai(gWxParamsResultList[2]))
499530 let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
500531 let emissionStart = iof(emissionContract, keyEmissionStartBlock())
501532 let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
502533 let h = if ((height > emissionEnd))
503534 then emissionEnd
504535 else height
505536 let dh = max([(h - emissionStart), 0])
506537 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
507538 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
508539 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
509540 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
510541 let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
511542 let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
512543 let totalCachedGwxKEY = keyTotalCachedGwx()
513544 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
514545 let arr = if (userIsExisting)
515546 then nil
516547 else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
517548 ((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
518549 then 0
519550 else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gWxAmountStart))])
520551 }
521552 }
522553 }
523554 }
524555
525556
526557
527558 @Callable(i)
528559 func increaseLock (deltaDuration) = {
529560 let cfgArray = readConfigArrayOrFail()
530561 let assetIdStr = cfgArray[IdxCfgAssetId]
531562 let assetId = fromBase58String(assetIdStr)
532563 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
533564 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
534565 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
535566 let pmtAmount = extractOptionalPaymentAmountOrFail(i, assetId)
536567 let userAddressStr = toString(i.caller)
537568 let userRecordArray = readLockParamsRecordOrFail(userAddressStr)
538569 let userNumStr = userRecordArray[IdxLockUserNum]
539570 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
540571 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
541572 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
542573 let lockEnd = (lockStart + lockDuration)
543574 let remainingDuration = max([(lockEnd - height), 0])
544575 let userAmountNew = (userAmount + pmtAmount)
545576 let lockDurationNew = (remainingDuration + deltaDuration)
546577 if ((0 > deltaDuration))
547578 then throw("duration is less then zero")
548579 else if ((minLockDuration > lockDurationNew))
549580 then throw(("lockDurationNew is less then minLockDuration=" + toString(minLockDuration)))
550581 else if ((lockDurationNew > maxLockDuration))
551582 then throw(("deltaDuration + existedLockDuration is greater then maxLockDuration=" + toString(maxLockDuration)))
552583 else {
553584 let coeffX8 = fraction(lockDurationNew, MULT8, maxLockDuration)
554585 let gWxAmountStart = fraction(userAmountNew, coeffX8, MULT8)
555586 let lockStartNew = height
556587 let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStartNew, lockDurationNew], nil))
557588 let k = ai(gWxParamsResultList[0])
558589 let b = ai(gWxParamsResultList[1])
559590 let period = toString(ai(gWxParamsResultList[2]))
560591 let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
561592 let emissionStart = iof(emissionContract, keyEmissionStartBlock())
562593 let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
563594 let h = if ((height > emissionEnd))
564595 then emissionEnd
565596 else height
566597 let dh = max([(h - emissionStart), 0])
567598 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
568599 let userBoostEmissionLastIntegral = ioz(this, userBoostEmissionLastIntegralKEY)
569600 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
570601 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
571602 if ((0 > userBoostEmissionIntegral))
572603 then throw("wrong calculations")
573604 else {
574605 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
575606 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
576607 let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
577608 let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
578609 let currUserGwx = calcCurrentGwxAmount(userAddressStr)
579610 let gwxDiff = (gWxAmountStart - currUserGwx)
580611 if ((0 > gwxDiff))
581612 then throw(("gwxDiff is less then 0: " + toString(gwxDiff)))
582613 else {
583614 let totalCachedGwxKEY = keyTotalCachedGwx()
584615 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
585616 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
586617 let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
587618 let userBoostAvaliableToClaimTotalNew = fraction(userBoostEmissionIntegral, currUserGwx, totalCachedGwx)
588619 let userMaxBoostIntNew = ((gWxAmountStart * lockDurationNew) / 2)
589620 let remainingUserMaxBoostInt = ((currUserGwx * remainingDuration) / 2)
590621 let userMaxBoostIntDiff = (userMaxBoostIntNew - remainingUserMaxBoostInt)
591622 (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStartNew, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gwxDiff))])
592623 }
593624 }
594625 }
595626 }
596627
597628
598629
599630 @Callable(i)
600631 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
601632 then throw("permissions denied")
602633 else {
603- let $t02692227024 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
604- let userBoostAvailable = $t02692227024._1
605- let dataState = $t02692227024._2
606- let debug = $t02692227024._3
634+ let $t02806228164 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
635+ let userBoostAvailable = $t02806228164._1
636+ let dataState = $t02806228164._2
637+ let debug = $t02806228164._3
607638 $Tuple2(dataState, [userBoostAvailable])
608639 }
609640
610641
611642
612643 @Callable(i)
613644 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
614- let $t02715627257 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
615- let userBoostAvailable = $t02715627257._1
616- let dataState = $t02715627257._2
617- let debug = $t02715627257._3
645+ let $t02829628397 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
646+ let userBoostAvailable = $t02829628397._1
647+ let dataState = $t02829628397._2
648+ let debug = $t02829628397._3
618649 $Tuple2(nil, [userBoostAvailable, debug])
619650 }
620651
621652
622653
623654 @Callable(i)
624655 func unlock (userAddress) = {
625656 let userRecordArray = readLockParamsRecordOrFail(userAddress)
626657 let userNumStr = userRecordArray[IdxLockUserNum]
627658 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
628659 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
629660 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
630661 let lockEnd = (lockStart + lockDuration)
631662 let cfgArray = readConfigArrayOrFail()
632663 let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
633664 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
634665 if ((lockEnd >= height))
635666 then throw((("wait " + toString(lockEnd)) + " to unlock"))
636667 else if ((0 >= userAmount))
637668 then throw("nothing to unlock")
638669 else {
639670 let period = valueOrElse(getInteger(mathContract, keyNextPeriod()), 0)
640671 (((LockParamsEntry(userAddress, userNumStr, 0, lockStart, lockDuration, 0, 0, toString(period)) ++ StatsEntry(-(userAmount), 0, 0, -1)) :+ HistoryEntry("unlock", userAddress, userAmount, lockStart, lockDuration, 0, 0, i)) :+ ScriptTransfer(addressFromStringValue(userAddress), userAmount, assetId))
641672 }
642673 }
643674
644675
645676
646677 @Callable(i)
647678 func gwxUserInfoREADONLY (userAddress) = {
648679 let gwxAmount = calcCurrentGwxAmount(userAddress)
649680 $Tuple2(nil, [gwxAmount])
650681 }
651682
652683
653684
654685 @Callable(i)
655686 func getUserGwxAmountAtHeightREADONLY (userAddress,targetHeight) = {
656687 let gwxAmount = calcUserGwxAmountAtHeight(userAddress, targetHeight)
657688 $Tuple2(nil, gwxAmount)
658689 }
659690
660691
661692
662693 @Callable(i)
663694 func setManager (pendingManagerPublicKey) = {
664695 let checkCaller = mustManager(i)
665696 if ((checkCaller == checkCaller))
666697 then {
667698 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
668699 if ((checkManagerPublicKey == checkManagerPublicKey))
669700 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
670701 else throw("Strict value is not equal to itself.")
671702 }
672703 else throw("Strict value is not equal to itself.")
673704 }
674705
675706
676707
677708 @Callable(i)
678709 func confirmManager () = {
679710 let pm = pendingManagerPublicKeyOrUnit()
680711 let hasPM = if (isDefined(pm))
681712 then true
682713 else throw("No pending manager")
683714 if ((hasPM == hasPM))
684715 then {
685716 let checkPM = if ((i.callerPublicKey == value(pm)))
686717 then true
687718 else throw("You are not pending manager")
688719 if ((checkPM == checkPM))
689720 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
690721 else throw("Strict value is not equal to itself.")
691722 }
692723 else throw("Strict value is not equal to itself.")
693724 }
694725
695726
696727 @Verifier(tx)
697728 func verify () = {
698729 let targetPublicKey = match managerPublicKeyOrUnit() {
699730 case pk: ByteVector =>
700731 pk
701732 case _: Unit =>
702733 tx.senderPublicKey
703734 case _ =>
704735 throw("Match error")
705736 }
706737 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
707738 }
708739

github/deemru/w8io/026f985 
84.95 ms