tx · GNhYbVZ9ACMchHwkqDAmgLKWwyachspSErHvicN71k6n 3N3UHNYQ8xwe2WWLKgXX628JyUtF6kYK4wS: -0.01000000 Waves 2020.09.28 12:27 [1196990] smart account 3N3UHNYQ8xwe2WWLKgXX628JyUtF6kYK4wS > SELF 0.00000000 Waves
{ "type": 13, "id": "GNhYbVZ9ACMchHwkqDAmgLKWwyachspSErHvicN71k6n", "fee": 1000000, "feeAssetId": null, "timestamp": 1601285260478, "version": 1, "sender": "3N3UHNYQ8xwe2WWLKgXX628JyUtF6kYK4wS", "senderPublicKey": "Hxyif8HnnHh34SZ7PZewDcNUgrZfHNJsQvLNCcPbCW27", "proofs": [ "zAQzf4qJaMRpjPBSgE8TYcFoFLpZF6tQnF6t2fbD9M6TdL7RL9M5AXRx8KNaKi73NNaB7f57AYDEW39KPcX8aRP" ], "script": "base64:AAIEAAAAAAAAADUIAhIKCggICAEIAQEICBIQCg4ICAEIAQgBAQEBAQEBARIDCgEIEgMKAQgSBAoCCAESAwoBCAAAAFcBAAAAFmNvbnZlcnRKc29uQXJyYXlUb0xpc3QAAAACAAAACWpzb25BcnJheQAAAAtzcGxpdFN5bWJvbAkABLUAAAACBQAAAAlqc29uQXJyYXkFAAAAC3NwbGl0U3ltYm9sAQAAABhnZXRTdHJpbmdCeUFkZHJlc3NBbmRLZXkAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAAB2FkZHJlc3MFAAAAA2tleQIAAAAAAQAAAAxnZXRCb29sQnlLZXkAAAABAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBsAAAACBQAAAAR0aGlzBQAAAANrZXkHAAAAAAxrZXlBc3NldENvZGUAAAAAAAAAAAEAAAAACmtleUFzc2V0SWQAAAAAAAAAAAIAAAAADmtleUFzc2V0U3RhdHVzAAAAAAAAAAADAAAAABVrZXlBc3NldFByaWNlRGVjaW1hbHMAAAAAAAAAAAQAAAAAE2tleUFzc2V0QmFraW5nQXNzZXQAAAAAAAAAAAUAAAAAG2tleU92ZXJjb2xsYXRlcmFsUGVyY2VudGFnZQAAAAAAAAAABgAAAAAKa2V5TWluUG9vbAAAAAAAAAAABwAAAAAVa2V5UHJpY2VPcmFjbGVBZGRyZXNzAAAAAAAAAAAIAAAAABBrZXlNaW5CdXlQYXltZW50AAAAAAAAAAAJAAAAABFrZXlNaW5TZWxsUGF5bWVudAAAAAAAAAAACgAAAAASa2V5QnV5TG9ja0ludGVydmFsAAAAAAAAAAALAAAAABNrZXlTZWxsTG9ja0ludGVydmFsAAAAAAAAAAAMAAAAAAlrZXlCdXlGZWUAAAAAAAAAAA0AAAAACmtleVNlbGxGZWUAAAAAAAAAAA4AAAAAGGtleVBvb2xSZWRlbXB0aW9uVGltZW91dAAAAAAAAAAADwAAAAAOYWRtaW5QdWJsaWNLZXkCAAAALEcxRWJ1NUFNSGFUSkZFYlpOa1pRY0pGVVE5S2ZpWVV3dXB5TEc4NTdEY0ZyAAAAABpuZXV0cmlub0NvbnRyYWN0QWRkcmVzc0tleQIAAAArJXMlc19fY29tbW9uQ29uZmlnX19uZXV0cmlub0NvbnRyYWN0QWRkcmVzcwAAAAAZbmV1dHJpbm9TdGFraW5nQWRkcmVzc0tleQIAAAAqJXMlc19fY29tbW9uQ29uZmlnX19uZXV0cmlub1N0YWtpbmdBZGRyZXNzAAAAABttaW5pbXVuUG9vbEZ1bmRpbmdBbW91bnRLZXkCAAAALCVzJXNfX2NvbW1vbkNvbmZpZ19fbWluaW11bVBvb2xGdW5kaW5nQW1vdW50AAAAABBpc0luaXRpYWxpemVkS2V5AgAAAB8lcyVzX19jb21tb25Db25maWdfX2luaXRpYWxpemVkAAAAABRjdXJyZW50QXNzZXRJbmRleEtleQIAAAAvJXMlc19fY29tbW9uQ29uZmlnX19wcmVkZWZpbmVkQXNzZXRzQWN0aXZlSW5kZXgAAAAAFGFzc2V0c0FkZHJlc3NMaXN0S2V5AgAAACglcyVzX19jb21tb25Db25maWdfX3ByZWRlZmluZWRBc3NldHNMaXN0AAAAAA5kZWJ0VG9rZW5JZEtleQIAAAAfJXMlc19fY29tbW9uQ29uZmlnX19kZWJ0QXNzZXRJZAAAAAAZZGVidFRva2VuRXRhbG9uQmFsYW5jZUtleQIAAAAqJXMlc19fY29tbW9uQ29uZmlnX19kZWJ0QXNzZXRFdGFsb25CYWxhbmNlAAAAABVkZWZvU3Rha2luZ0FkZHJlc3NLZXkCAAAAJiVzJXNfX2NvbW1vbkNvbmZpZ19fZGVmb1N0YWtpbmdBZGRyZXNzAAAAABpkZWZvU3Rha2luZ1BhY2VtYWtlclB1YktleQIAAAArJXMlc19fY29tbW9uQ29uZmlnX19kZWZvU3Rha2luZ1BhY2VtYWtlclB1YgAAAAASbmV1dHJpbm9Bc3NldElkS2V5AgAAABFuZXV0cmlub19hc3NldF9pZAAAAAAObnNidEFzc2V0SWRLZXkCAAAADWJvbmRfYXNzZXRfaWQAAAAADmRlZm9Bc3NldElkS2V5AgAAAA8lc19fZGVmb0Fzc2V0SWQAAAAAFXNldEFzc2V0U2NyaXB0VHhJZEtleQIAAAATJXNfX2Fzc2V0U2NyaXB0VHhJZAEAAAARZ2V0QXNzZXRDb25maWdLZXkAAAABAAAADGFzc2V0QWRkcmVzcwkAASwAAAACCQABLAAAAAICAAAAEyVzJXMlc19fZGVmb0Fzc2V0X18FAAAADGFzc2V0QWRkcmVzcwIAAAAIX19jb25maWcBAAAAEGdldEFzc2V0UHJpY2VLZXkAAAABAAAACWFzc2V0Q29kZQkAASwAAAACAgAAABIlcyVzX19hc3NldFByaWNlX18FAAAACWFzc2V0Q29kZQEAAAAVZ2V0QXNzZXRJbml0SGVpZ2h0S2V5AAAAAQAAAAxhc3NldEFkZHJlc3MJAAEsAAAAAgkAASwAAAACAgAAABMlcyVzJXNfX2RlZm9Bc3NldF9fBQAAAAxhc3NldEFkZHJlc3MCAAAADF9faW5pdEhlaWdodAEAAAAZZ2V0QXNzZXRBY3RpdmF0ZUhlaWdodEtleQAAAAEAAAAMYXNzZXRBZGRyZXNzCQABLAAAAAIJAAEsAAAAAgIAAAATJXMlcyVzX19kZWZvQXNzZXRfXwUAAAAMYXNzZXRBZGRyZXNzAgAAABBfX2FjdGl2YXRlSGVpZ2h0AQAAAB1nZXRBc3NldEN1cnJyZW50UG9vbEFtb3VudEtleQAAAAEAAAAMYXNzZXRBZGRyZXNzCQABLAAAAAIJAAEsAAAAAgIAAAATJXMlcyVzX19kZWZvQXNzZXRfXwUAAAAMYXNzZXRBZGRyZXNzAgAAAA1fX2N1cnJlbnRQb29sAQAAABhnZXRBc3NldE1heFBvb2xBbW91bnRLZXkAAAABAAAADGFzc2V0QWRkcmVzcwkAASwAAAACCQABLAAAAAICAAAAEyVzJXMlc19fZGVmb0Fzc2V0X18FAAAADGFzc2V0QWRkcmVzcwIAAAAJX19tYXhQb29sAQAAAA9nZXRBc3NldE1ldGFLZXkAAAABAAAADGFzc2V0QWRkcmVzcwkAASwAAAACCQABLAAAAAICAAAAEyVzJXMlc19fZGVmb0Fzc2V0X18FAAAADGFzc2V0QWRkcmVzcwIAAAAGX19tZXRhAQAAABVnZXRBc3NldFBvb2xNYWtlcnNLZXkAAAABAAAADGFzc2V0QWRkcmVzcwkAASwAAAACCQABLAAAAAICAAAAEyVzJXMlc19fZGVmb0Fzc2V0X18FAAAADGFzc2V0QWRkcmVzcwIAAAAMX19wb29sTWFrZXJzAQAAABhnZXRBc3NldEFkZHJlc3NCeUNvZGVLZXkAAAABAAAACWFzc2V0Q29kZQkAASwAAAACCQABLAAAAAICAAAAEyVzJXMlc19fZGVmb0Fzc2V0X18FAAAACWFzc2V0Q29kZQIAAAAUX19hZGRyZXNzQnlBc3NldENvZGUBAAAAG2dldEFzc2V0QWRkcmVzc0J5QXNzZXRJZEtleQAAAAEAAAAHYXNzZXRJZAkAASwAAAACCQABLAAAAAICAAAAEyVzJXMlc19fZGVmb0Fzc2V0X18FAAAAB2Fzc2V0SWQCAAAAEl9fYWRkcmVzc0J5QXNzZXRJZAEAAAAiZ2V0UG9vbE1ha2VyUGFydGljaXBhdGlvbkFtb3VudEtleQAAAAIAAAAMYXNzZXRBZGRyZXNzAAAAEHBvb2xNYWtlckFkZHJlc3MJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAQJXMlcyVzJXNfX3Bvb2xfXwUAAAAMYXNzZXRBZGRyZXNzAgAAAAJfXwUAAAAQcG9vbE1ha2VyQWRkcmVzcwIAAAAIX19hbW91bnQBAAAAJWdldFBvb2xNYWtlclBhcnRpY2lwYXRpb25NYXhBbW91bnRLZXkAAAACAAAADGFzc2V0QWRkcmVzcwAAABBwb29sTWFrZXJBZGRyZXNzCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAECVzJXMlcyVzX19wb29sX18FAAAADGFzc2V0QWRkcmVzcwIAAAACX18FAAAAEHBvb2xNYWtlckFkZHJlc3MCAAAAC19fbWF4QW1vdW50AQAAABtnZXRQb29sTWFrZXJMb2NrZWRBbW91bnRLZXkAAAACAAAADGFzc2V0QWRkcmVzcwAAABBwb29sTWFrZXJBZGRyZXNzCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAECVzJXMlcyVzX19wb29sX18FAAAADGFzc2V0QWRkcmVzcwIAAAACX18FAAAAEHBvb2xNYWtlckFkZHJlc3MCAAAADl9fbG9ja2VkQW1vdW50AQAAABtnZXRQb29sTWFrZXJVbmxvY2tIZWlnaHRLZXkAAAACAAAADGFzc2V0QWRkcmVzcwAAABBwb29sTWFrZXJBZGRyZXNzCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAECVzJXMlcyVzX19wb29sX18FAAAADGFzc2V0QWRkcmVzcwIAAAACX18FAAAAEHBvb2xNYWtlckFkZHJlc3MCAAAADl9fdW5sb2NrSGVpZ2h0AQAAABNnZXRBc3NldENvbmZpZ0FycmF5AAAAAQAAAAxhc3NldEFkZHJlc3MJAQAAABZjb252ZXJ0SnNvbkFycmF5VG9MaXN0AAAAAgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQEAAAAYZ2V0U3RyaW5nQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAEdGhpcwkBAAAAEWdldEFzc2V0Q29uZmlnS2V5AAAAAQUAAAAMYXNzZXRBZGRyZXNzCQABLAAAAAIJAAEsAAAAAgIAAAAOTm8gREVGTyBBc3NldCAFAAAADGFzc2V0QWRkcmVzcwIAAAAOY29uZmlnIHByZXNlbnQCAAAAAl9fAAAAABBuZXV0cmlub0NvbnRyYWN0CQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAabmV1dHJpbm9Db250cmFjdEFkZHJlc3NLZXkCAAAAH05vIG5ldXRyaW5vIGNvbnRyYWN0IHNwZWNpZmllZC4AAAAAD25ldXRyaW5vQXNzZXRJZAkAAlkAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAQbmV1dHJpbm9Db250cmFjdAUAAAASbmV1dHJpbm9Bc3NldElkS2V5AgAAABdObyBVU0ROIGFzc2V0IGlkIGZvdW5kLgAAAAALbnNidEFzc2V0SWQJAAJZAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAAEG5ldXRyaW5vQ29udHJhY3QFAAAADm5zYnRBc3NldElkS2V5AgAAABZObyBOU0JUIGFzc2V0IGlkIGZvdW5kAAAAABJtaW5pbXVtUG9vbEZ1bmRpbmcJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABttaW5pbXVuUG9vbEZ1bmRpbmdBbW91bnRLZXkCAAAALU1pbmltdW0gcG9vbCBmdW5kaW5nIGFtb3VudCBpcyBub3Qgc3BlY2lmaWVkLgAAAAALYXNzZXRTdGF0dXMJAAUVAAAAAwIAAAAIUFJPUE9TRUQCAAAABVJFQURZAgAAAAZJU1NVRUQAAAAAGHByZWRlZmluZWRBc3NldENvbnRyYWN0cwkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAFGFzc2V0c0FkZHJlc3NMaXN0S2V5AgAAAC1ObyBwb29sIG9mIHByZWRlcGxveWVkIGFzc2V0IGNvbnRyYWN0cyBmb3VuZC4AAAAAFHByZWRlZmluZWRBc3NldHNMaXN0CQEAAAAWY29udmVydEpzb25BcnJheVRvTGlzdAAAAAIFAAAAGHByZWRlZmluZWRBc3NldENvbnRyYWN0cwIAAAABLAAAAAARY3VycmVudEFzc2V0SW5kZXgJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAUY3VycmVudEFzc2V0SW5kZXhLZXkAAAAAAAAAAAAAAAAACWRlYnRUb2tlbgkAAlkAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAOZGVidFRva2VuSWRLZXkCAAAAE05vIGRlYnQgdG9rZW4gZm91bmQAAAAADW11bHRpcGxpY2F0b3IAAAAAAAAPQkAAAAAAFmRlYnRUb2tlblJlaXNzdWVBbW91bnQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAZZGVidFRva2VuRXRhbG9uQmFsYW5jZUtleQAAAAAAAAAAAAEAAAAVZ2V0QXNzZXRBZGRyZXNzQnlDb2RlAAAAAQAAAAthc3NldFN5bWJvbAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAAR0aGlzCQEAAAAYZ2V0QXNzZXRBZGRyZXNzQnlDb2RlS2V5AAAAAQUAAAALYXNzZXRTeW1ib2wCAAAAAAEAAAAMZ2V0QXNzZXRDb2RlAAAAAQAAAAthc3NldENvbmZpZwkAAZEAAAACBQAAAAthc3NldENvbmZpZwUAAAAMa2V5QXNzZXRDb2RlAQAAAApnZXRBc3NldElEAAAAAQAAAAthc3NldENvbmZpZwkAAZEAAAACBQAAAAthc3NldENvbmZpZwUAAAAKa2V5QXNzZXRJZAEAAAAOZ2V0QXNzZXRTdGF0dXMAAAABAAAAC2Fzc2V0Q29uZmlnCQABkQAAAAIFAAAAC2Fzc2V0Q29uZmlnBQAAAA5rZXlBc3NldFN0YXR1cwEAAAAVZ2V0QXNzZXRQcmljZURlY2ltYWxzAAAAAQAAAAthc3NldENvbmZpZwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAC2Fzc2V0Q29uZmlnBQAAABVrZXlBc3NldFByaWNlRGVjaW1hbHMBAAAAFWdldEFzc2V0QmFraW5nQXNzZXRJZAAAAAEAAAALYXNzZXRDb25maWcJAAGRAAAAAgUAAAALYXNzZXRDb25maWcFAAAAE2tleUFzc2V0QmFraW5nQXNzZXQBAAAAHWdldEFzc2V0T3ZlckNvbGxhdGVyYWxQZXJjZW50AAAAAQAAAAthc3NldENvbmZpZwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAC2Fzc2V0Q29uZmlnBQAAABtrZXlPdmVyY29sbGF0ZXJhbFBlcmNlbnRhZ2UBAAAAHWdldEFzc2V0TWluUmVxdWlyZWRQb29sQW1vdW50AAAAAQAAAAthc3NldENvbmZpZwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAC2Fzc2V0Q29uZmlnBQAAAAprZXlNaW5Qb29sAQAAABpnZXRBc3NldFByaWNlT3JhY2xlQWRkcmVzcwAAAAEAAAALYXNzZXRDb25maWcJAAGRAAAAAgUAAAALYXNzZXRDb25maWcFAAAAFWtleVByaWNlT3JhY2xlQWRkcmVzcwEAAAAYZ2V0TWluQnV5UGF5bWVudFBlckFzc2V0AAAAAQAAAAthc3NldENvbmZpZwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAC2Fzc2V0Q29uZmlnBQAAABBrZXlNaW5CdXlQYXltZW50AQAAABlnZXRNaW5TZWxsUGF5bWVudFBlckFzc2V0AAAAAQAAAAthc3NldENvbmZpZwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAC2Fzc2V0Q29uZmlnBQAAABFrZXlNaW5TZWxsUGF5bWVudAEAAAAaZ2V0QnV5TG9ja0ludGVydmFsUGVyQXNzZXQAAAABAAAAC2Fzc2V0Q29uZmlnCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAALYXNzZXRDb25maWcFAAAAEmtleUJ1eUxvY2tJbnRlcnZhbAEAAAAbZ2V0U2VsbExvY2tJbnRlcnZhbFBlckFzc2V0AAAAAQAAAAthc3NldENvbmZpZwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAC2Fzc2V0Q29uZmlnBQAAABNrZXlTZWxsTG9ja0ludGVydmFsAQAAABFnZXRCdXlGZWVQZXJBc3NldAAAAAEAAAALYXNzZXRDb25maWcJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAthc3NldENvbmZpZwUAAAAJa2V5QnV5RmVlAQAAABJnZXRTZWxsRmVlUGVyQXNzZXQAAAABAAAAC2Fzc2V0Q29uZmlnCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAALYXNzZXRDb25maWcFAAAACmtleVNlbGxGZWUBAAAAGmdldFJlZGVtcHRpb25UaW1lb3V0QmxvY2tzAAAAAQAAAAthc3NldENvbmZpZwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAC2Fzc2V0Q29uZmlnBQAAABhrZXlQb29sUmVkZW1wdGlvblRpbWVvdXQBAAAAEmdldEFzc2V0UG9vbE1ha2VycwAAAAEAAAAMYXNzZXRBZGRyZXNzCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMJAQAAABVnZXRBc3NldFBvb2xNYWtlcnNLZXkAAAABBQAAAAxhc3NldEFkZHJlc3MCAAAAAAEAAAASZ2V0QXNzZXRJbml0SGVpZ2h0AAAAAQAAAAxhc3NldEFkZHJlc3MJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkBAAAAFWdldEFzc2V0SW5pdEhlaWdodEtleQAAAAEFAAAADGFzc2V0QWRkcmVzcwAAAAAAAAAAAAEAAAAWZ2V0QXNzZXRBY3RpdmF0ZUhlaWdodAAAAAEAAAAMYXNzZXRBZGRyZXNzCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABlnZXRBc3NldEFjdGl2YXRlSGVpZ2h0S2V5AAAAAQUAAAAMYXNzZXRBZGRyZXNzAAAAAAAAAAAAAQAAABlnZXRBc3NldEN1cnJlbnRQb29sQW1vdW50AAAAAQAAAAxhc3NldEFkZHJlc3MJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkBAAAAHWdldEFzc2V0Q3VycnJlbnRQb29sQW1vdW50S2V5AAAAAQUAAAAMYXNzZXRBZGRyZXNzAAAAAAAAAAAAAQAAABVnZXRBc3NldE1heFBvb2xBbW91bnQAAAABAAAADGFzc2V0QWRkcmVzcwkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAYZ2V0QXNzZXRNYXhQb29sQW1vdW50S2V5AAAAAQUAAAAMYXNzZXRBZGRyZXNzAAAAAAAAAAAAAQAAAAxnZXRBc3NldE1ldGEAAAABAAAADGFzc2V0QWRkcmVzcwkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAAR0aGlzCQEAAAAPZ2V0QXNzZXRNZXRhS2V5AAAAAQUAAAAMYXNzZXRBZGRyZXNzAgAAAAABAAAAH2dldFBvb2xNYWtlclBhcnRpY2lwYXRpb25BbW91bnQAAAACAAAADGFzc2V0QWRkcmVzcwAAABBwb29sTWFrZXJBZGRyZXNzCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAACJnZXRQb29sTWFrZXJQYXJ0aWNpcGF0aW9uQW1vdW50S2V5AAAAAgUAAAAMYXNzZXRBZGRyZXNzBQAAABBwb29sTWFrZXJBZGRyZXNzAAAAAAAAAAAAAQAAACJnZXRQb29sTWFrZXJQYXJ0aWNpcGF0aW9uTWF4QW1vdW50AAAAAgAAAAxhc3NldEFkZHJlc3MAAAAQcG9vbE1ha2VyQWRkcmVzcwkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAlZ2V0UG9vbE1ha2VyUGFydGljaXBhdGlvbk1heEFtb3VudEtleQAAAAIFAAAADGFzc2V0QWRkcmVzcwUAAAAQcG9vbE1ha2VyQWRkcmVzcwAAAAAAAAAAAAEAAAAYZ2V0UG9vbE1ha2VyTG9ja2VkQW1vdW50AAAAAgAAAAxhc3NldEFkZHJlc3MAAAAQcG9vbE1ha2VyQWRkcmVzcwkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAbZ2V0UG9vbE1ha2VyTG9ja2VkQW1vdW50S2V5AAAAAgUAAAAMYXNzZXRBZGRyZXNzBQAAABBwb29sTWFrZXJBZGRyZXNzAAAAAAAAAAAAAQAAABhnZXRQb29sTWFrZXJVbmxvY2tIZWlnaHQAAAACAAAADGFzc2V0QWRkcmVzcwAAABBwb29sTWFrZXJBZGRyZXNzCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABtnZXRQb29sTWFrZXJVbmxvY2tIZWlnaHRLZXkAAAACBQAAAAxhc3NldEFkZHJlc3MFAAAAEHBvb2xNYWtlckFkZHJlc3MAAAAAAAAAAAABAAAADWdldEFzc2V0UHJpY2UAAAACAAAAEnByaWNlT3JhY2xlQWRkcmVzcwAAAAlhc3NldENvZGUJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAABJwcmljZU9yYWNsZUFkZHJlc3MJAQAAABBnZXRBc3NldFByaWNlS2V5AAAAAQUAAAAJYXNzZXRDb2RlAgAAABRObyBBc3NldCBwcmljZSBmb3VuZAEAAAAfY29tcG9zZUFzc2V0Q29uZmlndXJhdGlvblN0cmluZwAAAA8AAAAJYXNzZXRDb2RlAAAAB2Fzc2V0SWQAAAALYXNzZXRTdGF0dXMAAAANcHJpY2VEZWNpbWFscwAAAA5iYWNraW5nQXNzZXRJZAAAABVvdmVyQ29sbGF0ZXJhbFBlcmNlbnQAAAAHbWluUG9vbAAAABJwcmljZU9yYWNsZUFkZHJlc3MAAAANbWluQnV5UGF5bWVudAAAAA5taW5TZWxsUGF5bWVudAAAAA9idXlMb2NrSW50ZXJ2YWwAAAAQc2VsbExvY2tJbnRlcnZhbAAAAAZidXlGZWUAAAAHc2VsbEZlZQAAABVwb29sUmVkZW1wdGlvblRpbWVvdXQJAAS5AAAAAgkABEwAAAACAgAAAB4lcyVzJXMlZCVzJWQlZCVzJWQlZCVkJWQlZCVkJWQJAARMAAAAAgUAAAAJYXNzZXRDb2RlCQAETAAAAAIFAAAAB2Fzc2V0SWQJAARMAAAAAgUAAAALYXNzZXRTdGF0dXMJAARMAAAAAgkAAaQAAAABBQAAAA1wcmljZURlY2ltYWxzCQAETAAAAAIFAAAADmJhY2tpbmdBc3NldElkCQAETAAAAAIJAAGkAAAAAQUAAAAVb3ZlckNvbGxhdGVyYWxQZXJjZW50CQAETAAAAAIJAAGkAAAAAQUAAAAHbWluUG9vbAkABEwAAAACBQAAABJwcmljZU9yYWNsZUFkZHJlc3MJAARMAAAAAgkAAaQAAAABBQAAAA1taW5CdXlQYXltZW50CQAETAAAAAIJAAGkAAAAAQUAAAAObWluU2VsbFBheW1lbnQJAARMAAAAAgkAAaQAAAABBQAAAA9idXlMb2NrSW50ZXJ2YWwJAARMAAAAAgkAAaQAAAABBQAAABBzZWxsTG9ja0ludGVydmFsCQAETAAAAAIJAAGkAAAAAQUAAAAGYnV5RmVlCQAETAAAAAIJAAGkAAAAAQUAAAAHc2VsbEZlZQkABEwAAAACCQABpAAAAAEFAAAAFXBvb2xSZWRlbXB0aW9uVGltZW91dAUAAAADbmlsAgAAAAJfXwAAAAYAAAABaQEAAAAEaW5pdAAAAAgAAAAXbmV1dHJpbm9Db250cmFjdEFkZHJlc3MAAAAWbmV1dHJpbm9TdGFraW5nQWRkcmVzcwAAABhtaW5pbXVuUG9vbEZ1bmRpbmdBbW91bnQAAAATcHJlZGVmaW5lZEFzc2V0TGlzdAAAABFjdXJyZW50QXNzZXRJbmRleAAAABJkZWJ0RXRoYWxvbkJhbGFuY2UAAAASZGVmb1N0YWtpbmdBZGRyZXNzAAAAF2RlZm9TdGFraW5nUGFjZW1ha2VyUHViAwkBAAAAAiE9AAAAAgkAAlgAAAABCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkFAAAADmFkbWluUHVibGljS2V5CQAAAgAAAAECAAAAKk9ubHkgQWRtaW4gY2FuIHBlcmZvcm0gY29udHJhY3Qgb3BlcmF0aW9uLgMJAAAAAAAAAgkBAAAADGdldEJvb2xCeUtleQAAAAEFAAAAEGlzSW5pdGlhbGl6ZWRLZXkGCQAAAgAAAAECAAAAIUNvbnRyYWN0IHdhcyBhbHJlYWR5IGluaXRpYWxpemVkLgQAAAAJaXNzdWVEZWJ0CQAEQgAAAAUCAAAACURFRk9fREVCVAIAAAAQREVGTyBEZWJ0IFRva2VuLgAAAAAAAAAAAQAAAAAAAAAABgYEAAAAC2RlYnRUb2tlbklkCQAEOAAAAAEFAAAACWlzc3VlRGVidAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAABpuZXV0cmlub0NvbnRyYWN0QWRkcmVzc0tleQUAAAAXbmV1dHJpbm9Db250cmFjdEFkZHJlc3MJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAZbmV1dHJpbm9TdGFraW5nQWRkcmVzc0tleQUAAAAWbmV1dHJpbm9TdGFraW5nQWRkcmVzcwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAbbWluaW11blBvb2xGdW5kaW5nQW1vdW50S2V5BQAAABhtaW5pbXVuUG9vbEZ1bmRpbmdBbW91bnQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAUYXNzZXRzQWRkcmVzc0xpc3RLZXkFAAAAE3ByZWRlZmluZWRBc3NldExpc3QJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAFGN1cnJlbnRBc3NldEluZGV4S2V5BQAAABFjdXJyZW50QXNzZXRJbmRleAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAZZGVidFRva2VuRXRhbG9uQmFsYW5jZUtleQUAAAASZGVidEV0aGFsb25CYWxhbmNlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADmRlYnRUb2tlbklkS2V5CQACWAAAAAEFAAAAC2RlYnRUb2tlbklkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAFWRlZm9TdGFraW5nQWRkcmVzc0tleQUAAAASZGVmb1N0YWtpbmdBZGRyZXNzCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAGmRlZm9TdGFraW5nUGFjZW1ha2VyUHViS2V5BQAAABdkZWZvU3Rha2luZ1BhY2VtYWtlclB1YgkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAQaXNJbml0aWFsaXplZEtleQYJAARMAAAAAgUAAAAJaXNzdWVEZWJ0CQAETAAAAAIJAQAAAARCdXJuAAAAAgUAAAALZGVidFRva2VuSWQAAAAAAAAAAAEFAAAAA25pbAAAAAFpAQAAAAxwcm9wb3NlQXNzZXQAAAAOAAAACWFzc2V0Q29kZQAAAARtZXRhAAAAB21pblBvb2wAAAAScHJpY2VPcmFjbGVBZGRyZXNzAAAAFW92ZXJDb2xsYXRlcmFsUGVyY2VudAAAAA5iYWNraW5nQXNzZXRJZAAAAA1wcmljZURlY2ltYWxzAAAADW1pbkJ1eVBheW1lbnQAAAAObWluU2VsbFBheW1lbnQAAAAPYnV5TG9ja0ludGVydmFsAAAAEHNlbGxMb2NrSW50ZXJ2YWwAAAAGYnV5RmVlAAAAB3NlbGxGZWUAAAAVcG9vbFJlZGVtcHRpb25UaW1lb3V0AwkBAAAAAiE9AAAAAgkAAlgAAAABCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkFAAAADmFkbWluUHVibGljS2V5CQAAAgAAAAECAAAAKk9ubHkgQWRtaW4gY2FuIHBlcmZvcm0gY29udHJhY3Qgb3BlcmF0aW9uLgMJAAAAAAAAAgkBAAAADGdldEJvb2xCeUtleQAAAAEFAAAAEGlzSW5pdGlhbGl6ZWRLZXkHCQAAAgAAAAECAAAAGkNvbnRyYWN0IGlzIG5vdCB5ZXQgcmVhZHkuAwkBAAAAAiE9AAAAAgkAAlkAAAABBQAAAA5iYWNraW5nQXNzZXRJZAUAAAAPbmV1dHJpbm9Bc3NldElkCQAAAgAAAAECAAAAI0Jha2luZyBhc3NldCBpZCBjb3VsZCBiZSBVU0ROIG9ubHkuAwkBAAAAAiE9AAAAAgkBAAAAFWdldEFzc2V0QWRkcmVzc0J5Q29kZQAAAAEFAAAACWFzc2V0Q29kZQIAAAAACQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAABdBc3NldCB3aXRoIHBhc3NlZCBjb2RlIAUAAAAJYXNzZXRDb2RlAgAAABsgaGFzIGFscmVhZHkgYmVlbiBwcm9wb3NlZC4DCQAAZgAAAAIFAAAAEm1pbmltdW1Qb29sRnVuZGluZwUAAAAHbWluUG9vbAkAAAIAAAABCQABLAAAAAICAAAAM01pbmltdW0gcG9vbCBhbW91bnQgc2hvdWxkIGJlIGdyZWF0ZXIgb3IgZXF1YWxzIHRvIAkAAaQAAAABBQAAABJtaW5pbXVtUG9vbEZ1bmRpbmcDAwMDAwMDAwkAAGYAAAACAAAAAAAAAAAABQAAABVvdmVyQ29sbGF0ZXJhbFBlcmNlbnQGCQAAZgAAAAIAAAAAAAAAAAAFAAAADXByaWNlRGVjaW1hbHMGCQAAZgAAAAIAAAAAAAAAAAAFAAAADW1pbkJ1eVBheW1lbnQGCQAAZgAAAAIAAAAAAAAAAAAFAAAADm1pblNlbGxQYXltZW50BgkAAGYAAAACAAAAAAAAAAAABQAAAA9idXlMb2NrSW50ZXJ2YWwGCQAAZgAAAAIAAAAAAAAAAAAFAAAAEHNlbGxMb2NrSW50ZXJ2YWwGCQAAZgAAAAIAAAAAAAAAAAAFAAAABmJ1eUZlZQYJAABmAAAAAgAAAAAAAAAAAAUAAAAHc2VsbEZlZQkAAAIAAAABAgAAAChPbmUgb2YgdGhlIHBhc3NlZCBwYXJhbWV0ZXJzIGlzIGludmFsaWQuBAAAABdwcmljZU9yYWNsZUFkZHJlc3NWYWxpZAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAABJwcmljZU9yYWNsZUFkZHJlc3MCAAAAKVBhc3NlZCBQcmljZSBPcmFjbGUgQWRkcmVzcyBpcyBub3QgdmFsaWQuBAAAAAxhc3NldEFkZHJlc3MJAAGRAAAAAgUAAAAUcHJlZGVmaW5lZEFzc2V0c0xpc3QFAAAAEWN1cnJlbnRBc3NldEluZGV4BAAAAAtkZWZvQXNzZXRJZAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABBQAAAAxhc3NldEFkZHJlc3MCAAAAAAUAAAAOZGVmb0Fzc2V0SWRLZXkCAAAAF05vIGRlZm8gYXNzZXQgSUQgZm91bmQuCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABFnZXRBc3NldENvbmZpZ0tleQAAAAEFAAAADGFzc2V0QWRkcmVzcwkBAAAAH2NvbXBvc2VBc3NldENvbmZpZ3VyYXRpb25TdHJpbmcAAAAPBQAAAAlhc3NldENvZGUFAAAAC2RlZm9Bc3NldElkCAUAAAALYXNzZXRTdGF0dXMAAAACXzEFAAAADXByaWNlRGVjaW1hbHMFAAAADmJhY2tpbmdBc3NldElkBQAAABVvdmVyQ29sbGF0ZXJhbFBlcmNlbnQFAAAAB21pblBvb2wFAAAAEnByaWNlT3JhY2xlQWRkcmVzcwUAAAANbWluQnV5UGF5bWVudAUAAAAObWluU2VsbFBheW1lbnQFAAAAD2J1eUxvY2tJbnRlcnZhbAUAAAAQc2VsbExvY2tJbnRlcnZhbAUAAAAGYnV5RmVlBQAAAAdzZWxsRmVlBQAAABVwb29sUmVkZW1wdGlvblRpbWVvdXQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAGGdldEFzc2V0QWRkcmVzc0J5Q29kZUtleQAAAAEFAAAACWFzc2V0Q29kZQUAAAAMYXNzZXRBZGRyZXNzCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAA9nZXRBc3NldE1ldGFLZXkAAAABBQAAAAxhc3NldEFkZHJlc3MFAAAABG1ldGEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABVnZXRBc3NldEluaXRIZWlnaHRLZXkAAAABBQAAAAxhc3NldEFkZHJlc3MFAAAABmhlaWdodAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAUY3VycmVudEFzc2V0SW5kZXhLZXkJAABkAAAAAgUAAAARY3VycmVudEFzc2V0SW5kZXgAAAAAAAAAAAEJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAG2dldEFzc2V0QWRkcmVzc0J5QXNzZXRJZEtleQAAAAEFAAAAC2RlZm9Bc3NldElkBQAAAAxhc3NldEFkZHJlc3MFAAAAA25pbAAAAAFpAQAAABFmdW5kTGlxdWlkaXR5UG9vbAAAAAEAAAAJYXNzZXRDb2RlBAAAAAxhc3NldEFkZHJlc3MJAQAAABVnZXRBc3NldEFkZHJlc3NCeUNvZGUAAAABBQAAAAlhc3NldENvZGUEAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QJAQAAABNnZXRBc3NldENvbmZpZ0FycmF5AAAAAQUAAAAMYXNzZXRBZGRyZXNzBAAAAA9hdHRhY2hlZFBheW1lbnQJAQAAAAV2YWx1ZQAAAAEJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAADCQEAAAACIT0AAAACCQACWAAAAAEIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQUAAAAOYWRtaW5QdWJsaWNLZXkJAAACAAAAAQIAAAAqT25seSBBZG1pbiBjYW4gcGVyZm9ybSBjb250cmFjdCBvcGVyYXRpb24uAwkAAAAAAAACCQEAAAAMZ2V0Qm9vbEJ5S2V5AAAAAQUAAAAQaXNJbml0aWFsaXplZEtleQcJAAACAAAAAQIAAAAaQ29udHJhY3QgaXMgbm90IHlldCByZWFkeS4DCQEAAAACIT0AAAACCAUAAAAPYXR0YWNoZWRQYXltZW50AAAAB2Fzc2V0SWQFAAAAD25ldXRyaW5vQXNzZXRJZAkAAAIAAAABAgAAAC5MaXF1aWRpdHkgcG9vbCBjb3VsZCBiZSBmdW5kZWQgd2l0aCBVU0ROIG9ubHkuAwkAAAAAAAACCAUAAAAPYXR0YWNoZWRQYXltZW50AAAABmFtb3VudAAAAAAAAAAAAAkAAAIAAAABAgAAACJJbmNvcnJlY3QgYXR0YWNoZWQgcGF5bWVudCBhbW91bnQuAwkAAAAAAAACBQAAAAxhc3NldEFkZHJlc3MCAAAAAAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAAlQ2Fubm90IGZpbmQgbGlxdWlkaXR5IHBvb2wgZm9yIGFzc2V0IAUAAAAJYXNzZXRDb2RlAgAAAAEuBAAAAA9maW5hbFBvb2xBbW91bnQJAABkAAAAAggFAAAAD2F0dGFjaGVkUGF5bWVudAAAAAZhbW91bnQJAQAAABlnZXRBc3NldEN1cnJlbnRQb29sQW1vdW50AAAAAQUAAAAMYXNzZXRBZGRyZXNzBAAAAA1tYXhQb29sQW1vdW50CQEAAAAVZ2V0QXNzZXRNYXhQb29sQW1vdW50AAAAAQUAAAAMYXNzZXRBZGRyZXNzBAAAABBwb29sTWFrZXJBZGRyZXNzCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAXY3VycmVudFBvb2xNYWtlckJhbGFuY2UJAQAAAB9nZXRQb29sTWFrZXJQYXJ0aWNpcGF0aW9uQW1vdW50AAAAAgUAAAAMYXNzZXRBZGRyZXNzBQAAABBwb29sTWFrZXJBZGRyZXNzBAAAABNtYXhQb29sTWFrZXJCYWxhbmNlCQEAAAAiZ2V0UG9vbE1ha2VyUGFydGljaXBhdGlvbk1heEFtb3VudAAAAAIFAAAADGFzc2V0QWRkcmVzcwUAAAAQcG9vbE1ha2VyQWRkcmVzcwQAAAARY3VycmVudFBvb2xTdGF0dXMJAQAAAA5nZXRBc3NldFN0YXR1cwAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAAD2ZpbmFsUG9vbFN0YXR1cwMDCQAAZwAAAAIFAAAAD2ZpbmFsUG9vbEFtb3VudAkBAAAAHWdldEFzc2V0TWluUmVxdWlyZWRQb29sQW1vdW50AAAAAQUAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAkAAAAAAAACBQAAABFjdXJyZW50UG9vbFN0YXR1cwgFAAAAC2Fzc2V0U3RhdHVzAAAAAl8xBwgFAAAAC2Fzc2V0U3RhdHVzAAAAAl8yBQAAABFjdXJyZW50UG9vbFN0YXR1cwQAAAARY3VycmVudFBvb2xNYWtlcnMJAQAAABJnZXRBc3NldFBvb2xNYWtlcnMAAAABBQAAAAxhc3NldEFkZHJlc3MEAAAADW5ld1Bvb2xNYWtlcnMDCQAAAAAAAAIFAAAAEWN1cnJlbnRQb29sTWFrZXJzAgAAAAAFAAAAEHBvb2xNYWtlckFkZHJlc3MDCQEAAAAIY29udGFpbnMAAAACBQAAABFjdXJyZW50UG9vbE1ha2VycwUAAAAQcG9vbE1ha2VyQWRkcmVzcwUAAAARY3VycmVudFBvb2xNYWtlcnMJAAEsAAAAAgkAASwAAAACBQAAABFjdXJyZW50UG9vbE1ha2VycwIAAAABLAkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAABWFDb2RlCQEAAAAMZ2V0QXNzZXRDb2RlAAAAAQUAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAQAAAADYUlECQEAAAAKZ2V0QXNzZXRJRAAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAADmFQcmljZURlY2ltYWxzCQEAAAAVZ2V0QXNzZXRQcmljZURlY2ltYWxzAAAAAQUAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAQAAAAOYUJha2luZ0Fzc2V0SWQJAQAAABVnZXRBc3NldEJha2luZ0Fzc2V0SWQAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAABZhT3ZlckNvbGxhdGVyYWxQZXJjZW50CQEAAAAdZ2V0QXNzZXRPdmVyQ29sbGF0ZXJhbFBlcmNlbnQAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAABBhTWluUmVxdWlyZWRQb29sCQEAAAAdZ2V0QXNzZXRNaW5SZXF1aXJlZFBvb2xBbW91bnQAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAABNhUHJpY2VPcmFjbGVBZGRyZXNzCQEAAAAaZ2V0QXNzZXRQcmljZU9yYWNsZUFkZHJlc3MAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAAA5hTWluQnV5UGF5bWVudAkBAAAAGGdldE1pbkJ1eVBheW1lbnRQZXJBc3NldAAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAAD2FNaW5TZWxsUGF5bWVudAkBAAAAGWdldE1pblNlbGxQYXltZW50UGVyQXNzZXQAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAABBhQnV5TG9ja0ludGVydmFsCQEAAAAaZ2V0QnV5TG9ja0ludGVydmFsUGVyQXNzZXQAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAABFhU2VsbExvY2tJbnRlcnZhbAkBAAAAG2dldFNlbGxMb2NrSW50ZXJ2YWxQZXJBc3NldAAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAAB2FCdXlGZWUJAQAAABFnZXRCdXlGZWVQZXJBc3NldAAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAACGFTZWxsRmVlCQEAAAASZ2V0U2VsbEZlZVBlckFzc2V0AAAAAQUAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAQAAAAYYVJlZGVtcHRpb25UaW1lb3V0QmxvY2tzCQEAAAAaZ2V0UmVkZW1wdGlvblRpbWVvdXRCbG9ja3MAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAABNuZXdQb29sTWFrZXJCYWxhbmNlCQAAZAAAAAIFAAAAF2N1cnJlbnRQb29sTWFrZXJCYWxhbmNlCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQEAAAABnJlc3VsdAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAImdldFBvb2xNYWtlclBhcnRpY2lwYXRpb25BbW91bnRLZXkAAAACBQAAAAxhc3NldEFkZHJlc3MJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBQAAABNuZXdQb29sTWFrZXJCYWxhbmNlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAlZ2V0UG9vbE1ha2VyUGFydGljaXBhdGlvbk1heEFtb3VudEtleQAAAAIFAAAADGFzc2V0QWRkcmVzcwkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIDCQAAZgAAAAIFAAAAE25ld1Bvb2xNYWtlckJhbGFuY2UFAAAAE21heFBvb2xNYWtlckJhbGFuY2UFAAAAE25ld1Bvb2xNYWtlckJhbGFuY2UFAAAAE21heFBvb2xNYWtlckJhbGFuY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAB1nZXRBc3NldEN1cnJyZW50UG9vbEFtb3VudEtleQAAAAEFAAAADGFzc2V0QWRkcmVzcwUAAAAPZmluYWxQb29sQW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAYZ2V0QXNzZXRNYXhQb29sQW1vdW50S2V5AAAAAQUAAAAMYXNzZXRBZGRyZXNzAwkAAGYAAAACBQAAAA9maW5hbFBvb2xBbW91bnQFAAAADW1heFBvb2xBbW91bnQFAAAAD2ZpbmFsUG9vbEFtb3VudAUAAAANbWF4UG9vbEFtb3VudAkABEwAAAACCQEAAAALRGVsZXRlRW50cnkAAAABCQEAAAARZ2V0QXNzZXRDb25maWdLZXkAAAABBQAAAAxhc3NldEFkZHJlc3MJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAFWdldEFzc2V0UG9vbE1ha2Vyc0tleQAAAAEFAAAADGFzc2V0QWRkcmVzcwUAAAANbmV3UG9vbE1ha2VycwkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAARZ2V0QXNzZXRDb25maWdLZXkAAAABBQAAAAxhc3NldEFkZHJlc3MJAQAAAB9jb21wb3NlQXNzZXRDb25maWd1cmF0aW9uU3RyaW5nAAAADwUAAAAFYUNvZGUFAAAAA2FJRAUAAAAPZmluYWxQb29sU3RhdHVzBQAAAA5hUHJpY2VEZWNpbWFscwUAAAAOYUJha2luZ0Fzc2V0SWQFAAAAFmFPdmVyQ29sbGF0ZXJhbFBlcmNlbnQFAAAAEGFNaW5SZXF1aXJlZFBvb2wFAAAAE2FQcmljZU9yYWNsZUFkZHJlc3MFAAAADmFNaW5CdXlQYXltZW50BQAAAA9hTWluU2VsbFBheW1lbnQFAAAAEGFCdXlMb2NrSW50ZXJ2YWwFAAAAEWFTZWxsTG9ja0ludGVydmFsBQAAAAdhQnV5RmVlBQAAAAhhU2VsbEZlZQUAAAAYYVJlZGVtcHRpb25UaW1lb3V0QmxvY2tzBQAAAANuaWwDCQAAAAAAAAIFAAAAEWN1cnJlbnRQb29sU3RhdHVzCAUAAAALYXNzZXRTdGF0dXMAAAACXzMJAARNAAAAAgUAAAAGcmVzdWx0CQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAAxhc3NldEFkZHJlc3MIBQAAAA9hdHRhY2hlZFBheW1lbnQAAAAGYW1vdW50BQAAAA9uZXV0cmlub0Fzc2V0SWQFAAAABnJlc3VsdAAAAAFpAQAAAA1hY3RpdmF0ZUFzc2V0AAAAAQAAAAlhc3NldENvZGUEAAAADGFzc2V0QWRkcmVzcwkBAAAAFWdldEFzc2V0QWRkcmVzc0J5Q29kZQAAAAEFAAAACWFzc2V0Q29kZQQAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAkBAAAAE2dldEFzc2V0Q29uZmlnQXJyYXkAAAABBQAAAAxhc3NldEFkZHJlc3MEAAAAFmN1cnJlbnRBc3NldFBvb2xBbW91bnQJAQAAABlnZXRBc3NldEN1cnJlbnRQb29sQW1vdW50AAAAAQUAAAAMYXNzZXRBZGRyZXNzBAAAAAVhQ29kZQkBAAAADGdldEFzc2V0Q29kZQAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAADmFDdXJyZW50U3RhdHVzCQEAAAAOZ2V0QXNzZXRTdGF0dXMAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAAANhSUQJAQAAAApnZXRBc3NldElEAAAAAQUAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAQAAAAOYVByaWNlRGVjaW1hbHMJAQAAABVnZXRBc3NldFByaWNlRGVjaW1hbHMAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAAA5hQmFraW5nQXNzZXRJZAkBAAAAFWdldEFzc2V0QmFraW5nQXNzZXRJZAAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAAFmFPdmVyQ29sbGF0ZXJhbFBlcmNlbnQJAQAAAB1nZXRBc3NldE92ZXJDb2xsYXRlcmFsUGVyY2VudAAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAAEGFNaW5SZXF1aXJlZFBvb2wJAQAAAB1nZXRBc3NldE1pblJlcXVpcmVkUG9vbEFtb3VudAAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAAE2FQcmljZU9yYWNsZUFkZHJlc3MJAQAAABpnZXRBc3NldFByaWNlT3JhY2xlQWRkcmVzcwAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAADmFNaW5CdXlQYXltZW50CQEAAAAYZ2V0TWluQnV5UGF5bWVudFBlckFzc2V0AAAAAQUAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAQAAAAPYU1pblNlbGxQYXltZW50CQEAAAAZZ2V0TWluU2VsbFBheW1lbnRQZXJBc3NldAAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAAEGFCdXlMb2NrSW50ZXJ2YWwJAQAAABpnZXRCdXlMb2NrSW50ZXJ2YWxQZXJBc3NldAAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QEAAAAEWFTZWxsTG9ja0ludGVydmFsCQEAAAAbZ2V0U2VsbExvY2tJbnRlcnZhbFBlckFzc2V0AAAAAQUAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAQAAAAHYUJ1eUZlZQkBAAAAEWdldEJ1eUZlZVBlckFzc2V0AAAAAQUAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAQAAAAIYVNlbGxGZWUJAQAAABJnZXRTZWxsRmVlUGVyQXNzZXQAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAABhhUmVkZW1wdGlvblRpbWVvdXRCbG9ja3MJAQAAABpnZXRSZWRlbXB0aW9uVGltZW91dEJsb2NrcwAAAAEFAAAAFmFzc2V0Q29uZmlndXJhdGlvbkxpc3QDCQEAAAACIT0AAAACCQACWAAAAAEIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQUAAAAOYWRtaW5QdWJsaWNLZXkJAAACAAAAAQIAAAAqT25seSBBZG1pbiBjYW4gcGVyZm9ybSBjb250cmFjdCBvcGVyYXRpb24uAwkAAAAAAAACCQEAAAAMZ2V0Qm9vbEJ5S2V5AAAAAQUAAAAQaXNJbml0aWFsaXplZEtleQcJAAACAAAAAQIAAAAaQ29udHJhY3QgaXMgbm90IHlldCByZWFkeS4DCQEAAAACIT0AAAACBQAAAA5hQ3VycmVudFN0YXR1cwgFAAAAC2Fzc2V0U3RhdHVzAAAAAl8yCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAADBBc3NldCBpcyBub3QgaW4gUkVBRFkgc3RhdHVzLiBDdXJyZW50IHN0YXR1cyBpcyAFAAAADmFDdXJyZW50U3RhdHVzAgAAAAEuAwkAAAAAAAACBQAAAAxhc3NldEFkZHJlc3MCAAAAAAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAASQ2Fubm90IGZpbmQgYXNzZXQgBQAAAAlhc3NldENvZGUCAAAAAS4DCQAAZgAAAAIFAAAAEm1pbmltdW1Qb29sRnVuZGluZwUAAAAWY3VycmVudEFzc2V0UG9vbEFtb3VudAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAALUNhbm5vdCBpc3N1ZSBhc3NldCBhcyBsaXF1aWRpdHkgcG9vbCBhbW91bnQgKAkAAaQAAAABBQAAABZjdXJyZW50QXNzZXRQb29sQW1vdW50AgAAABkpIGlzIGxlc3MgdGhhbiByZXF1aXJlZCAoCQABpAAAAAEFAAAAEm1pbmltdW1Qb29sRnVuZGluZwIAAAABKQQAAAAJaXNzdWVEZWJ0CQEAAAAHUmVpc3N1ZQAAAAMFAAAACWRlYnRUb2tlbgUAAAAWZGVidFRva2VuUmVpc3N1ZUFtb3VudAYJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABlnZXRBc3NldEFjdGl2YXRlSGVpZ2h0S2V5AAAAAQUAAAAMYXNzZXRBZGRyZXNzBQAAAAZoZWlnaHQJAARMAAAAAgkBAAAAC0RlbGV0ZUVudHJ5AAAAAQkBAAAAEWdldEFzc2V0Q29uZmlnS2V5AAAAAQUAAAAMYXNzZXRBZGRyZXNzCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABFnZXRBc3NldENvbmZpZ0tleQAAAAEFAAAADGFzc2V0QWRkcmVzcwkBAAAAH2NvbXBvc2VBc3NldENvbmZpZ3VyYXRpb25TdHJpbmcAAAAPBQAAAAVhQ29kZQUAAAADYUlECAUAAAALYXNzZXRTdGF0dXMAAAACXzMFAAAADmFQcmljZURlY2ltYWxzBQAAAA5hQmFraW5nQXNzZXRJZAUAAAAWYU92ZXJDb2xsYXRlcmFsUGVyY2VudAUAAAAQYU1pblJlcXVpcmVkUG9vbAUAAAATYVByaWNlT3JhY2xlQWRkcmVzcwUAAAAOYU1pbkJ1eVBheW1lbnQFAAAAD2FNaW5TZWxsUGF5bWVudAUAAAAQYUJ1eUxvY2tJbnRlcnZhbAUAAAARYVNlbGxMb2NrSW50ZXJ2YWwFAAAAB2FCdXlGZWUFAAAACGFTZWxsRmVlBQAAABhhUmVkZW1wdGlvblRpbWVvdXRCbG9ja3MJAARMAAAAAgUAAAAJaXNzdWVEZWJ0CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAADGFzc2V0QWRkcmVzcwUAAAAWY3VycmVudEFzc2V0UG9vbEFtb3VudAUAAAAPbmV1dHJpbm9Bc3NldElkCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAADGFzc2V0QWRkcmVzcwUAAAAWZGVidFRva2VuUmVpc3N1ZUFtb3VudAUAAAAJZGVidFRva2VuBQAAAANuaWwAAAABaQEAAAAOcmVkZWVtRnJvbVBvb2wAAAACAAAACWFzc2V0Q29kZQAAAAZhbW91bnQEAAAADGFzc2V0QWRkcmVzcwkBAAAAFWdldEFzc2V0QWRkcmVzc0J5Q29kZQAAAAEFAAAACWFzc2V0Q29kZQQAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAkBAAAAE2dldEFzc2V0Q29uZmlnQXJyYXkAAAABBQAAAAxhc3NldEFkZHJlc3MEAAAADWNhbGxlckFkZHJlc3MJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAABl0b3RhbEFtb3VudEluUG9vbEJ5Q2FsbGVyCQEAAAAfZ2V0UG9vbE1ha2VyUGFydGljaXBhdGlvbkFtb3VudAAAAAIFAAAADGFzc2V0QWRkcmVzcwUAAAANY2FsbGVyQWRkcmVzcwQAAAAXbG9ja2VkQW1vdW50QnlQb29sTWFrZXIJAQAAABhnZXRQb29sTWFrZXJMb2NrZWRBbW91bnQAAAACBQAAAAxhc3NldEFkZHJlc3MFAAAADWNhbGxlckFkZHJlc3MDCQEAAAACIT0AAAACCQACWAAAAAEIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQUAAAAOYWRtaW5QdWJsaWNLZXkJAAACAAAAAQIAAAAqT25seSBBZG1pbiBjYW4gcGVyZm9ybSBjb250cmFjdCBvcGVyYXRpb24uAwkAAAAAAAACCQEAAAAMZ2V0Qm9vbEJ5S2V5AAAAAQUAAAAQaXNJbml0aWFsaXplZEtleQcJAAACAAAAAQIAAAAaQ29udHJhY3QgaXMgbm90IHlldCByZWFkeS4DCQAAAAAAAAIFAAAADGFzc2V0QWRkcmVzcwIAAAAACQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAABJDYW5ub3QgZmluZCBhc3NldCAFAAAACWFzc2V0Q29kZQIAAAABLgMDAwkAAGYAAAACAAAAAAAAAAAABQAAAAZhbW91bnQGCQAAAAAAAAIFAAAAGXRvdGFsQW1vdW50SW5Qb29sQnlDYWxsZXIAAAAAAAAAAAAGCQAAZgAAAAIFAAAABmFtb3VudAUAAAAZdG90YWxBbW91bnRJblBvb2xCeUNhbGxlcgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAAiQ2Fubm90IGZpbmQgcG9vbCBtYWtlciBieSBhZGRyZXNzIAUAAAANY2FsbGVyQWRkcmVzcwIAAAAhIG9yIGFtb3VudCBwYXNzZWQgaXMgbm90IGNvcnJlY3QuAwkAAGYAAAACBQAAABdsb2NrZWRBbW91bnRCeVBvb2xNYWtlcgAAAAAAAAAAAAkAAAIAAAABAgAAAEZQb29sIG1ha2VyIGFscmVhZHkgaGFzIGluaXRpYXRlZCByZWRlbXB0aW9uIHRoYXQgaXMgbm90IHdpdGhkcmF3biB5ZXQuCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAbZ2V0UG9vbE1ha2VyTG9ja2VkQW1vdW50S2V5AAAAAgUAAAAMYXNzZXRBZGRyZXNzBQAAAA1jYWxsZXJBZGRyZXNzBQAAAAZhbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABtnZXRQb29sTWFrZXJVbmxvY2tIZWlnaHRLZXkAAAACBQAAAAxhc3NldEFkZHJlc3MFAAAADWNhbGxlckFkZHJlc3MJAABkAAAAAgUAAAAGaGVpZ2h0CQEAAAAaZ2V0UmVkZW1wdGlvblRpbWVvdXRCbG9ja3MAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BQAAAANuaWwAAAABaQEAAAAId2l0aGRyYXcAAAABAAAACWFzc2V0Q29kZQQAAAAWYXNzZXRDb25maWd1cmF0aW9uTGlzdAkBAAAAE2dldEFzc2V0Q29uZmlnQXJyYXkAAAABBQAAAAlhc3NldENvZGUEAAAADGFzc2V0QWRkcmVzcwkBAAAAFWdldEFzc2V0QWRkcmVzc0J5Q29kZQAAAAEFAAAACWFzc2V0Q29kZQQAAAAScHJpY2VPcmFjbGVBZGRyZXNzCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAAaZ2V0QXNzZXRQcmljZU9yYWNsZUFkZHJlc3MAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BAAAAA1jYWxsZXJBZGRyZXNzCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAASc3ludGhldGljQXNzZXRJbmZvCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAPsAAAAAQkAAlkAAAABBQAAAAxhc3NldEFkZHJlc3MJAAEsAAAAAgIAAAAYQ2Fubm90IGZpbmQgYXNzZXQgYnkgaWQgBQAAAAxhc3NldEFkZHJlc3MEAAAAGnRvdGFsVVNETkJhbGFuY2VPbkNvbnRyYWN0CQAD8AAAAAIFAAAABHRoaXMFAAAAD25ldXRyaW5vQXNzZXRJZAQAAAAcdG90YWxBbW91bnRJblBvb2xCeVBvb2xNYWtlcgkBAAAAH2dldFBvb2xNYWtlclBhcnRpY2lwYXRpb25BbW91bnQAAAACBQAAAAxhc3NldEFkZHJlc3MFAAAADWNhbGxlckFkZHJlc3MEAAAAF2xvY2tlZEFtb3VudEJ5UG9vbE1ha2VyCQEAAAAYZ2V0UG9vbE1ha2VyTG9ja2VkQW1vdW50AAAAAgUAAAAMYXNzZXRBZGRyZXNzBQAAAA1jYWxsZXJBZGRyZXNzBAAAABFtaW5XaXRoZHJhd0hlaWdodAkBAAAAGGdldFBvb2xNYWtlclVubG9ja0hlaWdodAAAAAIFAAAADGFzc2V0QWRkcmVzcwUAAAANY2FsbGVyQWRkcmVzcwQAAAATcG9vbE1ha2V0UHJvcG9ydGlvbgkAAGkAAAACCQEAAAAVZ2V0QXNzZXRNYXhQb29sQW1vdW50AAAAAQUAAAAMYXNzZXRBZGRyZXNzCQEAAAAiZ2V0UG9vbE1ha2VyUGFydGljaXBhdGlvbk1heEFtb3VudAAAAAIFAAAADGFzc2V0QWRkcmVzcwUAAAANY2FsbGVyQWRkcmVzcwMJAQAAAAIhPQAAAAIJAAJYAAAAAQgFAAAAAWkAAAAPY2FsbGVyUHVibGljS2V5BQAAAA5hZG1pblB1YmxpY0tleQkAAAIAAAABAgAAACpPbmx5IEFkbWluIGNhbiBwZXJmb3JtIGNvbnRyYWN0IG9wZXJhdGlvbi4DCQAAAAAAAAIJAQAAAAxnZXRCb29sQnlLZXkAAAABBQAAABBpc0luaXRpYWxpemVkS2V5BwkAAAIAAAABAgAAABpDb250cmFjdCBpcyBub3QgeWV0IHJlYWR5LgMJAAAAAAAAAgkBAAAADGdldEJvb2xCeUtleQAAAAEFAAAAEGlzSW5pdGlhbGl6ZWRLZXkHCQAAAgAAAAECAAAAGkNvbnRyYWN0IGlzIG5vdCB5ZXQgcmVhZHkuAwkAAAAAAAACBQAAAAxhc3NldEFkZHJlc3MCAAAAAAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAASQ2Fubm90IGZpbmQgYXNzZXQgBQAAAAlhc3NldENvZGUCAAAAAS4DCQAAAAAAAAIFAAAAHHRvdGFsQW1vdW50SW5Qb29sQnlQb29sTWFrZXIAAAAAAAAAAAAJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAAIkNhbm5vdCBmaW5kIHBvb2wgbWFrZXIgYnkgYWRkcmVzcyAFAAAADWNhbGxlckFkZHJlc3MCAAAAFSBvciBubyBsb2NrZWQgYW1vdW50LgMJAABmAAAAAgUAAAAGaGVpZ2h0BQAAABFtaW5XaXRoZHJhd0hlaWdodAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAAMUGxlYXNlIHdhaXQgCQABpAAAAAEFAAAAEW1pbldpdGhkcmF3SGVpZ2h0AgAAABEgYmVmb3JlIHdpdGhkcmF3LgQAAAANYXNzZXRFbWlzc2lvbggFAAAAEnN5bnRoZXRpY0Fzc2V0SW5mbwAAAAhxdWFudGl0eQQAAAAMY3VycmVudFByaWNlCQEAAAANZ2V0QXNzZXRQcmljZQAAAAIFAAAAEnByaWNlT3JhY2xlQWRkcmVzcwUAAAAJYXNzZXRDb2RlBAAAABVwb29sTWFrZXJMb2NrZWRBbW91bnQJAQAAABhnZXRQb29sTWFrZXJMb2NrZWRBbW91bnQAAAACBQAAAAxhc3NldEFkZHJlc3MFAAAADWNhbGxlckFkZHJlc3MEAAAAG3ByaWNlV2l0aE92ZXJjb2xsYXRlcmFsUmF0ZQkAAGgAAAACCQEAAAAdZ2V0QXNzZXRPdmVyQ29sbGF0ZXJhbFBlcmNlbnQAAAABBQAAABZhc3NldENvbmZpZ3VyYXRpb25MaXN0BQAAAAxjdXJyZW50UHJpY2UEAAAAGXVzZG5OZWVkZWRUb0NvdmVyRW1pc3Npb24JAABoAAAAAgUAAAAbcHJpY2VXaXRoT3ZlcmNvbGxhdGVyYWxSYXRlBQAAAA1hc3NldEVtaXNzaW9uAwkAAGYAAAACBQAAABp0b3RhbFVTRE5CYWxhbmNlT25Db250cmFjdAUAAAAZdXNkbk5lZWRlZFRvQ292ZXJFbWlzc2lvbgQAAAAcYW1vdXRBdmFpbGFibGVUb0V4aXRGcm9tUG9vbAkAAGUAAAACBQAAABp0b3RhbFVTRE5CYWxhbmNlT25Db250cmFjdAUAAAAZdXNkbk5lZWRlZFRvQ292ZXJFbWlzc2lvbgQAAAARYW1vdW50Rm9yV2l0aGRyYXcJAABoAAAAAgUAAAATcG9vbE1ha2V0UHJvcG9ydGlvbgUAAAAcYW1vdXRBdmFpbGFibGVUb0V4aXRGcm9tUG9vbAQAAAARZmluYWxMb2NrZWRBbW91bnQJAABlAAAAAgkBAAAAGGdldFBvb2xNYWtlckxvY2tlZEFtb3VudAAAAAIFAAAADGFzc2V0QWRkcmVzcwUAAAANY2FsbGVyQWRkcmVzcwUAAAARYW1vdW50Rm9yV2l0aGRyYXcJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAB1nZXRBc3NldEN1cnJyZW50UG9vbEFtb3VudEtleQAAAAEFAAAADGFzc2V0QWRkcmVzcwkAAGUAAAACCQEAAAAZZ2V0QXNzZXRDdXJyZW50UG9vbEFtb3VudAAAAAEFAAAADGFzc2V0QWRkcmVzcwUAAAARYW1vdW50Rm9yV2l0aGRyYXcJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAACJnZXRQb29sTWFrZXJQYXJ0aWNpcGF0aW9uQW1vdW50S2V5AAAAAgUAAAAMYXNzZXRBZGRyZXNzBQAAAA1jYWxsZXJBZGRyZXNzCQAAZQAAAAIJAQAAAB9nZXRQb29sTWFrZXJQYXJ0aWNpcGF0aW9uQW1vdW50AAAAAgUAAAAMYXNzZXRBZGRyZXNzBQAAAA1jYWxsZXJBZGRyZXNzBQAAABFhbW91bnRGb3JXaXRoZHJhdwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAG2dldFBvb2xNYWtlckxvY2tlZEFtb3VudEtleQAAAAIFAAAADGFzc2V0QWRkcmVzcwUAAAANY2FsbGVyQWRkcmVzcwUAAAARZmluYWxMb2NrZWRBbW91bnQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAANY2FsbGVyQWRkcmVzcwUAAAARYW1vdW50Rm9yV2l0aGRyYXcFAAAAD25ldXRyaW5vQXNzZXRJZAUAAAADbmlsBQAAAANuaWwAAAAALsgbMQ==", "chainId": 84, "height": 1196990, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: 9earhUfVjmBWQKD4nQGRWWQv2eztDqGvmHDK2JGh3KeM Full:
Old | New | Differences | |
---|---|---|---|
1 | - | # no script | |
1 | + | {-# STDLIB_VERSION 4 #-} | |
2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | + | {-# CONTENT_TYPE DAPP #-} | |
4 | + | func convertJsonArrayToList (jsonArray,splitSymbol) = split(jsonArray, splitSymbol) | |
5 | + | ||
6 | + | ||
7 | + | func getStringByAddressAndKey (address,key) = valueOrElse(getString(address, key), "") | |
8 | + | ||
9 | + | ||
10 | + | func getBoolByKey (key) = valueOrElse(getBoolean(this, key), false) | |
11 | + | ||
12 | + | ||
13 | + | let keyAssetCode = 1 | |
14 | + | ||
15 | + | let keyAssetId = 2 | |
16 | + | ||
17 | + | let keyAssetStatus = 3 | |
18 | + | ||
19 | + | let keyAssetPriceDecimals = 4 | |
20 | + | ||
21 | + | let keyAssetBakingAsset = 5 | |
22 | + | ||
23 | + | let keyOvercollateralPercentage = 6 | |
24 | + | ||
25 | + | let keyMinPool = 7 | |
26 | + | ||
27 | + | let keyPriceOracleAddress = 8 | |
28 | + | ||
29 | + | let keyMinBuyPayment = 9 | |
30 | + | ||
31 | + | let keyMinSellPayment = 10 | |
32 | + | ||
33 | + | let keyBuyLockInterval = 11 | |
34 | + | ||
35 | + | let keySellLockInterval = 12 | |
36 | + | ||
37 | + | let keyBuyFee = 13 | |
38 | + | ||
39 | + | let keySellFee = 14 | |
40 | + | ||
41 | + | let keyPoolRedemptionTimeout = 15 | |
42 | + | ||
43 | + | let adminPublicKey = "G1Ebu5AMHaTJFEbZNkZQcJFUQ9KfiYUwupyLG857DcFr" | |
44 | + | ||
45 | + | let neutrinoContractAddressKey = "%s%s__commonConfig__neutrinoContractAddress" | |
46 | + | ||
47 | + | let neutrinoStakingAddressKey = "%s%s__commonConfig__neutrinoStakingAddress" | |
48 | + | ||
49 | + | let minimunPoolFundingAmountKey = "%s%s__commonConfig__minimumPoolFundingAmount" | |
50 | + | ||
51 | + | let isInitializedKey = "%s%s__commonConfig__initialized" | |
52 | + | ||
53 | + | let currentAssetIndexKey = "%s%s__commonConfig__predefinedAssetsActiveIndex" | |
54 | + | ||
55 | + | let assetsAddressListKey = "%s%s__commonConfig__predefinedAssetsList" | |
56 | + | ||
57 | + | let debtTokenIdKey = "%s%s__commonConfig__debtAssetId" | |
58 | + | ||
59 | + | let debtTokenEtalonBalanceKey = "%s%s__commonConfig__debtAssetEtalonBalance" | |
60 | + | ||
61 | + | let defoStakingAddressKey = "%s%s__commonConfig__defoStakingAddress" | |
62 | + | ||
63 | + | let defoStakingPacemakerPubKey = "%s%s__commonConfig__defoStakingPacemakerPub" | |
64 | + | ||
65 | + | let neutrinoAssetIdKey = "neutrino_asset_id" | |
66 | + | ||
67 | + | let nsbtAssetIdKey = "bond_asset_id" | |
68 | + | ||
69 | + | let defoAssetIdKey = "%s__defoAssetId" | |
70 | + | ||
71 | + | let setAssetScriptTxIdKey = "%s__assetScriptTxId" | |
72 | + | ||
73 | + | func getAssetConfigKey (assetAddress) = (("%s%s%s__defoAsset__" + assetAddress) + "__config") | |
74 | + | ||
75 | + | ||
76 | + | func getAssetPriceKey (assetCode) = ("%s%s__assetPrice__" + assetCode) | |
77 | + | ||
78 | + | ||
79 | + | func getAssetInitHeightKey (assetAddress) = (("%s%s%s__defoAsset__" + assetAddress) + "__initHeight") | |
80 | + | ||
81 | + | ||
82 | + | func getAssetActivateHeightKey (assetAddress) = (("%s%s%s__defoAsset__" + assetAddress) + "__activateHeight") | |
83 | + | ||
84 | + | ||
85 | + | func getAssetCurrrentPoolAmountKey (assetAddress) = (("%s%s%s__defoAsset__" + assetAddress) + "__currentPool") | |
86 | + | ||
87 | + | ||
88 | + | func getAssetMaxPoolAmountKey (assetAddress) = (("%s%s%s__defoAsset__" + assetAddress) + "__maxPool") | |
89 | + | ||
90 | + | ||
91 | + | func getAssetMetaKey (assetAddress) = (("%s%s%s__defoAsset__" + assetAddress) + "__meta") | |
92 | + | ||
93 | + | ||
94 | + | func getAssetPoolMakersKey (assetAddress) = (("%s%s%s__defoAsset__" + assetAddress) + "__poolMakers") | |
95 | + | ||
96 | + | ||
97 | + | func getAssetAddressByCodeKey (assetCode) = (("%s%s%s__defoAsset__" + assetCode) + "__addressByAssetCode") | |
98 | + | ||
99 | + | ||
100 | + | func getAssetAddressByAssetIdKey (assetId) = (("%s%s%s__defoAsset__" + assetId) + "__addressByAssetId") | |
101 | + | ||
102 | + | ||
103 | + | func getPoolMakerParticipationAmountKey (assetAddress,poolMakerAddress) = (((("%s%s%s%s__pool__" + assetAddress) + "__") + poolMakerAddress) + "__amount") | |
104 | + | ||
105 | + | ||
106 | + | func getPoolMakerParticipationMaxAmountKey (assetAddress,poolMakerAddress) = (((("%s%s%s%s__pool__" + assetAddress) + "__") + poolMakerAddress) + "__maxAmount") | |
107 | + | ||
108 | + | ||
109 | + | func getPoolMakerLockedAmountKey (assetAddress,poolMakerAddress) = (((("%s%s%s%s__pool__" + assetAddress) + "__") + poolMakerAddress) + "__lockedAmount") | |
110 | + | ||
111 | + | ||
112 | + | func getPoolMakerUnlockHeightKey (assetAddress,poolMakerAddress) = (((("%s%s%s%s__pool__" + assetAddress) + "__") + poolMakerAddress) + "__unlockHeight") | |
113 | + | ||
114 | + | ||
115 | + | func getAssetConfigArray (assetAddress) = convertJsonArrayToList(valueOrErrorMessage(getStringByAddressAndKey(this, getAssetConfigKey(assetAddress)), (("No DEFO Asset " + assetAddress) + "config present")), "__") | |
116 | + | ||
117 | + | ||
118 | + | let neutrinoContract = addressFromStringValue(valueOrErrorMessage(getString(this, neutrinoContractAddressKey), "No neutrino contract specified.")) | |
119 | + | ||
120 | + | let neutrinoAssetId = fromBase58String(valueOrErrorMessage(getString(neutrinoContract, neutrinoAssetIdKey), "No USDN asset id found.")) | |
121 | + | ||
122 | + | let nsbtAssetId = fromBase58String(valueOrErrorMessage(getString(neutrinoContract, nsbtAssetIdKey), "No NSBT asset id found")) | |
123 | + | ||
124 | + | let minimumPoolFunding = valueOrErrorMessage(getInteger(this, minimunPoolFundingAmountKey), "Minimum pool funding amount is not specified.") | |
125 | + | ||
126 | + | let assetStatus = $Tuple3("PROPOSED", "READY", "ISSUED") | |
127 | + | ||
128 | + | let predefinedAssetContracts = valueOrErrorMessage(getString(this, assetsAddressListKey), "No pool of predeployed asset contracts found.") | |
129 | + | ||
130 | + | let predefinedAssetsList = convertJsonArrayToList(predefinedAssetContracts, ",") | |
131 | + | ||
132 | + | let currentAssetIndex = valueOrElse(getInteger(this, currentAssetIndexKey), 0) | |
133 | + | ||
134 | + | let debtToken = fromBase58String(valueOrErrorMessage(getString(this, debtTokenIdKey), "No debt token found")) | |
135 | + | ||
136 | + | let multiplicator = 1000000 | |
137 | + | ||
138 | + | let debtTokenReissueAmount = valueOrElse(getInteger(this, debtTokenEtalonBalanceKey), 0) | |
139 | + | ||
140 | + | func getAssetAddressByCode (assetSymbol) = valueOrElse(getString(this, getAssetAddressByCodeKey(assetSymbol)), "") | |
141 | + | ||
142 | + | ||
143 | + | func getAssetCode (assetConfig) = assetConfig[keyAssetCode] | |
144 | + | ||
145 | + | ||
146 | + | func getAssetID (assetConfig) = assetConfig[keyAssetId] | |
147 | + | ||
148 | + | ||
149 | + | func getAssetStatus (assetConfig) = assetConfig[keyAssetStatus] | |
150 | + | ||
151 | + | ||
152 | + | func getAssetPriceDecimals (assetConfig) = parseIntValue(assetConfig[keyAssetPriceDecimals]) | |
153 | + | ||
154 | + | ||
155 | + | func getAssetBakingAssetId (assetConfig) = assetConfig[keyAssetBakingAsset] | |
156 | + | ||
157 | + | ||
158 | + | func getAssetOverCollateralPercent (assetConfig) = parseIntValue(assetConfig[keyOvercollateralPercentage]) | |
159 | + | ||
160 | + | ||
161 | + | func getAssetMinRequiredPoolAmount (assetConfig) = parseIntValue(assetConfig[keyMinPool]) | |
162 | + | ||
163 | + | ||
164 | + | func getAssetPriceOracleAddress (assetConfig) = assetConfig[keyPriceOracleAddress] | |
165 | + | ||
166 | + | ||
167 | + | func getMinBuyPaymentPerAsset (assetConfig) = parseIntValue(assetConfig[keyMinBuyPayment]) | |
168 | + | ||
169 | + | ||
170 | + | func getMinSellPaymentPerAsset (assetConfig) = parseIntValue(assetConfig[keyMinSellPayment]) | |
171 | + | ||
172 | + | ||
173 | + | func getBuyLockIntervalPerAsset (assetConfig) = parseIntValue(assetConfig[keyBuyLockInterval]) | |
174 | + | ||
175 | + | ||
176 | + | func getSellLockIntervalPerAsset (assetConfig) = parseIntValue(assetConfig[keySellLockInterval]) | |
177 | + | ||
178 | + | ||
179 | + | func getBuyFeePerAsset (assetConfig) = parseIntValue(assetConfig[keyBuyFee]) | |
180 | + | ||
181 | + | ||
182 | + | func getSellFeePerAsset (assetConfig) = parseIntValue(assetConfig[keySellFee]) | |
183 | + | ||
184 | + | ||
185 | + | func getRedemptionTimeoutBlocks (assetConfig) = parseIntValue(assetConfig[keyPoolRedemptionTimeout]) | |
186 | + | ||
187 | + | ||
188 | + | func getAssetPoolMakers (assetAddress) = valueOrElse(getString(this, getAssetPoolMakersKey(assetAddress)), "") | |
189 | + | ||
190 | + | ||
191 | + | func getAssetInitHeight (assetAddress) = valueOrElse(getInteger(this, getAssetInitHeightKey(assetAddress)), 0) | |
192 | + | ||
193 | + | ||
194 | + | func getAssetActivateHeight (assetAddress) = valueOrElse(getInteger(this, getAssetActivateHeightKey(assetAddress)), 0) | |
195 | + | ||
196 | + | ||
197 | + | func getAssetCurrentPoolAmount (assetAddress) = valueOrElse(getInteger(this, getAssetCurrrentPoolAmountKey(assetAddress)), 0) | |
198 | + | ||
199 | + | ||
200 | + | func getAssetMaxPoolAmount (assetAddress) = valueOrElse(getInteger(this, getAssetMaxPoolAmountKey(assetAddress)), 0) | |
201 | + | ||
202 | + | ||
203 | + | func getAssetMeta (assetAddress) = valueOrElse(getString(this, getAssetMetaKey(assetAddress)), "") | |
204 | + | ||
205 | + | ||
206 | + | func getPoolMakerParticipationAmount (assetAddress,poolMakerAddress) = valueOrElse(getInteger(this, getPoolMakerParticipationAmountKey(assetAddress, poolMakerAddress)), 0) | |
207 | + | ||
208 | + | ||
209 | + | func getPoolMakerParticipationMaxAmount (assetAddress,poolMakerAddress) = valueOrElse(getInteger(this, getPoolMakerParticipationMaxAmountKey(assetAddress, poolMakerAddress)), 0) | |
210 | + | ||
211 | + | ||
212 | + | func getPoolMakerLockedAmount (assetAddress,poolMakerAddress) = valueOrElse(getInteger(this, getPoolMakerLockedAmountKey(assetAddress, poolMakerAddress)), 0) | |
213 | + | ||
214 | + | ||
215 | + | func getPoolMakerUnlockHeight (assetAddress,poolMakerAddress) = valueOrElse(getInteger(this, getPoolMakerUnlockHeightKey(assetAddress, poolMakerAddress)), 0) | |
216 | + | ||
217 | + | ||
218 | + | func getAssetPrice (priceOracleAddress,assetCode) = valueOrErrorMessage(getInteger(priceOracleAddress, getAssetPriceKey(assetCode)), "No Asset price found") | |
219 | + | ||
220 | + | ||
221 | + | func composeAssetConfigurationString (assetCode,assetId,assetStatus,priceDecimals,backingAssetId,overCollateralPercent,minPool,priceOracleAddress,minBuyPayment,minSellPayment,buyLockInterval,sellLockInterval,buyFee,sellFee,poolRedemptionTimeout) = makeString(["%s%s%s%d%s%d%d%s%d%d%d%d%d%d%d", assetCode, assetId, assetStatus, toString(priceDecimals), backingAssetId, toString(overCollateralPercent), toString(minPool), priceOracleAddress, toString(minBuyPayment), toString(minSellPayment), toString(buyLockInterval), toString(sellLockInterval), toString(buyFee), toString(sellFee), toString(poolRedemptionTimeout)], "__") | |
222 | + | ||
223 | + | ||
224 | + | @Callable(i) | |
225 | + | func init (neutrinoContractAddress,neutrinoStakingAddress,minimunPoolFundingAmount,predefinedAssetList,currentAssetIndex,debtEthalonBalance,defoStakingAddress,defoStakingPacemakerPub) = if ((toBase58String(i.callerPublicKey) != adminPublicKey)) | |
226 | + | then throw("Only Admin can perform contract operation.") | |
227 | + | else if ((getBoolByKey(isInitializedKey) == true)) | |
228 | + | then throw("Contract was already initialized.") | |
229 | + | else { | |
230 | + | let issueDebt = Issue("DEFO_DEBT", "DEFO Debt Token.", 1, 6, true) | |
231 | + | let debtTokenId = calculateAssetId(issueDebt) | |
232 | + | [StringEntry(neutrinoContractAddressKey, neutrinoContractAddress), StringEntry(neutrinoStakingAddressKey, neutrinoStakingAddress), IntegerEntry(minimunPoolFundingAmountKey, minimunPoolFundingAmount), StringEntry(assetsAddressListKey, predefinedAssetList), IntegerEntry(currentAssetIndexKey, currentAssetIndex), IntegerEntry(debtTokenEtalonBalanceKey, debtEthalonBalance), StringEntry(debtTokenIdKey, toBase58String(debtTokenId)), StringEntry(defoStakingAddressKey, defoStakingAddress), StringEntry(defoStakingPacemakerPubKey, defoStakingPacemakerPub), BooleanEntry(isInitializedKey, true), issueDebt, Burn(debtTokenId, 1)] | |
233 | + | } | |
234 | + | ||
235 | + | ||
236 | + | ||
237 | + | @Callable(i) | |
238 | + | func proposeAsset (assetCode,meta,minPool,priceOracleAddress,overCollateralPercent,backingAssetId,priceDecimals,minBuyPayment,minSellPayment,buyLockInterval,sellLockInterval,buyFee,sellFee,poolRedemptionTimeout) = if ((toBase58String(i.callerPublicKey) != adminPublicKey)) | |
239 | + | then throw("Only Admin can perform contract operation.") | |
240 | + | else if ((getBoolByKey(isInitializedKey) == false)) | |
241 | + | then throw("Contract is not yet ready.") | |
242 | + | else if ((fromBase58String(backingAssetId) != neutrinoAssetId)) | |
243 | + | then throw("Baking asset id could be USDN only.") | |
244 | + | else if ((getAssetAddressByCode(assetCode) != "")) | |
245 | + | then throw((("Asset with passed code " + assetCode) + " has already been proposed.")) | |
246 | + | else if ((minimumPoolFunding > minPool)) | |
247 | + | then throw(("Minimum pool amount should be greater or equals to " + toString(minimumPoolFunding))) | |
248 | + | else if (if (if (if (if (if (if (if ((0 > overCollateralPercent)) | |
249 | + | then true | |
250 | + | else (0 > priceDecimals)) | |
251 | + | then true | |
252 | + | else (0 > minBuyPayment)) | |
253 | + | then true | |
254 | + | else (0 > minSellPayment)) | |
255 | + | then true | |
256 | + | else (0 > buyLockInterval)) | |
257 | + | then true | |
258 | + | else (0 > sellLockInterval)) | |
259 | + | then true | |
260 | + | else (0 > buyFee)) | |
261 | + | then true | |
262 | + | else (0 > sellFee)) | |
263 | + | then throw("One of the passed parameters is invalid.") | |
264 | + | else { | |
265 | + | let priceOracleAddressValid = valueOrErrorMessage(addressFromStringValue(priceOracleAddress), "Passed Price Oracle Address is not valid.") | |
266 | + | let assetAddress = predefinedAssetsList[currentAssetIndex] | |
267 | + | let defoAssetId = valueOrErrorMessage(getString(valueOrErrorMessage(addressFromString(assetAddress), ""), defoAssetIdKey), "No defo asset ID found.") | |
268 | + | [StringEntry(getAssetConfigKey(assetAddress), composeAssetConfigurationString(assetCode, defoAssetId, assetStatus._1, priceDecimals, backingAssetId, overCollateralPercent, minPool, priceOracleAddress, minBuyPayment, minSellPayment, buyLockInterval, sellLockInterval, buyFee, sellFee, poolRedemptionTimeout)), StringEntry(getAssetAddressByCodeKey(assetCode), assetAddress), StringEntry(getAssetMetaKey(assetAddress), meta), IntegerEntry(getAssetInitHeightKey(assetAddress), height), IntegerEntry(currentAssetIndexKey, (currentAssetIndex + 1)), StringEntry(getAssetAddressByAssetIdKey(defoAssetId), assetAddress)] | |
269 | + | } | |
270 | + | ||
271 | + | ||
272 | + | ||
273 | + | @Callable(i) | |
274 | + | func fundLiquidityPool (assetCode) = { | |
275 | + | let assetAddress = getAssetAddressByCode(assetCode) | |
276 | + | let assetConfigurationList = getAssetConfigArray(assetAddress) | |
277 | + | let attachedPayment = value(i.payments[0]) | |
278 | + | if ((toBase58String(i.callerPublicKey) != adminPublicKey)) | |
279 | + | then throw("Only Admin can perform contract operation.") | |
280 | + | else if ((getBoolByKey(isInitializedKey) == false)) | |
281 | + | then throw("Contract is not yet ready.") | |
282 | + | else if ((attachedPayment.assetId != neutrinoAssetId)) | |
283 | + | then throw("Liquidity pool could be funded with USDN only.") | |
284 | + | else if ((attachedPayment.amount == 0)) | |
285 | + | then throw("Incorrect attached payment amount.") | |
286 | + | else if ((assetAddress == "")) | |
287 | + | then throw((("Cannot find liquidity pool for asset " + assetCode) + ".")) | |
288 | + | else { | |
289 | + | let finalPoolAmount = (attachedPayment.amount + getAssetCurrentPoolAmount(assetAddress)) | |
290 | + | let maxPoolAmount = getAssetMaxPoolAmount(assetAddress) | |
291 | + | let poolMakerAddress = toString(i.caller) | |
292 | + | let currentPoolMakerBalance = getPoolMakerParticipationAmount(assetAddress, poolMakerAddress) | |
293 | + | let maxPoolMakerBalance = getPoolMakerParticipationMaxAmount(assetAddress, poolMakerAddress) | |
294 | + | let currentPoolStatus = getAssetStatus(assetConfigurationList) | |
295 | + | let finalPoolStatus = if (if ((finalPoolAmount >= getAssetMinRequiredPoolAmount(assetConfigurationList))) | |
296 | + | then (currentPoolStatus == assetStatus._1) | |
297 | + | else false) | |
298 | + | then assetStatus._2 | |
299 | + | else currentPoolStatus | |
300 | + | let currentPoolMakers = getAssetPoolMakers(assetAddress) | |
301 | + | let newPoolMakers = if ((currentPoolMakers == "")) | |
302 | + | then poolMakerAddress | |
303 | + | else if (contains(currentPoolMakers, poolMakerAddress)) | |
304 | + | then currentPoolMakers | |
305 | + | else ((currentPoolMakers + ",") + toString(i.caller)) | |
306 | + | let aCode = getAssetCode(assetConfigurationList) | |
307 | + | let aID = getAssetID(assetConfigurationList) | |
308 | + | let aPriceDecimals = getAssetPriceDecimals(assetConfigurationList) | |
309 | + | let aBakingAssetId = getAssetBakingAssetId(assetConfigurationList) | |
310 | + | let aOverCollateralPercent = getAssetOverCollateralPercent(assetConfigurationList) | |
311 | + | let aMinRequiredPool = getAssetMinRequiredPoolAmount(assetConfigurationList) | |
312 | + | let aPriceOracleAddress = getAssetPriceOracleAddress(assetConfigurationList) | |
313 | + | let aMinBuyPayment = getMinBuyPaymentPerAsset(assetConfigurationList) | |
314 | + | let aMinSellPayment = getMinSellPaymentPerAsset(assetConfigurationList) | |
315 | + | let aBuyLockInterval = getBuyLockIntervalPerAsset(assetConfigurationList) | |
316 | + | let aSellLockInterval = getSellLockIntervalPerAsset(assetConfigurationList) | |
317 | + | let aBuyFee = getBuyFeePerAsset(assetConfigurationList) | |
318 | + | let aSellFee = getSellFeePerAsset(assetConfigurationList) | |
319 | + | let aRedemptionTimeoutBlocks = getRedemptionTimeoutBlocks(assetConfigurationList) | |
320 | + | let newPoolMakerBalance = (currentPoolMakerBalance + i.payments[0].amount) | |
321 | + | let result = [IntegerEntry(getPoolMakerParticipationAmountKey(assetAddress, toString(i.caller)), newPoolMakerBalance), IntegerEntry(getPoolMakerParticipationMaxAmountKey(assetAddress, toString(i.caller)), if ((newPoolMakerBalance > maxPoolMakerBalance)) | |
322 | + | then newPoolMakerBalance | |
323 | + | else maxPoolMakerBalance), IntegerEntry(getAssetCurrrentPoolAmountKey(assetAddress), finalPoolAmount), IntegerEntry(getAssetMaxPoolAmountKey(assetAddress), if ((finalPoolAmount > maxPoolAmount)) | |
324 | + | then finalPoolAmount | |
325 | + | else maxPoolAmount), DeleteEntry(getAssetConfigKey(assetAddress)), StringEntry(getAssetPoolMakersKey(assetAddress), newPoolMakers), StringEntry(getAssetConfigKey(assetAddress), composeAssetConfigurationString(aCode, aID, finalPoolStatus, aPriceDecimals, aBakingAssetId, aOverCollateralPercent, aMinRequiredPool, aPriceOracleAddress, aMinBuyPayment, aMinSellPayment, aBuyLockInterval, aSellLockInterval, aBuyFee, aSellFee, aRedemptionTimeoutBlocks))] | |
326 | + | if ((currentPoolStatus == assetStatus._3)) | |
327 | + | then (result :+ ScriptTransfer(addressFromStringValue(assetAddress), attachedPayment.amount, neutrinoAssetId)) | |
328 | + | else result | |
329 | + | } | |
330 | + | } | |
331 | + | ||
332 | + | ||
333 | + | ||
334 | + | @Callable(i) | |
335 | + | func activateAsset (assetCode) = { | |
336 | + | let assetAddress = getAssetAddressByCode(assetCode) | |
337 | + | let assetConfigurationList = getAssetConfigArray(assetAddress) | |
338 | + | let currentAssetPoolAmount = getAssetCurrentPoolAmount(assetAddress) | |
339 | + | let aCode = getAssetCode(assetConfigurationList) | |
340 | + | let aCurrentStatus = getAssetStatus(assetConfigurationList) | |
341 | + | let aID = getAssetID(assetConfigurationList) | |
342 | + | let aPriceDecimals = getAssetPriceDecimals(assetConfigurationList) | |
343 | + | let aBakingAssetId = getAssetBakingAssetId(assetConfigurationList) | |
344 | + | let aOverCollateralPercent = getAssetOverCollateralPercent(assetConfigurationList) | |
345 | + | let aMinRequiredPool = getAssetMinRequiredPoolAmount(assetConfigurationList) | |
346 | + | let aPriceOracleAddress = getAssetPriceOracleAddress(assetConfigurationList) | |
347 | + | let aMinBuyPayment = getMinBuyPaymentPerAsset(assetConfigurationList) | |
348 | + | let aMinSellPayment = getMinSellPaymentPerAsset(assetConfigurationList) | |
349 | + | let aBuyLockInterval = getBuyLockIntervalPerAsset(assetConfigurationList) | |
350 | + | let aSellLockInterval = getSellLockIntervalPerAsset(assetConfigurationList) | |
351 | + | let aBuyFee = getBuyFeePerAsset(assetConfigurationList) | |
352 | + | let aSellFee = getSellFeePerAsset(assetConfigurationList) | |
353 | + | let aRedemptionTimeoutBlocks = getRedemptionTimeoutBlocks(assetConfigurationList) | |
354 | + | if ((toBase58String(i.callerPublicKey) != adminPublicKey)) | |
355 | + | then throw("Only Admin can perform contract operation.") | |
356 | + | else if ((getBoolByKey(isInitializedKey) == false)) | |
357 | + | then throw("Contract is not yet ready.") | |
358 | + | else if ((aCurrentStatus != assetStatus._2)) | |
359 | + | then throw((("Asset is not in READY status. Current status is " + aCurrentStatus) + ".")) | |
360 | + | else if ((assetAddress == "")) | |
361 | + | then throw((("Cannot find asset " + assetCode) + ".")) | |
362 | + | else if ((minimumPoolFunding > currentAssetPoolAmount)) | |
363 | + | then throw((((("Cannot issue asset as liquidity pool amount (" + toString(currentAssetPoolAmount)) + ") is less than required (") + toString(minimumPoolFunding)) + ")")) | |
364 | + | else { | |
365 | + | let issueDebt = Reissue(debtToken, debtTokenReissueAmount, true) | |
366 | + | [IntegerEntry(getAssetActivateHeightKey(assetAddress), height), DeleteEntry(getAssetConfigKey(assetAddress)), StringEntry(getAssetConfigKey(assetAddress), composeAssetConfigurationString(aCode, aID, assetStatus._3, aPriceDecimals, aBakingAssetId, aOverCollateralPercent, aMinRequiredPool, aPriceOracleAddress, aMinBuyPayment, aMinSellPayment, aBuyLockInterval, aSellLockInterval, aBuyFee, aSellFee, aRedemptionTimeoutBlocks)), issueDebt, ScriptTransfer(addressFromStringValue(assetAddress), currentAssetPoolAmount, neutrinoAssetId), ScriptTransfer(addressFromStringValue(assetAddress), debtTokenReissueAmount, debtToken)] | |
367 | + | } | |
368 | + | } | |
369 | + | ||
370 | + | ||
371 | + | ||
372 | + | @Callable(i) | |
373 | + | func redeemFromPool (assetCode,amount) = { | |
374 | + | let assetAddress = getAssetAddressByCode(assetCode) | |
375 | + | let assetConfigurationList = getAssetConfigArray(assetAddress) | |
376 | + | let callerAddress = toString(i.caller) | |
377 | + | let totalAmountInPoolByCaller = getPoolMakerParticipationAmount(assetAddress, callerAddress) | |
378 | + | let lockedAmountByPoolMaker = getPoolMakerLockedAmount(assetAddress, callerAddress) | |
379 | + | if ((toBase58String(i.callerPublicKey) != adminPublicKey)) | |
380 | + | then throw("Only Admin can perform contract operation.") | |
381 | + | else if ((getBoolByKey(isInitializedKey) == false)) | |
382 | + | then throw("Contract is not yet ready.") | |
383 | + | else if ((assetAddress == "")) | |
384 | + | then throw((("Cannot find asset " + assetCode) + ".")) | |
385 | + | else if (if (if ((0 > amount)) | |
386 | + | then true | |
387 | + | else (totalAmountInPoolByCaller == 0)) | |
388 | + | then true | |
389 | + | else (amount > totalAmountInPoolByCaller)) | |
390 | + | then throw((("Cannot find pool maker by address " + callerAddress) + " or amount passed is not correct.")) | |
391 | + | else if ((lockedAmountByPoolMaker > 0)) | |
392 | + | then throw("Pool maker already has initiated redemption that is not withdrawn yet.") | |
393 | + | else [IntegerEntry(getPoolMakerLockedAmountKey(assetAddress, callerAddress), amount), IntegerEntry(getPoolMakerUnlockHeightKey(assetAddress, callerAddress), (height + getRedemptionTimeoutBlocks(assetConfigurationList)))] | |
394 | + | } | |
395 | + | ||
396 | + | ||
397 | + | ||
398 | + | @Callable(i) | |
399 | + | func withdraw (assetCode) = { | |
400 | + | let assetConfigurationList = getAssetConfigArray(assetCode) | |
401 | + | let assetAddress = getAssetAddressByCode(assetCode) | |
402 | + | let priceOracleAddress = addressFromStringValue(getAssetPriceOracleAddress(assetConfigurationList)) | |
403 | + | let callerAddress = toString(i.caller) | |
404 | + | let syntheticAssetInfo = valueOrErrorMessage(assetInfo(fromBase58String(assetAddress)), ("Cannot find asset by id " + assetAddress)) | |
405 | + | let totalUSDNBalanceOnContract = assetBalance(this, neutrinoAssetId) | |
406 | + | let totalAmountInPoolByPoolMaker = getPoolMakerParticipationAmount(assetAddress, callerAddress) | |
407 | + | let lockedAmountByPoolMaker = getPoolMakerLockedAmount(assetAddress, callerAddress) | |
408 | + | let minWithdrawHeight = getPoolMakerUnlockHeight(assetAddress, callerAddress) | |
409 | + | let poolMaketProportion = (getAssetMaxPoolAmount(assetAddress) / getPoolMakerParticipationMaxAmount(assetAddress, callerAddress)) | |
410 | + | if ((toBase58String(i.callerPublicKey) != adminPublicKey)) | |
411 | + | then throw("Only Admin can perform contract operation.") | |
412 | + | else if ((getBoolByKey(isInitializedKey) == false)) | |
413 | + | then throw("Contract is not yet ready.") | |
414 | + | else if ((getBoolByKey(isInitializedKey) == false)) | |
415 | + | then throw("Contract is not yet ready.") | |
416 | + | else if ((assetAddress == "")) | |
417 | + | then throw((("Cannot find asset " + assetCode) + ".")) | |
418 | + | else if ((totalAmountInPoolByPoolMaker == 0)) | |
419 | + | then throw((("Cannot find pool maker by address " + callerAddress) + " or no locked amount.")) | |
420 | + | else if ((height > minWithdrawHeight)) | |
421 | + | then throw((("Please wait " + toString(minWithdrawHeight)) + " before withdraw.")) | |
422 | + | else { | |
423 | + | let assetEmission = syntheticAssetInfo.quantity | |
424 | + | let currentPrice = getAssetPrice(priceOracleAddress, assetCode) | |
425 | + | let poolMakerLockedAmount = getPoolMakerLockedAmount(assetAddress, callerAddress) | |
426 | + | let priceWithOvercollateralRate = (getAssetOverCollateralPercent(assetConfigurationList) * currentPrice) | |
427 | + | let usdnNeededToCoverEmission = (priceWithOvercollateralRate * assetEmission) | |
428 | + | if ((totalUSDNBalanceOnContract > usdnNeededToCoverEmission)) | |
429 | + | then { | |
430 | + | let amoutAvailableToExitFromPool = (totalUSDNBalanceOnContract - usdnNeededToCoverEmission) | |
431 | + | let amountForWithdraw = (poolMaketProportion * amoutAvailableToExitFromPool) | |
432 | + | let finalLockedAmount = (getPoolMakerLockedAmount(assetAddress, callerAddress) - amountForWithdraw) | |
433 | + | [IntegerEntry(getAssetCurrrentPoolAmountKey(assetAddress), (getAssetCurrentPoolAmount(assetAddress) - amountForWithdraw)), IntegerEntry(getPoolMakerParticipationAmountKey(assetAddress, callerAddress), (getPoolMakerParticipationAmount(assetAddress, callerAddress) - amountForWithdraw)), IntegerEntry(getPoolMakerLockedAmountKey(assetAddress, callerAddress), finalLockedAmount), ScriptTransfer(addressFromStringValue(callerAddress), amountForWithdraw, neutrinoAssetId)] | |
434 | + | } | |
435 | + | else nil | |
436 | + | } | |
437 | + | } | |
438 | + | ||
439 | + |
github/deemru/w8io/026f985 44.14 ms ◑