tx · Es1Nv9BoaMMHN6CUCckcLuH2RJURXEG3EET5mCvjs46b

3MrRa3KaEgRyyjQdMLuU78m5GkJLvP5DZLj:  -0.05100000 Waves

2022.07.15 09:26 [2140493] smart account 3MrRa3KaEgRyyjQdMLuU78m5GkJLvP5DZLj > SELF 0.00000000 Waves

{ "type": 13, "id": "Es1Nv9BoaMMHN6CUCckcLuH2RJURXEG3EET5mCvjs46b", "fee": 5100000, "feeAssetId": null, "timestamp": 1657866430880, "version": 2, "chainId": 84, "sender": "3MrRa3KaEgRyyjQdMLuU78m5GkJLvP5DZLj", "senderPublicKey": "AJNTN7EtP9dsAmPzcKRp9bRMvzZL4uwkmVxQuFuar3Qr", "proofs": [ "2eHY3XANhXomaHCwZABmD6FRUwxv7z5aNc8HMPHtTkWomEq8vz4y3MjQiUANi1u6oNskwgEf7DGhvtzquTrkW8Ad" ], "script": "base64:AAIFAAAAAAAAAEkIAhIAEgASCQoHAQEBAQEBARIOCgwBAQEBAQEBCAgIAQESBQoDAQEBEgUKAwEBARIAEgMKAQESABIDCgEIEgASAwoBCBIDCgEIAAAAdgAAAAAJa19vcmFfa2V5AgAAAAlrX29yYV9rZXkAAAAAD2tfb3JhX2Jsb2NrX2tleQIAAAAPa19vcmFfYmxvY2tfa2V5AAAAAAVrX29yYQIAAAAFa19vcmEAAAAACWtfYmFsYW5jZQIAAAAJa19iYWxhbmNlAAAAAA5rX3Bvc2l0aW9uU2l6ZQIAAAAOa19wb3NpdGlvblNpemUAAAAAEGtfcG9zaXRpb25NYXJnaW4CAAAAEGtfcG9zaXRpb25NYXJnaW4AAAAAFmtfcG9zaXRpb25PcGVuTm90aW9uYWwCAAAAFmtfcG9zaXRpb25PcGVuTm90aW9uYWwAAAAALmtfcG9zaXRpb25MYXN0VXBkYXRlZEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24CAAAAEmtfcG9zaXRpb25GcmFjdGlvbgAAAAANa19pbml0aWFsaXplZAIAAAANa19pbml0aWFsaXplZAAAAAAIa19wYXVzZWQCAAAACGtfcGF1c2VkAAAAAAVrX2ZlZQIAAAAFa19mZWUAAAAAD2tfZnVuZGluZ1BlcmlvZAIAAAAPa19mdW5kaW5nUGVyaW9kAAAAABFrX2luaXRNYXJnaW5SYXRpbwIAAAARa19pbml0TWFyZ2luUmF0aW8AAAAAGGtfbWFpbnRlbmFuY2VNYXJnaW5SYXRpbwIAAAAFa19tbXIAAAAAFWtfbGlxdWlkYXRpb25GZWVSYXRpbwIAAAAVa19saXF1aWRhdGlvbkZlZVJhdGlvAAAAAA1rX3NwcmVhZExpbWl0AgAAAA1rX3NwcmVhZExpbWl0AAAAABBrX21heFByaWNlSW1wYWN0AgAAABBrX21heFByaWNlSW1wYWN0AAAAAA1rX2xhc3REYXRhU3RyAgAAAA1rX2xhc3REYXRhU3RyAAAAAA5rX2xhc3RNaW51dGVJZAIAAAAOa19sYXN0TWludXRlSWQAAAAAHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlAgAAAB1rX3R3YXBEYXRhTGFzdEN1bXVsYXRpdmVQcmljZQAAAAATa190d2FwRGF0YUxhc3RQcmljZQIAAAATa190d2FwRGF0YUxhc3RQcmljZQAAAAAaa190d2FwRGF0YVByZXZpb3VzTWludXRlSWQCAAAAGmtfdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkAAAAACVrX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAgAAABtrX2xhdGVzdExvbmdQcmVtaXVtRnJhY3Rpb24AAAAAJmtfbGF0ZXN0U2hvcnRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAgAAABxrX2xhdGVzdFNob3J0UHJlbWl1bUZyYWN0aW9uAAAAABJrX25leHRGdW5kaW5nQmxvY2sCAAAAHmtfbmV4dEZ1bmRpbmdCbG9ja01pblRpbWVzdGFtcAAAAAARa19sb25nRnVuZGluZ1JhdGUCAAAAEWtfbG9uZ0Z1bmRpbmdSYXRlAAAAABJrX3Nob3J0RnVuZGluZ1JhdGUCAAAAEmtfc2hvcnRGdW5kaW5nUmF0ZQAAAAATa19xdW90ZUFzc2V0UmVzZXJ2ZQIAAAAIa19xdEFzdFIAAAAAEmtfYmFzZUFzc2V0UmVzZXJ2ZQIAAAAIa19ic0FzdFIAAAAAE2tfdG90YWxQb3NpdGlvblNpemUCAAAAE2tfdG90YWxQb3NpdGlvblNpemUAAAAAF2tfdG90YWxMb25nUG9zaXRpb25TaXplAgAAABdrX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAAAAAYa190b3RhbFNob3J0UG9zaXRpb25TaXplAgAAABhrX3RvdGFsU2hvcnRQb3NpdGlvblNpemUAAAAAFGtfY3VtdWxhdGl2ZU5vdGlvbmFsAgAAABRrX2N1bXVsYXRpdmVOb3Rpb25hbAAAAAAWa19vcGVuSW50ZXJlc3ROb3Rpb25hbAIAAAAWa19vcGVuSW50ZXJlc3ROb3Rpb25hbAAAAAAUa19jb29yZGluYXRvckFkZHJlc3MCAAAAFGtfY29vcmRpbmF0b3JBZGRyZXNzAAAAABNrX2luc3VyYW5jZV9hZGRyZXNzAgAAABNrX2luc3VyYW5jZV9hZGRyZXNzAAAAAA9rX2FkbWluX2FkZHJlc3MCAAAAD2tfYWRtaW5fYWRkcmVzcwAAAAASa19hZG1pbl9wdWJsaWNfa2V5AgAAABJrX2FkbWluX3B1YmxpY19rZXkAAAAADWtfcXVvdGVfYXNzZXQCAAAADWtfcXVvdGVfYXNzZXQAAAAAD2tfcXVvdGVfc3Rha2luZwIAAAAPa19xdW90ZV9zdGFraW5nAAAAABFrX3N0YWtpbmdfYWRkcmVzcwIAAAARa19zdGFraW5nX2FkZHJlc3MBAAAAC2Nvb3JkaW5hdG9yAAAAAAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAABHRoaXMFAAAAFGtfY29vcmRpbmF0b3JBZGRyZXNzAgAAABNDb29yZGluYXRvciBub3Qgc2V0AQAAAAxhZG1pbkFkZHJlc3MAAAAACQAEJgAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIJAQAAAAtjb29yZGluYXRvcgAAAAAFAAAAD2tfYWRtaW5fYWRkcmVzcwEAAAAOYWRtaW5QdWJsaWNLZXkAAAAACQACWQAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIJAQAAAAtjb29yZGluYXRvcgAAAAAFAAAAEmtfYWRtaW5fcHVibGljX2tleQEAAAAKcXVvdGVBc3NldAAAAAAJAAJZAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgkBAAAAC2Nvb3JkaW5hdG9yAAAAAAUAAAANa19xdW90ZV9hc3NldAEAAAARcXVvdGVBc3NldFN0YWtpbmcAAAAACQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgkBAAAAC2Nvb3JkaW5hdG9yAAAAAAUAAAAPa19xdW90ZV9zdGFraW5nAgAAABtRdW90ZSBhc3NldCBzdGFraW5nIG5vdCBzZXQBAAAADnN0YWtpbmdBZGRyZXNzAAAAAAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIJAQAAAAtjb29yZGluYXRvcgAAAAAFAAAAEWtfc3Rha2luZ19hZGRyZXNzAgAAABFJbnN1cmFuY2Ugbm90IHNldAEAAAAQaW5zdXJhbmNlQWRkcmVzcwAAAAAJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACCQEAAAALY29vcmRpbmF0b3IAAAAABQAAABNrX2luc3VyYW5jZV9hZGRyZXNzAgAAABFJbnN1cmFuY2Ugbm90IHNldAAAAAAIRElSX0xPTkcAAAAAAAAAAAEAAAAACURJUl9TSE9SVAAAAAAAAAAAAgAAAAAWRlVORElOR19CTE9DS19JTlRFUlZBTAAAAAAAAAAAPAAAAAANVFdBUF9JTlRFUlZBTAAAAAAAAAAADwAAAAAPT1JBQ0xFX0lOVEVSVkFMAAAAAAAAAAAPAAAAAAdTRUNPTkRTAAAAAAAAAAPoAAAAAAxERUNJTUFMX1VOSVQJAABoAAAAAgAAAAAAAAAAAQkAAGgAAAACCQAAaAAAAAIJAABoAAAAAgkAAGgAAAACCQAAaAAAAAIAAAAAAAAAAAoAAAAAAAAAAAoAAAAAAAAAAAoAAAAAAAAAAAoAAAAAAAAAAAoAAAAAAAAAAAoAAAAAD0hVTkRSRURfUEVSQ0VOVAkAAGgAAAACAAAAAAAAAABkBQAAAAxERUNJTUFMX1VOSVQAAAAAB09ORV9EQVkJAABoAAAAAgAAAAAAAAFRgAUAAAAMREVDSU1BTF9VTklUAAAAAAhBTExfRkVFUwAAAAAAAAAAZAAAAAAPUE5MX09QVElPTl9TUE9UAAAAAAAAAAABAAAAABFQTkxfT1BUSU9OX09SQUNMRQAAAAAAAAAAAgEAAAABcwAAAAEAAAACX3gJAAEsAAAAAgkAAaQAAAABBQAAAAJfeAIAAAABLAEAAAAEZGl2ZAAAAAIAAAACX3gAAAACX3kJAQAAAAhmcmFjdGlvbgAAAAQFAAAAAl94BQAAAAxERUNJTUFMX1VOSVQFAAAAAl95BQAAAAhIQUxGRVZFTgEAAAAEbXVsZAAAAAIAAAACX3gAAAACX3kJAQAAAAhmcmFjdGlvbgAAAAQFAAAAAl94BQAAAAJfeQUAAAAMREVDSU1BTF9VTklUBQAAAAhIQUxGRVZFTgEAAAADYWJzAAAAAQAAAAJfeAMJAABmAAAAAgUAAAACX3gAAAAAAAAAAAAFAAAAAl94CQEAAAABLQAAAAEFAAAAAl94AQAAAAR2bWF4AAAAAgAAAAJfeAAAAAJfeQMJAABnAAAAAgUAAAACX3gFAAAAAl95BQAAAAJfeAUAAAACX3kBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgAAAARfa2V5AAAACF9hZGRyZXNzCQABLAAAAAIJAAEsAAAAAgUAAAAEX2tleQIAAAABXwUAAAAIX2FkZHJlc3MBAAAACWxpc3RUb1N0cgAAAAEAAAAFX2xpc3QKAQAAAAVfam9pbgAAAAIAAAALYWNjdW11bGF0b3IAAAADdmFsCQABLAAAAAIJAAEsAAAAAgUAAAALYWNjdW11bGF0b3IFAAAAA3ZhbAIAAAABLAQAAAAKbmV3TGlzdFN0cgoAAAAAAiRsBQAAAAVfbGlzdAoAAAAAAiRzCQABkAAAAAEFAAAAAiRsCgAAAAAFJGFjYzACAAAAAAoBAAAABSRmMF8xAAAAAgAAAAIkYQAAAAIkaQMJAABnAAAAAgUAAAACJGkFAAAAAiRzBQAAAAIkYQkBAAAABV9qb2luAAAAAgUAAAACJGEJAAGRAAAAAgUAAAACJGwFAAAAAiRpCgEAAAAFJGYwXzIAAAACAAAAAiRhAAAAAiRpAwkAAGcAAAACBQAAAAIkaQUAAAACJHMFAAAAAiRhCQAAAgAAAAECAAAAFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEAAAAFJGYwXzIAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACBQAAAAUkYWNjMAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAgAAAAAAAAAAAwAAAAAAAAAABAAAAAAAAAAABQAAAAAAAAAABgAAAAAAAAAABwAAAAAAAAAACAAAAAAAAAAACQAAAAAAAAAACgAAAAAAAAAACwAAAAAAAAAADAAAAAAAAAAADQAAAAAAAAAADgAAAAAAAAAADwAAAAAAAAAAEAAAAAAAAAAAEQAAAAAAAAAAEgAAAAAAAAAAEwAAAAAAAAAAFAQAAAALbmV3TGlzdFN0clUJAQAAAAlkcm9wUmlnaHQAAAACBQAAAApuZXdMaXN0U3RyAAAAAAAAAAABBAAAAAtuZXdMaXN0U3RyUgMJAAAAAAAAAgkAAS8AAAACBQAAAAtuZXdMaXN0U3RyVQAAAAAAAAAAAQIAAAABLAkAATAAAAACBQAAAAtuZXdMaXN0U3RyVQAAAAAAAAAAAQUAAAALbmV3TGlzdFN0clUFAAAAC25ld0xpc3RTdHJSAQAAAAlzdHJUb0xpc3QAAAABAAAABF9zdHIJAAS1AAAAAgUAAAAEX3N0cgIAAAABLAEAAAALcHVzaFRvUXVldWUAAAADAAAABV9saXN0AAAACF9tYXhTaXplAAAABl92YWx1ZQMJAABmAAAAAgkAAZAAAAABBQAAAAVfbGlzdAUAAAAIX21heFNpemUJAARNAAAAAgkABFEAAAACBQAAAAVfbGlzdAAAAAAAAAAAAAUAAAAGX3ZhbHVlCQAETQAAAAIFAAAABV9saXN0BQAAAAZfdmFsdWUBAAAAA2ludAAAAAEAAAABawkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAAWsJAAEsAAAAAgIAAAANbm8gdmFsdWUgZm9yIAUAAAABawEAAAAIY2JhbGFuY2UAAAAACQEAAAADaW50AAAAAQUAAAAJa19iYWxhbmNlAQAAAANmZWUAAAAACQEAAAADaW50AAAAAQUAAAAFa19mZWUBAAAAD2luaXRNYXJnaW5SYXRpbwAAAAAJAQAAAANpbnQAAAABBQAAABFrX2luaXRNYXJnaW5SYXRpbwEAAAAGcXRBc3RSAAAAAAkBAAAAA2ludAAAAAEFAAAAE2tfcXVvdGVBc3NldFJlc2VydmUBAAAABmJzQXN0UgAAAAAJAQAAAANpbnQAAAABBQAAABJrX2Jhc2VBc3NldFJlc2VydmUBAAAAEXRvdGFsUG9zaXRpb25TaXplAAAAAAkBAAAAA2ludAAAAAEFAAAAE2tfdG90YWxQb3NpdGlvblNpemUBAAAAEmN1bXVsYXRpdmVOb3Rpb25hbAAAAAAJAQAAAANpbnQAAAABBQAAABRrX2N1bXVsYXRpdmVOb3Rpb25hbAEAAAAUb3BlbkludGVyZXN0Tm90aW9uYWwAAAAACQEAAAADaW50AAAAAQUAAAAWa19vcGVuSW50ZXJlc3ROb3Rpb25hbAEAAAAZbmV4dEZ1bmRpbmdCbG9ja1RpbWVzdGFtcAAAAAAJAQAAAANpbnQAAAABBQAAABJrX25leHRGdW5kaW5nQmxvY2sBAAAAEGZ1bmRpbmdQZXJpb2RSYXcAAAAACQEAAAADaW50AAAAAQUAAAAPa19mdW5kaW5nUGVyaW9kAQAAABRmdW5kaW5nUGVyaW9kRGVjaW1hbAAAAAAJAABoAAAAAgkBAAAAEGZ1bmRpbmdQZXJpb2RSYXcAAAAABQAAAAxERUNJTUFMX1VOSVQBAAAAFGZ1bmRpbmdQZXJpb2RTZWNvbmRzAAAAAAkAAGgAAAACCQEAAAAQZnVuZGluZ1BlcmlvZFJhdwAAAAAFAAAAB1NFQ09ORFMBAAAAFm1haW50ZW5hbmNlTWFyZ2luUmF0aW8AAAAACQEAAAADaW50AAAAAQUAAAAYa19tYWludGVuYW5jZU1hcmdpblJhdGlvAQAAABNsaXF1aWRhdGlvbkZlZVJhdGlvAAAAAAkBAAAAA2ludAAAAAEFAAAAFWtfbGlxdWlkYXRpb25GZWVSYXRpbwEAAAALc3ByZWFkTGltaXQAAAAACQEAAAADaW50AAAAAQUAAAANa19zcHJlYWRMaW1pdAEAAAAObWF4UHJpY2VJbXBhY3QAAAAACQEAAAADaW50AAAAAQUAAAAQa19tYXhQcmljZUltcGFjdAEAAAAjbGF0ZXN0TG9uZ0N1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAAACQEAAAADaW50AAAAAQUAAAAla19sYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgEAAAAkbGF0ZXN0U2hvcnRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAAAAAkBAAAAA2ludAAAAAEFAAAAJmtfbGF0ZXN0U2hvcnRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQAAABZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAAAAAkBAAAAA2ludAAAAAEFAAAAGGtfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQEAAAAVdG90YWxMb25nUG9zaXRpb25TaXplAAAAAAkBAAAAA2ludAAAAAEFAAAAF2tfdG90YWxMb25nUG9zaXRpb25TaXplAQAAABZyZXF1aXJlTW9yZU1hcmdpblJhdGlvAAAAAwAAAAxfbWFyZ2luUmF0aW8AAAAQX2Jhc2VNYXJnaW5SYXRpbwAAABRfbGFyZ2VyVGhhbk9yRXF1YWxUbwQAAAAUcmVtYWluaW5nTWFyZ2luUmF0aW8JAABlAAAAAgUAAAAMX21hcmdpblJhdGlvBQAAABBfYmFzZU1hcmdpblJhdGlvAwMFAAAAFF9sYXJnZXJUaGFuT3JFcXVhbFRvCQAAZgAAAAIAAAAAAAAAAAAFAAAAFHJlbWFpbmluZ01hcmdpblJhdGlvBwkAAAIAAAABAgAAAA5JbnZhbGlkIG1hcmdpbgMDCQEAAAABIQAAAAEFAAAAFF9sYXJnZXJUaGFuT3JFcXVhbFRvCQAAZwAAAAIFAAAAFHJlbWFpbmluZ01hcmdpblJhdGlvAAAAAAAAAAAABwkAAAIAAAABAgAAAA5JbnZhbGlkIG1hcmdpbgYBAAAAH2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAABAAAADV9wb3NpdGlvblNpemUDCQAAAAAAAAIFAAAADV9wb3NpdGlvblNpemUAAAAAAAAAAAAJAAACAAAAAQIAAAAsU2hvdWxkIG5vdCBiZSBjYWxsZWQgd2l0aCBfcG9zaXRpb25TaXplID09IDADCQAAZgAAAAIFAAAADV9wb3NpdGlvblNpemUAAAAAAAAAAAAJAQAAACNsYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAAAAAJAQAAACRsYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAAAAQAAAAtnZXRQb3NpdGlvbgAAAAEAAAAHX3RyYWRlcgQAAAAPcG9zaXRpb25TaXplT3B0CQAEGgAAAAIFAAAABHRoaXMJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAADmtfcG9zaXRpb25TaXplBQAAAAdfdHJhZGVyBAAAAAckbWF0Y2gwBQAAAA9wb3NpdGlvblNpemVPcHQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAAMcG9zaXRpb25TaXplBQAAAAckbWF0Y2gwCQAFFgAAAAQFAAAADHBvc2l0aW9uU2l6ZQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAQa19wb3NpdGlvbk1hcmdpbgUAAAAHX3RyYWRlcgkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAWa19wb3NpdGlvbk9wZW5Ob3Rpb25hbAUAAAAHX3RyYWRlcgkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAua19wb3NpdGlvbkxhc3RVcGRhdGVkQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUAAAAHX3RyYWRlcgkABRYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAABNyZXF1aXJlT3BlblBvc2l0aW9uAAAAAQAAAAdfdHJhZGVyAwkAAAAAAAACCAkBAAAAC2dldFBvc2l0aW9uAAAAAQUAAAAHX3RyYWRlcgAAAAJfMQAAAAAAAAAAAAkAAAIAAAABAgAAABBObyBvcGVuIHBvc2l0aW9uBgEAAAALaW5pdGlhbGl6ZWQAAAAACQEAAAALdmFsdWVPckVsc2UAAAACCQAEGwAAAAIFAAAABHRoaXMFAAAADWtfaW5pdGlhbGl6ZWQHAQAAAAZwYXVzZWQAAAAACQEAAAALdmFsdWVPckVsc2UAAAACCQAEGwAAAAIFAAAABHRoaXMFAAAACGtfcGF1c2VkBwEAAAANdXBkYXRlUmVzZXJ2ZQAAAAMAAAAGX2lzQWRkAAAAEV9xdW90ZUFzc2V0QW1vdW50AAAAEF9iYXNlQXNzZXRBbW91bnQDBQAAAAZfaXNBZGQEAAAAB25ld0Jhc2UJAABlAAAAAgkBAAAABmJzQXN0UgAAAAAFAAAAEF9iYXNlQXNzZXRBbW91bnQDCQAAZwAAAAIAAAAAAAAAAAAFAAAAB25ld0Jhc2UJAAACAAAAAQIAAAAqVHggbGVhZCB0byBiYXNlIGFzc2V0IHJlc2VydmUgPD0gMCwgcmV2ZXJ0CQAFFgAAAAQJAABkAAAAAgkBAAAABnF0QXN0UgAAAAAFAAAAEV9xdW90ZUFzc2V0QW1vdW50BQAAAAduZXdCYXNlCQAAZAAAAAIJAQAAABF0b3RhbFBvc2l0aW9uU2l6ZQAAAAAFAAAAEF9iYXNlQXNzZXRBbW91bnQJAABkAAAAAgkBAAAAEmN1bXVsYXRpdmVOb3Rpb25hbAAAAAAFAAAAEV9xdW90ZUFzc2V0QW1vdW50BAAAAAhuZXdRdW90ZQkAAGUAAAACCQEAAAAGcXRBc3RSAAAAAAUAAAARX3F1b3RlQXNzZXRBbW91bnQDCQAAZwAAAAIAAAAAAAAAAAAFAAAACG5ld1F1b3RlCQAAAgAAAAECAAAAKlR4IGxlYWQgdG8gYmFzZSBxdW90ZSByZXNlcnZlIDw9IDAsIHJldmVydAkABRYAAAAEBQAAAAhuZXdRdW90ZQkAAGQAAAACCQEAAAAGYnNBc3RSAAAAAAUAAAAQX2Jhc2VBc3NldEFtb3VudAkAAGUAAAACCQEAAAARdG90YWxQb3NpdGlvblNpemUAAAAABQAAABBfYmFzZUFzc2V0QW1vdW50CQAAZQAAAAIJAQAAABJjdW11bGF0aXZlTm90aW9uYWwAAAAABQAAABFfcXVvdGVBc3NldEFtb3VudAEAAAAJc3dhcElucHV0AAAAAgAAAAZfaXNBZGQAAAARX3F1b3RlQXNzZXRBbW91bnQEAAAAB19xdEFzdFIJAQAAAAZxdEFzdFIAAAAABAAAAAdfYnNBc3RSCQEAAAAGYnNBc3RSAAAAAAQAAAALcHJpY2VCZWZvcmUJAQAAAARkaXZkAAAAAgUAAAAHX3F0QXN0UgUAAAAHX2JzQXN0UgQAAAAnYW1vdW50QmFzZUFzc2V0Qm91Z2h0V2l0aG91dFByaWNlSW1wYWN0CQEAAAAEbXVsZAAAAAIFAAAAEV9xdW90ZUFzc2V0QW1vdW50BQAAAAtwcmljZUJlZm9yZQQAAAABawkBAAAABG11bGQAAAACBQAAAAdfcXRBc3RSBQAAAAdfYnNBc3RSBAAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyAwUAAAAGX2lzQWRkCQAAZAAAAAIFAAAAB19xdEFzdFIFAAAAEV9xdW90ZUFzc2V0QW1vdW50CQAAZQAAAAIFAAAAB19xdEFzdFIFAAAAEV9xdW90ZUFzc2V0QW1vdW50BAAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIJAQAAAARkaXZkAAAAAgUAAAABawUAAAAWcXVvdGVBc3NldFJlc2VydmVBZnRlcgQAAAAYYW1vdW50QmFzZUFzc2V0Qm91Z2h0QWJzCQEAAAADYWJzAAAAAQkAAGUAAAACBQAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAB19ic0FzdFIEAAAAFWFtb3VudEJhc2VBc3NldEJvdWdodAMFAAAABl9pc0FkZAUAAAAYYW1vdW50QmFzZUFzc2V0Qm91Z2h0QWJzCQEAAAABLQAAAAEFAAAAGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwQAAAALcHJpY2VJbXBhY3QJAABpAAAAAgkAAGUAAAACBQAAACdhbW91bnRCYXNlQXNzZXRCb3VnaHRXaXRob3V0UHJpY2VJbXBhY3QFAAAAGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwUAAAAnYW1vdW50QmFzZUFzc2V0Qm91Z2h0V2l0aG91dFByaWNlSW1wYWN0BAAAABNtYXhQcmljZUltcGFjdFZhbHVlCQEAAAAObWF4UHJpY2VJbXBhY3QAAAAAAwkAAGYAAAACBQAAAAtwcmljZUltcGFjdAUAAAATbWF4UHJpY2VJbXBhY3RWYWx1ZQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAA1QcmljZSBpbXBhY3QgCQABpAAAAAEFAAAAC3ByaWNlSW1wYWN0AgAAABQgPiBtYXggcHJpY2UgaW1wYWN0IAkAAaQAAAABBQAAABNtYXhQcmljZUltcGFjdFZhbHVlBAAAAA0kdDAxMjE1NDEyMzU3CQEAAAANdXBkYXRlUmVzZXJ2ZQAAAAMFAAAABl9pc0FkZAUAAAARX3F1b3RlQXNzZXRBbW91bnQFAAAAGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwQAAAAXcXVvdGVBc3NldFJlc2VydmVBZnRlcjEIBQAAAA0kdDAxMjE1NDEyMzU3AAAAAl8xBAAAABZiYXNlQXNzZXRSZXNlcnZlQWZ0ZXIxCAUAAAANJHQwMTIxNTQxMjM1NwAAAAJfMgQAAAAXdG90YWxQb3NpdGlvblNpemVBZnRlcjEIBQAAAA0kdDAxMjE1NDEyMzU3AAAAAl8zBAAAABhjdW11bGF0aXZlTm90aW9uYWxBZnRlcjEIBQAAAA0kdDAxMjE1NDEyMzU3AAAAAl80CQAFFwAAAAUFAAAAFWFtb3VudEJhc2VBc3NldEJvdWdodAUAAAAXcXVvdGVBc3NldFJlc2VydmVBZnRlcjEFAAAAFmJhc2VBc3NldFJlc2VydmVBZnRlcjEFAAAAF3RvdGFsUG9zaXRpb25TaXplQWZ0ZXIxBQAAABhjdW11bGF0aXZlTm90aW9uYWxBZnRlcjEBAAAAImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQAAAAEAAAAEF9vbGRQb3NpdGlvblNpemUAAAASX29sZFBvc2l0aW9uTWFyZ2luAAAAJV9vbGRQb3NpdGlvbkN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAAMX21hcmdpbkRlbHRhBAAAAA5mdW5kaW5nUGF5bWVudAMJAQAAAAIhPQAAAAIFAAAAEF9vbGRQb3NpdGlvblNpemUAAAAAAAAAAAAEAAAAIF9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uCQEAAAAfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAAAAEFAAAAEF9vbGRQb3NpdGlvblNpemUJAQAAAARtdWxkAAAAAgkAAGUAAAACBQAAACBfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUAAAAlX29sZFBvc2l0aW9uQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUAAAAQX29sZFBvc2l0aW9uU2l6ZQAAAAAAAAAAAAQAAAAMc2lnbmVkTWFyZ2luCQAAZAAAAAIJAABlAAAAAgUAAAAMX21hcmdpbkRlbHRhBQAAAA5mdW5kaW5nUGF5bWVudAUAAAASX29sZFBvc2l0aW9uTWFyZ2luBAAAAA0kdDAxMzEwNDEzMjMxAwkAAGYAAAACAAAAAAAAAAAABQAAAAxzaWduZWRNYXJnaW4JAAUUAAAAAgAAAAAAAAAAAAkBAAAAA2FicwAAAAEFAAAADHNpZ25lZE1hcmdpbgkABRQAAAACCQEAAAADYWJzAAAAAQUAAAAMc2lnbmVkTWFyZ2luAAAAAAAAAAAABAAAAAxyZW1haW5NYXJnaW4IBQAAAA0kdDAxMzEwNDEzMjMxAAAAAl8xBAAAAAdiYWREZWJ0CAUAAAANJHQwMTMxMDQxMzIzMQAAAAJfMgkABRUAAAADBQAAAAxyZW1haW5NYXJnaW4FAAAAB2JhZERlYnQFAAAADmZ1bmRpbmdQYXltZW50AQAAAApzd2FwT3V0cHV0AAAAAgAAAAZfaXNBZGQAAAAQX2Jhc2VBc3NldEFtb3VudAQAAAASX3F1b3RlQXNzZXRSZXNlcnZlCQEAAAAGcXRBc3RSAAAAAAQAAAARX2Jhc2VBc3NldFJlc2VydmUJAQAAAAZic0FzdFIAAAAAAwkAAAAAAAACBQAAABBfYmFzZUFzc2V0QW1vdW50AAAAAAAAAAAACQAAAgAAAAECAAAAGUludmFsaWQgYmFzZSBhc3NldCBhbW91bnQEAAAAAWsJAQAAAARtdWxkAAAAAgUAAAASX3F1b3RlQXNzZXRSZXNlcnZlBQAAABFfYmFzZUFzc2V0UmVzZXJ2ZQQAAAAYYmFzZUFzc2V0UG9vbEFtb3VudEFmdGVyAwUAAAAGX2lzQWRkCQAAZAAAAAIFAAAAEV9iYXNlQXNzZXRSZXNlcnZlBQAAABBfYmFzZUFzc2V0QW1vdW50CQAAZQAAAAIFAAAAEV9iYXNlQXNzZXRSZXNlcnZlBQAAABBfYmFzZUFzc2V0QW1vdW50BAAAAA9xdW90ZUFzc2V0QWZ0ZXIJAQAAAARkaXZkAAAAAgUAAAABawUAAAAYYmFzZUFzc2V0UG9vbEFtb3VudEFmdGVyBAAAAA5xdW90ZUFzc2V0U29sZAkBAAAAA2FicwAAAAEJAABlAAAAAgUAAAAPcXVvdGVBc3NldEFmdGVyBQAAABJfcXVvdGVBc3NldFJlc2VydmUEAAAADSR0MDE0MDY5MTQyNjIJAQAAAA11cGRhdGVSZXNlcnZlAAAAAwkBAAAAASEAAAABBQAAAAZfaXNBZGQFAAAADnF1b3RlQXNzZXRTb2xkBQAAABBfYmFzZUFzc2V0QW1vdW50BAAAABdxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyMQgFAAAADSR0MDE0MDY5MTQyNjIAAAACXzEEAAAAFmJhc2VBc3NldFJlc2VydmVBZnRlcjEIBQAAAA0kdDAxNDA2OTE0MjYyAAAAAl8yBAAAABd0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyMQgFAAAADSR0MDE0MDY5MTQyNjIAAAACXzMEAAAAGGN1bXVsYXRpdmVOb3Rpb25hbEFmdGVyMQgFAAAADSR0MDE0MDY5MTQyNjIAAAACXzQJAAUZAAAABwUAAAAOcXVvdGVBc3NldFNvbGQFAAAAF3F1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIxBQAAABZiYXNlQXNzZXRSZXNlcnZlQWZ0ZXIxBQAAABd0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyMQUAAAAYY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIxCQAAZQAAAAIJAQAAABV0b3RhbExvbmdQb3NpdGlvblNpemUAAAAAAwUAAAAGX2lzQWRkCQEAAAADYWJzAAAAAQUAAAAQX2Jhc2VBc3NldEFtb3VudAAAAAAAAAAAAAkAAGUAAAACCQEAAAAWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAAAAADCQEAAAABIQAAAAEFAAAABl9pc0FkZAkBAAAAA2FicwAAAAEFAAAAEF9iYXNlQXNzZXRBbW91bnQAAAAAAAAAAAABAAAAEmdldE9yYWNsZVR3YXBQcmljZQAAAAAEAAAABm9yYWNsZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAABHRoaXMFAAAABWtfb3JhAgAAAAAEAAAACHByaWNlS2V5CQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACBQAAAAR0aGlzBQAAAAlrX29yYV9rZXkEAAAACGJsb2NrS2V5CQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACBQAAAAR0aGlzBQAAAA9rX29yYV9ibG9ja19rZXkEAAAACWxhc3RWYWx1ZQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAGb3JhY2xlBQAAAAhwcmljZUtleQUAAAAJbGFzdFZhbHVlAQAAAAxnZXRTcG90UHJpY2UAAAAABAAAABJfcXVvdGVBc3NldFJlc2VydmUJAQAAAAZxdEFzdFIAAAAABAAAABFfYmFzZUFzc2V0UmVzZXJ2ZQkBAAAABmJzQXN0UgAAAAAJAQAAAARkaXZkAAAAAgUAAAASX3F1b3RlQXNzZXRSZXNlcnZlBQAAABFfYmFzZUFzc2V0UmVzZXJ2ZQEAAAAWaXNPdmVyRmx1Y3R1YXRpb25MaW1pdAAAAAAEAAAAC29yYWNsZVByaWNlCQEAAAASZ2V0T3JhY2xlVHdhcFByaWNlAAAAAAQAAAAMY3VycmVudFByaWNlCQEAAAAMZ2V0U3BvdFByaWNlAAAAAAkAAGYAAAACCQEAAAAEZGl2ZAAAAAIJAQAAAANhYnMAAAABCQAAZQAAAAIFAAAAC29yYWNsZVByaWNlBQAAAAxjdXJyZW50UHJpY2UFAAAAC29yYWNsZVByaWNlCQEAAAALc3ByZWFkTGltaXQAAAAAAQAAACNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAAAAAIAAAAHX3RyYWRlcgAAAAdfb3B0aW9uBAAAAA0kdDAxNTg5NDE2MDIyCQEAAAALZ2V0UG9zaXRpb24AAAABBQAAAAdfdHJhZGVyBAAAAAxwb3NpdGlvblNpemUIBQAAAA0kdDAxNTg5NDE2MDIyAAAAAl8xBAAAAA5wb3NpdGlvbk1hcmdpbggFAAAADSR0MDE1ODk0MTYwMjIAAAACXzIEAAAAFHBvc2l0aW9uT3Blbk5vdGlvbmFsCAUAAAANJHQwMTU4OTQxNjAyMgAAAAJfMwQAAAARcG9zaXRpb25Mc3RVcGRDUEYIBQAAAA0kdDAxNTg5NDE2MDIyAAAAAl80BAAAAA9wb3NpdGlvblNpemVBYnMJAQAAAANhYnMAAAABBQAAAAxwb3NpdGlvblNpemUDCQAAAAAAAAIFAAAAD3Bvc2l0aW9uU2l6ZUFicwAAAAAAAAAAAAkAAAIAAAABAgAAABVJbnZhbGlkIHBvc2l0aW9uIHNpemUEAAAAB2lzU2hvcnQJAABmAAAAAgAAAAAAAAAAAAUAAAAMcG9zaXRpb25TaXplBAAAABBwb3NpdGlvbk5vdGlvbmFsAwkAAAAAAAACBQAAAAdfb3B0aW9uBQAAAA9QTkxfT1BUSU9OX1NQT1QEAAAADSR0MDE2MjY5MTYzNzYJAQAAAApzd2FwT3V0cHV0AAAAAgkBAAAAASEAAAABBQAAAAdpc1Nob3J0BQAAAA9wb3NpdGlvblNpemVBYnMEAAAAE291dFBvc2l0aW9uTm90aW9uYWwIBQAAAA0kdDAxNjI2OTE2Mzc2AAAAAl8xBAAAAAJ4MQgFAAAADSR0MDE2MjY5MTYzNzYAAAACXzIEAAAAAngyCAUAAAANJHQwMTYyNjkxNjM3NgAAAAJfMwQAAAACeDMIBQAAAA0kdDAxNjI2OTE2Mzc2AAAAAl80BQAAABNvdXRQb3NpdGlvbk5vdGlvbmFsCQEAAAAEbXVsZAAAAAIFAAAAD3Bvc2l0aW9uU2l6ZUFicwkBAAAAEmdldE9yYWNsZVR3YXBQcmljZQAAAAAEAAAADXVucmVhbGl6ZWRQbmwDBQAAAAdpc1Nob3J0CQAAZQAAAAIFAAAAFHBvc2l0aW9uT3Blbk5vdGlvbmFsBQAAABBwb3NpdGlvbk5vdGlvbmFsCQAAZQAAAAIFAAAAEHBvc2l0aW9uTm90aW9uYWwFAAAAFHBvc2l0aW9uT3Blbk5vdGlvbmFsCQAFFAAAAAIFAAAAEHBvc2l0aW9uTm90aW9uYWwFAAAADXVucmVhbGl6ZWRQbmwBAAAAD2NhbGNNYXJnaW5SYXRpbwAAAAMAAAANX3JlbWFpbk1hcmdpbgAAAAhfYmFkRGVidAAAABFfcG9zaXRpb25Ob3Rpb25hbAkBAAAABGRpdmQAAAACCQAAZQAAAAIFAAAADV9yZW1haW5NYXJnaW4FAAAACF9iYWREZWJ0BQAAABFfcG9zaXRpb25Ob3Rpb25hbAEAAAAWZ2V0TWFyZ2luUmF0aW9CeU9wdGlvbgAAAAIAAAAHX3RyYWRlcgAAAAdfb3B0aW9uBAAAAA0kdDAxNzA0NjE3MTU3CQEAAAALZ2V0UG9zaXRpb24AAAABBQAAAAdfdHJhZGVyBAAAAAxwb3NpdGlvblNpemUIBQAAAA0kdDAxNzA0NjE3MTU3AAAAAl8xBAAAAA5wb3NpdGlvbk1hcmdpbggFAAAADSR0MDE3MDQ2MTcxNTcAAAACXzIEAAAAA3BvbggFAAAADSR0MDE3MDQ2MTcxNTcAAAACXzMEAAAAEXBvc2l0aW9uTHN0VXBkQ1BGCAUAAAANJHQwMTcwNDYxNzE1NwAAAAJfNAQAAAANJHQwMTcxNjMxNzI1NgkBAAAAI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAAAAAgUAAAAHX3RyYWRlcgUAAAAHX29wdGlvbgQAAAAQcG9zaXRpb25Ob3Rpb25hbAgFAAAADSR0MDE3MTYzMTcyNTYAAAACXzEEAAAADXVucmVhbGl6ZWRQbmwIBQAAAA0kdDAxNzE2MzE3MjU2AAAAAl8yBAAAAA0kdDAxNzI2MTE3NDI3CQEAAAAiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAAAAAQFAAAADHBvc2l0aW9uU2l6ZQUAAAAOcG9zaXRpb25NYXJnaW4FAAAAEXBvc2l0aW9uTHN0VXBkQ1BGBQAAAA11bnJlYWxpemVkUG5sBAAAAAxyZW1haW5NYXJnaW4IBQAAAA0kdDAxNzI2MTE3NDI3AAAAAl8xBAAAAAdiYWREZWJ0CAUAAAANJHQwMTcyNjExNzQyNwAAAAJfMgkBAAAAD2NhbGNNYXJnaW5SYXRpbwAAAAMFAAAADHJlbWFpbk1hcmdpbgUAAAAHYmFkRGVidAUAAAAQcG9zaXRpb25Ob3Rpb25hbAEAAAAOZ2V0TWFyZ2luUmF0aW8AAAABAAAAB190cmFkZXIJAQAAABZnZXRNYXJnaW5SYXRpb0J5T3B0aW9uAAAAAgUAAAAHX3RyYWRlcgUAAAAPUE5MX09QVElPTl9TUE9UAQAAABVpbnRlcm5hbENsb3NlUG9zaXRpb24AAAABAAAAB190cmFkZXIEAAAADSR0MDE3NzQzMTc4NzEJAQAAAAtnZXRQb3NpdGlvbgAAAAEFAAAAB190cmFkZXIEAAAADHBvc2l0aW9uU2l6ZQgFAAAADSR0MDE3NzQzMTc4NzEAAAACXzEEAAAADnBvc2l0aW9uTWFyZ2luCAUAAAANJHQwMTc3NDMxNzg3MQAAAAJfMgQAAAAUcG9zaXRpb25PcGVuTm90aW9uYWwIBQAAAA0kdDAxNzc0MzE3ODcxAAAAAl8zBAAAABFwb3NpdGlvbkxzdFVwZENQRggFAAAADSR0MDE3NzQzMTc4NzEAAAACXzQEAAAADSR0MDE3ODc3MTc5NjQJAQAAACNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAAAAAIFAAAAB190cmFkZXIFAAAAD1BOTF9PUFRJT05fU1BPVAQAAAACeDEIBQAAAA0kdDAxNzg3NzE3OTY0AAAAAl8xBAAAAA11bnJlYWxpemVkUG5sCAUAAAANJHQwMTc4NzcxNzk2NAAAAAJfMgQAAAANJHQwMTc5NjkxODEzNwkBAAAAImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQAAAAEBQAAAAxwb3NpdGlvblNpemUFAAAADnBvc2l0aW9uTWFyZ2luBQAAABFwb3NpdGlvbkxzdFVwZENQRgUAAAANdW5yZWFsaXplZFBubAQAAAAMcmVtYWluTWFyZ2luCAUAAAANJHQwMTc5NjkxODEzNwAAAAJfMQQAAAAHYmFkRGVidAgFAAAADSR0MDE3OTY5MTgxMzcAAAACXzIEAAAAFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQkBAAAAAS0AAAABBQAAAAxwb3NpdGlvblNpemUEAAAAC3JlYWxpemVkUG5sBQAAAA11bnJlYWxpemVkUG5sBAAAAA1tYXJnaW5Ub1ZhdWx0CQEAAAABLQAAAAEFAAAADHJlbWFpbk1hcmdpbgQAAAANJHQwMTgyNjQxODU0NQkBAAAACnN3YXBPdXRwdXQAAAACCQAAZgAAAAIFAAAADHBvc2l0aW9uU2l6ZQAAAAAAAAAAAAkBAAAAA2FicwAAAAEFAAAADHBvc2l0aW9uU2l6ZQQAAAAZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAgFAAAADSR0MDE4MjY0MTg1NDUAAAACXzEEAAAAFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQAAAA0kdDAxODI2NDE4NTQ1AAAAAl8yBAAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQAAAA0kdDAxODI2NDE4NTQ1AAAAAl8zBAAAABZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUAAAANJHQwMTgyNjQxODU0NQAAAAJfNAQAAAAXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIIBQAAAA0kdDAxODI2NDE4NTQ1AAAAAl81BAAAAA50b3RhbExvbmdBZnRlcggFAAAADSR0MDE4MjY0MTg1NDUAAAACXzYEAAAAD3RvdGFsU2hvcnRBZnRlcggFAAAADSR0MDE4MjY0MTg1NDUAAAACXzcEAAAAGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIJAABlAAAAAgkBAAAAFG9wZW5JbnRlcmVzdE5vdGlvbmFsAAAAAAUAAAAUcG9zaXRpb25PcGVuTm90aW9uYWwJAAUeAAAADAUAAAAVZXhjaGFuZ2VkUG9zaXRpb25TaXplBQAAAAdiYWREZWJ0BQAAAAtyZWFsaXplZFBubAUAAAANbWFyZ2luVG9WYXVsdAUAAAAWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBQAAABdjdW11bGF0aXZlTm90aW9uYWxBZnRlcgUAAAAZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgUAAAAZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAUAAAAOdG90YWxMb25nQWZ0ZXIFAAAAD3RvdGFsU2hvcnRBZnRlcgEAAAAQZ2V0VHdhcFNwb3RQcmljZQAAAAAEAAAACG1pbnV0ZUlkCQAAaQAAAAIJAABpAAAAAggFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAAAAAAAAAAA+gAAAAAAAAAADwEAAAADXN0YXJ0TWludXRlSWQJAABlAAAAAgUAAAAIbWludXRlSWQFAAAADVRXQVBfSU5URVJWQUwEAAAAB2xpc3RTdHIJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAANa19sYXN0RGF0YVN0cgIAAAAABAAAAARsaXN0CQAEtQAAAAIFAAAAB2xpc3RTdHICAAAAASwKAQAAAAhmaWx0ZXJGbgAAAAIAAAALYWNjdW11bGF0b3IAAAAEbmV4dAMJAABnAAAAAgUAAAANc3RhcnRNaW51dGVJZAkBAAAADXBhcnNlSW50VmFsdWUAAAABBQAAAARuZXh0CQAETQAAAAIFAAAAC2FjY3VtdWxhdG9yCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEFAAAABG5leHQFAAAAC2FjY3VtdWxhdG9yBAAAAAVsaXN0RgoAAAAAAiRsBQAAAARsaXN0CgAAAAACJHMJAAGQAAAAAQUAAAACJGwKAAAAAAUkYWNjMAUAAAADbmlsCgEAAAAFJGYwXzEAAAACAAAAAiRhAAAAAiRpAwkAAGcAAAACBQAAAAIkaQUAAAACJHMFAAAAAiRhCQEAAAAIZmlsdGVyRm4AAAACBQAAAAIkYQkAAZEAAAACBQAAAAIkbAUAAAACJGkKAQAAAAUkZjBfMgAAAAIAAAACJGEAAAACJGkDCQAAZwAAAAIFAAAAAiRpBQAAAAIkcwUAAAACJGEJAAACAAAAAQIAAAAUTGlzdCBzaXplIGV4Y2VlZHMgMjAJAQAAAAUkZjBfMgAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIJAQAAAAUkZjBfMQAAAAIFAAAABSRhY2MwAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAACAAAAAAAAAAADAAAAAAAAAAAEAAAAAAAAAAAFAAAAAAAAAAAGAAAAAAAAAAAHAAAAAAAAAAAIAAAAAAAAAAAJAAAAAAAAAAAKAAAAAAAAAAALAAAAAAAAAAAMAAAAAAAAAAANAAAAAAAAAAAOAAAAAAAAAAAPAAAAAAAAAAAQAAAAAAAAAAARAAAAAAAAAAASAAAAAAAAAAATAAAAAAAAAAAUBAAAAAhtYXhJbmRleAMJAABmAAAAAgkAAZAAAAABBQAAAAVsaXN0RgAAAAAAAAAAAAkAAZYAAAABBQAAAAVsaXN0RgkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAABGxpc3QAAAAAAAAAAAAEAAAADGxhc3RNaW51dGVJZAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAA5rX2xhc3RNaW51dGVJZAAAAAAAAAAAAAQAAAAWZW5kTGFzdEN1bXVsYXRpdmVQcmljZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQABLAAAAAIJAAEsAAAAAgUAAAAda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UCAAAAAV8JAAGkAAAAAQUAAAAMbGFzdE1pbnV0ZUlkAAAAAAAAAAAABAAAAAxlbmRMYXN0UHJpY2UJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkAASwAAAACCQABLAAAAAIFAAAAE2tfdHdhcERhdGFMYXN0UHJpY2UCAAAAAV8JAAGkAAAAAQUAAAAMbGFzdE1pbnV0ZUlkAAAAAAAAAAAABAAAABJub3dDdW11bGF0aXZlUHJpY2UJAABkAAAAAgUAAAAWZW5kTGFzdEN1bXVsYXRpdmVQcmljZQkAAGgAAAACCQAAZQAAAAIFAAAACG1pbnV0ZUlkBQAAAAxsYXN0TWludXRlSWQFAAAADGVuZExhc3RQcmljZQQAAAAYc3RhcnRMYXN0Q3VtdWxhdGl2ZVByaWNlCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAAEsAAAAAgkAASwAAAACBQAAAB1rX3R3YXBEYXRhTGFzdEN1bXVsYXRpdmVQcmljZQIAAAABXwkAAaQAAAABBQAAAAhtYXhJbmRleAAAAAAAAAAAAAQAAAAOc3RhcnRMYXN0UHJpY2UJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkAASwAAAACCQABLAAAAAIFAAAAE2tfdHdhcERhdGFMYXN0UHJpY2UCAAAAAV8JAAGkAAAAAQUAAAAIbWF4SW5kZXgAAAAAAAAAAAAEAAAAFHN0YXJ0Q3VtdWxhdGl2ZVByaWNlCQAAZAAAAAIFAAAAGHN0YXJ0TGFzdEN1bXVsYXRpdmVQcmljZQkAAGgAAAACCQAAZQAAAAIFAAAADXN0YXJ0TWludXRlSWQFAAAACG1heEluZGV4BQAAAA5zdGFydExhc3RQcmljZQkAAGkAAAACCQAAZQAAAAIFAAAAEm5vd0N1bXVsYXRpdmVQcmljZQUAAAAUc3RhcnRDdW11bGF0aXZlUHJpY2UFAAAADVRXQVBfSU5URVJWQUwBAAAADnVwZGF0ZVNldHRpbmdzAAAABwAAABBfaW5pdE1hcmdpblJhdGlvAAAABF9tbXIAAAAUX2xpcXVpZGF0aW9uRmVlUmF0aW8AAAAOX2Z1bmRpbmdQZXJpb2QAAAAEX2ZlZQAAAAxfc3ByZWFkTGltaXQAAAAPX21heFByaWNlSW1wYWN0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABFrX2luaXRNYXJnaW5SYXRpbwUAAAAQX2luaXRNYXJnaW5SYXRpbwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAYa19tYWludGVuYW5jZU1hcmdpblJhdGlvBQAAAARfbW1yCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVrX2xpcXVpZGF0aW9uRmVlUmF0aW8FAAAAFF9saXF1aWRhdGlvbkZlZVJhdGlvCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA9rX2Z1bmRpbmdQZXJpb2QFAAAADl9mdW5kaW5nUGVyaW9kCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAVrX2ZlZQUAAAAEX2ZlZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAANa19zcHJlYWRMaW1pdAUAAAAMX3NwcmVhZExpbWl0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABBrX21heFByaWNlSW1wYWN0BQAAAA9fbWF4UHJpY2VJbXBhY3QFAAAAA25pbAEAAAANdXBkYXRlRnVuZGluZwAAAAUAAAARX25leHRGdW5kaW5nQmxvY2sAAAAkX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAAAJV9sYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAAQX2xvbmdGdW5kaW5nUmF0ZQAAABFfc2hvcnRGdW5kaW5nUmF0ZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASa19uZXh0RnVuZGluZ0Jsb2NrBQAAABFfbmV4dEZ1bmRpbmdCbG9jawkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAla19sYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUAAAAkX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAACZrX2xhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUAAAAlX2xhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARa19sb25nRnVuZGluZ1JhdGUFAAAAEF9sb25nRnVuZGluZ1JhdGUJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEmtfc2hvcnRGdW5kaW5nUmF0ZQUAAAARX3Nob3J0RnVuZGluZ1JhdGUFAAAAA25pbAEAAAAOdXBkYXRlUG9zaXRpb24AAAAFAAAACF9hZGRyZXNzAAAABV9zaXplAAAAB19tYXJnaW4AAAANX29wZW5Ob3Rpb25hbAAAACBfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAOa19wb3NpdGlvblNpemUFAAAACF9hZGRyZXNzBQAAAAVfc2l6ZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAQa19wb3NpdGlvbk1hcmdpbgUAAAAIX2FkZHJlc3MFAAAAB19tYXJnaW4JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAAFmtfcG9zaXRpb25PcGVuTm90aW9uYWwFAAAACF9hZGRyZXNzBQAAAA1fb3Blbk5vdGlvbmFsCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAOdG9Db21wb3NpdGVLZXkAAAACBQAAAC5rX3Bvc2l0aW9uTGFzdFVwZGF0ZWRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uBQAAAAhfYWRkcmVzcwUAAAAgX2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FAAAAA25pbAEAAAAKYXBwZW5kVHdhcAAAAAEAAAAFcHJpY2UEAAAACG1pbnV0ZUlkCQAAaQAAAAIJAABpAAAAAggFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAAAAAAAAAAA+gAAAAAAAAAADwEAAAAEHByZXZpb3VzTWludXRlSWQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAOa19sYXN0TWludXRlSWQAAAAAAAAAAAADCQAAZgAAAAIFAAAAEHByZXZpb3VzTWludXRlSWQFAAAACG1pbnV0ZUlkCQAAAgAAAAECAAAAEVRXQVAgb3V0LW9mLW9yZGVyBAAAAAxsYXN0TWludXRlSWQDCQAAAAAAAAIFAAAAEHByZXZpb3VzTWludXRlSWQAAAAAAAAAAAAFAAAACG1pbnV0ZUlkBQAAABBwcmV2aW91c01pbnV0ZUlkAwkAAGYAAAACBQAAAAhtaW51dGVJZAUAAAAQcHJldmlvdXNNaW51dGVJZAQAAAATcHJldkN1bXVsYXRpdmVQcmljZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQABLAAAAAIJAAEsAAAAAgUAAAAda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UCAAAAAV8JAAGkAAAAAQUAAAAQcHJldmlvdXNNaW51dGVJZAAAAAAAAAAAAAQAAAAJcHJldlByaWNlCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAAEsAAAAAgkAASwAAAACBQAAABNrX3R3YXBEYXRhTGFzdFByaWNlAgAAAAFfCQABpAAAAAEFAAAAEHByZXZpb3VzTWludXRlSWQFAAAABXByaWNlBAAAABNsYXN0Q3VtdWxhdGl2ZVByaWNlCQAAZAAAAAIFAAAAE3ByZXZDdW11bGF0aXZlUHJpY2UJAABoAAAAAgkAAGUAAAACBQAAAAhtaW51dGVJZAUAAAAMbGFzdE1pbnV0ZUlkBQAAAAlwcmV2UHJpY2UEAAAABGxpc3QJAQAAAAtwdXNoVG9RdWV1ZQAAAAMJAQAAAAlzdHJUb0xpc3QAAAABCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAADWtfbGFzdERhdGFTdHICAAAAAAUAAAANVFdBUF9JTlRFUlZBTAkAAaQAAAABBQAAAAhtaW51dGVJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UJAAGkAAAAAQUAAAAIbWludXRlSWQFAAAAE2xhc3RDdW11bGF0aXZlUHJpY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAAE2tfdHdhcERhdGFMYXN0UHJpY2UJAAGkAAAAAQUAAAAIbWludXRlSWQFAAAABXByaWNlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAOdG9Db21wb3NpdGVLZXkAAAACBQAAABprX3R3YXBEYXRhUHJldmlvdXNNaW51dGVJZAkAAaQAAAABBQAAAAhtaW51dGVJZAUAAAAQcHJldmlvdXNNaW51dGVJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAOa19sYXN0TWludXRlSWQFAAAACG1pbnV0ZUlkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADWtfbGFzdERhdGFTdHIJAQAAAAlsaXN0VG9TdHIAAAABBQAAAARsaXN0BQAAAANuaWwEAAAAGHR3YXBEYXRhUHJldmlvdXNNaW51dGVJZAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAOdG9Db21wb3NpdGVLZXkAAAACBQAAABprX3R3YXBEYXRhUHJldmlvdXNNaW51dGVJZAkAAaQAAAABBQAAAAhtaW51dGVJZAAAAAAAAAAAAAQAAAATcHJldkN1bXVsYXRpdmVQcmljZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAOdG9Db21wb3NpdGVLZXkAAAACBQAAAB1rX3R3YXBEYXRhTGFzdEN1bXVsYXRpdmVQcmljZQkAAaQAAAABBQAAABh0d2FwRGF0YVByZXZpb3VzTWludXRlSWQAAAAAAAAAAAAEAAAACXByZXZQcmljZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAOdG9Db21wb3NpdGVLZXkAAAACBQAAABNrX3R3YXBEYXRhTGFzdFByaWNlCQABpAAAAAEFAAAAGHR3YXBEYXRhUHJldmlvdXNNaW51dGVJZAUAAAAFcHJpY2UEAAAAE2xhc3RDdW11bGF0aXZlUHJpY2UJAABkAAAAAgUAAAATcHJldkN1bXVsYXRpdmVQcmljZQkAAGgAAAACCQAAZQAAAAIFAAAACG1pbnV0ZUlkBQAAABh0d2FwRGF0YVByZXZpb3VzTWludXRlSWQFAAAACXByZXZQcmljZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UJAAGkAAAAAQUAAAAIbWludXRlSWQFAAAAE2xhc3RDdW11bGF0aXZlUHJpY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAAE2tfdHdhcERhdGFMYXN0UHJpY2UJAAGkAAAAAQUAAAAIbWludXRlSWQFAAAABXByaWNlBQAAAANuaWwBAAAACXVwZGF0ZUFtbQAAAAcAAAAHX3F0QXN0UgAAAAdfYnNBc3RSAAAAF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyAAAAGF9jdW11bGF0aXZlTm90aW9uYWxBZnRlcgAAABVfb3BlbkludGVyZXN0Tm90aW9uYWwAAAAWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAAABdfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQMJAQAAAAIhPQAAAAIJAABlAAAAAgUAAAAWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQUAAAAXX3RvdGFsU2hvcnRQb3NpdGlvblNpemUFAAAAF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABhJbnZhbGlkIEFNTSBzdGF0ZSBkYXRhOiAJAAGkAAAAAQUAAAAWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQIAAAAEICsgIAkAAaQAAAABBQAAABdfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQIAAAAEICE9IAkAAaQAAAABBQAAABdfdG90YWxQb3NpdGlvblNpemVBZnRlcgkABE4AAAACCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABNrX3F1b3RlQXNzZXRSZXNlcnZlBQAAAAdfcXRBc3RSCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJrX2Jhc2VBc3NldFJlc2VydmUFAAAAB19ic0FzdFIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAE2tfdG90YWxQb3NpdGlvblNpemUFAAAAF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABRrX2N1bXVsYXRpdmVOb3Rpb25hbAUAAAAYX2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABZrX29wZW5JbnRlcmVzdE5vdGlvbmFsBQAAABVfb3BlbkludGVyZXN0Tm90aW9uYWwJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAF2tfdG90YWxMb25nUG9zaXRpb25TaXplBQAAABZfdG90YWxMb25nUG9zaXRpb25TaXplCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABhrX3RvdGFsU2hvcnRQb3NpdGlvblNpemUFAAAAF190b3RhbFNob3J0UG9zaXRpb25TaXplBQAAAANuaWwJAQAAAAphcHBlbmRUd2FwAAAAAQkBAAAABGRpdmQAAAACBQAAAAdfcXRBc3RSBQAAAAdfYnNBc3RSAQAAAA5kZWxldGVQb3NpdGlvbgAAAAEAAAAIX2FkZHJlc3MJAARMAAAAAgkBAAAAC0RlbGV0ZUVudHJ5AAAAAQkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAOa19wb3NpdGlvblNpemUFAAAACF9hZGRyZXNzCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAAEGtfcG9zaXRpb25NYXJnaW4FAAAACF9hZGRyZXNzCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAAFmtfcG9zaXRpb25PcGVuTm90aW9uYWwFAAAACF9hZGRyZXNzCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAALmtfcG9zaXRpb25MYXN0VXBkYXRlZEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FAAAACF9hZGRyZXNzBQAAAANuaWwBAAAACHdpdGhkcmF3AAAAAgAAAAhfYWRkcmVzcwAAAAdfYW1vdW50BAAAAAdiYWxhbmNlCQAD8AAAAAIFAAAABHRoaXMJAQAAAApxdW90ZUFzc2V0AAAAAAMJAABmAAAAAgUAAAAHX2Ftb3VudAUAAAAHYmFsYW5jZQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABNVbmFibGUgdG8gd2l0aGRyYXcgCQABpAAAAAEFAAAAB19hbW91bnQCAAAAFyBmcm9tIGNvbnRyYWN0IGJhbGFuY2UgCQABpAAAAAEFAAAAB2JhbGFuY2UJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAAIX2FkZHJlc3MFAAAAB19hbW91bnQJAQAAAApxdW90ZUFzc2V0AAAAAAUAAAADbmlsAQAAAA11cGRhdGVCYWxhbmNlAAAAAQAAAAFpAwkAAGYAAAACAAAAAAAAAAAABQAAAAFpCQAAAgAAAAECAAAAB0JhbGFuY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAACWtfYmFsYW5jZQUAAAABaQUAAAADbmlsAQAAAAt0cmFuc2ZlckZlZQAAAAEAAAABaQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCQEAAAAOc3Rha2luZ0FkZHJlc3MAAAAABQAAAAFpCQEAAAAKcXVvdGVBc3NldAAAAAAFAAAAA25pbAAAAA0AAAABaQEAAAAFcGF1c2UAAAAAAwkBAAAAAiE9AAAAAggFAAAAAWkAAAAGY2FsbGVyCQEAAAAMYWRtaW5BZGRyZXNzAAAAAAkAAAIAAAABAgAAABpJbnZhbGlkIHRvZ2dsZVBhdXNlIHBhcmFtcwkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAIa19wYXVzZWQGBQAAAANuaWwAAAABaQEAAAAHdW5wYXVzZQAAAAADCQEAAAACIT0AAAACCAUAAAABaQAAAAZjYWxsZXIJAQAAAAxhZG1pbkFkZHJlc3MAAAAACQAAAgAAAAECAAAAGkludmFsaWQgdG9nZ2xlUGF1c2UgcGFyYW1zCQAETAAAAAIJAQAAAAxCb29sZWFuRW50cnkAAAACBQAAAAhrX3BhdXNlZAcFAAAAA25pbAAAAAFpAQAAAA5jaGFuZ2VTZXR0aW5ncwAAAAcAAAAQX2luaXRNYXJnaW5SYXRpbwAAAARfbW1yAAAAFF9saXF1aWRhdGlvbkZlZVJhdGlvAAAADl9mdW5kaW5nUGVyaW9kAAAABF9mZWUAAAAMX3NwcmVhZExpbWl0AAAAD19tYXhQcmljZUltcGFjdAMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgkBAAAADGFkbWluQWRkcmVzcwAAAAAJAAACAAAAAQIAAAAdSW52YWxpZCBjaGFuZ2VTZXR0aW5ncyBwYXJhbXMJAQAAAA51cGRhdGVTZXR0aW5ncwAAAAcFAAAAEF9pbml0TWFyZ2luUmF0aW8FAAAABF9tbXIFAAAAFF9saXF1aWRhdGlvbkZlZVJhdGlvBQAAAA5fZnVuZGluZ1BlcmlvZAUAAAAEX2ZlZQUAAAAMX3NwcmVhZExpbWl0BQAAAA9fbWF4UHJpY2VJbXBhY3QAAAABaQEAAAAKaW5pdGlhbGl6ZQAAAAwAAAAHX3F0QXN0UgAAAAdfYnNBc3RSAAAADl9mdW5kaW5nUGVyaW9kAAAAEF9pbml0TWFyZ2luUmF0aW8AAAAEX21tcgAAABRfbGlxdWlkYXRpb25GZWVSYXRpbwAAAARfZmVlAAAAB19vcmFjbGUAAAAKX29yYWNsZUtleQAAAAxfY29vcmRpbmF0b3IAAAAMX3NwcmVhZExpbWl0AAAAD19tYXhQcmljZUltcGFjdAMDAwMDAwMDAwMJAABnAAAAAgAAAAAAAAAAAAUAAAAHX3F0QXN0UgYJAABnAAAAAgAAAAAAAAAAAAUAAAAHX2JzQXN0UgYJAABnAAAAAgAAAAAAAAAAAAUAAAAOX2Z1bmRpbmdQZXJpb2QGCQAAZwAAAAIAAAAAAAAAAAAFAAAAEF9pbml0TWFyZ2luUmF0aW8GCQAAZwAAAAIAAAAAAAAAAAAFAAAABF9tbXIGCQAAZwAAAAIAAAAAAAAAAAAFAAAAFF9saXF1aWRhdGlvbkZlZVJhdGlvBgkAAGcAAAACAAAAAAAAAAAABQAAAARfZmVlBgkAAGcAAAACAAAAAAAAAAAABQAAAAxfc3ByZWFkTGltaXQGCQAAZwAAAAIAAAAAAAAAAAAFAAAAD19tYXhQcmljZUltcGFjdAYJAQAAAAtpbml0aWFsaXplZAAAAAAJAAACAAAAAQIAAAAdSW52YWxpZCBpbml0aWFsaXplIHBhcmFtZXRlcnMJAAROAAAAAgkABE4AAAACCQAETgAAAAIJAAROAAAAAgkBAAAACXVwZGF0ZUFtbQAAAAcFAAAAB19xdEFzdFIFAAAAB19ic0FzdFIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAQAAAA51cGRhdGVTZXR0aW5ncwAAAAcFAAAAEF9pbml0TWFyZ2luUmF0aW8FAAAABF9tbXIFAAAAFF9saXF1aWRhdGlvbkZlZVJhdGlvBQAAAA5fZnVuZGluZ1BlcmlvZAUAAAAEX2ZlZQUAAAAMX3NwcmVhZExpbWl0BQAAAA9fbWF4UHJpY2VJbXBhY3QJAQAAAA11cGRhdGVGdW5kaW5nAAAABQkAAGQAAAACCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAUAAAAOX2Z1bmRpbmdQZXJpb2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAQAAAA11cGRhdGVCYWxhbmNlAAAAAQAAAAAAAAAAAAkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAANa19pbml0aWFsaXplZAYJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAFa19vcmEFAAAAB19vcmFjbGUJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAJa19vcmFfa2V5BQAAAApfb3JhY2xlS2V5CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAFGtfY29vcmRpbmF0b3JBZGRyZXNzBQAAAAxfY29vcmRpbmF0b3IFAAAAA25pbAAAAAFpAQAAABBkZWNyZWFzZVBvc2l0aW9uAAAAAwAAAAdfYW1vdW50AAAACV9sZXZlcmFnZQAAABNfbWluQmFzZUFzc2V0QW1vdW50AwMDAwMDCQAAZwAAAAIAAAAAAAAAAAAFAAAAB19hbW91bnQGAwkAAGYAAAACCQAAaAAAAAIAAAAAAAAAAAEFAAAADERFQ0lNQUxfVU5JVAUAAAAJX2xldmVyYWdlBgkAAGYAAAACBQAAAAlfbGV2ZXJhZ2UJAABoAAAAAgAAAAAAAAAAAwUAAAAMREVDSU1BTF9VTklUBgkBAAAAASEAAAABCQEAAAALaW5pdGlhbGl6ZWQAAAAABgkBAAAAASEAAAABCQEAAAAWcmVxdWlyZU1vcmVNYXJnaW5SYXRpbwAAAAMJAQAAAARkaXZkAAAAAgUAAAAMREVDSU1BTF9VTklUBQAAAAlfbGV2ZXJhZ2UJAQAAAA9pbml0TWFyZ2luUmF0aW8AAAAABgYJAQAAAAEhAAAAAQkBAAAAE3JlcXVpcmVPcGVuUG9zaXRpb24AAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgYJAQAAAAZwYXVzZWQAAAAACQAAAgAAAAECAAAAI0ludmFsaWQgZGVjcmVhc2VQb3NpdGlvbiBwYXJhbWV0ZXJzBAAAAA0kdDAyODM4NjI4NTM4CQEAAAALZ2V0UG9zaXRpb24AAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAPb2xkUG9zaXRpb25TaXplCAUAAAANJHQwMjgzODYyODUzOAAAAAJfMQQAAAARb2xkUG9zaXRpb25NYXJnaW4IBQAAAA0kdDAyODM4NjI4NTM4AAAAAl8yBAAAABdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFAAAADSR0MDI4Mzg2Mjg1MzgAAAACXzMEAAAAFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUAAAANJHQwMjgzODYyODUzOAAAAAJfNAQAAAAKX2RpcmVjdGlvbgMJAABmAAAAAgUAAAAPb2xkUG9zaXRpb25TaXplAAAAAAAAAAAABQAAAAlESVJfU0hPUlQFAAAACERJUl9MT05HBAAAAAVpc0FkZAkAAAAAAAACBQAAAApfZGlyZWN0aW9uBQAAAAhESVJfTE9ORwQAAAAMb3Blbk5vdGlvbmFsCQEAAAAEbXVsZAAAAAIFAAAAB19hbW91bnQFAAAACV9sZXZlcmFnZQQAAAANJHQwMjg3MTEyODgyNwkBAAAAI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIFAAAAD1BOTF9PUFRJT05fU1BPVAQAAAATb2xkUG9zaXRpb25Ob3Rpb25hbAgFAAAADSR0MDI4NzExMjg4MjcAAAACXzEEAAAADXVucmVhbGl6ZWRQbmwIBQAAAA0kdDAyODcxMTI4ODI3AAAAAl8yBAAAAA0kdDAyODgzMzMxMzgyAwkAAGYAAAACBQAAABNvbGRQb3NpdGlvbk5vdGlvbmFsBQAAAAxvcGVuTm90aW9uYWwEAAAADSR0MDI5MjEwMjk0MjkJAQAAAAlzd2FwSW5wdXQAAAACBQAAAAVpc0FkZAUAAAAMb3Blbk5vdGlvbmFsBAAAABVleGNoYW5nZWRQb3NpdGlvblNpemUIBQAAAA0kdDAyOTIxMDI5NDI5AAAAAl8xBAAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwMjkyMTAyOTQyOQAAAAJfMgQAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwMjkyMTAyOTQyOQAAAAJfMwQAAAAWdG90YWxQb3NpdGlvblNpemVBZnRlcggFAAAADSR0MDI5MjEwMjk0MjkAAAACXzQEAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCAUAAAANJHQwMjkyMTAyOTQyOQAAAAJfNQQAAAAYZXhjaGFuZ2VkUG9zaXRpb25TaXplQWJzCQEAAAADYWJzAAAAAQUAAAAVZXhjaGFuZ2VkUG9zaXRpb25TaXplAwMJAQAAAAIhPQAAAAIFAAAAE19taW5CYXNlQXNzZXRBbW91bnQAAAAAAAAAAAAJAABmAAAAAgUAAAATX21pbkJhc2VBc3NldEFtb3VudAUAAAAYZXhjaGFuZ2VkUG9zaXRpb25TaXplQWJzBwkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACVUb28gbGl0dGxlIGJhc2UgYXNzZXQgZXhjaGFuZ2VkLCBnb3QgCQABpAAAAAEFAAAAGGV4Y2hhbmdlZFBvc2l0aW9uU2l6ZUFicwIAAAAKIGV4cGVjdGVkIAkAAaQAAAABBQAAABNfbWluQmFzZUFzc2V0QW1vdW50BAAAAAtyZWFsaXplZFBubAkBAAAABGRpdmQAAAACCQEAAAAEbXVsZAAAAAIFAAAADXVucmVhbGl6ZWRQbmwFAAAAGGV4Y2hhbmdlZFBvc2l0aW9uU2l6ZUFicwkBAAAAA2FicwAAAAEFAAAAD29sZFBvc2l0aW9uU2l6ZQQAAAANJHQwMjk4NjYzMDExMQkBAAAAImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQAAAAEBQAAAA9vbGRQb3NpdGlvblNpemUFAAAAEW9sZFBvc2l0aW9uTWFyZ2luBQAAABRvbGRQb3NpdGlvbkxzdFVwZENQRgUAAAALcmVhbGl6ZWRQbmwEAAAADHJlbWFpbk1hcmdpbggFAAAADSR0MDI5ODY2MzAxMTEAAAACXzEEAAAAB2JhZERlYnQIBQAAAA0kdDAyOTg2NjMwMTExAAAAAl8yBAAAAA5mdW5kaW5nUGF5bWVudAgFAAAADSR0MDI5ODY2MzAxMTEAAAACXzMEAAAAGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQFAAAADG9wZW5Ob3Rpb25hbAQAAAASdW5yZWFsaXplZFBubEFmdGVyCQAAZQAAAAIFAAAADXVucmVhbGl6ZWRQbmwFAAAAC3JlYWxpemVkUG5sBAAAABJyZW1haW5PcGVuTm90aW9uYWwDCQAAZgAAAAIFAAAAD29sZFBvc2l0aW9uU2l6ZQAAAAAAAAAAAAkAAGUAAAACCQAAZQAAAAIFAAAAE29sZFBvc2l0aW9uTm90aW9uYWwFAAAAGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQFAAAAEnVucmVhbGl6ZWRQbmxBZnRlcgkAAGUAAAACCQAAZAAAAAIFAAAAEnVucmVhbGl6ZWRQbmxBZnRlcgUAAAATb2xkUG9zaXRpb25Ob3Rpb25hbAUAAAAZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAQAAAAPbmV3UG9zaXRpb25TaXplCQAAZAAAAAIFAAAAD29sZFBvc2l0aW9uU2l6ZQUAAAAVZXhjaGFuZ2VkUG9zaXRpb25TaXplCQAFHQAAAAsFAAAAD25ld1Bvc2l0aW9uU2l6ZQUAAAAMcmVtYWluTWFyZ2luCQEAAAADYWJzAAAAAQUAAAAScmVtYWluT3Blbk5vdGlvbmFsCQEAAAAfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAAAAEFAAAAD25ld1Bvc2l0aW9uU2l6ZQUAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBQAAABdjdW11bGF0aXZlTm90aW9uYWxBZnRlcgkAAGUAAAACCQEAAAAUb3BlbkludGVyZXN0Tm90aW9uYWwAAAAABQAAAAxvcGVuTm90aW9uYWwJAABlAAAAAgkBAAAAFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAAAAADCQAAZgAAAAIFAAAAD25ld1Bvc2l0aW9uU2l6ZQAAAAAAAAAAAAkBAAAAA2FicwAAAAEFAAAAFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQAAAAAAAAAAAAkAAGUAAAACCQEAAAAWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAAAAADCQAAZgAAAAIAAAAAAAAAAAAFAAAAD25ld1Bvc2l0aW9uU2l6ZQkBAAAAA2FicwAAAAEFAAAAFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQAAAAAAAAAAAAkAAAIAAAABAgAAABRDbG9zZSBwb3NpdGlvbiBmaXJzdAQAAAAPbmV3UG9zaXRpb25TaXplCAUAAAANJHQwMjg4MzMzMTM4MgAAAAJfMQQAAAAXbmV3UG9zaXRpb25SZW1haW5NYXJnaW4IBQAAAA0kdDAyODgzMzMxMzgyAAAAAl8yBAAAABduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFAAAADSR0MDI4ODMzMzEzODIAAAACXzMEAAAAFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCAUAAAANJHQwMjg4MzMzMTM4MgAAAAJfNAQAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwMjg4MzMzMTM4MgAAAAJfNQQAAAAWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFAAAADSR0MDI4ODMzMzEzODIAAAACXzYEAAAAFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQAAAA0kdDAyODgzMzMxMzgyAAAAAl83BAAAABdjdW11bGF0aXZlTm90aW9uYWxBZnRlcggFAAAADSR0MDI4ODMzMzEzODIAAAACXzgEAAAAGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIIBQAAAA0kdDAyODgzMzMxMzgyAAAAAl85BAAAAA50b3RhbExvbmdBZnRlcggFAAAADSR0MDI4ODMzMzEzODIAAAADXzEwBAAAAA90b3RhbFNob3J0QWZ0ZXIIBQAAAA0kdDAyODgzMzMxMzgyAAAAA18xMQkABE4AAAACCQEAAAAOdXBkYXRlUG9zaXRpb24AAAAFCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgUAAAAPbmV3UG9zaXRpb25TaXplBQAAABduZXdQb3NpdGlvblJlbWFpbk1hcmdpbgUAAAAXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFAAAAFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCQEAAAAJdXBkYXRlQW1tAAAABwUAAAAWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBQAAABdjdW11bGF0aXZlTm90aW9uYWxBZnRlcgUAAAAZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgUAAAAOdG90YWxMb25nQWZ0ZXIFAAAAD3RvdGFsU2hvcnRBZnRlcgAAAAFpAQAAABBpbmNyZWFzZVBvc2l0aW9uAAAAAwAAAApfZGlyZWN0aW9uAAAACV9sZXZlcmFnZQAAABNfbWluQmFzZUFzc2V0QW1vdW50BAAAAApfcmF3QW1vdW50CAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQDAwMDAwMDAwkBAAAAAiE9AAAAAgUAAAAKX2RpcmVjdGlvbgUAAAAIRElSX0xPTkcJAQAAAAIhPQAAAAIFAAAACl9kaXJlY3Rpb24FAAAACURJUl9TSE9SVAcGCQAAZwAAAAIAAAAAAAAAAAAFAAAACl9yYXdBbW91bnQGAwkAAGYAAAACCQAAaAAAAAIAAAAAAAAAAAEFAAAADERFQ0lNQUxfVU5JVAUAAAAJX2xldmVyYWdlBgkAAGYAAAACBQAAAAlfbGV2ZXJhZ2UJAABoAAAAAgAAAAAAAAAAAwUAAAAMREVDSU1BTF9VTklUBgkBAAAAASEAAAABCQEAAAALaW5pdGlhbGl6ZWQAAAAABgkBAAAAAiE9AAAAAggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAHYXNzZXRJZAkBAAAACnF1b3RlQXNzZXQAAAAABgkBAAAAASEAAAABCQEAAAAWcmVxdWlyZU1vcmVNYXJnaW5SYXRpbwAAAAMJAQAAAARkaXZkAAAAAgUAAAAMREVDSU1BTF9VTklUBQAAAAlfbGV2ZXJhZ2UJAQAAAA9pbml0TWFyZ2luUmF0aW8AAAAABgYJAQAAAAZwYXVzZWQAAAAACQAAAgAAAAECAAAAI0ludmFsaWQgaW5jcmVhc2VQb3NpdGlvbiBwYXJhbWV0ZXJzBAAAAAlmZWVBbW91bnQJAQAAAARtdWxkAAAAAgUAAAAKX3Jhd0Ftb3VudAkBAAAAA2ZlZQAAAAAEAAAAB19hbW91bnQJAABlAAAAAgUAAAAKX3Jhd0Ftb3VudAUAAAAJZmVlQW1vdW50BAAAAA0kdDAzMjQxODMyNTcwCQEAAAALZ2V0UG9zaXRpb24AAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAPb2xkUG9zaXRpb25TaXplCAUAAAANJHQwMzI0MTgzMjU3MAAAAAJfMQQAAAARb2xkUG9zaXRpb25NYXJnaW4IBQAAAA0kdDAzMjQxODMyNTcwAAAAAl8yBAAAABdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFAAAADSR0MDMyNDE4MzI1NzAAAAACXzMEAAAAFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUAAAANJHQwMzI0MTgzMjU3MAAAAAJfNAQAAAANaXNOZXdQb3NpdGlvbgkAAAAAAAACBQAAAA9vbGRQb3NpdGlvblNpemUAAAAAAAAAAAAEAAAAD2lzU2FtZURpcmVjdGlvbgMJAABmAAAAAgUAAAAPb2xkUG9zaXRpb25TaXplAAAAAAAAAAAACQAAAAAAAAIFAAAACl9kaXJlY3Rpb24FAAAACERJUl9MT05HCQAAAAAAAAIFAAAACl9kaXJlY3Rpb24FAAAACURJUl9TSE9SVAQAAAAOZXhwYW5kRXhpc3RpbmcDCQEAAAABIQAAAAEFAAAADWlzTmV3UG9zaXRpb24FAAAAD2lzU2FtZURpcmVjdGlvbgcEAAAABWlzQWRkCQAAAAAAAAIFAAAACl9kaXJlY3Rpb24FAAAACERJUl9MT05HBAAAAA0kdDAzMjg1OTM1MjQ4AwMFAAAADWlzTmV3UG9zaXRpb24GBQAAAA5leHBhbmRFeGlzdGluZwQAAAAMb3Blbk5vdGlvbmFsCQEAAAAEbXVsZAAAAAIFAAAAB19hbW91bnQFAAAACV9sZXZlcmFnZQQAAAANJHQwMzMyODMzMzQ4OQkBAAAACXN3YXBJbnB1dAAAAAIFAAAABWlzQWRkBQAAAAxvcGVuTm90aW9uYWwEAAAAFWFtb3VudEJhc2VBc3NldEJvdWdodAgFAAAADSR0MDMzMjgzMzM0ODkAAAACXzEEAAAAFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQAAAA0kdDAzMzI4MzMzNDg5AAAAAl8yBAAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQAAAA0kdDAzMzI4MzMzNDg5AAAAAl8zBAAAABZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUAAAANJHQwMzMyODMzMzQ4OQAAAAJfNAQAAAAXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIIBQAAAA0kdDAzMzI4MzMzNDg5AAAAAl81AwMJAQAAAAIhPQAAAAIFAAAAE19taW5CYXNlQXNzZXRBbW91bnQAAAAAAAAAAAAJAABmAAAAAgUAAAATX21pbkJhc2VBc3NldEFtb3VudAkBAAAAA2FicwAAAAEFAAAAFWFtb3VudEJhc2VBc3NldEJvdWdodAcJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAANTGltaXQgZXJyb3I6IAkAAaQAAAABCQEAAAADYWJzAAAAAQUAAAAVYW1vdW50QmFzZUFzc2V0Qm91Z2h0AgAAAAMgPCAJAAGkAAAAAQUAAAATX21pbkJhc2VBc3NldEFtb3VudAQAAAAPbmV3UG9zaXRpb25TaXplCQAAZAAAAAIFAAAAD29sZFBvc2l0aW9uU2l6ZQUAAAAVYW1vdW50QmFzZUFzc2V0Qm91Z2h0BAAAABlpbmNyZWFzZU1hcmdpblJlcXVpcmVtZW50CQEAAAAEZGl2ZAAAAAIFAAAADG9wZW5Ob3Rpb25hbAUAAAAJX2xldmVyYWdlBAAAAA0kdDAzMzg3MDM0MTA5CQEAAAAiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAAAAAQFAAAAD29sZFBvc2l0aW9uU2l6ZQUAAAARb2xkUG9zaXRpb25NYXJnaW4FAAAAFG9sZFBvc2l0aW9uTHN0VXBkQ1BGBQAAABlpbmNyZWFzZU1hcmdpblJlcXVpcmVtZW50BAAAAAxyZW1haW5NYXJnaW4IBQAAAA0kdDAzMzg3MDM0MTA5AAAAAl8xBAAAAAJ4MQgFAAAADSR0MDMzODcwMzQxMDkAAAACXzIEAAAAAngyCAUAAAANJHQwMzM4NzAzNDEwOQAAAAJfMwkABR0AAAALBQAAAA9uZXdQb3NpdGlvblNpemUFAAAADHJlbWFpbk1hcmdpbgkAAGQAAAACBQAAABdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAUAAAAMb3Blbk5vdGlvbmFsCQEAAAAfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAAAAEFAAAAD25ld1Bvc2l0aW9uU2l6ZQUAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBQAAABdjdW11bGF0aXZlTm90aW9uYWxBZnRlcgkAAGQAAAACCQEAAAAUb3BlbkludGVyZXN0Tm90aW9uYWwAAAAABQAAAAxvcGVuTm90aW9uYWwJAABkAAAAAgkBAAAAFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAAAAADCQAAZgAAAAIFAAAAD25ld1Bvc2l0aW9uU2l6ZQAAAAAAAAAAAAkBAAAAA2FicwAAAAEFAAAAFWFtb3VudEJhc2VBc3NldEJvdWdodAAAAAAAAAAAAAkAAGQAAAACCQEAAAAWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAAAAADCQAAZgAAAAIAAAAAAAAAAAAFAAAAD25ld1Bvc2l0aW9uU2l6ZQkBAAAAA2FicwAAAAEFAAAAFWFtb3VudEJhc2VBc3NldEJvdWdodAAAAAAAAAAAAAQAAAAMb3Blbk5vdGlvbmFsCQEAAAAEbXVsZAAAAAIFAAAAB19hbW91bnQFAAAACV9sZXZlcmFnZQQAAAANJHQwMzQ5NDEzNTA1NwkBAAAAI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIFAAAAD1BOTF9PUFRJT05fU1BPVAQAAAATb2xkUG9zaXRpb25Ob3Rpb25hbAgFAAAADSR0MDM0OTQxMzUwNTcAAAACXzEEAAAADXVucmVhbGl6ZWRQbmwIBQAAAA0kdDAzNDk0MTM1MDU3AAAAAl8yAwkAAGYAAAACBQAAABNvbGRQb3NpdGlvbk5vdGlvbmFsBQAAAAxvcGVuTm90aW9uYWwJAAACAAAAAQIAAAAuVXNlIGRlY3JlYXNlUG9zaXRpb24gdG8gZGVjcmVhc2UgcG9zaXRpb24gc2l6ZQkAAAIAAAABAgAAABRDbG9zZSBwb3NpdGlvbiBmaXJzdAQAAAAPbmV3UG9zaXRpb25TaXplCAUAAAANJHQwMzI4NTkzNTI0OAAAAAJfMQQAAAAXbmV3UG9zaXRpb25SZW1haW5NYXJnaW4IBQAAAA0kdDAzMjg1OTM1MjQ4AAAAAl8yBAAAABduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFAAAADSR0MDMyODU5MzUyNDgAAAACXzMEAAAAFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCAUAAAANJHQwMzI4NTkzNTI0OAAAAAJfNAQAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwMzI4NTkzNTI0OAAAAAJfNQQAAAAWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFAAAADSR0MDMyODU5MzUyNDgAAAACXzYEAAAAFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQAAAA0kdDAzMjg1OTM1MjQ4AAAAAl83BAAAABdjdW11bGF0aXZlTm90aW9uYWxBZnRlcggFAAAADSR0MDMyODU5MzUyNDgAAAACXzgEAAAAGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIIBQAAAA0kdDAzMjg1OTM1MjQ4AAAAAl85BAAAAA50b3RhbExvbmdBZnRlcggFAAAADSR0MDMyODU5MzUyNDgAAAADXzEwBAAAAA90b3RhbFNob3J0QWZ0ZXIIBQAAAA0kdDAzMjg1OTM1MjQ4AAAAA18xMQQAAAAMZmVlVG9TdGFrZXJzCQAAaQAAAAIFAAAACWZlZUFtb3VudAAAAAAAAAAAAgQAAAAOZmVlVG9JbnN1cmFuY2UJAABlAAAAAgUAAAAJZmVlQW1vdW50BQAAAAxmZWVUb1N0YWtlcnMEAAAABXN0YWtlCQAD/AAAAAQJAQAAABFxdW90ZUFzc2V0U3Rha2luZwAAAAACAAAADmxvY2tOZXV0cmlub1NQCQAETAAAAAIJAAQlAAAAAQkBAAAADnN0YWtpbmdBZGRyZXNzAAAAAAkABEwAAAACBQAAAAhBTExfRkVFUwUAAAADbmlsCQAETAAAAAIJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACCQEAAAAKcXVvdGVBc3NldAAAAAAFAAAAB19hbW91bnQFAAAAA25pbAMJAAAAAAAAAgUAAAAFc3Rha2UFAAAABXN0YWtlBAAAABBkZXBvc2l0SW5zdXJhbmNlCQAD/AAAAAQJAQAAABBpbnN1cmFuY2VBZGRyZXNzAAAAAAIAAAAHZGVwb3NpdAUAAAADbmlsCQAETAAAAAIJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACCQEAAAAKcXVvdGVBc3NldAAAAAAFAAAADmZlZVRvSW5zdXJhbmNlBQAAAANuaWwDCQAAAAAAAAIFAAAAEGRlcG9zaXRJbnN1cmFuY2UFAAAAEGRlcG9zaXRJbnN1cmFuY2UJAAROAAAAAgkABE4AAAACCQAETgAAAAIJAQAAAA51cGRhdGVQb3NpdGlvbgAAAAUJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBQAAAA9uZXdQb3NpdGlvblNpemUFAAAAF25ld1Bvc2l0aW9uUmVtYWluTWFyZ2luBQAAABduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAUAAAAUbmV3UG9zaXRpb25MYXRlc3RDUEYJAQAAAAl1cGRhdGVBbW0AAAAHBQAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyBQAAABlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyBQAAAA50b3RhbExvbmdBZnRlcgUAAAAPdG90YWxTaG9ydEFmdGVyCQEAAAALdHJhbnNmZXJGZWUAAAABBQAAAAxmZWVUb1N0YWtlcnMJAQAAAA11cGRhdGVCYWxhbmNlAAAAAQkAAGQAAAACCQEAAAAIY2JhbGFuY2UAAAAABQAAAAdfYW1vdW50CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAJYWRkTWFyZ2luAAAAAAQAAAAKX3Jhd0Ftb3VudAgJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50AwMDAwkBAAAAAiE9AAAAAggJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAHYXNzZXRJZAkBAAAACnF1b3RlQXNzZXQAAAAABgkBAAAAASEAAAABCQEAAAATcmVxdWlyZU9wZW5Qb3NpdGlvbgAAAAEJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBgkBAAAAASEAAAABCQEAAAALaW5pdGlhbGl6ZWQAAAAABgkBAAAABnBhdXNlZAAAAAAJAAACAAAAAQIAAAAcSW52YWxpZCBhZGRNYXJnaW4gcGFyYW1ldGVycwQAAAAJZmVlQW1vdW50CQEAAAAEbXVsZAAAAAIFAAAACl9yYXdBbW91bnQJAQAAAANmZWUAAAAABAAAAAdfYW1vdW50CQAAZQAAAAIFAAAACl9yYXdBbW91bnQFAAAACWZlZUFtb3VudAQAAAANJHQwMzY1MjQzNjY3NgkBAAAAC2dldFBvc2l0aW9uAAAAAQkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAAD29sZFBvc2l0aW9uU2l6ZQgFAAAADSR0MDM2NTI0MzY2NzYAAAACXzEEAAAAEW9sZFBvc2l0aW9uTWFyZ2luCAUAAAANJHQwMzY1MjQzNjY3NgAAAAJfMgQAAAAXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQAAAA0kdDAzNjUyNDM2Njc2AAAAAl8zBAAAABRvbGRQb3NpdGlvbkxzdFVwZENQRggFAAAADSR0MDM2NTI0MzY2NzYAAAACXzQEAAAADGZlZVRvU3Rha2VycwkAAGkAAAACBQAAAAlmZWVBbW91bnQAAAAAAAAAAAIEAAAADmZlZVRvSW5zdXJhbmNlCQAAZQAAAAIFAAAACWZlZUFtb3VudAUAAAAMZmVlVG9TdGFrZXJzBAAAAAVzdGFrZQkAA/wAAAAECQEAAAARcXVvdGVBc3NldFN0YWtpbmcAAAAAAgAAAA5sb2NrTmV1dHJpbm9TUAkABEwAAAACCQAEJQAAAAEJAQAAAA5zdGFraW5nQWRkcmVzcwAAAAAJAARMAAAAAgUAAAAIQUxMX0ZFRVMFAAAAA25pbAkABEwAAAACCQEAAAAPQXR0YWNoZWRQYXltZW50AAAAAgkBAAAACnF1b3RlQXNzZXQAAAAABQAAAAdfYW1vdW50BQAAAANuaWwDCQAAAAAAAAIFAAAABXN0YWtlBQAAAAVzdGFrZQQAAAAQZGVwb3NpdEluc3VyYW5jZQkAA/wAAAAECQEAAAAQaW5zdXJhbmNlQWRkcmVzcwAAAAACAAAAB2RlcG9zaXQFAAAAA25pbAkABEwAAAACCQEAAAAPQXR0YWNoZWRQYXltZW50AAAAAgkBAAAACnF1b3RlQXNzZXQAAAAABQAAAA5mZWVUb0luc3VyYW5jZQUAAAADbmlsAwkAAAAAAAACBQAAABBkZXBvc2l0SW5zdXJhbmNlBQAAABBkZXBvc2l0SW5zdXJhbmNlCQAETgAAAAIJAAROAAAAAgkBAAAADnVwZGF0ZVBvc2l0aW9uAAAABQkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIFAAAAD29sZFBvc2l0aW9uU2l6ZQkAAGQAAAACBQAAABFvbGRQb3NpdGlvbk1hcmdpbgUAAAAHX2Ftb3VudAUAAAAXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwFAAAAFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCQEAAAALdHJhbnNmZXJGZWUAAAABBQAAAAxmZWVUb1N0YWtlcnMJAQAAAA11cGRhdGVCYWxhbmNlAAAAAQkAAGQAAAACCQEAAAAIY2JhbGFuY2UAAAAABQAAAAdfYW1vdW50CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAMcmVtb3ZlTWFyZ2luAAAAAQAAAAdfYW1vdW50AwMDAwkAAGcAAAACAAAAAAAAAAAABQAAAAdfYW1vdW50BgkBAAAAASEAAAABCQEAAAATcmVxdWlyZU9wZW5Qb3NpdGlvbgAAAAEJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBgkBAAAAASEAAAABCQEAAAALaW5pdGlhbGl6ZWQAAAAABgkBAAAABnBhdXNlZAAAAAAJAAACAAAAAQIAAAAfSW52YWxpZCByZW1vdmVNYXJnaW4gcGFyYW1ldGVycwQAAAANJHQwMzc1OTYzNzc0OAkBAAAAC2dldFBvc2l0aW9uAAAAAQkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAAD29sZFBvc2l0aW9uU2l6ZQgFAAAADSR0MDM3NTk2Mzc3NDgAAAACXzEEAAAAEW9sZFBvc2l0aW9uTWFyZ2luCAUAAAANJHQwMzc1OTYzNzc0OAAAAAJfMgQAAAAXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQAAAA0kdDAzNzU5NjM3NzQ4AAAAAl8zBAAAABRvbGRQb3NpdGlvbkxzdFVwZENQRggFAAAADSR0MDM3NTk2Mzc3NDgAAAACXzQEAAAAC21hcmdpbkRlbHRhCQEAAAABLQAAAAEFAAAAB19hbW91bnQEAAAADSR0MDM3Nzg1Mzc5NjQJAQAAACJjYWxjUmVtYWluTWFyZ2luV2l0aEZ1bmRpbmdQYXltZW50AAAABAUAAAAPb2xkUG9zaXRpb25TaXplBQAAABFvbGRQb3NpdGlvbk1hcmdpbgUAAAAUb2xkUG9zaXRpb25Mc3RVcGRDUEYFAAAAC21hcmdpbkRlbHRhBAAAAAxyZW1haW5NYXJnaW4IBQAAAA0kdDAzNzc4NTM3OTY0AAAAAl8xBAAAAAdiYWREZWJ0CAUAAAANJHQwMzc3ODUzNzk2NAAAAAJfMgMJAQAAAAIhPQAAAAIFAAAAB2JhZERlYnQAAAAAAAAAAAAJAAACAAAAAQIAAAAdSW52YWxpZCByZW1vdmVkIG1hcmdpbiBhbW91bnQEAAAAC21hcmdpblJhdGlvCQEAAAAPY2FsY01hcmdpblJhdGlvAAAAAwUAAAAMcmVtYWluTWFyZ2luBQAAAAdiYWREZWJ0BQAAABdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAMJAQAAAAEhAAAAAQkBAAAAFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8AAAADBQAAAAttYXJnaW5SYXRpbwkBAAAAD2luaXRNYXJnaW5SYXRpbwAAAAAGCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAGVRvbyBtdWNoIG1hcmdpbiByZW1vdmVkOiAJAAGkAAAAAQUAAAALbWFyZ2luUmF0aW8CAAAAAyA8IAkAAaQAAAABCQEAAAAPaW5pdE1hcmdpblJhdGlvAAAAAAQAAAAHdW5zdGFrZQkAA/wAAAAECQEAAAARcXVvdGVBc3NldFN0YWtpbmcAAAAAAgAAAA51bmxvY2tOZXV0cmlubwkABEwAAAACBQAAAAdfYW1vdW50CQAETAAAAAIJAAJYAAAAAQkBAAAACnF1b3RlQXNzZXQAAAAABQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAHdW5zdGFrZQUAAAAHdW5zdGFrZQkABE4AAAACCQAETgAAAAIJAQAAAA51cGRhdGVQb3NpdGlvbgAAAAUJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBQAAAA9vbGRQb3NpdGlvblNpemUFAAAADHJlbWFpbk1hcmdpbgUAAAAXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwJAQAAAB9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAAAAQUAAAAPb2xkUG9zaXRpb25TaXplCQEAAAAId2l0aGRyYXcAAAACCAUAAAABaQAAAAZjYWxsZXIFAAAAB19hbW91bnQJAQAAAA11cGRhdGVCYWxhbmNlAAAAAQkAAGUAAAACCQEAAAAIY2JhbGFuY2UAAAAABQAAAAdfYW1vdW50CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAA1jbG9zZVBvc2l0aW9uAAAAAAMDAwkBAAAAASEAAAABCQEAAAATcmVxdWlyZU9wZW5Qb3NpdGlvbgAAAAEJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBgkBAAAAASEAAAABCQEAAAALaW5pdGlhbGl6ZWQAAAAABgkBAAAABnBhdXNlZAAAAAAJAAACAAAAAQIAAAAgSW52YWxpZCBjbG9zZVBvc2l0aW9uIHBhcmFtZXRlcnMEAAAADSR0MDM5MDYwMzk0NDQJAQAAABVpbnRlcm5hbENsb3NlUG9zaXRpb24AAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAACeDEIBQAAAA0kdDAzOTA2MDM5NDQ0AAAAAl8xBAAAAA9wb3NpdGlvbkJhZERlYnQIBQAAAA0kdDAzOTA2MDM5NDQ0AAAAAl8yBAAAAAtyZWFsaXplZFBubAgFAAAADSR0MDM5MDYwMzk0NDQAAAACXzMEAAAADW1hcmdpblRvVmF1bHQIBQAAAA0kdDAzOTA2MDM5NDQ0AAAAAl80BAAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwMzkwNjAzOTQ0NAAAAAJfNQQAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwMzkwNjAzOTQ0NAAAAAJfNgQAAAAWdG90YWxQb3NpdGlvblNpemVBZnRlcggFAAAADSR0MDM5MDYwMzk0NDQAAAACXzcEAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCAUAAAANJHQwMzkwNjAzOTQ0NAAAAAJfOAQAAAAZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcggFAAAADSR0MDM5MDYwMzk0NDQAAAACXzkEAAAAAngyCAUAAAANJHQwMzkwNjAzOTQ0NAAAAANfMTAEAAAADnRvdGFsTG9uZ0FmdGVyCAUAAAANJHQwMzkwNjAzOTQ0NAAAAANfMTEEAAAAD3RvdGFsU2hvcnRBZnRlcggFAAAADSR0MDM5MDYwMzk0NDQAAAADXzEyAwkAAGYAAAACBQAAAA9wb3NpdGlvbkJhZERlYnQAAAAAAAAAAAAJAAACAAAAAQIAAAAmVW5hYmxlIHRvIGNsb3NlIHBvc2l0aW9uIHdpdGggYmFkIGRlYnQEAAAADndpdGhkcmF3QW1vdW50CQEAAAADYWJzAAAAAQUAAAANbWFyZ2luVG9WYXVsdAQAAAAKYW1tQmFsYW5jZQkAAGUAAAACCQEAAAAIY2JhbGFuY2UAAAAABQAAAA53aXRoZHJhd0Ftb3VudAQAAAANJHQwMzk2NTMzOTc5NQMJAABmAAAAAgAAAAAAAAAAAAUAAAAKYW1tQmFsYW5jZQkABRQAAAACAAAAAAAAAAAACQEAAAADYWJzAAAAAQUAAAAKYW1tQmFsYW5jZQkABRQAAAACBQAAAAphbW1CYWxhbmNlAAAAAAAAAAAABAAAAA1hbW1OZXdCYWxhbmNlCAUAAAANJHQwMzk2NTMzOTc5NQAAAAJfMQQAAAAQZ2V0RnJvbUluc3VyYW5jZQgFAAAADSR0MDM5NjUzMzk3OTUAAAACXzIEAAAAAXgDCQAAZgAAAAIFAAAAEGdldEZyb21JbnN1cmFuY2UAAAAAAAAAAAAEAAAAEXdpdGhkcmF3SW5zdXJhbmNlCQAD/AAAAAQJAQAAABBpbnN1cmFuY2VBZGRyZXNzAAAAAAIAAAAId2l0aGRyYXcJAARMAAAAAgUAAAAQZ2V0RnJvbUluc3VyYW5jZQUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAEXdpdGhkcmF3SW5zdXJhbmNlBQAAABF3aXRoZHJhd0luc3VyYW5jZQUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUAAAADbmlsAwkAAAAAAAACBQAAAAF4BQAAAAF4BAAAAAd1bnN0YWtlCQAD/AAAAAQJAQAAABFxdW90ZUFzc2V0U3Rha2luZwAAAAACAAAADnVubG9ja05ldXRyaW5vCQAETAAAAAIJAABlAAAAAgUAAAAOd2l0aGRyYXdBbW91bnQFAAAAEGdldEZyb21JbnN1cmFuY2UJAARMAAAAAgkAAlgAAAABCQEAAAAKcXVvdGVBc3NldAAAAAAFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAAd1bnN0YWtlBQAAAAd1bnN0YWtlCQAETgAAAAIJAAROAAAAAgkABE4AAAACCQEAAAAOZGVsZXRlUG9zaXRpb24AAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgkBAAAACXVwZGF0ZUFtbQAAAAcFAAAAFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAFWJhc2VBc3NldFJlc2VydmVBZnRlcgUAAAAWdG90YWxQb3NpdGlvblNpemVBZnRlcgUAAAAXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIFAAAAGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIFAAAADnRvdGFsTG9uZ0FmdGVyBQAAAA90b3RhbFNob3J0QWZ0ZXIJAQAAAAh3aXRoZHJhdwAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAOd2l0aGRyYXdBbW91bnQJAQAAAA11cGRhdGVCYWxhbmNlAAAAAQUAAAANYW1tTmV3QmFsYW5jZQkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAACWxpcXVpZGF0ZQAAAAEAAAAHX3RyYWRlcgQAAAAPc3BvdE1hcmdpblJhdGlvCQEAAAAWZ2V0TWFyZ2luUmF0aW9CeU9wdGlvbgAAAAIFAAAAB190cmFkZXIFAAAAD1BOTF9PUFRJT05fU1BPVAQAAAALbWFyZ2luUmF0aW8DCQEAAAAWaXNPdmVyRmx1Y3R1YXRpb25MaW1pdAAAAAAEAAAAEW9yYWNsZU1hcmdpblJhdGlvCQEAAAAWZ2V0TWFyZ2luUmF0aW9CeU9wdGlvbgAAAAIFAAAAB190cmFkZXIFAAAAEVBOTF9PUFRJT05fT1JBQ0xFCQEAAAAEdm1heAAAAAIFAAAAD3Nwb3RNYXJnaW5SYXRpbwUAAAARb3JhY2xlTWFyZ2luUmF0aW8FAAAAD3Nwb3RNYXJnaW5SYXRpbwMDAwMJAQAAAAEhAAAAAQkBAAAAFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8AAAADBQAAAAttYXJnaW5SYXRpbwkBAAAAFm1haW50ZW5hbmNlTWFyZ2luUmF0aW8AAAAABwYJAQAAAAEhAAAAAQkBAAAAE3JlcXVpcmVPcGVuUG9zaXRpb24AAAABBQAAAAdfdHJhZGVyBgkBAAAAASEAAAABCQEAAAALaW5pdGlhbGl6ZWQAAAAABgkBAAAABnBhdXNlZAAAAAAJAAACAAAAAQIAAAATVW5hYmxlIHRvIGxpcXVpZGF0ZQQAAAANJHQwNDEzNDM0MTc1OQkBAAAAFWludGVybmFsQ2xvc2VQb3NpdGlvbgAAAAEFAAAAB190cmFkZXIEAAAAAngxCAUAAAANJHQwNDEzNDM0MTc1OQAAAAJfMQQAAAAHYmFkRGVidAgFAAAADSR0MDQxMzQzNDE3NTkAAAACXzIEAAAAAngyCAUAAAANJHQwNDEzNDM0MTc1OQAAAAJfMwQAAAACeDMIBQAAAA0kdDA0MTM0MzQxNzU5AAAAAl80BAAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwNDEzNDM0MTc1OQAAAAJfNQQAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwNDEzNDM0MTc1OQAAAAJfNgQAAAAWdG90YWxQb3NpdGlvblNpemVBZnRlcggFAAAADSR0MDQxMzQzNDE3NTkAAAACXzcEAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCAUAAAANJHQwNDEzNDM0MTc1OQAAAAJfOAQAAAAZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcggFAAAADSR0MDQxMzQzNDE3NTkAAAACXzkEAAAAGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQIBQAAAA0kdDA0MTM0MzQxNzU5AAAAA18xMAQAAAAOdG90YWxMb25nQWZ0ZXIIBQAAAA0kdDA0MTM0MzQxNzU5AAAAA18xMQQAAAAPdG90YWxTaG9ydEFmdGVyCAUAAAANJHQwNDEzNDM0MTc1OQAAAANfMTIEAAAAEmxpcXVpZGF0aW9uUGVuYWx0eQkBAAAABG11bGQAAAACBQAAABlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50CQEAAAATbGlxdWlkYXRpb25GZWVSYXRpbwAAAAAEAAAAD2ZlZVRvTGlxdWlkYXRvcgkAAGkAAAACBQAAABJsaXF1aWRhdGlvblBlbmFsdHkAAAAAAAAAAAIEAAAADmZlZVRvSW5zdXJhbmNlCQAAZQAAAAIFAAAAEmxpcXVpZGF0aW9uUGVuYWx0eQUAAAAPZmVlVG9MaXF1aWRhdG9yBAAAAAphbW1CYWxhbmNlCQAAZQAAAAIJAQAAAAhjYmFsYW5jZQAAAAAFAAAAEmxpcXVpZGF0aW9uUGVuYWx0eQQAAAANJHQwNDIxNTc0MjI5MgMJAABmAAAAAgAAAAAAAAAAAAUAAAAKYW1tQmFsYW5jZQkABRQAAAACAAAAAAAAAAAACQEAAAADYWJzAAAAAQUAAAAKYW1tQmFsYW5jZQkABRQAAAACBQAAAAphbW1CYWxhbmNlAAAAAAAAAAAABAAAAA1uZXdBbW1CYWxhbmNlCAUAAAANJHQwNDIxNTc0MjI5MgAAAAJfMQQAAAARdGFrZUZyb21JbnN1cmFuY2UIBQAAAA0kdDA0MjE1NzQyMjkyAAAAAl8yBAAAAAF4AwkAAGYAAAACBQAAABF0YWtlRnJvbUluc3VyYW5jZQAAAAAAAAAAAAQAAAARd2l0aGRyYXdJbnN1cmFuY2UJAAP8AAAABAkBAAAAEGluc3VyYW5jZUFkZHJlc3MAAAAAAgAAAAh3aXRoZHJhdwkABEwAAAACBQAAABF0YWtlRnJvbUluc3VyYW5jZQUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAEXdpdGhkcmF3SW5zdXJhbmNlBQAAABF3aXRoZHJhd0luc3VyYW5jZQUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUAAAADbmlsAwkAAAAAAAACBQAAAAF4BQAAAAF4BAAAAAd1bnN0YWtlCQAD/AAAAAQJAQAAABFxdW90ZUFzc2V0U3Rha2luZwAAAAACAAAADnVubG9ja05ldXRyaW5vCQAETAAAAAIJAABlAAAAAgUAAAASbGlxdWlkYXRpb25QZW5hbHR5BQAAABF0YWtlRnJvbUluc3VyYW5jZQkABEwAAAACCQACWAAAAAEJAQAAAApxdW90ZUFzc2V0AAAAAAUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAB3Vuc3Rha2UFAAAAB3Vuc3Rha2UEAAAAEGRlcG9zaXRJbnN1cmFuY2UJAAP8AAAABAkBAAAAEGluc3VyYW5jZUFkZHJlc3MAAAAAAgAAAAdkZXBvc2l0BQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIJAQAAAApxdW90ZUFzc2V0AAAAAAUAAAAOZmVlVG9JbnN1cmFuY2UFAAAAA25pbAMJAAAAAAAAAgUAAAAQZGVwb3NpdEluc3VyYW5jZQUAAAAQZGVwb3NpdEluc3VyYW5jZQkABE4AAAACCQAETgAAAAIJAAROAAAAAgkBAAAADmRlbGV0ZVBvc2l0aW9uAAAAAQUAAAAHX3RyYWRlcgkBAAAACXVwZGF0ZUFtbQAAAAcFAAAAFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAFWJhc2VBc3NldFJlc2VydmVBZnRlcgUAAAAWdG90YWxQb3NpdGlvblNpemVBZnRlcgUAAAAXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIFAAAAGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIFAAAADnRvdGFsTG9uZ0FmdGVyBQAAAA90b3RhbFNob3J0QWZ0ZXIJAQAAAAh3aXRoZHJhdwAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAPZmVlVG9MaXF1aWRhdG9yCQEAAAANdXBkYXRlQmFsYW5jZQAAAAEFAAAADW5ld0FtbUJhbGFuY2UJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAKcGF5RnVuZGluZwAAAAAEAAAAFWZ1bmRpbmdCbG9ja1RpbWVzdGFtcAkBAAAAGW5leHRGdW5kaW5nQmxvY2tUaW1lc3RhbXAAAAAAAwMDCQAAZgAAAAIFAAAAFWZ1bmRpbmdCbG9ja1RpbWVzdGFtcAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAGCQEAAAABIQAAAAEJAQAAAAtpbml0aWFsaXplZAAAAAAGCQEAAAAGcGF1c2VkAAAAAAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACFJbnZhbGlkIGZ1bmRpbmcgYmxvY2sgdGltZXN0YW1wOiAJAAGkAAAAAQgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXACAAAAAyA8IAkAAaQAAAABBQAAABVmdW5kaW5nQmxvY2tUaW1lc3RhbXAEAAAAD3VuZGVybHlpbmdQcmljZQkBAAAAEmdldE9yYWNsZVR3YXBQcmljZQAAAAAEAAAADXNwb3RUd2FwUHJpY2UJAQAAABBnZXRUd2FwU3BvdFByaWNlAAAAAAQAAAAHcHJlbWl1bQkAAGUAAAACBQAAAA1zcG90VHdhcFByaWNlBQAAAA91bmRlcmx5aW5nUHJpY2UEAAAADSR0MDQzNjY4NDUwMDMDAwkAAAAAAAACCQEAAAAWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAAAAAAAAAAAAAAAAAGCQAAAAAAAAIJAQAAABV0b3RhbExvbmdQb3NpdGlvblNpemUAAAAAAAAAAAAAAAAACQAFFAAAAAIAAAAAAAAAAAAAAAAAAAAAAAADCQAAZgAAAAIAAAAAAAAAAAAFAAAAB3ByZW1pdW0EAAAAFHNob3J0UHJlbWl1bUZyYWN0aW9uCQEAAAAEZGl2ZAAAAAIJAQAAAARtdWxkAAAAAgUAAAAHcHJlbWl1bQkBAAAAFGZ1bmRpbmdQZXJpb2REZWNpbWFsAAAAAAUAAAAHT05FX0RBWQQAAAATbG9uZ1ByZW1pdW1GcmFjdGlvbgkBAAAABGRpdmQAAAACCQEAAAAEbXVsZAAAAAIFAAAAFHNob3J0UHJlbWl1bUZyYWN0aW9uCQEAAAAWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAAAAAJAQAAABV0b3RhbExvbmdQb3NpdGlvblNpemUAAAAACQAFFAAAAAIFAAAAFHNob3J0UHJlbWl1bUZyYWN0aW9uBQAAABNsb25nUHJlbWl1bUZyYWN0aW9uBAAAABNsb25nUHJlbWl1bUZyYWN0aW9uCQEAAAAEZGl2ZAAAAAIJAQAAAARtdWxkAAAAAgUAAAAHcHJlbWl1bQkBAAAAFGZ1bmRpbmdQZXJpb2REZWNpbWFsAAAAAAUAAAAHT05FX0RBWQQAAAAUc2hvcnRQcmVtaXVtRnJhY3Rpb24JAQAAAARkaXZkAAAAAgkBAAAABG11bGQAAAACBQAAABNsb25nUHJlbWl1bUZyYWN0aW9uCQEAAAAVdG90YWxMb25nUG9zaXRpb25TaXplAAAAAAkBAAAAFnRvdGFsU2hvcnRQb3NpdGlvblNpemUAAAAACQAFFAAAAAIFAAAAFHNob3J0UHJlbWl1bUZyYWN0aW9uBQAAABNsb25nUHJlbWl1bUZyYWN0aW9uBAAAABRzaG9ydFByZW1pdW1GcmFjdGlvbggFAAAADSR0MDQzNjY4NDUwMDMAAAACXzEEAAAAE2xvbmdQcmVtaXVtRnJhY3Rpb24IBQAAAA0kdDA0MzY2ODQ1MDAzAAAAAl8yCQEAAAANdXBkYXRlRnVuZGluZwAAAAUJAABkAAAAAgUAAAAVZnVuZGluZ0Jsb2NrVGltZXN0YW1wCQEAAAAUZnVuZGluZ1BlcmlvZFNlY29uZHMAAAAACQAAZAAAAAIJAQAAACNsYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAAAAAFAAAAE2xvbmdQcmVtaXVtRnJhY3Rpb24JAABkAAAAAgkBAAAAJGxhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAAAAAFAAAAFHNob3J0UHJlbWl1bUZyYWN0aW9uCQEAAAAEZGl2ZAAAAAIFAAAAE2xvbmdQcmVtaXVtRnJhY3Rpb24FAAAAD3VuZGVybHlpbmdQcmljZQkBAAAABGRpdmQAAAACBQAAABRzaG9ydFByZW1pdW1GcmFjdGlvbgUAAAAPdW5kZXJseWluZ1ByaWNlAAAAAWkBAAAABXZfZ2V0AAAAAQAAAAdfdHJhZGVyBAAAAA0kdDA0NTM3ODQ1NDMxCQEAAAAVaW50ZXJuYWxDbG9zZVBvc2l0aW9uAAAAAQUAAAAHX3RyYWRlcgQAAAACeDEIBQAAAA0kdDA0NTM3ODQ1NDMxAAAAAl8xBAAAAAJ4MggFAAAADSR0MDQ1Mzc4NDU0MzEAAAACXzIEAAAAAngzCAUAAAANJHQwNDUzNzg0NTQzMQAAAAJfMwQAAAACeDQIBQAAAA0kdDA0NTM3ODQ1NDMxAAAAAl80CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAQAAAAFzAAAAAQUAAAACeDIJAQAAAAFzAAAAAQUAAAACeDMJAQAAAAFzAAAAAQUAAAACeDQJAQAAAAFzAAAAAQkBAAAADmdldE1hcmdpblJhdGlvAAAAAQUAAAAHX3RyYWRlcgAAAAFpAQAAACd2aWV3X2NhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQAAAABAAAAB190cmFkZXIEAAAADSR0MDQ1NTc4NDU2ODkJAQAAAAtnZXRQb3NpdGlvbgAAAAEFAAAAB190cmFkZXIEAAAADHBvc2l0aW9uU2l6ZQgFAAAADSR0MDQ1NTc4NDU2ODkAAAACXzEEAAAADnBvc2l0aW9uTWFyZ2luCAUAAAANJHQwNDU1Nzg0NTY4OQAAAAJfMgQAAAADcG9uCAUAAAANJHQwNDU1Nzg0NTY4OQAAAAJfMwQAAAARcG9zaXRpb25Mc3RVcGRDUEYIBQAAAA0kdDA0NTU3ODQ1Njg5AAAAAl80BAAAAA0kdDA0NTY5NDQ1Nzk1CQEAAAAjZ2V0UG9zaXRpb25Ob3Rpb25hbEFuZFVucmVhbGl6ZWRQbmwAAAACBQAAAAdfdHJhZGVyBQAAAA9QTkxfT1BUSU9OX1NQT1QEAAAAEHBvc2l0aW9uTm90aW9uYWwIBQAAAA0kdDA0NTY5NDQ1Nzk1AAAAAl8xBAAAAA11bnJlYWxpemVkUG5sCAUAAAANJHQwNDU2OTQ0NTc5NQAAAAJfMgQAAAANJHQwNDU4MDA0NTk4MgkBAAAAImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQAAAAEBQAAAAxwb3NpdGlvblNpemUFAAAADnBvc2l0aW9uTWFyZ2luBQAAABFwb3NpdGlvbkxzdFVwZENQRgUAAAANdW5yZWFsaXplZFBubAQAAAAMcmVtYWluTWFyZ2luCAUAAAANJHQwNDU4MDA0NTk4MgAAAAJfMQQAAAAHYmFkRGVidAgFAAAADSR0MDQ1ODAwNDU5ODIAAAACXzIEAAAADmZ1bmRpbmdQYXltZW50CAUAAAANJHQwNDU4MDA0NTk4MgAAAAJfMwkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkBAAAAAXMAAAABBQAAAAxyZW1haW5NYXJnaW4JAQAAAAFzAAAAAQUAAAAOZnVuZGluZ1BheW1lbnQJAQAAAAFzAAAAAQkBAAAADmdldE1hcmdpblJhdGlvAAAAAQUAAAAHX3RyYWRlcgAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACQEAAAAOYWRtaW5QdWJsaWNLZXkAAAAA7dwFyw==", "height": 2140493, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: D9cjd63FWQLDogszsMaRrYC1c14PdYWRW1mZeNUjfwT3 Next: GUtmTSVCPF7UyQUsXZQbE2iZX8kH3jxZ2XA297S4yJxm Diff:
OldNewDifferences
419419 let x3 = $t01626916376._4
420420 outPositionNotional
421421 }
422- else (positionSizeAbs * getOracleTwapPrice())
422+ else muld(positionSizeAbs, getOracleTwapPrice())
423423 let unrealizedPnl = if (isShort)
424424 then (positionOpenNotional - positionNotional)
425425 else (positionNotional - positionOpenNotional)
432432
433433
434434 func getMarginRatioByOption (_trader,_option) = {
435- let $t01704117152 = getPosition(_trader)
436- let positionSize = $t01704117152._1
437- let positionMargin = $t01704117152._2
438- let pon = $t01704117152._3
439- let positionLstUpdCPF = $t01704117152._4
440- let $t01715817251 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
441- let positionNotional = $t01715817251._1
442- let unrealizedPnl = $t01715817251._2
443- let $t01725617422 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
444- let remainMargin = $t01725617422._1
445- let badDebt = $t01725617422._2
435+ let $t01704617157 = getPosition(_trader)
436+ let positionSize = $t01704617157._1
437+ let positionMargin = $t01704617157._2
438+ let pon = $t01704617157._3
439+ let positionLstUpdCPF = $t01704617157._4
440+ let $t01716317256 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
441+ let positionNotional = $t01716317256._1
442+ let unrealizedPnl = $t01716317256._2
443+ let $t01726117427 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
444+ let remainMargin = $t01726117427._1
445+ let badDebt = $t01726117427._2
446446 calcMarginRatio(remainMargin, badDebt, positionNotional)
447447 }
448448
451451
452452
453453 func internalClosePosition (_trader) = {
454- let $t01773817866 = getPosition(_trader)
455- let positionSize = $t01773817866._1
456- let positionMargin = $t01773817866._2
457- let positionOpenNotional = $t01773817866._3
458- let positionLstUpdCPF = $t01773817866._4
459- let $t01787217959 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
460- let x1 = $t01787217959._1
461- let unrealizedPnl = $t01787217959._2
462- let $t01796418132 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
463- let remainMargin = $t01796418132._1
464- let badDebt = $t01796418132._2
454+ let $t01774317871 = getPosition(_trader)
455+ let positionSize = $t01774317871._1
456+ let positionMargin = $t01774317871._2
457+ let positionOpenNotional = $t01774317871._3
458+ let positionLstUpdCPF = $t01774317871._4
459+ let $t01787717964 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
460+ let x1 = $t01787717964._1
461+ let unrealizedPnl = $t01787717964._2
462+ let $t01796918137 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
463+ let remainMargin = $t01796918137._1
464+ let badDebt = $t01796918137._2
465465 let exchangedPositionSize = -(positionSize)
466466 let realizedPnl = unrealizedPnl
467467 let marginToVault = -(remainMargin)
468- let $t01825918540 = swapOutput((positionSize > 0), abs(positionSize))
469- let exchangedQuoteAssetAmount = $t01825918540._1
470- let quoteAssetReserveAfter = $t01825918540._2
471- let baseAssetReserveAfter = $t01825918540._3
472- let totalPositionSizeAfter = $t01825918540._4
473- let cumulativeNotionalAfter = $t01825918540._5
474- let totalLongAfter = $t01825918540._6
475- let totalShortAfter = $t01825918540._7
468+ let $t01826418545 = swapOutput((positionSize > 0), abs(positionSize))
469+ let exchangedQuoteAssetAmount = $t01826418545._1
470+ let quoteAssetReserveAfter = $t01826418545._2
471+ let baseAssetReserveAfter = $t01826418545._3
472+ let totalPositionSizeAfter = $t01826418545._4
473+ let cumulativeNotionalAfter = $t01826418545._5
474+ let totalLongAfter = $t01826418545._6
475+ let totalShortAfter = $t01826418545._7
476476 let openInterestNotionalAfter = (openInterestNotional() - positionOpenNotional)
477477 $Tuple12(exchangedPositionSize, badDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, exchangedQuoteAssetAmount, totalLongAfter, totalShortAfter)
478478 }
638638 else paused())
639639 then throw("Invalid decreasePosition parameters")
640640 else {
641- let $t02838128533 = getPosition(toString(i.caller))
642- let oldPositionSize = $t02838128533._1
643- let oldPositionMargin = $t02838128533._2
644- let oldPositionOpenNotional = $t02838128533._3
645- let oldPositionLstUpdCPF = $t02838128533._4
641+ let $t02838628538 = getPosition(toString(i.caller))
642+ let oldPositionSize = $t02838628538._1
643+ let oldPositionMargin = $t02838628538._2
644+ let oldPositionOpenNotional = $t02838628538._3
645+ let oldPositionLstUpdCPF = $t02838628538._4
646646 let _direction = if ((oldPositionSize > 0))
647647 then DIR_SHORT
648648 else DIR_LONG
649649 let isAdd = (_direction == DIR_LONG)
650650 let openNotional = muld(_amount, _leverage)
651- let $t02870628822 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
652- let oldPositionNotional = $t02870628822._1
653- let unrealizedPnl = $t02870628822._2
654- let $t02882831377 = if ((oldPositionNotional > openNotional))
651+ let $t02871128827 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
652+ let oldPositionNotional = $t02871128827._1
653+ let unrealizedPnl = $t02871128827._2
654+ let $t02883331382 = if ((oldPositionNotional > openNotional))
655655 then {
656- let $t02920529424 = swapInput(isAdd, openNotional)
657- let exchangedPositionSize = $t02920529424._1
658- let quoteAssetReserveAfter = $t02920529424._2
659- let baseAssetReserveAfter = $t02920529424._3
660- let totalPositionSizeAfter = $t02920529424._4
661- let cumulativeNotionalAfter = $t02920529424._5
656+ let $t02921029429 = swapInput(isAdd, openNotional)
657+ let exchangedPositionSize = $t02921029429._1
658+ let quoteAssetReserveAfter = $t02921029429._2
659+ let baseAssetReserveAfter = $t02921029429._3
660+ let totalPositionSizeAfter = $t02921029429._4
661+ let cumulativeNotionalAfter = $t02921029429._5
662662 let exchangedPositionSizeAbs = abs(exchangedPositionSize)
663663 if (if ((_minBaseAssetAmount != 0))
664664 then (_minBaseAssetAmount > exchangedPositionSizeAbs)
666666 then throw(((("Too little base asset exchanged, got " + toString(exchangedPositionSizeAbs)) + " expected ") + toString(_minBaseAssetAmount)))
667667 else {
668668 let realizedPnl = divd(muld(unrealizedPnl, exchangedPositionSizeAbs), abs(oldPositionSize))
669- let $t02986130106 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
670- let remainMargin = $t02986130106._1
671- let badDebt = $t02986130106._2
672- let fundingPayment = $t02986130106._3
669+ let $t02986630111 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
670+ let remainMargin = $t02986630111._1
671+ let badDebt = $t02986630111._2
672+ let fundingPayment = $t02986630111._3
673673 let exchangedQuoteAssetAmount = openNotional
674674 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
675675 let remainOpenNotional = if ((oldPositionSize > 0))
684684 }
685685 }
686686 else throw("Close position first")
687- let newPositionSize = $t02882831377._1
688- let newPositionRemainMargin = $t02882831377._2
689- let newPositionOpenNotional = $t02882831377._3
690- let newPositionLatestCPF = $t02882831377._4
691- let baseAssetReserveAfter = $t02882831377._5
692- let quoteAssetReserveAfter = $t02882831377._6
693- let totalPositionSizeAfter = $t02882831377._7
694- let cumulativeNotionalAfter = $t02882831377._8
695- let openInterestNotionalAfter = $t02882831377._9
696- let totalLongAfter = $t02882831377._10
697- let totalShortAfter = $t02882831377._11
687+ let newPositionSize = $t02883331382._1
688+ let newPositionRemainMargin = $t02883331382._2
689+ let newPositionOpenNotional = $t02883331382._3
690+ let newPositionLatestCPF = $t02883331382._4
691+ let baseAssetReserveAfter = $t02883331382._5
692+ let quoteAssetReserveAfter = $t02883331382._6
693+ let totalPositionSizeAfter = $t02883331382._7
694+ let cumulativeNotionalAfter = $t02883331382._8
695+ let openInterestNotionalAfter = $t02883331382._9
696+ let totalLongAfter = $t02883331382._10
697+ let totalShortAfter = $t02883331382._11
698698 (updatePosition(toString(i.caller), newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter))
699699 }
700700
724724 else {
725725 let feeAmount = muld(_rawAmount, fee())
726726 let _amount = (_rawAmount - feeAmount)
727- let $t03241332565 = getPosition(toString(i.caller))
728- let oldPositionSize = $t03241332565._1
729- let oldPositionMargin = $t03241332565._2
730- let oldPositionOpenNotional = $t03241332565._3
731- let oldPositionLstUpdCPF = $t03241332565._4
727+ let $t03241832570 = getPosition(toString(i.caller))
728+ let oldPositionSize = $t03241832570._1
729+ let oldPositionMargin = $t03241832570._2
730+ let oldPositionOpenNotional = $t03241832570._3
731+ let oldPositionLstUpdCPF = $t03241832570._4
732732 let isNewPosition = (oldPositionSize == 0)
733733 let isSameDirection = if ((oldPositionSize > 0))
734734 then (_direction == DIR_LONG)
737737 then isSameDirection
738738 else false
739739 let isAdd = (_direction == DIR_LONG)
740- let $t03285435243 = if (if (isNewPosition)
740+ let $t03285935248 = if (if (isNewPosition)
741741 then true
742742 else expandExisting)
743743 then {
744744 let openNotional = muld(_amount, _leverage)
745- let $t03327833484 = swapInput(isAdd, openNotional)
746- let amountBaseAssetBought = $t03327833484._1
747- let quoteAssetReserveAfter = $t03327833484._2
748- let baseAssetReserveAfter = $t03327833484._3
749- let totalPositionSizeAfter = $t03327833484._4
750- let cumulativeNotionalAfter = $t03327833484._5
745+ let $t03328333489 = swapInput(isAdd, openNotional)
746+ let amountBaseAssetBought = $t03328333489._1
747+ let quoteAssetReserveAfter = $t03328333489._2
748+ let baseAssetReserveAfter = $t03328333489._3
749+ let totalPositionSizeAfter = $t03328333489._4
750+ let cumulativeNotionalAfter = $t03328333489._5
751751 if (if ((_minBaseAssetAmount != 0))
752752 then (_minBaseAssetAmount > abs(amountBaseAssetBought))
753753 else false)
755755 else {
756756 let newPositionSize = (oldPositionSize + amountBaseAssetBought)
757757 let increaseMarginRequirement = divd(openNotional, _leverage)
758- let $t03386534104 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
759- let remainMargin = $t03386534104._1
760- let x1 = $t03386534104._2
761- let x2 = $t03386534104._3
758+ let $t03387034109 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
759+ let remainMargin = $t03387034109._1
760+ let x1 = $t03387034109._2
761+ let x2 = $t03387034109._3
762762 $Tuple11(newPositionSize, remainMargin, (oldPositionOpenNotional + openNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, (openInterestNotional() + openNotional), (totalLongPositionSize() + (if ((newPositionSize > 0))
763763 then abs(amountBaseAssetBought)
764764 else 0)), (totalShortPositionSize() + (if ((0 > newPositionSize))
768768 }
769769 else {
770770 let openNotional = muld(_amount, _leverage)
771- let $t03493635052 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
772- let oldPositionNotional = $t03493635052._1
773- let unrealizedPnl = $t03493635052._2
771+ let $t03494135057 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
772+ let oldPositionNotional = $t03494135057._1
773+ let unrealizedPnl = $t03494135057._2
774774 if ((oldPositionNotional > openNotional))
775775 then throw("Use decreasePosition to decrease position size")
776776 else throw("Close position first")
777777 }
778- let newPositionSize = $t03285435243._1
779- let newPositionRemainMargin = $t03285435243._2
780- let newPositionOpenNotional = $t03285435243._3
781- let newPositionLatestCPF = $t03285435243._4
782- let baseAssetReserveAfter = $t03285435243._5
783- let quoteAssetReserveAfter = $t03285435243._6
784- let totalPositionSizeAfter = $t03285435243._7
785- let cumulativeNotionalAfter = $t03285435243._8
786- let openInterestNotionalAfter = $t03285435243._9
787- let totalLongAfter = $t03285435243._10
788- let totalShortAfter = $t03285435243._11
778+ let newPositionSize = $t03285935248._1
779+ let newPositionRemainMargin = $t03285935248._2
780+ let newPositionOpenNotional = $t03285935248._3
781+ let newPositionLatestCPF = $t03285935248._4
782+ let baseAssetReserveAfter = $t03285935248._5
783+ let quoteAssetReserveAfter = $t03285935248._6
784+ let totalPositionSizeAfter = $t03285935248._7
785+ let cumulativeNotionalAfter = $t03285935248._8
786+ let openInterestNotionalAfter = $t03285935248._9
787+ let totalLongAfter = $t03285935248._10
788+ let totalShortAfter = $t03285935248._11
789789 let feeToStakers = (feeAmount / 2)
790790 let feeToInsurance = (feeAmount - feeToStakers)
791791 let stake = invoke(quoteAssetStaking(), "lockNeutrinoSP", [toString(stakingAddress()), ALL_FEES], [AttachedPayment(quoteAsset(), _amount)])
816816 else {
817817 let feeAmount = muld(_rawAmount, fee())
818818 let _amount = (_rawAmount - feeAmount)
819- let $t03651936671 = getPosition(toString(i.caller))
820- let oldPositionSize = $t03651936671._1
821- let oldPositionMargin = $t03651936671._2
822- let oldPositionOpenNotional = $t03651936671._3
823- let oldPositionLstUpdCPF = $t03651936671._4
819+ let $t03652436676 = getPosition(toString(i.caller))
820+ let oldPositionSize = $t03652436676._1
821+ let oldPositionMargin = $t03652436676._2
822+ let oldPositionOpenNotional = $t03652436676._3
823+ let oldPositionLstUpdCPF = $t03652436676._4
824824 let feeToStakers = (feeAmount / 2)
825825 let feeToInsurance = (feeAmount - feeToStakers)
826826 let stake = invoke(quoteAssetStaking(), "lockNeutrinoSP", [toString(stakingAddress()), ALL_FEES], [AttachedPayment(quoteAsset(), _amount)])
847847 else paused())
848848 then throw("Invalid removeMargin parameters")
849849 else {
850- let $t03759137743 = getPosition(toString(i.caller))
851- let oldPositionSize = $t03759137743._1
852- let oldPositionMargin = $t03759137743._2
853- let oldPositionOpenNotional = $t03759137743._3
854- let oldPositionLstUpdCPF = $t03759137743._4
850+ let $t03759637748 = getPosition(toString(i.caller))
851+ let oldPositionSize = $t03759637748._1
852+ let oldPositionMargin = $t03759637748._2
853+ let oldPositionOpenNotional = $t03759637748._3
854+ let oldPositionLstUpdCPF = $t03759637748._4
855855 let marginDelta = -(_amount)
856- let $t03778037959 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
857- let remainMargin = $t03778037959._1
858- let badDebt = $t03778037959._2
856+ let $t03778537964 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
857+ let remainMargin = $t03778537964._1
858+ let badDebt = $t03778537964._2
859859 if ((badDebt != 0))
860860 then throw("Invalid removed margin amount")
861861 else {
881881 else paused())
882882 then throw("Invalid closePosition parameters")
883883 else {
884- let $t03905539439 = internalClosePosition(toString(i.caller))
885- let x1 = $t03905539439._1
886- let positionBadDebt = $t03905539439._2
887- let realizedPnl = $t03905539439._3
888- let marginToVault = $t03905539439._4
889- let quoteAssetReserveAfter = $t03905539439._5
890- let baseAssetReserveAfter = $t03905539439._6
891- let totalPositionSizeAfter = $t03905539439._7
892- let cumulativeNotionalAfter = $t03905539439._8
893- let openInterestNotionalAfter = $t03905539439._9
894- let x2 = $t03905539439._10
895- let totalLongAfter = $t03905539439._11
896- let totalShortAfter = $t03905539439._12
884+ let $t03906039444 = internalClosePosition(toString(i.caller))
885+ let x1 = $t03906039444._1
886+ let positionBadDebt = $t03906039444._2
887+ let realizedPnl = $t03906039444._3
888+ let marginToVault = $t03906039444._4
889+ let quoteAssetReserveAfter = $t03906039444._5
890+ let baseAssetReserveAfter = $t03906039444._6
891+ let totalPositionSizeAfter = $t03906039444._7
892+ let cumulativeNotionalAfter = $t03906039444._8
893+ let openInterestNotionalAfter = $t03906039444._9
894+ let x2 = $t03906039444._10
895+ let totalLongAfter = $t03906039444._11
896+ let totalShortAfter = $t03906039444._12
897897 if ((positionBadDebt > 0))
898898 then throw("Unable to close position with bad debt")
899899 else {
900900 let withdrawAmount = abs(marginToVault)
901901 let ammBalance = (cbalance() - withdrawAmount)
902- let $t03964839790 = if ((0 > ammBalance))
902+ let $t03965339795 = if ((0 > ammBalance))
903903 then $Tuple2(0, abs(ammBalance))
904904 else $Tuple2(ammBalance, 0)
905- let ammNewBalance = $t03964839790._1
906- let getFromInsurance = $t03964839790._2
905+ let ammNewBalance = $t03965339795._1
906+ let getFromInsurance = $t03965339795._2
907907 let x = if ((getFromInsurance > 0))
908908 then {
909909 let withdrawInsurance = invoke(insuranceAddress(), "withdraw", [getFromInsurance], nil)
943943 else paused())
944944 then throw("Unable to liquidate")
945945 else {
946- let $t04133841754 = internalClosePosition(_trader)
947- let x1 = $t04133841754._1
948- let badDebt = $t04133841754._2
949- let x2 = $t04133841754._3
950- let x3 = $t04133841754._4
951- let quoteAssetReserveAfter = $t04133841754._5
952- let baseAssetReserveAfter = $t04133841754._6
953- let totalPositionSizeAfter = $t04133841754._7
954- let cumulativeNotionalAfter = $t04133841754._8
955- let openInterestNotionalAfter = $t04133841754._9
956- let exchangedQuoteAssetAmount = $t04133841754._10
957- let totalLongAfter = $t04133841754._11
958- let totalShortAfter = $t04133841754._12
946+ let $t04134341759 = internalClosePosition(_trader)
947+ let x1 = $t04134341759._1
948+ let badDebt = $t04134341759._2
949+ let x2 = $t04134341759._3
950+ let x3 = $t04134341759._4
951+ let quoteAssetReserveAfter = $t04134341759._5
952+ let baseAssetReserveAfter = $t04134341759._6
953+ let totalPositionSizeAfter = $t04134341759._7
954+ let cumulativeNotionalAfter = $t04134341759._8
955+ let openInterestNotionalAfter = $t04134341759._9
956+ let exchangedQuoteAssetAmount = $t04134341759._10
957+ let totalLongAfter = $t04134341759._11
958+ let totalShortAfter = $t04134341759._12
959959 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
960960 let feeToLiquidator = (liquidationPenalty / 2)
961961 let feeToInsurance = (liquidationPenalty - feeToLiquidator)
962962 let ammBalance = (cbalance() - liquidationPenalty)
963- let $t04215242287 = if ((0 > ammBalance))
963+ let $t04215742292 = if ((0 > ammBalance))
964964 then $Tuple2(0, abs(ammBalance))
965965 else $Tuple2(ammBalance, 0)
966- let newAmmBalance = $t04215242287._1
967- let takeFromInsurance = $t04215242287._2
966+ let newAmmBalance = $t04215742292._1
967+ let takeFromInsurance = $t04215742292._2
968968 let x = if ((takeFromInsurance > 0))
969969 then {
970970 let withdrawInsurance = invoke(insuranceAddress(), "withdraw", [takeFromInsurance], nil)
10041004 let underlyingPrice = getOracleTwapPrice()
10051005 let spotTwapPrice = getTwapSpotPrice()
10061006 let premium = (spotTwapPrice - underlyingPrice)
1007- let $t04366344998 = if (if ((totalShortPositionSize() == 0))
1007+ let $t04366845003 = if (if ((totalShortPositionSize() == 0))
10081008 then true
10091009 else (totalLongPositionSize() == 0))
10101010 then $Tuple2(0, 0)
10191019 let shortPremiumFraction = divd(muld(longPremiumFraction, totalLongPositionSize()), totalShortPositionSize())
10201020 $Tuple2(shortPremiumFraction, longPremiumFraction)
10211021 }
1022- let shortPremiumFraction = $t04366344998._1
1023- let longPremiumFraction = $t04366344998._2
1022+ let shortPremiumFraction = $t04366845003._1
1023+ let longPremiumFraction = $t04366845003._2
10241024 updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), divd(longPremiumFraction, underlyingPrice), divd(shortPremiumFraction, underlyingPrice))
10251025 }
10261026 }
10291029
10301030 @Callable(i)
10311031 func v_get (_trader) = {
1032- let $t04537345426 = internalClosePosition(_trader)
1033- let x1 = $t04537345426._1
1034- let x2 = $t04537345426._2
1035- let x3 = $t04537345426._3
1036- let x4 = $t04537345426._4
1032+ let $t04537845431 = internalClosePosition(_trader)
1033+ let x1 = $t04537845431._1
1034+ let x2 = $t04537845431._2
1035+ let x3 = $t04537845431._3
1036+ let x4 = $t04537845431._4
10371037 throw((((s(x2) + s(x3)) + s(x4)) + s(getMarginRatio(_trader))))
10381038 }
10391039
10411041
10421042 @Callable(i)
10431043 func view_calcRemainMarginWithFundingPayment (_trader) = {
1044- let $t04557345684 = getPosition(_trader)
1045- let positionSize = $t04557345684._1
1046- let positionMargin = $t04557345684._2
1047- let pon = $t04557345684._3
1048- let positionLstUpdCPF = $t04557345684._4
1049- let $t04568945790 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1050- let positionNotional = $t04568945790._1
1051- let unrealizedPnl = $t04568945790._2
1052- let $t04579545977 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1053- let remainMargin = $t04579545977._1
1054- let badDebt = $t04579545977._2
1055- let fundingPayment = $t04579545977._3
1044+ let $t04557845689 = getPosition(_trader)
1045+ let positionSize = $t04557845689._1
1046+ let positionMargin = $t04557845689._2
1047+ let pon = $t04557845689._3
1048+ let positionLstUpdCPF = $t04557845689._4
1049+ let $t04569445795 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1050+ let positionNotional = $t04569445795._1
1051+ let unrealizedPnl = $t04569445795._2
1052+ let $t04580045982 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1053+ let remainMargin = $t04580045982._1
1054+ let badDebt = $t04580045982._2
1055+ let fundingPayment = $t04580045982._3
10561056 throw(((s(remainMargin) + s(fundingPayment)) + s(getMarginRatio(_trader))))
10571057 }
10581058
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let k_ora_key = "k_ora_key"
55
66 let k_ora_block_key = "k_ora_block_key"
77
88 let k_ora = "k_ora"
99
1010 let k_balance = "k_balance"
1111
1212 let k_positionSize = "k_positionSize"
1313
1414 let k_positionMargin = "k_positionMargin"
1515
1616 let k_positionOpenNotional = "k_positionOpenNotional"
1717
1818 let k_positionLastUpdatedCumulativePremiumFraction = "k_positionFraction"
1919
2020 let k_initialized = "k_initialized"
2121
2222 let k_paused = "k_paused"
2323
2424 let k_fee = "k_fee"
2525
2626 let k_fundingPeriod = "k_fundingPeriod"
2727
2828 let k_initMarginRatio = "k_initMarginRatio"
2929
3030 let k_maintenanceMarginRatio = "k_mmr"
3131
3232 let k_liquidationFeeRatio = "k_liquidationFeeRatio"
3333
3434 let k_spreadLimit = "k_spreadLimit"
3535
3636 let k_maxPriceImpact = "k_maxPriceImpact"
3737
3838 let k_lastDataStr = "k_lastDataStr"
3939
4040 let k_lastMinuteId = "k_lastMinuteId"
4141
4242 let k_twapDataLastCumulativePrice = "k_twapDataLastCumulativePrice"
4343
4444 let k_twapDataLastPrice = "k_twapDataLastPrice"
4545
4646 let k_twapDataPreviousMinuteId = "k_twapDataPreviousMinuteId"
4747
4848 let k_latestLongCumulativePremiumFraction = "k_latestLongPremiumFraction"
4949
5050 let k_latestShortCumulativePremiumFraction = "k_latestShortPremiumFraction"
5151
5252 let k_nextFundingBlock = "k_nextFundingBlockMinTimestamp"
5353
5454 let k_longFundingRate = "k_longFundingRate"
5555
5656 let k_shortFundingRate = "k_shortFundingRate"
5757
5858 let k_quoteAssetReserve = "k_qtAstR"
5959
6060 let k_baseAssetReserve = "k_bsAstR"
6161
6262 let k_totalPositionSize = "k_totalPositionSize"
6363
6464 let k_totalLongPositionSize = "k_totalLongPositionSize"
6565
6666 let k_totalShortPositionSize = "k_totalShortPositionSize"
6767
6868 let k_cumulativeNotional = "k_cumulativeNotional"
6969
7070 let k_openInterestNotional = "k_openInterestNotional"
7171
7272 let k_coordinatorAddress = "k_coordinatorAddress"
7373
7474 let k_insurance_address = "k_insurance_address"
7575
7676 let k_admin_address = "k_admin_address"
7777
7878 let k_admin_public_key = "k_admin_public_key"
7979
8080 let k_quote_asset = "k_quote_asset"
8181
8282 let k_quote_staking = "k_quote_staking"
8383
8484 let k_staking_address = "k_staking_address"
8585
8686 func coordinator () = valueOrErrorMessage(addressFromString(getStringValue(this, k_coordinatorAddress)), "Coordinator not set")
8787
8888
8989 func adminAddress () = addressFromString(getStringValue(coordinator(), k_admin_address))
9090
9191
9292 func adminPublicKey () = fromBase58String(getStringValue(coordinator(), k_admin_public_key))
9393
9494
9595 func quoteAsset () = fromBase58String(getStringValue(coordinator(), k_quote_asset))
9696
9797
9898 func quoteAssetStaking () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_quote_staking)), "Quote asset staking not set")
9999
100100
101101 func stakingAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_staking_address)), "Insurance not set")
102102
103103
104104 func insuranceAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_insurance_address)), "Insurance not set")
105105
106106
107107 let DIR_LONG = 1
108108
109109 let DIR_SHORT = 2
110110
111111 let FUNDING_BLOCK_INTERVAL = 60
112112
113113 let TWAP_INTERVAL = 15
114114
115115 let ORACLE_INTERVAL = 15
116116
117117 let SECONDS = 1000
118118
119119 let DECIMAL_UNIT = (1 * (((((10 * 10) * 10) * 10) * 10) * 10))
120120
121121 let HUNDRED_PERCENT = (100 * DECIMAL_UNIT)
122122
123123 let ONE_DAY = (86400 * DECIMAL_UNIT)
124124
125125 let ALL_FEES = 100
126126
127127 let PNL_OPTION_SPOT = 1
128128
129129 let PNL_OPTION_ORACLE = 2
130130
131131 func s (_x) = (toString(_x) + ",")
132132
133133
134134 func divd (_x,_y) = fraction(_x, DECIMAL_UNIT, _y, HALFEVEN)
135135
136136
137137 func muld (_x,_y) = fraction(_x, _y, DECIMAL_UNIT, HALFEVEN)
138138
139139
140140 func abs (_x) = if ((_x > 0))
141141 then _x
142142 else -(_x)
143143
144144
145145 func vmax (_x,_y) = if ((_x >= _y))
146146 then _x
147147 else _y
148148
149149
150150 func toCompositeKey (_key,_address) = ((_key + "_") + _address)
151151
152152
153153 func listToStr (_list) = {
154154 func _join (accumulator,val) = ((accumulator + val) + ",")
155155
156156 let newListStr = {
157157 let $l = _list
158158 let $s = size($l)
159159 let $acc0 = ""
160160 func $f0_1 ($a,$i) = if (($i >= $s))
161161 then $a
162162 else _join($a, $l[$i])
163163
164164 func $f0_2 ($a,$i) = if (($i >= $s))
165165 then $a
166166 else throw("List size exceeds 20")
167167
168168 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
169169 }
170170 let newListStrU = dropRight(newListStr, 1)
171171 let newListStrR = if ((take(newListStrU, 1) == ","))
172172 then drop(newListStrU, 1)
173173 else newListStrU
174174 newListStrR
175175 }
176176
177177
178178 func strToList (_str) = split(_str, ",")
179179
180180
181181 func pushToQueue (_list,_maxSize,_value) = if ((size(_list) > _maxSize))
182182 then (removeByIndex(_list, 0) :+ _value)
183183 else (_list :+ _value)
184184
185185
186186 func int (k) = valueOrErrorMessage(getInteger(this, k), ("no value for " + k))
187187
188188
189189 func cbalance () = int(k_balance)
190190
191191
192192 func fee () = int(k_fee)
193193
194194
195195 func initMarginRatio () = int(k_initMarginRatio)
196196
197197
198198 func qtAstR () = int(k_quoteAssetReserve)
199199
200200
201201 func bsAstR () = int(k_baseAssetReserve)
202202
203203
204204 func totalPositionSize () = int(k_totalPositionSize)
205205
206206
207207 func cumulativeNotional () = int(k_cumulativeNotional)
208208
209209
210210 func openInterestNotional () = int(k_openInterestNotional)
211211
212212
213213 func nextFundingBlockTimestamp () = int(k_nextFundingBlock)
214214
215215
216216 func fundingPeriodRaw () = int(k_fundingPeriod)
217217
218218
219219 func fundingPeriodDecimal () = (fundingPeriodRaw() * DECIMAL_UNIT)
220220
221221
222222 func fundingPeriodSeconds () = (fundingPeriodRaw() * SECONDS)
223223
224224
225225 func maintenanceMarginRatio () = int(k_maintenanceMarginRatio)
226226
227227
228228 func liquidationFeeRatio () = int(k_liquidationFeeRatio)
229229
230230
231231 func spreadLimit () = int(k_spreadLimit)
232232
233233
234234 func maxPriceImpact () = int(k_maxPriceImpact)
235235
236236
237237 func latestLongCumulativePremiumFraction () = int(k_latestLongCumulativePremiumFraction)
238238
239239
240240 func latestShortCumulativePremiumFraction () = int(k_latestShortCumulativePremiumFraction)
241241
242242
243243 func totalShortPositionSize () = int(k_totalShortPositionSize)
244244
245245
246246 func totalLongPositionSize () = int(k_totalLongPositionSize)
247247
248248
249249 func requireMoreMarginRatio (_marginRatio,_baseMarginRatio,_largerThanOrEqualTo) = {
250250 let remainingMarginRatio = (_marginRatio - _baseMarginRatio)
251251 if (if (_largerThanOrEqualTo)
252252 then (0 > remainingMarginRatio)
253253 else false)
254254 then throw("Invalid margin")
255255 else if (if (!(_largerThanOrEqualTo))
256256 then (remainingMarginRatio >= 0)
257257 else false)
258258 then throw("Invalid margin")
259259 else true
260260 }
261261
262262
263263 func latestCumulativePremiumFraction (_positionSize) = if ((_positionSize == 0))
264264 then throw("Should not be called with _positionSize == 0")
265265 else if ((_positionSize > 0))
266266 then latestLongCumulativePremiumFraction()
267267 else latestShortCumulativePremiumFraction()
268268
269269
270270 func getPosition (_trader) = {
271271 let positionSizeOpt = getInteger(this, toCompositeKey(k_positionSize, _trader))
272272 match positionSizeOpt {
273273 case positionSize: Int =>
274274 $Tuple4(positionSize, getIntegerValue(this, toCompositeKey(k_positionMargin, _trader)), getIntegerValue(this, toCompositeKey(k_positionOpenNotional, _trader)), getIntegerValue(this, toCompositeKey(k_positionLastUpdatedCumulativePremiumFraction, _trader)))
275275 case _ =>
276276 $Tuple4(0, 0, 0, 0)
277277 }
278278 }
279279
280280
281281 func requireOpenPosition (_trader) = if ((getPosition(_trader)._1 == 0))
282282 then throw("No open position")
283283 else true
284284
285285
286286 func initialized () = valueOrElse(getBoolean(this, k_initialized), false)
287287
288288
289289 func paused () = valueOrElse(getBoolean(this, k_paused), false)
290290
291291
292292 func updateReserve (_isAdd,_quoteAssetAmount,_baseAssetAmount) = if (_isAdd)
293293 then {
294294 let newBase = (bsAstR() - _baseAssetAmount)
295295 if ((0 >= newBase))
296296 then throw("Tx lead to base asset reserve <= 0, revert")
297297 else $Tuple4((qtAstR() + _quoteAssetAmount), newBase, (totalPositionSize() + _baseAssetAmount), (cumulativeNotional() + _quoteAssetAmount))
298298 }
299299 else {
300300 let newQuote = (qtAstR() - _quoteAssetAmount)
301301 if ((0 >= newQuote))
302302 then throw("Tx lead to base quote reserve <= 0, revert")
303303 else $Tuple4(newQuote, (bsAstR() + _baseAssetAmount), (totalPositionSize() - _baseAssetAmount), (cumulativeNotional() - _quoteAssetAmount))
304304 }
305305
306306
307307 func swapInput (_isAdd,_quoteAssetAmount) = {
308308 let _qtAstR = qtAstR()
309309 let _bsAstR = bsAstR()
310310 let priceBefore = divd(_qtAstR, _bsAstR)
311311 let amountBaseAssetBoughtWithoutPriceImpact = muld(_quoteAssetAmount, priceBefore)
312312 let k = muld(_qtAstR, _bsAstR)
313313 let quoteAssetReserveAfter = if (_isAdd)
314314 then (_qtAstR + _quoteAssetAmount)
315315 else (_qtAstR - _quoteAssetAmount)
316316 let baseAssetReserveAfter = divd(k, quoteAssetReserveAfter)
317317 let amountBaseAssetBoughtAbs = abs((baseAssetReserveAfter - _bsAstR))
318318 let amountBaseAssetBought = if (_isAdd)
319319 then amountBaseAssetBoughtAbs
320320 else -(amountBaseAssetBoughtAbs)
321321 let priceImpact = ((amountBaseAssetBoughtWithoutPriceImpact - amountBaseAssetBoughtAbs) / amountBaseAssetBoughtWithoutPriceImpact)
322322 let maxPriceImpactValue = maxPriceImpact()
323323 if ((priceImpact > maxPriceImpactValue))
324324 then throw(((("Price impact " + toString(priceImpact)) + " > max price impact ") + toString(maxPriceImpactValue)))
325325 else {
326326 let $t01215412357 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
327327 let quoteAssetReserveAfter1 = $t01215412357._1
328328 let baseAssetReserveAfter1 = $t01215412357._2
329329 let totalPositionSizeAfter1 = $t01215412357._3
330330 let cumulativeNotionalAfter1 = $t01215412357._4
331331 $Tuple5(amountBaseAssetBought, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1, cumulativeNotionalAfter1)
332332 }
333333 }
334334
335335
336336 func calcRemainMarginWithFundingPayment (_oldPositionSize,_oldPositionMargin,_oldPositionCumulativePremiumFraction,_marginDelta) = {
337337 let fundingPayment = if ((_oldPositionSize != 0))
338338 then {
339339 let _latestCumulativePremiumFraction = latestCumulativePremiumFraction(_oldPositionSize)
340340 muld((_latestCumulativePremiumFraction - _oldPositionCumulativePremiumFraction), _oldPositionSize)
341341 }
342342 else 0
343343 let signedMargin = ((_marginDelta - fundingPayment) + _oldPositionMargin)
344344 let $t01310413231 = if ((0 > signedMargin))
345345 then $Tuple2(0, abs(signedMargin))
346346 else $Tuple2(abs(signedMargin), 0)
347347 let remainMargin = $t01310413231._1
348348 let badDebt = $t01310413231._2
349349 $Tuple3(remainMargin, badDebt, fundingPayment)
350350 }
351351
352352
353353 func swapOutput (_isAdd,_baseAssetAmount) = {
354354 let _quoteAssetReserve = qtAstR()
355355 let _baseAssetReserve = bsAstR()
356356 if ((_baseAssetAmount == 0))
357357 then throw("Invalid base asset amount")
358358 else {
359359 let k = muld(_quoteAssetReserve, _baseAssetReserve)
360360 let baseAssetPoolAmountAfter = if (_isAdd)
361361 then (_baseAssetReserve + _baseAssetAmount)
362362 else (_baseAssetReserve - _baseAssetAmount)
363363 let quoteAssetAfter = divd(k, baseAssetPoolAmountAfter)
364364 let quoteAssetSold = abs((quoteAssetAfter - _quoteAssetReserve))
365365 let $t01406914262 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
366366 let quoteAssetReserveAfter1 = $t01406914262._1
367367 let baseAssetReserveAfter1 = $t01406914262._2
368368 let totalPositionSizeAfter1 = $t01406914262._3
369369 let cumulativeNotionalAfter1 = $t01406914262._4
370370 $Tuple7(quoteAssetSold, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1, cumulativeNotionalAfter1, (totalLongPositionSize() - (if (_isAdd)
371371 then abs(_baseAssetAmount)
372372 else 0)), (totalShortPositionSize() - (if (!(_isAdd))
373373 then abs(_baseAssetAmount)
374374 else 0)))
375375 }
376376 }
377377
378378
379379 func getOracleTwapPrice () = {
380380 let oracle = valueOrErrorMessage(addressFromString(getStringValue(this, k_ora)), "")
381381 let priceKey = getStringValue(this, k_ora_key)
382382 let blockKey = getStringValue(this, k_ora_block_key)
383383 let lastValue = getIntegerValue(oracle, priceKey)
384384 lastValue
385385 }
386386
387387
388388 func getSpotPrice () = {
389389 let _quoteAssetReserve = qtAstR()
390390 let _baseAssetReserve = bsAstR()
391391 divd(_quoteAssetReserve, _baseAssetReserve)
392392 }
393393
394394
395395 func isOverFluctuationLimit () = {
396396 let oraclePrice = getOracleTwapPrice()
397397 let currentPrice = getSpotPrice()
398398 (divd(abs((oraclePrice - currentPrice)), oraclePrice) > spreadLimit())
399399 }
400400
401401
402402 func getPositionNotionalAndUnrealizedPnl (_trader,_option) = {
403403 let $t01589416022 = getPosition(_trader)
404404 let positionSize = $t01589416022._1
405405 let positionMargin = $t01589416022._2
406406 let positionOpenNotional = $t01589416022._3
407407 let positionLstUpdCPF = $t01589416022._4
408408 let positionSizeAbs = abs(positionSize)
409409 if ((positionSizeAbs == 0))
410410 then throw("Invalid position size")
411411 else {
412412 let isShort = (0 > positionSize)
413413 let positionNotional = if ((_option == PNL_OPTION_SPOT))
414414 then {
415415 let $t01626916376 = swapOutput(!(isShort), positionSizeAbs)
416416 let outPositionNotional = $t01626916376._1
417417 let x1 = $t01626916376._2
418418 let x2 = $t01626916376._3
419419 let x3 = $t01626916376._4
420420 outPositionNotional
421421 }
422- else (positionSizeAbs * getOracleTwapPrice())
422+ else muld(positionSizeAbs, getOracleTwapPrice())
423423 let unrealizedPnl = if (isShort)
424424 then (positionOpenNotional - positionNotional)
425425 else (positionNotional - positionOpenNotional)
426426 $Tuple2(positionNotional, unrealizedPnl)
427427 }
428428 }
429429
430430
431431 func calcMarginRatio (_remainMargin,_badDebt,_positionNotional) = divd((_remainMargin - _badDebt), _positionNotional)
432432
433433
434434 func getMarginRatioByOption (_trader,_option) = {
435- let $t01704117152 = getPosition(_trader)
436- let positionSize = $t01704117152._1
437- let positionMargin = $t01704117152._2
438- let pon = $t01704117152._3
439- let positionLstUpdCPF = $t01704117152._4
440- let $t01715817251 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
441- let positionNotional = $t01715817251._1
442- let unrealizedPnl = $t01715817251._2
443- let $t01725617422 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
444- let remainMargin = $t01725617422._1
445- let badDebt = $t01725617422._2
435+ let $t01704617157 = getPosition(_trader)
436+ let positionSize = $t01704617157._1
437+ let positionMargin = $t01704617157._2
438+ let pon = $t01704617157._3
439+ let positionLstUpdCPF = $t01704617157._4
440+ let $t01716317256 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
441+ let positionNotional = $t01716317256._1
442+ let unrealizedPnl = $t01716317256._2
443+ let $t01726117427 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
444+ let remainMargin = $t01726117427._1
445+ let badDebt = $t01726117427._2
446446 calcMarginRatio(remainMargin, badDebt, positionNotional)
447447 }
448448
449449
450450 func getMarginRatio (_trader) = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
451451
452452
453453 func internalClosePosition (_trader) = {
454- let $t01773817866 = getPosition(_trader)
455- let positionSize = $t01773817866._1
456- let positionMargin = $t01773817866._2
457- let positionOpenNotional = $t01773817866._3
458- let positionLstUpdCPF = $t01773817866._4
459- let $t01787217959 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
460- let x1 = $t01787217959._1
461- let unrealizedPnl = $t01787217959._2
462- let $t01796418132 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
463- let remainMargin = $t01796418132._1
464- let badDebt = $t01796418132._2
454+ let $t01774317871 = getPosition(_trader)
455+ let positionSize = $t01774317871._1
456+ let positionMargin = $t01774317871._2
457+ let positionOpenNotional = $t01774317871._3
458+ let positionLstUpdCPF = $t01774317871._4
459+ let $t01787717964 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
460+ let x1 = $t01787717964._1
461+ let unrealizedPnl = $t01787717964._2
462+ let $t01796918137 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
463+ let remainMargin = $t01796918137._1
464+ let badDebt = $t01796918137._2
465465 let exchangedPositionSize = -(positionSize)
466466 let realizedPnl = unrealizedPnl
467467 let marginToVault = -(remainMargin)
468- let $t01825918540 = swapOutput((positionSize > 0), abs(positionSize))
469- let exchangedQuoteAssetAmount = $t01825918540._1
470- let quoteAssetReserveAfter = $t01825918540._2
471- let baseAssetReserveAfter = $t01825918540._3
472- let totalPositionSizeAfter = $t01825918540._4
473- let cumulativeNotionalAfter = $t01825918540._5
474- let totalLongAfter = $t01825918540._6
475- let totalShortAfter = $t01825918540._7
468+ let $t01826418545 = swapOutput((positionSize > 0), abs(positionSize))
469+ let exchangedQuoteAssetAmount = $t01826418545._1
470+ let quoteAssetReserveAfter = $t01826418545._2
471+ let baseAssetReserveAfter = $t01826418545._3
472+ let totalPositionSizeAfter = $t01826418545._4
473+ let cumulativeNotionalAfter = $t01826418545._5
474+ let totalLongAfter = $t01826418545._6
475+ let totalShortAfter = $t01826418545._7
476476 let openInterestNotionalAfter = (openInterestNotional() - positionOpenNotional)
477477 $Tuple12(exchangedPositionSize, badDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, exchangedQuoteAssetAmount, totalLongAfter, totalShortAfter)
478478 }
479479
480480
481481 func getTwapSpotPrice () = {
482482 let minuteId = ((lastBlock.timestamp / 1000) / 60)
483483 let startMinuteId = (minuteId - TWAP_INTERVAL)
484484 let listStr = valueOrElse(getString(this, k_lastDataStr), "")
485485 let list = split(listStr, ",")
486486 func filterFn (accumulator,next) = if ((startMinuteId >= parseIntValue(next)))
487487 then (accumulator :+ parseIntValue(next))
488488 else accumulator
489489
490490 let listF = {
491491 let $l = list
492492 let $s = size($l)
493493 let $acc0 = nil
494494 func $f0_1 ($a,$i) = if (($i >= $s))
495495 then $a
496496 else filterFn($a, $l[$i])
497497
498498 func $f0_2 ($a,$i) = if (($i >= $s))
499499 then $a
500500 else throw("List size exceeds 20")
501501
502502 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
503503 }
504504 let maxIndex = if ((size(listF) > 0))
505505 then max(listF)
506506 else parseIntValue(list[0])
507507 let lastMinuteId = valueOrElse(getInteger(this, k_lastMinuteId), 0)
508508 let endLastCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(lastMinuteId))), 0)
509509 let endLastPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(lastMinuteId))), 0)
510510 let nowCumulativePrice = (endLastCumulativePrice + ((minuteId - lastMinuteId) * endLastPrice))
511511 let startLastCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(maxIndex))), 0)
512512 let startLastPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(maxIndex))), 0)
513513 let startCumulativePrice = (startLastCumulativePrice + ((startMinuteId - maxIndex) * startLastPrice))
514514 ((nowCumulativePrice - startCumulativePrice) / TWAP_INTERVAL)
515515 }
516516
517517
518518 func updateSettings (_initMarginRatio,_mmr,_liquidationFeeRatio,_fundingPeriod,_fee,_spreadLimit,_maxPriceImpact) = [IntegerEntry(k_initMarginRatio, _initMarginRatio), IntegerEntry(k_maintenanceMarginRatio, _mmr), IntegerEntry(k_liquidationFeeRatio, _liquidationFeeRatio), IntegerEntry(k_fundingPeriod, _fundingPeriod), IntegerEntry(k_fee, _fee), IntegerEntry(k_spreadLimit, _spreadLimit), IntegerEntry(k_maxPriceImpact, _maxPriceImpact)]
519519
520520
521521 func updateFunding (_nextFundingBlock,_latestLongCumulativePremiumFraction,_latestShortCumulativePremiumFraction,_longFundingRate,_shortFundingRate) = [IntegerEntry(k_nextFundingBlock, _nextFundingBlock), IntegerEntry(k_latestLongCumulativePremiumFraction, _latestLongCumulativePremiumFraction), IntegerEntry(k_latestShortCumulativePremiumFraction, _latestShortCumulativePremiumFraction), IntegerEntry(k_longFundingRate, _longFundingRate), IntegerEntry(k_shortFundingRate, _shortFundingRate)]
522522
523523
524524 func updatePosition (_address,_size,_margin,_openNotional,_latestCumulativePremiumFraction) = [IntegerEntry(toCompositeKey(k_positionSize, _address), _size), IntegerEntry(toCompositeKey(k_positionMargin, _address), _margin), IntegerEntry(toCompositeKey(k_positionOpenNotional, _address), _openNotional), IntegerEntry(toCompositeKey(k_positionLastUpdatedCumulativePremiumFraction, _address), _latestCumulativePremiumFraction)]
525525
526526
527527 func appendTwap (price) = {
528528 let minuteId = ((lastBlock.timestamp / 1000) / 60)
529529 let previousMinuteId = valueOrElse(getInteger(this, k_lastMinuteId), 0)
530530 if ((previousMinuteId > minuteId))
531531 then throw("TWAP out-of-order")
532532 else {
533533 let lastMinuteId = if ((previousMinuteId == 0))
534534 then minuteId
535535 else previousMinuteId
536536 if ((minuteId > previousMinuteId))
537537 then {
538538 let prevCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(previousMinuteId))), 0)
539539 let prevPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(previousMinuteId))), price)
540540 let lastCumulativePrice = (prevCumulativePrice + ((minuteId - lastMinuteId) * prevPrice))
541541 let list = pushToQueue(strToList(valueOrElse(getString(this, k_lastDataStr), "")), TWAP_INTERVAL, toString(minuteId))
542542 [IntegerEntry(toCompositeKey(k_twapDataLastCumulativePrice, toString(minuteId)), lastCumulativePrice), IntegerEntry(toCompositeKey(k_twapDataLastPrice, toString(minuteId)), price), IntegerEntry(toCompositeKey(k_twapDataPreviousMinuteId, toString(minuteId)), previousMinuteId), IntegerEntry(k_lastMinuteId, minuteId), StringEntry(k_lastDataStr, listToStr(list))]
543543 }
544544 else {
545545 let twapDataPreviousMinuteId = valueOrElse(getInteger(this, toCompositeKey(k_twapDataPreviousMinuteId, toString(minuteId))), 0)
546546 let prevCumulativePrice = valueOrElse(getInteger(this, toCompositeKey(k_twapDataLastCumulativePrice, toString(twapDataPreviousMinuteId))), 0)
547547 let prevPrice = valueOrElse(getInteger(this, toCompositeKey(k_twapDataLastPrice, toString(twapDataPreviousMinuteId))), price)
548548 let lastCumulativePrice = (prevCumulativePrice + ((minuteId - twapDataPreviousMinuteId) * prevPrice))
549549 [IntegerEntry(toCompositeKey(k_twapDataLastCumulativePrice, toString(minuteId)), lastCumulativePrice), IntegerEntry(toCompositeKey(k_twapDataLastPrice, toString(minuteId)), price)]
550550 }
551551 }
552552 }
553553
554554
555555 func updateAmm (_qtAstR,_bsAstR,_totalPositionSizeAfter,_cumulativeNotionalAfter,_openInterestNotional,_totalLongPositionSize,_totalShortPositionSize) = if (((_totalLongPositionSize - _totalShortPositionSize) != _totalPositionSizeAfter))
556556 then throw(((((("Invalid AMM state data: " + toString(_totalLongPositionSize)) + " + ") + toString(_totalShortPositionSize)) + " != ") + toString(_totalPositionSizeAfter)))
557557 else ([IntegerEntry(k_quoteAssetReserve, _qtAstR), IntegerEntry(k_baseAssetReserve, _bsAstR), IntegerEntry(k_totalPositionSize, _totalPositionSizeAfter), IntegerEntry(k_cumulativeNotional, _cumulativeNotionalAfter), IntegerEntry(k_openInterestNotional, _openInterestNotional), IntegerEntry(k_totalLongPositionSize, _totalLongPositionSize), IntegerEntry(k_totalShortPositionSize, _totalShortPositionSize)] ++ appendTwap(divd(_qtAstR, _bsAstR)))
558558
559559
560560 func deletePosition (_address) = [DeleteEntry(toCompositeKey(k_positionSize, _address)), DeleteEntry(toCompositeKey(k_positionMargin, _address)), DeleteEntry(toCompositeKey(k_positionOpenNotional, _address)), DeleteEntry(toCompositeKey(k_positionLastUpdatedCumulativePremiumFraction, _address))]
561561
562562
563563 func withdraw (_address,_amount) = {
564564 let balance = assetBalance(this, quoteAsset())
565565 if ((_amount > balance))
566566 then throw(((("Unable to withdraw " + toString(_amount)) + " from contract balance ") + toString(balance)))
567567 else [ScriptTransfer(_address, _amount, quoteAsset())]
568568 }
569569
570570
571571 func updateBalance (i) = if ((0 > i))
572572 then throw("Balance")
573573 else [IntegerEntry(k_balance, i)]
574574
575575
576576 func transferFee (i) = [ScriptTransfer(stakingAddress(), i, quoteAsset())]
577577
578578
579579 @Callable(i)
580580 func pause () = if ((i.caller != adminAddress()))
581581 then throw("Invalid togglePause params")
582582 else [BooleanEntry(k_paused, true)]
583583
584584
585585
586586 @Callable(i)
587587 func unpause () = if ((i.caller != adminAddress()))
588588 then throw("Invalid togglePause params")
589589 else [BooleanEntry(k_paused, false)]
590590
591591
592592
593593 @Callable(i)
594594 func changeSettings (_initMarginRatio,_mmr,_liquidationFeeRatio,_fundingPeriod,_fee,_spreadLimit,_maxPriceImpact) = if ((i.caller != adminAddress()))
595595 then throw("Invalid changeSettings params")
596596 else updateSettings(_initMarginRatio, _mmr, _liquidationFeeRatio, _fundingPeriod, _fee, _spreadLimit, _maxPriceImpact)
597597
598598
599599
600600 @Callable(i)
601601 func initialize (_qtAstR,_bsAstR,_fundingPeriod,_initMarginRatio,_mmr,_liquidationFeeRatio,_fee,_oracle,_oracleKey,_coordinator,_spreadLimit,_maxPriceImpact) = if (if (if (if (if (if (if (if (if (if ((0 >= _qtAstR))
602602 then true
603603 else (0 >= _bsAstR))
604604 then true
605605 else (0 >= _fundingPeriod))
606606 then true
607607 else (0 >= _initMarginRatio))
608608 then true
609609 else (0 >= _mmr))
610610 then true
611611 else (0 >= _liquidationFeeRatio))
612612 then true
613613 else (0 >= _fee))
614614 then true
615615 else (0 >= _spreadLimit))
616616 then true
617617 else (0 >= _maxPriceImpact))
618618 then true
619619 else initialized())
620620 then throw("Invalid initialize parameters")
621621 else ((((updateAmm(_qtAstR, _bsAstR, 0, 0, 0, 0, 0) ++ updateSettings(_initMarginRatio, _mmr, _liquidationFeeRatio, _fundingPeriod, _fee, _spreadLimit, _maxPriceImpact)) ++ updateFunding((lastBlock.timestamp + _fundingPeriod), 0, 0, 0, 0)) ++ updateBalance(0)) ++ [BooleanEntry(k_initialized, true), StringEntry(k_ora, _oracle), StringEntry(k_ora_key, _oracleKey), StringEntry(k_coordinatorAddress, _coordinator)])
622622
623623
624624
625625 @Callable(i)
626626 func decreasePosition (_amount,_leverage,_minBaseAssetAmount) = if (if (if (if (if (if ((0 >= _amount))
627627 then true
628628 else if (((1 * DECIMAL_UNIT) > _leverage))
629629 then true
630630 else (_leverage > (3 * DECIMAL_UNIT)))
631631 then true
632632 else !(initialized()))
633633 then true
634634 else !(requireMoreMarginRatio(divd(DECIMAL_UNIT, _leverage), initMarginRatio(), true)))
635635 then true
636636 else !(requireOpenPosition(toString(i.caller))))
637637 then true
638638 else paused())
639639 then throw("Invalid decreasePosition parameters")
640640 else {
641- let $t02838128533 = getPosition(toString(i.caller))
642- let oldPositionSize = $t02838128533._1
643- let oldPositionMargin = $t02838128533._2
644- let oldPositionOpenNotional = $t02838128533._3
645- let oldPositionLstUpdCPF = $t02838128533._4
641+ let $t02838628538 = getPosition(toString(i.caller))
642+ let oldPositionSize = $t02838628538._1
643+ let oldPositionMargin = $t02838628538._2
644+ let oldPositionOpenNotional = $t02838628538._3
645+ let oldPositionLstUpdCPF = $t02838628538._4
646646 let _direction = if ((oldPositionSize > 0))
647647 then DIR_SHORT
648648 else DIR_LONG
649649 let isAdd = (_direction == DIR_LONG)
650650 let openNotional = muld(_amount, _leverage)
651- let $t02870628822 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
652- let oldPositionNotional = $t02870628822._1
653- let unrealizedPnl = $t02870628822._2
654- let $t02882831377 = if ((oldPositionNotional > openNotional))
651+ let $t02871128827 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
652+ let oldPositionNotional = $t02871128827._1
653+ let unrealizedPnl = $t02871128827._2
654+ let $t02883331382 = if ((oldPositionNotional > openNotional))
655655 then {
656- let $t02920529424 = swapInput(isAdd, openNotional)
657- let exchangedPositionSize = $t02920529424._1
658- let quoteAssetReserveAfter = $t02920529424._2
659- let baseAssetReserveAfter = $t02920529424._3
660- let totalPositionSizeAfter = $t02920529424._4
661- let cumulativeNotionalAfter = $t02920529424._5
656+ let $t02921029429 = swapInput(isAdd, openNotional)
657+ let exchangedPositionSize = $t02921029429._1
658+ let quoteAssetReserveAfter = $t02921029429._2
659+ let baseAssetReserveAfter = $t02921029429._3
660+ let totalPositionSizeAfter = $t02921029429._4
661+ let cumulativeNotionalAfter = $t02921029429._5
662662 let exchangedPositionSizeAbs = abs(exchangedPositionSize)
663663 if (if ((_minBaseAssetAmount != 0))
664664 then (_minBaseAssetAmount > exchangedPositionSizeAbs)
665665 else false)
666666 then throw(((("Too little base asset exchanged, got " + toString(exchangedPositionSizeAbs)) + " expected ") + toString(_minBaseAssetAmount)))
667667 else {
668668 let realizedPnl = divd(muld(unrealizedPnl, exchangedPositionSizeAbs), abs(oldPositionSize))
669- let $t02986130106 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
670- let remainMargin = $t02986130106._1
671- let badDebt = $t02986130106._2
672- let fundingPayment = $t02986130106._3
669+ let $t02986630111 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
670+ let remainMargin = $t02986630111._1
671+ let badDebt = $t02986630111._2
672+ let fundingPayment = $t02986630111._3
673673 let exchangedQuoteAssetAmount = openNotional
674674 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
675675 let remainOpenNotional = if ((oldPositionSize > 0))
676676 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
677677 else ((unrealizedPnlAfter + oldPositionNotional) - exchangedQuoteAssetAmount)
678678 let newPositionSize = (oldPositionSize + exchangedPositionSize)
679679 $Tuple11(newPositionSize, remainMargin, abs(remainOpenNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, (openInterestNotional() - openNotional), (totalLongPositionSize() - (if ((newPositionSize > 0))
680680 then abs(exchangedPositionSize)
681681 else 0)), (totalShortPositionSize() - (if ((0 > newPositionSize))
682682 then abs(exchangedPositionSize)
683683 else 0)))
684684 }
685685 }
686686 else throw("Close position first")
687- let newPositionSize = $t02882831377._1
688- let newPositionRemainMargin = $t02882831377._2
689- let newPositionOpenNotional = $t02882831377._3
690- let newPositionLatestCPF = $t02882831377._4
691- let baseAssetReserveAfter = $t02882831377._5
692- let quoteAssetReserveAfter = $t02882831377._6
693- let totalPositionSizeAfter = $t02882831377._7
694- let cumulativeNotionalAfter = $t02882831377._8
695- let openInterestNotionalAfter = $t02882831377._9
696- let totalLongAfter = $t02882831377._10
697- let totalShortAfter = $t02882831377._11
687+ let newPositionSize = $t02883331382._1
688+ let newPositionRemainMargin = $t02883331382._2
689+ let newPositionOpenNotional = $t02883331382._3
690+ let newPositionLatestCPF = $t02883331382._4
691+ let baseAssetReserveAfter = $t02883331382._5
692+ let quoteAssetReserveAfter = $t02883331382._6
693+ let totalPositionSizeAfter = $t02883331382._7
694+ let cumulativeNotionalAfter = $t02883331382._8
695+ let openInterestNotionalAfter = $t02883331382._9
696+ let totalLongAfter = $t02883331382._10
697+ let totalShortAfter = $t02883331382._11
698698 (updatePosition(toString(i.caller), newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter))
699699 }
700700
701701
702702
703703 @Callable(i)
704704 func increasePosition (_direction,_leverage,_minBaseAssetAmount) = {
705705 let _rawAmount = i.payments[0].amount
706706 if (if (if (if (if (if (if (if ((_direction != DIR_LONG))
707707 then (_direction != DIR_SHORT)
708708 else false)
709709 then true
710710 else (0 >= _rawAmount))
711711 then true
712712 else if (((1 * DECIMAL_UNIT) > _leverage))
713713 then true
714714 else (_leverage > (3 * DECIMAL_UNIT)))
715715 then true
716716 else !(initialized()))
717717 then true
718718 else (i.payments[0].assetId != quoteAsset()))
719719 then true
720720 else !(requireMoreMarginRatio(divd(DECIMAL_UNIT, _leverage), initMarginRatio(), true)))
721721 then true
722722 else paused())
723723 then throw("Invalid increasePosition parameters")
724724 else {
725725 let feeAmount = muld(_rawAmount, fee())
726726 let _amount = (_rawAmount - feeAmount)
727- let $t03241332565 = getPosition(toString(i.caller))
728- let oldPositionSize = $t03241332565._1
729- let oldPositionMargin = $t03241332565._2
730- let oldPositionOpenNotional = $t03241332565._3
731- let oldPositionLstUpdCPF = $t03241332565._4
727+ let $t03241832570 = getPosition(toString(i.caller))
728+ let oldPositionSize = $t03241832570._1
729+ let oldPositionMargin = $t03241832570._2
730+ let oldPositionOpenNotional = $t03241832570._3
731+ let oldPositionLstUpdCPF = $t03241832570._4
732732 let isNewPosition = (oldPositionSize == 0)
733733 let isSameDirection = if ((oldPositionSize > 0))
734734 then (_direction == DIR_LONG)
735735 else (_direction == DIR_SHORT)
736736 let expandExisting = if (!(isNewPosition))
737737 then isSameDirection
738738 else false
739739 let isAdd = (_direction == DIR_LONG)
740- let $t03285435243 = if (if (isNewPosition)
740+ let $t03285935248 = if (if (isNewPosition)
741741 then true
742742 else expandExisting)
743743 then {
744744 let openNotional = muld(_amount, _leverage)
745- let $t03327833484 = swapInput(isAdd, openNotional)
746- let amountBaseAssetBought = $t03327833484._1
747- let quoteAssetReserveAfter = $t03327833484._2
748- let baseAssetReserveAfter = $t03327833484._3
749- let totalPositionSizeAfter = $t03327833484._4
750- let cumulativeNotionalAfter = $t03327833484._5
745+ let $t03328333489 = swapInput(isAdd, openNotional)
746+ let amountBaseAssetBought = $t03328333489._1
747+ let quoteAssetReserveAfter = $t03328333489._2
748+ let baseAssetReserveAfter = $t03328333489._3
749+ let totalPositionSizeAfter = $t03328333489._4
750+ let cumulativeNotionalAfter = $t03328333489._5
751751 if (if ((_minBaseAssetAmount != 0))
752752 then (_minBaseAssetAmount > abs(amountBaseAssetBought))
753753 else false)
754754 then throw(((("Limit error: " + toString(abs(amountBaseAssetBought))) + " < ") + toString(_minBaseAssetAmount)))
755755 else {
756756 let newPositionSize = (oldPositionSize + amountBaseAssetBought)
757757 let increaseMarginRequirement = divd(openNotional, _leverage)
758- let $t03386534104 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
759- let remainMargin = $t03386534104._1
760- let x1 = $t03386534104._2
761- let x2 = $t03386534104._3
758+ let $t03387034109 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
759+ let remainMargin = $t03387034109._1
760+ let x1 = $t03387034109._2
761+ let x2 = $t03387034109._3
762762 $Tuple11(newPositionSize, remainMargin, (oldPositionOpenNotional + openNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, (openInterestNotional() + openNotional), (totalLongPositionSize() + (if ((newPositionSize > 0))
763763 then abs(amountBaseAssetBought)
764764 else 0)), (totalShortPositionSize() + (if ((0 > newPositionSize))
765765 then abs(amountBaseAssetBought)
766766 else 0)))
767767 }
768768 }
769769 else {
770770 let openNotional = muld(_amount, _leverage)
771- let $t03493635052 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
772- let oldPositionNotional = $t03493635052._1
773- let unrealizedPnl = $t03493635052._2
771+ let $t03494135057 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
772+ let oldPositionNotional = $t03494135057._1
773+ let unrealizedPnl = $t03494135057._2
774774 if ((oldPositionNotional > openNotional))
775775 then throw("Use decreasePosition to decrease position size")
776776 else throw("Close position first")
777777 }
778- let newPositionSize = $t03285435243._1
779- let newPositionRemainMargin = $t03285435243._2
780- let newPositionOpenNotional = $t03285435243._3
781- let newPositionLatestCPF = $t03285435243._4
782- let baseAssetReserveAfter = $t03285435243._5
783- let quoteAssetReserveAfter = $t03285435243._6
784- let totalPositionSizeAfter = $t03285435243._7
785- let cumulativeNotionalAfter = $t03285435243._8
786- let openInterestNotionalAfter = $t03285435243._9
787- let totalLongAfter = $t03285435243._10
788- let totalShortAfter = $t03285435243._11
778+ let newPositionSize = $t03285935248._1
779+ let newPositionRemainMargin = $t03285935248._2
780+ let newPositionOpenNotional = $t03285935248._3
781+ let newPositionLatestCPF = $t03285935248._4
782+ let baseAssetReserveAfter = $t03285935248._5
783+ let quoteAssetReserveAfter = $t03285935248._6
784+ let totalPositionSizeAfter = $t03285935248._7
785+ let cumulativeNotionalAfter = $t03285935248._8
786+ let openInterestNotionalAfter = $t03285935248._9
787+ let totalLongAfter = $t03285935248._10
788+ let totalShortAfter = $t03285935248._11
789789 let feeToStakers = (feeAmount / 2)
790790 let feeToInsurance = (feeAmount - feeToStakers)
791791 let stake = invoke(quoteAssetStaking(), "lockNeutrinoSP", [toString(stakingAddress()), ALL_FEES], [AttachedPayment(quoteAsset(), _amount)])
792792 if ((stake == stake))
793793 then {
794794 let depositInsurance = invoke(insuranceAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), feeToInsurance)])
795795 if ((depositInsurance == depositInsurance))
796796 then (((updatePosition(toString(i.caller), newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter)) ++ transferFee(feeToStakers)) ++ updateBalance((cbalance() + _amount)))
797797 else throw("Strict value is not equal to itself.")
798798 }
799799 else throw("Strict value is not equal to itself.")
800800 }
801801 }
802802
803803
804804
805805 @Callable(i)
806806 func addMargin () = {
807807 let _rawAmount = i.payments[0].amount
808808 if (if (if (if ((i.payments[0].assetId != quoteAsset()))
809809 then true
810810 else !(requireOpenPosition(toString(i.caller))))
811811 then true
812812 else !(initialized()))
813813 then true
814814 else paused())
815815 then throw("Invalid addMargin parameters")
816816 else {
817817 let feeAmount = muld(_rawAmount, fee())
818818 let _amount = (_rawAmount - feeAmount)
819- let $t03651936671 = getPosition(toString(i.caller))
820- let oldPositionSize = $t03651936671._1
821- let oldPositionMargin = $t03651936671._2
822- let oldPositionOpenNotional = $t03651936671._3
823- let oldPositionLstUpdCPF = $t03651936671._4
819+ let $t03652436676 = getPosition(toString(i.caller))
820+ let oldPositionSize = $t03652436676._1
821+ let oldPositionMargin = $t03652436676._2
822+ let oldPositionOpenNotional = $t03652436676._3
823+ let oldPositionLstUpdCPF = $t03652436676._4
824824 let feeToStakers = (feeAmount / 2)
825825 let feeToInsurance = (feeAmount - feeToStakers)
826826 let stake = invoke(quoteAssetStaking(), "lockNeutrinoSP", [toString(stakingAddress()), ALL_FEES], [AttachedPayment(quoteAsset(), _amount)])
827827 if ((stake == stake))
828828 then {
829829 let depositInsurance = invoke(insuranceAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), feeToInsurance)])
830830 if ((depositInsurance == depositInsurance))
831831 then ((updatePosition(toString(i.caller), oldPositionSize, (oldPositionMargin + _amount), oldPositionOpenNotional, oldPositionLstUpdCPF) ++ transferFee(feeToStakers)) ++ updateBalance((cbalance() + _amount)))
832832 else throw("Strict value is not equal to itself.")
833833 }
834834 else throw("Strict value is not equal to itself.")
835835 }
836836 }
837837
838838
839839
840840 @Callable(i)
841841 func removeMargin (_amount) = if (if (if (if ((0 >= _amount))
842842 then true
843843 else !(requireOpenPosition(toString(i.caller))))
844844 then true
845845 else !(initialized()))
846846 then true
847847 else paused())
848848 then throw("Invalid removeMargin parameters")
849849 else {
850- let $t03759137743 = getPosition(toString(i.caller))
851- let oldPositionSize = $t03759137743._1
852- let oldPositionMargin = $t03759137743._2
853- let oldPositionOpenNotional = $t03759137743._3
854- let oldPositionLstUpdCPF = $t03759137743._4
850+ let $t03759637748 = getPosition(toString(i.caller))
851+ let oldPositionSize = $t03759637748._1
852+ let oldPositionMargin = $t03759637748._2
853+ let oldPositionOpenNotional = $t03759637748._3
854+ let oldPositionLstUpdCPF = $t03759637748._4
855855 let marginDelta = -(_amount)
856- let $t03778037959 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
857- let remainMargin = $t03778037959._1
858- let badDebt = $t03778037959._2
856+ let $t03778537964 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
857+ let remainMargin = $t03778537964._1
858+ let badDebt = $t03778537964._2
859859 if ((badDebt != 0))
860860 then throw("Invalid removed margin amount")
861861 else {
862862 let marginRatio = calcMarginRatio(remainMargin, badDebt, oldPositionOpenNotional)
863863 if (!(requireMoreMarginRatio(marginRatio, initMarginRatio(), true)))
864864 then throw(((("Too much margin removed: " + toString(marginRatio)) + " < ") + toString(initMarginRatio())))
865865 else {
866866 let unstake = invoke(quoteAssetStaking(), "unlockNeutrino", [_amount, toBase58String(quoteAsset())], nil)
867867 if ((unstake == unstake))
868868 then ((updatePosition(toString(i.caller), oldPositionSize, remainMargin, oldPositionOpenNotional, latestCumulativePremiumFraction(oldPositionSize)) ++ withdraw(i.caller, _amount)) ++ updateBalance((cbalance() - _amount)))
869869 else throw("Strict value is not equal to itself.")
870870 }
871871 }
872872 }
873873
874874
875875
876876 @Callable(i)
877877 func closePosition () = if (if (if (!(requireOpenPosition(toString(i.caller))))
878878 then true
879879 else !(initialized()))
880880 then true
881881 else paused())
882882 then throw("Invalid closePosition parameters")
883883 else {
884- let $t03905539439 = internalClosePosition(toString(i.caller))
885- let x1 = $t03905539439._1
886- let positionBadDebt = $t03905539439._2
887- let realizedPnl = $t03905539439._3
888- let marginToVault = $t03905539439._4
889- let quoteAssetReserveAfter = $t03905539439._5
890- let baseAssetReserveAfter = $t03905539439._6
891- let totalPositionSizeAfter = $t03905539439._7
892- let cumulativeNotionalAfter = $t03905539439._8
893- let openInterestNotionalAfter = $t03905539439._9
894- let x2 = $t03905539439._10
895- let totalLongAfter = $t03905539439._11
896- let totalShortAfter = $t03905539439._12
884+ let $t03906039444 = internalClosePosition(toString(i.caller))
885+ let x1 = $t03906039444._1
886+ let positionBadDebt = $t03906039444._2
887+ let realizedPnl = $t03906039444._3
888+ let marginToVault = $t03906039444._4
889+ let quoteAssetReserveAfter = $t03906039444._5
890+ let baseAssetReserveAfter = $t03906039444._6
891+ let totalPositionSizeAfter = $t03906039444._7
892+ let cumulativeNotionalAfter = $t03906039444._8
893+ let openInterestNotionalAfter = $t03906039444._9
894+ let x2 = $t03906039444._10
895+ let totalLongAfter = $t03906039444._11
896+ let totalShortAfter = $t03906039444._12
897897 if ((positionBadDebt > 0))
898898 then throw("Unable to close position with bad debt")
899899 else {
900900 let withdrawAmount = abs(marginToVault)
901901 let ammBalance = (cbalance() - withdrawAmount)
902- let $t03964839790 = if ((0 > ammBalance))
902+ let $t03965339795 = if ((0 > ammBalance))
903903 then $Tuple2(0, abs(ammBalance))
904904 else $Tuple2(ammBalance, 0)
905- let ammNewBalance = $t03964839790._1
906- let getFromInsurance = $t03964839790._2
905+ let ammNewBalance = $t03965339795._1
906+ let getFromInsurance = $t03965339795._2
907907 let x = if ((getFromInsurance > 0))
908908 then {
909909 let withdrawInsurance = invoke(insuranceAddress(), "withdraw", [getFromInsurance], nil)
910910 if ((withdrawInsurance == withdrawInsurance))
911911 then nil
912912 else throw("Strict value is not equal to itself.")
913913 }
914914 else nil
915915 if ((x == x))
916916 then {
917917 let unstake = invoke(quoteAssetStaking(), "unlockNeutrino", [(withdrawAmount - getFromInsurance), toBase58String(quoteAsset())], nil)
918918 if ((unstake == unstake))
919919 then (((deletePosition(toString(i.caller)) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter)) ++ withdraw(i.caller, withdrawAmount)) ++ updateBalance(ammNewBalance))
920920 else throw("Strict value is not equal to itself.")
921921 }
922922 else throw("Strict value is not equal to itself.")
923923 }
924924 }
925925
926926
927927
928928 @Callable(i)
929929 func liquidate (_trader) = {
930930 let spotMarginRatio = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
931931 let marginRatio = if (isOverFluctuationLimit())
932932 then {
933933 let oracleMarginRatio = getMarginRatioByOption(_trader, PNL_OPTION_ORACLE)
934934 vmax(spotMarginRatio, oracleMarginRatio)
935935 }
936936 else spotMarginRatio
937937 if (if (if (if (!(requireMoreMarginRatio(marginRatio, maintenanceMarginRatio(), false)))
938938 then true
939939 else !(requireOpenPosition(_trader)))
940940 then true
941941 else !(initialized()))
942942 then true
943943 else paused())
944944 then throw("Unable to liquidate")
945945 else {
946- let $t04133841754 = internalClosePosition(_trader)
947- let x1 = $t04133841754._1
948- let badDebt = $t04133841754._2
949- let x2 = $t04133841754._3
950- let x3 = $t04133841754._4
951- let quoteAssetReserveAfter = $t04133841754._5
952- let baseAssetReserveAfter = $t04133841754._6
953- let totalPositionSizeAfter = $t04133841754._7
954- let cumulativeNotionalAfter = $t04133841754._8
955- let openInterestNotionalAfter = $t04133841754._9
956- let exchangedQuoteAssetAmount = $t04133841754._10
957- let totalLongAfter = $t04133841754._11
958- let totalShortAfter = $t04133841754._12
946+ let $t04134341759 = internalClosePosition(_trader)
947+ let x1 = $t04134341759._1
948+ let badDebt = $t04134341759._2
949+ let x2 = $t04134341759._3
950+ let x3 = $t04134341759._4
951+ let quoteAssetReserveAfter = $t04134341759._5
952+ let baseAssetReserveAfter = $t04134341759._6
953+ let totalPositionSizeAfter = $t04134341759._7
954+ let cumulativeNotionalAfter = $t04134341759._8
955+ let openInterestNotionalAfter = $t04134341759._9
956+ let exchangedQuoteAssetAmount = $t04134341759._10
957+ let totalLongAfter = $t04134341759._11
958+ let totalShortAfter = $t04134341759._12
959959 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
960960 let feeToLiquidator = (liquidationPenalty / 2)
961961 let feeToInsurance = (liquidationPenalty - feeToLiquidator)
962962 let ammBalance = (cbalance() - liquidationPenalty)
963- let $t04215242287 = if ((0 > ammBalance))
963+ let $t04215742292 = if ((0 > ammBalance))
964964 then $Tuple2(0, abs(ammBalance))
965965 else $Tuple2(ammBalance, 0)
966- let newAmmBalance = $t04215242287._1
967- let takeFromInsurance = $t04215242287._2
966+ let newAmmBalance = $t04215742292._1
967+ let takeFromInsurance = $t04215742292._2
968968 let x = if ((takeFromInsurance > 0))
969969 then {
970970 let withdrawInsurance = invoke(insuranceAddress(), "withdraw", [takeFromInsurance], nil)
971971 if ((withdrawInsurance == withdrawInsurance))
972972 then nil
973973 else throw("Strict value is not equal to itself.")
974974 }
975975 else nil
976976 if ((x == x))
977977 then {
978978 let unstake = invoke(quoteAssetStaking(), "unlockNeutrino", [(liquidationPenalty - takeFromInsurance), toBase58String(quoteAsset())], nil)
979979 if ((unstake == unstake))
980980 then {
981981 let depositInsurance = invoke(insuranceAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), feeToInsurance)])
982982 if ((depositInsurance == depositInsurance))
983983 then (((deletePosition(_trader) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter)) ++ withdraw(i.caller, feeToLiquidator)) ++ updateBalance(newAmmBalance))
984984 else throw("Strict value is not equal to itself.")
985985 }
986986 else throw("Strict value is not equal to itself.")
987987 }
988988 else throw("Strict value is not equal to itself.")
989989 }
990990 }
991991
992992
993993
994994 @Callable(i)
995995 func payFunding () = {
996996 let fundingBlockTimestamp = nextFundingBlockTimestamp()
997997 if (if (if ((fundingBlockTimestamp > lastBlock.timestamp))
998998 then true
999999 else !(initialized()))
10001000 then true
10011001 else paused())
10021002 then throw(((("Invalid funding block timestamp: " + toString(lastBlock.timestamp)) + " < ") + toString(fundingBlockTimestamp)))
10031003 else {
10041004 let underlyingPrice = getOracleTwapPrice()
10051005 let spotTwapPrice = getTwapSpotPrice()
10061006 let premium = (spotTwapPrice - underlyingPrice)
1007- let $t04366344998 = if (if ((totalShortPositionSize() == 0))
1007+ let $t04366845003 = if (if ((totalShortPositionSize() == 0))
10081008 then true
10091009 else (totalLongPositionSize() == 0))
10101010 then $Tuple2(0, 0)
10111011 else if ((0 > premium))
10121012 then {
10131013 let shortPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
10141014 let longPremiumFraction = divd(muld(shortPremiumFraction, totalShortPositionSize()), totalLongPositionSize())
10151015 $Tuple2(shortPremiumFraction, longPremiumFraction)
10161016 }
10171017 else {
10181018 let longPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
10191019 let shortPremiumFraction = divd(muld(longPremiumFraction, totalLongPositionSize()), totalShortPositionSize())
10201020 $Tuple2(shortPremiumFraction, longPremiumFraction)
10211021 }
1022- let shortPremiumFraction = $t04366344998._1
1023- let longPremiumFraction = $t04366344998._2
1022+ let shortPremiumFraction = $t04366845003._1
1023+ let longPremiumFraction = $t04366845003._2
10241024 updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), divd(longPremiumFraction, underlyingPrice), divd(shortPremiumFraction, underlyingPrice))
10251025 }
10261026 }
10271027
10281028
10291029
10301030 @Callable(i)
10311031 func v_get (_trader) = {
1032- let $t04537345426 = internalClosePosition(_trader)
1033- let x1 = $t04537345426._1
1034- let x2 = $t04537345426._2
1035- let x3 = $t04537345426._3
1036- let x4 = $t04537345426._4
1032+ let $t04537845431 = internalClosePosition(_trader)
1033+ let x1 = $t04537845431._1
1034+ let x2 = $t04537845431._2
1035+ let x3 = $t04537845431._3
1036+ let x4 = $t04537845431._4
10371037 throw((((s(x2) + s(x3)) + s(x4)) + s(getMarginRatio(_trader))))
10381038 }
10391039
10401040
10411041
10421042 @Callable(i)
10431043 func view_calcRemainMarginWithFundingPayment (_trader) = {
1044- let $t04557345684 = getPosition(_trader)
1045- let positionSize = $t04557345684._1
1046- let positionMargin = $t04557345684._2
1047- let pon = $t04557345684._3
1048- let positionLstUpdCPF = $t04557345684._4
1049- let $t04568945790 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1050- let positionNotional = $t04568945790._1
1051- let unrealizedPnl = $t04568945790._2
1052- let $t04579545977 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1053- let remainMargin = $t04579545977._1
1054- let badDebt = $t04579545977._2
1055- let fundingPayment = $t04579545977._3
1044+ let $t04557845689 = getPosition(_trader)
1045+ let positionSize = $t04557845689._1
1046+ let positionMargin = $t04557845689._2
1047+ let pon = $t04557845689._3
1048+ let positionLstUpdCPF = $t04557845689._4
1049+ let $t04569445795 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1050+ let positionNotional = $t04569445795._1
1051+ let unrealizedPnl = $t04569445795._2
1052+ let $t04580045982 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1053+ let remainMargin = $t04580045982._1
1054+ let badDebt = $t04580045982._2
1055+ let fundingPayment = $t04580045982._3
10561056 throw(((s(remainMargin) + s(fundingPayment)) + s(getMarginRatio(_trader))))
10571057 }
10581058
10591059
10601060 @Verifier(tx)
10611061 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], adminPublicKey())
10621062

github/deemru/w8io/026f985 
151.39 ms