tx · Ejm9dCEZ8C5yuYQQ7q7LfCiRbvA9YtZSx1kpLsFbe3Eo 3NAkRz8VVS1aizMWiZ7Hxs3N9vrfhpR6579: -0.01000000 Waves 2021.04.08 12:18 [1473279] smart account 3NAkRz8VVS1aizMWiZ7Hxs3N9vrfhpR6579 > SELF 0.00000000 Waves
{ "type": 13, "id": "Ejm9dCEZ8C5yuYQQ7q7LfCiRbvA9YtZSx1kpLsFbe3Eo", "fee": 1000000, "feeAssetId": null, "timestamp": 1617873580465, "version": 1, "sender": "3NAkRz8VVS1aizMWiZ7Hxs3N9vrfhpR6579", "senderPublicKey": "FfAdQadqxbreLcPRBWUwLEMjbdgTBwTq2VCwSD18LrG1", "proofs": [ "4S2RRisynj7ZNyUHRhMicvMLMVeWKWgtQ3GdEXTeeJCJ4yFZPszw848RQui6PPyhNQz67vvo1YJWkzAAosPch5pX" ], "script": "base64:AAIEAAAAAAAAADsIAhIQCg4ICAgBCAEBAQgBAQEBCBIDCgEBEgASABIFCgMICAgSBQoDCAgIEgMKAQgSBAoCCAESAwoBCAAAAEsAAAAAA1NFUAIAAAACX18BAAAAD2dldFN0cmluZ09yRmFpbAAAAAEAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAADa2V5CQABLAAAAAICAAAAFU5vIGRhdGEgZm9yIHRoaXMua2V5PQUAAAADa2V5AQAAABBnZXRCb29sZWFuT3JGYWlsAAAAAQAAAANrZXkJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBsAAAACBQAAAAR0aGlzBQAAAANrZXkJAAEsAAAAAgIAAAAVTm8gZGF0YSBmb3IgdGhpcy5rZXk9BQAAAANrZXkBAAAADGdldEludE9yRmFpbAAAAAEAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAADa2V5CQABLAAAAAICAAAAFU5vIGRhdGEgZm9yIHRoaXMua2V5PQUAAAADa2V5AQAAAA5mYWlsRXhlY3V0ZUdldAAAAAUAAAADbXNnAAAADGJhc2VBc3NldFN0cgAAAA51c2VyQWRkcmVzc1N0cgAAAA1zdWJtaXRUeElkU3RyAAAADW9wZXJhdGlvblR5cGUJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIFAAAAA21zZwIAAAAMOiBiYXNlQXNzZXQ9BQAAAAxiYXNlQXNzZXRTdHICAAAADSB1c2VyQWRkcmVzcz0FAAAADnVzZXJBZGRyZXNzU3RyAgAAAAwgc3VibWl0VHhJZD0FAAAADXN1Ym1pdFR4SWRTdHICAAAACyBvcGVyYXRpb249BQAAAA1vcGVyYXRpb25UeXBlAQAAABdmYWlsU3VibWl0TGltaXRzRXhjZWVkcwAAAAQAAAANcmVtYWluaW5nQmFzZQAAAA5yZW1haW5pbmdTaGFyZQAAABBuZXdSZW1haW5pbmdCYXNlAAAAEW5ld1JlbWFpbmluZ1NoYXJlCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACtzdWJtaXQgb3BlcmF0aW9uIGxpbWl0cyBoYXZlIGJlZW4gcmVhY2hlZDogAgAAABIgcmVtYWluaW5nQmFzZVZhbD0JAAGkAAAAAQUAAAANcmVtYWluaW5nQmFzZQIAAAATIHJlbWFpbmluZ1NoYXJlVmFsPQkAAaQAAAABBQAAAA5yZW1haW5pbmdTaGFyZQIAAAAVIG5ld1JlbWFpbmluZ0Jhc2VWYWw9CQABpAAAAAEFAAAAEG5ld1JlbWFpbmluZ0Jhc2UCAAAAFiBuZXdSZW1haW5pbmdTaGFyZVZhbD0JAAGkAAAAAQUAAAARbmV3UmVtYWluaW5nU2hhcmUBAAAAFGZhaWxUb3B1cE1hbmFnZXJPbmx5AAAAAQAAABN0b3B1cE1hbmFnZXJBZGRyZXNzCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAACNvcGVydGlvbiBkZW5pZWQ6IG9ubHkgdG9wVXBNYW5hZ2VyPQUAAAATdG9wdXBNYW5hZ2VyQWRkcmVzcwIAAAAbIGNhbiBzZW5kIHN1Y2ggdHJhbnNhY3Rpb25zAQAAABFjb252ZXJ0U2hhcmUyQmFzZQAAAAMAAAALc2hhcmVBbW91bnQAAAAFcHJpY2UAAAAJcHJpY2VNdWx0CQAAawAAAAMFAAAAC3NoYXJlQW1vdW50BQAAAAVwcmljZQUAAAAJcHJpY2VNdWx0AQAAABFjb252ZXJ0QmFzZTJTaGFyZQAAAAMAAAAKYmFzZUFtb3VudAAAAAVwcmljZQAAAAlwcmljZU11bHQJAABrAAAAAwUAAAAKYmFzZUFtb3VudAUAAAAJcHJpY2VNdWx0BQAAAAVwcmljZQEAAAALa2V5QXNzZXRDZmcAAAABAAAADGJhc2VBc3NldFN0cgkAASwAAAACAgAAABclcyVzJXNfX2NvbmZpZ19fYXNzZXRfXwUAAAAMYmFzZUFzc2V0U3RyAQAAABZrZXlOZXh0SW50ZXJuYWxBc3NldElkAAAAAAIAAAAXJXNfX25leHRJbnRlcm5hbEFzc2V0SWQBAAAADGtleVByaWNlTGFzdAAAAAEAAAAVaW50ZXJuYWxCYXNldEFzc2V0U3RyCQABLAAAAAICAAAAFSVzJXMlZF9fcHJpY2VfX2xhc3RfXwUAAAAVaW50ZXJuYWxCYXNldEFzc2V0U3RyAQAAAAtrZXlQcmljZUFUSAAAAAEAAAAVaW50ZXJuYWxCYXNldEFzc2V0U3RyCQABLAAAAAICAAAAFCVzJXMlZF9fcHJpY2VfX2F0aF9fBQAAABVpbnRlcm5hbEJhc2V0QXNzZXRTdHIBAAAAEmtleVByaWNlQnlUb3BVcElkeAAAAAIAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIAAAAIdG9wVXBJZHgJAAS5AAAAAgkABEwAAAACAgAAABslcyVzJWQlZF9fcHJpY2VfX2J5VG9wVXBJZHgJAARMAAAAAgUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIJAARMAAAAAgkAAaQAAAABBQAAAAh0b3BVcElkeAUAAAADbmlsBQAAAANTRVABAAAAD2tleVByaWNlSGlzdG9yeQAAAAMAAAAVaW50ZXJuYWxCYXNldEFzc2V0U3RyAAAAAWgAAAAJdGltZXN0YW1wCQAEuQAAAAIJAARMAAAAAgIAAAAaJXMlcyVkJWQlZF9fcHJpY2VfX2hpc3RvcnkJAARMAAAAAgUAAAAVaW50ZXJuYWxCYXNldEFzc2V0U3RyCQAETAAAAAIJAAGkAAAAAQUAAAABaAkABEwAAAACCQABpAAAAAEFAAAACXRpbWVzdGFtcAUAAAADbmlsBQAAAANTRVABAAAADmtleVRvdGFsTG9ja2VkAAAAAQAAABVpbnRlcm5hbEJhc2V0QXNzZXRTdHIJAAEsAAAAAgIAAAAXJXMlcyVkX190b3RhbF9fbG9ja2VkX18FAAAAFWludGVybmFsQmFzZXRBc3NldFN0cgEAAAAUa2V5VG90YWxMb2NrZWRCeVVzZXIAAAACAAAAFGludGVybmFsQmFzZUFzc2V0U3RyAAAADnVzZXJBZGRyZXNzU3RyCQAEuQAAAAIJAARMAAAAAgIAAAAXJXMlcyVkJXNfX3RvdGFsX19sb2NrZWQJAARMAAAAAgUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIJAARMAAAAAgUAAAAOdXNlckFkZHJlc3NTdHIFAAAAA25pbAUAAAADU0VQAQAAAB9rZXlNYXBwaW5nc0ludGVybmFsMmJhc2VBc3NldElkAAAAAQAAABFpbnRlcm5hbEJhc2VBc3NldAkAASwAAAACAgAAACglcyVzJWRfX21hcHBpbmdzX19pbnRlcm5hbDJiYXNlQXNzZXRJZF9fCQABpAAAAAEFAAAAEWludGVybmFsQmFzZUFzc2V0AQAAAB9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkAAAAAQAAAAxiYXNlQXNzZXRTdHIJAAEsAAAAAgIAAAAoJXMlcyVzX19tYXBwaW5nc19fYmFzZUFzc2V0MmludGVybmFsSWRfXwUAAAAMYmFzZUFzc2V0U3RyAQAAABxrZXlNYXBwaW5nc1NoYXJlMmJhc2VBc3NldElkAAAAAQAAAA1zaGFyZUFzc2V0U3RyCQABLAAAAAICAAAAJSVzJXMlc19fbWFwcGluZ3NfX3NoYXJlMmJhc2VBc3NldElkX18FAAAADXNoYXJlQXNzZXRTdHIBAAAAHGtleU1hcHBpbmdzQmFzZUFzc2V0MnNoYXJlSWQAAAABAAAADGJhc2VBc3NldFN0cgkAASwAAAACAgAAACUlcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyc2hhcmVJZF9fBQAAAAxiYXNlQXNzZXRTdHIBAAAAGmtleVNodXRkb3duU3VibWl0T3BlcmF0aW9uAAAAAQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgkAASwAAAACAgAAABolcyVzJWRfX3NodXRkb3duX19zdWJtaXRfXwUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIBAAAAEmtleVNodXRkb3duTWFuYWdlcgAAAAEAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIJAAEsAAAAAgIAAAAbJXMlcyVkX19zaHV0ZG93bl9fbWFuYWdlcl9fBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgEAAAASa2V5VG9wVXBDdXJyZW50SWR4AAAAAQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgkAASwAAAACAgAAABslcyVzJWRfX3RvcHVwX19jdXJyZW50SWR4X18FAAAAFGludGVybmFsQmFzZUFzc2V0U3RyAQAAABJrZXlUb3BVcExhc3RIZWlnaHQAAAACAAAAFWludGVybmFsQmFzZXRBc3NldFN0cgAAAAZzZW5kZXIJAAS5AAAAAgkABEwAAAACAgAAAB8lcyVzJXMlZCVzX190b3B1cF9fbGFzdF9faGVpZ2h0CQAETAAAAAIFAAAAFWludGVybmFsQmFzZXRBc3NldFN0cgkABEwAAAACBQAAAAZzZW5kZXIFAAAAA25pbAUAAAADU0VQAQAAAA5rZXlUb3B1cE11dGV4dAAAAAEAAAAVaW50ZXJuYWxCYXNldEFzc2V0U3RyCQABLAAAAAICAAAAFiVzJXMlZF9fdG9wdXBfX211dGV4X18FAAAAFWludGVybmFsQmFzZXRBc3NldFN0cgEAAAAVa2V5VG9wdXBMYXN0VGltZXN0YW1wAAAAAQAAABVpbnRlcm5hbEJhc2V0QXNzZXRTdHIJAAEsAAAAAgIAAAAiJXMlcyVzJWRfX3RvcHVwX19sYXN0X190aW1lc3RhbXBfXwUAAAAVaW50ZXJuYWxCYXNldEFzc2V0U3RyAQAAAA9rZXlUb3B1cEhpc3RvcnkAAAACAAAAFWludGVybmFsQmFzZXRBc3NldFN0cgAAAAh0b3B1cElkeAkABLkAAAACCQAETAAAAAICAAAAGCVzJXMlZCVkX190b3B1cF9faGlzdG9yeQkABEwAAAACBQAAABVpbnRlcm5hbEJhc2V0QXNzZXRTdHIJAARMAAAAAgkAAaQAAAABBQAAAAh0b3B1cElkeAUAAAADbmlsBQAAAANTRVABAAAAEmtleUxpbWl0c1JlbWFpbmluZwAAAAEAAAAVaW50ZXJuYWxCYXNldEFzc2V0U3RyCQABLAAAAAICAAAAGyVzJXMlZF9fbGltaXRzX19yZW1haW5pbmdfXwUAAAAVaW50ZXJuYWxCYXNldEFzc2V0U3RyAAAAABJJZHhDZmdTaGFyZUFzc2V0SWQAAAAAAAAAAAEAAAAAF0lkeENmZ0ludGVybmFsQmFzZUFzc2V0AAAAAAAAAAACAAAAABxJZHhDZmdEZWNpbWFsc011bHRCb3RoQXNzZXRzAAAAAAAAAAADAAAAABdJZHhDZmdEZWNpbWFsc011bHRQcmljZQAAAAAAAAAABAAAAAAUSWR4Q2ZnR2V0RGVsYXlCbG9ja3MAAAAAAAAAAAUAAAAAG0lkeENmZ1RvcHVwSW50ZXJ2YWxJbkJsb2NrcwAAAAAAAAAABgAAAAAaSWR4Q2ZnVG9wdXBNYXhOZWdhdGl2ZVBhcnQAAAAAAAAAAAcAAAAAGUlkeENmZ1RvcHVwTWFuYWdlckFkZHJlc3MAAAAAAAAAAAgAAAAAGUlkeENmZ1N1Ym1pdExpbWl0c0Jhc2VNYXgAAAAAAAAAAAkAAAAAG0lkeENmZ1N1Ym1pdExpbWl0c0Jhc2VSZXNldAAAAAAAAAAACgAAAAAaSWR4Q2ZnU3VibWl0TGltaXRzU2hhcmVNYXgAAAAAAAAAAAsAAAAAHElkeENmZ1N1Ym1pdExpbWl0c1NoYXJlUmVzZXQAAAAAAAAAAAwAAAAAEklkeENmZ0FkbWluQWRkcmVzcwAAAAAAAAAADQEAAAAMZGF0YUFzc2V0Q2ZnAAAADQAAAA1zaGFyZUFzc2V0U3RyAAAAFGludGVybmFsQmFzZUFzc2V0U3RyAAAAFmRlY2ltYWxzTXVsdEJvdGhBc3NldHMAAAARZGVjaW1hbHNNdWx0UHJpY2UAAAAQZ2V0RGVsYXlJbkJsb2NrcwAAABV0b3B1cEludGVydmFsSW5CbG9ja3MAAAAUdG9wdXBNYXhOZWdhdGl2ZVBhcnQAAAATdG9wdXBNYW5hZ2VyQWRkcmVzcwAAABNzdWJtaXRMaW1pdHNCYXNlTWF4AAAAFXN1Ym1pdExpbWl0c0Jhc2VSZXNldAAAABRzdWJtaXRMaW1pdHNTaGFyZU1heAAAABZzdWJtaXRMaW1pdHNTaGFyZVJlc2V0AAAADGFkbWluQWRkcmVzcwkABLkAAAACCQAETAAAAAICAAAAGCVzJWQlZCVkJWQlZCVkJXMlZCVkJWQlZAkABEwAAAACBQAAAA1zaGFyZUFzc2V0U3RyCQAETAAAAAIFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyCQAETAAAAAIJAAGkAAAAAQUAAAAWZGVjaW1hbHNNdWx0Qm90aEFzc2V0cwkABEwAAAACCQABpAAAAAEFAAAAEWRlY2ltYWxzTXVsdFByaWNlCQAETAAAAAIJAAGkAAAAAQUAAAAQZ2V0RGVsYXlJbkJsb2NrcwkABEwAAAACCQABpAAAAAEFAAAAFXRvcHVwSW50ZXJ2YWxJbkJsb2NrcwkABEwAAAACCQABpAAAAAEFAAAAFHRvcHVwTWF4TmVnYXRpdmVQYXJ0CQAETAAAAAIFAAAAE3RvcHVwTWFuYWdlckFkZHJlc3MJAARMAAAAAgkAAaQAAAABBQAAABNzdWJtaXRMaW1pdHNCYXNlTWF4CQAETAAAAAIJAAGkAAAAAQUAAAAVc3VibWl0TGltaXRzQmFzZVJlc2V0CQAETAAAAAIJAAGkAAAAAQUAAAAUc3VibWl0TGltaXRzU2hhcmVNYXgJAARMAAAAAgkAAaQAAAABBQAAABZzdWJtaXRMaW1pdHNTaGFyZVJlc2V0CQAETAAAAAIFAAAADGFkbWluQWRkcmVzcwUAAAADbmlsBQAAAANTRVAAAAAAFUlkeFRvdGFsTG9ja2VkSW5TaGFyZQAAAAAAAAAAAQAAAAAVSWR4VG90YWxMb2NrZWRPdXRCYXNlAAAAAAAAAAACAAAAABRJZHhUb3RhbExvY2tlZEluQmFzZQAAAAAAAAAAAwAAAAAWSWR4VG90YWxMb2NrZWRPdXRTaGFyZQAAAAAAAAAABAEAAAAPZGF0YVRvdGFsTG9ja2VkAAAABAAAAA1pblNoYXJlQW1vdW50AAAADW91dEJhc2VBbW91bnQAAAAMaW5CYXNlQW1vdW50AAAADm91dFNoYXJlQW1vdW50CQAEuQAAAAIJAARMAAAAAgIAAAAIJWQlZCVkJWQJAARMAAAAAgkAAaQAAAABBQAAAA1pblNoYXJlQW1vdW50CQAETAAAAAIJAAGkAAAAAQUAAAANb3V0QmFzZUFtb3VudAkABEwAAAACCQABpAAAAAEFAAAADGluQmFzZUFtb3VudAkABEwAAAACCQABpAAAAAEFAAAADm91dFNoYXJlQW1vdW50BQAAAANuaWwFAAAAA1NFUAEAAAASZGF0YVRvdGFsTG9ja2VkSW50AAAABAAAAA1pblNoYXJlQW1vdW50AAAADW91dEJhc2VBbW91bnQAAAAMaW5CYXNlQW1vdW50AAAADm91dFNoYXJlQW1vdW50CQAETAAAAAIA//////////8JAARMAAAAAgUAAAANaW5TaGFyZUFtb3VudAkABEwAAAACBQAAAA1vdXRCYXNlQW1vdW50CQAETAAAAAIFAAAADGluQmFzZUFtb3VudAkABEwAAAACBQAAAA5vdXRTaGFyZUFtb3VudAUAAAADbmlsAQAAAA9yZWFkVG90YWxMb2NrZWQAAAABAAAAA2tleQQAAAAQdG90YWxMb2NrZWRBcnJheQkABLUAAAACCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAA2tleQkBAAAAD2RhdGFUb3RhbExvY2tlZAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAA1NFUAkBAAAAEmRhdGFUb3RhbExvY2tlZEludAAAAAQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABB0b3RhbExvY2tlZEFycmF5BQAAABVJZHhUb3RhbExvY2tlZEluU2hhcmUJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABB0b3RhbExvY2tlZEFycmF5BQAAABVJZHhUb3RhbExvY2tlZE91dEJhc2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABB0b3RhbExvY2tlZEFycmF5BQAAABRJZHhUb3RhbExvY2tlZEluQmFzZQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAEHRvdGFsTG9ja2VkQXJyYXkFAAAAFklkeFRvdGFsTG9ja2VkT3V0U2hhcmUBAAAAE2NhbGNUb3RhbExvY2tlZERpZmYAAAAIAAAACWRpcmVjdGlvbgAAAA1vcGVyYXRpb25UeXBlAAAAFGludGVybmFsQmFzZUFzc2V0U3RyAAAABXByaWNlAAAACXByaWNlTXVsdAAAAAhpbkFtb3VudAAAAAtiYXNlQXNzZXRJZAAAAAxzaGFyZUFzc2V0SWQEAAAAAXQJAAEsAAAAAgUAAAAJZGlyZWN0aW9uBQAAAA1vcGVyYXRpb25UeXBlAwkAAAAAAAACBQAAAAF0AgAAAAdzdWJtaXRQBAAAAAl0b3RhbERpZmYJAQAAABJkYXRhVG90YWxMb2NrZWRJbnQAAAAEAAAAAAAAAAAAAAAAAAAAAAAABQAAAAhpbkFtb3VudAAAAAAAAAAAAAQAAAAIdXNlckRpZmYFAAAACXRvdGFsRGlmZgkABRYAAAAEBQAAAAl0b3RhbERpZmYFAAAACHVzZXJEaWZmAAAAAAAAAAAACQACWQAAAAECAAAAAAMJAAAAAAAAAgUAAAABdAIAAAAHc3VibWl0RwQAAAAJdG90YWxEaWZmCQEAAAASZGF0YVRvdGFsTG9ja2VkSW50AAAABAUAAAAIaW5BbW91bnQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACHVzZXJEaWZmBQAAAAl0b3RhbERpZmYJAAUWAAAABAUAAAAJdG90YWxEaWZmBQAAAAh1c2VyRGlmZgAAAAAAAAAAAAkAAlkAAAABAgAAAAADCQAAAAAAAAIFAAAAAXQCAAAACGV4ZWN1dGVQBAAAAAlvdXRBbW91bnQJAQAAABFjb252ZXJ0QmFzZTJTaGFyZQAAAAMFAAAACGluQW1vdW50BQAAAAVwcmljZQUAAAAJcHJpY2VNdWx0BAAAAAl0b3RhbERpZmYJAQAAABJkYXRhVG90YWxMb2NrZWRJbnQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAlvdXRBbW91bnQEAAAACHVzZXJEaWZmCQEAAAASZGF0YVRvdGFsTG9ja2VkSW50AAAABAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAIaW5BbW91bnQAAAAAAAAAAAAJAAUWAAAABAUAAAAJdG90YWxEaWZmBQAAAAh1c2VyRGlmZgUAAAAJb3V0QW1vdW50BQAAAAxzaGFyZUFzc2V0SWQDCQAAAAAAAAIFAAAAAXQCAAAACGV4ZWN1dGVHBAAAAAlvdXRBbW91bnQJAQAAABFjb252ZXJ0U2hhcmUyQmFzZQAAAAMFAAAACGluQW1vdW50BQAAAAVwcmljZQUAAAAJcHJpY2VNdWx0BAAAAAl0b3RhbERpZmYJAQAAABJkYXRhVG90YWxMb2NrZWRJbnQAAAAEAAAAAAAAAAAABQAAAAlvdXRBbW91bnQAAAAAAAAAAAAAAAAAAAAAAAAEAAAACHVzZXJEaWZmCQEAAAASZGF0YVRvdGFsTG9ja2VkSW50AAAABAUAAAAIaW5BbW91bnQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAAUWAAAABAUAAAAJdG90YWxEaWZmBQAAAAh1c2VyRGlmZgUAAAAJb3V0QW1vdW50BQAAAAtiYXNlQXNzZXRJZAMJAAAAAAAAAgUAAAABdAIAAAAFdG9wdXAEAAAAEHRvdGFsTG9ja2VkQXJyYXkJAQAAAA9yZWFkVG90YWxMb2NrZWQAAAABCQEAAAAOa2V5VG90YWxMb2NrZWQAAAABBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgQAAAAXdG90YWxMb2NrZWRJbkJhc2VBbW91bnQJAAGRAAAAAgUAAAAQdG90YWxMb2NrZWRBcnJheQUAAAAUSWR4VG90YWxMb2NrZWRJbkJhc2UEAAAAGHRvdGFsTG9ja2VkSW5TaGFyZUFtb3VudAkAAZEAAAACBQAAABB0b3RhbExvY2tlZEFycmF5BQAAABVJZHhUb3RhbExvY2tlZEluU2hhcmUEAAAACXRvdGFsRGlmZgkBAAAAEmRhdGFUb3RhbExvY2tlZEludAAAAAQFAAAAGHRvdGFsTG9ja2VkSW5TaGFyZUFtb3VudAkAAGgAAAACAP//////////CQEAAAARY29udmVydFNoYXJlMkJhc2UAAAADBQAAABh0b3RhbExvY2tlZEluU2hhcmVBbW91bnQFAAAABXByaWNlBQAAAAlwcmljZU11bHQFAAAAF3RvdGFsTG9ja2VkSW5CYXNlQW1vdW50CQAAaAAAAAIA//////////8JAQAAABFjb252ZXJ0QmFzZTJTaGFyZQAAAAMFAAAAF3RvdGFsTG9ja2VkSW5CYXNlQW1vdW50BQAAAAVwcmljZQUAAAAJcHJpY2VNdWx0CQAFFgAAAAQFAAAACXRvdGFsRGlmZgUAAAADbmlsAAAAAAAAAAAACQACWQAAAAECAAAAAAkAAAIAAAABCQABLAAAAAICAAAAEVVuc3VwcG9ydGVkIFR5cGUgBQAAAAF0AQAAABZUb3RhbExvY2tlZFN0cmluZ0VudHJ5AAAAAwAAAAZhY3Rpb24AAAADa2V5AAAABGRpZmYKAQAAAAZVUERBVEUAAAACAAAAAWEAAAABYgMJAAAAAAAAAgUAAAAGYWN0aW9uAgAAAAlJTkNSRU1FTlQJAABkAAAAAgUAAAABYQUAAAABYgMJAAAAAAAAAgUAAAAGYWN0aW9uAgAAAAlERUNSRU1FTlQJAABlAAAAAgUAAAABYQUAAAABYgkAAAIAAAABCQABLAAAAAICAAAAE1Vuc3VwcG9ydGVkIGFjdGlvbiAFAAAABmFjdGlvbgQAAAAJZGF0YUFycmF5CQEAAAAPcmVhZFRvdGFsTG9ja2VkAAAAAQUAAAADa2V5CQEAAAALU3RyaW5nRW50cnkAAAACBQAAAANrZXkJAQAAAA9kYXRhVG90YWxMb2NrZWQAAAAECQEAAAAGVVBEQVRFAAAAAgkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAFUlkeFRvdGFsTG9ja2VkSW5TaGFyZQkAAZEAAAACBQAAAARkaWZmBQAAABVJZHhUb3RhbExvY2tlZEluU2hhcmUJAQAAAAZVUERBVEUAAAACCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAVSWR4VG90YWxMb2NrZWRPdXRCYXNlCQABkQAAAAIFAAAABGRpZmYFAAAAFUlkeFRvdGFsTG9ja2VkT3V0QmFzZQkBAAAABlVQREFURQAAAAIJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAABRJZHhUb3RhbExvY2tlZEluQmFzZQkAAZEAAAACBQAAAARkaWZmBQAAABRJZHhUb3RhbExvY2tlZEluQmFzZQkBAAAABlVQREFURQAAAAIJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAABZJZHhUb3RhbExvY2tlZE91dFNoYXJlCQABkQAAAAIFAAAABGRpZmYFAAAAFklkeFRvdGFsTG9ja2VkT3V0U2hhcmUBAAAADGtleU9wZXJhdGlvbgAAAAQAAAANb3BlcmF0aW9uVHlwZQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgAAAAt1c2VyQWRkcmVzcwAAAAR0eElkCQAEuQAAAAIJAARMAAAAAgIAAAAIJXMlZCVzJXMJAARMAAAAAgUAAAANb3BlcmF0aW9uVHlwZQkABEwAAAACBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgkABEwAAAACBQAAAAt1c2VyQWRkcmVzcwkABEwAAAACBQAAAAR0eElkBQAAAANuaWwFAAAAA1NFUAAAAAANSWR4T3BlclN0YXR1cwAAAAAAAAAAAQAAAAAPSWR4T3BlckluQW1vdW50AAAAAAAAAAACAAAAAAxJZHhPcGVyUHJpY2UAAAAAAAAAAAMAAAAAEElkeE9wZXJPdXRBbW91bnQAAAAAAAAAAAQAAAAAEklkeE9wZXJTdGFydEhlaWdodAAAAAAAAAAABQAAAAAVSWR4T3BlclN0YXJ0VGltZXN0YW1wAAAAAAAAAAAGAAAAABBJZHhPcGVyRW5kSGVpZ2h0AAAAAAAAAAAHAAAAABNJZHhPcGVyRW5kVGltZXN0YW1wAAAAAAAAAAAIAAAAABVJZHhPcGVyVG9wdXBVbmxvY2tJZHgAAAAAAAAAAAkBAAAAHnByaXZhdGVEYXRhT3BlcmF0aW9uQWxsU3RyaW5ncwAAAAkAAAAGc3RhdHVzAAAADWluQXNzZXRBbW91bnQAAAAFcHJpY2UAAAAOb3V0QXNzZXRBbW91bnQAAAALc3RhcnRIZWlnaHQAAAAOc3RhcnRUaW1lc3RhbXAAAAAJZW5kSGVpZ2h0AAAADGVuZFRpbWVzdGFtcAAAAARsb2NrCQAEuQAAAAIJAARMAAAAAgIAAAASJXMlZCVkJWQlZCVkJWQlZCVkCQAETAAAAAIFAAAABnN0YXR1cwkABEwAAAACBQAAAA1pbkFzc2V0QW1vdW50CQAETAAAAAIFAAAABXByaWNlCQAETAAAAAIFAAAADm91dEFzc2V0QW1vdW50CQAETAAAAAIFAAAAC3N0YXJ0SGVpZ2h0CQAETAAAAAIFAAAADnN0YXJ0VGltZXN0YW1wCQAETAAAAAIFAAAACWVuZEhlaWdodAkABEwAAAACBQAAAAxlbmRUaW1lc3RhbXAJAARMAAAAAgUAAAAEbG9jawUAAAADbmlsBQAAAANTRVABAAAADWRhdGFPcGVyYXRpb24AAAAJAAAABnN0YXR1cwAAAA1pbkFzc2V0QW1vdW50AAAABXByaWNlAAAADm91dEFzc2V0QW1vdW50AAAAC3N0YXJ0SGVpZ2h0AAAADnN0YXJ0VGltZXN0YW1wAAAACWVuZEhlaWdodAAAAAxlbmRUaW1lc3RhbXAAAAAOdG9wdXBVbmxvY2tJZHgJAQAAAB5wcml2YXRlRGF0YU9wZXJhdGlvbkFsbFN0cmluZ3MAAAAJBQAAAAZzdGF0dXMJAAGkAAAAAQUAAAANaW5Bc3NldEFtb3VudAkAAaQAAAABBQAAAAVwcmljZQkAAaQAAAABBQAAAA5vdXRBc3NldEFtb3VudAkAAaQAAAABBQAAAAtzdGFydEhlaWdodAkAAaQAAAABBQAAAA5zdGFydFRpbWVzdGFtcAkAAaQAAAABBQAAAAllbmRIZWlnaHQJAAGkAAAAAQUAAAAMZW5kVGltZXN0YW1wCQABpAAAAAEFAAAADnRvcHVwVW5sb2NrSWR4AQAAABxkYXRhT3BlcmF0aW9uRXhlY3V0aW9uVXBkYXRlAAAABAAAAA1jdXJyT3BlckFycmF5AAAACW5ld1N0YXR1cwAAAAhuZXdQcmljZQAAAAxuZXdPdXRBbW91bnQJAQAAAB5wcml2YXRlRGF0YU9wZXJhdGlvbkFsbFN0cmluZ3MAAAAJBQAAAAluZXdTdGF0dXMJAAGRAAAAAgUAAAANY3Vyck9wZXJBcnJheQUAAAAPSWR4T3BlckluQW1vdW50CQABpAAAAAEFAAAACG5ld1ByaWNlCQABpAAAAAEFAAAADG5ld091dEFtb3VudAkAAZEAAAACBQAAAA1jdXJyT3BlckFycmF5BQAAABJJZHhPcGVyU3RhcnRIZWlnaHQJAAGRAAAAAgUAAAANY3Vyck9wZXJBcnJheQUAAAAVSWR4T3BlclN0YXJ0VGltZXN0YW1wCQABpAAAAAEFAAAABmhlaWdodAkAAaQAAAABCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAkAAZEAAAACBQAAAA1jdXJyT3BlckFycmF5BQAAABVJZHhPcGVyVG9wdXBVbmxvY2tJZHgBAAAAEnJlYWRBc3NldENmZ09yRmFpbAAAAAEAAAAMYmFzZUFzc2V0U3RyBAAAAANrZXkJAQAAAAtrZXlBc3NldENmZwAAAAEFAAAADGJhc2VBc3NldFN0cgkABLUAAAACCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAQUAAAADa2V5BQAAAANTRVAAAAAAFklkeExpbWl0c1JlbWFpbmluZ0Jhc2UAAAAAAAAAAAEAAAAAF0lkeExpbWl0c1JlbWFpbmluZ1NoYXJlAAAAAAAAAAACAQAAABpSZW1haW5pbmdMaW1pdHNTdHJpbmdFbnRyeQAAAAMAAAADa2V5AAAAEmJhc2VSZW1haW5pbmdMaW1pdAAAABNzaGFyZVJlbWFpbmluZ0xpbWl0CQEAAAALU3RyaW5nRW50cnkAAAACBQAAAANrZXkJAAS5AAAAAgkABEwAAAACAgAAAAQlZCVkCQAETAAAAAIJAAGkAAAAAQUAAAASYmFzZVJlbWFpbmluZ0xpbWl0CQAETAAAAAIJAAGkAAAAAQUAAAATc2hhcmVSZW1haW5pbmdMaW1pdAUAAAADbmlsBQAAAANTRVABAAAAElRvcHVwTXV0ZXhJbnRFbnRyeQAAAAIAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIAAAAOYWNxdWlyZWRIZWlnaHQJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAOa2V5VG9wdXBNdXRleHQAAAABBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAOYWNxdWlyZWRIZWlnaHQBAAAAEGdlbmVyaWNDYWxjUHJpY2UAAAAFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyAAAAC2Jhc2VBc3NldElkAAAAD3RvcFVwQmFzZUFtb3VudAAAAAxzaGFyZUFzc2V0SWQAAAARZGVjaW1hbHNNdWx0UHJpY2UEAAAAEHRvdGFsTG9ja2VkQXJyYXkJAQAAAA9yZWFkVG90YWxMb2NrZWQAAAABCQEAAAAOa2V5VG90YWxMb2NrZWQAAAABBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgQAAAAYdG90YWxMb2NrZWRPdXRCYXNlQW1vdW50CQABkQAAAAIFAAAAEHRvdGFsTG9ja2VkQXJyYXkFAAAAFUlkeFRvdGFsTG9ja2VkT3V0QmFzZQQAAAAZY3Vyckl0ZXJUb3RhbEluQmFzZUFtb3VudAkAAZEAAAACBQAAABB0b3RhbExvY2tlZEFycmF5BQAAABRJZHhUb3RhbExvY2tlZEluQmFzZQQAAAAQYmFzZUFzc2V0QmFsYW5jZQkAA/AAAAACBQAAAAR0aGlzBQAAAAtiYXNlQXNzZXRJZAQAAAATYmFzZUFzc2V0QmFsYW5jZVdDTwkAAGUAAAACCQAAZQAAAAIJAABkAAAAAgUAAAAQYmFzZUFzc2V0QmFsYW5jZQUAAAAPdG9wVXBCYXNlQW1vdW50BQAAABljdXJySXRlclRvdGFsSW5CYXNlQW1vdW50BQAAABh0b3RhbExvY2tlZE91dEJhc2VBbW91bnQEAAAAGXRvdGFsTG9ja2VkT3V0U2hhcmVBbW91bnQJAAGRAAAAAgUAAAAQdG90YWxMb2NrZWRBcnJheQUAAAAWSWR4VG90YWxMb2NrZWRPdXRTaGFyZQQAAAAaY3Vyckl0ZXJUb3RhbEluU2hhcmVBbW91bnQJAAGRAAAAAgUAAAAQdG90YWxMb2NrZWRBcnJheQUAAAAVSWR4VG90YWxMb2NrZWRJblNoYXJlBAAAAA1zaGFyZUVtaXNzaW9uCAkBAAAABXZhbHVlAAAAAQkAA+wAAAABBQAAAAxzaGFyZUFzc2V0SWQAAAAIcXVhbnRpdHkDCQAAZgAAAAIAAAAAAAAAAAAFAAAAE2Jhc2VBc3NldEJhbGFuY2VXQ08JAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAArYmFzZUFzc2V0QmFsYW5jZVdjbyA8IDA6IGJhc2VBc3NldHRCYWxhbmNlPQkAAaQAAAABBQAAABBiYXNlQXNzZXRCYWxhbmNlAgAAABUgYmFzZUFzc2V0QmFsYW5jZVdjbz0JAAGkAAAAAQUAAAATYmFzZUFzc2V0QmFsYW5jZVdDTwQAAAAJbGFzdFByaWNlCQEAAAAMZ2V0SW50T3JGYWlsAAAAAQkBAAAADGtleVByaWNlTGFzdAAAAAEFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyBAAAAAVwcmljZQMJAAAAAAAAAgUAAAANc2hhcmVFbWlzc2lvbgAAAAAAAAAAAAUAAAAJbGFzdFByaWNlCQAAawAAAAMFAAAAE2Jhc2VBc3NldEJhbGFuY2VXQ08FAAAAEWRlY2ltYWxzTXVsdFByaWNlBQAAAA1zaGFyZUVtaXNzaW9uCQAFGwAAAAkFAAAABXByaWNlBQAAABBiYXNlQXNzZXRCYWxhbmNlAP//////////BQAAABNiYXNlQXNzZXRCYWxhbmNlV0NPBQAAAA1zaGFyZUVtaXNzaW9uBQAAABljdXJySXRlclRvdGFsSW5CYXNlQW1vdW50BQAAABpjdXJySXRlclRvdGFsSW5TaGFyZUFtb3VudAUAAAAYdG90YWxMb2NrZWRPdXRCYXNlQW1vdW50BQAAABl0b3RhbExvY2tlZE91dFNoYXJlQW1vdW50AQAAAAljYWxjUHJpY2UAAAAEAAAAFGludGVybmFsQmFzZUFzc2V0U3RyAAAAC2Jhc2VBc3NldElkAAAADHNoYXJlQXNzZXRJZAAAABFkZWNpbWFsc011bHRQcmljZQkBAAAAEGdlbmVyaWNDYWxjUHJpY2UAAAAFBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAALYmFzZUFzc2V0SWQAAAAAAAAAAAAFAAAADHNoYXJlQXNzZXRJZAUAAAARZGVjaW1hbHNNdWx0UHJpY2UBAAAADGNvbW1vblN1Ym1pdAAAAAUAAAANb3BlcmF0aW9uVHlwZQAAAAFpAAAACGluQW1vdW50AAAACWluQXNzZXRJZAAAAAxiYXNlQXNzZXRTdHIEAAAACmluQXNzZXRTdHIJAAJYAAAAAQUAAAAJaW5Bc3NldElkBAAAAA51c2VyQWRkcmVzc1N0cgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAAC2Jhc2VBc3NldElkCQACWQAAAAEFAAAADGJhc2VBc3NldFN0cgQAAAAIY2ZnQXJyYXkJAQAAABJyZWFkQXNzZXRDZmdPckZhaWwAAAABBQAAAAxiYXNlQXNzZXRTdHIEAAAADXNoYXJlQXNzZXRTdHIJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAEklkeENmZ1NoYXJlQXNzZXRJZAQAAAAMc2hhcmVBc3NldElkCQACWQAAAAEFAAAADXNoYXJlQXNzZXRTdHIEAAAAFmRlY2ltYWxzTXVsdEJvdGhBc3NldHMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAAcSWR4Q2ZnRGVjaW1hbHNNdWx0Qm90aEFzc2V0cwQAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAF0lkeENmZ0ludGVybmFsQmFzZUFzc2V0BAAAAAlsaW1pdHNLRVkJAQAAABJrZXlMaW1pdHNSZW1haW5pbmcAAAABBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgQAAAAObGltaXRzQ2ZnQXJyYXkJAAS1AAAAAgkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAEFAAAACWxpbWl0c0tFWQUAAAADU0VQBAAAABNsaW1pdHNSZW1haW5pbmdCYXNlCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAObGltaXRzQ2ZnQXJyYXkFAAAAFklkeExpbWl0c1JlbWFpbmluZ0Jhc2UEAAAAFGxpbWl0c1JlbWFpbmluZ1NoYXJlCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAObGltaXRzQ2ZnQXJyYXkFAAAAF0lkeExpbWl0c1JlbWFpbmluZ1NoYXJlBAAAAA9pc1N1Ym1pdEJsb2NrZWQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQbAAAAAgUAAAAEdGhpcwkBAAAAGmtleVNodXRkb3duU3VibWl0T3BlcmF0aW9uAAAAAQUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIHAwUAAAAPaXNTdWJtaXRCbG9ja2VkCQAAAgAAAAECAAAAG3N1Ym1pdCBvcGVyYXRpb24gaXMgYmxvY2tlZAQAAAAPb3BlcmF0aW9uc011dGV4CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAAA5rZXlUb3B1cE11dGV4dAAAAAEFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyAAAAAAAAAAAAAwkAAGYAAAACCQAAZAAAAAIFAAAAD29wZXJhdGlvbnNNdXRleAAAAAAAAAAAPAUAAAAGaGVpZ2h0CQAAAgAAAAECAAAALnN1Ym1pdCBvcGVyYXRpb25zIGFyZSBibG9ja2VkIGJ5IHRvcHVwIG1hbmFnZXIEAAAACWRpZmZUdXBsZQkBAAAAE2NhbGNUb3RhbExvY2tlZERpZmYAAAAIAgAAAAZzdWJtaXQFAAAADW9wZXJhdGlvblR5cGUFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyAAAAAAAAAAAAAAAAAAAAAAAABQAAAAhpbkFtb3VudAUAAAALYmFzZUFzc2V0SWQFAAAADHNoYXJlQXNzZXRJZAQAAAAWbGltaXRzUmVtYWluaW5nQmFzZU5ldwkAAGUAAAACBQAAABNsaW1pdHNSZW1haW5pbmdCYXNlCQABkQAAAAIIBQAAAAlkaWZmVHVwbGUAAAACXzIFAAAAFElkeFRvdGFsTG9ja2VkSW5CYXNlBAAAABdsaW1pdHNSZW1haW5pbmdTaGFyZU5ldwkAAGUAAAACBQAAABRsaW1pdHNSZW1haW5pbmdTaGFyZQkAAZEAAAACCAUAAAAJZGlmZlR1cGxlAAAAAl8yBQAAABVJZHhUb3RhbExvY2tlZEluU2hhcmUDAwkAAGYAAAACAAAAAAAAAAAABQAAABZsaW1pdHNSZW1haW5pbmdCYXNlTmV3BgkAAGYAAAACAAAAAAAAAAAABQAAABdsaW1pdHNSZW1haW5pbmdTaGFyZU5ldwkBAAAAF2ZhaWxTdWJtaXRMaW1pdHNFeGNlZWRzAAAABAUAAAATbGltaXRzUmVtYWluaW5nQmFzZQUAAAAUbGltaXRzUmVtYWluaW5nU2hhcmUFAAAAFmxpbWl0c1JlbWFpbmluZ0Jhc2VOZXcFAAAAF2xpbWl0c1JlbWFpbmluZ1NoYXJlTmV3BAAAAA90b3BVcEN1cnJlbnRJZHgJAQAAAAxnZXRJbnRPckZhaWwAAAABCQEAAAASa2V5VG9wVXBDdXJyZW50SWR4AAAAAQUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIJAARNAAAAAgkABE0AAAACCQAETQAAAAIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAADGtleU9wZXJhdGlvbgAAAAQFAAAADW9wZXJhdGlvblR5cGUFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyBQAAAA51c2VyQWRkcmVzc1N0cgkAAlgAAAABCAUAAAABaQAAAA10cmFuc2FjdGlvbklkCQEAAAANZGF0YU9wZXJhdGlvbgAAAAkCAAAAB1BFTkRJTkcFAAAACGluQW1vdW50AAAAAAAAAAAAAAAAAAAAAAAABQAAAAZoZWlnaHQIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wAAAAAAAAAAAAAAAAAAAAAAAACQAAZAAAAAIFAAAAD3RvcFVwQ3VycmVudElkeAAAAAAAAAAAAQUAAAADbmlsCQEAAAAWVG90YWxMb2NrZWRTdHJpbmdFbnRyeQAAAAMCAAAACUlOQ1JFTUVOVAkBAAAADmtleVRvdGFsTG9ja2VkAAAAAQUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIIBQAAAAlkaWZmVHVwbGUAAAACXzEJAQAAABZUb3RhbExvY2tlZFN0cmluZ0VudHJ5AAAAAwIAAAAJSU5DUkVNRU5UCQEAAAAUa2V5VG90YWxMb2NrZWRCeVVzZXIAAAACBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAOdXNlckFkZHJlc3NTdHIIBQAAAAlkaWZmVHVwbGUAAAACXzIJAQAAABpSZW1haW5pbmdMaW1pdHNTdHJpbmdFbnRyeQAAAAMFAAAACWxpbWl0c0tFWQUAAAAWbGltaXRzUmVtYWluaW5nQmFzZU5ldwUAAAAXbGltaXRzUmVtYWluaW5nU2hhcmVOZXcBAAAADWNvbW1vbkV4ZWN1dGUAAAAEAAAADW9wZXJhdGlvblR5cGUAAAAMYmFzZUFzc2V0U3RyAAAADnVzZXJBZGRyZXNzU3RyAAAADXN1Ym1pdFR4SWRTdHIEAAAAC3VzZXJBZGRyZXNzCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAA51c2VyQWRkcmVzc1N0cgQAAAANYXNzZXRDZmdBcnJheQkBAAAAEnJlYWRBc3NldENmZ09yRmFpbAAAAAEFAAAADGJhc2VBc3NldFN0cgQAAAAMc2hhcmVBc3NldElkCQACWQAAAAEJAAGRAAAAAgUAAAANYXNzZXRDZmdBcnJheQUAAAASSWR4Q2ZnU2hhcmVBc3NldElkBAAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgkAAZEAAAACBQAAAA1hc3NldENmZ0FycmF5BQAAABdJZHhDZmdJbnRlcm5hbEJhc2VBc3NldAQAAAARZGVjaW1hbHNNdWx0UHJpY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA1hc3NldENmZ0FycmF5BQAAABdJZHhDZmdEZWNpbWFsc011bHRQcmljZQQAAAALYmFzZUFzc2V0SWQJAAJZAAAAAQUAAAAMYmFzZUFzc2V0U3RyBAAAAAxvcGVyYXRpb25LZXkJAQAAAAxrZXlPcGVyYXRpb24AAAAEBQAAAA1vcGVyYXRpb25UeXBlBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAOdXNlckFkZHJlc3NTdHIFAAAADXN1Ym1pdFR4SWRTdHIEAAAADm9wZXJhdGlvbkFycmF5CQAEtQAAAAIJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAABBQAAAAxvcGVyYXRpb25LZXkFAAAAA1NFUAQAAAAGc3RhdHVzCQABkQAAAAIFAAAADm9wZXJhdGlvbkFycmF5BQAAAA1JZHhPcGVyU3RhdHVzBAAAAAhpbkFtb3VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADm9wZXJhdGlvbkFycmF5BQAAAA9JZHhPcGVySW5BbW91bnQEAAAADnRvcHVwVW5sb2NrSWR4CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAOb3BlcmF0aW9uQXJyYXkFAAAAFUlkeE9wZXJUb3B1cFVubG9ja0lkeAQAAAAMY3VyclRvcFVwSWR4CQEAAAAMZ2V0SW50T3JGYWlsAAAAAQkBAAAAEmtleVRvcFVwQ3VycmVudElkeAAAAAEFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyBAAAAA5wcmljZUJ5VG9wVXBJZAkBAAAADGdldEludE9yRmFpbAAAAAEJAQAAABJrZXlQcmljZUJ5VG9wVXBJZHgAAAACBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAOdG9wdXBVbmxvY2tJZHgDCQEAAAACIT0AAAACBQAAAAZzdGF0dXMCAAAAB1BFTkRJTkcJAQAAAA5mYWlsRXhlY3V0ZUdldAAAAAUCAAAAFVN0YXR1cyBpcyBub3QgUEVORElORwUAAAAMYmFzZUFzc2V0U3RyBQAAAA51c2VyQWRkcmVzc1N0cgUAAAANc3VibWl0VHhJZFN0cgUAAAANb3BlcmF0aW9uVHlwZQMJAABmAAAAAgUAAAAOdG9wdXBVbmxvY2tJZHgFAAAADGN1cnJUb3BVcElkeAkBAAAADmZhaWxFeGVjdXRlR2V0AAAABQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAJT3BlckxvY2tbCQABpAAAAAEFAAAADnRvcHVwVW5sb2NrSWR4AgAAAARdID4gCQABpAAAAAEFAAAADGN1cnJUb3BVcElkeAUAAAAMYmFzZUFzc2V0U3RyBQAAAA51c2VyQWRkcmVzc1N0cgUAAAANc3VibWl0VHhJZFN0cgUAAAANb3BlcmF0aW9uVHlwZQQAAAAJZGlmZlR1cGxlCQEAAAATY2FsY1RvdGFsTG9ja2VkRGlmZgAAAAgCAAAAB2V4ZWN1dGUFAAAADW9wZXJhdGlvblR5cGUFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyBQAAAA5wcmljZUJ5VG9wVXBJZAUAAAARZGVjaW1hbHNNdWx0UHJpY2UFAAAACGluQW1vdW50BQAAAAtiYXNlQXNzZXRJZAUAAAAMc2hhcmVBc3NldElkBAAAAAlvdXRBbW91bnQIBQAAAAlkaWZmVHVwbGUAAAACXzMEAAAAD291dFRyYW5zZmVyRGF0YQMJAAAAAAAAAggFAAAACWRpZmZUdXBsZQAAAAJfNAUAAAALYmFzZUFzc2V0SWQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAALdXNlckFkZHJlc3MFAAAACW91dEFtb3VudAUAAAALYmFzZUFzc2V0SWQFAAAAA25pbAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAt1c2VyQWRkcmVzcwUAAAAJb3V0QW1vdW50BQAAAAxzaGFyZUFzc2V0SWQFAAAAA25pbAkABE0AAAACCQAETQAAAAIJAARNAAAAAgUAAAAPb3V0VHJhbnNmZXJEYXRhCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAAxvcGVyYXRpb25LZXkJAQAAABxkYXRhT3BlcmF0aW9uRXhlY3V0aW9uVXBkYXRlAAAABAUAAAAOb3BlcmF0aW9uQXJyYXkCAAAACEZJTklTSEVEBQAAAA5wcmljZUJ5VG9wVXBJZAUAAAAJb3V0QW1vdW50CQEAAAAWVG90YWxMb2NrZWRTdHJpbmdFbnRyeQAAAAMCAAAACURFQ1JFTUVOVAkBAAAADmtleVRvdGFsTG9ja2VkAAAAAQUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIIBQAAAAlkaWZmVHVwbGUAAAACXzEJAQAAABZUb3RhbExvY2tlZFN0cmluZ0VudHJ5AAAAAwIAAAAJREVDUkVNRU5UCQEAAAAUa2V5VG90YWxMb2NrZWRCeVVzZXIAAAACBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAOdXNlckFkZHJlc3NTdHIIBQAAAAlkaWZmVHVwbGUAAAACXzIBAAAAG3ByaXZhdGVDdXJyZW50U3lzUGFyYW1zUkVTVAAAAAEAAAAMYmFzZUFzc2V0U3RyBAAAAAtiYXNlQXNzZXRJZAkAAlkAAAABBQAAAAxiYXNlQXNzZXRTdHIEAAAACGNmZ0FycmF5CQEAAAAScmVhZEFzc2V0Q2ZnT3JGYWlsAAAAAQUAAAAMYmFzZUFzc2V0U3RyBAAAAA1zaGFyZUFzc2V0U3RyCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABJJZHhDZmdTaGFyZUFzc2V0SWQEAAAADHNoYXJlQXNzZXRJZAkAAlkAAAABBQAAAA1zaGFyZUFzc2V0U3RyBAAAABlkZWNpbWFsc011bHRCb3RoQXNzZXRzVmFsCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAHElkeENmZ0RlY2ltYWxzTXVsdEJvdGhBc3NldHMEAAAAFGRlY2ltYWxzTXVsdFByaWNlVmFsCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAF0lkeENmZ0RlY2ltYWxzTXVsdFByaWNlBAAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAAXSWR4Q2ZnSW50ZXJuYWxCYXNlQXNzZXQEAAAAC3ByaWNlQXRoS0VZCQEAAAALa2V5UHJpY2VBVEgAAAABBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgQAAAALcHJpY2VBdGhWYWwJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAALcHJpY2VBdGhLRVkAAAAAAAAAAAAEAAAADHByaWNlTGFzdEtFWQkBAAAADGtleVByaWNlTGFzdAAAAAEFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyBAAAAAxwcmljZUxhc3RWYWwJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAMcHJpY2VMYXN0S0VZAAAAAAAAAAAABAAAABB0b3B1cExhc3RUaW1lS0VZCQEAAAAVa2V5VG9wdXBMYXN0VGltZXN0YW1wAAAAAQUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIEAAAAEHRvcHVwTGFzdFRpbWVWYWwJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAQdG9wdXBMYXN0VGltZUtFWQAAAAAAAAAAAAQAAAAIc3lzU3RhdGUJAQAAAAljYWxjUHJpY2UAAAAEBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAALYmFzZUFzc2V0SWQFAAAADHNoYXJlQXNzZXRJZAUAAAAUZGVjaW1hbHNNdWx0UHJpY2VWYWwJAAUgAAAADgkBAAAADEludGVnZXJFbnRyeQAAAAICAAAABXByaWNlBQAAAAxwcmljZUxhc3RWYWwJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAABFkZWNpbWFsc011bHRQcmljZQUAAAAUZGVjaW1hbHNNdWx0UHJpY2VWYWwJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAABBiYXNlQXNzZXRCYWxhbmNlCAUAAAAIc3lzU3RhdGUAAAACXzIJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAAAItMQgFAAAACHN5c1N0YXRlAAAAAl8zCQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAATYmFzZUFzc2V0QmFsYW5jZVdDTwgFAAAACHN5c1N0YXRlAAAAAl80CQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAANc2hhcmVFbWlzc2lvbggFAAAACHN5c1N0YXRlAAAAAl81CQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAAZY3Vyckl0ZXJUb3RhbEluQmFzZUFtb3VudAgFAAAACHN5c1N0YXRlAAAAAl82CQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAAaY3Vyckl0ZXJUb3RhbEluU2hhcmVBbW91bnQIBQAAAAhzeXNTdGF0ZQAAAAJfNwkBAAAADEludGVnZXJFbnRyeQAAAAICAAAAGHRvdGFsTG9ja2VkT3V0QmFzZUFtb3VudAgFAAAACHN5c1N0YXRlAAAAAl84CQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAAZdG90YWxMb2NrZWRPdXRTaGFyZUFtb3VudAgFAAAACHN5c1N0YXRlAAAAAl85CQEAAAAMSW50ZWdlckVudHJ5AAAAAgIAAAAWZGVjaW1hbHNNdWx0Qm90aEFzc2V0cwUAAAAZZGVjaW1hbHNNdWx0Qm90aEFzc2V0c1ZhbAkBAAAADEludGVnZXJFbnRyeQAAAAICAAAACHByaWNlQVRIBQAAAAtwcmljZUF0aFZhbAkBAAAADEludGVnZXJFbnRyeQAAAAICAAAAEXByaWNlUmVjYWxjdWxhdGVkCAUAAAAIc3lzU3RhdGUAAAACXzEJAQAAAAxJbnRlZ2VyRW50cnkAAAACAgAAABJ0b3B1cExhc3RUaW1lc3RhbXAFAAAAEHRvcHVwTGFzdFRpbWVWYWwAAAAJAAAAAWkBAAAAEmFkbWluUmVnaXN0ZXJBc3NldAAAAA4AAAAMYmFzZUFzc2V0U3RyAAAADnNoYXJlQXNzZXROYW1lAAAAD3NoYXJlQXNzZXREZXNjcgAAABBnZXREZWxheWluQmxvY2tzAAAAFnNodXRkb3duTWFuYWdlckFkZHJlc3MAAAAKc3RhcnRQcmljZQAAABV0b3B1cEludGVydmFsSW5CbG9ja3MAAAAUdG9wdXBNYXhOZWdhdGl2ZVBhcnQAAAATdG9wdXBNYW5hZ2VyQWRkcmVzcwAAABNzdWJtaXRMaW1pdHNCYXNlTWF4AAAAFXN1Ym1pdExpbWl0c0Jhc2VSZXNldAAAABRzdWJtaXRMaW1pdHNTaGFyZU1heAAAABZzdWJtaXRMaW1pdHNTaGFyZVJlc2V0AAAADGFkbWluQWRkcmVzcwQAAAALYmFzZUFzc2V0SWQJAAJZAAAAAQUAAAAMYmFzZUFzc2V0U3RyBAAAABJib3RoQXNzZXRzRGVjaW1hbHMICQEAAAAFdmFsdWUAAAABCQAD7AAAAAEFAAAAC2Jhc2VBc3NldElkAAAACGRlY2ltYWxzBAAAABZkZWNpbWFsc011bHRCb3RoQXNzZXRzCQAAbAAAAAYAAAAAAAAAAAoAAAAAAAAAAAAFAAAAEmJvdGhBc3NldHNEZWNpbWFscwAAAAAAAAAAAAAAAAAAAAAAAAUAAAAERE9XTgQAAAARZGVjaW1hbHNNdWx0UHJpY2UJAABoAAAAAgkAAGgAAAACAAAAAAAAAABkAAAAAAAAAAPoAAAAAAAAAAPoBAAAABh0b3B1cE1heE5lZ2F0aXZlUGVyY2VudHMJAABrAAAAAwUAAAAUdG9wdXBNYXhOZWdhdGl2ZVBhcnQAAAAAAAAAAGQFAAAAFmRlY2ltYWxzTXVsdEJvdGhBc3NldHMEAAAAEGJhc2VBc3NldEJhbGFuY2UJAAPwAAAAAgUAAAAEdGhpcwUAAAALYmFzZUFzc2V0SWQDCQEAAAACIT0AAAACCAUAAAABaQAAAAZjYWxsZXIFAAAABHRoaXMJAAACAAAAAQIAAAAScGVybWlzc2lvbnMgZGVuaWVkAwkAAAAAAAACBQAAABBiYXNlQXNzZXRCYWxhbmNlAAAAAAAAAAAACQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQAEJQAAAAEFAAAABHRoaXMCAAAAIiBtdXN0IGhhdmUgYW55IGluaXRpYWwgYmFsYW5jZSBvZiAFAAAADGJhc2VBc3NldFN0cgMJAQAAAAlpc0RlZmluZWQAAAABCQAEHQAAAAIFAAAABHRoaXMJAQAAAAtrZXlBc3NldENmZwAAAAEFAAAADGJhc2VBc3NldFN0cgkAAAIAAAABCQABLAAAAAIFAAAADGJhc2VBc3NldFN0cgIAAAAcIGhhcyBiZWVuIGFscmVhZHkgcmVnaXN0ZXJlZAMJAQAAAAIhPQAAAAIJAAQlAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAAWc2h1dGRvd25NYW5hZ2VyQWRkcmVzcwUAAAAWc2h1dGRvd25NYW5hZ2VyQWRkcmVzcwkAAAIAAAABAgAAAB5pbnZhbGlkIHNodXRkb3duTWFuYWdlckFkZHJlc3MDCQEAAAACIT0AAAACCQAEJQAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAE3RvcHVwTWFuYWdlckFkZHJlc3MFAAAAE3RvcHVwTWFuYWdlckFkZHJlc3MJAAACAAAAAQIAAAAbaW52YWxpZCB0b3B1cE1hbmFnZXJBZGRyZXNzAwkAAGYAAAACAAAAAAAAAAAABQAAABBnZXREZWxheWluQmxvY2tzCQAAAgAAAAEJAAEsAAAAAgIAAAAZaW52YWxpZCBnZXREZWxheWluQmxvY2tzPQkAAaQAAAABBQAAABBnZXREZWxheWluQmxvY2tzAwMJAABnAAAAAgAAAAAAAAAAAAUAAAAYdG9wdXBNYXhOZWdhdGl2ZVBlcmNlbnRzBgkAAGcAAAACBQAAABh0b3B1cE1heE5lZ2F0aXZlUGVyY2VudHMAAAAAAAAAAGMJAAACAAAAAQIAAAAmaW52YWxpZCB0b3B1cE1heE5lZ2F0aXZlUGFydCBwYXJhbWV0ZXIEAAAAD3NoYXJlSW5pdEFtb3VudAkBAAAAEWNvbnZlcnRCYXNlMlNoYXJlAAAAAwUAAAAQYmFzZUFzc2V0QmFsYW5jZQUAAAAKc3RhcnRQcmljZQUAAAARZGVjaW1hbHNNdWx0UHJpY2UEAAAAFXNoYXJlQXNzZXRJc3N1ZUFjdGlvbgkABEIAAAAFBQAAAA5zaGFyZUFzc2V0TmFtZQUAAAAPc2hhcmVBc3NldERlc2NyBQAAAA9zaGFyZUluaXRBbW91bnQFAAAAEmJvdGhBc3NldHNEZWNpbWFscwYEAAAADHNoYXJlQXNzZXRJZAkABDgAAAABBQAAABVzaGFyZUFzc2V0SXNzdWVBY3Rpb24EAAAADXNoYXJlQXNzZXRTdHIJAAJYAAAAAQUAAAAMc2hhcmVBc3NldElkBAAAABNpbnRlcm5hbEJhc2VBc3NldElkCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABZrZXlOZXh0SW50ZXJuYWxBc3NldElkAAAAAAAAAAAAAAAAAAQAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIJAAGkAAAAAQUAAAATaW50ZXJuYWxCYXNlQXNzZXRJZAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAALa2V5QXNzZXRDZmcAAAABBQAAAAxiYXNlQXNzZXRTdHIJAQAAAAxkYXRhQXNzZXRDZmcAAAANBQAAAA1zaGFyZUFzc2V0U3RyBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAWZGVjaW1hbHNNdWx0Qm90aEFzc2V0cwUAAAARZGVjaW1hbHNNdWx0UHJpY2UFAAAAEGdldERlbGF5aW5CbG9ja3MFAAAAFXRvcHVwSW50ZXJ2YWxJbkJsb2NrcwUAAAAUdG9wdXBNYXhOZWdhdGl2ZVBhcnQFAAAAE3RvcHVwTWFuYWdlckFkZHJlc3MFAAAAE3N1Ym1pdExpbWl0c0Jhc2VNYXgFAAAAFXN1Ym1pdExpbWl0c0Jhc2VSZXNldAUAAAAUc3VibWl0TGltaXRzU2hhcmVNYXgFAAAAFnN1Ym1pdExpbWl0c1NoYXJlUmVzZXQFAAAADGFkbWluQWRkcmVzcwkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAfa2V5TWFwcGluZ3NJbnRlcm5hbDJiYXNlQXNzZXRJZAAAAAEFAAAAE2ludGVybmFsQmFzZUFzc2V0SWQFAAAADGJhc2VBc3NldFN0cgkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZAAAAAEFAAAADGJhc2VBc3NldFN0cgUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAHGtleU1hcHBpbmdzU2hhcmUyYmFzZUFzc2V0SWQAAAABBQAAAA1zaGFyZUFzc2V0U3RyBQAAAAxiYXNlQXNzZXRTdHIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAHGtleU1hcHBpbmdzQmFzZUFzc2V0MnNoYXJlSWQAAAABBQAAAAxiYXNlQXNzZXRTdHIFAAAADXNoYXJlQXNzZXRTdHIJAARMAAAAAgkBAAAADEJvb2xlYW5FbnRyeQAAAAIJAQAAABprZXlTaHV0ZG93blN1Ym1pdE9wZXJhdGlvbgAAAAEFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyBwkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5U2h1dGRvd25NYW5hZ2VyAAAAAQUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIFAAAAFnNodXRkb3duTWFuYWdlckFkZHJlc3MJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABZrZXlOZXh0SW50ZXJuYWxBc3NldElkAAAAAAkAAGQAAAACBQAAABNpbnRlcm5hbEJhc2VBc3NldElkAAAAAAAAAAABCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAMa2V5UHJpY2VMYXN0AAAAAQUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIFAAAACnN0YXJ0UHJpY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA9rZXlQcmljZUhpc3RvcnkAAAADBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAGaGVpZ2h0CAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAUAAAAKc3RhcnRQcmljZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAEmtleVRvcFVwQ3VycmVudElkeAAAAAEFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyAAAAAAAAAAAACQAETAAAAAIJAQAAABpSZW1haW5pbmdMaW1pdHNTdHJpbmdFbnRyeQAAAAMJAQAAABJrZXlMaW1pdHNSZW1haW5pbmcAAAABBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAATc3VibWl0TGltaXRzQmFzZU1heAUAAAAUc3VibWl0TGltaXRzU2hhcmVNYXgJAARMAAAAAgUAAAAVc2hhcmVBc3NldElzc3VlQWN0aW9uCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAE3RvcHVwTWFuYWdlckFkZHJlc3MFAAAAD3NoYXJlSW5pdEFtb3VudAUAAAAMc2hhcmVBc3NldElkBQAAAANuaWwAAAABaQEAAAAPc2h1dGRvd25TdWJtaXRzAAAAAQAAABNpbnRlcm5hbEJhc2VBc3NldElkBAAAABZpbnRlcm5hbEJhc2VBc3NldElkU3RyCQABpAAAAAEFAAAAE2ludGVybmFsQmFzZUFzc2V0SWQEAAAADmJhc2VBc3NldElkU3RyCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAQkBAAAAH2tleU1hcHBpbmdzSW50ZXJuYWwyYmFzZUFzc2V0SWQAAAABBQAAABNpbnRlcm5hbEJhc2VBc3NldElkBAAAABZzaHV0ZG93bk1hbmFnZXJBZGRyZXNzCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAQkBAAAAEmtleVNodXRkb3duTWFuYWdlcgAAAAEFAAAAFmludGVybmFsQmFzZUFzc2V0SWRTdHIDCQAAZgAAAAIAAAAAAAAAAAEJAAExAAAAAQUAAAAOYmFzZUFzc2V0SWRTdHIJAAACAAAAAQIAAAAbaW52YWxpZCBpbnRlcm5hbEJhc2VBc3NldElkAwkBAAAAAiE9AAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIFAAAAFnNodXRkb3duTWFuYWdlckFkZHJlc3MJAAACAAAAAQIAAAANYWNjZXNzIGRlbmllZAkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgkBAAAAGmtleVNodXRkb3duU3VibWl0T3BlcmF0aW9uAAAAAQkAAaQAAAABBQAAABNpbnRlcm5hbEJhc2VBc3NldElkBgUAAAADbmlsAAAAAWkBAAAACXN1Ym1pdFB1dAAAAAAEAAAAA3BtdAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAQAAAAIaW5BbW91bnQIBQAAAANwbXQAAAAGYW1vdW50BAAAAAlpbkFzc2V0SWQJAQAAAAV2YWx1ZQAAAAEIBQAAAANwbXQAAAAHYXNzZXRJZAQAAAAMYmFzZUFzc2V0U3RyCQACWAAAAAEFAAAACWluQXNzZXRJZAkBAAAADGNvbW1vblN1Ym1pdAAAAAUCAAAAAVAFAAAAAWkFAAAACGluQW1vdW50BQAAAAlpbkFzc2V0SWQFAAAADGJhc2VBc3NldFN0cgAAAAFpAQAAAAlzdWJtaXRHZXQAAAAABAAAAANwbXQJAQAAAAV2YWx1ZQAAAAEJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAEAAAACGluQW1vdW50CAUAAAADcG10AAAABmFtb3VudAQAAAAJaW5Bc3NldElkCQEAAAAFdmFsdWUAAAABCAUAAAADcG10AAAAB2Fzc2V0SWQEAAAADXNoYXJlQXNzZXRTdHIJAAJYAAAAAQUAAAAJaW5Bc3NldElkBAAAAAxiYXNlQXNzZXRTdHIJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAABCQEAAAAca2V5TWFwcGluZ3NTaGFyZTJiYXNlQXNzZXRJZAAAAAEFAAAADXNoYXJlQXNzZXRTdHIJAQAAAAxjb21tb25TdWJtaXQAAAAFAgAAAAFHBQAAAAFpBQAAAAhpbkFtb3VudAUAAAAJaW5Bc3NldElkBQAAAAxiYXNlQXNzZXRTdHIAAAABaQEAAAAKZXhlY3V0ZVB1dAAAAAMAAAAMYmFzZUFzc2V0U3RyAAAADnVzZXJBZGRyZXNzU3RyAAAADXN1Ym1pdFR4SWRTdHIJAQAAAA1jb21tb25FeGVjdXRlAAAABAIAAAABUAUAAAAMYmFzZUFzc2V0U3RyBQAAAA51c2VyQWRkcmVzc1N0cgUAAAANc3VibWl0VHhJZFN0cgAAAAFpAQAAAApleGVjdXRlR2V0AAAAAwAAAAxiYXNlQXNzZXRTdHIAAAAOdXNlckFkZHJlc3NTdHIAAAANc3VibWl0VHhJZFN0cgkBAAAADWNvbW1vbkV4ZWN1dGUAAAAEAgAAAAFHBQAAAAxiYXNlQXNzZXRTdHIFAAAADnVzZXJBZGRyZXNzU3RyBQAAAA1zdWJtaXRUeElkU3RyAAAAAWkBAAAAD29wZXJhdGlvbnNNdXRleAAAAAEAAAAMYmFzZUFzc2V0U3RyBAAAAA1hc3NldENmZ0FycmF5CQEAAAAScmVhZEFzc2V0Q2ZnT3JGYWlsAAAAAQUAAAAMYmFzZUFzc2V0U3RyBAAAABZ0b3BVcE1hbmFnZXJBZGRyZXNzU3RyCQABkQAAAAIFAAAADWFzc2V0Q2ZnQXJyYXkFAAAAGUlkeENmZ1RvcHVwTWFuYWdlckFkZHJlc3MEAAAAFGludGVybmFsQmFzZUFzc2V0U3RyCQABkQAAAAIFAAAADWFzc2V0Q2ZnQXJyYXkFAAAAF0lkeENmZ0ludGVybmFsQmFzZUFzc2V0AwkBAAAAAiE9AAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIFAAAAFnRvcFVwTWFuYWdlckFkZHJlc3NTdHIJAQAAABRmYWlsVG9wdXBNYW5hZ2VyT25seQAAAAEFAAAAFnRvcFVwTWFuYWdlckFkZHJlc3NTdHIJAARMAAAAAgkBAAAAElRvcHVwTXV0ZXhJbnRFbnRyeQAAAAIFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyBQAAAAZoZWlnaHQFAAAAA25pbAAAAAFpAQAAAAx0b3BVcEJhbGFuY2UAAAACAAAADGJhc2VBc3NldFN0cgAAAAZpbmNvbWUEAAAAC2Jhc2VBc3NldElkCQACWQAAAAEFAAAADGJhc2VBc3NldFN0cgQAAAANYXNzZXRDZmdBcnJheQkBAAAAEnJlYWRBc3NldENmZ09yRmFpbAAAAAEFAAAADGJhc2VBc3NldFN0cgQAAAAMc2hhcmVBc3NldElkCQACWQAAAAEJAAGRAAAAAgUAAAANYXNzZXRDZmdBcnJheQUAAAASSWR4Q2ZnU2hhcmVBc3NldElkBAAAAAlwcmljZU11bHQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA1hc3NldENmZ0FycmF5BQAAABdJZHhDZmdEZWNpbWFsc011bHRQcmljZQQAAAANYm90aEFzc2V0TXVsdAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADWFzc2V0Q2ZnQXJyYXkFAAAAHElkeENmZ0RlY2ltYWxzTXVsdEJvdGhBc3NldHMEAAAAFXRvcHVwSW50ZXJ2YWxJbkJsb2NrcwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADWFzc2V0Q2ZnQXJyYXkFAAAAG0lkeENmZ1RvcHVwSW50ZXJ2YWxJbkJsb2NrcwQAAAAUdG9wdXBNYXhOZWdhdGl2ZVBhcnQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA1hc3NldENmZ0FycmF5BQAAABpJZHhDZmdUb3B1cE1heE5lZ2F0aXZlUGFydAQAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIJAAGRAAAAAgUAAAANYXNzZXRDZmdBcnJheQUAAAAXSWR4Q2ZnSW50ZXJuYWxCYXNlQXNzZXQEAAAAFnRvcFVwTWFuYWdlckFkZHJlc3NTdHIJAAGRAAAAAgUAAAANYXNzZXRDZmdBcnJheQUAAAAZSWR4Q2ZnVG9wdXBNYW5hZ2VyQWRkcmVzcwQAAAATc3VibWl0TGltaXRzQmFzZU1heAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADWFzc2V0Q2ZnQXJyYXkFAAAAGUlkeENmZ1N1Ym1pdExpbWl0c0Jhc2VNYXgEAAAAFHN1Ym1pdExpbWl0c1NoYXJlTWF4CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAANYXNzZXRDZmdBcnJheQUAAAAaSWR4Q2ZnU3VibWl0TGltaXRzU2hhcmVNYXgEAAAAEnRvcFVwQ3VycmVudElkeEtFWQkBAAAAEmtleVRvcFVwQ3VycmVudElkeAAAAAEFAAAAFGludGVybmFsQmFzZUFzc2V0U3RyBAAAAAxwcmV2VG9wVXBJZHgJAQAAAAxnZXRJbnRPckZhaWwAAAABBQAAABJ0b3BVcEN1cnJlbnRJZHhLRVkEAAAAD2N1cnJlbnRUb3BVcElkeAkAAGQAAAACBQAAAAxwcmV2VG9wVXBJZHgAAAAAAAAAAAEEAAAABXZhbGlkAwkAAGYAAAACBQAAAAZpbmNvbWUAAAAAAAAAAAAEAAAAA3BtdAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAQAAAAKcG10QXNzZXRJZAkBAAAABXZhbHVlAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkAwkBAAAAAiE9AAAAAgUAAAALYmFzZUFzc2V0SWQFAAAACnBtdEFzc2V0SWQJAAACAAAAAQIAAAA+YXR0YWNoZWQgcGF5bWVudCdzIGFzc2V0IGlkIGlzIE5PVCBtYXRjaGVkIHBhc3NlZCBiYXNlQXNzZXRTdHIDCQAAZgAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAAgb25seSBvbmUgcGF5bWVudCBjYW4gYmUgYXR0YWNoZWQDCQEAAAACIT0AAAACCAUAAAADcG10AAAABmFtb3VudAUAAAAGaW5jb21lCQAAAgAAAAECAAAAPWF0dGFjaGVkIHBheW1lbnQuYW1vdW50IGlzIE5PVCBtYXRjaGVkIHBhc3NlZCBpbmNvbWUgYXJndW1lbnQGAwkAAGYAAAACAAAAAAAAAAAABQAAAAZpbmNvbWUEAAAAC2Jhc2VCYWxhbmNlCQAD8AAAAAIFAAAABHRoaXMFAAAAC2Jhc2VBc3NldElkBAAAAA1hbGxvd2VkQW1vdW50CQAAawAAAAMFAAAAFHRvcHVwTWF4TmVnYXRpdmVQYXJ0BQAAAAtiYXNlQmFsYW5jZQUAAAANYm90aEFzc2V0TXVsdAMJAABmAAAAAgkBAAAAAS0AAAABBQAAAAZpbmNvbWUFAAAADWFsbG93ZWRBbW91bnQJAAACAAAAAQkAASwAAAACAgAAAC90b3B1cCBuZWdhdGl2ZSBpbmNvbWUgY291bGRuJ3QgYmUgZ3JlYXRlciB0aGFuIAkAAaQAAAABBQAAAA1hbGxvd2VkQW1vdW50BgkAAAIAAAABAgAAABp6ZXJvIGluY29tZSBpcyBub3QgYWxsb3dlZAQAAAASdG9wVXBMYXN0SGVpZ2h0S0VZCQEAAAASa2V5VG9wVXBMYXN0SGVpZ2h0AAAAAgUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAA90b3BVcExhc3RIZWlnaHQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAASdG9wVXBMYXN0SGVpZ2h0S0VZAAAAAAAAAAAAAwkBAAAAAiE9AAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIFAAAAFnRvcFVwTWFuYWdlckFkZHJlc3NTdHIJAQAAABRmYWlsVG9wdXBNYW5hZ2VyT25seQAAAAEFAAAAFnRvcFVwTWFuYWdlckFkZHJlc3NTdHIDCQEAAAABIQAAAAEFAAAABXZhbGlkCQAAAgAAAAECAAAAEXZhbGlkYXRpb24gZmFpbGVkAwkAAGYAAAACBQAAABV0b3B1cEludGVydmFsSW5CbG9ja3MJAABlAAAAAgUAAAAGaGVpZ2h0BQAAAA90b3BVcExhc3RIZWlnaHQJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAADDEgdG9wdXAgcGVyIAkAAaQAAAABBQAAABV0b3B1cEludGVydmFsSW5CbG9ja3MCAAAAKCBibG9ja3MgZnJvbSB0aGUgc2FtZSBhZGRyZXNzIGlzIGFsbG93ZWQEAAAABXByaWNlCAkBAAAAEGdlbmVyaWNDYWxjUHJpY2UAAAAFBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAALYmFzZUFzc2V0SWQFAAAABmluY29tZQUAAAAMc2hhcmVBc3NldElkBQAAAAlwcmljZU11bHQAAAACXzEEAAAACWRpZmZUdXBsZQkBAAAAE2NhbGNUb3RhbExvY2tlZERpZmYAAAAIAgAAAAV0b3B1cAIAAAAABQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAFcHJpY2UFAAAACXByaWNlTXVsdAAAAAAAAAAAAAUAAAALYmFzZUFzc2V0SWQFAAAADHNoYXJlQXNzZXRJZAQAAAAOdG9wdXBUb3RhbERpZmYIBQAAAAlkaWZmVHVwbGUAAAACXzEEAAAAC3ByaWNlQXRoS0VZCQEAAAALa2V5UHJpY2VBVEgAAAABBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgQAAAAMcHJldlByaWNlQVRICQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAC3ByaWNlQXRoS0VZAAAAAAAAAAAACQAETgAAAAIJAARNAAAAAgkABE0AAAACCQAETQAAAAIJAARNAAAAAgkABE0AAAACCQAETQAAAAIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAAxrZXlQcmljZUxhc3QAAAABBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAFcHJpY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA9rZXlQcmljZUhpc3RvcnkAAAADBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAGaGVpZ2h0CAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAUAAAAFcHJpY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABJrZXlQcmljZUJ5VG9wVXBJZHgAAAACBQAAABRpbnRlcm5hbEJhc2VBc3NldFN0cgUAAAAPY3VycmVudFRvcFVwSWR4BQAAAAVwcmljZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASdG9wVXBDdXJyZW50SWR4S0VZBQAAAA9jdXJyZW50VG9wVXBJZHgJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC3ByaWNlQXRoS0VZAwkAAGYAAAACBQAAAAVwcmljZQUAAAAMcHJldlByaWNlQVRIBQAAAAVwcmljZQUAAAAMcHJldlByaWNlQVRICQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJ0b3BVcExhc3RIZWlnaHRLRVkFAAAABmhlaWdodAUAAAADbmlsCQEAAAAWVG90YWxMb2NrZWRTdHJpbmdFbnRyeQAAAAMCAAAACURFQ1JFTUVOVAkBAAAADmtleVRvdGFsTG9ja2VkAAAAAQUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIFAAAADnRvcHVwVG90YWxEaWZmCQEAAAASVG9wdXBNdXRleEludEVudHJ5AAAAAgUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIAAAAAAAAAAAAJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAVa2V5VG9wdXBMYXN0VGltZXN0YW1wAAAAAQUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wCQEAAAAaUmVtYWluaW5nTGltaXRzU3RyaW5nRW50cnkAAAADCQEAAAASa2V5TGltaXRzUmVtYWluaW5nAAAAAQUAAAAUaW50ZXJuYWxCYXNlQXNzZXRTdHIFAAAAE3N1Ym1pdExpbWl0c0Jhc2VNYXgFAAAAFHN1Ym1pdExpbWl0c1NoYXJlTWF4CQEAAAAEQnVybgAAAAIFAAAADHNoYXJlQXNzZXRJZAkAAZEAAAACBQAAAA50b3B1cFRvdGFsRGlmZgUAAAAVSWR4VG90YWxMb2NrZWRJblNoYXJlCQEAAAAHUmVpc3N1ZQAAAAMFAAAADHNoYXJlQXNzZXRJZAkBAAAAAS0AAAABCQABkQAAAAIFAAAADnRvcHVwVG90YWxEaWZmBQAAABZJZHhUb3RhbExvY2tlZE91dFNoYXJlBgMJAABmAAAAAgAAAAAAAAAAAAUAAAAGaW5jb21lCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgkBAAAAAS0AAAABBQAAAAZpbmNvbWUFAAAAC2Jhc2VBc3NldElkBQAAAANuaWwFAAAAA25pbAAAAAFpAQAAABRjdXJyZW50U3lzUGFyYW1zUkVTVAAAAAEAAAAMYmFzZUFzc2V0U3RyBAAAAA1zeXNTdGF0ZVR1cGxlCQEAAAAbcHJpdmF0ZUN1cnJlbnRTeXNQYXJhbXNSRVNUAAAAAQUAAAAMYmFzZUFzc2V0U3RyBAAAAAVwcmljZQgIBQAAAA1zeXNTdGF0ZVR1cGxlAAAAAl8xAAAABXZhbHVlBAAAABFkZWNpbWFsc011bHRQcmljZQgIBQAAAA1zeXNTdGF0ZVR1cGxlAAAAAl8yAAAABXZhbHVlBAAAABBiYXNlQXNzZXRCYWxhbmNlCAgFAAAADXN5c1N0YXRlVHVwbGUAAAACXzMAAAAFdmFsdWUEAAAAFXRvdGFsTG9ja2VkQmFzZUFtb3VudAgIBQAAAA1zeXNTdGF0ZVR1cGxlAAAAAl80AAAABXZhbHVlBAAAABNiYXNlQXNzZXRCYWxhbmNlV0NPCAgFAAAADXN5c1N0YXRlVHVwbGUAAAACXzUAAAAFdmFsdWUEAAAADXNoYXJlRW1pc3Npb24ICAUAAAANc3lzU3RhdGVUdXBsZQAAAAJfNgAAAAV2YWx1ZQQAAAAZY3Vyckl0ZXJUb3RhbEluQmFzZUFtb3VudAgIBQAAAA1zeXNTdGF0ZVR1cGxlAAAAAl83AAAABXZhbHVlBAAAABpjdXJySXRlclRvdGFsSW5TaGFyZUFtb3VudAgIBQAAAA1zeXNTdGF0ZVR1cGxlAAAAAl84AAAABXZhbHVlBAAAABh0b3RhbExvY2tlZE91dEJhc2VBbW91bnQICAUAAAANc3lzU3RhdGVUdXBsZQAAAAJfOQAAAAV2YWx1ZQQAAAAZdG90YWxMb2NrZWRPdXRTaGFyZUFtb3VudAgIBQAAAA1zeXNTdGF0ZVR1cGxlAAAAA18xMAAAAAV2YWx1ZQQAAAAWZGVjaW1hbHNNdWx0Qm90aEFzc2V0cwgIBQAAAA1zeXNTdGF0ZVR1cGxlAAAAA18xMQAAAAV2YWx1ZQQAAAAIcHJpY2VBVEgICAUAAAANc3lzU3RhdGVUdXBsZQAAAANfMTIAAAAFdmFsdWUEAAAAEXByaWNlUmVjYWxjdWxhdGVkCAgFAAAADXN5c1N0YXRlVHVwbGUAAAADXzEzAAAABXZhbHVlBAAAAA10b3B1cExhc3RUaW1lCAgFAAAADXN5c1N0YXRlVHVwbGUAAAADXzE0AAAABXZhbHVlBAAAAAhyZXN0RGF0YQkABLkAAAACCQAETAAAAAICAAAAGXN0YXJ0Q3VycmVudFN5c1BhcmFtc1JFU1QJAARMAAAAAgkAAaQAAAABBQAAAAVwcmljZQkABEwAAAACCQABpAAAAAEFAAAAEWRlY2ltYWxzTXVsdFByaWNlCQAETAAAAAIJAAGkAAAAAQUAAAAQYmFzZUFzc2V0QmFsYW5jZQkABEwAAAACCQABpAAAAAEFAAAAFXRvdGFsTG9ja2VkQmFzZUFtb3VudAkABEwAAAACCQABpAAAAAEFAAAAE2Jhc2VBc3NldEJhbGFuY2VXQ08JAARMAAAAAgkAAaQAAAABBQAAAA1zaGFyZUVtaXNzaW9uCQAETAAAAAIJAAGkAAAAAQUAAAAZY3Vyckl0ZXJUb3RhbEluQmFzZUFtb3VudAkABEwAAAACCQABpAAAAAEFAAAAGmN1cnJJdGVyVG90YWxJblNoYXJlQW1vdW50CQAETAAAAAIJAAGkAAAAAQUAAAAYdG90YWxMb2NrZWRPdXRCYXNlQW1vdW50CQAETAAAAAIJAAGkAAAAAQUAAAAZdG90YWxMb2NrZWRPdXRTaGFyZUFtb3VudAkABEwAAAACCQABpAAAAAEFAAAAFmRlY2ltYWxzTXVsdEJvdGhBc3NldHMJAARMAAAAAgkAAaQAAAABBQAAAAhwcmljZUFUSAkABEwAAAACCQABpAAAAAEFAAAAEXByaWNlUmVjYWxjdWxhdGVkCQAETAAAAAIJAAGkAAAAAQUAAAANdG9wdXBMYXN0VGltZQkABEwAAAACAgAAABdlbmRDdXJyZW50U3lzUGFyYW1zUkVTVAUAAAADbmlsBQAAAANTRVAJAAACAAAAAQUAAAAIcmVzdERhdGEAAAAA/QJjSw==", "chainId": 84, "height": 1473279, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: 6pjRwXrrEcPcU2U94Ax2cuENuwahBQZwnd5F7Yo2DFz3 Full:
Old | New | Differences | |
---|---|---|---|
1 | - | # no script | |
1 | + | {-# STDLIB_VERSION 4 #-} | |
2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | + | {-# CONTENT_TYPE DAPP #-} | |
4 | + | let SEP = "__" | |
5 | + | ||
6 | + | func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), ("No data for this.key=" + key)) | |
7 | + | ||
8 | + | ||
9 | + | func getBooleanOrFail (key) = valueOrErrorMessage(getBoolean(this, key), ("No data for this.key=" + key)) | |
10 | + | ||
11 | + | ||
12 | + | func getIntOrFail (key) = valueOrErrorMessage(getInteger(this, key), ("No data for this.key=" + key)) | |
13 | + | ||
14 | + | ||
15 | + | func failExecuteGet (msg,baseAssetStr,userAddressStr,submitTxIdStr,operationType) = throw(((((((((msg + ": baseAsset=") + baseAssetStr) + " userAddress=") + userAddressStr) + " submitTxId=") + submitTxIdStr) + " operation=") + operationType)) | |
16 | + | ||
17 | + | ||
18 | + | func failSubmitLimitsExceeds (remainingBase,remainingShare,newRemainingBase,newRemainingShare) = throw((((((((("submit operation limits have been reached: " + " remainingBaseVal=") + toString(remainingBase)) + " remainingShareVal=") + toString(remainingShare)) + " newRemainingBaseVal=") + toString(newRemainingBase)) + " newRemainingShareVal=") + toString(newRemainingShare))) | |
19 | + | ||
20 | + | ||
21 | + | func failTopupManagerOnly (topupManagerAddress) = throw((("opertion denied: only topUpManager=" + topupManagerAddress) + " can send such transactions")) | |
22 | + | ||
23 | + | ||
24 | + | func convertShare2Base (shareAmount,price,priceMult) = fraction(shareAmount, price, priceMult) | |
25 | + | ||
26 | + | ||
27 | + | func convertBase2Share (baseAmount,price,priceMult) = fraction(baseAmount, priceMult, price) | |
28 | + | ||
29 | + | ||
30 | + | func keyAssetCfg (baseAssetStr) = ("%s%s%s__config__asset__" + baseAssetStr) | |
31 | + | ||
32 | + | ||
33 | + | func keyNextInternalAssetId () = "%s__nextInternalAssetId" | |
34 | + | ||
35 | + | ||
36 | + | func keyPriceLast (internalBasetAssetStr) = ("%s%s%d__price__last__" + internalBasetAssetStr) | |
37 | + | ||
38 | + | ||
39 | + | func keyPriceATH (internalBasetAssetStr) = ("%s%s%d__price__ath__" + internalBasetAssetStr) | |
40 | + | ||
41 | + | ||
42 | + | func keyPriceByTopUpIdx (internalBaseAssetStr,topUpIdx) = makeString(["%s%s%d%d__price__byTopUpIdx", internalBaseAssetStr, toString(topUpIdx)], SEP) | |
43 | + | ||
44 | + | ||
45 | + | func keyPriceHistory (internalBasetAssetStr,h,timestamp) = makeString(["%s%s%d%d%d__price__history", internalBasetAssetStr, toString(h), toString(timestamp)], SEP) | |
46 | + | ||
47 | + | ||
48 | + | func keyTotalLocked (internalBasetAssetStr) = ("%s%s%d__total__locked__" + internalBasetAssetStr) | |
49 | + | ||
50 | + | ||
51 | + | func keyTotalLockedByUser (internalBaseAssetStr,userAddressStr) = makeString(["%s%s%d%s__total__locked", internalBaseAssetStr, userAddressStr], SEP) | |
52 | + | ||
53 | + | ||
54 | + | func keyMappingsInternal2baseAssetId (internalBaseAsset) = ("%s%s%d__mappings__internal2baseAssetId__" + toString(internalBaseAsset)) | |
55 | + | ||
56 | + | ||
57 | + | func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr) | |
58 | + | ||
59 | + | ||
60 | + | func keyMappingsShare2baseAssetId (shareAssetStr) = ("%s%s%s__mappings__share2baseAssetId__" + shareAssetStr) | |
61 | + | ||
62 | + | ||
63 | + | func keyMappingsBaseAsset2shareId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2shareId__" + baseAssetStr) | |
64 | + | ||
65 | + | ||
66 | + | func keyShutdownSubmitOperation (internalBaseAssetStr) = ("%s%s%d__shutdown__submit__" + internalBaseAssetStr) | |
67 | + | ||
68 | + | ||
69 | + | func keyShutdownManager (internalBaseAssetStr) = ("%s%s%d__shutdown__manager__" + internalBaseAssetStr) | |
70 | + | ||
71 | + | ||
72 | + | func keyTopUpCurrentIdx (internalBaseAssetStr) = ("%s%s%d__topup__currentIdx__" + internalBaseAssetStr) | |
73 | + | ||
74 | + | ||
75 | + | func keyTopUpLastHeight (internalBasetAssetStr,sender) = makeString(["%s%s%s%d%s__topup__last__height", internalBasetAssetStr, sender], SEP) | |
76 | + | ||
77 | + | ||
78 | + | func keyTopupMutext (internalBasetAssetStr) = ("%s%s%d__topup__mutex__" + internalBasetAssetStr) | |
79 | + | ||
80 | + | ||
81 | + | func keyTopupLastTimestamp (internalBasetAssetStr) = ("%s%s%s%d__topup__last__timestamp__" + internalBasetAssetStr) | |
82 | + | ||
83 | + | ||
84 | + | func keyTopupHistory (internalBasetAssetStr,topupIdx) = makeString(["%s%s%d%d__topup__history", internalBasetAssetStr, toString(topupIdx)], SEP) | |
85 | + | ||
86 | + | ||
87 | + | func keyLimitsRemaining (internalBasetAssetStr) = ("%s%s%d__limits__remaining__" + internalBasetAssetStr) | |
88 | + | ||
89 | + | ||
90 | + | let IdxCfgShareAssetId = 1 | |
91 | + | ||
92 | + | let IdxCfgInternalBaseAsset = 2 | |
93 | + | ||
94 | + | let IdxCfgDecimalsMultBothAssets = 3 | |
95 | + | ||
96 | + | let IdxCfgDecimalsMultPrice = 4 | |
97 | + | ||
98 | + | let IdxCfgGetDelayBlocks = 5 | |
99 | + | ||
100 | + | let IdxCfgTopupIntervalInBlocks = 6 | |
101 | + | ||
102 | + | let IdxCfgTopupMaxNegativePart = 7 | |
103 | + | ||
104 | + | let IdxCfgTopupManagerAddress = 8 | |
105 | + | ||
106 | + | let IdxCfgSubmitLimitsBaseMax = 9 | |
107 | + | ||
108 | + | let IdxCfgSubmitLimitsBaseReset = 10 | |
109 | + | ||
110 | + | let IdxCfgSubmitLimitsShareMax = 11 | |
111 | + | ||
112 | + | let IdxCfgSubmitLimitsShareReset = 12 | |
113 | + | ||
114 | + | let IdxCfgAdminAddress = 13 | |
115 | + | ||
116 | + | func dataAssetCfg (shareAssetStr,internalBaseAssetStr,decimalsMultBothAssets,decimalsMultPrice,getDelayInBlocks,topupIntervalInBlocks,topupMaxNegativePart,topupManagerAddress,submitLimitsBaseMax,submitLimitsBaseReset,submitLimitsShareMax,submitLimitsShareReset,adminAddress) = makeString(["%s%d%d%d%d%d%d%s%d%d%d%d", shareAssetStr, internalBaseAssetStr, toString(decimalsMultBothAssets), toString(decimalsMultPrice), toString(getDelayInBlocks), toString(topupIntervalInBlocks), toString(topupMaxNegativePart), topupManagerAddress, toString(submitLimitsBaseMax), toString(submitLimitsBaseReset), toString(submitLimitsShareMax), toString(submitLimitsShareReset), adminAddress], SEP) | |
117 | + | ||
118 | + | ||
119 | + | let IdxTotalLockedInShare = 1 | |
120 | + | ||
121 | + | let IdxTotalLockedOutBase = 2 | |
122 | + | ||
123 | + | let IdxTotalLockedInBase = 3 | |
124 | + | ||
125 | + | let IdxTotalLockedOutShare = 4 | |
126 | + | ||
127 | + | func dataTotalLocked (inShareAmount,outBaseAmount,inBaseAmount,outShareAmount) = makeString(["%d%d%d%d", toString(inShareAmount), toString(outBaseAmount), toString(inBaseAmount), toString(outShareAmount)], SEP) | |
128 | + | ||
129 | + | ||
130 | + | func dataTotalLockedInt (inShareAmount,outBaseAmount,inBaseAmount,outShareAmount) = [-1, inShareAmount, outBaseAmount, inBaseAmount, outShareAmount] | |
131 | + | ||
132 | + | ||
133 | + | func readTotalLocked (key) = { | |
134 | + | let totalLockedArray = split(valueOrElse(getString(this, key), dataTotalLocked(0, 0, 0, 0)), SEP) | |
135 | + | dataTotalLockedInt(parseIntValue(totalLockedArray[IdxTotalLockedInShare]), parseIntValue(totalLockedArray[IdxTotalLockedOutBase]), parseIntValue(totalLockedArray[IdxTotalLockedInBase]), parseIntValue(totalLockedArray[IdxTotalLockedOutShare])) | |
136 | + | } | |
137 | + | ||
138 | + | ||
139 | + | func calcTotalLockedDiff (direction,operationType,internalBaseAssetStr,price,priceMult,inAmount,baseAssetId,shareAssetId) = { | |
140 | + | let t = (direction + operationType) | |
141 | + | if ((t == "submitP")) | |
142 | + | then { | |
143 | + | let totalDiff = dataTotalLockedInt(0, 0, inAmount, 0) | |
144 | + | let userDiff = totalDiff | |
145 | + | $Tuple4(totalDiff, userDiff, 0, fromBase58String("")) | |
146 | + | } | |
147 | + | else if ((t == "submitG")) | |
148 | + | then { | |
149 | + | let totalDiff = dataTotalLockedInt(inAmount, 0, 0, 0) | |
150 | + | let userDiff = totalDiff | |
151 | + | $Tuple4(totalDiff, userDiff, 0, fromBase58String("")) | |
152 | + | } | |
153 | + | else if ((t == "executeP")) | |
154 | + | then { | |
155 | + | let outAmount = convertBase2Share(inAmount, price, priceMult) | |
156 | + | let totalDiff = dataTotalLockedInt(0, 0, 0, outAmount) | |
157 | + | let userDiff = dataTotalLockedInt(0, 0, inAmount, 0) | |
158 | + | $Tuple4(totalDiff, userDiff, outAmount, shareAssetId) | |
159 | + | } | |
160 | + | else if ((t == "executeG")) | |
161 | + | then { | |
162 | + | let outAmount = convertShare2Base(inAmount, price, priceMult) | |
163 | + | let totalDiff = dataTotalLockedInt(0, outAmount, 0, 0) | |
164 | + | let userDiff = dataTotalLockedInt(inAmount, 0, 0, 0) | |
165 | + | $Tuple4(totalDiff, userDiff, outAmount, baseAssetId) | |
166 | + | } | |
167 | + | else if ((t == "topup")) | |
168 | + | then { | |
169 | + | let totalLockedArray = readTotalLocked(keyTotalLocked(internalBaseAssetStr)) | |
170 | + | let totalLockedInBaseAmount = totalLockedArray[IdxTotalLockedInBase] | |
171 | + | let totalLockedInShareAmount = totalLockedArray[IdxTotalLockedInShare] | |
172 | + | let totalDiff = dataTotalLockedInt(totalLockedInShareAmount, (-1 * convertShare2Base(totalLockedInShareAmount, price, priceMult)), totalLockedInBaseAmount, (-1 * convertBase2Share(totalLockedInBaseAmount, price, priceMult))) | |
173 | + | $Tuple4(totalDiff, nil, 0, fromBase58String("")) | |
174 | + | } | |
175 | + | else throw(("Unsupported Type " + t)) | |
176 | + | } | |
177 | + | ||
178 | + | ||
179 | + | func TotalLockedStringEntry (action,key,diff) = { | |
180 | + | func UPDATE (a,b) = if ((action == "INCREMENT")) | |
181 | + | then (a + b) | |
182 | + | else if ((action == "DECREMENT")) | |
183 | + | then (a - b) | |
184 | + | else throw(("Unsupported action " + action)) | |
185 | + | ||
186 | + | let dataArray = readTotalLocked(key) | |
187 | + | StringEntry(key, dataTotalLocked(UPDATE(dataArray[IdxTotalLockedInShare], diff[IdxTotalLockedInShare]), UPDATE(dataArray[IdxTotalLockedOutBase], diff[IdxTotalLockedOutBase]), UPDATE(dataArray[IdxTotalLockedInBase], diff[IdxTotalLockedInBase]), UPDATE(dataArray[IdxTotalLockedOutShare], diff[IdxTotalLockedOutShare]))) | |
188 | + | } | |
189 | + | ||
190 | + | ||
191 | + | func keyOperation (operationType,internalBaseAssetStr,userAddress,txId) = makeString(["%s%d%s%s", operationType, internalBaseAssetStr, userAddress, txId], SEP) | |
192 | + | ||
193 | + | ||
194 | + | let IdxOperStatus = 1 | |
195 | + | ||
196 | + | let IdxOperInAmount = 2 | |
197 | + | ||
198 | + | let IdxOperPrice = 3 | |
199 | + | ||
200 | + | let IdxOperOutAmount = 4 | |
201 | + | ||
202 | + | let IdxOperStartHeight = 5 | |
203 | + | ||
204 | + | let IdxOperStartTimestamp = 6 | |
205 | + | ||
206 | + | let IdxOperEndHeight = 7 | |
207 | + | ||
208 | + | let IdxOperEndTimestamp = 8 | |
209 | + | ||
210 | + | let IdxOperTopupUnlockIdx = 9 | |
211 | + | ||
212 | + | func privateDataOperationAllStrings (status,inAssetAmount,price,outAssetAmount,startHeight,startTimestamp,endHeight,endTimestamp,lock) = makeString(["%s%d%d%d%d%d%d%d%d", status, inAssetAmount, price, outAssetAmount, startHeight, startTimestamp, endHeight, endTimestamp, lock], SEP) | |
213 | + | ||
214 | + | ||
215 | + | func dataOperation (status,inAssetAmount,price,outAssetAmount,startHeight,startTimestamp,endHeight,endTimestamp,topupUnlockIdx) = privateDataOperationAllStrings(status, toString(inAssetAmount), toString(price), toString(outAssetAmount), toString(startHeight), toString(startTimestamp), toString(endHeight), toString(endTimestamp), toString(topupUnlockIdx)) | |
216 | + | ||
217 | + | ||
218 | + | func dataOperationExecutionUpdate (currOperArray,newStatus,newPrice,newOutAmount) = privateDataOperationAllStrings(newStatus, currOperArray[IdxOperInAmount], toString(newPrice), toString(newOutAmount), currOperArray[IdxOperStartHeight], currOperArray[IdxOperStartTimestamp], toString(height), toString(lastBlock.timestamp), currOperArray[IdxOperTopupUnlockIdx]) | |
219 | + | ||
220 | + | ||
221 | + | func readAssetCfgOrFail (baseAssetStr) = { | |
222 | + | let key = keyAssetCfg(baseAssetStr) | |
223 | + | split(getStringOrFail(key), SEP) | |
224 | + | } | |
225 | + | ||
226 | + | ||
227 | + | let IdxLimitsRemainingBase = 1 | |
228 | + | ||
229 | + | let IdxLimitsRemainingShare = 2 | |
230 | + | ||
231 | + | func RemainingLimitsStringEntry (key,baseRemainingLimit,shareRemainingLimit) = StringEntry(key, makeString(["%d%d", toString(baseRemainingLimit), toString(shareRemainingLimit)], SEP)) | |
232 | + | ||
233 | + | ||
234 | + | func TopupMutexIntEntry (internalBaseAssetStr,acquiredHeight) = IntegerEntry(keyTopupMutext(internalBaseAssetStr), acquiredHeight) | |
235 | + | ||
236 | + | ||
237 | + | func genericCalcPrice (internalBaseAssetStr,baseAssetId,topUpBaseAmount,shareAssetId,decimalsMultPrice) = { | |
238 | + | let totalLockedArray = readTotalLocked(keyTotalLocked(internalBaseAssetStr)) | |
239 | + | let totalLockedOutBaseAmount = totalLockedArray[IdxTotalLockedOutBase] | |
240 | + | let currIterTotalInBaseAmount = totalLockedArray[IdxTotalLockedInBase] | |
241 | + | let baseAssetBalance = assetBalance(this, baseAssetId) | |
242 | + | let baseAssetBalanceWCO = (((baseAssetBalance + topUpBaseAmount) - currIterTotalInBaseAmount) - totalLockedOutBaseAmount) | |
243 | + | let totalLockedOutShareAmount = totalLockedArray[IdxTotalLockedOutShare] | |
244 | + | let currIterTotalInShareAmount = totalLockedArray[IdxTotalLockedInShare] | |
245 | + | let shareEmission = value(assetInfo(shareAssetId)).quantity | |
246 | + | if ((0 > baseAssetBalanceWCO)) | |
247 | + | then throw(((("baseAssetBalanceWco < 0: baseAssettBalance=" + toString(baseAssetBalance)) + " baseAssetBalanceWco=") + toString(baseAssetBalanceWCO))) | |
248 | + | else { | |
249 | + | let lastPrice = getIntOrFail(keyPriceLast(internalBaseAssetStr)) | |
250 | + | let price = if ((shareEmission == 0)) | |
251 | + | then lastPrice | |
252 | + | else fraction(baseAssetBalanceWCO, decimalsMultPrice, shareEmission) | |
253 | + | $Tuple9(price, baseAssetBalance, -1, baseAssetBalanceWCO, shareEmission, currIterTotalInBaseAmount, currIterTotalInShareAmount, totalLockedOutBaseAmount, totalLockedOutShareAmount) | |
254 | + | } | |
255 | + | } | |
256 | + | ||
257 | + | ||
258 | + | func calcPrice (internalBaseAssetStr,baseAssetId,shareAssetId,decimalsMultPrice) = genericCalcPrice(internalBaseAssetStr, baseAssetId, 0, shareAssetId, decimalsMultPrice) | |
259 | + | ||
260 | + | ||
261 | + | func commonSubmit (operationType,i,inAmount,inAssetId,baseAssetStr) = { | |
262 | + | let inAssetStr = toBase58String(inAssetId) | |
263 | + | let userAddressStr = toString(i.caller) | |
264 | + | let baseAssetId = fromBase58String(baseAssetStr) | |
265 | + | let cfgArray = readAssetCfgOrFail(baseAssetStr) | |
266 | + | let shareAssetStr = cfgArray[IdxCfgShareAssetId] | |
267 | + | let shareAssetId = fromBase58String(shareAssetStr) | |
268 | + | let decimalsMultBothAssets = parseIntValue(cfgArray[IdxCfgDecimalsMultBothAssets]) | |
269 | + | let internalBaseAssetStr = cfgArray[IdxCfgInternalBaseAsset] | |
270 | + | let limitsKEY = keyLimitsRemaining(internalBaseAssetStr) | |
271 | + | let limitsCfgArray = split(getStringOrFail(limitsKEY), SEP) | |
272 | + | let limitsRemainingBase = parseIntValue(limitsCfgArray[IdxLimitsRemainingBase]) | |
273 | + | let limitsRemainingShare = parseIntValue(limitsCfgArray[IdxLimitsRemainingShare]) | |
274 | + | let isSubmitBlocked = valueOrElse(getBoolean(this, keyShutdownSubmitOperation(internalBaseAssetStr)), false) | |
275 | + | if (isSubmitBlocked) | |
276 | + | then throw("submit operation is blocked") | |
277 | + | else { | |
278 | + | let operationsMutex = valueOrElse(getInteger(this, keyTopupMutext(internalBaseAssetStr)), 0) | |
279 | + | if (((operationsMutex + 60) > height)) | |
280 | + | then throw("submit operations are blocked by topup manager") | |
281 | + | else { | |
282 | + | let diffTuple = calcTotalLockedDiff("submit", operationType, internalBaseAssetStr, 0, 0, inAmount, baseAssetId, shareAssetId) | |
283 | + | let limitsRemainingBaseNew = (limitsRemainingBase - diffTuple._2[IdxTotalLockedInBase]) | |
284 | + | let limitsRemainingShareNew = (limitsRemainingShare - diffTuple._2[IdxTotalLockedInShare]) | |
285 | + | if (if ((0 > limitsRemainingBaseNew)) | |
286 | + | then true | |
287 | + | else (0 > limitsRemainingShareNew)) | |
288 | + | then failSubmitLimitsExceeds(limitsRemainingBase, limitsRemainingShare, limitsRemainingBaseNew, limitsRemainingShareNew) | |
289 | + | else { | |
290 | + | let topUpCurrentIdx = getIntOrFail(keyTopUpCurrentIdx(internalBaseAssetStr)) | |
291 | + | ((([StringEntry(keyOperation(operationType, internalBaseAssetStr, userAddressStr, toBase58String(i.transactionId)), dataOperation("PENDING", inAmount, 0, 0, height, lastBlock.timestamp, 0, 0, (topUpCurrentIdx + 1)))] :+ TotalLockedStringEntry("INCREMENT", keyTotalLocked(internalBaseAssetStr), diffTuple._1)) :+ TotalLockedStringEntry("INCREMENT", keyTotalLockedByUser(internalBaseAssetStr, userAddressStr), diffTuple._2)) :+ RemainingLimitsStringEntry(limitsKEY, limitsRemainingBaseNew, limitsRemainingShareNew)) | |
292 | + | } | |
293 | + | } | |
294 | + | } | |
295 | + | } | |
296 | + | ||
297 | + | ||
298 | + | func commonExecute (operationType,baseAssetStr,userAddressStr,submitTxIdStr) = { | |
299 | + | let userAddress = addressFromStringValue(userAddressStr) | |
300 | + | let assetCfgArray = readAssetCfgOrFail(baseAssetStr) | |
301 | + | let shareAssetId = fromBase58String(assetCfgArray[IdxCfgShareAssetId]) | |
302 | + | let internalBaseAssetStr = assetCfgArray[IdxCfgInternalBaseAsset] | |
303 | + | let decimalsMultPrice = parseIntValue(assetCfgArray[IdxCfgDecimalsMultPrice]) | |
304 | + | let baseAssetId = fromBase58String(baseAssetStr) | |
305 | + | let operationKey = keyOperation(operationType, internalBaseAssetStr, userAddressStr, submitTxIdStr) | |
306 | + | let operationArray = split(getStringOrFail(operationKey), SEP) | |
307 | + | let status = operationArray[IdxOperStatus] | |
308 | + | let inAmount = parseIntValue(operationArray[IdxOperInAmount]) | |
309 | + | let topupUnlockIdx = parseIntValue(operationArray[IdxOperTopupUnlockIdx]) | |
310 | + | let currTopUpIdx = getIntOrFail(keyTopUpCurrentIdx(internalBaseAssetStr)) | |
311 | + | let priceByTopUpId = getIntOrFail(keyPriceByTopUpIdx(internalBaseAssetStr, topupUnlockIdx)) | |
312 | + | if ((status != "PENDING")) | |
313 | + | then failExecuteGet("Status is not PENDING", baseAssetStr, userAddressStr, submitTxIdStr, operationType) | |
314 | + | else if ((topupUnlockIdx > currTopUpIdx)) | |
315 | + | then failExecuteGet(((("OperLock[" + toString(topupUnlockIdx)) + "] > ") + toString(currTopUpIdx)), baseAssetStr, userAddressStr, submitTxIdStr, operationType) | |
316 | + | else { | |
317 | + | let diffTuple = calcTotalLockedDiff("execute", operationType, internalBaseAssetStr, priceByTopUpId, decimalsMultPrice, inAmount, baseAssetId, shareAssetId) | |
318 | + | let outAmount = diffTuple._3 | |
319 | + | let outTransferData = if ((diffTuple._4 == baseAssetId)) | |
320 | + | then [ScriptTransfer(userAddress, outAmount, baseAssetId)] | |
321 | + | else [ScriptTransfer(userAddress, outAmount, shareAssetId)] | |
322 | + | (((outTransferData :+ StringEntry(operationKey, dataOperationExecutionUpdate(operationArray, "FINISHED", priceByTopUpId, outAmount))) :+ TotalLockedStringEntry("DECREMENT", keyTotalLocked(internalBaseAssetStr), diffTuple._1)) :+ TotalLockedStringEntry("DECREMENT", keyTotalLockedByUser(internalBaseAssetStr, userAddressStr), diffTuple._2)) | |
323 | + | } | |
324 | + | } | |
325 | + | ||
326 | + | ||
327 | + | func privateCurrentSysParamsREST (baseAssetStr) = { | |
328 | + | let baseAssetId = fromBase58String(baseAssetStr) | |
329 | + | let cfgArray = readAssetCfgOrFail(baseAssetStr) | |
330 | + | let shareAssetStr = cfgArray[IdxCfgShareAssetId] | |
331 | + | let shareAssetId = fromBase58String(shareAssetStr) | |
332 | + | let decimalsMultBothAssetsVal = parseIntValue(cfgArray[IdxCfgDecimalsMultBothAssets]) | |
333 | + | let decimalsMultPriceVal = parseIntValue(cfgArray[IdxCfgDecimalsMultPrice]) | |
334 | + | let internalBaseAssetStr = cfgArray[IdxCfgInternalBaseAsset] | |
335 | + | let priceAthKEY = keyPriceATH(internalBaseAssetStr) | |
336 | + | let priceAthVal = valueOrElse(getInteger(this, priceAthKEY), 0) | |
337 | + | let priceLastKEY = keyPriceLast(internalBaseAssetStr) | |
338 | + | let priceLastVal = valueOrElse(getInteger(this, priceLastKEY), 0) | |
339 | + | let topupLastTimeKEY = keyTopupLastTimestamp(internalBaseAssetStr) | |
340 | + | let topupLastTimeVal = valueOrElse(getInteger(this, topupLastTimeKEY), 0) | |
341 | + | let sysState = calcPrice(internalBaseAssetStr, baseAssetId, shareAssetId, decimalsMultPriceVal) | |
342 | + | $Tuple14(IntegerEntry("price", priceLastVal), IntegerEntry("decimalsMultPrice", decimalsMultPriceVal), IntegerEntry("baseAssetBalance", sysState._2), IntegerEntry("-1", sysState._3), IntegerEntry("baseAssetBalanceWCO", sysState._4), IntegerEntry("shareEmission", sysState._5), IntegerEntry("currIterTotalInBaseAmount", sysState._6), IntegerEntry("currIterTotalInShareAmount", sysState._7), IntegerEntry("totalLockedOutBaseAmount", sysState._8), IntegerEntry("totalLockedOutShareAmount", sysState._9), IntegerEntry("decimalsMultBothAssets", decimalsMultBothAssetsVal), IntegerEntry("priceATH", priceAthVal), IntegerEntry("priceRecalculated", sysState._1), IntegerEntry("topupLastTimestamp", topupLastTimeVal)) | |
343 | + | } | |
344 | + | ||
345 | + | ||
346 | + | @Callable(i) | |
347 | + | func adminRegisterAsset (baseAssetStr,shareAssetName,shareAssetDescr,getDelayinBlocks,shutdownManagerAddress,startPrice,topupIntervalInBlocks,topupMaxNegativePart,topupManagerAddress,submitLimitsBaseMax,submitLimitsBaseReset,submitLimitsShareMax,submitLimitsShareReset,adminAddress) = { | |
348 | + | let baseAssetId = fromBase58String(baseAssetStr) | |
349 | + | let bothAssetsDecimals = value(assetInfo(baseAssetId)).decimals | |
350 | + | let decimalsMultBothAssets = pow(10, 0, bothAssetsDecimals, 0, 0, DOWN) | |
351 | + | let decimalsMultPrice = ((100 * 1000) * 1000) | |
352 | + | let topupMaxNegativePercents = fraction(topupMaxNegativePart, 100, decimalsMultBothAssets) | |
353 | + | let baseAssetBalance = assetBalance(this, baseAssetId) | |
354 | + | if ((i.caller != this)) | |
355 | + | then throw("permissions denied") | |
356 | + | else if ((baseAssetBalance == 0)) | |
357 | + | then throw(((toString(this) + " must have any initial balance of ") + baseAssetStr)) | |
358 | + | else if (isDefined(getString(this, keyAssetCfg(baseAssetStr)))) | |
359 | + | then throw((baseAssetStr + " has been already registered")) | |
360 | + | else if ((toString(addressFromStringValue(shutdownManagerAddress)) != shutdownManagerAddress)) | |
361 | + | then throw("invalid shutdownManagerAddress") | |
362 | + | else if ((toString(addressFromStringValue(topupManagerAddress)) != topupManagerAddress)) | |
363 | + | then throw("invalid topupManagerAddress") | |
364 | + | else if ((0 > getDelayinBlocks)) | |
365 | + | then throw(("invalid getDelayinBlocks=" + toString(getDelayinBlocks))) | |
366 | + | else if (if ((0 >= topupMaxNegativePercents)) | |
367 | + | then true | |
368 | + | else (topupMaxNegativePercents >= 99)) | |
369 | + | then throw("invalid topupMaxNegativePart parameter") | |
370 | + | else { | |
371 | + | let shareInitAmount = convertBase2Share(baseAssetBalance, startPrice, decimalsMultPrice) | |
372 | + | let shareAssetIssueAction = Issue(shareAssetName, shareAssetDescr, shareInitAmount, bothAssetsDecimals, true) | |
373 | + | let shareAssetId = calculateAssetId(shareAssetIssueAction) | |
374 | + | let shareAssetStr = toBase58String(shareAssetId) | |
375 | + | let internalBaseAssetId = valueOrElse(getInteger(this, keyNextInternalAssetId()), 0) | |
376 | + | let internalBaseAssetStr = toString(internalBaseAssetId) | |
377 | + | [StringEntry(keyAssetCfg(baseAssetStr), dataAssetCfg(shareAssetStr, internalBaseAssetStr, decimalsMultBothAssets, decimalsMultPrice, getDelayinBlocks, topupIntervalInBlocks, topupMaxNegativePart, topupManagerAddress, submitLimitsBaseMax, submitLimitsBaseReset, submitLimitsShareMax, submitLimitsShareReset, adminAddress)), StringEntry(keyMappingsInternal2baseAssetId(internalBaseAssetId), baseAssetStr), StringEntry(keyMappingsBaseAsset2internalId(baseAssetStr), internalBaseAssetStr), StringEntry(keyMappingsShare2baseAssetId(shareAssetStr), baseAssetStr), StringEntry(keyMappingsBaseAsset2shareId(baseAssetStr), shareAssetStr), BooleanEntry(keyShutdownSubmitOperation(internalBaseAssetStr), false), StringEntry(keyShutdownManager(internalBaseAssetStr), shutdownManagerAddress), IntegerEntry(keyNextInternalAssetId(), (internalBaseAssetId + 1)), IntegerEntry(keyPriceLast(internalBaseAssetStr), startPrice), IntegerEntry(keyPriceHistory(internalBaseAssetStr, height, lastBlock.timestamp), startPrice), IntegerEntry(keyTopUpCurrentIdx(internalBaseAssetStr), 0), RemainingLimitsStringEntry(keyLimitsRemaining(internalBaseAssetStr), submitLimitsBaseMax, submitLimitsShareMax), shareAssetIssueAction, ScriptTransfer(addressFromStringValue(topupManagerAddress), shareInitAmount, shareAssetId)] | |
378 | + | } | |
379 | + | } | |
380 | + | ||
381 | + | ||
382 | + | ||
383 | + | @Callable(i) | |
384 | + | func shutdownSubmits (internalBaseAssetId) = { | |
385 | + | let internalBaseAssetIdStr = toString(internalBaseAssetId) | |
386 | + | let baseAssetIdStr = getStringOrFail(keyMappingsInternal2baseAssetId(internalBaseAssetId)) | |
387 | + | let shutdownManagerAddress = getStringOrFail(keyShutdownManager(internalBaseAssetIdStr)) | |
388 | + | if ((1 > size(baseAssetIdStr))) | |
389 | + | then throw("invalid internalBaseAssetId") | |
390 | + | else if ((toString(i.caller) != shutdownManagerAddress)) | |
391 | + | then throw("access denied") | |
392 | + | else [BooleanEntry(keyShutdownSubmitOperation(toString(internalBaseAssetId)), true)] | |
393 | + | } | |
394 | + | ||
395 | + | ||
396 | + | ||
397 | + | @Callable(i) | |
398 | + | func submitPut () = { | |
399 | + | let pmt = value(i.payments[0]) | |
400 | + | let inAmount = pmt.amount | |
401 | + | let inAssetId = value(pmt.assetId) | |
402 | + | let baseAssetStr = toBase58String(inAssetId) | |
403 | + | commonSubmit("P", i, inAmount, inAssetId, baseAssetStr) | |
404 | + | } | |
405 | + | ||
406 | + | ||
407 | + | ||
408 | + | @Callable(i) | |
409 | + | func submitGet () = { | |
410 | + | let pmt = value(i.payments[0]) | |
411 | + | let inAmount = pmt.amount | |
412 | + | let inAssetId = value(pmt.assetId) | |
413 | + | let shareAssetStr = toBase58String(inAssetId) | |
414 | + | let baseAssetStr = getStringOrFail(keyMappingsShare2baseAssetId(shareAssetStr)) | |
415 | + | commonSubmit("G", i, inAmount, inAssetId, baseAssetStr) | |
416 | + | } | |
417 | + | ||
418 | + | ||
419 | + | ||
420 | + | @Callable(i) | |
421 | + | func executePut (baseAssetStr,userAddressStr,submitTxIdStr) = commonExecute("P", baseAssetStr, userAddressStr, submitTxIdStr) | |
422 | + | ||
423 | + | ||
424 | + | ||
425 | + | @Callable(i) | |
426 | + | func executeGet (baseAssetStr,userAddressStr,submitTxIdStr) = commonExecute("G", baseAssetStr, userAddressStr, submitTxIdStr) | |
427 | + | ||
428 | + | ||
429 | + | ||
430 | + | @Callable(i) | |
431 | + | func operationsMutex (baseAssetStr) = { | |
432 | + | let assetCfgArray = readAssetCfgOrFail(baseAssetStr) | |
433 | + | let topUpManagerAddressStr = assetCfgArray[IdxCfgTopupManagerAddress] | |
434 | + | let internalBaseAssetStr = assetCfgArray[IdxCfgInternalBaseAsset] | |
435 | + | if ((toString(i.caller) != topUpManagerAddressStr)) | |
436 | + | then failTopupManagerOnly(topUpManagerAddressStr) | |
437 | + | else [TopupMutexIntEntry(internalBaseAssetStr, height)] | |
438 | + | } | |
439 | + | ||
440 | + | ||
441 | + | ||
442 | + | @Callable(i) | |
443 | + | func topUpBalance (baseAssetStr,income) = { | |
444 | + | let baseAssetId = fromBase58String(baseAssetStr) | |
445 | + | let assetCfgArray = readAssetCfgOrFail(baseAssetStr) | |
446 | + | let shareAssetId = fromBase58String(assetCfgArray[IdxCfgShareAssetId]) | |
447 | + | let priceMult = parseIntValue(assetCfgArray[IdxCfgDecimalsMultPrice]) | |
448 | + | let bothAssetMult = parseIntValue(assetCfgArray[IdxCfgDecimalsMultBothAssets]) | |
449 | + | let topupIntervalInBlocks = parseIntValue(assetCfgArray[IdxCfgTopupIntervalInBlocks]) | |
450 | + | let topupMaxNegativePart = parseIntValue(assetCfgArray[IdxCfgTopupMaxNegativePart]) | |
451 | + | let internalBaseAssetStr = assetCfgArray[IdxCfgInternalBaseAsset] | |
452 | + | let topUpManagerAddressStr = assetCfgArray[IdxCfgTopupManagerAddress] | |
453 | + | let submitLimitsBaseMax = parseIntValue(assetCfgArray[IdxCfgSubmitLimitsBaseMax]) | |
454 | + | let submitLimitsShareMax = parseIntValue(assetCfgArray[IdxCfgSubmitLimitsShareMax]) | |
455 | + | let topUpCurrentIdxKEY = keyTopUpCurrentIdx(internalBaseAssetStr) | |
456 | + | let prevTopUpIdx = getIntOrFail(topUpCurrentIdxKEY) | |
457 | + | let currentTopUpIdx = (prevTopUpIdx + 1) | |
458 | + | let valid = if ((income > 0)) | |
459 | + | then { | |
460 | + | let pmt = value(i.payments[0]) | |
461 | + | let pmtAssetId = value(pmt.assetId) | |
462 | + | if ((baseAssetId != pmtAssetId)) | |
463 | + | then throw("attached payment's asset id is NOT matched passed baseAssetStr") | |
464 | + | else if ((size(i.payments) > 1)) | |
465 | + | then throw("only one payment can be attached") | |
466 | + | else if ((pmt.amount != income)) | |
467 | + | then throw("attached payment.amount is NOT matched passed income argument") | |
468 | + | else true | |
469 | + | } | |
470 | + | else if ((0 > income)) | |
471 | + | then { | |
472 | + | let baseBalance = assetBalance(this, baseAssetId) | |
473 | + | let allowedAmount = fraction(topupMaxNegativePart, baseBalance, bothAssetMult) | |
474 | + | if ((-(income) > allowedAmount)) | |
475 | + | then throw(("topup negative income couldn't be greater than " + toString(allowedAmount))) | |
476 | + | else true | |
477 | + | } | |
478 | + | else throw("zero income is not allowed") | |
479 | + | let topUpLastHeightKEY = keyTopUpLastHeight(internalBaseAssetStr, toString(i.caller)) | |
480 | + | let topUpLastHeight = valueOrElse(getInteger(this, topUpLastHeightKEY), 0) | |
481 | + | if ((toString(i.caller) != topUpManagerAddressStr)) | |
482 | + | then failTopupManagerOnly(topUpManagerAddressStr) | |
483 | + | else if (!(valid)) | |
484 | + | then throw("validation failed") | |
485 | + | else if ((topupIntervalInBlocks > (height - topUpLastHeight))) | |
486 | + | then throw((("1 topup per " + toString(topupIntervalInBlocks)) + " blocks from the same address is allowed")) | |
487 | + | else { | |
488 | + | let price = genericCalcPrice(internalBaseAssetStr, baseAssetId, income, shareAssetId, priceMult)._1 | |
489 | + | let diffTuple = calcTotalLockedDiff("topup", "", internalBaseAssetStr, price, priceMult, 0, baseAssetId, shareAssetId) | |
490 | + | let topupTotalDiff = diffTuple._1 | |
491 | + | let priceAthKEY = keyPriceATH(internalBaseAssetStr) | |
492 | + | let prevPriceATH = valueOrElse(getInteger(this, priceAthKEY), 0) | |
493 | + | ((((((([IntegerEntry(keyPriceLast(internalBaseAssetStr), price), IntegerEntry(keyPriceHistory(internalBaseAssetStr, height, lastBlock.timestamp), price), IntegerEntry(keyPriceByTopUpIdx(internalBaseAssetStr, currentTopUpIdx), price), IntegerEntry(topUpCurrentIdxKEY, currentTopUpIdx), IntegerEntry(priceAthKEY, if ((price > prevPriceATH)) | |
494 | + | then price | |
495 | + | else prevPriceATH), IntegerEntry(topUpLastHeightKEY, height)] :+ TotalLockedStringEntry("DECREMENT", keyTotalLocked(internalBaseAssetStr), topupTotalDiff)) :+ TopupMutexIntEntry(internalBaseAssetStr, 0)) :+ IntegerEntry(keyTopupLastTimestamp(internalBaseAssetStr), lastBlock.timestamp)) :+ RemainingLimitsStringEntry(keyLimitsRemaining(internalBaseAssetStr), submitLimitsBaseMax, submitLimitsShareMax)) :+ Burn(shareAssetId, topupTotalDiff[IdxTotalLockedInShare])) :+ Reissue(shareAssetId, -(topupTotalDiff[IdxTotalLockedOutShare]), true)) ++ (if ((0 > income)) | |
496 | + | then [ScriptTransfer(i.caller, -(income), baseAssetId)] | |
497 | + | else nil)) | |
498 | + | } | |
499 | + | } | |
500 | + | ||
501 | + | ||
502 | + | ||
503 | + | @Callable(i) | |
504 | + | func currentSysParamsREST (baseAssetStr) = { | |
505 | + | let sysStateTuple = privateCurrentSysParamsREST(baseAssetStr) | |
506 | + | let price = sysStateTuple._1.value | |
507 | + | let decimalsMultPrice = sysStateTuple._2.value | |
508 | + | let baseAssetBalance = sysStateTuple._3.value | |
509 | + | let totalLockedBaseAmount = sysStateTuple._4.value | |
510 | + | let baseAssetBalanceWCO = sysStateTuple._5.value | |
511 | + | let shareEmission = sysStateTuple._6.value | |
512 | + | let currIterTotalInBaseAmount = sysStateTuple._7.value | |
513 | + | let currIterTotalInShareAmount = sysStateTuple._8.value | |
514 | + | let totalLockedOutBaseAmount = sysStateTuple._9.value | |
515 | + | let totalLockedOutShareAmount = sysStateTuple._10.value | |
516 | + | let decimalsMultBothAssets = sysStateTuple._11.value | |
517 | + | let priceATH = sysStateTuple._12.value | |
518 | + | let priceRecalculated = sysStateTuple._13.value | |
519 | + | let topupLastTime = sysStateTuple._14.value | |
520 | + | let restData = makeString(["startCurrentSysParamsREST", toString(price), toString(decimalsMultPrice), toString(baseAssetBalance), toString(totalLockedBaseAmount), toString(baseAssetBalanceWCO), toString(shareEmission), toString(currIterTotalInBaseAmount), toString(currIterTotalInShareAmount), toString(totalLockedOutBaseAmount), toString(totalLockedOutShareAmount), toString(decimalsMultBothAssets), toString(priceATH), toString(priceRecalculated), toString(topupLastTime), "endCurrentSysParamsREST"], SEP) | |
521 | + | throw(restData) | |
522 | + | } | |
523 | + | ||
524 | + |
github/deemru/w8io/026f985 32.67 ms ◑