tx · 5X9Q99jY5HW38F29nxJ5LPAQSremBKKryJC8DaQEHrUz

3Mu1HbpAbcgSTDLftXUZXYZDdyXBU1HeEKz:  -0.05000000 Waves

2021.08.25 17:37 [1673983] smart account 3Mu1HbpAbcgSTDLftXUZXYZDdyXBU1HeEKz > SELF 0.00000000 Waves

{ "type": 13, "id": "5X9Q99jY5HW38F29nxJ5LPAQSremBKKryJC8DaQEHrUz", "fee": 5000000, "feeAssetId": null, "timestamp": 1629902236623, "version": 2, "chainId": 84, "sender": "3Mu1HbpAbcgSTDLftXUZXYZDdyXBU1HeEKz", "senderPublicKey": "7Vn6fEvwb5WVoQmeMMtTH5ghWBZFoUzV4iX5qfqnTWMU", "proofs": [ "38vA1KxjGFe28FUMKQssmirEGShf1E5r32Q5dn96bjZb4TWzeHJy9PENERpWLTXDtu915pVHaMdjTvTuB5jgF3Sz" ], "script": "base64:AAIFAAAAAAAAACIIAhIDCgEBEgASBwoFCAgICAESABIFCgMBAQgSBQoDAQEIAAAANgAAAAAUZmFjdG9yeUFkZHJlc3NTdHJpbmcCAAAAIzNOQlBiU21TY1U0VWZxVnJuWWM3OXd2eGp0aXZmbWduU2dHAAAAAApsUGRlY2ltYWxzAAAAAAAAAAAIAAAAABFkZWNpbWFsc011bHRQcmljZQkAAGgAAAACCQAAaAAAAAIAAAAAAAAAAGQAAAAAAAAAA+gAAAAAAAAAA+gAAAAAA1NFUAIAAAACX18AAAAAClBvb2xBY3RpdmUAAAAAAAAAAAEAAAAAD1Bvb2xQdXREaXNhYmxlZAAAAAAAAAAAAgAAAAATUG9vbE1hdGNoZXJEaXNhYmxlZAAAAAAAAAAAAwAAAAAMUG9vbFNodXRkb3duAAAAAAAAAAAEAAAAAAxidXlPcmRlclR5cGUAAAAAAAAAAAAAAAAADXNlbGxPcmRlclR5cGUAAAAAAAAAAAEAAAAADmlkeFBvb2xBZGRyZXNzAAAAAAAAAAABAAAAAA1pZHhQb29sU3RhdHVzAAAAAAAAAAACAAAAABBpZHhQb29sTFBBc3NldElkAAAAAAAAAAADAAAAABBpZHhBbW91bnRBc3NldElkAAAAAAAAAAAEAAAAAA9pZHhQcmljZUFzc2V0SWQAAAAAAAAAAAUAAAAAFmlkeEFtb3VudEFzc2V0RGVjaW1hbHMAAAAAAAAAAAYAAAAAFWlkeFByaWNlQXNzZXREZWNpbWFscwAAAAAAAAAABwAAAAAYaWR4QW1vdW50QXNzZXRJbnRlcm5hbElkAAAAAAAAAAAIAAAAABdpZHhQcmljZUFzc2V0SW50ZXJuYWxJZAAAAAAAAAAACQAAAAANaWR4UG9vbFdlaWdodAAAAAAAAAAACgAAAAASaWR4TFBBc3NldERlY2ltYWxzAAAAAAAAAAALAAAAABNpZHhNYXRjaGVyUHVibGljS2V5AAAAAAAAAAAMAAAAACNpZG1heEFsbG93ZWRPcmRlclByaWNlRGlmZmVyZW5jZVBjdAAAAAAAAAAADQAAAAAVaWR4UG9vbEFtb3VudEFzc2V0QW10AAAAAAAAAAABAAAAABRpZHhQb29sUHJpY2VBc3NldEFtdAAAAAAAAAAAAgAAAAARaWR4UG9vbExQQXNzZXRBbXQAAAAAAAAAAAMBAAAADGtleVByaWNlTGFzdAAAAAACAAAAESVzJXNfX3ByaWNlX19sYXN0AQAAAA9rZXlQcmljZUhpc3RvcnkAAAACAAAAAWgAAAAJdGltZXN0YW1wCQAEuQAAAAIJAARMAAAAAgIAAAAYJXMlcyVkJWRfX3ByaWNlX19oaXN0b3J5CQAETAAAAAIJAAGkAAAAAQUAAAABaAkABEwAAAACCQABpAAAAAEFAAAACXRpbWVzdGFtcAUAAAADbmlsBQAAAANTRVABAAAAEGtleVBvb2xMaXF1aWRpdHkAAAACAAAAE2ludGVybmFsQW1vdW50QXNzZXQAAAASaW50ZXJuYWxQcmljZUFzc2V0CQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACCVkJWQlc19fBQAAABNpbnRlcm5hbEFtb3VudEFzc2V0AgAAAAJfXwUAAAASaW50ZXJuYWxQcmljZUFzc2V0AgAAAAhfX2xvY2tlZAEAAAAWa2V5UG9vbExpcXVpZGl0eUJ5VXNlcgAAAAMAAAATaW50ZXJuYWxBbW91bnRBc3NldAAAABJpbnRlcm5hbFByaWNlQXNzZXQAAAALdXNlckFkZHJlc3MJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACiVkJWQlcyVzX18FAAAAE2ludGVybmFsQW1vdW50QXNzZXQCAAAAAl9fBQAAABJpbnRlcm5hbFByaWNlQXNzZXQCAAAAAl9fBQAAAAt1c2VyQWRkcmVzcwIAAAAIX19sb2NrZWQBAAAAEmtleVB1dEFjdGlvbkJ5VXNlcgAAAAIAAAALdXNlckFkZHJlc3MAAAAEdHhJZAkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAALJXMlcyVzX19QX18FAAAAC3VzZXJBZGRyZXNzAgAAAAJfXwUAAAAEdHhJZAEAAAASa2V5R2V0QWN0aW9uQnlVc2VyAAAAAgAAAAt1c2VyQWRkcmVzcwAAAAR0eElkCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAAslcyVzJXNfX0dfXwUAAAALdXNlckFkZHJlc3MCAAAAAl9fBQAAAAR0eElkAQAAAA5rZXlBbW91bnRBc3NldAAAAAACAAAADyVzX19hbW91bnRBc3NldAEAAAANa2V5UHJpY2VBc3NldAAAAAACAAAADiVzX19wcmljZUFzc2V0AQAAAClrZXlNYXBwaW5nUG9vbENvbnRyYWN0QWRkcmVzc1RvUG9vbEFzc2V0cwAAAAEAAAATcG9vbENvbnRyYWN0QWRkcmVzcwkAASwAAAACCQABLAAAAAICAAAACCVzJXMlc19fBQAAABNwb29sQ29udHJhY3RBZGRyZXNzAgAAACBfX21hcHBpbmdzX19wb29sQ29udHJhY3QyTHBBc3NldAEAAAANa2V5UG9vbENvbmZpZwAAAAIAAAATYW1vdW50QXNzZXRJbnRlcm5hbAAAABJwcmljZUFzc2V0SW50ZXJuYWwJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAIJWQlZCVzX18FAAAAE2Ftb3VudEFzc2V0SW50ZXJuYWwCAAAAAl9fBQAAABJwcmljZUFzc2V0SW50ZXJuYWwCAAAACF9fY29uZmlnAQAAAB9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkAAAAAQAAAAxiYXNlQXNzZXRTdHIJAAEsAAAAAgIAAAAoJXMlcyVzX19tYXBwaW5nc19fYmFzZUFzc2V0MmludGVybmFsSWRfXwUAAAAMYmFzZUFzc2V0U3RyAQAAABNrZXlBbGxQb29sc1NodXRkb3duAAAAAAIAAAAMJXNfX3NodXRkb3duAQAAABBpc0dsb2JhbFNodXRkb3duAAAAAAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBsAAAACCQEAAAAFdmFsdWUAAAABCQAEJgAAAAEFAAAAFGZhY3RvcnlBZGRyZXNzU3RyaW5nCQEAAAATa2V5QWxsUG9vbHNTaHV0ZG93bgAAAAAHAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAPcG9vbEFtb3VudEFzc2V0CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQiAAAAAQkBAAAADmtleUFtb3VudEFzc2V0AAAAAAIAAAAgTm8gY29uZmlnIGZvciBhbW91bnQgYXNzZXQgZm91bmQEAAAADnBvb2xQcmljZUFzc2V0CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQiAAAAAQkBAAAADWtleVByaWNlQXNzZXQAAAAAAgAAAB9ObyBjb25maWcgZm9yIHByaWNlIGFzc2V0IGZvdW5kBAAAABZwb29sUHJpY2VBc3NldEludGVybmFsCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgkBAAAABXZhbHVlAAAAAQkABCYAAAABBQAAABRmYWN0b3J5QWRkcmVzc1N0cmluZwkBAAAAH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQAAAABBQAAAA5wb29sUHJpY2VBc3NldAIAAAAoTm8gY29uZmlnIGZvciBpbnRlcm5hbCBwcmljZSBhc3NldCBmb3VuZAQAAAAXcG9vbEFtb3VudEFzc2V0SW50ZXJuYWwJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACCQEAAAAFdmFsdWUAAAABCQAEJgAAAAEFAAAAFGZhY3RvcnlBZGRyZXNzU3RyaW5nCQEAAAAfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZAAAAAEFAAAAD3Bvb2xBbW91bnRBc3NldAIAAAApTm8gY29uZmlnIGZvciBpbnRlcm5hbCBhbW91bnQgYXNzZXQgZm91bmQJAAS1AAAAAgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAFGZhY3RvcnlBZGRyZXNzU3RyaW5nCQEAAAANa2V5UG9vbENvbmZpZwAAAAIJAAGkAAAAAQUAAAAXcG9vbEFtb3VudEFzc2V0SW50ZXJuYWwJAAGkAAAAAQUAAAAWcG9vbFByaWNlQXNzZXRJbnRlcm5hbAIAAAAoTm8gZmFjdG9yeSBjb25maWcgZm91bmQgZm9yIHBvb2wgYXNzZXRzLgUAAAADU0VQAQAAABBnZXRQb29sTGlxdWlkaXR5AAAAAgAAABVhbW91bnRBc3NldEludGVybmFsSWQAAAAUcHJpY2VBc3NldEludGVybmFsSWQEAAAAGWN1cnJlbnRQb29sTGlxdWlkaXR5VmFsdWUJAAQiAAAAAQkBAAAAEGtleVBvb2xMaXF1aWRpdHkAAAACBQAAABVhbW91bnRBc3NldEludGVybmFsSWQFAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkAwkBAAAAASEAAAABCQEAAAAJaXNEZWZpbmVkAAAAAQUAAAAZY3VycmVudFBvb2xMaXF1aWRpdHlWYWx1ZQkABEwAAAACAgAAAAAJAARMAAAAAgIAAAABMAkABEwAAAACAgAAAAEwCQAETAAAAAICAAAAATAFAAAAA25pbAkABLUAAAACCQEAAAAFdmFsdWUAAAABBQAAABljdXJyZW50UG9vbExpcXVpZGl0eVZhbHVlBQAAAANTRVABAAAAFmdldFBvb2xMaXF1aWRpdHlCeVVzZXIAAAADAAAAFWFtb3VudEFzc2V0SW50ZXJuYWxJZAAAABRwcmljZUFzc2V0SW50ZXJuYWxJZAAAAAt1c2VyQWRkcmVzcwQAAAAZY3VycmVudFBvb2xMaXF1aWRpdHlWYWx1ZQkABCIAAAABCQEAAAAWa2V5UG9vbExpcXVpZGl0eUJ5VXNlcgAAAAMFAAAAFWFtb3VudEFzc2V0SW50ZXJuYWxJZAUAAAAUcHJpY2VBc3NldEludGVybmFsSWQFAAAAC3VzZXJBZGRyZXNzAwkBAAAAASEAAAABCQEAAAAJaXNEZWZpbmVkAAAAAQUAAAAZY3VycmVudFBvb2xMaXF1aWRpdHlWYWx1ZQkABEwAAAACAgAAAAAJAARMAAAAAgIAAAABMAkABEwAAAACAgAAAAEwCQAETAAAAAICAAAAATAJAARMAAAAAgIAAAABMAUAAAADbmlsCQAEtQAAAAIJAQAAAAV2YWx1ZQAAAAEFAAAAGWN1cnJlbnRQb29sTGlxdWlkaXR5VmFsdWUFAAAAA1NFUAEAAAARZGF0YVBvb2xMaXF1aWRpdHkAAAADAAAAEWFtb3VudEFzc2V0TG9ja2VkAAAAEHByaWNlQXNzZXRMb2NrZWQAAAANbHBUb2tlbkxvY2tlZAkABLkAAAACCQAETAAAAAICAAAABiVkJWQlZAkABEwAAAACCQABpAAAAAEFAAAAEWFtb3VudEFzc2V0TG9ja2VkCQAETAAAAAIJAAGkAAAAAQUAAAAQcHJpY2VBc3NldExvY2tlZAkABEwAAAACCQABpAAAAAEFAAAADWxwVG9rZW5Mb2NrZWQFAAAAA25pbAUAAAADU0VQAQAAABdkYXRhUG9vbExpcXVpZGl0eUJ5VXNlcgAAAAQAAAARYW1vdW50QXNzZXRMb2NrZWQAAAAQcHJpY2VBc3NldExvY2tlZAAAAA1scFRva2VuTG9ja2VkAAAAC3VzZXJBZGRyZXNzCQAEuQAAAAIJAARMAAAAAgIAAAAGJWQlZCVkCQAETAAAAAIJAAGkAAAAAQUAAAARYW1vdW50QXNzZXRMb2NrZWQJAARMAAAAAgkAAaQAAAABBQAAABBwcmljZUFzc2V0TG9ja2VkCQAETAAAAAIJAAGkAAAAAQUAAAANbHBUb2tlbkxvY2tlZAUAAAADbmlsBQAAAANTRVABAAAAEWRhdGFQdXRBY3Rpb25JbmZvAAAACAAAABBpbkFtb3VudEFzc2V0QW10AAAAD2luUHJpY2VBc3NldEFtdAAAAAhvdXRMcEFtdAAAAAVwcmljZQAAAB1zbGlwcGFnZVRvbGVyYW5jZVBhc3NlZEJ5VXNlcgAAABVzbGlwcGFnZVRvbGVyYW5jZVJlYWwAAAAIdHhIZWlnaHQAAAALdHhUaW1lc3RhbXAJAAS5AAAAAgkABEwAAAACAgAAAA4lZCVkJWQlZCVkJWQlZAkABEwAAAACCQABpAAAAAEFAAAAEGluQW1vdW50QXNzZXRBbXQJAARMAAAAAgkAAaQAAAABBQAAAA9pblByaWNlQXNzZXRBbXQJAARMAAAAAgkAAaQAAAABBQAAAAhvdXRMcEFtdAkABEwAAAACCQABpAAAAAEFAAAABXByaWNlCQAETAAAAAIJAAGkAAAAAQUAAAAdc2xpcHBhZ2VUb2xlcmFuY2VQYXNzZWRCeVVzZXIJAARMAAAAAgkAAaQAAAABBQAAABVzbGlwcGFnZVRvbGVyYW5jZVJlYWwJAARMAAAAAgkAAaQAAAABBQAAAAh0eEhlaWdodAkABEwAAAACCQABpAAAAAEFAAAAC3R4VGltZXN0YW1wBQAAAANuaWwFAAAAA1NFUAEAAAARZGF0YUdldEFjdGlvbkluZm8AAAAGAAAAEW91dEFtb3VudEFzc2V0QW10AAAAEG91dFByaWNlQXNzZXRBbXQAAAAHaW5McEFtdAAAAAVwcmljZQAAAAh0eEhlaWdodAAAAAt0eFRpbWVzdGFtcAkABLkAAAACCQAETAAAAAICAAAADCVkJWQlZCVkJWQlZAkABEwAAAACCQABpAAAAAEFAAAAEW91dEFtb3VudEFzc2V0QW10CQAETAAAAAIJAAGkAAAAAQUAAAAQb3V0UHJpY2VBc3NldEFtdAkABEwAAAACCQABpAAAAAEFAAAAB2luTHBBbXQJAARMAAAAAgkAAaQAAAABBQAAAAVwcmljZQkABEwAAAACCQABpAAAAAEFAAAACHR4SGVpZ2h0CQAETAAAAAIJAAGkAAAAAQUAAAALdHhUaW1lc3RhbXAFAAAAA25pbAUAAAADU0VQAQAAAA1nZXRTY3JpcHRIYXNoAAAAAAkAAloAAAABCQEAAAAFdmFsdWUAAAABCQAD8QAAAAEFAAAABHRoaXMBAAAAHXByaXZhdGVDYXN0QXNzZXRUb01heERlY2ltYWxzAAAAAgAAAA1hc3NldERlY2ltYWxzAAAAC2Fzc2V0QW1vdW50BAAAAAxkZWNpbWFsc011bHQJAABsAAAABgAAAAAAAAAACgAAAAAAAAAAAAkAAGUAAAACBQAAAApsUGRlY2ltYWxzBQAAAA1hc3NldERlY2ltYWxzAAAAAAAAAAAAAAAAAAAAAAAABQAAAARET1dOCQAFFAAAAAIJAABoAAAAAgUAAAALYXNzZXRBbW91bnQFAAAADGRlY2ltYWxzTXVsdAUAAAAMZGVjaW1hbHNNdWx0AQAAACBwcml2YXRlQ2FzdEFzc2V0VG9PcmlnaW5EZWNpbWFscwAAAAIAAAANYXNzZXREZWNpbWFscwAAAAthc3NldEFtb3VudAQAAAAMZGVjaW1hbHNNdWx0CQAAbAAAAAYAAAAAAAAAAAoAAAAAAAAAAAAJAABlAAAAAgUAAAAKbFBkZWNpbWFscwUAAAANYXNzZXREZWNpbWFscwAAAAAAAAAAAAAAAAAAAAAAAAUAAAAERE9XTgkABRQAAAACCQAAaQAAAAIFAAAAC2Fzc2V0QW1vdW50BQAAAAxkZWNpbWFsc011bHQFAAAADGRlY2ltYWxzTXVsdAEAAAAVcHJpdmF0ZUNhbGN1bGF0ZVByaWNlAAAABAAAABJhbW91dEFzc2V0RGVjaW1hbHMAAAAScHJpY2VBc3NldERlY2ltYWxzAAAADmFtb3VudEFzc2V0QW10AAAADXByaWNlQXNzZXRBbXQEAAAAGGFtb3VudEFzc2V0UG9vbExvY2tlZEFtdAgJAQAAAB1wcml2YXRlQ2FzdEFzc2V0VG9NYXhEZWNpbWFscwAAAAIFAAAAEmFtb3V0QXNzZXREZWNpbWFscwUAAAAOYW1vdW50QXNzZXRBbXQAAAACXzEEAAAAF3ByaWNlQXNzZXRQb29sTG9ja2VkQW10CAkBAAAAHXByaXZhdGVDYXN0QXNzZXRUb01heERlY2ltYWxzAAAAAgUAAAAScHJpY2VBc3NldERlY2ltYWxzBQAAAA1wcmljZUFzc2V0QW10AAAAAl8xCQAAawAAAAMFAAAAF3ByaWNlQXNzZXRQb29sTG9ja2VkQW10BQAAABFkZWNpbWFsc011bHRQcmljZQUAAAAYYW1vdW50QXNzZXRQb29sTG9ja2VkQW10AQAAABtwcml2YXRlRXN0aW1hdGVHZXRPcGVyYXRpb24AAAADAAAAEHBheW1lbnRMcEFzc2V0SWQAAAAPcGF5bWVudExwQW1vdW50AAAAC3VzZXJBZGRyZXNzBAAAAA5wb29sQ29uZmlnTGlzdAkBAAAADWdldFBvb2xDb25maWcAAAAABAAAAAlscEFzc2V0SWQJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAAEGlkeFBvb2xMUEFzc2V0SWQEAAAADWFtb3VudEFzc2V0SWQJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAAEGlkeEFtb3VudEFzc2V0SWQEAAAADHByaWNlQXNzZXRJZAkAAZEAAAACBQAAAA5wb29sQ29uZmlnTGlzdAUAAAAPaWR4UHJpY2VBc3NldElkBAAAABVhbW91bnRBc3NldEludGVybmFsSWQJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAAGGlkeEFtb3VudEFzc2V0SW50ZXJuYWxJZAQAAAAUcHJpY2VBc3NldEludGVybmFsSWQJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAAF2lkeFByaWNlQXNzZXRJbnRlcm5hbElkBAAAABJhbW91dEFzc2V0RGVjaW1hbHMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA5wb29sQ29uZmlnTGlzdAUAAAAWaWR4QW1vdW50QXNzZXREZWNpbWFscwQAAAAScHJpY2VBc3NldERlY2ltYWxzCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAAFWlkeFByaWNlQXNzZXREZWNpbWFscwQAAAAKcG9vbFN0YXR1cwkAAZEAAAACBQAAAA5wb29sQ29uZmlnTGlzdAUAAAANaWR4UG9vbFN0YXR1cwQAAAARdXNlckxpcXVpZGl0eUxpc3QJAQAAABZnZXRQb29sTGlxdWlkaXR5QnlVc2VyAAAAAwUAAAAVYW1vdW50QXNzZXRJbnRlcm5hbElkBQAAABRwcmljZUFzc2V0SW50ZXJuYWxJZAUAAAALdXNlckFkZHJlc3MEAAAADXVzZXJMUEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABF1c2VyTGlxdWlkaXR5TGlzdAUAAAARaWR4UG9vbExQQXNzZXRBbXQEAAAAFnVzZXJBbW91bnRBc3NldEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABF1c2VyTGlxdWlkaXR5TGlzdAUAAAAVaWR4UG9vbEFtb3VudEFzc2V0QW10BAAAABV1c2VyUHJpY2VBc3NldEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABF1c2VyTGlxdWlkaXR5TGlzdAUAAAAUaWR4UG9vbFByaWNlQXNzZXRBbXQEAAAAEXBvb2xMaXF1aWRpdHlMaXN0CQEAAAAQZ2V0UG9vbExpcXVpZGl0eQAAAAIFAAAAFWFtb3VudEFzc2V0SW50ZXJuYWxJZAUAAAAUcHJpY2VBc3NldEludGVybmFsSWQEAAAADXBvb2xMUEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABFwb29sTGlxdWlkaXR5TGlzdAUAAAARaWR4UG9vbExQQXNzZXRBbXQEAAAAFnBvb2xBbW91bnRBc3NldEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABFwb29sTGlxdWlkaXR5TGlzdAUAAAAVaWR4UG9vbEFtb3VudEFzc2V0QW10BAAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABFwb29sTGlxdWlkaXR5TGlzdAUAAAAUaWR4UG9vbFByaWNlQXNzZXRBbXQDCQEAAAACIT0AAAACBQAAAAlscEFzc2V0SWQFAAAAEHBheW1lbnRMcEFzc2V0SWQJAAACAAAAAQIAAAAVSW52YWxpZCBhc3NldCBwYXNzZWQuAwkAAGYAAAACBQAAAA9wYXltZW50THBBbW91bnQFAAAADXVzZXJMUEJhbGFuY2UJAAACAAAAAQIAAAAySW52YWxpZCBhbW91bnQgcGFzc2VkLiBBbW91bnQgbGVzcyB0aGFuIGF2YWlsYWJsZS4EAAAAGGFtb3VudEFzc2V0UG9vbExvY2tlZEFtdAgJAQAAAB1wcml2YXRlQ2FzdEFzc2V0VG9NYXhEZWNpbWFscwAAAAIFAAAAEmFtb3V0QXNzZXREZWNpbWFscwUAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQAAAAJfMQQAAAAXcHJpY2VBc3NldFBvb2xMb2NrZWRBbXQICQEAAAAdcHJpdmF0ZUNhc3RBc3NldFRvTWF4RGVjaW1hbHMAAAACBQAAABJwcmljZUFzc2V0RGVjaW1hbHMFAAAAFXBvb2xQcmljZUFzc2V0QmFsYW5jZQAAAAJfMQQAAAARb3V0QW1vdW50QXNzZXRBbXQJAABrAAAAAwUAAAAYYW1vdW50QXNzZXRQb29sTG9ja2VkQW10BQAAAA9wYXltZW50THBBbW91bnQFAAAADXBvb2xMUEJhbGFuY2UEAAAAEG91dFByaWNlQXNzZXRBbXQJAABrAAAAAwUAAAAXcHJpY2VBc3NldFBvb2xMb2NrZWRBbXQFAAAAD3BheW1lbnRMcEFtb3VudAUAAAANcG9vbExQQmFsYW5jZQQAAAAWb3V0QW1vdW50QXNzZXRBbXRGaW5hbAgJAQAAACBwcml2YXRlQ2FzdEFzc2V0VG9PcmlnaW5EZWNpbWFscwAAAAIFAAAAEmFtb3V0QXNzZXREZWNpbWFscwUAAAARb3V0QW1vdW50QXNzZXRBbXQAAAACXzEEAAAAFW91dFByaWNlQXNzZXRBbXRGaW5hbAgJAQAAACBwcml2YXRlQ2FzdEFzc2V0VG9PcmlnaW5EZWNpbWFscwAAAAIFAAAAEnByaWNlQXNzZXREZWNpbWFscwUAAAAQb3V0UHJpY2VBc3NldEFtdAAAAAJfMQQAAAAMY3VycmVudFByaWNlCQAAawAAAAMFAAAAF3ByaWNlQXNzZXRQb29sTG9ja2VkQW10BQAAABFkZWNpbWFsc011bHRQcmljZQUAAAAYYW1vdW50QXNzZXRQb29sTG9ja2VkQW10CQAFIAAAAA4FAAAAFm91dEFtb3VudEFzc2V0QW10RmluYWwFAAAAFW91dFByaWNlQXNzZXRBbXRGaW5hbAUAAAAVYW1vdW50QXNzZXRJbnRlcm5hbElkBQAAABRwcmljZUFzc2V0SW50ZXJuYWxJZAUAAAAWdXNlckFtb3VudEFzc2V0QmFsYW5jZQUAAAANYW1vdW50QXNzZXRJZAUAAAAVdXNlclByaWNlQXNzZXRCYWxhbmNlBQAAAAxwcmljZUFzc2V0SWQFAAAADXVzZXJMUEJhbGFuY2UFAAAAFnBvb2xBbW91bnRBc3NldEJhbGFuY2UFAAAAFXBvb2xQcmljZUFzc2V0QmFsYW5jZQUAAAANcG9vbExQQmFsYW5jZQUAAAAMY3VycmVudFByaWNlBQAAAApwb29sU3RhdHVzAQAAABtwcml2YXRlRXN0aW1hdGVQdXRPcGVyYXRpb24AAAAGAAAAEXNsaXBwYWdlVG9sZXJhbmNlAAAAEGluQW1vdW50QXNzZXRBbXQAAAAPaW5BbW91bnRBc3NldElkAAAAD2luUHJpY2VBc3NldEFtdAAAAA5pblByaWNlQXNzZXRJZAAAAAt1c2VyQWRkcmVzcwQAAAAScG9vbENvbmZpZ0RhdGFMaXN0CQEAAAANZ2V0UG9vbENvbmZpZwAAAAAEAAAACWxwQXNzZXRJZAkAAlkAAAABCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAQaWR4UG9vbExQQXNzZXRJZAQAAAANYW1vdW50QXNzZXRJZAkAAZEAAAACBQAAABJwb29sQ29uZmlnRGF0YUxpc3QFAAAAEGlkeEFtb3VudEFzc2V0SWQEAAAADHByaWNlQXNzZXRJZAkAAZEAAAACBQAAABJwb29sQ29uZmlnRGF0YUxpc3QFAAAAD2lkeFByaWNlQXNzZXRJZAQAAAAVYW1vdW50QXNzZXRJbnRlcm5hbElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAYaWR4QW1vdW50QXNzZXRJbnRlcm5hbElkBAAAABRwcmljZUFzc2V0SW50ZXJuYWxJZAkAAZEAAAACBQAAABJwb29sQ29uZmlnRGF0YUxpc3QFAAAAF2lkeFByaWNlQXNzZXRJbnRlcm5hbElkBAAAABJhbW91dEFzc2V0RGVjaW1hbHMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABJwb29sQ29uZmlnRGF0YUxpc3QFAAAAFmlkeEFtb3VudEFzc2V0RGVjaW1hbHMEAAAAEnByaWNlQXNzZXREZWNpbWFscwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAVaWR4UHJpY2VBc3NldERlY2ltYWxzBAAAAApwb29sU3RhdHVzCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAANaWR4UG9vbFN0YXR1cwQAAAAVcG9vbExpcXVpZGl0eURhdGFMaXN0CQEAAAAQZ2V0UG9vbExpcXVpZGl0eQAAAAIFAAAAFWFtb3VudEFzc2V0SW50ZXJuYWxJZAUAAAAUcHJpY2VBc3NldEludGVybmFsSWQEAAAAFnBvb2xBbW91bnRBc3NldEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABVwb29sTGlxdWlkaXR5RGF0YUxpc3QFAAAAFWlkeFBvb2xBbW91bnRBc3NldEFtdAQAAAAVcG9vbFByaWNlQXNzZXRCYWxhbmNlCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAVcG9vbExpcXVpZGl0eURhdGFMaXN0BQAAABRpZHhQb29sUHJpY2VBc3NldEFtdAQAAAANcG9vbExQQmFsYW5jZQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAFXBvb2xMaXF1aWRpdHlEYXRhTGlzdAUAAAARaWR4UG9vbExQQXNzZXRBbXQEAAAAFXVzZXJMaXF1aWRpdHlEYXRhTGlzdAkBAAAAFmdldFBvb2xMaXF1aWRpdHlCeVVzZXIAAAADBQAAABVhbW91bnRBc3NldEludGVybmFsSWQFAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkBQAAAAt1c2VyQWRkcmVzcwQAAAAWdXNlckFtb3VudEFzc2V0QmFsYW5jZQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAFXVzZXJMaXF1aWRpdHlEYXRhTGlzdAUAAAAVaWR4UG9vbEFtb3VudEFzc2V0QW10BAAAABV1c2VyUHJpY2VBc3NldEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABV1c2VyTGlxdWlkaXR5RGF0YUxpc3QFAAAAFGlkeFBvb2xQcmljZUFzc2V0QW10BAAAAA11c2VyTFBCYWxhbmNlCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAVdXNlckxpcXVpZGl0eURhdGFMaXN0BQAAABFpZHhQb29sTFBBc3NldEFtdAMDCQEAAAACIT0AAAACBQAAAA1hbW91bnRBc3NldElkBQAAAA9pbkFtb3VudEFzc2V0SWQGCQEAAAACIT0AAAACBQAAAAxwcmljZUFzc2V0SWQFAAAADmluUHJpY2VBc3NldElkCQAAAgAAAAECAAAAJUludmFsaWQgYW1vdW50IG9yIHByaWNlIGFzc2V0IHBhc3NlZC4EAAAAH2luQW1vdW50QXNzZXRBbXRDYWxjdWxhdGVkVHVwbGUJAQAAAB1wcml2YXRlQ2FzdEFzc2V0VG9NYXhEZWNpbWFscwAAAAIFAAAAEmFtb3V0QXNzZXREZWNpbWFscwUAAAAQaW5BbW91bnRBc3NldEFtdAQAAAAeaW5QcmljZUFzc2V0QW10Q2FsY3VsYXRlZFR1cGxlCQEAAAAdcHJpdmF0ZUNhc3RBc3NldFRvTWF4RGVjaW1hbHMAAAACBQAAABJwcmljZUFzc2V0RGVjaW1hbHMFAAAAD2luUHJpY2VBc3NldEFtdAQAAAAaaW5BbW91bnRBc3NldEFtdENhbGN1bGF0ZWQIBQAAAB9pbkFtb3VudEFzc2V0QW10Q2FsY3VsYXRlZFR1cGxlAAAAAl8xBAAAABlpblByaWNlQXNzZXRBbXRDYWxjdWxhdGVkCAUAAAAeaW5QcmljZUFzc2V0QW10Q2FsY3VsYXRlZFR1cGxlAAAAAl8xBAAAAAl1c2VyUHJpY2UJAABrAAAAAwUAAAAZaW5QcmljZUFzc2V0QW10Q2FsY3VsYXRlZAUAAAARZGVjaW1hbHNNdWx0UHJpY2UFAAAAGmluQW1vdW50QXNzZXRBbXRDYWxjdWxhdGVkBAAAABhhbW91bnRBc3NldFBvb2xMb2NrZWRBbXQJAABoAAAAAgUAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQgFAAAAH2luQW1vdW50QXNzZXRBbXRDYWxjdWxhdGVkVHVwbGUAAAACXzIEAAAAF3ByaWNlQXNzZXRQb29sTG9ja2VkQW10CQAAaAAAAAIFAAAAFXBvb2xQcmljZUFzc2V0QmFsYW5jZQgFAAAAHmluUHJpY2VBc3NldEFtdENhbGN1bGF0ZWRUdXBsZQAAAAJfMgQAAAALY3VyZW50UHJpY2UDCQAAAAAAAAIFAAAADXBvb2xMUEJhbGFuY2UAAAAAAAAAAAAAAAAAAAAAAAAJAABrAAAAAwUAAAAXcHJpY2VBc3NldFBvb2xMb2NrZWRBbXQFAAAAEWRlY2ltYWxzTXVsdFByaWNlBQAAABhhbW91bnRBc3NldFBvb2xMb2NrZWRBbXQEAAAACHNsaXBwYWdlAwkAAAAAAAACBQAAAAtjdXJlbnRQcmljZQAAAAAAAAAAAAAAAAAAAAAAAAMJAABmAAAAAgUAAAALY3VyZW50UHJpY2UFAAAACXVzZXJQcmljZQkAAGsAAAADCQAAZQAAAAIFAAAAC2N1cmVudFByaWNlBQAAAAl1c2VyUHJpY2UAAAAAAAAAAGQFAAAAC2N1cmVudFByaWNlCQAAawAAAAMJAABlAAAAAgUAAAAJdXNlclByaWNlBQAAAAtjdXJlbnRQcmljZQAAAAAAAAAAZAUAAAALY3VyZW50UHJpY2UDAwkBAAAAAiE9AAAAAgUAAAALY3VyZW50UHJpY2UAAAAAAAAAAAAJAABmAAAAAgkAAGgAAAACBQAAAAhzbGlwcGFnZQUAAAARZGVjaW1hbHNNdWx0UHJpY2UFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBwkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAA9QcmljZSBzbGlwcGFnZSAJAAGkAAAAAQkAAGgAAAACBQAAAAhzbGlwcGFnZQUAAAARZGVjaW1hbHNNdWx0UHJpY2UCAAAAHiBleGNlZWRlZCB0aGUgcGFzc2VkIGxpbWl0IG9mIAkAAaQAAAABBQAAABFzbGlwcGFnZVRvbGVyYW5jZQQAAAAKZmluYWxQcmljZQkAAGsAAAADCQAAZAAAAAIFAAAAF3ByaWNlQXNzZXRQb29sTG9ja2VkQW10BQAAABlpblByaWNlQXNzZXRBbXRDYWxjdWxhdGVkBQAAABFkZWNpbWFsc011bHRQcmljZQkAAGQAAAACBQAAABhhbW91bnRBc3NldFBvb2xMb2NrZWRBbXQFAAAAGmluQW1vdW50QXNzZXRBbXRDYWxjdWxhdGVkBAAAAAtvdXRMcEFtb3VudAMJAAAAAAAAAgUAAAANcG9vbExQQmFsYW5jZQAAAAAAAAAAAAQAAAAFcGFydEEJAABsAAAABgUAAAAaaW5BbW91bnRBc3NldEFtdENhbGN1bGF0ZWQAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAEAAAAAAAAAAAAFAAAABERPV04EAAAABXBhcnRCCQAAbAAAAAYFAAAAGWluUHJpY2VBc3NldEFtdENhbGN1bGF0ZWQAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAEAAAAAAAAAAAAFAAAABERPV04JAABoAAAAAgUAAAAFcGFydEEFAAAABXBhcnRCBAAAABJscEFtdEJ5QW1vdW50QXNzZXQJAABrAAAAAwUAAAANcG9vbExQQmFsYW5jZQUAAAAaaW5BbW91bnRBc3NldEFtdENhbGN1bGF0ZWQFAAAAGGFtb3VudEFzc2V0UG9vbExvY2tlZEFtdAQAAAARbHBBbXRCeVByaWNlQXNzZXQJAABrAAAAAwUAAAANcG9vbExQQmFsYW5jZQUAAAAZaW5QcmljZUFzc2V0QW10Q2FsY3VsYXRlZAUAAAAXcHJpY2VBc3NldFBvb2xMb2NrZWRBbXQDCQAAZgAAAAIFAAAAEWxwQW10QnlQcmljZUFzc2V0BQAAABJscEFtdEJ5QW1vdW50QXNzZXQFAAAAEmxwQW10QnlBbW91bnRBc3NldAUAAAARbHBBbXRCeVByaWNlQXNzZXQJAAUfAAAADQUAAAALb3V0THBBbW91bnQFAAAACmZpbmFsUHJpY2UFAAAAFnVzZXJBbW91bnRBc3NldEJhbGFuY2UFAAAAFXVzZXJQcmljZUFzc2V0QmFsYW5jZQUAAAANdXNlckxQQmFsYW5jZQUAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQUAAAAVcG9vbFByaWNlQXNzZXRCYWxhbmNlBQAAAA1wb29sTFBCYWxhbmNlBQAAABVhbW91bnRBc3NldEludGVybmFsSWQFAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkBQAAAAlscEFzc2V0SWQFAAAACHNsaXBwYWdlBQAAAApwb29sU3RhdHVzAQAAABx2YWxpZGF0ZU1hdGNoZXJPcmRlckFsbG93ZWQyAAAAAAQAAAAJb3JkZXJUeXBlAgAAAANCVVkEAAAAC29yZGVyQW1vdW50AAAAAAA7msoABAAAAAtvcmRlclByaWNjZQAAAAAAAWOHoAQAAAAScG9vbENvbmZpZ0RhdGFMaXN0CQEAAAANZ2V0UG9vbENvbmZpZwAAAAAEAAAADWFtb3VudEFzc2V0SWQJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABBpZHhBbW91bnRBc3NldElkBAAAAAxwcmljZUFzc2V0SWQJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAAA9pZHhQcmljZUFzc2V0SWQEAAAACnBvb2xTdGF0dXMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABJwb29sQ29uZmlnRGF0YUxpc3QFAAAADWlkeFBvb2xTdGF0dXMEAAAAE21hdGNoZXJQdWJsaWNLZXlTdHIJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABNpZHhNYXRjaGVyUHVibGljS2V5BAAAABVhbW91bnRBc3NldEludGVybmFsSWQJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABhpZHhBbW91bnRBc3NldEludGVybmFsSWQEAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAXaWR4UHJpY2VBc3NldEludGVybmFsSWQEAAAAE2Ftb3VudEFzc2V0RGVjaW1hbHMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABJwb29sQ29uZmlnRGF0YUxpc3QFAAAAFmlkeEFtb3VudEFzc2V0RGVjaW1hbHMEAAAAEnByaWNlQXNzZXREZWNpbWFscwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAVaWR4UHJpY2VBc3NldERlY2ltYWxzBAAAACFtYXhBbGxvd2VkT3JkZXJQcmljZURpZmZlcmVuY2VQY3QJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABJwb29sQ29uZmlnRGF0YUxpc3QFAAAAI2lkbWF4QWxsb3dlZE9yZGVyUHJpY2VEaWZmZXJlbmNlUGN0BAAAABVwb29sTGlxdWlkaXR5RGF0YUxpc3QJAQAAABBnZXRQb29sTGlxdWlkaXR5AAAAAgUAAAAVYW1vdW50QXNzZXRJbnRlcm5hbElkBQAAABRwcmljZUFzc2V0SW50ZXJuYWxJZAQAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAFXBvb2xMaXF1aWRpdHlEYXRhTGlzdAUAAAAVaWR4UG9vbEFtb3VudEFzc2V0QW10BAAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABVwb29sTGlxdWlkaXR5RGF0YUxpc3QFAAAAFGlkeFBvb2xQcmljZUFzc2V0QW10BAAAAAxjdXJyZW50UHJpY2UDCQAAAAAAAAIFAAAACW9yZGVyVHlwZQIAAAADQlVZCQEAAAAVcHJpdmF0ZUNhbGN1bGF0ZVByaWNlAAAABAUAAAATYW1vdW50QXNzZXREZWNpbWFscwUAAAAScHJpY2VBc3NldERlY2ltYWxzCQAAZAAAAAIFAAAAFnBvb2xBbW91bnRBc3NldEJhbGFuY2UFAAAAC29yZGVyQW1vdW50BQAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UJAQAAABVwcml2YXRlQ2FsY3VsYXRlUHJpY2UAAAAEBQAAABNhbW91bnRBc3NldERlY2ltYWxzBQAAABJwcmljZUFzc2V0RGVjaW1hbHMJAABkAAAAAgUAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQUAAAALb3JkZXJBbW91bnQFAAAAFXBvb2xQcmljZUFzc2V0QmFsYW5jZQQAAAARaXNQb29sU3RhdHVzVmFsaWQDAwMJAQAAABBpc0dsb2JhbFNodXRkb3duAAAAAAYJAAAAAAAAAgUAAAAKcG9vbFN0YXR1cwUAAAATUG9vbE1hdGNoZXJEaXNhYmxlZAYJAAAAAAAAAgUAAAAKcG9vbFN0YXR1cwUAAAAMUG9vbFNodXRkb3duBwYEAAAAEmlzVmFsaWRNYXRjaGVyU2lnbgYEAAAAEGlzVmFsaWRBc3NldFBhaXIGBAAAAApvcmRlclByaWNlBQAAAAtvcmRlclByaWNjZQQAAAANcHJpY2VEZWNpbWFscwkAAGUAAAACCQAAZAAAAAIAAAAAAAAAAAgFAAAAEnByaWNlQXNzZXREZWNpbWFscwUAAAATYW1vdW50QXNzZXREZWNpbWFscwQAAAAQY2FzdGVkT3JkZXJQcmljZQgJAQAAAB1wcml2YXRlQ2FzdEFzc2V0VG9NYXhEZWNpbWFscwAAAAIFAAAADXByaWNlRGVjaW1hbHMFAAAACm9yZGVyUHJpY2UAAAACXzEEAAAAEWlzT3JkZXJQcmljZVZhbGlkAwkAAAAAAAACBQAAAAlvcmRlclR5cGUCAAAAA0JVWQkAAGcAAAACBQAAAAxjdXJyZW50UHJpY2UFAAAAEGNhc3RlZE9yZGVyUHJpY2UJAABnAAAAAgUAAAAQY2FzdGVkT3JkZXJQcmljZQUAAAAMY3VycmVudFByaWNlAwYJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAC29yZGVyUHJpY2U9CQABpAAAAAEFAAAACm9yZGVyUHJpY2UCAAAAEiBjYXN0ZWRPcmRlclByaWNlPQkAAaQAAAABBQAAABBjYXN0ZWRPcmRlclByaWNlAgAAAA4gY3VycmVudFByaWNlPQkAAaQAAAABBQAAAAxjdXJyZW50UHJpY2UJAARMAAAAAgMDAwUAAAAQaXNWYWxpZEFzc2V0UGFpcgUAAAASaXNWYWxpZE1hdGNoZXJTaWduBwUAAAARaXNQb29sU3RhdHVzVmFsaWQHBQAAABFpc09yZGVyUHJpY2VWYWxpZAcFAAAAA25pbAEAAAAbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkAAAAAQAAAAVvcmRlcgQAAAAScG9vbENvbmZpZ0RhdGFMaXN0CQEAAAANZ2V0UG9vbENvbmZpZwAAAAAEAAAADWFtb3VudEFzc2V0SWQJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABBpZHhBbW91bnRBc3NldElkBAAAAAxwcmljZUFzc2V0SWQJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAAA9pZHhQcmljZUFzc2V0SWQEAAAACnBvb2xTdGF0dXMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABJwb29sQ29uZmlnRGF0YUxpc3QFAAAADWlkeFBvb2xTdGF0dXMEAAAAE21hdGNoZXJQdWJsaWNLZXlTdHIJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABNpZHhNYXRjaGVyUHVibGljS2V5BAAAABVhbW91bnRBc3NldEludGVybmFsSWQJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABhpZHhBbW91bnRBc3NldEludGVybmFsSWQEAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAXaWR4UHJpY2VBc3NldEludGVybmFsSWQEAAAAE2Ftb3VudEFzc2V0RGVjaW1hbHMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABJwb29sQ29uZmlnRGF0YUxpc3QFAAAAFmlkeEFtb3VudEFzc2V0RGVjaW1hbHMEAAAAEnByaWNlQXNzZXREZWNpbWFscwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAVaWR4UHJpY2VBc3NldERlY2ltYWxzBAAAACFtYXhBbGxvd2VkT3JkZXJQcmljZURpZmZlcmVuY2VQY3QJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABJwb29sQ29uZmlnRGF0YUxpc3QFAAAAI2lkbWF4QWxsb3dlZE9yZGVyUHJpY2VEaWZmZXJlbmNlUGN0BAAAABVwb29sTGlxdWlkaXR5RGF0YUxpc3QJAQAAABBnZXRQb29sTGlxdWlkaXR5AAAAAgUAAAAVYW1vdW50QXNzZXRJbnRlcm5hbElkBQAAABRwcmljZUFzc2V0SW50ZXJuYWxJZAQAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAFXBvb2xMaXF1aWRpdHlEYXRhTGlzdAUAAAAVaWR4UG9vbEFtb3VudEFzc2V0QW10BAAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABVwb29sTGlxdWlkaXR5RGF0YUxpc3QFAAAAFGlkeFBvb2xQcmljZUFzc2V0QW10BAAAAAxjdXJyZW50UHJpY2UDCQAAAAAAAAIIBQAAAAVvcmRlcgAAAAlvcmRlclR5cGUFAAAAA0J1eQkBAAAAFXByaXZhdGVDYWxjdWxhdGVQcmljZQAAAAQFAAAAE2Ftb3VudEFzc2V0RGVjaW1hbHMFAAAAEnByaWNlQXNzZXREZWNpbWFscwkAAGQAAAACBQAAABZwb29sQW1vdW50QXNzZXRCYWxhbmNlCAUAAAAFb3JkZXIAAAAGYW1vdW50BQAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UJAQAAABVwcml2YXRlQ2FsY3VsYXRlUHJpY2UAAAAEBQAAABNhbW91bnRBc3NldERlY2ltYWxzBQAAABJwcmljZUFzc2V0RGVjaW1hbHMJAABkAAAAAgUAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQgFAAAABW9yZGVyAAAABmFtb3VudAUAAAAVcG9vbFByaWNlQXNzZXRCYWxhbmNlBAAAABFpc1Bvb2xTdGF0dXNWYWxpZAMDAwkBAAAAEGlzR2xvYmFsU2h1dGRvd24AAAAABgkAAAAAAAACBQAAAApwb29sU3RhdHVzBQAAABNQb29sTWF0Y2hlckRpc2FibGVkBgkAAAAAAAACBQAAAApwb29sU3RhdHVzBQAAAAxQb29sU2h1dGRvd24HBgQAAAASaXNWYWxpZE1hdGNoZXJTaWduBgQAAAAQb3JkZXJBbW91bnRBc3NldAgIBQAAAAVvcmRlcgAAAAlhc3NldFBhaXIAAAALYW1vdW50QXNzZXQEAAAAE29yZGVyQW1vdW50QXNzZXRTdHIDCQAAAAAAAAIFAAAAEG9yZGVyQW1vdW50QXNzZXQFAAAABHVuaXQCAAAAAAkAAlgAAAABCQEAAAAFdmFsdWUAAAABBQAAABBvcmRlckFtb3VudEFzc2V0BAAAAA9vcmRlclByaWNlQXNzZXQICAUAAAAFb3JkZXIAAAAJYXNzZXRQYWlyAAAACnByaWNlQXNzZXQEAAAAEm9yZGVyUHJpY2VBc3NldFN0cgMJAAAAAAAAAgUAAAAPb3JkZXJQcmljZUFzc2V0BQAAAAR1bml0AgAAAAAJAAJYAAAAAQkBAAAABXZhbHVlAAAAAQUAAAAPb3JkZXJQcmljZUFzc2V0BAAAABBpc1ZhbGlkQXNzZXRQYWlyAwMJAQAAAAIhPQAAAAIFAAAAE29yZGVyQW1vdW50QXNzZXRTdHIFAAAADWFtb3VudEFzc2V0SWQGCQEAAAACIT0AAAACBQAAABJvcmRlclByaWNlQXNzZXRTdHIFAAAADHByaWNlQXNzZXRJZAcGBAAAAApvcmRlclByaWNlCAUAAAAFb3JkZXIAAAAFcHJpY2UEAAAADXByaWNlRGVjaW1hbHMJAABlAAAAAgkAAGQAAAACAAAAAAAAAAAIBQAAABJwcmljZUFzc2V0RGVjaW1hbHMFAAAAE2Ftb3VudEFzc2V0RGVjaW1hbHMEAAAAEGNhc3RlZE9yZGVyUHJpY2UICQEAAAAdcHJpdmF0ZUNhc3RBc3NldFRvTWF4RGVjaW1hbHMAAAACBQAAAA1wcmljZURlY2ltYWxzBQAAAApvcmRlclByaWNlAAAAAl8xBAAAABFpc09yZGVyUHJpY2VWYWxpZAMJAAAAAAAAAggFAAAABW9yZGVyAAAACW9yZGVyVHlwZQUAAAADQnV5CQAAZwAAAAIFAAAADGN1cnJlbnRQcmljZQUAAAAQY2FzdGVkT3JkZXJQcmljZQkAAGcAAAACBQAAABBjYXN0ZWRPcmRlclByaWNlBQAAAAxjdXJyZW50UHJpY2UDBgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAALb3JkZXJQcmljZT0JAAGkAAAAAQUAAAAKb3JkZXJQcmljZQIAAAASIGNhc3RlZE9yZGVyUHJpY2U9CQABpAAAAAEFAAAAEGNhc3RlZE9yZGVyUHJpY2UCAAAADiBjdXJyZW50UHJpY2U9CQABpAAAAAEFAAAADGN1cnJlbnRQcmljZQkABEwAAAACAwMDBQAAABBpc1ZhbGlkQXNzZXRQYWlyBQAAABJpc1ZhbGlkTWF0Y2hlclNpZ24HBQAAABFpc1Bvb2xTdGF0dXNWYWxpZAcFAAAAEWlzT3JkZXJQcmljZVZhbGlkBwUAAAADbmlsAAAABgAAAAFpAQAAAANwdXQAAAABAAAAEXNsaXBwYWdlVG9sZXJhbmNlBAAAAA5wbXRBbW91bnRBc3NldAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAQAAAAQaW5BbW91bnRBc3NldEFtdAgFAAAADnBtdEFtb3VudEFzc2V0AAAABmFtb3VudAQAAAAPaW5BbW91bnRBc3NldElkAwkBAAAAASEAAAABCQEAAAAJaXNEZWZpbmVkAAAAAQgFAAAADnBtdEFtb3VudEFzc2V0AAAAB2Fzc2V0SWQJAAJZAAAAAQIAAAAACQEAAAAFdmFsdWUAAAABCAUAAAAOcG10QW1vdW50QXNzZXQAAAAHYXNzZXRJZAQAAAANcG10UHJpY2VBc3NldAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAQQAAAAPaW5QcmljZUFzc2V0QW10CAUAAAANcG10UHJpY2VBc3NldAAAAAZhbW91bnQEAAAADmluUHJpY2VBc3NldElkCQEAAAAFdmFsdWUAAAABCAUAAAANcG10UHJpY2VBc3NldAAAAAdhc3NldElkBAAAABNlc3RpbWF0ZWRQdXRSZXN1bHRzCQEAAAAbcHJpdmF0ZUVzdGltYXRlUHV0T3BlcmF0aW9uAAAABgUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAAEGluQW1vdW50QXNzZXRBbXQJAAJYAAAAAQUAAAAPaW5BbW91bnRBc3NldElkBQAAAA9pblByaWNlQXNzZXRBbXQJAAJYAAAAAQUAAAAOaW5QcmljZUFzc2V0SWQJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAAtvdXRMcEFtb3VudAgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAACXzEEAAAAC2N1cmVudFByaWNlCAUAAAATZXN0aW1hdGVkUHV0UmVzdWx0cwAAAAJfMgQAAAAWdXNlckFtb3VudEFzc2V0QmFsYW5jZQgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAACXzMEAAAAFXVzZXJQcmljZUFzc2V0QmFsYW5jZQgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAACXzQEAAAADXVzZXJMUEJhbGFuY2UIBQAAABNlc3RpbWF0ZWRQdXRSZXN1bHRzAAAAAl81BAAAABZwb29sQW1vdW50QXNzZXRCYWxhbmNlCAUAAAATZXN0aW1hdGVkUHV0UmVzdWx0cwAAAAJfNgQAAAAVcG9vbFByaWNlQXNzZXRCYWxhbmNlCAUAAAATZXN0aW1hdGVkUHV0UmVzdWx0cwAAAAJfNwQAAAANcG9vbExQQmFsYW5jZQgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAACXzgEAAAAFWFtb3VudEFzc2V0SW50ZXJuYWxJZAgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAACXzkEAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkCAUAAAATZXN0aW1hdGVkUHV0UmVzdWx0cwAAAANfMTAEAAAACWxwQXNzZXRJZAgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAADXzExBAAAABJzbGlwcGFnZUNhbGN1bGF0ZWQIBQAAABNlc3RpbWF0ZWRQdXRSZXN1bHRzAAAAA18xMgQAAAAKcG9vbFN0YXR1cwkBAAAADXBhcnNlSW50VmFsdWUAAAABCAUAAAATZXN0aW1hdGVkUHV0UmVzdWx0cwAAAANfMTMDAwMJAQAAABBpc0dsb2JhbFNodXRkb3duAAAAAAYJAAAAAAAAAgUAAAAKcG9vbFN0YXR1cwUAAAAPUG9vbFB1dERpc2FibGVkBgkAAAAAAAACBQAAAApwb29sU3RhdHVzBQAAAAxQb29sU2h1dGRvd24JAAACAAAAAQkAASwAAAACAgAAACxQdXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4uIFN0YXR1cyA9IAkAAaQAAAABBQAAAApwb29sU3RhdHVzCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAAxrZXlQcmljZUxhc3QAAAAACQABLAAAAAICAAAABCVzX18JAAGkAAAAAQUAAAALY3VyZW50UHJpY2UJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAD2tleVByaWNlSGlzdG9yeQAAAAIFAAAABmhlaWdodAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAJAAEsAAAAAgIAAAAEJXNfXwkAAaQAAAABBQAAAAtjdXJlbnRQcmljZQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5UHV0QWN0aW9uQnlVc2VyAAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAkBAAAAEWRhdGFQdXRBY3Rpb25JbmZvAAAACAUAAAAQaW5BbW91bnRBc3NldEFtdAUAAAAPaW5QcmljZUFzc2V0QW10BQAAAAtvdXRMcEFtb3VudAUAAAALY3VyZW50UHJpY2UFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBQAAABJzbGlwcGFnZUNhbGN1bGF0ZWQFAAAABmhlaWdodAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAFmtleVBvb2xMaXF1aWRpdHlCeVVzZXIAAAADBQAAABVhbW91bnRBc3NldEludGVybmFsSWQFAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgkBAAAAEWRhdGFQb29sTGlxdWlkaXR5AAAAAwkAAGQAAAACBQAAABZ1c2VyQW1vdW50QXNzZXRCYWxhbmNlBQAAABBpbkFtb3VudEFzc2V0QW10CQAAZAAAAAIFAAAAFXVzZXJQcmljZUFzc2V0QmFsYW5jZQUAAAAPaW5QcmljZUFzc2V0QW10CQAAZAAAAAIFAAAADXVzZXJMUEJhbGFuY2UFAAAAC291dExwQW1vdW50CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABBrZXlQb29sTGlxdWlkaXR5AAAAAgUAAAAVYW1vdW50QXNzZXRJbnRlcm5hbElkBQAAABRwcmljZUFzc2V0SW50ZXJuYWxJZAkBAAAAEWRhdGFQb29sTGlxdWlkaXR5AAAAAwkAAGQAAAACBQAAABZwb29sQW1vdW50QXNzZXRCYWxhbmNlBQAAABBpbkFtb3VudEFzc2V0QW10CQAAZAAAAAIFAAAAFXBvb2xQcmljZUFzc2V0QmFsYW5jZQUAAAAPaW5QcmljZUFzc2V0QW10CQAAZAAAAAIFAAAADXBvb2xMUEJhbGFuY2UFAAAAC291dExwQW1vdW50CQAETAAAAAIJAQAAAAdSZWlzc3VlAAAAAwUAAAAJbHBBc3NldElkBQAAAAtvdXRMcEFtb3VudAYJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAtvdXRMcEFtb3VudAUAAAAJbHBBc3NldElkBQAAAANuaWwAAAABaQEAAAADZ2V0AAAAAAQAAAAOcG10QW1vdW50QXNzZXQJAQAAAAV2YWx1ZQAAAAEJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAEAAAACnBtdEFzc2V0SWQJAQAAAAV2YWx1ZQAAAAEIBQAAAA5wbXRBbW91bnRBc3NldAAAAAdhc3NldElkBAAAAA5wbXRBc3NldEFtb3VudAgFAAAADnBtdEFtb3VudEFzc2V0AAAABmFtb3VudAQAAAAHcmVzdWx0cwkBAAAAG3ByaXZhdGVFc3RpbWF0ZUdldE9wZXJhdGlvbgAAAAMJAAJYAAAAAQUAAAAKcG10QXNzZXRJZAUAAAAOcG10QXNzZXRBbW91bnQJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAABFvdXRBbW91bnRBc3NldEFtdAgFAAAAB3Jlc3VsdHMAAAACXzEEAAAAEG91dFByaWNlQXNzZXRBbXQIBQAAAAdyZXN1bHRzAAAAAl8yBAAAABVhbW91bnRBc3NldEludGVybmFsSWQIBQAAAAdyZXN1bHRzAAAAAl8zBAAAABRwcmljZUFzc2V0SW50ZXJuYWxJZAgFAAAAB3Jlc3VsdHMAAAACXzQEAAAAFnVzZXJBbW91bnRBc3NldEJhbGFuY2UIBQAAAAdyZXN1bHRzAAAAAl81BAAAAA1hbW91bnRBc3NldElkCAUAAAAHcmVzdWx0cwAAAAJfNgQAAAAVdXNlclByaWNlQXNzZXRCYWxhbmNlCAUAAAAHcmVzdWx0cwAAAAJfNwQAAAAMcHJpY2VBc3NldElkCAUAAAAHcmVzdWx0cwAAAAJfOAQAAAANdXNlckxQQmFsYW5jZQgFAAAAB3Jlc3VsdHMAAAACXzkEAAAAFnBvb2xBbW91bnRBc3NldEJhbGFuY2UIBQAAAAdyZXN1bHRzAAAAA18xMAQAAAAVcG9vbFByaWNlQXNzZXRCYWxhbmNlCAUAAAAHcmVzdWx0cwAAAANfMTEEAAAADXBvb2xMUEJhbGFuY2UIBQAAAAdyZXN1bHRzAAAAA18xMgQAAAAMY3VycmVudFByaWNlCAUAAAAHcmVzdWx0cwAAAANfMTMEAAAACnBvb2xTdGF0dXMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQgFAAAAB3Jlc3VsdHMAAAADXzE0AwMJAQAAABBpc0dsb2JhbFNodXRkb3duAAAAAAYJAAAAAAAAAgUAAAAKcG9vbFN0YXR1cwUAAAAMUG9vbFNodXRkb3duCQAAAgAAAAEJAAEsAAAAAgIAAAAsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAAGkAAAAAQUAAAAKcG9vbFN0YXR1cwkABEwAAAACCQEAAAAEQnVybgAAAAIFAAAACnBtdEFzc2V0SWQFAAAADnBtdEFzc2V0QW1vdW50CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAARb3V0QW1vdW50QXNzZXRBbXQDCQAAAAAAAAIFAAAADWFtb3VudEFzc2V0SWQCAAAAAAUAAAAEdW5pdAkAAlkAAAABBQAAAA1hbW91bnRBc3NldElkCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAQb3V0UHJpY2VBc3NldEFtdAkAAlkAAAABBQAAAAxwcmljZUFzc2V0SWQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAFmtleVBvb2xMaXF1aWRpdHlCeVVzZXIAAAADBQAAABVhbW91bnRBc3NldEludGVybmFsSWQFAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgkBAAAAEWRhdGFQb29sTGlxdWlkaXR5AAAAAwkAAGUAAAACBQAAABZ1c2VyQW1vdW50QXNzZXRCYWxhbmNlBQAAABFvdXRBbW91bnRBc3NldEFtdAkAAGUAAAACBQAAABV1c2VyUHJpY2VBc3NldEJhbGFuY2UFAAAAEG91dFByaWNlQXNzZXRBbXQJAABlAAAAAgUAAAANdXNlckxQQmFsYW5jZQUAAAAOcG10QXNzZXRBbW91bnQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAEGtleVBvb2xMaXF1aWRpdHkAAAACBQAAABVhbW91bnRBc3NldEludGVybmFsSWQFAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkCQEAAAARZGF0YVBvb2xMaXF1aWRpdHkAAAADCQAAZQAAAAIFAAAAFnBvb2xBbW91bnRBc3NldEJhbGFuY2UFAAAAEW91dEFtb3VudEFzc2V0QW10CQAAZQAAAAIFAAAAFXBvb2xQcmljZUFzc2V0QmFsYW5jZQUAAAAQb3V0UHJpY2VBc3NldEFtdAkAAGUAAAACBQAAAA1wb29sTFBCYWxhbmNlBQAAAA5wbXRBc3NldEFtb3VudAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5R2V0QWN0aW9uQnlVc2VyAAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAkBAAAAEWRhdGFHZXRBY3Rpb25JbmZvAAAABgUAAAARb3V0QW1vdW50QXNzZXRBbXQFAAAAEG91dFByaWNlQXNzZXRBbXQFAAAADnBtdEFzc2V0QW1vdW50BQAAAAxjdXJyZW50UHJpY2UFAAAABmhlaWdodAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAADGtleVByaWNlTGFzdAAAAAAJAAEsAAAAAgIAAAAEJXNfXwkAAaQAAAABBQAAAAxjdXJyZW50UHJpY2UJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAD2tleVByaWNlSGlzdG9yeQAAAAIFAAAABmhlaWdodAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAJAAEsAAAAAgIAAAAEJXNfXwkAAaQAAAABBQAAAAxjdXJyZW50UHJpY2UFAAAAA25pbAAAAAFpAQAAAAhhY3RpdmF0ZQAAAAUAAAAOYW1vdW50QXNzZXRTdHIAAAANcHJpY2VBc3NldFN0cgAAAAtscEFzc2V0TmFtZQAAAAxscEFzc2V0RGVzY3IAAAAKcG9vbFdlaWdodAMJAQAAAAIhPQAAAAIJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBQAAABRmYWN0b3J5QWRkcmVzc1N0cmluZwkAAAIAAAABAgAAABJwZXJtaXNzaW9ucyBkZW5pZWQEAAAADWFtb3VudEFzc2V0SWQJAAJZAAAAAQUAAAAOYW1vdW50QXNzZXRTdHIEAAAAE2Ftb3VudEFzc2V0RGVjaW1hbHMICQEAAAAFdmFsdWUAAAABCQAD7AAAAAEFAAAADWFtb3VudEFzc2V0SWQAAAAIZGVjaW1hbHMEAAAADHByaWNlQXNzZXRJZAkAAlkAAAABBQAAAA1wcmljZUFzc2V0U3RyBAAAABJwcmljZUFzc2V0RGVjaW1hbHMICQEAAAAFdmFsdWUAAAABCQAD7AAAAAEFAAAADHByaWNlQXNzZXRJZAAAAAhkZWNpbWFscwQAAAASbHBBc3NldElzc3VlQWN0aW9uCQAEQgAAAAUFAAAAC2xwQXNzZXROYW1lBQAAAAxscEFzc2V0RGVzY3IAAAAAAAAAAAEAAAAAAAAAAAgGBAAAAAlscEFzc2V0SWQJAAQ4AAAAAQUAAAASbHBBc3NldElzc3VlQWN0aW9uBAAAABFscEFzc2V0SWRBc1N0cmluZwkAAlgAAAABBQAAAAlscEFzc2V0SWQJAAUUAAAAAgkABEwAAAACBQAAABJscEFzc2V0SXNzdWVBY3Rpb24JAARMAAAAAgkBAAAABEJ1cm4AAAACBQAAAAlscEFzc2V0SWQAAAAAAAAAAAEJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAADmtleUFtb3VudEFzc2V0AAAAAAUAAAAOYW1vdW50QXNzZXRTdHIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAADWtleVByaWNlQXNzZXQAAAAABQAAAA1wcmljZUFzc2V0U3RyBQAAAANuaWwFAAAAEWxwQXNzZXRJZEFzU3RyaW5nAAAAAWkBAAAADXN0YXRzUkVBRE9OTFkAAAAABAAAABJwb29sQ29uZmlnRGF0YUxpc3QJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAJbHBBc3NldElkCQACWQAAAAEJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABBpZHhQb29sTFBBc3NldElkBAAAAA1hbW91bnRBc3NldElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAQaWR4QW1vdW50QXNzZXRJZAQAAAAMcHJpY2VBc3NldElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAPaWR4UHJpY2VBc3NldElkBAAAABVhbW91bnRBc3NldEludGVybmFsSWQJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABhpZHhBbW91bnRBc3NldEludGVybmFsSWQEAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAXaWR4UHJpY2VBc3NldEludGVybmFsSWQEAAAAEmFtb3V0QXNzZXREZWNpbWFscwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAWaWR4QW1vdW50QXNzZXREZWNpbWFscwQAAAAScHJpY2VBc3NldERlY2ltYWxzCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABVpZHhQcmljZUFzc2V0RGVjaW1hbHMEAAAAFXBvb2xMaXF1aWRpdHlEYXRhTGlzdAkBAAAAEGdldFBvb2xMaXF1aWRpdHkAAAACBQAAABVhbW91bnRBc3NldEludGVybmFsSWQFAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkBAAAABZwb29sQW1vdW50QXNzZXRCYWxhbmNlCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAVcG9vbExpcXVpZGl0eURhdGFMaXN0BQAAABVpZHhQb29sQW1vdW50QXNzZXRBbXQEAAAAFXBvb2xQcmljZUFzc2V0QmFsYW5jZQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAFXBvb2xMaXF1aWRpdHlEYXRhTGlzdAUAAAAUaWR4UG9vbFByaWNlQXNzZXRBbXQEAAAADXBvb2xMUEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABVwb29sTGlxdWlkaXR5RGF0YUxpc3QFAAAAEWlkeFBvb2xMUEFzc2V0QW10BAAAABhhbW91bnRBc3NldFBvb2xMb2NrZWRBbXQICQEAAAAdcHJpdmF0ZUNhc3RBc3NldFRvTWF4RGVjaW1hbHMAAAACBQAAABJhbW91dEFzc2V0RGVjaW1hbHMFAAAAFnBvb2xBbW91bnRBc3NldEJhbGFuY2UAAAACXzEEAAAAF3ByaWNlQXNzZXRQb29sTG9ja2VkQW10CAkBAAAAHXByaXZhdGVDYXN0QXNzZXRUb01heERlY2ltYWxzAAAAAgUAAAAScHJpY2VBc3NldERlY2ltYWxzBQAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UAAAACXzEEAAAAFGxwUHJpY2VJbkFtb3VudEFzc2V0CQAAawAAAAMFAAAAGGFtb3VudEFzc2V0UG9vbExvY2tlZEFtdAkAAGgAAAACAAAAAAAAAAABBQAAABFkZWNpbWFsc011bHRQcmljZQUAAAANcG9vbExQQmFsYW5jZQQAAAATbHBQcmljZUluUHJpY2VBc3NldAkAAGsAAAADBQAAABdwcmljZUFzc2V0UG9vbExvY2tlZEFtdAkAAGgAAAACAAAAAAAAAAABBQAAABFkZWNpbWFsc011bHRQcmljZQUAAAANcG9vbExQQmFsYW5jZQQAAAAMY3VycmVudFByaWNlCQEAAAAVcHJpdmF0ZUNhbGN1bGF0ZVByaWNlAAAABAUAAAASYW1vdXRBc3NldERlY2ltYWxzBQAAABJwcmljZUFzc2V0RGVjaW1hbHMFAAAAFnBvb2xBbW91bnRBc3NldEJhbGFuY2UFAAAAFXBvb2xQcmljZUFzc2V0QmFsYW5jZQkABRQAAAACBQAAAANuaWwJAAS5AAAAAgkABEwAAAACAgAAAAwlZCVkJWQlZCVkJWQJAARMAAAAAgkAAaQAAAABBQAAABZwb29sQW1vdW50QXNzZXRCYWxhbmNlCQAETAAAAAIJAAGkAAAAAQUAAAAVcG9vbFByaWNlQXNzZXRCYWxhbmNlCQAETAAAAAIJAAGkAAAAAQUAAAANcG9vbExQQmFsYW5jZQkABEwAAAACCQABpAAAAAEFAAAADGN1cnJlbnRQcmljZQkABEwAAAACCQABpAAAAAEFAAAAFGxwUHJpY2VJbkFtb3VudEFzc2V0CQAETAAAAAIJAAGkAAAAAQUAAAATbHBQcmljZUluUHJpY2VBc3NldAUAAAADbmlsBQAAAANTRVAAAAABaQEAAAAYcHV0QnlBbW91bnRBc3NldFJFQURPTkxZAAAAAwAAABFzbGlwcGFnZVRvbGVyYW5jZQAAABBpbkFtb3VudEFzc2V0QW10AAAAC3VzZXJBZGRyZXNzBAAAABJwb29sQ29uZmlnRGF0YUxpc3QJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAJbHBBc3NldElkCQACWQAAAAEJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABBpZHhQb29sTFBBc3NldElkBAAAAA1hbW91bnRBc3NldElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAQaWR4QW1vdW50QXNzZXRJZAQAAAAMcHJpY2VBc3NldElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAPaWR4UHJpY2VBc3NldElkBAAAABVhbW91bnRBc3NldEludGVybmFsSWQJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABhpZHhBbW91bnRBc3NldEludGVybmFsSWQEAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAXaWR4UHJpY2VBc3NldEludGVybmFsSWQEAAAAEmFtb3V0QXNzZXREZWNpbWFscwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAWaWR4QW1vdW50QXNzZXREZWNpbWFscwQAAAAScHJpY2VBc3NldERlY2ltYWxzCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABVpZHhQcmljZUFzc2V0RGVjaW1hbHMEAAAACnBvb2xTdGF0dXMJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAAA1pZHhQb29sU3RhdHVzBAAAABVwb29sTGlxdWlkaXR5RGF0YUxpc3QJAQAAABBnZXRQb29sTGlxdWlkaXR5AAAAAgUAAAAVYW1vdW50QXNzZXRJbnRlcm5hbElkBQAAABRwcmljZUFzc2V0SW50ZXJuYWxJZAQAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAFXBvb2xMaXF1aWRpdHlEYXRhTGlzdAUAAAAVaWR4UG9vbEFtb3VudEFzc2V0QW10BAAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABVwb29sTGlxdWlkaXR5RGF0YUxpc3QFAAAAFGlkeFBvb2xQcmljZUFzc2V0QW10BAAAAA1wb29sTFBCYWxhbmNlCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAVcG9vbExpcXVpZGl0eURhdGFMaXN0BQAAABFpZHhQb29sTFBBc3NldEFtdAQAAAAdYW1vdW50QXNzZXRBbXRDYWxjdWxhdGVkVHVwbGUJAQAAAB1wcml2YXRlQ2FzdEFzc2V0VG9NYXhEZWNpbWFscwAAAAIFAAAAEmFtb3V0QXNzZXREZWNpbWFscwUAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQQAAAAccHJpY2VBc3NldEFtdENhbGN1bGF0ZWRUdXBsZQkBAAAAHXByaXZhdGVDYXN0QXNzZXRUb01heERlY2ltYWxzAAAAAgUAAAAScHJpY2VBc3NldERlY2ltYWxzBQAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UEAAAAC2N1cmVudFByaWNlAwkAAAAAAAACBQAAAA1wb29sTFBCYWxhbmNlAAAAAAAAAAAAAAAAAAAAAAAACQAAawAAAAMIBQAAABxwcmljZUFzc2V0QW10Q2FsY3VsYXRlZFR1cGxlAAAAAl8xBQAAABFkZWNpbWFsc011bHRQcmljZQgFAAAAHWFtb3VudEFzc2V0QW10Q2FsY3VsYXRlZFR1cGxlAAAAAl8xBAAAABlpblByaWNlQXNzZXRBbXRDYWxjdWxhdGVkCQAAawAAAAMFAAAAEGluQW1vdW50QXNzZXRBbXQFAAAAC2N1cmVudFByaWNlBQAAABFkZWNpbWFsc011bHRQcmljZQQAAAAPaW5QcmljZUFzc2V0QW10CAkBAAAAIHByaXZhdGVDYXN0QXNzZXRUb09yaWdpbkRlY2ltYWxzAAAAAgUAAAAScHJpY2VBc3NldERlY2ltYWxzBQAAABlpblByaWNlQXNzZXRBbXRDYWxjdWxhdGVkAAAAAl8xBAAAAAdyZXN1bHRzCQEAAAAbcHJpdmF0ZUVzdGltYXRlUHV0T3BlcmF0aW9uAAAABgUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAAEGluQW1vdW50QXNzZXRBbXQFAAAADWFtb3VudEFzc2V0SWQFAAAAD2luUHJpY2VBc3NldEFtdAUAAAAMcHJpY2VBc3NldElkBQAAAAt1c2VyQWRkcmVzcwkABRQAAAACBQAAAANuaWwJAAS5AAAAAgkABEwAAAACAgAAABolZCVkJWQlZCVkJWQlZCVkJWQlZCVzJWQlZAkABEwAAAACCQABpAAAAAEIBQAAAAdyZXN1bHRzAAAAAl8xCQAETAAAAAIJAAGkAAAAAQgFAAAAB3Jlc3VsdHMAAAACXzIJAARMAAAAAgkAAaQAAAABCAUAAAAHcmVzdWx0cwAAAAJfMwkABEwAAAACCQABpAAAAAEIBQAAAAdyZXN1bHRzAAAAAl80CQAETAAAAAIJAAGkAAAAAQgFAAAAB3Jlc3VsdHMAAAACXzUJAARMAAAAAgkAAaQAAAABCAUAAAAHcmVzdWx0cwAAAAJfNgkABEwAAAACCQABpAAAAAEIBQAAAAdyZXN1bHRzAAAAAl83CQAETAAAAAIJAAGkAAAAAQgFAAAAB3Jlc3VsdHMAAAACXzgJAARMAAAAAggFAAAAB3Jlc3VsdHMAAAACXzkJAARMAAAAAggFAAAAB3Jlc3VsdHMAAAADXzEwCQAETAAAAAIJAAJYAAAAAQgFAAAAB3Jlc3VsdHMAAAADXzExCQAETAAAAAIJAAGkAAAAAQgFAAAAB3Jlc3VsdHMAAAADXzEyCQAETAAAAAIIBQAAAAdyZXN1bHRzAAAAA18xMwUAAAADbmlsBQAAAANTRVAAAAABaQEAAAATcHV0QnlQcmljZUFzc2V0UkVBRAAAAAMAAAARc2xpcHBhZ2VUb2xlcmFuY2UAAAAPaW5QcmljZUFzc2V0QW10AAAAC3VzZXJBZGRyZXNzBAAAABJwb29sQ29uZmlnRGF0YUxpc3QJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAJbHBBc3NldElkCQACWQAAAAEJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABBpZHhQb29sTFBBc3NldElkBAAAAA1hbW91bnRBc3NldElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAQaWR4QW1vdW50QXNzZXRJZAQAAAAMcHJpY2VBc3NldElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAPaWR4UHJpY2VBc3NldElkBAAAABVhbW91bnRBc3NldEludGVybmFsSWQJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABhpZHhBbW91bnRBc3NldEludGVybmFsSWQEAAAAFHByaWNlQXNzZXRJbnRlcm5hbElkCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAXaWR4UHJpY2VBc3NldEludGVybmFsSWQEAAAAEmFtb3V0QXNzZXREZWNpbWFscwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAEnBvb2xDb25maWdEYXRhTGlzdAUAAAAWaWR4QW1vdW50QXNzZXREZWNpbWFscwQAAAAScHJpY2VBc3NldERlY2ltYWxzCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAABVpZHhQcmljZUFzc2V0RGVjaW1hbHMEAAAACnBvb2xTdGF0dXMJAAGRAAAAAgUAAAAScG9vbENvbmZpZ0RhdGFMaXN0BQAAAA1pZHhQb29sU3RhdHVzBAAAABVwb29sTGlxdWlkaXR5RGF0YUxpc3QJAQAAABBnZXRQb29sTGlxdWlkaXR5AAAAAgUAAAAVYW1vdW50QXNzZXRJbnRlcm5hbElkBQAAABRwcmljZUFzc2V0SW50ZXJuYWxJZAQAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAFXBvb2xMaXF1aWRpdHlEYXRhTGlzdAUAAAAVaWR4UG9vbEFtb3VudEFzc2V0QW10BAAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABVwb29sTGlxdWlkaXR5RGF0YUxpc3QFAAAAFGlkeFBvb2xQcmljZUFzc2V0QW10BAAAAA1wb29sTFBCYWxhbmNlCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAVcG9vbExpcXVpZGl0eURhdGFMaXN0BQAAABFpZHhQb29sTFBBc3NldEFtdAQAAAAdYW1vdW50QXNzZXRBbXRDYWxjdWxhdGVkVHVwbGUJAQAAAB1wcml2YXRlQ2FzdEFzc2V0VG9NYXhEZWNpbWFscwAAAAIFAAAAEmFtb3V0QXNzZXREZWNpbWFscwUAAAAWcG9vbEFtb3VudEFzc2V0QmFsYW5jZQQAAAAccHJpY2VBc3NldEFtdENhbGN1bGF0ZWRUdXBsZQkBAAAAHXByaXZhdGVDYXN0QXNzZXRUb01heERlY2ltYWxzAAAAAgUAAAAScHJpY2VBc3NldERlY2ltYWxzBQAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UEAAAAHmluUHJpY2VBc3NldEFtdENhbGN1bGF0ZWRUdXBsZQkBAAAAHXByaXZhdGVDYXN0QXNzZXRUb01heERlY2ltYWxzAAAAAgUAAAAScHJpY2VBc3NldERlY2ltYWxzBQAAAA9pblByaWNlQXNzZXRBbXQEAAAAC2N1cmVudFByaWNlAwkAAAAAAAACBQAAAA1wb29sTFBCYWxhbmNlAAAAAAAAAAAAAAAAAAAAAAAACQAAawAAAAMIBQAAABxwcmljZUFzc2V0QW10Q2FsY3VsYXRlZFR1cGxlAAAAAl8xBQAAABFkZWNpbWFsc011bHRQcmljZQgFAAAAHWFtb3VudEFzc2V0QW10Q2FsY3VsYXRlZFR1cGxlAAAAAl8xBAAAABppbkFtb3VudEFzc2V0QW10Q2FsY3VsYXRlZAkAAGsAAAADCAUAAAAeaW5QcmljZUFzc2V0QW10Q2FsY3VsYXRlZFR1cGxlAAAAAl8xBQAAABFkZWNpbWFsc011bHRQcmljZQUAAAALY3VyZW50UHJpY2UEAAAAEGluQW1vdW50QXNzZXRBbXQICQEAAAAgcHJpdmF0ZUNhc3RBc3NldFRvT3JpZ2luRGVjaW1hbHMAAAACBQAAABJhbW91dEFzc2V0RGVjaW1hbHMFAAAAGmluQW1vdW50QXNzZXRBbXRDYWxjdWxhdGVkAAAAAl8xBAAAAAdyZXN1bHRzCQEAAAAbcHJpdmF0ZUVzdGltYXRlUHV0T3BlcmF0aW9uAAAABgUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAAEGluQW1vdW50QXNzZXRBbXQFAAAADWFtb3VudEFzc2V0SWQFAAAAD2luUHJpY2VBc3NldEFtdAUAAAAMcHJpY2VBc3NldElkBQAAAAt1c2VyQWRkcmVzcwkABRQAAAACBQAAAANuaWwJAAS5AAAAAgkABEwAAAACAgAAABolZCVkJWQlZCVkJWQlZCVkJWQlZCVzJWQlZAkABEwAAAACCQABpAAAAAEIBQAAAAdyZXN1bHRzAAAAAl8xCQAETAAAAAIJAAGkAAAAAQgFAAAAB3Jlc3VsdHMAAAACXzIJAARMAAAAAgkAAaQAAAABCAUAAAAHcmVzdWx0cwAAAAJfMwkABEwAAAACCQABpAAAAAEIBQAAAAdyZXN1bHRzAAAAAl80CQAETAAAAAIJAAGkAAAAAQgFAAAAB3Jlc3VsdHMAAAACXzUJAARMAAAAAgkAAaQAAAABCAUAAAAHcmVzdWx0cwAAAAJfNgkABEwAAAACCQABpAAAAAEIBQAAAAdyZXN1bHRzAAAAAl83CQAETAAAAAIJAAGkAAAAAQgFAAAAB3Jlc3VsdHMAAAACXzgJAARMAAAAAggFAAAAB3Jlc3VsdHMAAAACXzkJAARMAAAAAggFAAAAB3Jlc3VsdHMAAAADXzEwCQAETAAAAAIJAAJYAAAAAQgFAAAAB3Jlc3VsdHMAAAADXzExCQAETAAAAAIJAAGkAAAAAQgFAAAAB3Jlc3VsdHMAAAADXzEyCQAETAAAAAIIBQAAAAdyZXN1bHRzAAAAA18xMwUAAAADbmlsBQAAAANTRVAAAAABAAAAAnR4AQAAAAZ2ZXJpZnkAAAAABAAAAAckbWF0Y2gwBQAAAAJ0eAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAFT3JkZXIEAAAABW9yZGVyBQAAAAckbWF0Y2gwCQABkQAAAAIJAQAAABt2YWxpZGF0ZU1hdGNoZXJPcmRlckFsbG93ZWQAAAABBQAAAAVvcmRlcgAAAAAAAAAAAQkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAIBQAAAAJ0eAAAAA9zZW5kZXJQdWJsaWNLZXnpNVW6", "height": 1673983, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Ao7rrDDLpJ5cVg1T8SMk3GB8jQGakhBtrBfmJvNpGwBy Next: 69TT5ZvVJdZqhy1k4e5X3vMzF88N1c1g8jcJQzKvpw8r Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let factoryAddressString = "3NBPbSmScU4UfqVrnYc79wvxjtivfmgnSgG"
5+
46 let lPdecimals = 8
57
68 let decimalsMultPrice = ((100 * 1000) * 1000)
1820 let buyOrderType = 0
1921
2022 let sellOrderType = 1
21-
22-let factoryAddressString = "3NBPbSmScU4UfqVrnYc79wvxjtivfmgnSgG"
2323
2424 let idxPoolAddress = 1
2525
120120 func dataPoolLiquidity (amountAssetLocked,priceAssetLocked,lpTokenLocked) = makeString(["%d%d%d", toString(amountAssetLocked), toString(priceAssetLocked), toString(lpTokenLocked)], SEP)
121121
122122
123+func dataPoolLiquidityByUser (amountAssetLocked,priceAssetLocked,lpTokenLocked,userAddress) = makeString(["%d%d%d", toString(amountAssetLocked), toString(priceAssetLocked), toString(lpTokenLocked)], SEP)
124+
125+
123126 func dataPutActionInfo (inAmountAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d%d", toString(inAmountAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageTolerancePassedByUser), toString(slippageToleranceReal), toString(txHeight), toString(txTimestamp)], SEP)
124127
125128
126129 func dataGetActionInfo (outAmountAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmountAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
127130
128131
129-func dataPoolLiquidityByUser (amountAssetLocked,priceAssetLocked,lpTokenLocked,userAddress) = makeString(["%d%d%d", toString(amountAssetLocked), toString(priceAssetLocked), toString(lpTokenLocked)], SEP)
130-
131-
132132 func getScriptHash () = toBase64String(value(scriptHash(this)))
133133
134134
135-func privateCastAssetToLPDecimals (assetDecimals,assetAmount) = {
135+func privateCastAssetToMaxDecimals (assetDecimals,assetAmount) = {
136136 let decimalsMult = pow(10, 0, (lPdecimals - assetDecimals), 0, 0, DOWN)
137137 $Tuple2((assetAmount * decimalsMult), decimalsMult)
138138 }
145145
146146
147147 func privateCalculatePrice (amoutAssetDecimals,priceAssetDecimals,amountAssetAmt,priceAssetAmt) = {
148- let amountAssetPoolLockedAmt = privateCastAssetToLPDecimals(amoutAssetDecimals, amountAssetAmt)._1
149- let priceAssetPoolLockedAmt = privateCastAssetToLPDecimals(priceAssetDecimals, priceAssetAmt)._1
148+ let amountAssetPoolLockedAmt = privateCastAssetToMaxDecimals(amoutAssetDecimals, amountAssetAmt)._1
149+ let priceAssetPoolLockedAmt = privateCastAssetToMaxDecimals(priceAssetDecimals, priceAssetAmt)._1
150150 fraction(priceAssetPoolLockedAmt, decimalsMultPrice, amountAssetPoolLockedAmt)
151- }
152-
153-
154-func privateGetPoolStatistics () = {
155- let poolConfigDataList = getPoolConfig()
156- let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
157- let amountAssetId = poolConfigDataList[idxAmountAssetId]
158- let priceAssetId = poolConfigDataList[idxPriceAssetId]
159- let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
160- let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
161- let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
162- let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
163- let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
164- let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
165- let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
166- let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
167- let amountAssetPoolLockedAmt = privateCastAssetToLPDecimals(amoutAssetDecimals, poolAmountAssetBalance)._1
168- let priceAssetPoolLockedAmt = privateCastAssetToLPDecimals(priceAssetDecimals, poolPriceAssetBalance)._1
169- let lpPriceInAmountAsset = fraction(amountAssetPoolLockedAmt, (1 * decimalsMultPrice), poolLPBalance)
170- let lpPriceInPriceAsset = fraction(priceAssetPoolLockedAmt, (1 * decimalsMultPrice), poolLPBalance)
171- let currentPrice = privateCalculatePrice(amoutAssetDecimals, priceAssetDecimals, poolAmountAssetBalance, poolPriceAssetBalance)
172-[poolAmountAssetBalance, poolPriceAssetBalance, poolLPBalance, currentPrice, lpPriceInAmountAsset, lpPriceInPriceAsset]
173151 }
174152
175153
196174 else if ((paymentLpAmount > userLPBalance))
197175 then throw("Invalid amount passed. Amount less than available.")
198176 else {
199- let amountAssetPoolLockedAmt = privateCastAssetToLPDecimals(amoutAssetDecimals, poolAmountAssetBalance)._1
200- let priceAssetPoolLockedAmt = privateCastAssetToLPDecimals(priceAssetDecimals, poolPriceAssetBalance)._1
177+ let amountAssetPoolLockedAmt = privateCastAssetToMaxDecimals(amoutAssetDecimals, poolAmountAssetBalance)._1
178+ let priceAssetPoolLockedAmt = privateCastAssetToMaxDecimals(priceAssetDecimals, poolPriceAssetBalance)._1
201179 let outAmountAssetAmt = fraction(amountAssetPoolLockedAmt, paymentLpAmount, poolLPBalance)
202180 let outPriceAssetAmt = fraction(priceAssetPoolLockedAmt, paymentLpAmount, poolLPBalance)
203181 let outAmountAssetAmtFinal = privateCastAssetToOriginDecimals(amoutAssetDecimals, outAmountAssetAmt)._1
231209 else (priceAssetId != inPriceAssetId))
232210 then throw("Invalid amount or price asset passed.")
233211 else {
234- let inAmountAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(amoutAssetDecimals, inAmountAssetAmt)
235- let inPriceAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(priceAssetDecimals, inPriceAssetAmt)
212+ let inAmountAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(amoutAssetDecimals, inAmountAssetAmt)
213+ let inPriceAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(priceAssetDecimals, inPriceAssetAmt)
236214 let inAmountAssetAmtCalculated = inAmountAssetAmtCalculatedTuple._1
237215 let inPriceAssetAmtCalculated = inPriceAssetAmtCalculatedTuple._1
238216 let userPrice = fraction(inPriceAssetAmtCalculated, decimalsMultPrice, inAmountAssetAmtCalculated)
271249 }
272250
273251
274-func estimatePutOperationBasedOnAmountAsset (slippageTolerance,inAmountAssetAmt,userAddress) = {
275- let poolConfigDataList = getPoolConfig()
276- let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
277- let amountAssetId = poolConfigDataList[idxAmountAssetId]
278- let priceAssetId = poolConfigDataList[idxPriceAssetId]
279- let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
280- let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
281- let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
282- let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
283- let poolStatus = poolConfigDataList[idxPoolStatus]
284- let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
285- let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
286- let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
287- let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
288- let amountAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(amoutAssetDecimals, poolAmountAssetBalance)
289- let priceAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(priceAssetDecimals, poolPriceAssetBalance)
290- let curentPrice = if ((poolLPBalance == 0))
291- then 0
292- else fraction(priceAssetAmtCalculatedTuple._1, decimalsMultPrice, amountAssetAmtCalculatedTuple._1)
293- let inPriceAssetAmtCalculated = fraction(inAmountAssetAmt, curentPrice, decimalsMultPrice)
294- let inPriceAssetAmt = privateCastAssetToOriginDecimals(priceAssetDecimals, inPriceAssetAmtCalculated)._1
295- privateEstimatePutOperation(slippageTolerance, inAmountAssetAmt, amountAssetId, inPriceAssetAmt, priceAssetId, userAddress)
296- }
297-
298-
299-func estimatePutOperationBasedOnPriceAsset (slippageTolerance,inPriceAssetAmt,userAddress) = {
300- let poolConfigDataList = getPoolConfig()
301- let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
302- let amountAssetId = poolConfigDataList[idxAmountAssetId]
303- let priceAssetId = poolConfigDataList[idxPriceAssetId]
304- let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
305- let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
306- let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
307- let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
308- let poolStatus = poolConfigDataList[idxPoolStatus]
309- let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
310- let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
311- let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
312- let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
313- let amountAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(amoutAssetDecimals, poolAmountAssetBalance)
314- let priceAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(priceAssetDecimals, poolPriceAssetBalance)
315- let inPriceAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(priceAssetDecimals, inPriceAssetAmt)
316- let curentPrice = if ((poolLPBalance == 0))
317- then 0
318- else fraction(priceAssetAmtCalculatedTuple._1, decimalsMultPrice, amountAssetAmtCalculatedTuple._1)
319- let inAmountAssetAmtCalculated = fraction(inPriceAssetAmtCalculatedTuple._1, decimalsMultPrice, curentPrice)
320- let inAmountAssetAmt = privateCastAssetToOriginDecimals(amoutAssetDecimals, inAmountAssetAmtCalculated)._1
321- privateEstimatePutOperation(slippageTolerance, inAmountAssetAmt, amountAssetId, inPriceAssetAmt, priceAssetId, userAddress)
322- }
323-
324-
325252 func validateMatcherOrderAllowed2 () = {
326253 let orderType = "BUY"
327254 let orderAmount = 1000000000
353280 let isValidAssetPair = true
354281 let orderPrice = orderPricce
355282 let priceDecimals = ((8 + priceAssetDecimals) - amountAssetDecimals)
356- let castedOrderPrice = privateCastAssetToLPDecimals(priceDecimals, orderPrice)._1
283+ let castedOrderPrice = privateCastAssetToMaxDecimals(priceDecimals, orderPrice)._1
357284 let isOrderPriceValid = if ((orderType == "BUY"))
358285 then (currentPrice >= castedOrderPrice)
359286 else (castedOrderPrice >= currentPrice)
409336 else true
410337 let orderPrice = order.price
411338 let priceDecimals = ((8 + priceAssetDecimals) - amountAssetDecimals)
412- let castedOrderPrice = privateCastAssetToLPDecimals(priceDecimals, orderPrice)._1
339+ let castedOrderPrice = privateCastAssetToMaxDecimals(priceDecimals, orderPrice)._1
413340 let isOrderPriceValid = if ((order.orderType == Buy))
414341 then (currentPrice >= castedOrderPrice)
415342 else (castedOrderPrice >= currentPrice)
506433 }
507434
508435
436+
437+@Callable(i)
438+func statsREADONLY () = {
439+ let poolConfigDataList = getPoolConfig()
440+ let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
441+ let amountAssetId = poolConfigDataList[idxAmountAssetId]
442+ let priceAssetId = poolConfigDataList[idxPriceAssetId]
443+ let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
444+ let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
445+ let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
446+ let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
447+ let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
448+ let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
449+ let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
450+ let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
451+ let amountAssetPoolLockedAmt = privateCastAssetToMaxDecimals(amoutAssetDecimals, poolAmountAssetBalance)._1
452+ let priceAssetPoolLockedAmt = privateCastAssetToMaxDecimals(priceAssetDecimals, poolPriceAssetBalance)._1
453+ let lpPriceInAmountAsset = fraction(amountAssetPoolLockedAmt, (1 * decimalsMultPrice), poolLPBalance)
454+ let lpPriceInPriceAsset = fraction(priceAssetPoolLockedAmt, (1 * decimalsMultPrice), poolLPBalance)
455+ let currentPrice = privateCalculatePrice(amoutAssetDecimals, priceAssetDecimals, poolAmountAssetBalance, poolPriceAssetBalance)
456+ $Tuple2(nil, makeString(["%d%d%d%d%d%d", toString(poolAmountAssetBalance), toString(poolPriceAssetBalance), toString(poolLPBalance), toString(currentPrice), toString(lpPriceInAmountAsset), toString(lpPriceInPriceAsset)], SEP))
457+ }
458+
459+
460+
461+@Callable(i)
462+func putByAmountAssetREADONLY (slippageTolerance,inAmountAssetAmt,userAddress) = {
463+ let poolConfigDataList = getPoolConfig()
464+ let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
465+ let amountAssetId = poolConfigDataList[idxAmountAssetId]
466+ let priceAssetId = poolConfigDataList[idxPriceAssetId]
467+ let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
468+ let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
469+ let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
470+ let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
471+ let poolStatus = poolConfigDataList[idxPoolStatus]
472+ let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
473+ let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
474+ let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
475+ let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
476+ let amountAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(amoutAssetDecimals, poolAmountAssetBalance)
477+ let priceAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(priceAssetDecimals, poolPriceAssetBalance)
478+ let curentPrice = if ((poolLPBalance == 0))
479+ then 0
480+ else fraction(priceAssetAmtCalculatedTuple._1, decimalsMultPrice, amountAssetAmtCalculatedTuple._1)
481+ let inPriceAssetAmtCalculated = fraction(inAmountAssetAmt, curentPrice, decimalsMultPrice)
482+ let inPriceAssetAmt = privateCastAssetToOriginDecimals(priceAssetDecimals, inPriceAssetAmtCalculated)._1
483+ let results = privateEstimatePutOperation(slippageTolerance, inAmountAssetAmt, amountAssetId, inPriceAssetAmt, priceAssetId, userAddress)
484+ $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d%d%d%s%d%d", toString(results._1), toString(results._2), toString(results._3), toString(results._4), toString(results._5), toString(results._6), toString(results._7), toString(results._8), results._9, results._10, toBase58String(results._11), toString(results._12), results._13], SEP))
485+ }
486+
487+
488+
489+@Callable(i)
490+func putByPriceAssetREAD (slippageTolerance,inPriceAssetAmt,userAddress) = {
491+ let poolConfigDataList = getPoolConfig()
492+ let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
493+ let amountAssetId = poolConfigDataList[idxAmountAssetId]
494+ let priceAssetId = poolConfigDataList[idxPriceAssetId]
495+ let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
496+ let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
497+ let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
498+ let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
499+ let poolStatus = poolConfigDataList[idxPoolStatus]
500+ let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
501+ let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
502+ let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
503+ let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
504+ let amountAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(amoutAssetDecimals, poolAmountAssetBalance)
505+ let priceAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(priceAssetDecimals, poolPriceAssetBalance)
506+ let inPriceAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(priceAssetDecimals, inPriceAssetAmt)
507+ let curentPrice = if ((poolLPBalance == 0))
508+ then 0
509+ else fraction(priceAssetAmtCalculatedTuple._1, decimalsMultPrice, amountAssetAmtCalculatedTuple._1)
510+ let inAmountAssetAmtCalculated = fraction(inPriceAssetAmtCalculatedTuple._1, decimalsMultPrice, curentPrice)
511+ let inAmountAssetAmt = privateCastAssetToOriginDecimals(amoutAssetDecimals, inAmountAssetAmtCalculated)._1
512+ let results = privateEstimatePutOperation(slippageTolerance, inAmountAssetAmt, amountAssetId, inPriceAssetAmt, priceAssetId, userAddress)
513+ $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d%d%d%s%d%d", toString(results._1), toString(results._2), toString(results._3), toString(results._4), toString(results._5), toString(results._6), toString(results._7), toString(results._8), results._9, results._10, toBase58String(results._11), toString(results._12), results._13], SEP))
514+ }
515+
516+
509517 @Verifier(tx)
510518 func verify () = match tx {
511519 case order: Order =>
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let factoryAddressString = "3NBPbSmScU4UfqVrnYc79wvxjtivfmgnSgG"
5+
46 let lPdecimals = 8
57
68 let decimalsMultPrice = ((100 * 1000) * 1000)
79
810 let SEP = "__"
911
1012 let PoolActive = 1
1113
1214 let PoolPutDisabled = 2
1315
1416 let PoolMatcherDisabled = 3
1517
1618 let PoolShutdown = 4
1719
1820 let buyOrderType = 0
1921
2022 let sellOrderType = 1
21-
22-let factoryAddressString = "3NBPbSmScU4UfqVrnYc79wvxjtivfmgnSgG"
2323
2424 let idxPoolAddress = 1
2525
2626 let idxPoolStatus = 2
2727
2828 let idxPoolLPAssetId = 3
2929
3030 let idxAmountAssetId = 4
3131
3232 let idxPriceAssetId = 5
3333
3434 let idxAmountAssetDecimals = 6
3535
3636 let idxPriceAssetDecimals = 7
3737
3838 let idxAmountAssetInternalId = 8
3939
4040 let idxPriceAssetInternalId = 9
4141
4242 let idxPoolWeight = 10
4343
4444 let idxLPAssetDecimals = 11
4545
4646 let idxMatcherPublicKey = 12
4747
4848 let idmaxAllowedOrderPriceDifferencePct = 13
4949
5050 let idxPoolAmountAssetAmt = 1
5151
5252 let idxPoolPriceAssetAmt = 2
5353
5454 let idxPoolLPAssetAmt = 3
5555
5656 func keyPriceLast () = "%s%s__price__last"
5757
5858
5959 func keyPriceHistory (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
6060
6161
6262 func keyPoolLiquidity (internalAmountAsset,internalPriceAsset) = (((("%d%d%s__" + internalAmountAsset) + "__") + internalPriceAsset) + "__locked")
6363
6464
6565 func keyPoolLiquidityByUser (internalAmountAsset,internalPriceAsset,userAddress) = (((((("%d%d%s%s__" + internalAmountAsset) + "__") + internalPriceAsset) + "__") + userAddress) + "__locked")
6666
6767
6868 func keyPutActionByUser (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
6969
7070
7171 func keyGetActionByUser (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
7272
7373
7474 func keyAmountAsset () = "%s__amountAsset"
7575
7676
7777 func keyPriceAsset () = "%s__priceAsset"
7878
7979
8080 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
8181
8282
8383 func keyPoolConfig (amountAssetInternal,priceAssetInternal) = (((("%d%d%s__" + amountAssetInternal) + "__") + priceAssetInternal) + "__config")
8484
8585
8686 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
8787
8888
8989 func keyAllPoolsShutdown () = "%s__shutdown"
9090
9191
9292 func isGlobalShutdown () = valueOrElse(getBoolean(value(addressFromString(factoryAddressString)), keyAllPoolsShutdown()), false)
9393
9494
9595 func getPoolConfig () = {
9696 let poolAmountAsset = valueOrErrorMessage(getString(keyAmountAsset()), "No config for amount asset found")
9797 let poolPriceAsset = valueOrErrorMessage(getString(keyPriceAsset()), "No config for price asset found")
9898 let poolPriceAssetInternal = valueOrErrorMessage(getInteger(value(addressFromString(factoryAddressString)), keyMappingsBaseAsset2internalId(poolPriceAsset)), "No config for internal price asset found")
9999 let poolAmountAssetInternal = valueOrErrorMessage(getInteger(value(addressFromString(factoryAddressString)), keyMappingsBaseAsset2internalId(poolAmountAsset)), "No config for internal amount asset found")
100100 split(valueOrErrorMessage(getString(addressFromStringValue(factoryAddressString), keyPoolConfig(toString(poolAmountAssetInternal), toString(poolPriceAssetInternal))), "No factory config found for pool assets."), SEP)
101101 }
102102
103103
104104 func getPoolLiquidity (amountAssetInternalId,priceAssetInternalId) = {
105105 let currentPoolLiquidityValue = getString(keyPoolLiquidity(amountAssetInternalId, priceAssetInternalId))
106106 if (!(isDefined(currentPoolLiquidityValue)))
107107 then ["", "0", "0", "0"]
108108 else split(value(currentPoolLiquidityValue), SEP)
109109 }
110110
111111
112112 func getPoolLiquidityByUser (amountAssetInternalId,priceAssetInternalId,userAddress) = {
113113 let currentPoolLiquidityValue = getString(keyPoolLiquidityByUser(amountAssetInternalId, priceAssetInternalId, userAddress))
114114 if (!(isDefined(currentPoolLiquidityValue)))
115115 then ["", "0", "0", "0", "0"]
116116 else split(value(currentPoolLiquidityValue), SEP)
117117 }
118118
119119
120120 func dataPoolLiquidity (amountAssetLocked,priceAssetLocked,lpTokenLocked) = makeString(["%d%d%d", toString(amountAssetLocked), toString(priceAssetLocked), toString(lpTokenLocked)], SEP)
121121
122122
123+func dataPoolLiquidityByUser (amountAssetLocked,priceAssetLocked,lpTokenLocked,userAddress) = makeString(["%d%d%d", toString(amountAssetLocked), toString(priceAssetLocked), toString(lpTokenLocked)], SEP)
124+
125+
123126 func dataPutActionInfo (inAmountAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d%d", toString(inAmountAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageTolerancePassedByUser), toString(slippageToleranceReal), toString(txHeight), toString(txTimestamp)], SEP)
124127
125128
126129 func dataGetActionInfo (outAmountAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmountAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
127130
128131
129-func dataPoolLiquidityByUser (amountAssetLocked,priceAssetLocked,lpTokenLocked,userAddress) = makeString(["%d%d%d", toString(amountAssetLocked), toString(priceAssetLocked), toString(lpTokenLocked)], SEP)
130-
131-
132132 func getScriptHash () = toBase64String(value(scriptHash(this)))
133133
134134
135-func privateCastAssetToLPDecimals (assetDecimals,assetAmount) = {
135+func privateCastAssetToMaxDecimals (assetDecimals,assetAmount) = {
136136 let decimalsMult = pow(10, 0, (lPdecimals - assetDecimals), 0, 0, DOWN)
137137 $Tuple2((assetAmount * decimalsMult), decimalsMult)
138138 }
139139
140140
141141 func privateCastAssetToOriginDecimals (assetDecimals,assetAmount) = {
142142 let decimalsMult = pow(10, 0, (lPdecimals - assetDecimals), 0, 0, DOWN)
143143 $Tuple2((assetAmount / decimalsMult), decimalsMult)
144144 }
145145
146146
147147 func privateCalculatePrice (amoutAssetDecimals,priceAssetDecimals,amountAssetAmt,priceAssetAmt) = {
148- let amountAssetPoolLockedAmt = privateCastAssetToLPDecimals(amoutAssetDecimals, amountAssetAmt)._1
149- let priceAssetPoolLockedAmt = privateCastAssetToLPDecimals(priceAssetDecimals, priceAssetAmt)._1
148+ let amountAssetPoolLockedAmt = privateCastAssetToMaxDecimals(amoutAssetDecimals, amountAssetAmt)._1
149+ let priceAssetPoolLockedAmt = privateCastAssetToMaxDecimals(priceAssetDecimals, priceAssetAmt)._1
150150 fraction(priceAssetPoolLockedAmt, decimalsMultPrice, amountAssetPoolLockedAmt)
151- }
152-
153-
154-func privateGetPoolStatistics () = {
155- let poolConfigDataList = getPoolConfig()
156- let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
157- let amountAssetId = poolConfigDataList[idxAmountAssetId]
158- let priceAssetId = poolConfigDataList[idxPriceAssetId]
159- let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
160- let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
161- let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
162- let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
163- let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
164- let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
165- let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
166- let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
167- let amountAssetPoolLockedAmt = privateCastAssetToLPDecimals(amoutAssetDecimals, poolAmountAssetBalance)._1
168- let priceAssetPoolLockedAmt = privateCastAssetToLPDecimals(priceAssetDecimals, poolPriceAssetBalance)._1
169- let lpPriceInAmountAsset = fraction(amountAssetPoolLockedAmt, (1 * decimalsMultPrice), poolLPBalance)
170- let lpPriceInPriceAsset = fraction(priceAssetPoolLockedAmt, (1 * decimalsMultPrice), poolLPBalance)
171- let currentPrice = privateCalculatePrice(amoutAssetDecimals, priceAssetDecimals, poolAmountAssetBalance, poolPriceAssetBalance)
172-[poolAmountAssetBalance, poolPriceAssetBalance, poolLPBalance, currentPrice, lpPriceInAmountAsset, lpPriceInPriceAsset]
173151 }
174152
175153
176154 func privateEstimateGetOperation (paymentLpAssetId,paymentLpAmount,userAddress) = {
177155 let poolConfigList = getPoolConfig()
178156 let lpAssetId = poolConfigList[idxPoolLPAssetId]
179157 let amountAssetId = poolConfigList[idxAmountAssetId]
180158 let priceAssetId = poolConfigList[idxPriceAssetId]
181159 let amountAssetInternalId = poolConfigList[idxAmountAssetInternalId]
182160 let priceAssetInternalId = poolConfigList[idxPriceAssetInternalId]
183161 let amoutAssetDecimals = parseIntValue(poolConfigList[idxAmountAssetDecimals])
184162 let priceAssetDecimals = parseIntValue(poolConfigList[idxPriceAssetDecimals])
185163 let poolStatus = poolConfigList[idxPoolStatus]
186164 let userLiquidityList = getPoolLiquidityByUser(amountAssetInternalId, priceAssetInternalId, userAddress)
187165 let userLPBalance = parseIntValue(userLiquidityList[idxPoolLPAssetAmt])
188166 let userAmountAssetBalance = parseIntValue(userLiquidityList[idxPoolAmountAssetAmt])
189167 let userPriceAssetBalance = parseIntValue(userLiquidityList[idxPoolPriceAssetAmt])
190168 let poolLiquidityList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
191169 let poolLPBalance = parseIntValue(poolLiquidityList[idxPoolLPAssetAmt])
192170 let poolAmountAssetBalance = parseIntValue(poolLiquidityList[idxPoolAmountAssetAmt])
193171 let poolPriceAssetBalance = parseIntValue(poolLiquidityList[idxPoolPriceAssetAmt])
194172 if ((lpAssetId != paymentLpAssetId))
195173 then throw("Invalid asset passed.")
196174 else if ((paymentLpAmount > userLPBalance))
197175 then throw("Invalid amount passed. Amount less than available.")
198176 else {
199- let amountAssetPoolLockedAmt = privateCastAssetToLPDecimals(amoutAssetDecimals, poolAmountAssetBalance)._1
200- let priceAssetPoolLockedAmt = privateCastAssetToLPDecimals(priceAssetDecimals, poolPriceAssetBalance)._1
177+ let amountAssetPoolLockedAmt = privateCastAssetToMaxDecimals(amoutAssetDecimals, poolAmountAssetBalance)._1
178+ let priceAssetPoolLockedAmt = privateCastAssetToMaxDecimals(priceAssetDecimals, poolPriceAssetBalance)._1
201179 let outAmountAssetAmt = fraction(amountAssetPoolLockedAmt, paymentLpAmount, poolLPBalance)
202180 let outPriceAssetAmt = fraction(priceAssetPoolLockedAmt, paymentLpAmount, poolLPBalance)
203181 let outAmountAssetAmtFinal = privateCastAssetToOriginDecimals(amoutAssetDecimals, outAmountAssetAmt)._1
204182 let outPriceAssetAmtFinal = privateCastAssetToOriginDecimals(priceAssetDecimals, outPriceAssetAmt)._1
205183 let currentPrice = fraction(priceAssetPoolLockedAmt, decimalsMultPrice, amountAssetPoolLockedAmt)
206184 $Tuple14(outAmountAssetAmtFinal, outPriceAssetAmtFinal, amountAssetInternalId, priceAssetInternalId, userAmountAssetBalance, amountAssetId, userPriceAssetBalance, priceAssetId, userLPBalance, poolAmountAssetBalance, poolPriceAssetBalance, poolLPBalance, currentPrice, poolStatus)
207185 }
208186 }
209187
210188
211189 func privateEstimatePutOperation (slippageTolerance,inAmountAssetAmt,inAmountAssetId,inPriceAssetAmt,inPriceAssetId,userAddress) = {
212190 let poolConfigDataList = getPoolConfig()
213191 let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
214192 let amountAssetId = poolConfigDataList[idxAmountAssetId]
215193 let priceAssetId = poolConfigDataList[idxPriceAssetId]
216194 let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
217195 let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
218196 let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
219197 let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
220198 let poolStatus = poolConfigDataList[idxPoolStatus]
221199 let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
222200 let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
223201 let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
224202 let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
225203 let userLiquidityDataList = getPoolLiquidityByUser(amountAssetInternalId, priceAssetInternalId, userAddress)
226204 let userAmountAssetBalance = parseIntValue(userLiquidityDataList[idxPoolAmountAssetAmt])
227205 let userPriceAssetBalance = parseIntValue(userLiquidityDataList[idxPoolPriceAssetAmt])
228206 let userLPBalance = parseIntValue(userLiquidityDataList[idxPoolLPAssetAmt])
229207 if (if ((amountAssetId != inAmountAssetId))
230208 then true
231209 else (priceAssetId != inPriceAssetId))
232210 then throw("Invalid amount or price asset passed.")
233211 else {
234- let inAmountAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(amoutAssetDecimals, inAmountAssetAmt)
235- let inPriceAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(priceAssetDecimals, inPriceAssetAmt)
212+ let inAmountAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(amoutAssetDecimals, inAmountAssetAmt)
213+ let inPriceAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(priceAssetDecimals, inPriceAssetAmt)
236214 let inAmountAssetAmtCalculated = inAmountAssetAmtCalculatedTuple._1
237215 let inPriceAssetAmtCalculated = inPriceAssetAmtCalculatedTuple._1
238216 let userPrice = fraction(inPriceAssetAmtCalculated, decimalsMultPrice, inAmountAssetAmtCalculated)
239217 let amountAssetPoolLockedAmt = (poolAmountAssetBalance * inAmountAssetAmtCalculatedTuple._2)
240218 let priceAssetPoolLockedAmt = (poolPriceAssetBalance * inPriceAssetAmtCalculatedTuple._2)
241219 let curentPrice = if ((poolLPBalance == 0))
242220 then 0
243221 else fraction(priceAssetPoolLockedAmt, decimalsMultPrice, amountAssetPoolLockedAmt)
244222 let slippage = if ((curentPrice == 0))
245223 then 0
246224 else if ((curentPrice > userPrice))
247225 then fraction((curentPrice - userPrice), 100, curentPrice)
248226 else fraction((userPrice - curentPrice), 100, curentPrice)
249227 if (if ((curentPrice != 0))
250228 then ((slippage * decimalsMultPrice) > slippageTolerance)
251229 else false)
252230 then throw(((("Price slippage " + toString((slippage * decimalsMultPrice))) + " exceeded the passed limit of ") + toString(slippageTolerance)))
253231 else {
254232 let finalPrice = fraction((priceAssetPoolLockedAmt + inPriceAssetAmtCalculated), decimalsMultPrice, (amountAssetPoolLockedAmt + inAmountAssetAmtCalculated))
255233 let outLpAmount = if ((poolLPBalance == 0))
256234 then {
257235 let partA = pow(inAmountAssetAmtCalculated, 0, 5, 1, 0, DOWN)
258236 let partB = pow(inPriceAssetAmtCalculated, 0, 5, 1, 0, DOWN)
259237 (partA * partB)
260238 }
261239 else {
262240 let lpAmtByAmountAsset = fraction(poolLPBalance, inAmountAssetAmtCalculated, amountAssetPoolLockedAmt)
263241 let lpAmtByPriceAsset = fraction(poolLPBalance, inPriceAssetAmtCalculated, priceAssetPoolLockedAmt)
264242 if ((lpAmtByPriceAsset > lpAmtByAmountAsset))
265243 then lpAmtByAmountAsset
266244 else lpAmtByPriceAsset
267245 }
268246 $Tuple13(outLpAmount, finalPrice, userAmountAssetBalance, userPriceAssetBalance, userLPBalance, poolAmountAssetBalance, poolPriceAssetBalance, poolLPBalance, amountAssetInternalId, priceAssetInternalId, lpAssetId, slippage, poolStatus)
269247 }
270248 }
271249 }
272250
273251
274-func estimatePutOperationBasedOnAmountAsset (slippageTolerance,inAmountAssetAmt,userAddress) = {
275- let poolConfigDataList = getPoolConfig()
276- let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
277- let amountAssetId = poolConfigDataList[idxAmountAssetId]
278- let priceAssetId = poolConfigDataList[idxPriceAssetId]
279- let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
280- let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
281- let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
282- let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
283- let poolStatus = poolConfigDataList[idxPoolStatus]
284- let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
285- let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
286- let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
287- let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
288- let amountAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(amoutAssetDecimals, poolAmountAssetBalance)
289- let priceAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(priceAssetDecimals, poolPriceAssetBalance)
290- let curentPrice = if ((poolLPBalance == 0))
291- then 0
292- else fraction(priceAssetAmtCalculatedTuple._1, decimalsMultPrice, amountAssetAmtCalculatedTuple._1)
293- let inPriceAssetAmtCalculated = fraction(inAmountAssetAmt, curentPrice, decimalsMultPrice)
294- let inPriceAssetAmt = privateCastAssetToOriginDecimals(priceAssetDecimals, inPriceAssetAmtCalculated)._1
295- privateEstimatePutOperation(slippageTolerance, inAmountAssetAmt, amountAssetId, inPriceAssetAmt, priceAssetId, userAddress)
296- }
297-
298-
299-func estimatePutOperationBasedOnPriceAsset (slippageTolerance,inPriceAssetAmt,userAddress) = {
300- let poolConfigDataList = getPoolConfig()
301- let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
302- let amountAssetId = poolConfigDataList[idxAmountAssetId]
303- let priceAssetId = poolConfigDataList[idxPriceAssetId]
304- let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
305- let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
306- let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
307- let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
308- let poolStatus = poolConfigDataList[idxPoolStatus]
309- let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
310- let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
311- let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
312- let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
313- let amountAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(amoutAssetDecimals, poolAmountAssetBalance)
314- let priceAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(priceAssetDecimals, poolPriceAssetBalance)
315- let inPriceAssetAmtCalculatedTuple = privateCastAssetToLPDecimals(priceAssetDecimals, inPriceAssetAmt)
316- let curentPrice = if ((poolLPBalance == 0))
317- then 0
318- else fraction(priceAssetAmtCalculatedTuple._1, decimalsMultPrice, amountAssetAmtCalculatedTuple._1)
319- let inAmountAssetAmtCalculated = fraction(inPriceAssetAmtCalculatedTuple._1, decimalsMultPrice, curentPrice)
320- let inAmountAssetAmt = privateCastAssetToOriginDecimals(amoutAssetDecimals, inAmountAssetAmtCalculated)._1
321- privateEstimatePutOperation(slippageTolerance, inAmountAssetAmt, amountAssetId, inPriceAssetAmt, priceAssetId, userAddress)
322- }
323-
324-
325252 func validateMatcherOrderAllowed2 () = {
326253 let orderType = "BUY"
327254 let orderAmount = 1000000000
328255 let orderPricce = 23300000
329256 let poolConfigDataList = getPoolConfig()
330257 let amountAssetId = poolConfigDataList[idxAmountAssetId]
331258 let priceAssetId = poolConfigDataList[idxPriceAssetId]
332259 let poolStatus = parseIntValue(poolConfigDataList[idxPoolStatus])
333260 let matcherPublicKeyStr = poolConfigDataList[idxMatcherPublicKey]
334261 let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
335262 let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
336263 let amountAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
337264 let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
338265 let maxAllowedOrderPriceDifferencePct = parseIntValue(poolConfigDataList[idmaxAllowedOrderPriceDifferencePct])
339266 let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
340267 let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
341268 let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
342269 let currentPrice = if ((orderType == "BUY"))
343270 then privateCalculatePrice(amountAssetDecimals, priceAssetDecimals, (poolAmountAssetBalance + orderAmount), poolPriceAssetBalance)
344271 else privateCalculatePrice(amountAssetDecimals, priceAssetDecimals, (poolAmountAssetBalance + orderAmount), poolPriceAssetBalance)
345272 let isPoolStatusValid = if (if (if (isGlobalShutdown())
346273 then true
347274 else (poolStatus == PoolMatcherDisabled))
348275 then true
349276 else (poolStatus == PoolShutdown))
350277 then false
351278 else true
352279 let isValidMatcherSign = true
353280 let isValidAssetPair = true
354281 let orderPrice = orderPricce
355282 let priceDecimals = ((8 + priceAssetDecimals) - amountAssetDecimals)
356- let castedOrderPrice = privateCastAssetToLPDecimals(priceDecimals, orderPrice)._1
283+ let castedOrderPrice = privateCastAssetToMaxDecimals(priceDecimals, orderPrice)._1
357284 let isOrderPriceValid = if ((orderType == "BUY"))
358285 then (currentPrice >= castedOrderPrice)
359286 else (castedOrderPrice >= currentPrice)
360287 if (true)
361288 then throw(((((("orderPrice=" + toString(orderPrice)) + " castedOrderPrice=") + toString(castedOrderPrice)) + " currentPrice=") + toString(currentPrice)))
362289 else [if (if (if (isValidAssetPair)
363290 then isValidMatcherSign
364291 else false)
365292 then isPoolStatusValid
366293 else false)
367294 then isOrderPriceValid
368295 else false]
369296 }
370297
371298
372299 func validateMatcherOrderAllowed (order) = {
373300 let poolConfigDataList = getPoolConfig()
374301 let amountAssetId = poolConfigDataList[idxAmountAssetId]
375302 let priceAssetId = poolConfigDataList[idxPriceAssetId]
376303 let poolStatus = parseIntValue(poolConfigDataList[idxPoolStatus])
377304 let matcherPublicKeyStr = poolConfigDataList[idxMatcherPublicKey]
378305 let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
379306 let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
380307 let amountAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
381308 let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
382309 let maxAllowedOrderPriceDifferencePct = parseIntValue(poolConfigDataList[idmaxAllowedOrderPriceDifferencePct])
383310 let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
384311 let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
385312 let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
386313 let currentPrice = if ((order.orderType == Buy))
387314 then privateCalculatePrice(amountAssetDecimals, priceAssetDecimals, (poolAmountAssetBalance + order.amount), poolPriceAssetBalance)
388315 else privateCalculatePrice(amountAssetDecimals, priceAssetDecimals, (poolAmountAssetBalance + order.amount), poolPriceAssetBalance)
389316 let isPoolStatusValid = if (if (if (isGlobalShutdown())
390317 then true
391318 else (poolStatus == PoolMatcherDisabled))
392319 then true
393320 else (poolStatus == PoolShutdown))
394321 then false
395322 else true
396323 let isValidMatcherSign = true
397324 let orderAmountAsset = order.assetPair.amountAsset
398325 let orderAmountAssetStr = if ((orderAmountAsset == unit))
399326 then ""
400327 else toBase58String(value(orderAmountAsset))
401328 let orderPriceAsset = order.assetPair.priceAsset
402329 let orderPriceAssetStr = if ((orderPriceAsset == unit))
403330 then ""
404331 else toBase58String(value(orderPriceAsset))
405332 let isValidAssetPair = if (if ((orderAmountAssetStr != amountAssetId))
406333 then true
407334 else (orderPriceAssetStr != priceAssetId))
408335 then false
409336 else true
410337 let orderPrice = order.price
411338 let priceDecimals = ((8 + priceAssetDecimals) - amountAssetDecimals)
412- let castedOrderPrice = privateCastAssetToLPDecimals(priceDecimals, orderPrice)._1
339+ let castedOrderPrice = privateCastAssetToMaxDecimals(priceDecimals, orderPrice)._1
413340 let isOrderPriceValid = if ((order.orderType == Buy))
414341 then (currentPrice >= castedOrderPrice)
415342 else (castedOrderPrice >= currentPrice)
416343 if (true)
417344 then throw(((((("orderPrice=" + toString(orderPrice)) + " castedOrderPrice=") + toString(castedOrderPrice)) + " currentPrice=") + toString(currentPrice)))
418345 else [if (if (if (isValidAssetPair)
419346 then isValidMatcherSign
420347 else false)
421348 then isPoolStatusValid
422349 else false)
423350 then isOrderPriceValid
424351 else false]
425352 }
426353
427354
428355 @Callable(i)
429356 func put (slippageTolerance) = {
430357 let pmtAmountAsset = value(i.payments[0])
431358 let inAmountAssetAmt = pmtAmountAsset.amount
432359 let inAmountAssetId = if (!(isDefined(pmtAmountAsset.assetId)))
433360 then fromBase58String("")
434361 else value(pmtAmountAsset.assetId)
435362 let pmtPriceAsset = value(i.payments[1])
436363 let inPriceAssetAmt = pmtPriceAsset.amount
437364 let inPriceAssetId = value(pmtPriceAsset.assetId)
438365 let estimatedPutResults = privateEstimatePutOperation(slippageTolerance, inAmountAssetAmt, toBase58String(inAmountAssetId), inPriceAssetAmt, toBase58String(inPriceAssetId), toString(i.caller))
439366 let outLpAmount = estimatedPutResults._1
440367 let curentPrice = estimatedPutResults._2
441368 let userAmountAssetBalance = estimatedPutResults._3
442369 let userPriceAssetBalance = estimatedPutResults._4
443370 let userLPBalance = estimatedPutResults._5
444371 let poolAmountAssetBalance = estimatedPutResults._6
445372 let poolPriceAssetBalance = estimatedPutResults._7
446373 let poolLPBalance = estimatedPutResults._8
447374 let amountAssetInternalId = estimatedPutResults._9
448375 let priceAssetInternalId = estimatedPutResults._10
449376 let lpAssetId = estimatedPutResults._11
450377 let slippageCalculated = estimatedPutResults._12
451378 let poolStatus = parseIntValue(estimatedPutResults._13)
452379 if (if (if (isGlobalShutdown())
453380 then true
454381 else (poolStatus == PoolPutDisabled))
455382 then true
456383 else (poolStatus == PoolShutdown))
457384 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
458385 else [StringEntry(keyPriceLast(), ("%s__" + toString(curentPrice))), StringEntry(keyPriceHistory(height, lastBlock.timestamp), ("%s__" + toString(curentPrice))), StringEntry(keyPutActionByUser(toString(i.caller), toBase58String(i.transactionId)), dataPutActionInfo(inAmountAssetAmt, inPriceAssetAmt, outLpAmount, curentPrice, slippageTolerance, slippageCalculated, height, lastBlock.timestamp)), StringEntry(keyPoolLiquidityByUser(amountAssetInternalId, priceAssetInternalId, toString(i.caller)), dataPoolLiquidity((userAmountAssetBalance + inAmountAssetAmt), (userPriceAssetBalance + inPriceAssetAmt), (userLPBalance + outLpAmount))), StringEntry(keyPoolLiquidity(amountAssetInternalId, priceAssetInternalId), dataPoolLiquidity((poolAmountAssetBalance + inAmountAssetAmt), (poolPriceAssetBalance + inPriceAssetAmt), (poolLPBalance + outLpAmount))), Reissue(lpAssetId, outLpAmount, true), ScriptTransfer(i.caller, outLpAmount, lpAssetId)]
459386 }
460387
461388
462389
463390 @Callable(i)
464391 func get () = {
465392 let pmtAmountAsset = value(i.payments[0])
466393 let pmtAssetId = value(pmtAmountAsset.assetId)
467394 let pmtAssetAmount = pmtAmountAsset.amount
468395 let results = privateEstimateGetOperation(toBase58String(pmtAssetId), pmtAssetAmount, toString(i.caller))
469396 let outAmountAssetAmt = results._1
470397 let outPriceAssetAmt = results._2
471398 let amountAssetInternalId = results._3
472399 let priceAssetInternalId = results._4
473400 let userAmountAssetBalance = results._5
474401 let amountAssetId = results._6
475402 let userPriceAssetBalance = results._7
476403 let priceAssetId = results._8
477404 let userLPBalance = results._9
478405 let poolAmountAssetBalance = results._10
479406 let poolPriceAssetBalance = results._11
480407 let poolLPBalance = results._12
481408 let currentPrice = results._13
482409 let poolStatus = parseIntValue(results._14)
483410 if (if (isGlobalShutdown())
484411 then true
485412 else (poolStatus == PoolShutdown))
486413 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
487414 else [Burn(pmtAssetId, pmtAssetAmount), ScriptTransfer(i.caller, outAmountAssetAmt, if ((amountAssetId == ""))
488415 then unit
489416 else fromBase58String(amountAssetId)), ScriptTransfer(i.caller, outPriceAssetAmt, fromBase58String(priceAssetId)), StringEntry(keyPoolLiquidityByUser(amountAssetInternalId, priceAssetInternalId, toString(i.caller)), dataPoolLiquidity((userAmountAssetBalance - outAmountAssetAmt), (userPriceAssetBalance - outPriceAssetAmt), (userLPBalance - pmtAssetAmount))), StringEntry(keyPoolLiquidity(amountAssetInternalId, priceAssetInternalId), dataPoolLiquidity((poolAmountAssetBalance - outAmountAssetAmt), (poolPriceAssetBalance - outPriceAssetAmt), (poolLPBalance - pmtAssetAmount))), StringEntry(keyGetActionByUser(toString(i.caller), toBase58String(i.transactionId)), dataGetActionInfo(outAmountAssetAmt, outPriceAssetAmt, pmtAssetAmount, currentPrice, height, lastBlock.timestamp)), StringEntry(keyPriceLast(), ("%s__" + toString(currentPrice))), StringEntry(keyPriceHistory(height, lastBlock.timestamp), ("%s__" + toString(currentPrice)))]
490417 }
491418
492419
493420
494421 @Callable(i)
495422 func activate (amountAssetStr,priceAssetStr,lpAssetName,lpAssetDescr,poolWeight) = if ((toString(i.caller) != factoryAddressString))
496423 then throw("permissions denied")
497424 else {
498425 let amountAssetId = fromBase58String(amountAssetStr)
499426 let amountAssetDecimals = value(assetInfo(amountAssetId)).decimals
500427 let priceAssetId = fromBase58String(priceAssetStr)
501428 let priceAssetDecimals = value(assetInfo(priceAssetId)).decimals
502429 let lpAssetIssueAction = Issue(lpAssetName, lpAssetDescr, 1, 8, true)
503430 let lpAssetId = calculateAssetId(lpAssetIssueAction)
504431 let lpAssetIdAsString = toBase58String(lpAssetId)
505432 $Tuple2([lpAssetIssueAction, Burn(lpAssetId, 1), StringEntry(keyAmountAsset(), amountAssetStr), StringEntry(keyPriceAsset(), priceAssetStr)], lpAssetIdAsString)
506433 }
507434
508435
436+
437+@Callable(i)
438+func statsREADONLY () = {
439+ let poolConfigDataList = getPoolConfig()
440+ let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
441+ let amountAssetId = poolConfigDataList[idxAmountAssetId]
442+ let priceAssetId = poolConfigDataList[idxPriceAssetId]
443+ let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
444+ let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
445+ let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
446+ let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
447+ let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
448+ let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
449+ let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
450+ let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
451+ let amountAssetPoolLockedAmt = privateCastAssetToMaxDecimals(amoutAssetDecimals, poolAmountAssetBalance)._1
452+ let priceAssetPoolLockedAmt = privateCastAssetToMaxDecimals(priceAssetDecimals, poolPriceAssetBalance)._1
453+ let lpPriceInAmountAsset = fraction(amountAssetPoolLockedAmt, (1 * decimalsMultPrice), poolLPBalance)
454+ let lpPriceInPriceAsset = fraction(priceAssetPoolLockedAmt, (1 * decimalsMultPrice), poolLPBalance)
455+ let currentPrice = privateCalculatePrice(amoutAssetDecimals, priceAssetDecimals, poolAmountAssetBalance, poolPriceAssetBalance)
456+ $Tuple2(nil, makeString(["%d%d%d%d%d%d", toString(poolAmountAssetBalance), toString(poolPriceAssetBalance), toString(poolLPBalance), toString(currentPrice), toString(lpPriceInAmountAsset), toString(lpPriceInPriceAsset)], SEP))
457+ }
458+
459+
460+
461+@Callable(i)
462+func putByAmountAssetREADONLY (slippageTolerance,inAmountAssetAmt,userAddress) = {
463+ let poolConfigDataList = getPoolConfig()
464+ let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
465+ let amountAssetId = poolConfigDataList[idxAmountAssetId]
466+ let priceAssetId = poolConfigDataList[idxPriceAssetId]
467+ let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
468+ let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
469+ let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
470+ let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
471+ let poolStatus = poolConfigDataList[idxPoolStatus]
472+ let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
473+ let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
474+ let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
475+ let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
476+ let amountAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(amoutAssetDecimals, poolAmountAssetBalance)
477+ let priceAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(priceAssetDecimals, poolPriceAssetBalance)
478+ let curentPrice = if ((poolLPBalance == 0))
479+ then 0
480+ else fraction(priceAssetAmtCalculatedTuple._1, decimalsMultPrice, amountAssetAmtCalculatedTuple._1)
481+ let inPriceAssetAmtCalculated = fraction(inAmountAssetAmt, curentPrice, decimalsMultPrice)
482+ let inPriceAssetAmt = privateCastAssetToOriginDecimals(priceAssetDecimals, inPriceAssetAmtCalculated)._1
483+ let results = privateEstimatePutOperation(slippageTolerance, inAmountAssetAmt, amountAssetId, inPriceAssetAmt, priceAssetId, userAddress)
484+ $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d%d%d%s%d%d", toString(results._1), toString(results._2), toString(results._3), toString(results._4), toString(results._5), toString(results._6), toString(results._7), toString(results._8), results._9, results._10, toBase58String(results._11), toString(results._12), results._13], SEP))
485+ }
486+
487+
488+
489+@Callable(i)
490+func putByPriceAssetREAD (slippageTolerance,inPriceAssetAmt,userAddress) = {
491+ let poolConfigDataList = getPoolConfig()
492+ let lpAssetId = fromBase58String(poolConfigDataList[idxPoolLPAssetId])
493+ let amountAssetId = poolConfigDataList[idxAmountAssetId]
494+ let priceAssetId = poolConfigDataList[idxPriceAssetId]
495+ let amountAssetInternalId = poolConfigDataList[idxAmountAssetInternalId]
496+ let priceAssetInternalId = poolConfigDataList[idxPriceAssetInternalId]
497+ let amoutAssetDecimals = parseIntValue(poolConfigDataList[idxAmountAssetDecimals])
498+ let priceAssetDecimals = parseIntValue(poolConfigDataList[idxPriceAssetDecimals])
499+ let poolStatus = poolConfigDataList[idxPoolStatus]
500+ let poolLiquidityDataList = getPoolLiquidity(amountAssetInternalId, priceAssetInternalId)
501+ let poolAmountAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolAmountAssetAmt])
502+ let poolPriceAssetBalance = parseIntValue(poolLiquidityDataList[idxPoolPriceAssetAmt])
503+ let poolLPBalance = parseIntValue(poolLiquidityDataList[idxPoolLPAssetAmt])
504+ let amountAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(amoutAssetDecimals, poolAmountAssetBalance)
505+ let priceAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(priceAssetDecimals, poolPriceAssetBalance)
506+ let inPriceAssetAmtCalculatedTuple = privateCastAssetToMaxDecimals(priceAssetDecimals, inPriceAssetAmt)
507+ let curentPrice = if ((poolLPBalance == 0))
508+ then 0
509+ else fraction(priceAssetAmtCalculatedTuple._1, decimalsMultPrice, amountAssetAmtCalculatedTuple._1)
510+ let inAmountAssetAmtCalculated = fraction(inPriceAssetAmtCalculatedTuple._1, decimalsMultPrice, curentPrice)
511+ let inAmountAssetAmt = privateCastAssetToOriginDecimals(amoutAssetDecimals, inAmountAssetAmtCalculated)._1
512+ let results = privateEstimatePutOperation(slippageTolerance, inAmountAssetAmt, amountAssetId, inPriceAssetAmt, priceAssetId, userAddress)
513+ $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d%d%d%s%d%d", toString(results._1), toString(results._2), toString(results._3), toString(results._4), toString(results._5), toString(results._6), toString(results._7), toString(results._8), results._9, results._10, toBase58String(results._11), toString(results._12), results._13], SEP))
514+ }
515+
516+
509517 @Verifier(tx)
510518 func verify () = match tx {
511519 case order: Order =>
512520 validateMatcherOrderAllowed(order)[1]
513521 case _ =>
514522 sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
515523 }
516524

github/deemru/w8io/026f985 
65.07 ms