tx · FuSgDV6SfcmmPtZSfHjrwEpJySTKm1qH2RLL9vaahj3Z

3N8G95pEaYEhZ4U3m3UrzpEzwBFn5vvXsZH:  -0.05000000 Waves

2022.07.02 22:12 [2122442] smart account 3N8G95pEaYEhZ4U3m3UrzpEzwBFn5vvXsZH > SELF 0.00000000 Waves

{ "type": 13, "id": "FuSgDV6SfcmmPtZSfHjrwEpJySTKm1qH2RLL9vaahj3Z", "fee": 5000000, "feeAssetId": null, "timestamp": 1656789153930, "version": 2, "chainId": 84, "sender": "3N8G95pEaYEhZ4U3m3UrzpEzwBFn5vvXsZH", "senderPublicKey": "Hj6oyH6As5UWo8fZ1K4hPsEY7nxH3MvhBqDD6axiwjXs", "proofs": [ "3QfnGKzD47cAQTZd2UUaqg6khN3Cqs3rxiBLwuuNfcaRb7cxMoLTHfdLDZBWpPgci9GT4vMHwB8AJza3gBVm77Lt" ], "script": "base64:AAIFAAAAAAAAAEoIAhIAEgASCQoHAQEBAQEBARIOCgwBAQEBAQEBCAgIAQESBgoEAQEBARIFCgMBAQESABIDCgEBEgASAwoBCBIAEgMKAQgSAwoBCAAAAHAAAAAACWtfb3JhX2tleQIAAAAJa19vcmFfa2V5AAAAAA9rX29yYV9ibG9ja19rZXkCAAAAD2tfb3JhX2Jsb2NrX2tleQAAAAAFa19vcmECAAAABWtfb3JhAAAAAAlrX2JhbGFuY2UCAAAACWtfYmFsYW5jZQAAAAAOa19wb3NpdGlvblNpemUCAAAADmtfcG9zaXRpb25TaXplAAAAABBrX3Bvc2l0aW9uTWFyZ2luAgAAABBrX3Bvc2l0aW9uTWFyZ2luAAAAABZrX3Bvc2l0aW9uT3Blbk5vdGlvbmFsAgAAABZrX3Bvc2l0aW9uT3Blbk5vdGlvbmFsAAAAAC5rX3Bvc2l0aW9uTGFzdFVwZGF0ZWRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAgAAABJrX3Bvc2l0aW9uRnJhY3Rpb24AAAAADWtfaW5pdGlhbGl6ZWQCAAAADWtfaW5pdGlhbGl6ZWQAAAAACGtfcGF1c2VkAgAAAAhrX3BhdXNlZAAAAAAFa19mZWUCAAAABWtfZmVlAAAAAA9rX2Z1bmRpbmdQZXJpb2QCAAAAD2tfZnVuZGluZ1BlcmlvZAAAAAARa19pbml0TWFyZ2luUmF0aW8CAAAAEWtfaW5pdE1hcmdpblJhdGlvAAAAABhrX21haW50ZW5hbmNlTWFyZ2luUmF0aW8CAAAABWtfbW1yAAAAABVrX2xpcXVpZGF0aW9uRmVlUmF0aW8CAAAAFWtfbGlxdWlkYXRpb25GZWVSYXRpbwAAAAANa19zcHJlYWRMaW1pdAIAAAANa19zcHJlYWRMaW1pdAAAAAAQa19tYXhQcmljZUltcGFjdAIAAAAQa19tYXhQcmljZUltcGFjdAAAAAANa19sYXN0RGF0YVN0cgIAAAANa19sYXN0RGF0YVN0cgAAAAAOa19sYXN0TWludXRlSWQCAAAADmtfbGFzdE1pbnV0ZUlkAAAAAB1rX3R3YXBEYXRhTGFzdEN1bXVsYXRpdmVQcmljZQIAAAAda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UAAAAAE2tfdHdhcERhdGFMYXN0UHJpY2UCAAAAE2tfdHdhcERhdGFMYXN0UHJpY2UAAAAAJWtfbGF0ZXN0TG9uZ0N1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24CAAAAG2tfbGF0ZXN0TG9uZ1ByZW1pdW1GcmFjdGlvbgAAAAAma19sYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24CAAAAHGtfbGF0ZXN0U2hvcnRQcmVtaXVtRnJhY3Rpb24AAAAAEmtfbmV4dEZ1bmRpbmdCbG9jawIAAAAea19uZXh0RnVuZGluZ0Jsb2NrTWluVGltZXN0YW1wAAAAABFrX2xvbmdGdW5kaW5nUmF0ZQIAAAARa19sb25nRnVuZGluZ1JhdGUAAAAAEmtfc2hvcnRGdW5kaW5nUmF0ZQIAAAASa19zaG9ydEZ1bmRpbmdSYXRlAAAAABNrX3F1b3RlQXNzZXRSZXNlcnZlAgAAAAhrX3F0QXN0UgAAAAASa19iYXNlQXNzZXRSZXNlcnZlAgAAAAhrX2JzQXN0UgAAAAATa190b3RhbFBvc2l0aW9uU2l6ZQIAAAATa190b3RhbFBvc2l0aW9uU2l6ZQAAAAAXa190b3RhbExvbmdQb3NpdGlvblNpemUCAAAAF2tfdG90YWxMb25nUG9zaXRpb25TaXplAAAAABhrX3RvdGFsU2hvcnRQb3NpdGlvblNpemUCAAAAGGtfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAAAAAUa19jdW11bGF0aXZlTm90aW9uYWwCAAAAFGtfY3VtdWxhdGl2ZU5vdGlvbmFsAAAAABZrX29wZW5JbnRlcmVzdE5vdGlvbmFsAgAAABZrX29wZW5JbnRlcmVzdE5vdGlvbmFsAAAAABRrX2Nvb3JkaW5hdG9yQWRkcmVzcwIAAAAUa19jb29yZGluYXRvckFkZHJlc3MAAAAAE2tfaW5zdXJhbmNlX2FkZHJlc3MCAAAAE2tfaW5zdXJhbmNlX2FkZHJlc3MAAAAAD2tfYWRtaW5fYWRkcmVzcwIAAAAPa19hZG1pbl9hZGRyZXNzAAAAABJrX2FkbWluX3B1YmxpY19rZXkCAAAAEmtfYWRtaW5fcHVibGljX2tleQAAAAANa19xdW90ZV9hc3NldAIAAAANa19xdW90ZV9hc3NldAAAAAAPa19xdW90ZV9zdGFraW5nAgAAAA9rX3F1b3RlX3N0YWtpbmcAAAAAEWtfc3Rha2luZ19hZGRyZXNzAgAAABFrX3N0YWtpbmdfYWRkcmVzcwEAAAALY29vcmRpbmF0b3IAAAAACQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgUAAAAEdGhpcwUAAAAUa19jb29yZGluYXRvckFkZHJlc3MCAAAAE0Nvb3JkaW5hdG9yIG5vdCBzZXQBAAAADGFkbWluQWRkcmVzcwAAAAAJAAQmAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgkBAAAAC2Nvb3JkaW5hdG9yAAAAAAUAAAAPa19hZG1pbl9hZGRyZXNzAQAAAA5hZG1pblB1YmxpY0tleQAAAAAJAAJZAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgkBAAAAC2Nvb3JkaW5hdG9yAAAAAAUAAAASa19hZG1pbl9wdWJsaWNfa2V5AQAAAApxdW90ZUFzc2V0AAAAAAkAAlkAAAABCQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACCQEAAAALY29vcmRpbmF0b3IAAAAABQAAAA1rX3F1b3RlX2Fzc2V0AQAAABFxdW90ZUFzc2V0U3Rha2luZwAAAAAJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACCQEAAAALY29vcmRpbmF0b3IAAAAABQAAAA9rX3F1b3RlX3N0YWtpbmcCAAAAG1F1b3RlIGFzc2V0IHN0YWtpbmcgbm90IHNldAEAAAAOc3Rha2luZ0FkZHJlc3MAAAAACQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgkBAAAAC2Nvb3JkaW5hdG9yAAAAAAUAAAARa19zdGFraW5nX2FkZHJlc3MCAAAAEUluc3VyYW5jZSBub3Qgc2V0AQAAABBpbnN1cmFuY2VBZGRyZXNzAAAAAAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIJAQAAAAtjb29yZGluYXRvcgAAAAAFAAAAE2tfaW5zdXJhbmNlX2FkZHJlc3MCAAAAEUluc3VyYW5jZSBub3Qgc2V0AAAAAAhESVJfTE9ORwAAAAAAAAAAAQAAAAAJRElSX1NIT1JUAAAAAAAAAAACAAAAABZGVU5ESU5HX0JMT0NLX0lOVEVSVkFMAAAAAAAAAAA8AAAAAA1UV0FQX0lOVEVSVkFMAAAAAAAAAAAPAAAAAA9PUkFDTEVfSU5URVJWQUwAAAAAAAAAAA8AAAAAB1NFQ09ORFMAAAAAAAAAA+gAAAAADERFQ0lNQUxfVU5JVAkAAGgAAAACAAAAAAAAAAABCQAAaAAAAAIJAABoAAAAAgkAAGgAAAACCQAAaAAAAAIJAABoAAAAAgAAAAAAAAAACgAAAAAAAAAACgAAAAAAAAAACgAAAAAAAAAACgAAAAAAAAAACgAAAAAAAAAACgAAAAAPSFVORFJFRF9QRVJDRU5UCQAAaAAAAAIAAAAAAAAAAGQFAAAADERFQ0lNQUxfVU5JVAAAAAAHT05FX0RBWQkAAGgAAAACAAAAAAAAAVGABQAAAAxERUNJTUFMX1VOSVQAAAAACEFMTF9GRUVTAAAAAAAAAABkAAAAAA9QTkxfT1BUSU9OX1NQT1QAAAAAAAAAAAEAAAAAEVBOTF9PUFRJT05fT1JBQ0xFAAAAAAAAAAACAQAAAAFzAAAAAQAAAAJfeAkAASwAAAACCQABpAAAAAEFAAAAAl94AgAAAAEsAQAAAARkaXZkAAAAAgAAAAJfeAAAAAJfeQkBAAAACGZyYWN0aW9uAAAABAUAAAACX3gFAAAADERFQ0lNQUxfVU5JVAUAAAACX3kFAAAACEhBTEZFVkVOAQAAAARtdWxkAAAAAgAAAAJfeAAAAAJfeQkBAAAACGZyYWN0aW9uAAAABAUAAAACX3gFAAAAAl95BQAAAAxERUNJTUFMX1VOSVQFAAAACEhBTEZFVkVOAQAAAANhYnMAAAABAAAAAl94AwkAAGYAAAACBQAAAAJfeAAAAAAAAAAAAAUAAAACX3gJAQAAAAEtAAAAAQUAAAACX3gBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgAAAARfa2V5AAAACF9hZGRyZXNzCQABLAAAAAIJAAEsAAAAAgUAAAAEX2tleQIAAAABXwUAAAAIX2FkZHJlc3MBAAAAA2ludAAAAAEAAAABawkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAAWsJAAEsAAAAAgIAAAANbm8gdmFsdWUgZm9yIAUAAAABawEAAAAIY2JhbGFuY2UAAAAACQEAAAADaW50AAAAAQUAAAAJa19iYWxhbmNlAQAAAANmZWUAAAAACQEAAAADaW50AAAAAQUAAAAFa19mZWUBAAAAD2luaXRNYXJnaW5SYXRpbwAAAAAJAQAAAANpbnQAAAABBQAAABFrX2luaXRNYXJnaW5SYXRpbwEAAAAGcXRBc3RSAAAAAAkBAAAAA2ludAAAAAEFAAAAE2tfcXVvdGVBc3NldFJlc2VydmUBAAAABmJzQXN0UgAAAAAJAQAAAANpbnQAAAABBQAAABJrX2Jhc2VBc3NldFJlc2VydmUBAAAAEXRvdGFsUG9zaXRpb25TaXplAAAAAAkBAAAAA2ludAAAAAEFAAAAE2tfdG90YWxQb3NpdGlvblNpemUBAAAAEmN1bXVsYXRpdmVOb3Rpb25hbAAAAAAJAQAAAANpbnQAAAABBQAAABRrX2N1bXVsYXRpdmVOb3Rpb25hbAEAAAAUb3BlbkludGVyZXN0Tm90aW9uYWwAAAAACQEAAAADaW50AAAAAQUAAAAWa19vcGVuSW50ZXJlc3ROb3Rpb25hbAEAAAAZbmV4dEZ1bmRpbmdCbG9ja1RpbWVzdGFtcAAAAAAJAQAAAANpbnQAAAABBQAAABJrX25leHRGdW5kaW5nQmxvY2sBAAAAEGZ1bmRpbmdQZXJpb2RSYXcAAAAACQEAAAADaW50AAAAAQUAAAAPa19mdW5kaW5nUGVyaW9kAQAAABRmdW5kaW5nUGVyaW9kRGVjaW1hbAAAAAAJAABoAAAAAgkBAAAAEGZ1bmRpbmdQZXJpb2RSYXcAAAAABQAAAAxERUNJTUFMX1VOSVQBAAAAFGZ1bmRpbmdQZXJpb2RTZWNvbmRzAAAAAAkAAGgAAAACCQEAAAAQZnVuZGluZ1BlcmlvZFJhdwAAAAAFAAAAB1NFQ09ORFMBAAAAFm1haW50ZW5hbmNlTWFyZ2luUmF0aW8AAAAACQEAAAADaW50AAAAAQUAAAAYa19tYWludGVuYW5jZU1hcmdpblJhdGlvAQAAABNsaXF1aWRhdGlvbkZlZVJhdGlvAAAAAAkBAAAAA2ludAAAAAEFAAAAFWtfbGlxdWlkYXRpb25GZWVSYXRpbwEAAAALc3ByZWFkTGltaXQAAAAACQEAAAADaW50AAAAAQUAAAANa19zcHJlYWRMaW1pdAEAAAAObWF4UHJpY2VJbXBhY3QAAAAACQEAAAADaW50AAAAAQUAAAAQa19tYXhQcmljZUltcGFjdAEAAAAjbGF0ZXN0TG9uZ0N1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAAACQEAAAADaW50AAAAAQUAAAAla19sYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgEAAAAkbGF0ZXN0U2hvcnRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAAAAAkBAAAAA2ludAAAAAEFAAAAJmtfbGF0ZXN0U2hvcnRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQAAABZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAAAAAkBAAAAA2ludAAAAAEFAAAAGGtfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQEAAAAVdG90YWxMb25nUG9zaXRpb25TaXplAAAAAAkBAAAAA2ludAAAAAEFAAAAF2tfdG90YWxMb25nUG9zaXRpb25TaXplAQAAABZyZXF1aXJlTW9yZU1hcmdpblJhdGlvAAAAAwAAAAxfbWFyZ2luUmF0aW8AAAAQX2Jhc2VNYXJnaW5SYXRpbwAAABRfbGFyZ2VyVGhhbk9yRXF1YWxUbwQAAAAUcmVtYWluaW5nTWFyZ2luUmF0aW8JAABlAAAAAgUAAAAMX21hcmdpblJhdGlvBQAAABBfYmFzZU1hcmdpblJhdGlvAwMFAAAAFF9sYXJnZXJUaGFuT3JFcXVhbFRvCQAAZgAAAAIAAAAAAAAAAAAFAAAAFHJlbWFpbmluZ01hcmdpblJhdGlvBwkAAAIAAAABAgAAAA5JbnZhbGlkIG1hcmdpbgMDCQEAAAABIQAAAAEFAAAAFF9sYXJnZXJUaGFuT3JFcXVhbFRvCQAAZwAAAAIFAAAAFHJlbWFpbmluZ01hcmdpblJhdGlvAAAAAAAAAAAABwkAAAIAAAABAgAAAA5JbnZhbGlkIG1hcmdpbgYBAAAAH2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAABAAAADV9wb3NpdGlvblNpemUDCQAAAAAAAAIFAAAADV9wb3NpdGlvblNpemUAAAAAAAAAAAAJAAACAAAAAQIAAAAsU2hvdWxkIG5vdCBiZSBjYWxsZWQgd2l0aCBfcG9zaXRpb25TaXplID09IDADCQAAZgAAAAIFAAAADV9wb3NpdGlvblNpemUAAAAAAAAAAAAJAQAAACNsYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAAAAAJAQAAACRsYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAAAAQAAAAtnZXRQb3NpdGlvbgAAAAEAAAAHX3RyYWRlcgQAAAAPcG9zaXRpb25TaXplT3B0CQAEGgAAAAIFAAAABHRoaXMJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAADmtfcG9zaXRpb25TaXplBQAAAAdfdHJhZGVyBAAAAAckbWF0Y2gwBQAAAA9wb3NpdGlvblNpemVPcHQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAAMcG9zaXRpb25TaXplBQAAAAckbWF0Y2gwCQAFFgAAAAQFAAAADHBvc2l0aW9uU2l6ZQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAQa19wb3NpdGlvbk1hcmdpbgUAAAAHX3RyYWRlcgkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAWa19wb3NpdGlvbk9wZW5Ob3Rpb25hbAUAAAAHX3RyYWRlcgkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAua19wb3NpdGlvbkxhc3RVcGRhdGVkQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUAAAAHX3RyYWRlcgkABRYAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAABNyZXF1aXJlT3BlblBvc2l0aW9uAAAAAQAAAAdfdHJhZGVyAwkAAAAAAAACCAkBAAAAC2dldFBvc2l0aW9uAAAAAQUAAAAHX3RyYWRlcgAAAAJfMQAAAAAAAAAAAAkAAAIAAAABAgAAABBObyBvcGVuIHBvc2l0aW9uBgEAAAALaW5pdGlhbGl6ZWQAAAAACQEAAAALdmFsdWVPckVsc2UAAAACCQAEGwAAAAIFAAAABHRoaXMFAAAADWtfaW5pdGlhbGl6ZWQHAQAAAAZwYXVzZWQAAAAACQEAAAALdmFsdWVPckVsc2UAAAACCQAEGwAAAAIFAAAABHRoaXMFAAAACGtfcGF1c2VkBwEAAAANdXBkYXRlUmVzZXJ2ZQAAAAMAAAAGX2lzQWRkAAAAEV9xdW90ZUFzc2V0QW1vdW50AAAAEF9iYXNlQXNzZXRBbW91bnQDBQAAAAZfaXNBZGQEAAAAB25ld0Jhc2UJAABlAAAAAgkBAAAABmJzQXN0UgAAAAAFAAAAEF9iYXNlQXNzZXRBbW91bnQDCQAAZwAAAAIAAAAAAAAAAAAFAAAAB25ld0Jhc2UJAAACAAAAAQIAAAAqVHggbGVhZCB0byBiYXNlIGFzc2V0IHJlc2VydmUgPD0gMCwgcmV2ZXJ0CQAFFgAAAAQJAABkAAAAAgkBAAAABnF0QXN0UgAAAAAFAAAAEV9xdW90ZUFzc2V0QW1vdW50BQAAAAduZXdCYXNlCQAAZAAAAAIJAQAAABF0b3RhbFBvc2l0aW9uU2l6ZQAAAAAFAAAAEF9iYXNlQXNzZXRBbW91bnQJAABkAAAAAgkBAAAAEmN1bXVsYXRpdmVOb3Rpb25hbAAAAAAFAAAAEV9xdW90ZUFzc2V0QW1vdW50BAAAAAhuZXdRdW90ZQkAAGUAAAACCQEAAAAGcXRBc3RSAAAAAAUAAAARX3F1b3RlQXNzZXRBbW91bnQDCQAAZwAAAAIAAAAAAAAAAAAFAAAACG5ld1F1b3RlCQAAAgAAAAECAAAAKlR4IGxlYWQgdG8gYmFzZSBxdW90ZSByZXNlcnZlIDw9IDAsIHJldmVydAkABRYAAAAEBQAAAAhuZXdRdW90ZQkAAGQAAAACCQEAAAAGYnNBc3RSAAAAAAUAAAAQX2Jhc2VBc3NldEFtb3VudAkAAGUAAAACCQEAAAARdG90YWxQb3NpdGlvblNpemUAAAAABQAAABBfYmFzZUFzc2V0QW1vdW50CQAAZQAAAAIJAQAAABJjdW11bGF0aXZlTm90aW9uYWwAAAAABQAAABFfcXVvdGVBc3NldEFtb3VudAEAAAAJc3dhcElucHV0AAAAAgAAAAZfaXNBZGQAAAARX3F1b3RlQXNzZXRBbW91bnQEAAAAB19xdEFzdFIJAQAAAAZxdEFzdFIAAAAABAAAAAdfYnNBc3RSCQEAAAAGYnNBc3RSAAAAAAQAAAALcHJpY2VCZWZvcmUJAQAAAARkaXZkAAAAAgUAAAAHX3F0QXN0UgUAAAAHX2JzQXN0UgQAAAAnYW1vdW50QmFzZUFzc2V0Qm91Z2h0V2l0aG91dFByaWNlSW1wYWN0CQEAAAAEbXVsZAAAAAIFAAAAEV9xdW90ZUFzc2V0QW1vdW50BQAAAAtwcmljZUJlZm9yZQQAAAABawkBAAAABG11bGQAAAACBQAAAAdfcXRBc3RSBQAAAAdfYnNBc3RSBAAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyAwUAAAAGX2lzQWRkCQAAZAAAAAIFAAAAB19xdEFzdFIFAAAAEV9xdW90ZUFzc2V0QW1vdW50CQAAZQAAAAIFAAAAB19xdEFzdFIFAAAAEV9xdW90ZUFzc2V0QW1vdW50BAAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIJAQAAAARkaXZkAAAAAgUAAAABawUAAAAWcXVvdGVBc3NldFJlc2VydmVBZnRlcgQAAAAYYW1vdW50QmFzZUFzc2V0Qm91Z2h0QWJzCQEAAAADYWJzAAAAAQkAAGUAAAACBQAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAB19ic0FzdFIEAAAAFWFtb3VudEJhc2VBc3NldEJvdWdodAMFAAAABl9pc0FkZAUAAAAYYW1vdW50QmFzZUFzc2V0Qm91Z2h0QWJzCQEAAAABLQAAAAEFAAAAGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwQAAAALcHJpY2VJbXBhY3QJAABpAAAAAgkAAGUAAAACBQAAACdhbW91bnRCYXNlQXNzZXRCb3VnaHRXaXRob3V0UHJpY2VJbXBhY3QFAAAAGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwUAAAAnYW1vdW50QmFzZUFzc2V0Qm91Z2h0V2l0aG91dFByaWNlSW1wYWN0BAAAABNtYXhQcmljZUltcGFjdFZhbHVlCQEAAAAObWF4UHJpY2VJbXBhY3QAAAAAAwkAAGYAAAACBQAAAAtwcmljZUltcGFjdAUAAAATbWF4UHJpY2VJbXBhY3RWYWx1ZQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAA1QcmljZSBpbXBhY3QgCQABpAAAAAEFAAAAC3ByaWNlSW1wYWN0AgAAABQgPiBtYXggcHJpY2UgaW1wYWN0IAkAAaQAAAABBQAAABNtYXhQcmljZUltcGFjdFZhbHVlBAAAAA0kdDAxMTQzMjExNjM1CQEAAAANdXBkYXRlUmVzZXJ2ZQAAAAMFAAAABl9pc0FkZAUAAAARX3F1b3RlQXNzZXRBbW91bnQFAAAAGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwQAAAAXcXVvdGVBc3NldFJlc2VydmVBZnRlcjEIBQAAAA0kdDAxMTQzMjExNjM1AAAAAl8xBAAAABZiYXNlQXNzZXRSZXNlcnZlQWZ0ZXIxCAUAAAANJHQwMTE0MzIxMTYzNQAAAAJfMgQAAAAXdG90YWxQb3NpdGlvblNpemVBZnRlcjEIBQAAAA0kdDAxMTQzMjExNjM1AAAAAl8zBAAAABhjdW11bGF0aXZlTm90aW9uYWxBZnRlcjEIBQAAAA0kdDAxMTQzMjExNjM1AAAAAl80CQAFFwAAAAUFAAAAFWFtb3VudEJhc2VBc3NldEJvdWdodAUAAAAXcXVvdGVBc3NldFJlc2VydmVBZnRlcjEFAAAAFmJhc2VBc3NldFJlc2VydmVBZnRlcjEFAAAAF3RvdGFsUG9zaXRpb25TaXplQWZ0ZXIxBQAAABhjdW11bGF0aXZlTm90aW9uYWxBZnRlcjEBAAAAImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQAAAAEAAAAEF9vbGRQb3NpdGlvblNpemUAAAASX29sZFBvc2l0aW9uTWFyZ2luAAAAJV9vbGRQb3NpdGlvbkN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAAMX21hcmdpbkRlbHRhBAAAAA5mdW5kaW5nUGF5bWVudAMJAQAAAAIhPQAAAAIFAAAAEF9vbGRQb3NpdGlvblNpemUAAAAAAAAAAAAEAAAAIF9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uCQEAAAAfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAAAAEFAAAAEF9vbGRQb3NpdGlvblNpemUJAQAAAARtdWxkAAAAAgkAAGUAAAACBQAAACBfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUAAAAlX29sZFBvc2l0aW9uQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUAAAAQX29sZFBvc2l0aW9uU2l6ZQAAAAAAAAAAAAQAAAAMc2lnbmVkTWFyZ2luCQAAZAAAAAIJAABlAAAAAgUAAAAMX21hcmdpbkRlbHRhBQAAAA5mdW5kaW5nUGF5bWVudAUAAAASX29sZFBvc2l0aW9uTWFyZ2luBAAAAA0kdDAxMjM4MjEyNTA5AwkAAGYAAAACAAAAAAAAAAAABQAAAAxzaWduZWRNYXJnaW4JAAUUAAAAAgAAAAAAAAAAAAkBAAAAA2FicwAAAAEFAAAADHNpZ25lZE1hcmdpbgkABRQAAAACCQEAAAADYWJzAAAAAQUAAAAMc2lnbmVkTWFyZ2luAAAAAAAAAAAABAAAAAxyZW1haW5NYXJnaW4IBQAAAA0kdDAxMjM4MjEyNTA5AAAAAl8xBAAAAAdiYWREZWJ0CAUAAAANJHQwMTIzODIxMjUwOQAAAAJfMgkABRUAAAADBQAAAAxyZW1haW5NYXJnaW4FAAAAB2JhZERlYnQFAAAADmZ1bmRpbmdQYXltZW50AQAAAApzd2FwT3V0cHV0AAAAAgAAAAZfaXNBZGQAAAAQX2Jhc2VBc3NldEFtb3VudAQAAAASX3F1b3RlQXNzZXRSZXNlcnZlCQEAAAAGcXRBc3RSAAAAAAQAAAARX2Jhc2VBc3NldFJlc2VydmUJAQAAAAZic0FzdFIAAAAAAwkAAAAAAAACBQAAABBfYmFzZUFzc2V0QW1vdW50AAAAAAAAAAAACQAAAgAAAAECAAAAGUludmFsaWQgYmFzZSBhc3NldCBhbW91bnQEAAAAAWsJAQAAAARtdWxkAAAAAgUAAAASX3F1b3RlQXNzZXRSZXNlcnZlBQAAABFfYmFzZUFzc2V0UmVzZXJ2ZQQAAAAYYmFzZUFzc2V0UG9vbEFtb3VudEFmdGVyAwUAAAAGX2lzQWRkCQAAZAAAAAIFAAAAEV9iYXNlQXNzZXRSZXNlcnZlBQAAABBfYmFzZUFzc2V0QW1vdW50CQAAZQAAAAIFAAAAEV9iYXNlQXNzZXRSZXNlcnZlBQAAABBfYmFzZUFzc2V0QW1vdW50BAAAAA9xdW90ZUFzc2V0QWZ0ZXIJAQAAAARkaXZkAAAAAgUAAAABawUAAAAYYmFzZUFzc2V0UG9vbEFtb3VudEFmdGVyBAAAAA5xdW90ZUFzc2V0U29sZAkBAAAAA2FicwAAAAEJAABlAAAAAgUAAAAPcXVvdGVBc3NldEFmdGVyBQAAABJfcXVvdGVBc3NldFJlc2VydmUEAAAADSR0MDEzMzQ3MTM1NDAJAQAAAA11cGRhdGVSZXNlcnZlAAAAAwkBAAAAASEAAAABBQAAAAZfaXNBZGQFAAAADnF1b3RlQXNzZXRTb2xkBQAAABBfYmFzZUFzc2V0QW1vdW50BAAAABdxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyMQgFAAAADSR0MDEzMzQ3MTM1NDAAAAACXzEEAAAAFmJhc2VBc3NldFJlc2VydmVBZnRlcjEIBQAAAA0kdDAxMzM0NzEzNTQwAAAAAl8yBAAAABd0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyMQgFAAAADSR0MDEzMzQ3MTM1NDAAAAACXzMEAAAAGGN1bXVsYXRpdmVOb3Rpb25hbEFmdGVyMQgFAAAADSR0MDEzMzQ3MTM1NDAAAAACXzQJAAUZAAAABwUAAAAOcXVvdGVBc3NldFNvbGQFAAAAF3F1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIxBQAAABZiYXNlQXNzZXRSZXNlcnZlQWZ0ZXIxBQAAABd0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyMQUAAAAYY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIxCQAAZQAAAAIJAQAAABV0b3RhbExvbmdQb3NpdGlvblNpemUAAAAAAwUAAAAGX2lzQWRkCQEAAAADYWJzAAAAAQUAAAAQX2Jhc2VBc3NldEFtb3VudAAAAAAAAAAAAAkAAGUAAAACCQEAAAAWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAAAAADCQEAAAABIQAAAAEFAAAABl9pc0FkZAkBAAAAA2FicwAAAAEFAAAAEF9iYXNlQXNzZXRBbW91bnQAAAAAAAAAAAABAAAAEmdldE9yYWNsZVR3YXBQcmljZQAAAAAEAAAABm9yYWNsZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAABHRoaXMFAAAABWtfb3JhAgAAAAAEAAAACHByaWNlS2V5CQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACBQAAAAR0aGlzBQAAAAlrX29yYV9rZXkEAAAACGJsb2NrS2V5CQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACBQAAAAR0aGlzBQAAAA9rX29yYV9ibG9ja19rZXkEAAAACWxhc3RWYWx1ZQkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAGb3JhY2xlBQAAAAhwcmljZUtleQUAAAAJbGFzdFZhbHVlAQAAAAxnZXRTcG90UHJpY2UAAAAABAAAABJfcXVvdGVBc3NldFJlc2VydmUJAQAAAAZxdEFzdFIAAAAABAAAABFfYmFzZUFzc2V0UmVzZXJ2ZQkBAAAABmJzQXN0UgAAAAAJAQAAAARkaXZkAAAAAgUAAAASX3F1b3RlQXNzZXRSZXNlcnZlBQAAABFfYmFzZUFzc2V0UmVzZXJ2ZQEAAAAWaXNPdmVyRmx1Y3R1YXRpb25MaW1pdAAAAAAEAAAAC29yYWNsZVByaWNlCQEAAAASZ2V0T3JhY2xlVHdhcFByaWNlAAAAAAQAAAAMY3VycmVudFByaWNlCQEAAAAMZ2V0U3BvdFByaWNlAAAAAAkAAGYAAAACCQEAAAAEZGl2ZAAAAAIJAQAAAANhYnMAAAABCQAAZQAAAAIFAAAAC29yYWNsZVByaWNlBQAAAAxjdXJyZW50UHJpY2UFAAAAC29yYWNsZVByaWNlCQEAAAALc3ByZWFkTGltaXQAAAAAAQAAACNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAAAAAIAAAAHX3RyYWRlcgAAAAdfb3B0aW9uBAAAAA0kdDAxNTE3MjE1MzAwCQEAAAALZ2V0UG9zaXRpb24AAAABBQAAAAdfdHJhZGVyBAAAAAxwb3NpdGlvblNpemUIBQAAAA0kdDAxNTE3MjE1MzAwAAAAAl8xBAAAAA5wb3NpdGlvbk1hcmdpbggFAAAADSR0MDE1MTcyMTUzMDAAAAACXzIEAAAAFHBvc2l0aW9uT3Blbk5vdGlvbmFsCAUAAAANJHQwMTUxNzIxNTMwMAAAAAJfMwQAAAARcG9zaXRpb25Mc3RVcGRDUEYIBQAAAA0kdDAxNTE3MjE1MzAwAAAAAl80BAAAAA9wb3NpdGlvblNpemVBYnMJAQAAAANhYnMAAAABBQAAAAxwb3NpdGlvblNpemUDCQAAAAAAAAIFAAAAD3Bvc2l0aW9uU2l6ZUFicwAAAAAAAAAAAAkAAAIAAAABAgAAABVJbnZhbGlkIHBvc2l0aW9uIHNpemUEAAAAB2lzU2hvcnQJAABmAAAAAgAAAAAAAAAAAAUAAAAMcG9zaXRpb25TaXplBAAAABBwb3NpdGlvbk5vdGlvbmFsAwkAAAAAAAACBQAAAAdfb3B0aW9uBQAAAA9QTkxfT1BUSU9OX1NQT1QEAAAADSR0MDE1NTQ3MTU2NTQJAQAAAApzd2FwT3V0cHV0AAAAAgkBAAAAASEAAAABBQAAAAdpc1Nob3J0BQAAAA9wb3NpdGlvblNpemVBYnMEAAAAE291dFBvc2l0aW9uTm90aW9uYWwIBQAAAA0kdDAxNTU0NzE1NjU0AAAAAl8xBAAAAAJ4MQgFAAAADSR0MDE1NTQ3MTU2NTQAAAACXzIEAAAAAngyCAUAAAANJHQwMTU1NDcxNTY1NAAAAAJfMwQAAAACeDMIBQAAAA0kdDAxNTU0NzE1NjU0AAAAAl80BQAAABNvdXRQb3NpdGlvbk5vdGlvbmFsCQAAaAAAAAIFAAAAD3Bvc2l0aW9uU2l6ZUFicwkBAAAAEmdldE9yYWNsZVR3YXBQcmljZQAAAAAEAAAADXVucmVhbGl6ZWRQbmwDBQAAAAdpc1Nob3J0CQAAZQAAAAIFAAAAFHBvc2l0aW9uT3Blbk5vdGlvbmFsBQAAABBwb3NpdGlvbk5vdGlvbmFsCQAAZQAAAAIFAAAAEHBvc2l0aW9uTm90aW9uYWwFAAAAFHBvc2l0aW9uT3Blbk5vdGlvbmFsCQAFFAAAAAIFAAAAEHBvc2l0aW9uTm90aW9uYWwFAAAADXVucmVhbGl6ZWRQbmwBAAAAFmdldE1hcmdpblJhdGlvQnlPcHRpb24AAAACAAAAB190cmFkZXIAAAAHX29wdGlvbgQAAAANJHQwMTYxNDkxNjI2MAkBAAAAC2dldFBvc2l0aW9uAAAAAQUAAAAHX3RyYWRlcgQAAAAMcG9zaXRpb25TaXplCAUAAAANJHQwMTYxNDkxNjI2MAAAAAJfMQQAAAAOcG9zaXRpb25NYXJnaW4IBQAAAA0kdDAxNjE0OTE2MjYwAAAAAl8yBAAAAANwb24IBQAAAA0kdDAxNjE0OTE2MjYwAAAAAl8zBAAAABFwb3NpdGlvbkxzdFVwZENQRggFAAAADSR0MDE2MTQ5MTYyNjAAAAACXzQEAAAADSR0MDE2MjY2MTYzNTkJAQAAACNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAAAAAIFAAAAB190cmFkZXIFAAAAB19vcHRpb24EAAAAEHBvc2l0aW9uTm90aW9uYWwIBQAAAA0kdDAxNjI2NjE2MzU5AAAAAl8xBAAAAA11bnJlYWxpemVkUG5sCAUAAAANJHQwMTYyNjYxNjM1OQAAAAJfMgQAAAANJHQwMTYzNjQxNjUzMAkBAAAAImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQAAAAEBQAAAAxwb3NpdGlvblNpemUFAAAADnBvc2l0aW9uTWFyZ2luBQAAABFwb3NpdGlvbkxzdFVwZENQRgUAAAANdW5yZWFsaXplZFBubAQAAAAMcmVtYWluTWFyZ2luCAUAAAANJHQwMTYzNjQxNjUzMAAAAAJfMQQAAAAHYmFkRGVidAgFAAAADSR0MDE2MzY0MTY1MzAAAAACXzIJAQAAAARkaXZkAAAAAgkAAGUAAAACBQAAAAxyZW1haW5NYXJnaW4FAAAAB2JhZERlYnQFAAAAEHBvc2l0aW9uTm90aW9uYWwBAAAADmdldE1hcmdpblJhdGlvAAAAAQAAAAdfdHJhZGVyCQEAAAAWZ2V0TWFyZ2luUmF0aW9CeU9wdGlvbgAAAAIFAAAAB190cmFkZXIFAAAAD1BOTF9PUFRJT05fU1BPVAEAAAAVaW50ZXJuYWxDbG9zZVBvc2l0aW9uAAAAAQAAAAdfdHJhZGVyBAAAAA0kdDAxNjgzNjE2OTQ3CQEAAAALZ2V0UG9zaXRpb24AAAABBQAAAAdfdHJhZGVyBAAAAAxwb3NpdGlvblNpemUIBQAAAA0kdDAxNjgzNjE2OTQ3AAAAAl8xBAAAAA5wb3NpdGlvbk1hcmdpbggFAAAADSR0MDE2ODM2MTY5NDcAAAACXzIEAAAAA3BvbggFAAAADSR0MDE2ODM2MTY5NDcAAAACXzMEAAAAEXBvc2l0aW9uTHN0VXBkQ1BGCAUAAAANJHQwMTY4MzYxNjk0NwAAAAJfNAQAAAANJHQwMTY5NTMxNzA0MAkBAAAAI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAAAAAgUAAAAHX3RyYWRlcgUAAAAPUE5MX09QVElPTl9TUE9UBAAAAAJ4MQgFAAAADSR0MDE2OTUzMTcwNDAAAAACXzEEAAAADXVucmVhbGl6ZWRQbmwIBQAAAA0kdDAxNjk1MzE3MDQwAAAAAl8yBAAAAA0kdDAxNzA0NTE3MjEzCQEAAAAiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAAAAAQFAAAADHBvc2l0aW9uU2l6ZQUAAAAOcG9zaXRpb25NYXJnaW4FAAAAEXBvc2l0aW9uTHN0VXBkQ1BGBQAAAA11bnJlYWxpemVkUG5sBAAAAAxyZW1haW5NYXJnaW4IBQAAAA0kdDAxNzA0NTE3MjEzAAAAAl8xBAAAAAdiYWREZWJ0CAUAAAANJHQwMTcwNDUxNzIxMwAAAAJfMgQAAAAVZXhjaGFuZ2VkUG9zaXRpb25TaXplCQEAAAABLQAAAAEFAAAADHBvc2l0aW9uU2l6ZQQAAAALcmVhbGl6ZWRQbmwFAAAADXVucmVhbGl6ZWRQbmwEAAAADW1hcmdpblRvVmF1bHQJAQAAAAEtAAAAAQUAAAAMcmVtYWluTWFyZ2luBAAAAA0kdDAxNzM0MDE3NjIxCQEAAAAKc3dhcE91dHB1dAAAAAIJAABmAAAAAgUAAAAMcG9zaXRpb25TaXplAAAAAAAAAAAACQEAAAADYWJzAAAAAQUAAAAMcG9zaXRpb25TaXplBAAAABlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50CAUAAAANJHQwMTczNDAxNzYyMQAAAAJfMQQAAAAWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFAAAADSR0MDE3MzQwMTc2MjEAAAACXzIEAAAAFWJhc2VBc3NldFJlc2VydmVBZnRlcggFAAAADSR0MDE3MzQwMTc2MjEAAAACXzMEAAAAFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQAAAA0kdDAxNzM0MDE3NjIxAAAAAl80BAAAABdjdW11bGF0aXZlTm90aW9uYWxBZnRlcggFAAAADSR0MDE3MzQwMTc2MjEAAAACXzUEAAAADnRvdGFsTG9uZ0FmdGVyCAUAAAANJHQwMTczNDAxNzYyMQAAAAJfNgQAAAAPdG90YWxTaG9ydEFmdGVyCAUAAAANJHQwMTczNDAxNzYyMQAAAAJfNwQAAAAZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgkAAGUAAAACCQEAAAAUb3BlbkludGVyZXN0Tm90aW9uYWwAAAAABQAAAANwb24JAAUeAAAADAUAAAAVZXhjaGFuZ2VkUG9zaXRpb25TaXplBQAAAAdiYWREZWJ0BQAAAAtyZWFsaXplZFBubAUAAAANbWFyZ2luVG9WYXVsdAUAAAAWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBQAAABdjdW11bGF0aXZlTm90aW9uYWxBZnRlcgUAAAAZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgUAAAAZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAUAAAAOdG90YWxMb25nQWZ0ZXIFAAAAD3RvdGFsU2hvcnRBZnRlcgEAAAAQZ2V0VHdhcFNwb3RQcmljZQAAAAAEAAAACG1pbnV0ZUlkCQAAaQAAAAIJAABpAAAAAggFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAAAAAAAAAAA+gAAAAAAAAAADwEAAAADXN0YXJ0TWludXRlSWQJAABlAAAAAgUAAAAIbWludXRlSWQFAAAADVRXQVBfSU5URVJWQUwEAAAAB2xpc3RTdHIJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAANa19sYXN0RGF0YVN0cgIAAAAABAAAAARsaXN0CQAEtQAAAAIFAAAAB2xpc3RTdHICAAAAASwKAQAAAAhmaWx0ZXJGbgAAAAIAAAALYWNj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AAAIbWF4SW5kZXgAAAAAAAAAAAAEAAAAFHN0YXJ0Q3VtdWxhdGl2ZVByaWNlCQAAZAAAAAIFAAAAGHN0YXJ0TGFzdEN1bXVsYXRpdmVQcmljZQkAAGgAAAACCQAAZQAAAAIFAAAADXN0YXJ0TWludXRlSWQFAAAACG1heEluZGV4BQAAAA5zdGFydExhc3RQcmljZQkAAGkAAAACCQAAZQAAAAIFAAAAEm5vd0N1bXVsYXRpdmVQcmljZQUAAAAUc3RhcnRDdW11bGF0aXZlUHJpY2UFAAAADVRXQVBfSU5URVJWQUwBAAAADnVwZGF0ZVNldHRpbmdzAAAABwAAABBfaW5pdE1hcmdpblJhdGlvAAAABF9tbXIAAAAUX2xpcXVpZGF0aW9uRmVlUmF0aW8AAAAOX2Z1bmRpbmdQZXJpb2QAAAAEX2ZlZQAAAAxfc3ByZWFkTGltaXQAAAAPX21heFByaWNlSW1wYWN0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABFrX2luaXRNYXJnaW5SYXRpbwUAAAAQX2luaXRNYXJnaW5SYXRpbwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAYa19tYWludGVuYW5jZU1hcmdpblJhdGlvBQAAAARfbW1yCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVrX2xpcXVpZGF0aW9uRmVlUmF0aW8FAAAAFF9saXF1aWRhdGlvbkZlZVJhdGlvCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA9rX2Z1bmRpbmdQZXJpb2QFAAAADl9mdW5kaW5nUGVyaW9kCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAVrX2ZlZQUAAAAEX2ZlZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAANa19zcHJlYWRMaW1pdAUAAAAMX3NwcmVhZExpbWl0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABBrX21heFByaWNlSW1wYWN0BQAAAA9fbWF4UHJpY2VJbXBhY3QFAAAAA25pbAEAAAANdXBkYXRlRnVuZGluZwAAAAUAAAARX25leHRGdW5kaW5nQmxvY2sAAAAkX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAAAJV9sYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAAQX2xvbmdGdW5kaW5nUmF0ZQAAABFfc2hvcnRGdW5kaW5nUmF0ZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASa19uZXh0RnVuZGluZ0Jsb2NrBQAAABFfbmV4dEZ1bmRpbmdCbG9jawkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAla19sYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUAAAAkX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAACZrX2xhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUAAAAlX2xhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARa19sb25nRnVuZGluZ1JhdGUFAAAAEF9sb25nRnVuZGluZ1JhdGUJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEmtfc2hvcnRGdW5kaW5nUmF0ZQUAAAARX3Nob3J0RnVuZGluZ1JhdGUFAAAAA25pbAEAAAAOdXBkYXRlUG9zaXRpb24AAAAFAAAACF9hZGRyZXNzAAAABV9zaXplAAAAB19tYXJnaW4AAAANX29wZW5Ob3Rpb25hbAAAACBfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAOa19wb3NpdGlvblNpemUFAAAACF9hZGRyZXNzBQAAAAVfc2l6ZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAQa19wb3NpdGlvbk1hcmdpbgUAAAAIX2FkZHJlc3MFAAAAB19tYXJnaW4JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAAFmtfcG9zaXRpb25PcGVuTm90aW9uYWwFAAAACF9hZGRyZXNzBQAAAA1fb3Blbk5vdGlvbmFsCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAOdG9Db21wb3NpdGVLZXkAAAACBQAAAC5rX3Bvc2l0aW9uTGFzdFVwZGF0ZWRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uBQAAAAhfYWRkcmVzcwUAAAAgX2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FAAAAA25pbAEAAAAKYXBwZW5kVHdhcAAAAAEAAAAFcHJpY2UEAAAACG1pbnV0ZUlkCQAAaQAAAAIJAABpAAAAAggFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAAAAAAAAAAA+gAAAAAAAAAADwEAAAAEHByZXZpb3VzTWludXRlSWQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAOa19sYXN0TWludXRlSWQAAAAAAAAAAAADCQAAZgAAAAIFAAAAEHByZXZpb3VzTWludXRlSWQFAAAACG1pbnV0ZUlkCQAAAgAAAAECAAAAEVRXQVAgb3V0LW9mLW9yZGVyBAAAAAxsYXN0TWludXRlSWQDCQAAAAAAAAIFAAAAEHByZXZpb3VzTWludXRlSWQAAAAAAAAAAAAFAAAACG1pbnV0ZUlkBQAAABBwcmV2aW91c01pbnV0ZUlkBAAAAAdsaXN0U3RyCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAADWtfbGFzdERhdGFTdHICAAAAAAQAAAAHb2xkTGlzdAkABLUAAAACBQAAAAdsaXN0U3RyAgAAAAEsBAAAAARsaXN0AwkAAGYAAAACCQABkAAAAAEFAAAAB29sZExpc3QFAAAADVRXQVBfSU5URVJWQUwJAARNAAAAAgkABFEAAAACBQAAAAdvbGRMaXN0AAAAAAAAAAAACQABpAAAAAEFAAAACG1pbnV0ZUlkCQAETQAAAAIFAAAAB29sZExpc3QJAAGkAAAAAQUAAAAIbWludXRlSWQEAAAAE3ByZXZDdW11bGF0aXZlUHJpY2UJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkAASwAAAACCQABLAAAAAIFAAAAHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlAgAAAAFfCQABpAAAAAEFAAAAEHByZXZpb3VzTWludXRlSWQAAAAAAAAAAAAEAAAACXByZXZQcmljZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQABLAAAAAIJAAEsAAAAAgUAAAATa190d2FwRGF0YUxhc3RQcmljZQIAAAABXwkAAaQAAAABBQAAABBwcmV2aW91c01pbnV0ZUlkBQAAAAVwcmljZQQAAAATbGFzdEN1bXVsYXRpdmVQcmljZQkAAGQAAAACBQAAABNwcmV2Q3VtdWxhdGl2ZVByaWNlCQAAaAAAAAIJAABlAAAAAgUAAAAIbWludXRlSWQFAAAADGxhc3RNaW51dGVJZAUAAAAJcHJldlByaWNlCgEAAAAEam9pbgAAAAIAAAALYWNjdW11bGF0b3IAAAADdmFsCQABLAAAAAIJAAEsAAAAAgUAAAALYWNjdW11bGF0b3IFAAAAA3ZhbAIAAAABLAQAAAAKbmV3TGlzdFN0cgoAAAAAAiRsBQAAAARsaXN0CgAAAAACJHMJAAGQAAAAAQUAAAACJGwKAAAAAAUkYWNjMAIAAAAACgEAAAAFJGYwXzEAAAACAAAAAiRhAAAAAiRpAwkAAGcAAAACBQAAAAIkaQUAAAACJHMFAAAAAiRhCQEAAAAEam9pbgAAAAIFAAAAAiRhCQABkQAAAAIFAAAAAiRsBQAAAAIkaQoBAAAABSRmMF8yAAAAAgAAAAIkYQAAAAIkaQMJAABnAAAAAgUAAAACJGkFAAAAAiRzBQAAAAIkYQkAAAIAAAABAgAAABRMaXN0IHNpemUgZXhjZWVkcyAyMAkBAAAABSRmMF8yAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgkBAAAABSRmMF8xAAAAAgUAAAAFJGFjYzAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAIAAAAAAAAAAAMAAAAAAAAAAAQAAAAAAAAAAAUAAAAAAAAAAAYAAAAAAAAAAAcAAAAAAAAAAAgAAAAAAAAAAAkAAAAAAAAAAAoAAAAAAAAAAAsAAAAAAAAAAAwAAAAAAAAAAA0AAAAAAAAAAA4AAAAAAAAAAA8AAAAAAAAAABAAAAAAAAAAABEAAAAAAAAAABIAAAAAAAAAABMAAAAAAAAAABQEAAAAC25ld0xpc3RTdHJVCQEAAAAJZHJvcFJpZ2h0AAAAAgUAAAAKbmV3TGlzdFN0cgAAAAAAAAAAAQQAAAALbmV3TGlzdFN0clIDCQAAAAAAAAIJAAEvAAAAAgUAAAALbmV3TGlzdFN0clUAAAAAAAAAAAECAAAAASwJAAEwAAAAAgUAAAALbmV3TGlzdFN0clUAAAAAAAAAAAEFAAAAC25ld0xpc3RTdHJVCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAIJAAEsAAAAAgUAAAAda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UCAAAAAV8JAAGkAAAAAQUAAAAIbWludXRlSWQFAAAAE2xhc3RDdW11bGF0aXZlUHJpY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAAEsAAAAAgkAASwAAAACBQAAABNrX3R3YXBEYXRhTGFzdFByaWNlAgAAAAFfCQABpAAAAAEFAAAACG1pbnV0ZUlkBQAAAAVwcmljZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAOa19sYXN0TWludXRlSWQFAAAACG1pbnV0ZUlkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADWtfbGFzdERhdGFTdHIFAAAAC25ld0xpc3RTdHJSBQAAAANuaWwBAAAACXVwZGF0ZUFtbQAAAAcAAAAHX3F0QXN0UgAAAAdfYnNBc3RSAAAAF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyAAAAGF9jdW11bGF0aXZlTm90aW9uYWxBZnRlcgAAABVfb3BlbkludGVyZXN0Tm90aW9uYWwAAAAWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAAABdfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQMJAQAAAAIhPQAAAAIJAABlAAAAAgUAAAAWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQUAAAAXX3RvdGFsU2hvcnRQb3NpdGlvblNpemUFAAAAF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABhJbnZhbGlkIEFNTSBzdGF0ZSBkYXRhOiAJAAGkAAAAAQUAAAAWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQIAAAAEICsgIAkAAaQAAAABBQAAABdfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQIAAAAEICE9IAkAAaQAAAABBQAAABdfdG90YWxQb3NpdGlvblNpemVBZnRlcgkABE4AAAACCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABNrX3F1b3RlQXNzZXRSZXNlcnZlBQAAAAdfcXRBc3RSCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJrX2Jhc2VBc3NldFJlc2VydmUFAAAAB19ic0FzdFIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAE2tfdG90YWxQb3NpdGlvblNpemUFAAAAF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABRrX2N1bXVsYXRpdmVOb3Rpb25hbAUAAAAYX2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABZrX29wZW5JbnRlcmVzdE5vdGlvbmFsBQAAABVfb3BlbkludGVyZXN0Tm90aW9uYWwJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAF2tfdG90YWxMb25nUG9zaXRpb25TaXplBQAAABZfdG90YWxMb25nUG9zaXRpb25TaXplCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABhrX3RvdGFsU2hvcnRQb3NpdGlvblNpemUFAAAAF190b3RhbFNob3J0UG9zaXRpb25TaXplBQAAAANuaWwJAQAAAAphcHBlbmRUd2FwAAAAAQkBAAAABGRpdmQAAAACBQAAAAdfcXRBc3RSBQAAAAdfYnNBc3RSAQAAAA5kZWxldGVQb3NpdGlvbgAAAAEAAAAIX2FkZHJlc3MJAARMAAAAAgkBAAAAC0RlbGV0ZUVudHJ5AAAAAQkBAAAADnRvQ29tcG9zaXRlS2V5AAAAAgUAAAAOa19wb3NpdGlvblNpemUFAAAACF9hZGRyZXNzCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAAEGtfcG9zaXRpb25NYXJnaW4FAAAACF9hZGRyZXNzCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAAFmtfcG9zaXRpb25PcGVuTm90aW9uYWwFAAAACF9hZGRyZXNzCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEJAQAAAA50b0NvbXBvc2l0ZUtleQAAAAIFAAAALmtfcG9zaXRpb25MYXN0VXBkYXRlZEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FAAAACF9hZGRyZXNzBQAAAANuaWwBAAAACHdpdGhkcmF3AAAAAgAAAAhfYWRkcmVzcwAAAAdfYW1vdW50BAAAAAdiYWxhbmNlCQAD8AAAAAIFAAAABHRoaXMJAQAAAApxdW90ZUFzc2V0AAAAAAMJAABmAAAAAgUAAAAHX2Ftb3VudAUAAAAHYmFsYW5jZQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABNVbmFibGUgdG8gd2l0aGRyYXcgCQABpAAAAAEFAAAAB19hbW91bnQCAAAAFyBmcm9tIGNvbnRyYWN0IGJhbGFuY2UgCQABpAAAAAEFAAAAB2JhbGFuY2UJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAAIX2FkZHJl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AAEhAAAAAQkBAAAAE3JlcXVpcmVPcGVuUG9zaXRpb24AAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgYJAQAAAAZwYXVzZWQAAAAACQAAAgAAAAECAAAAI0ludmFsaWQgZGVjcmVhc2VQb3NpdGlvbiBwYXJhbWV0ZXJzBAAAAA0kdDAyNjgwMTI2OTUzCQEAAAALZ2V0UG9zaXRpb24AAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAPb2xkUG9zaXRpb25TaXplCAUAAAANJHQwMjY4MDEyNjk1MwAAAAJfMQQAAAARb2xkUG9zaXRpb25NYXJnaW4IBQAAAA0kdDAyNjgwMTI2OTUzAAAAAl8yBAAAABdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFAAAADSR0MDI2ODAxMjY5NTMAAAACXzMEAAAAFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUAAAANJHQwMjY4MDEyNjk1MwAAAAJfNAQAAAANaXNOZXdQb3NpdGlvbgkAAAAAAAACBQAAAA9vbGRQb3NpdGlvblNpemUAAAAAAAAAAAAEAAAAD2lzU2FtZURpcmVjdGlvbgMJAABmAAAAAgUAAAAPb2xkUG9zaXRpb25TaXplAAAAAAAAAAAACQAAAAAAAAIFAAAACl9kaXJlY3Rpb24FAAAACERJUl9MT05HCQAAAAAAAAIFAAAACl9kaXJlY3Rpb24FAAAACURJUl9TSE9SVAQAAAAOZXhwYW5kRXhpc3RpbmcDCQEAAAABIQAAAAEFAAAADWlzTmV3UG9zaXRpb24FAAAAD2lzU2FtZURpcmVjdGlvbgcEAAAABWlzQWRkCQAAAAAAAAIFAAAACl9kaXJlY3Rpb24FAAAACERJUl9MT05HBAAAAA0kdDAyNzI0MjMwMjgwAwMFAAAADWlzTmV3UG9zaXRpb24GBQAAAA5leHBhbmRFeGlzdGluZwkAAAIAAAABAgAAADVVc2UgaW5jcmVhc2VQb3NpdGlvbiB0byBvcGVuIG5ldyBvciBpbmNyZWFzZSBwb3NpdGlvbgQAAAAMb3Blbk5vdGlvbmFsCQEAAAAEbXVsZAAAAAIFAAAAB19hbW91bnQFAAAACV9sZXZlcmFnZQQAAAANJHQwMjc3NDgyNzg2NAkBAAAAI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIFAAAAD1BOTF9PUFRJT05fU1BPVAQAAAATb2xkUG9zaXRpb25Ob3Rpb25hbAgFAAAADSR0MDI3NzQ4Mjc4NjQAAAACXzEEAAAADXVucmVhbGl6ZWRQbmwIBQAAAA0kdDAyNzc0ODI3ODY0AAAAAl8yAwkAAGYAAAACBQAAABNvbGRQb3NpdGlvbk5vdGlvbmFsBQAAAAxvcGVuTm90aW9uYWwEAAAADSR0MDI3OTI2MjgxNTYJAQAAAAlzd2FwSW5wdXQAAAACBQAAAAVpc0FkZAUAAAAMb3Blbk5vdGlvbmFsBAAAABVleGNoYW5nZWRQb3NpdGlvblNpemUIBQAAAA0kdDAyNzkyNjI4MTU2AAAAAl8xBAAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwMjc5MjYyODE1NgAAAAJfMgQAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwMjc5MjYyODE1NgAAAAJfMwQAAAAWdG90YWxQb3NpdGlvblNpemVBZnRlcggFAAAADSR0MDI3OTI2MjgxNTYAAAACXzQEAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCAUAAAANJHQwMjc5MjYyODE1NgAAAAJfNQQAAAAYZXhjaGFuZ2VkUG9zaXRpb25TaXplQWJzCQEAAAADYWJzAAAAAQUAAAAVZXhjaGFuZ2VkUG9zaXRpb25TaXplAwMJAQAAAAIhPQAAAAIFAAAAE19taW5CYXNlQXNzZXRBbW91bnQAAAAAAAAAAAAJAABmAAAAAgUAAAATX21pbkJhc2VBc3NldEFtb3VudAUAAAAYZXhjaGFuZ2VkUG9zaXRpb25TaXplQWJzBwkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACVUb28gbGl0dGxlIGJhc2UgYXNzZXQgZXhjaGFuZ2VkLCBnb3QgCQABpAAAAAEFAAAAGGV4Y2hhbmdlZFBvc2l0aW9uU2l6ZUFicwIAAAAKIGV4cGVjdGVkIAkAAaQAAAABBQAAABNfbWluQmFzZUFzc2V0QW1vdW50BAAAAAtyZWFsaXplZFBubAMJAQAAAAIhPQAAAAIFAAAAD29sZFBvc2l0aW9uU2l6ZQAAAAAAAAAAAAkBAAAABGRpdmQAAAACCQEAAAAEbXVsZAAAAAIFAAAADXVucmVhbGl6ZWRQbmwFAAAAGGV4Y2hhbmdlZFBvc2l0aW9uU2l6ZUFicwUAAAAPb2xkUG9zaXRpb25TaXplAAAAAAAAAAAABAAAAA0kdDAyODY5NjI4OTUzCQEAAAAiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAAAAAQFAAAAD29sZFBvc2l0aW9uU2l6ZQUAAAARb2xkUG9zaXRpb25NYXJnaW4FAAAAFG9sZFBvc2l0aW9uTHN0VXBkQ1BGBQAAAAtyZWFsaXplZFBubAQAAAAMcmVtYWluTWFyZ2luCAUAAAANJHQwMjg2OTYyODk1MwAAAAJfMQQAAAAHYmFkRGVidAgFAAAADSR0MDI4Njk2Mjg5NTMAAAACXzIEAAAADmZ1bmRpbmdQYXltZW50CAUAAAANJHQwMjg2OTYyODk1MwAAAAJfMwQAAAAZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAUAAAAMb3Blbk5vdGlvbmFsBAAAABJ1bnJlYWxpemVkUG5sQWZ0ZXIJAABlAAAAAgUAAAANdW5yZWFsaXplZFBubAUAAAALcmVhbGl6ZWRQbmwEAAAAEnJlbWFpbk9wZW5Ob3Rpb25hbAMJAABmAAAAAgUAAAAPb2xkUG9zaXRpb25TaXplAAAAAAAAAAAACQAAZQAAAAIJAABlAAAAAgUAAAATb2xkUG9zaXRpb25Ob3Rpb25hbAUAAAAZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAUAAAASdW5yZWFsaXplZFBubEFmdGVyCQAAZQAAAAIJAABkAAAAAgUAAAASdW5yZWFsaXplZFBubEFmdGVyBQAAABNvbGRQb3NpdGlvbk5vdGlvbmFsBQAAABlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50BAAAAA9uZXdQb3NpdGlvblNpemUJAABkAAAAAgUAAAAPb2xkUG9zaXRpb25TaXplBQAAABVleGNoYW5nZWRQb3NpdGlvblNpemUJAAUdAAAACwUAAAAPbmV3UG9zaXRpb25TaXplBQAAAAxyZW1haW5NYXJnaW4JAQAAAANhYnMAAAABBQAAABJyZW1haW5PcGVuTm90aW9uYWwJAQAAAB9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAAAAQUAAAAPbmV3UG9zaXRpb25TaXplBQAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCQAAZQAAAAIJAQAAABRvcGVuSW50ZXJlc3ROb3Rpb25hbAAAAAAFAAAADG9wZW5Ob3Rpb25hbAkAAGUAAAACCQEAAAAVdG90YWxMb25nUG9zaXRpb25TaXplAAAAAAMJAABmAAAAAgUAAAAPbmV3UG9zaXRpb25TaXplAAAAAAAAAAAACQEAAAADYWJzAAAAAQUAAAAVZXhjaGFuZ2VkUG9zaXRpb25TaXplAAAAAAAAAAAACQAAZQAAAAIJAQAAABZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAAAAAMJAABmAAAAAgAAAAAAAAAAAAUAAAAPbmV3UG9zaXRpb25TaXplCQEAAAADYWJzAAAAAQUAAAAVZXhjaGFuZ2VkUG9zaXRpb25TaXplAAAAAAAAAAAACQAAAgAAAAECAAAAFENsb3NlIHBvc2l0aW9uIGZpcnN0BAAAAA9uZXdQb3NpdGlvblNpemUIBQAAAA0kdDAyNzI0MjMwMjgwAAAAAl8xBAAAABduZXdQb3NpdGlvblJlbWFpbk1hcmdpbggFAAAADSR0MDI3MjQyMzAyODAAAAACXzIEAAAAF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsCAUAAAANJHQwMjcyNDIzMDI4MAAAAAJfMwQAAAAUbmV3UG9zaXRpb25MYXRlc3RDUEYIBQAAAA0kdDAyNzI0MjMwMjgwAAAAAl80BAAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQAAAA0kdDAyNzI0MjMwMjgwAAAAAl81BAAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwMjcyNDIzMDI4MAAAAAJfNgQAAAAWdG90YWxQb3NpdGlvblNpemVBZnRlcggFAAAADSR0MDI3MjQyMzAyODAAAAACXzcEAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCAUAAAANJHQwMjcyNDIzMDI4MAAAAAJfOAQAAAAZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcggFAAAADSR0MDI3MjQyMzAyODAAAAACXzkEAAAADnRvdGFsTG9uZ0FmdGVyCAUAAAANJHQwMjcyNDIzMDI4MAAAAANfMTAEAAAAD3RvdGFsU2hvcnRBZnRlcggFAAAADSR0MDI3MjQyMzAyODAAAAADXzExCQAETgAAAAIJAQAAAA51cGRhdGVQb3NpdGlvbgAAAAUJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBQAAAA9uZXdQb3NpdGlvblNpemUFAAAAF25ld1Bvc2l0aW9uUmVtYWluTWFyZ2luBQAAABduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAUAAAAUbmV3UG9zaXRpb25MYXRlc3RDUEYJAQAAAAl1cGRhdGVBbW0AAAAHBQAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyBQAAABlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyBQAAAA50b3RhbExvbmdBZnRlcgUAAAAPdG90YWxTaG9ydEFmdGVyAAAAAWkBAAAAEGluY3JlYXNlUG9zaXRpb24AAAADAAAACl9kaXJlY3Rpb24AAAAJX2xldmVyYWdlAAAAE19taW5CYXNlQXNzZXRBbW91bnQEAAAACl9yYXdBbW91bnQICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAMDAwMDAwMDCQEAAAACIT0AAAACBQAAAApfZGlyZWN0aW9uBQAAAAhESVJfTE9ORwkBAAAAAiE9AAAAAgUAAAAKX2RpcmVjdGlvbgUAAAAJRElSX1NIT1JUBwYJAABnAAAAAgAAAAAAAAAAAAUAAAAKX3Jhd0Ftb3VudAYDCQAAZgAAAAIJAABoAAAAAgAAAAAAAAAAAQUAAAAMREVDSU1BTF9VTklUBQAAAAlfbGV2ZXJhZ2UGCQAAZgAAAAIFAAAACV9sZXZlcmFnZQkAAGgAAAACAAAAAAAAAAADBQAAAAxERUNJTUFMX1VOSVQGCQEAAAABIQAAAAEJAQAAAAtpbml0aWFsaXplZAAAAAAGCQEAAAACIT0AAAACCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkCQEAAAAKcXVvdGVBc3NldAAAAAAGCQEAAAABIQAAAAEJAQAAABZyZXF1aXJlTW9yZU1hcmdpblJhdGlvAAAAAwkBAAAABGRpdmQAAAACBQAAAAxERUNJTUFMX1VOSVQFAAAACV9sZXZlcmFnZQkBAAAAD2luaXRNYXJnaW5SYXRpbwAAAAAGBgkBAAAABnBhdXNlZAAAAAAJAAACAAAAAQIAAAAjSW52YWxpZCBpbmNyZWFzZVBvc2l0aW9uIHBhcmFtZXRlcnMEAAAACWZlZUFtb3VudAkBAAAABG11bGQAAAACBQAAAApfcmF3QW1vdW50CQEAAAADZmVlAAAAAAQAAAAHX2Ftb3VudAkAAGUAAAACBQAAAApfcmF3QW1vdW50BQAAAAlmZWVBbW91bnQEAAAADSR0MDMxMzE2MzE0NDAJAQAAAAtnZXRQb3NpdGlvbgAAAAEJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAA9vbGRQb3NpdGlvblNpemUIBQAAAA0kdDAzMTMxNjMxNDQwAAAAAl8xBAAAABFvbGRQb3NpdGlvbk1hcmdpbggFAAAADSR0MDMxMzE2MzE0NDAAAAACXzIEAAAAF29sZFBvc2l0aW9uT3Blbk5vdGlvbmFsCAUAAAANJHQwMzEzMTYzMTQ0MAAAAAJfMwQAAAANaXNOZXdQb3NpdGlvbgkAAAAAAAACBQAAAA9vbGRQb3NpdGlvblNpemUAAAAAAAAAAAAEAAAAD2lzU2FtZURpcmVjdGlvbgMJAABmAAAAAgUAAAAPb2xkUG9zaXRpb25TaXplAAAAAAAAAAAACQAAAAAAAAIFAAAACl9kaXJlY3Rpb24FAAAACERJUl9MT05HCQAAAAAAAAIFAAAACl9kaXJlY3Rpb24FAAAACURJUl9TSE9SVAQAAAAOZXhwYW5kRXhpc3RpbmcDCQEAAAABIQAAAAEFAAAADWlzTmV3UG9zaXRpb24FAAAAD2lzU2FtZURpcmVjdGlvbgcEAAAABWlzQWRkCQAAAAAAAAIFAAAACl9kaXJlY3Rpb24FAAAACERJUl9MT05HBAAAAA0kdDAzMTcyOTM0MTk2AwMFAAAADWlzTmV3UG9zaXRpb24GBQAAAA5leHBhbmRFeGlzdGluZwQAAAAMb3Blbk5vdGlvbmFsCQEAAAAEbXVsZAAAAAIFAAAAB19hbW91bnQFAAAACV9sZXZlcmFnZQQAAAANJHQwMzIxNTMzMjM1OQkBAAAACXN3YXBJbnB1dAAAAAIFAAAABWlzQWRkBQAAAAxvcGVuTm90aW9uYWwEAAAAFWFtb3VudEJhc2VBc3NldEJvdWdodAgFAAAADSR0MDMyMTUzMzIzNTkAAAACXzEEAAAAFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQAAAA0kdDAzMjE1MzMyMzU5AAAAAl8yBAAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQAAAA0kdDAzMjE1MzMyMzU5AAAAAl8zBAAAABZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUAAAANJHQwMzIxNTMzMjM1OQAAAAJfNAQAAAAXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIIBQAAAA0kdDAzMjE1MzMyMzU5AAAAAl81AwMJAQAAAAIhPQAAAAIFAAAAE19taW5CYXNlQXNzZXRBbW91bnQAAAAAAAAAAAAJAABmAAAAAgUAAAATX21pbkJhc2VBc3NldEFtb3VudAkBAAAAA2FicwAAAAEFAAAAFWFtb3VudEJhc2VBc3NldEJvdWdodAcJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAANTGltaXQgZXJyb3I6IAkAAaQAAAABCQEAAAADYWJzAAAAAQUAAAAVYW1vdW50QmFzZUFzc2V0Qm91Z2h0AgAAAAMgPCAJAAGkAAAAAQUAAAATX21pbkJhc2VBc3NldEFtb3VudAQAAAAPbmV3UG9zaXRpb25TaXplCQAAZAAAAAIFAAAAD29sZFBvc2l0aW9uU2l6ZQUAAAAVYW1vdW50QmFzZUFzc2V0Qm91Z2h0BAAAABFwb3NpdGlvbkxzdFVwZENQRgkBAAAAH2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24AAAABBQAAAA9uZXdQb3NpdGlvblNpemUEAAAAGWluY3JlYXNlTWFyZ2luUmVxdWlyZW1lbnQJAQAAAARkaXZkAAAAAgUAAAAMb3Blbk5vdGlvbmFsBQAAAAlfbGV2ZXJhZ2UEAAAADSR0MDMyODIxMzMwNTcJAQAAACJjYWxjUmVtYWluTWFyZ2luV2l0aEZ1bmRpbmdQYXltZW50AAAABAUAAAAPb2xkUG9zaXRpb25TaXplBQAAABFvbGRQb3NpdGlvbk1hcmdpbgUAAAARcG9zaXRpb25Mc3RVcGRDUEYFAAAAGWluY3JlYXNlTWFyZ2luUmVxdWlyZW1lbnQEAAAADHJlbWFpbk1hcmdpbggFAAAADSR0MDMyODIxMzMwNTcAAAACXzEEAAAAAngxCAUAAAANJHQwMzI4MjEzMzA1NwAAAAJfMgQAAAACeDIIBQAAAA0kdDAzMjgyMTMzMDU3AAAAAl8zCQAFHQAAAAsFAAAAD25ld1Bvc2l0aW9uU2l6ZQUAAAAMcmVtYWluTWFyZ2luCQAAZAAAAAIFAAAAF29sZFBvc2l0aW9uT3Blbk5vdGlvbmFsBQAAAAxvcGVuTm90aW9uYWwJAQAAAB9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAAAAQUAAAAPbmV3UG9zaXRpb25TaXplBQAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCQAAZAAAAAIJAQAAABRvcGVuSW50ZXJlc3ROb3Rpb25hbAAAAAAFAAAADG9wZW5Ob3Rpb25hbAkAAGQAAAACCQEAAAAVdG90YWxMb25nUG9zaXRpb25TaXplAAAAAAMJAABmAAAAAgUAAAAPbmV3UG9zaXRpb25TaXplAAAAAAAAAAAACQEAAAADYWJzAAAAAQUAAAAVYW1vdW50QmFzZUFzc2V0Qm91Z2h0AAAAAAAAAAAACQAAZAAAAAIJAQAAABZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAAAAAMJAABmAAAAAgAAAAAAAAAAAAUAAAAPbmV3UG9zaXRpb25TaXplCQEAAAADYWJzAAAAAQUAAAAVYW1vdW50QmFzZUFzc2V0Qm91Z2h0AAAAAAAAAAAABAAAAAxvcGVuTm90aW9uYWwJAQAAAARtdWxkAAAAAgUAAAAHX2Ftb3VudAUAAAAJX2xldmVyYWdlBAAAAA0kdDAzMzg4OTM0MDA1CQEAAAAjZ2V0UG9zaXRpb25Ob3Rpb25hbEFuZFVucmVhbGl6ZWRQbmwAAAACCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgUAAAAPUE5MX09QVElPTl9TUE9UBAAAABNvbGRQb3NpdGlvbk5vdGlvbmFsCAUAAAANJHQwMzM4ODkzNDAwNQAAAAJfMQQAAAANdW5yZWFsaXplZFBubAgFAAAADSR0MDMzODg5MzQwMDUAAAACXzIDCQAAZgAAAAIFAAAAE29sZFBvc2l0aW9uTm90aW9uYWwFAAAADG9wZW5Ob3Rpb25hbAkAAAIAAAABAgAAAC5Vc2UgZGVjcmVhc2VQb3NpdGlvbiB0byBkZWNyZWFzZSBwb3NpdGlvbiBzaXplCQAAAgAAAAECAAAAFENsb3NlIHBvc2l0aW9uIGZpcnN0BAAAAA9uZXdQb3NpdGlvblNpemUIBQAAAA0kdDAzMTcyOTM0MTk2AAAAAl8xBAAAABduZXdQb3NpdGlvblJlbWFpbk1hcmdpbggFAAAADSR0MDMxNzI5MzQxOTYAAAACXzIEAAAAF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsCAUAAAANJHQwMzE3MjkzNDE5NgAAAAJfMwQAAAAUbmV3UG9zaXRpb25MYXRlc3RDUEYIBQAAAA0kdDAzMTcyOTM0MTk2AAAAAl80BAAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQAAAA0kdDAzMTcyOTM0MTk2AAAAAl81BAAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUAAAANJHQwMzE3MjkzNDE5NgAAAAJfNgQAAAAWdG90YWxQb3NpdGlvblNpemVBZnRlcggFAAAADSR0MDMxNzI5MzQxOTYAAAACXzcEAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCAUAAAANJHQwMzE3MjkzNDE5NgAAAAJfOAQAAAAZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcggFAAAADSR0MDMxNzI5MzQxOTYAAAACXzkEAAAADnRvdGFsTG9uZ0FmdGVyCAUAAAANJHQwMzE3MjkzNDE5NgAAAANfMTAEAAAAD3RvdGFsU2hvcnRBZnRlcggFAAAADSR0MDMxNzI5MzQxOTYAAAADXzExBAAAAAxmZWVUb1N0YWtlcnMJAABpAAAAAgUAAAAJZmVlQW1vdW50AAAAAAAAAAACBAAAAA5mZWVUb0luc3VyYW5jZQkAAGUAAAACBQAAAAlmZWVBbW91bnQFAAAADGZlZVRvU3Rha2VycwQAAAAFc3Rha2UJAAP8AAAABAkBAAAAEXF1b3RlQXNzZXRTdGFraW5nAAAAAAIAAAAObG9ja05ldXRyaW5vU1AJAARMAAAAAgkABCUAAAABCQEAAAAOc3Rha2luZ0FkZHJlc3MAAAAACQAETAAAAAIFAAAACEFMTF9GRUVTBQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIJAQAAAApxdW90ZUFzc2V0AAAAAAUAAAAHX2Ftb3VudAUAAAADbmlsAwkAAAAAAAACBQAAAAVzdGFrZQUAAAAFc3Rha2UEAAAAEGRlcG9zaXRJbnN1cmFuY2UJAAP8AAAABAkBAAAAEGluc3VyYW5jZUFkZHJlc3MAAAAAAgAAAAdkZXBvc2l0BQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIJAQAAAApxdW90ZUFzc2V0AAAAAAUAAAAOZmVlVG9JbnN1cmFuY2UFAAAAA25pbAMJAAAAAAAAAgUAAAAQZGVwb3NpdEluc3VyYW5jZQUAAAAQZGVwb3NpdEluc3VyYW5jZQkABE4AAAACCQAETgAAAAIJAAROAAAAAgkBAAAADnVwZGF0ZVBvc2l0aW9uAAAABQkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIFAAAAD25ld1Bvc2l0aW9uU2l6ZQUAAAAXbmV3UG9zaXRpb25SZW1haW5NYXJnaW4FAAAAF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsBQAAABRuZXdQb3NpdGlvbkxhdGVzdENQRgkBAAAACXVwZGF0ZUFtbQAAAAcFAAAAFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAFWJhc2VBc3NldFJlc2VydmVBZnRlcgUAAAAWdG90YWxQb3NpdGlvblNpemVBZnRlcgUAAAAXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIFAAAAGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIFAAAADnRvdGFsTG9uZ0FmdGVyBQAAAA90b3RhbFNob3J0QWZ0ZXIJAQAAAAt0cmFuc2ZlckZlZQAAAAEFAAAADGZlZVRvU3Rha2VycwkBAAAADXVwZGF0ZUJhbGFuY2UAAAABCQAAZAAAAAIJAQAAAAhjYmFsYW5jZQAAAAAFAAAAB19hbW91bnQJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAlhZGRNYXJnaW4AAAAABAAAAApfcmF3QW1vdW50CAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQDAwMDCQEAAAACIT0AAAACCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkCQEAAAAKcXVvdGVBc3NldAAAAAAGCQEAAAABIQAAAAEJAQAAABNyZXF1aXJlT3BlblBvc2l0aW9uAAAAAQkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIGCQEAAAABIQAAAAEJAQAAAAtpbml0aWFsaXplZAAAAAAGCQEAAAAGcGF1c2VkAAAAAAkAAAIAAAABAgAAABxJbnZhbGlkIGFkZE1hcmdpbiBwYXJhbWV0ZXJzBAAAAAlmZWVBbW91bnQJAQAAAARtdWxkAAAAAgUAAAAKX3Jhd0Ftb3VudAkBAAAAA2ZlZQAAAAAEAAAAB19hbW91bnQJAABlAAAAAgUAAAAKX3Jhd0Ftb3VudAUAAAAJZmVlQW1vdW50BAAAAA0kdDAzNTQ3MjM1NjI0CQEAAAALZ2V0UG9zaXRpb24AAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAPb2xkUG9zaXRpb25TaXplCAUAAAANJHQwMzU0NzIzNTYyNAAAAAJfMQQAAAARb2xkUG9zaXRpb25NYXJnaW4IBQAAAA0kdDAzNTQ3MjM1NjI0AAAAAl8yBAAAABdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFAAAADSR0MDM1NDcyMzU2MjQAAAACXzMEAAAAFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUAAAANJHQwMzU0NzIzNTYyNAAAAAJfNAQAAAAMZmVlVG9TdGFrZXJzCQAAaQAAAAIFAAAACWZlZUFtb3VudAAAAAAAAAAAAgQAAAAOZmVlVG9JbnN1cmFuY2UJAABlAAAAAgUAAAAJZmVlQW1vdW50BQAAAAxmZWVUb1N0YWtlcnMEAAAABXN0YWtlCQAD/AAAAAQJAQAAABFxdW90ZUFzc2V0U3Rha2luZwAAAAACAAAADmxvY2tOZXV0cmlub1NQCQAETAAAAAIJAAQlAAAAAQkBAAAADnN0YWtpbmdBZGRyZXNzAAAAAAkABEwAAAACBQAAAAhBTExfRkVFUwUAAAADbmlsCQAETAAAAAIJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACCQEAAAAKcXVvdGVBc3NldAAAAAAFAAAAB19hbW91bnQFAAAAA25pbAMJAAAAAAAAAgUAAAAFc3Rha2UFAAAABXN0YWtlBAAAABBkZXBvc2l0SW5zdXJhbmNlCQAD/AAAAAQJAQAAABBpbnN1cmFuY2VBZGRyZXNzAAAAAAIAAAAHZGVwb3NpdAUAAAADbmlsCQAETAAAAAIJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACCQEAAAAKcXVvdGVBc3NldAAAAAAFAAAADmZlZVRvSW5zdXJhbmNlBQAAAANuaWwDCQAAAAAAAAIFAAAAEGRlcG9zaXRJbnN1cmFuY2UFAAAAEGRlcG9zaXRJbnN1cmFuY2UJAAROAAAAAgkABE4AAAACCQEAAAAOdXBkYXRlUG9zaXRpb24AAAAFCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgUAAAAPb2xkUG9zaXRpb25TaXplCQAAZAAAAAIFAAAAEW9sZFBvc2l0aW9uTWFyZ2luBQAAAAdfYW1vdW50BQAAABdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAUAAAAUb2xkUG9zaXRpb25Mc3RVcGRDUEYJAQAAAAt0cmFuc2ZlckZlZQAAAAEFAAAADGZlZVRvU3Rha2VycwkBAAAADXVwZGF0ZUJhbGFuY2UAAAABCQAAZAAAAAIJAQAAAAhjYmFsYW5jZQAAAAAFAAAAB19hbW91bnQJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAxyZW1vdmVNYXJnaW4AAAABAAAAB19hbW91bnQDAwMDCQAAZwAAAAIAAAAAAAAAAAAFAAAAB19hbW91bnQGCQEAAAABIQAAAAEJAQAAABNyZXF1aXJlT3BlblBvc2l0aW9uAAAAAQkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIGCQEAAAABIQAAAAEJAQAAAAtpbml0aWFsaXplZAAAAAAGCQEAAAAGcGF1c2VkAAAAAAkAAAIAAAABAgAAAB9JbnZhbGlkIHJlbW92ZU1hcmdpbiBwYXJhbWV0ZXJzBAAAAA0kdDAzNjU0NDM2Njk2CQEAAAALZ2V0UG9zaXRpb24AAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAPb2xkUG9zaXRpb25TaXplCAUAAAANJHQwMzY1NDQzNjY5NgAAAAJfMQQAAAARb2xkUG9zaXRpb25NYXJnaW4IBQAAAA0kdDAzNjU0NDM2Njk2AAAAAl8yBAAAABdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFAAAADSR0MDM2NTQ0MzY2OTYAAAACXzMEAAAAFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUAAAANJHQwMzY1NDQzNjY5NgAAAAJfNAQAAAALbWFyZ2luRGVsdGEJAQAAAAEtAAAAAQUAAAAHX2Ftb3VudAQAAAANJHQwMzY3MzMzNjkxMgkBAAAAImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQAAAAEBQAAAA9vbGRQb3NpdGlvblNpemUFAAAAEW9sZFBvc2l0aW9uTWFyZ2luBQAAABRvbGRQb3NpdGlvbkxzdFVwZENQRgUAAAALbWFyZ2luRGVsdGEEAAAADHJlbWFpbk1hcmdpbggFAAAADSR0MDM2NzMzMzY5MTIAAAACXzEEAAAAB2JhZERlYnQIBQAAAA0kdDAzNjczMzM2OTEyAAAAAl8yAwkBAAAAAiE9AAAAAgUAAAAHYmFkRGVidAAAAAAAAAAAAAkAAAIAAAABAgAAABtJbnZhbGlkIGFkZGVkIG1hcmdpbiBhbW91bnQEAAAAB3Vuc3Rha2UJAAP8AAAABAkBAAAAEXF1b3RlQXNzZXRTdGFraW5nAAAAAAIAAAAOdW5sb2NrTmV1dHJpbm8JAARMAAAAAgUAAAAHX2Ftb3VudAkABEwAAAACCQACWAAAAAEJAQAAAApxdW90ZUFzc2V0AAAAAAUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAB3Vuc3Rha2UFAAAAB3Vuc3Rha2UJAAROAAAAAgkABE4AAAACCQEAAAAOdXBkYXRlUG9zaXRpb24AAAAFCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgUAAAAPb2xkUG9zaXRpb25TaXplBQAAAAxyZW1haW5NYXJnaW4FAAAAF29sZFBvc2l0aW9uT3Blbk5vdGlvbmFsCQEAAAAfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAAAAEFAAAAD29sZFBvc2l0aW9uU2l6ZQkBAAAACHdpdGhkcmF3AAAAAggFAAAAAWkAAAAGY2FsbGVyBQAAAAdfYW1vdW50CQEAAAANdXBkYXRlQmFsYW5jZQAAAAEJAABlAAAAAgkBAAAACGNiYWxhbmNlAAAAAAUAAAAHX2Ftb3VudAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAANY2xvc2VQb3NpdGlvbgAAAAADAwMJAQAAAAEhAAAAAQkBAAAAE3JlcXVpcmVPcGVuUG9zaXRpb24AAAABCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgYJAQAAAAEhAAAAAQkBAAAAC2luaXRpYWxpemVkAAAAAAYJAQAAAAZwYXVzZWQAAAAACQAAAgAAAAECAAAAIEludmFsaWQgY2xvc2VQb3NpdGlvbiBwYXJhbWV0ZXJzBAAAAA0kdDAzNzY3MjM4MDU2CQEAAAAVaW50ZXJuYWxDbG9zZVBvc2l0aW9uAAAAAQkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAAAngxCAUAAAANJHQwMzc2NzIzODA1NgAAAAJfMQQAAAAPcG9zaXRpb25CYWREZWJ0CAUAAAANJHQwMzc2NzIzODA1NgAAAAJfMgQAAAALcmVhbGl6ZWRQbmwIBQAAAA0kdDAzNzY3MjM4MDU2AAAAAl8zBAAAAA1tYXJnaW5Ub1ZhdWx0CAUAAAANJHQwMzc2NzIzODA1NgAAAAJfNAQAAAAWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFAAAADSR0MDM3NjcyMzgwNTYAAAACXzUEAAAAFWJhc2VBc3NldFJlc2VydmVBZnRlcggFAAAADSR0MDM3NjcyMzgwNTYAAAACXzYEAAAAFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQAAAA0kdDAzNzY3MjM4MDU2AAAAAl83BAAAABdjdW11bGF0aXZlTm90aW9uYWxBZnRlcggFAAAADSR0MDM3NjcyMzgwNTYAAAACXzgEAAAAGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIIBQAAAA0kdDAzNzY3MjM4MDU2AAAAAl85BAAAAAJ4MggFAAAADSR0MDM3NjcyMzgwNTYAAAADXzEwBAAAAA50b3RhbExvbmdBZnRlcggFAAAADSR0MDM3NjcyMzgwNTYAAAADXzExBAAAAA90b3RhbFNob3J0QWZ0ZXIIBQAAAA0kdDAzNzY3MjM4MDU2AAAAA18xMgMJAABmAAAAAgUAAAAPcG9zaXRpb25CYWREZWJ0AAAAAAAAAAAACQAAAgAAAAECAAAAJlVuYWJsZSB0byBjbG9zZSBwb3NpdGlvbiB3aXRoIGJhZCBkZWJ0BAAAAA53aXRoZHJhd0Ftb3VudAkBAAAAA2FicwAAAAEFAAAADW1hcmdpblRvVmF1bHQEAAAACmFtbUJhbGFuY2UJAABlAAAAAgkBAAAACGNiYWxhbmNlAAAAAAUAAAAOd2l0aGRyYXdBbW91bnQEAAAADSR0MDM4MjY1Mzg0MDcDCQAAZgAAAAIAAAAAAAAAAAAFAAAACmFtbUJhbGFuY2UJAAUUAAAAAgAAAAAAAAAAAAkBAAAAA2FicwAAAAEFAAAACmFtbUJhbGFuY2UJAAUUAAAAAgUAAAAKYW1tQmFsYW5jZQAAAAAAAAAAAAQAAAANYW1tTmV3QmFsYW5jZQgFAAAADSR0MDM4MjY1Mzg0MDcAAAACXzEEAAAAEGdldEZyb21JbnN1cmFuY2UIBQAAAA0kdDAzODI2NTM4NDA3AAAAAl8yBAAAAAF4AwkAAGYAAAACBQAAABBnZXRGcm9tSW5zdXJhbmNlAAAAAAAAAAAABAAAABF3aXRoZHJhd0luc3VyYW5jZQkAA/wAAAAECQEAAAAQaW5zdXJhbmNlQWRkcmVzcwAAAAACAAAACHdpdGhkcmF3CQAETAAAAAIFAAAAEGdldEZyb21JbnN1cmFuY2UFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAABF3aXRoZHJhd0luc3VyYW5jZQUAAAARd2l0aGRyYXdJbnN1cmFuY2UFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FAAAAA25pbAMJAAAAAAAAAgUAAAABeAUAAAABeAQAAAAHdW5zdGFrZQkAA/wAAAAECQEAAAARcXVvdGVBc3NldFN0YWtpbmcAAAAAAgAAAA51bmxvY2tOZXV0cmlubwkABEwAAAACCQAAZQAAAAIFAAAADndpdGhkcmF3QW1vdW50BQAAABBnZXRGcm9tSW5zdXJhbmNlCQAETAAAAAIJAAJYAAAAAQkBAAAACnF1b3RlQXNzZXQAAAAABQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAHdW5zdGFrZQUAAAAHdW5zdGFrZQkABE4AAAACCQAETgAAAAIJAAROAAAAAgkBAAAADmRlbGV0ZVBvc2l0aW9uAAAAAQkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIJAQAAAAl1cGRhdGVBbW0AAAAHBQAAABZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFAAAAFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFAAAAF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyBQAAABlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyBQAAAA50b3RhbExvbmdBZnRlcgUAAAAPdG90YWxTaG9ydEFmdGVyCQEAAAAId2l0aGRyYXcAAAACCAUAAAABaQAAAAZjYWxsZXIFAAAADndpdGhkcmF3QW1vdW50CQEAAAANdXBkYXRlQmFsYW5jZQAAAAEFAAAADWFtbU5ld0JhbGFuY2UJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAlsaXF1aWRhdGUAAAABAAAAB190cmFkZXIEAAAAC21hcmdpblJhdGlvAwkBAAAAFmlzT3ZlckZsdWN0dWF0aW9uTGltaXQAAAAACQEAAAAWZ2V0TWFyZ2luUmF0aW9CeU9wdGlvbgAAAAIFAAAAB190cmFkZXIFAAAAEVBOTF9PUFRJT05fT1JBQ0xFCQEAAAAWZ2V0TWFyZ2luUmF0aW9CeU9wdGlvbgAAAAIFAAAAB190cmFkZXIFAAAAD1BOTF9PUFRJT05fU1BPVAMDAwMJAQAAAAEhAAAAAQkBAAAAFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8AAAADBQAAAAttYXJnaW5SYXRpbwkBAAAAFm1haW50ZW5hbmNlTWFyZ2luUmF0aW8AAAAABwYJAQAAAAEhAAAAAQkBAAAAE3JlcXVpcmVPcGVuUG9zaXRpb24AAAABBQAAAAdfdHJhZGVyBgkBAAAAASEAAAABCQEAAAALaW5pdGlhbGl6ZWQAAAAABgkBAAAABnBhdXNlZAAAAAAJAAACAAAAAQIAAAATVW5hYmxlIHRvIGxpcXVpZGF0ZQQAAAANJHQwMzk4NDY0MDI3MwkBAAAAFWludGVybmFsQ2xvc2VQb3NpdGlvbgAAAAEFAAAAB190cmFkZXIEAAAAAngxCAUAAAANJHQwMzk4NDY0MDI3MwAAAAJfMQQAAAAHYmFkRGVidAgFAAAADSR0MDM5ODQ2NDAyNzMAAAACXzIEAAAAAngyCAUAAAANJHQwMzk4NDY0MDI3MwAAAAJfMwQAAAANbWFyZ2luVG9WYXVsdAgFAAAADSR0MDM5ODQ2NDAyNzMAAAACXzQEAAAAFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQAAAA0kdDAzOTg0NjQwMjczAAAAAl81BAAAABViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQAAAA0kdDAzOTg0NjQwMjczAAAAAl82BAAAABZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUAAAANJHQwMzk4NDY0MDI3MwAAAAJfNwQAAAAXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIIBQAAAA0kdDAzOTg0NjQwMjczAAAAAl84BAAAABlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCAUAAAANJHQwMzk4NDY0MDI3MwAAAAJfOQQAAAAZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAgFAAAADSR0MDM5ODQ2NDAyNzMAAAADXzEwBAAAAA50b3RhbExvbmdBZnRlcggFAAAADSR0MDM5ODQ2NDAyNzMAAAADXzExBAAAAA90b3RhbFNob3J0QWZ0ZXIIBQAAAA0kdDAzOTg0NjQwMjczAAAAA18xMgQAAAASbGlxdWlkYXRpb25QZW5hbHR5CQEAAAAEbXVsZAAAAAIFAAAAGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQJAQAAABNsaXF1aWRhdGlvbkZlZVJhdGlvAAAAAAQAAAAPZmVlVG9MaXF1aWRhdG9yCQAAaQAAAAIFAAAAEmxpcXVpZGF0aW9uUGVuYWx0eQAAAAAAAAAAAgQAAAAOZmVlVG9JbnN1cmFuY2UJAABlAAAAAgUAAAASbGlxdWlkYXRpb25QZW5hbHR5BQAAAA9mZWVUb0xpcXVpZGF0b3IEAAAACmFtbUJhZERlYnQJAABlAAAAAgkBAAAACGNiYWxhbmNlAAAAAAUAAAASbGlxdWlkYXRpb25QZW5hbHR5BAAAAA0kdDA0MDY3MTQwODA2AwkAAGYAAAACAAAAAAAAAAAABQAAAAphbW1CYWREZWJ0CQAFFAAAAAIAAAAAAAAAAAAJAQAAAANhYnMAAAABBQAAAAphbW1CYWREZWJ0CQAFFAAAAAIFAAAACmFtbUJhZERlYnQAAAAAAAAAAAAEAAAADW5ld0FtbUJhbGFuY2UIBQAAAA0kdDA0MDY3MTQwODA2AAAAAl8xBAAAABF0YWtlRnJvbUluc3VyYW5jZQgFAAAADSR0MDQwNjcxNDA4MDYAAAACXzIEAAAAAXgDCQAAZgAAAAIFAAAAEXRha2VGcm9tSW5zdXJhbmNlAAAAAAAAAAAABAAAABF3aXRoZHJhd0luc3VyYW5jZQkAA/wAAAAECQEAAAAQaW5zdXJhbmNlQWRkcmVzcwAAAAACAAAACHdpdGhkcmF3CQAETAAAAAIFAAAAEXRha2VGcm9tSW5zdXJhbmNlBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAARd2l0aGRyYXdJbnN1cmFuY2UFAAAAEXdpdGhkcmF3SW5zdXJhbmNlBQAAAANuaWwJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQAAAANuaWwDCQAAAAAAAAIFAAAAAXgFAAAAAXgEAAAAEGRlcG9zaXRJbnN1cmFuY2UJAAP8AAAABAkBAAAAEGluc3VyYW5jZUFkZHJlc3MAAAAAAgAAAAdkZXBvc2l0BQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIJAQAAAApxdW90ZUFzc2V0AAAAAAUAAAAOZmVlVG9JbnN1cmFuY2UFAAAAA25pbAMJAAAAAAAAAgUAAAAQZGVwb3NpdEluc3VyYW5jZQUAAAAQZGVwb3NpdEluc3VyYW5jZQQAAAAHdW5zdGFrZQkAA/wAAAAECQEAAAARcXVvdGVBc3NldFN0YWtpbmcAAAAAAgAAAA51bmxvY2tOZXV0cmlubwkABEwAAAACCQAAZQAAAAIFAAAAD2ZlZVRvTGlxdWlkYXRvcgUAAAARdGFrZUZyb21JbnN1cmFuY2UJAARMAAAAAgkAAlgAAAABCQEAAAAKcXVvdGVBc3NldAAAAAAFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAAd1bnN0YWtlBQAAAAd1bnN0YWtlCQAETgAAAAIJAAROAAAAAgkABE4AAAACCQEAAAAOZGVsZXRlUG9zaXRpb24AAAABBQAAAAdfdHJhZGVyCQEAAAAJdXBkYXRlQW1tAAAABwUAAAAWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUAAAAVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBQAAABZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBQAAABdjdW11bGF0aXZlTm90aW9uYWxBZnRlcgUAAAAZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgUAAAAOdG90YWxMb25nQWZ0ZXIFAAAAD3RvdGFsU2hvcnRBZnRlcgkBAAAACHdpdGhkcmF3AAAAAggFAAAAAWkAAAAGY2FsbGVyBQAAAA9mZWVUb0xpcXVpZGF0b3IJAQAAAA11cGRhdGVCYWxhbmNlAAAAAQUAAAAKYW1tQmFkRGVidAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAApwYXlGdW5kaW5nAAAAAAQAAAAVZnVuZGluZ0Jsb2NrVGltZXN0YW1wCQEAAAAZbmV4dEZ1bmRpbmdCbG9ja1RpbWVzdGFtcAAAAAADAwMJAABmAAAAAgUAAAAVZnVuZGluZ0Jsb2NrVGltZXN0YW1wCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAYJAQAAAAEhAAAAAQkBAAAAC2luaXRpYWxpemVkAAAAAAYJAQAAAAZwYXVzZWQAAAAACQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAIUludmFsaWQgZnVuZGluZyBibG9jayB0aW1lc3RhbXA6IAkAAaQAAAABCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAIAAAADIDwgCQABpAAAAAEFAAAAFWZ1bmRpbmdCbG9ja1RpbWVzdGFtcAQAAAAPdW5kZXJseWluZ1ByaWNlCQEAAAASZ2V0T3JhY2xlVHdhcFByaWNlAAAAAAQAAAANc3BvdFR3YXBQcmljZQkBAAAAEGdldFR3YXBTcG90UHJpY2UAAAAABAAAAAdwcmVtaXVtCQAAZQAAAAIFAAAADXNwb3RUd2FwUHJpY2UFAAAAD3VuZGVybHlpbmdQcmljZQQAAAANJHQwNDIxNzY0MzUxMQMDCQAAAAAAAAIJAQAAABZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAAAAAAAAAAAAAAAAAYJAAAAAAAAAgkBAAAAFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAAAAAAAAAAAAAAAAAJAAUUAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAMJAABmAAAAAgAAAAAAAAAAAAUAAAAHcHJlbWl1bQQAAAAUc2hvcnRQcmVtaXVtRnJhY3Rpb24JAQAAAARkaXZkAAAAAgkBAAAABG11bGQAAAACBQAAAAdwcmVtaXVtCQEAAAAUZnVuZGluZ1BlcmlvZERlY2ltYWwAAAAABQAAAAdPTkVfREFZBAAAABNsb25nUHJlbWl1bUZyYWN0aW9uCQEAAAAEZGl2ZAAAAAIJAQAAAARtdWxkAAAAAgUAAAAUc2hvcnRQcmVtaXVtRnJhY3Rpb24JAQAAABZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAAAAAkBAAAAFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAAAAAJAAUUAAAAAgUAAAAUc2hvcnRQcmVtaXVtRnJhY3Rpb24FAAAAE2xvbmdQcmVtaXVtRnJhY3Rpb24EAAAAE2xvbmdQcmVtaXVtRnJhY3Rpb24JAQAAAARkaXZkAAAAAgkBAAAABG11bGQAAAACBQAAAAdwcmVtaXVtCQEAAAAUZnVuZGluZ1BlcmlvZERlY2ltYWwAAAAABQAAAAdPTkVfREFZBAAAABRzaG9ydFByZW1pdW1GcmFjdGlvbgkBAAAABGRpdmQAAAACCQEAAAAEbXVsZAAAAAIFAAAAE2xvbmdQcmVtaXVtRnJhY3Rpb24JAQAAABV0b3RhbExvbmdQb3NpdGlvblNpemUAAAAACQEAAAAWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAAAAAJAAUUAAAAAgUAAAAUc2hvcnRQcmVtaXVtRnJhY3Rpb24FAAAAE2xvbmdQcmVtaXVtRnJhY3Rpb24EAAAAFHNob3J0UHJlbWl1bUZyYWN0aW9uCAUAAAANJHQwNDIxNzY0MzUxMQAAAAJfMQQAAAATbG9uZ1ByZW1pdW1GcmFjdGlvbggFAAAADSR0MDQyMTc2NDM1MTEAAAACXzIJAQAAAA11cGRhdGVGdW5kaW5nAAAABQkAAGQAAAACBQAAABVmdW5kaW5nQmxvY2tUaW1lc3RhbXAJAQAAABRmdW5kaW5nUGVyaW9kU2Vjb25kcwAAAAAJAABkAAAAAgkBAAAAI2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAAAAAUAAAATbG9uZ1ByZW1pdW1GcmFjdGlvbgkAAGQAAAACCQEAAAAkbGF0ZXN0U2hvcnRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAAAAAUAAAAUc2hvcnRQcmVtaXVtRnJhY3Rpb24JAQAAAARkaXZkAAAAAgUAAAATbG9uZ1ByZW1pdW1GcmFjdGlvbgUAAAAPdW5kZXJseWluZ1ByaWNlCQEAAAAEZGl2ZAAAAAIFAAAAFHNob3J0UHJlbWl1bUZyYWN0aW9uBQAAAA91bmRlcmx5aW5nUHJpY2UAAAABaQEAAAAFdl9nZXQAAAABAAAAB190cmFkZXIEAAAADSR0MDQzODg2NDM5MzkJAQAAABVpbnRlcm5hbENsb3NlUG9zaXRpb24AAAABBQAAAAdfdHJhZGVyBAAAAAJ4MQgFAAAADSR0MDQzODg2NDM5MzkAAAACXzEEAAAAAngyCAUAAAANJHQwNDM4ODY0MzkzOQAAAAJfMgQAAAACeDMIBQAAAA0kdDA0Mzg4NjQzOTM5AAAAAl8zBAAAAAJ4NAgFAAAADSR0MDQzODg2NDM5MzkAAAACXzQJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkBAAAAAXMAAAABBQAAAAJ4MgkBAAAAAXMAAAABBQAAAAJ4MwkBAAAAAXMAAAABBQAAAAJ4NAkBAAAAAXMAAAABCQEAAAAOZ2V0TWFyZ2luUmF0aW8AAAABBQAAAAdfdHJhZGVyAAAAAWkBAAAAJ3ZpZXdfY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAAAAAEAAAAHX3RyYWRlcgQAAAANJHQwNDQwODY0NDE5NwkBAAAAC2dldFBvc2l0aW9uAAAAAQUAAAAHX3RyYWRlcgQAAAAMcG9zaXRpb25TaXplCAUAAAANJHQwNDQwODY0NDE5NwAAAAJfMQQAAAAOcG9zaXRpb25NYXJnaW4IBQAAAA0kdDA0NDA4NjQ0MTk3AAAAAl8yBAAAAANwb24IBQAAAA0kdDA0NDA4NjQ0MTk3AAAAAl8zBAAAABFwb3NpdGlvbkxzdFVwZENQRggFAAAADSR0MDQ0MDg2NDQxOTcAAAACXzQEAAAADSR0MDQ0MjAyNDQzMDMJAQAAACNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAAAAAIFAAAAB190cmFkZXIFAAAAD1BOTF9PUFRJT05fU1BPVAQAAAAQcG9zaXRpb25Ob3Rpb25hbAgFAAAADSR0MDQ0MjAyNDQzMDMAAAACXzEEAAAADXVucmVhbGl6ZWRQbmwIBQAAAA0kdDA0NDIwMjQ0MzAzAAAAAl8yBAAAAA0kdDA0NDMwODQ0NDkwCQEAAAAiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAAAAAQFAAAADHBvc2l0aW9uU2l6ZQUAAAAOcG9zaXRpb25NYXJnaW4FAAAAEXBvc2l0aW9uTHN0VXBkQ1BGBQAAAA11bnJlYWxpemVkUG5sBAAAAAxyZW1haW5NYXJnaW4IBQAAAA0kdDA0NDMwODQ0NDkwAAAAAl8xBAAAAAdiYWREZWJ0CAUAAAANJHQwNDQzMDg0NDQ5MAAAAAJfMgQAAAAOZnVuZGluZ1BheW1lbnQIBQAAAA0kdDA0NDMwODQ0NDkwAAAAAl8zCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQEAAAABcwAAAAEFAAAADHJlbWFpbk1hcmdpbgkBAAAAAXMAAAABBQAAAA5mdW5kaW5nUGF5bWVudAkBAAAAAXMAAAABCQEAAAAOZ2V0TWFyZ2luUmF0aW8AAAABBQAAAAdfdHJhZGVyAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAJAQAAAA5hZG1pblB1YmxpY0tleQAAAACJypcF", "height": 2122442, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9UZ7omFNbh8d4fPBqHZFKVdFFALUGNMofNZtDSoC8Xp3 Next: FYSNibP2BnGQCBdyEbDb9NWMDYi5X2o4CJ61M9HTTZ8e Diff:
OldNewDifferences
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let k_ora_key = "k_ora_key"
5+
6+let k_ora_block_key = "k_ora_block_key"
57
68 let k_ora = "k_ora"
79
107109 let FUNDING_BLOCK_INTERVAL = 60
108110
109111 let TWAP_INTERVAL = 15
112+
113+let ORACLE_INTERVAL = 15
110114
111115 let SECONDS = 1000
112116
279283 if ((priceImpact > maxPriceImpactValue))
280284 then throw(((("Price impact " + toString(priceImpact)) + " > max price impact ") + toString(maxPriceImpactValue)))
281285 else {
282- let $t01132811531 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
283- let quoteAssetReserveAfter1 = $t01132811531._1
284- let baseAssetReserveAfter1 = $t01132811531._2
285- let totalPositionSizeAfter1 = $t01132811531._3
286- let cumulativeNotionalAfter1 = $t01132811531._4
286+ let $t01143211635 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
287+ let quoteAssetReserveAfter1 = $t01143211635._1
288+ let baseAssetReserveAfter1 = $t01143211635._2
289+ let totalPositionSizeAfter1 = $t01143211635._3
290+ let cumulativeNotionalAfter1 = $t01143211635._4
287291 $Tuple5(amountBaseAssetBought, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1, cumulativeNotionalAfter1)
288292 }
289293 }
297301 }
298302 else 0
299303 let signedMargin = ((_marginDelta - fundingPayment) + _oldPositionMargin)
300- let $t01227812405 = if ((0 > signedMargin))
304+ let $t01238212509 = if ((0 > signedMargin))
301305 then $Tuple2(0, abs(signedMargin))
302306 else $Tuple2(abs(signedMargin), 0)
303- let remainMargin = $t01227812405._1
304- let badDebt = $t01227812405._2
307+ let remainMargin = $t01238212509._1
308+ let badDebt = $t01238212509._2
305309 $Tuple3(remainMargin, badDebt, fundingPayment)
306310 }
307311
318322 else (_baseAssetReserve - _baseAssetAmount)
319323 let quoteAssetAfter = divd(k, baseAssetPoolAmountAfter)
320324 let quoteAssetSold = abs((quoteAssetAfter - _quoteAssetReserve))
321- let $t01324313436 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
322- let quoteAssetReserveAfter1 = $t01324313436._1
323- let baseAssetReserveAfter1 = $t01324313436._2
324- let totalPositionSizeAfter1 = $t01324313436._3
325- let cumulativeNotionalAfter1 = $t01324313436._4
325+ let $t01334713540 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
326+ let quoteAssetReserveAfter1 = $t01334713540._1
327+ let baseAssetReserveAfter1 = $t01334713540._2
328+ let totalPositionSizeAfter1 = $t01334713540._3
329+ let cumulativeNotionalAfter1 = $t01334713540._4
326330 $Tuple7(quoteAssetSold, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1, cumulativeNotionalAfter1, (totalLongPositionSize() - (if (_isAdd)
327331 then abs(_baseAssetAmount)
328332 else 0)), (totalShortPositionSize() - (if (!(_isAdd))
335339 func getOracleTwapPrice () = {
336340 let oracle = valueOrErrorMessage(addressFromString(getStringValue(this, k_ora)), "")
337341 let priceKey = getStringValue(this, k_ora_key)
338- getIntegerValue(oracle, priceKey)
342+ let blockKey = getStringValue(this, k_ora_block_key)
343+ let lastValue = getIntegerValue(oracle, priceKey)
344+ lastValue
339345 }
340346
341347
354360
355361
356362 func getPositionNotionalAndUnrealizedPnl (_trader,_option) = {
357- let $t01471014838 = getPosition(_trader)
358- let positionSize = $t01471014838._1
359- let positionMargin = $t01471014838._2
360- let positionOpenNotional = $t01471014838._3
361- let positionLstUpdCPF = $t01471014838._4
363+ let $t01517215300 = getPosition(_trader)
364+ let positionSize = $t01517215300._1
365+ let positionMargin = $t01517215300._2
366+ let positionOpenNotional = $t01517215300._3
367+ let positionLstUpdCPF = $t01517215300._4
362368 let positionSizeAbs = abs(positionSize)
363369 if ((positionSizeAbs == 0))
364370 then throw("Invalid position size")
366372 let isShort = (0 > positionSize)
367373 let positionNotional = if ((_option == PNL_OPTION_SPOT))
368374 then {
369- let $t01508515192 = swapOutput(!(isShort), positionSizeAbs)
370- let outPositionNotional = $t01508515192._1
371- let x1 = $t01508515192._2
372- let x2 = $t01508515192._3
373- let x3 = $t01508515192._4
375+ let $t01554715654 = swapOutput(!(isShort), positionSizeAbs)
376+ let outPositionNotional = $t01554715654._1
377+ let x1 = $t01554715654._2
378+ let x2 = $t01554715654._3
379+ let x3 = $t01554715654._4
374380 outPositionNotional
375381 }
376382 else (positionSizeAbs * getOracleTwapPrice())
383389
384390
385391 func getMarginRatioByOption (_trader,_option) = {
386- let $t01568715798 = getPosition(_trader)
387- let positionSize = $t01568715798._1
388- let positionMargin = $t01568715798._2
389- let pon = $t01568715798._3
390- let positionLstUpdCPF = $t01568715798._4
391- let $t01580415897 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
392- let positionNotional = $t01580415897._1
393- let unrealizedPnl = $t01580415897._2
394- let $t01590216068 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
395- let remainMargin = $t01590216068._1
396- let badDebt = $t01590216068._2
392+ let $t01614916260 = getPosition(_trader)
393+ let positionSize = $t01614916260._1
394+ let positionMargin = $t01614916260._2
395+ let pon = $t01614916260._3
396+ let positionLstUpdCPF = $t01614916260._4
397+ let $t01626616359 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
398+ let positionNotional = $t01626616359._1
399+ let unrealizedPnl = $t01626616359._2
400+ let $t01636416530 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
401+ let remainMargin = $t01636416530._1
402+ let badDebt = $t01636416530._2
397403 divd((remainMargin - badDebt), positionNotional)
398404 }
399405
402408
403409
404410 func internalClosePosition (_trader) = {
405- let $t01637416485 = getPosition(_trader)
406- let positionSize = $t01637416485._1
407- let positionMargin = $t01637416485._2
408- let pon = $t01637416485._3
409- let positionLstUpdCPF = $t01637416485._4
410- let $t01649116578 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
411- let x1 = $t01649116578._1
412- let unrealizedPnl = $t01649116578._2
413- let $t01658316751 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
414- let remainMargin = $t01658316751._1
415- let badDebt = $t01658316751._2
411+ let $t01683616947 = getPosition(_trader)
412+ let positionSize = $t01683616947._1
413+ let positionMargin = $t01683616947._2
414+ let pon = $t01683616947._3
415+ let positionLstUpdCPF = $t01683616947._4
416+ let $t01695317040 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
417+ let x1 = $t01695317040._1
418+ let unrealizedPnl = $t01695317040._2
419+ let $t01704517213 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
420+ let remainMargin = $t01704517213._1
421+ let badDebt = $t01704517213._2
416422 let exchangedPositionSize = -(positionSize)
417423 let realizedPnl = unrealizedPnl
418424 let marginToVault = -(remainMargin)
419- let $t01687817159 = swapOutput((positionSize > 0), abs(positionSize))
420- let exchangedQuoteAssetAmount = $t01687817159._1
421- let quoteAssetReserveAfter = $t01687817159._2
422- let baseAssetReserveAfter = $t01687817159._3
423- let totalPositionSizeAfter = $t01687817159._4
424- let cumulativeNotionalAfter = $t01687817159._5
425- let totalLongAfter = $t01687817159._6
426- let totalShortAfter = $t01687817159._7
425+ let $t01734017621 = swapOutput((positionSize > 0), abs(positionSize))
426+ let exchangedQuoteAssetAmount = $t01734017621._1
427+ let quoteAssetReserveAfter = $t01734017621._2
428+ let baseAssetReserveAfter = $t01734017621._3
429+ let totalPositionSizeAfter = $t01734017621._4
430+ let cumulativeNotionalAfter = $t01734017621._5
431+ let totalLongAfter = $t01734017621._6
432+ let totalShortAfter = $t01734017621._7
427433 let openInterestNotionalAfter = (openInterestNotional() - pon)
428434 $Tuple12(exchangedPositionSize, badDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, exchangedQuoteAssetAmount, totalLongAfter, totalShortAfter)
429435 }
607613 else paused())
608614 then throw("Invalid decreasePosition parameters")
609615 else {
610- let $t02633926491 = getPosition(toString(i.caller))
611- let oldPositionSize = $t02633926491._1
612- let oldPositionMargin = $t02633926491._2
613- let oldPositionOpenNotional = $t02633926491._3
614- let oldPositionLstUpdCPF = $t02633926491._4
616+ let $t02680126953 = getPosition(toString(i.caller))
617+ let oldPositionSize = $t02680126953._1
618+ let oldPositionMargin = $t02680126953._2
619+ let oldPositionOpenNotional = $t02680126953._3
620+ let oldPositionLstUpdCPF = $t02680126953._4
615621 let isNewPosition = (oldPositionSize == 0)
616622 let isSameDirection = if ((oldPositionSize > 0))
617623 then (_direction == DIR_LONG)
620626 then isSameDirection
621627 else false
622628 let isAdd = (_direction == DIR_LONG)
623- let $t02678029818 = if (if (isNewPosition)
629+ let $t02724230280 = if (if (isNewPosition)
624630 then true
625631 else expandExisting)
626632 then throw("Use increasePosition to open new or increase position")
627633 else {
628634 let openNotional = muld(_amount, _leverage)
629- let $t02728627402 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
630- let oldPositionNotional = $t02728627402._1
631- let unrealizedPnl = $t02728627402._2
635+ let $t02774827864 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
636+ let oldPositionNotional = $t02774827864._1
637+ let unrealizedPnl = $t02774827864._2
632638 if ((oldPositionNotional > openNotional))
633639 then {
634- let $t02746427694 = swapInput(isAdd, openNotional)
635- let exchangedPositionSize = $t02746427694._1
636- let quoteAssetReserveAfter = $t02746427694._2
637- let baseAssetReserveAfter = $t02746427694._3
638- let totalPositionSizeAfter = $t02746427694._4
639- let cumulativeNotionalAfter = $t02746427694._5
640+ let $t02792628156 = swapInput(isAdd, openNotional)
641+ let exchangedPositionSize = $t02792628156._1
642+ let quoteAssetReserveAfter = $t02792628156._2
643+ let baseAssetReserveAfter = $t02792628156._3
644+ let totalPositionSizeAfter = $t02792628156._4
645+ let cumulativeNotionalAfter = $t02792628156._5
640646 let exchangedPositionSizeAbs = abs(exchangedPositionSize)
641647 if (if ((_minBaseAssetAmount != 0))
642648 then (_minBaseAssetAmount > exchangedPositionSizeAbs)
646652 let realizedPnl = if ((oldPositionSize != 0))
647653 then divd(muld(unrealizedPnl, exchangedPositionSizeAbs), oldPositionSize)
648654 else 0
649- let $t02823428491 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
650- let remainMargin = $t02823428491._1
651- let badDebt = $t02823428491._2
652- let fundingPayment = $t02823428491._3
655+ let $t02869628953 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
656+ let remainMargin = $t02869628953._1
657+ let badDebt = $t02869628953._2
658+ let fundingPayment = $t02869628953._3
653659 let exchangedQuoteAssetAmount = openNotional
654660 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
655661 let remainOpenNotional = if ((oldPositionSize > 0))
665671 }
666672 else throw("Close position first")
667673 }
668- let newPositionSize = $t02678029818._1
669- let newPositionRemainMargin = $t02678029818._2
670- let newPositionOpenNotional = $t02678029818._3
671- let newPositionLatestCPF = $t02678029818._4
672- let baseAssetReserveAfter = $t02678029818._5
673- let quoteAssetReserveAfter = $t02678029818._6
674- let totalPositionSizeAfter = $t02678029818._7
675- let cumulativeNotionalAfter = $t02678029818._8
676- let openInterestNotionalAfter = $t02678029818._9
677- let totalLongAfter = $t02678029818._10
678- let totalShortAfter = $t02678029818._11
674+ let newPositionSize = $t02724230280._1
675+ let newPositionRemainMargin = $t02724230280._2
676+ let newPositionOpenNotional = $t02724230280._3
677+ let newPositionLatestCPF = $t02724230280._4
678+ let baseAssetReserveAfter = $t02724230280._5
679+ let quoteAssetReserveAfter = $t02724230280._6
680+ let totalPositionSizeAfter = $t02724230280._7
681+ let cumulativeNotionalAfter = $t02724230280._8
682+ let openInterestNotionalAfter = $t02724230280._9
683+ let totalLongAfter = $t02724230280._10
684+ let totalShortAfter = $t02724230280._11
679685 (updatePosition(toString(i.caller), newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter))
680686 }
681687
705711 else {
706712 let feeAmount = muld(_rawAmount, fee())
707713 let _amount = (_rawAmount - feeAmount)
708- let $t03085430978 = getPosition(toString(i.caller))
709- let oldPositionSize = $t03085430978._1
710- let oldPositionMargin = $t03085430978._2
711- let oldPositionOpenNotional = $t03085430978._3
714+ let $t03131631440 = getPosition(toString(i.caller))
715+ let oldPositionSize = $t03131631440._1
716+ let oldPositionMargin = $t03131631440._2
717+ let oldPositionOpenNotional = $t03131631440._3
712718 let isNewPosition = (oldPositionSize == 0)
713719 let isSameDirection = if ((oldPositionSize > 0))
714720 then (_direction == DIR_LONG)
717723 then isSameDirection
718724 else false
719725 let isAdd = (_direction == DIR_LONG)
720- let $t03126733734 = if (if (isNewPosition)
726+ let $t03172934196 = if (if (isNewPosition)
721727 then true
722728 else expandExisting)
723729 then {
724730 let openNotional = muld(_amount, _leverage)
725- let $t03169131897 = swapInput(isAdd, openNotional)
726- let amountBaseAssetBought = $t03169131897._1
727- let quoteAssetReserveAfter = $t03169131897._2
728- let baseAssetReserveAfter = $t03169131897._3
729- let totalPositionSizeAfter = $t03169131897._4
730- let cumulativeNotionalAfter = $t03169131897._5
731+ let $t03215332359 = swapInput(isAdd, openNotional)
732+ let amountBaseAssetBought = $t03215332359._1
733+ let quoteAssetReserveAfter = $t03215332359._2
734+ let baseAssetReserveAfter = $t03215332359._3
735+ let totalPositionSizeAfter = $t03215332359._4
736+ let cumulativeNotionalAfter = $t03215332359._5
731737 if (if ((_minBaseAssetAmount != 0))
732738 then (_minBaseAssetAmount > abs(amountBaseAssetBought))
733739 else false)
736742 let newPositionSize = (oldPositionSize + amountBaseAssetBought)
737743 let positionLstUpdCPF = latestCumulativePremiumFraction(newPositionSize)
738744 let increaseMarginRequirement = divd(openNotional, _leverage)
739- let $t03235932595 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, positionLstUpdCPF, increaseMarginRequirement)
740- let remainMargin = $t03235932595._1
741- let x1 = $t03235932595._2
742- let x2 = $t03235932595._3
745+ let $t03282133057 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, positionLstUpdCPF, increaseMarginRequirement)
746+ let remainMargin = $t03282133057._1
747+ let x1 = $t03282133057._2
748+ let x2 = $t03282133057._3
743749 $Tuple11(newPositionSize, remainMargin, (oldPositionOpenNotional + openNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, (openInterestNotional() + openNotional), (totalLongPositionSize() + (if ((newPositionSize > 0))
744750 then abs(amountBaseAssetBought)
745751 else 0)), (totalShortPositionSize() + (if ((0 > newPositionSize))
749755 }
750756 else {
751757 let openNotional = muld(_amount, _leverage)
752- let $t03342733543 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
753- let oldPositionNotional = $t03342733543._1
754- let unrealizedPnl = $t03342733543._2
758+ let $t03388934005 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
759+ let oldPositionNotional = $t03388934005._1
760+ let unrealizedPnl = $t03388934005._2
755761 if ((oldPositionNotional > openNotional))
756762 then throw("Use decreasePosition to decrease position size")
757763 else throw("Close position first")
758764 }
759- let newPositionSize = $t03126733734._1
760- let newPositionRemainMargin = $t03126733734._2
761- let newPositionOpenNotional = $t03126733734._3
762- let newPositionLatestCPF = $t03126733734._4
763- let baseAssetReserveAfter = $t03126733734._5
764- let quoteAssetReserveAfter = $t03126733734._6
765- let totalPositionSizeAfter = $t03126733734._7
766- let cumulativeNotionalAfter = $t03126733734._8
767- let openInterestNotionalAfter = $t03126733734._9
768- let totalLongAfter = $t03126733734._10
769- let totalShortAfter = $t03126733734._11
765+ let newPositionSize = $t03172934196._1
766+ let newPositionRemainMargin = $t03172934196._2
767+ let newPositionOpenNotional = $t03172934196._3
768+ let newPositionLatestCPF = $t03172934196._4
769+ let baseAssetReserveAfter = $t03172934196._5
770+ let quoteAssetReserveAfter = $t03172934196._6
771+ let totalPositionSizeAfter = $t03172934196._7
772+ let cumulativeNotionalAfter = $t03172934196._8
773+ let openInterestNotionalAfter = $t03172934196._9
774+ let totalLongAfter = $t03172934196._10
775+ let totalShortAfter = $t03172934196._11
770776 let feeToStakers = (feeAmount / 2)
771777 let feeToInsurance = (feeAmount - feeToStakers)
772778 let stake = invoke(quoteAssetStaking(), "lockNeutrinoSP", [toString(stakingAddress()), ALL_FEES], [AttachedPayment(quoteAsset(), _amount)])
797803 else {
798804 let feeAmount = muld(_rawAmount, fee())
799805 let _amount = (_rawAmount - feeAmount)
800- let $t03501035162 = getPosition(toString(i.caller))
801- let oldPositionSize = $t03501035162._1
802- let oldPositionMargin = $t03501035162._2
803- let oldPositionOpenNotional = $t03501035162._3
804- let oldPositionLstUpdCPF = $t03501035162._4
806+ let $t03547235624 = getPosition(toString(i.caller))
807+ let oldPositionSize = $t03547235624._1
808+ let oldPositionMargin = $t03547235624._2
809+ let oldPositionOpenNotional = $t03547235624._3
810+ let oldPositionLstUpdCPF = $t03547235624._4
805811 let feeToStakers = (feeAmount / 2)
806812 let feeToInsurance = (feeAmount - feeToStakers)
807813 let stake = invoke(quoteAssetStaking(), "lockNeutrinoSP", [toString(stakingAddress()), ALL_FEES], [AttachedPayment(quoteAsset(), _amount)])
828834 else paused())
829835 then throw("Invalid removeMargin parameters")
830836 else {
831- let $t03608236234 = getPosition(toString(i.caller))
832- let oldPositionSize = $t03608236234._1
833- let oldPositionMargin = $t03608236234._2
834- let oldPositionOpenNotional = $t03608236234._3
835- let oldPositionLstUpdCPF = $t03608236234._4
837+ let $t03654436696 = getPosition(toString(i.caller))
838+ let oldPositionSize = $t03654436696._1
839+ let oldPositionMargin = $t03654436696._2
840+ let oldPositionOpenNotional = $t03654436696._3
841+ let oldPositionLstUpdCPF = $t03654436696._4
836842 let marginDelta = -(_amount)
837- let $t03627136450 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
838- let remainMargin = $t03627136450._1
839- let badDebt = $t03627136450._2
843+ let $t03673336912 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
844+ let remainMargin = $t03673336912._1
845+ let badDebt = $t03673336912._2
840846 if ((badDebt != 0))
841847 then throw("Invalid added margin amount")
842848 else {
857863 else paused())
858864 then throw("Invalid closePosition parameters")
859865 else {
860- let $t03721037594 = internalClosePosition(toString(i.caller))
861- let x1 = $t03721037594._1
862- let positionBadDebt = $t03721037594._2
863- let realizedPnl = $t03721037594._3
864- let marginToVault = $t03721037594._4
865- let quoteAssetReserveAfter = $t03721037594._5
866- let baseAssetReserveAfter = $t03721037594._6
867- let totalPositionSizeAfter = $t03721037594._7
868- let cumulativeNotionalAfter = $t03721037594._8
869- let openInterestNotionalAfter = $t03721037594._9
870- let x2 = $t03721037594._10
871- let totalLongAfter = $t03721037594._11
872- let totalShortAfter = $t03721037594._12
866+ let $t03767238056 = internalClosePosition(toString(i.caller))
867+ let x1 = $t03767238056._1
868+ let positionBadDebt = $t03767238056._2
869+ let realizedPnl = $t03767238056._3
870+ let marginToVault = $t03767238056._4
871+ let quoteAssetReserveAfter = $t03767238056._5
872+ let baseAssetReserveAfter = $t03767238056._6
873+ let totalPositionSizeAfter = $t03767238056._7
874+ let cumulativeNotionalAfter = $t03767238056._8
875+ let openInterestNotionalAfter = $t03767238056._9
876+ let x2 = $t03767238056._10
877+ let totalLongAfter = $t03767238056._11
878+ let totalShortAfter = $t03767238056._12
873879 if ((positionBadDebt > 0))
874880 then throw("Unable to close position with bad debt")
875881 else {
876882 let withdrawAmount = abs(marginToVault)
877883 let ammBalance = (cbalance() - withdrawAmount)
878- let $t03780337945 = if ((0 > ammBalance))
884+ let $t03826538407 = if ((0 > ammBalance))
879885 then $Tuple2(0, abs(ammBalance))
880886 else $Tuple2(ammBalance, 0)
881- let ammNewBalance = $t03780337945._1
882- let getFromInsurance = $t03780337945._2
887+ let ammNewBalance = $t03826538407._1
888+ let getFromInsurance = $t03826538407._2
883889 let x = if ((getFromInsurance > 0))
884890 then {
885891 let withdrawInsurance = invoke(insuranceAddress(), "withdraw", [getFromInsurance], nil)
915921 else paused())
916922 then throw("Unable to liquidate")
917923 else {
918- let $t03938439811 = internalClosePosition(_trader)
919- let x1 = $t03938439811._1
920- let badDebt = $t03938439811._2
921- let x2 = $t03938439811._3
922- let marginToVault = $t03938439811._4
923- let quoteAssetReserveAfter = $t03938439811._5
924- let baseAssetReserveAfter = $t03938439811._6
925- let totalPositionSizeAfter = $t03938439811._7
926- let cumulativeNotionalAfter = $t03938439811._8
927- let openInterestNotionalAfter = $t03938439811._9
928- let exchangedQuoteAssetAmount = $t03938439811._10
929- let totalLongAfter = $t03938439811._11
930- let totalShortAfter = $t03938439811._12
924+ let $t03984640273 = internalClosePosition(_trader)
925+ let x1 = $t03984640273._1
926+ let badDebt = $t03984640273._2
927+ let x2 = $t03984640273._3
928+ let marginToVault = $t03984640273._4
929+ let quoteAssetReserveAfter = $t03984640273._5
930+ let baseAssetReserveAfter = $t03984640273._6
931+ let totalPositionSizeAfter = $t03984640273._7
932+ let cumulativeNotionalAfter = $t03984640273._8
933+ let openInterestNotionalAfter = $t03984640273._9
934+ let exchangedQuoteAssetAmount = $t03984640273._10
935+ let totalLongAfter = $t03984640273._11
936+ let totalShortAfter = $t03984640273._12
931937 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
932938 let feeToLiquidator = (liquidationPenalty / 2)
933939 let feeToInsurance = (liquidationPenalty - feeToLiquidator)
934940 let ammBadDebt = (cbalance() - liquidationPenalty)
935- let $t04020940344 = if ((0 > ammBadDebt))
941+ let $t04067140806 = if ((0 > ammBadDebt))
936942 then $Tuple2(0, abs(ammBadDebt))
937943 else $Tuple2(ammBadDebt, 0)
938- let newAmmBalance = $t04020940344._1
939- let takeFromInsurance = $t04020940344._2
944+ let newAmmBalance = $t04067140806._1
945+ let takeFromInsurance = $t04067140806._2
940946 let x = if ((takeFromInsurance > 0))
941947 then {
942948 let withdrawInsurance = invoke(insuranceAddress(), "withdraw", [takeFromInsurance], nil)
976982 let underlyingPrice = getOracleTwapPrice()
977983 let spotTwapPrice = getTwapSpotPrice()
978984 let premium = (spotTwapPrice - underlyingPrice)
979- let $t04171443510 = if (if ((totalShortPositionSize() == 0))
985+ let $t04217643511 = if (if ((totalShortPositionSize() == 0))
980986 then true
981987 else (totalLongPositionSize() == 0))
982- then $Tuple4(0, 0, 0, 0)
988+ then $Tuple2(0, 0)
983989 else if ((0 > premium))
984990 then {
985991 let shortPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
986- let shortFundingRate = divd(shortPremiumFraction, underlyingPrice)
987992 let longPremiumFraction = divd(muld(shortPremiumFraction, totalShortPositionSize()), totalLongPositionSize())
988- let longFundingRate = divd(muld(longPremiumFraction, HUNDRED_PERCENT), underlyingPrice)
989- $Tuple4(shortPremiumFraction, longPremiumFraction, shortFundingRate, longFundingRate)
993+ $Tuple2(shortPremiumFraction, longPremiumFraction)
990994 }
991995 else {
992996 let longPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
993- let longFundingRate = divd(longPremiumFraction, underlyingPrice)
994997 let shortPremiumFraction = divd(muld(longPremiumFraction, totalLongPositionSize()), totalShortPositionSize())
995- let shortFundingRate = divd(muld(shortPremiumFraction, HUNDRED_PERCENT), underlyingPrice)
996- $Tuple4(shortPremiumFraction, longPremiumFraction, shortFundingRate, longFundingRate)
998+ $Tuple2(shortPremiumFraction, longPremiumFraction)
997999 }
998- let shortPremiumFraction = $t04171443510._1
999- let longPremiumFraction = $t04171443510._2
1000- let shortFundingRate = $t04171443510._3
1001- let longFundingRate = $t04171443510._4
1002- updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), longFundingRate, shortFundingRate)
1000+ let shortPremiumFraction = $t04217643511._1
1001+ let longPremiumFraction = $t04217643511._2
1002+ updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), divd(longPremiumFraction, underlyingPrice), divd(shortPremiumFraction, underlyingPrice))
10031003 }
10041004 }
10051005
10071007
10081008 @Callable(i)
10091009 func v_get (_trader) = {
1010- let $t04383143884 = internalClosePosition(_trader)
1011- let x1 = $t04383143884._1
1012- let x2 = $t04383143884._2
1013- let x3 = $t04383143884._3
1014- let x4 = $t04383143884._4
1010+ let $t04388643939 = internalClosePosition(_trader)
1011+ let x1 = $t04388643939._1
1012+ let x2 = $t04388643939._2
1013+ let x3 = $t04388643939._3
1014+ let x4 = $t04388643939._4
10151015 throw((((s(x2) + s(x3)) + s(x4)) + s(getMarginRatio(_trader))))
10161016 }
10171017
10191019
10201020 @Callable(i)
10211021 func view_calcRemainMarginWithFundingPayment (_trader) = {
1022- let $t04403144142 = getPosition(_trader)
1023- let positionSize = $t04403144142._1
1024- let positionMargin = $t04403144142._2
1025- let pon = $t04403144142._3
1026- let positionLstUpdCPF = $t04403144142._4
1027- let $t04414744248 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1028- let positionNotional = $t04414744248._1
1029- let unrealizedPnl = $t04414744248._2
1030- let $t04425344435 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1031- let remainMargin = $t04425344435._1
1032- let badDebt = $t04425344435._2
1033- let fundingPayment = $t04425344435._3
1022+ let $t04408644197 = getPosition(_trader)
1023+ let positionSize = $t04408644197._1
1024+ let positionMargin = $t04408644197._2
1025+ let pon = $t04408644197._3
1026+ let positionLstUpdCPF = $t04408644197._4
1027+ let $t04420244303 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1028+ let positionNotional = $t04420244303._1
1029+ let unrealizedPnl = $t04420244303._2
1030+ let $t04430844490 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1031+ let remainMargin = $t04430844490._1
1032+ let badDebt = $t04430844490._2
1033+ let fundingPayment = $t04430844490._3
10341034 throw(((s(remainMargin) + s(fundingPayment)) + s(getMarginRatio(_trader))))
10351035 }
10361036
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let k_ora_key = "k_ora_key"
5+
6+let k_ora_block_key = "k_ora_block_key"
57
68 let k_ora = "k_ora"
79
810 let k_balance = "k_balance"
911
1012 let k_positionSize = "k_positionSize"
1113
1214 let k_positionMargin = "k_positionMargin"
1315
1416 let k_positionOpenNotional = "k_positionOpenNotional"
1517
1618 let k_positionLastUpdatedCumulativePremiumFraction = "k_positionFraction"
1719
1820 let k_initialized = "k_initialized"
1921
2022 let k_paused = "k_paused"
2123
2224 let k_fee = "k_fee"
2325
2426 let k_fundingPeriod = "k_fundingPeriod"
2527
2628 let k_initMarginRatio = "k_initMarginRatio"
2729
2830 let k_maintenanceMarginRatio = "k_mmr"
2931
3032 let k_liquidationFeeRatio = "k_liquidationFeeRatio"
3133
3234 let k_spreadLimit = "k_spreadLimit"
3335
3436 let k_maxPriceImpact = "k_maxPriceImpact"
3537
3638 let k_lastDataStr = "k_lastDataStr"
3739
3840 let k_lastMinuteId = "k_lastMinuteId"
3941
4042 let k_twapDataLastCumulativePrice = "k_twapDataLastCumulativePrice"
4143
4244 let k_twapDataLastPrice = "k_twapDataLastPrice"
4345
4446 let k_latestLongCumulativePremiumFraction = "k_latestLongPremiumFraction"
4547
4648 let k_latestShortCumulativePremiumFraction = "k_latestShortPremiumFraction"
4749
4850 let k_nextFundingBlock = "k_nextFundingBlockMinTimestamp"
4951
5052 let k_longFundingRate = "k_longFundingRate"
5153
5254 let k_shortFundingRate = "k_shortFundingRate"
5355
5456 let k_quoteAssetReserve = "k_qtAstR"
5557
5658 let k_baseAssetReserve = "k_bsAstR"
5759
5860 let k_totalPositionSize = "k_totalPositionSize"
5961
6062 let k_totalLongPositionSize = "k_totalLongPositionSize"
6163
6264 let k_totalShortPositionSize = "k_totalShortPositionSize"
6365
6466 let k_cumulativeNotional = "k_cumulativeNotional"
6567
6668 let k_openInterestNotional = "k_openInterestNotional"
6769
6870 let k_coordinatorAddress = "k_coordinatorAddress"
6971
7072 let k_insurance_address = "k_insurance_address"
7173
7274 let k_admin_address = "k_admin_address"
7375
7476 let k_admin_public_key = "k_admin_public_key"
7577
7678 let k_quote_asset = "k_quote_asset"
7779
7880 let k_quote_staking = "k_quote_staking"
7981
8082 let k_staking_address = "k_staking_address"
8183
8284 func coordinator () = valueOrErrorMessage(addressFromString(getStringValue(this, k_coordinatorAddress)), "Coordinator not set")
8385
8486
8587 func adminAddress () = addressFromString(getStringValue(coordinator(), k_admin_address))
8688
8789
8890 func adminPublicKey () = fromBase58String(getStringValue(coordinator(), k_admin_public_key))
8991
9092
9193 func quoteAsset () = fromBase58String(getStringValue(coordinator(), k_quote_asset))
9294
9395
9496 func quoteAssetStaking () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_quote_staking)), "Quote asset staking not set")
9597
9698
9799 func stakingAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_staking_address)), "Insurance not set")
98100
99101
100102 func insuranceAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_insurance_address)), "Insurance not set")
101103
102104
103105 let DIR_LONG = 1
104106
105107 let DIR_SHORT = 2
106108
107109 let FUNDING_BLOCK_INTERVAL = 60
108110
109111 let TWAP_INTERVAL = 15
112+
113+let ORACLE_INTERVAL = 15
110114
111115 let SECONDS = 1000
112116
113117 let DECIMAL_UNIT = (1 * (((((10 * 10) * 10) * 10) * 10) * 10))
114118
115119 let HUNDRED_PERCENT = (100 * DECIMAL_UNIT)
116120
117121 let ONE_DAY = (86400 * DECIMAL_UNIT)
118122
119123 let ALL_FEES = 100
120124
121125 let PNL_OPTION_SPOT = 1
122126
123127 let PNL_OPTION_ORACLE = 2
124128
125129 func s (_x) = (toString(_x) + ",")
126130
127131
128132 func divd (_x,_y) = fraction(_x, DECIMAL_UNIT, _y, HALFEVEN)
129133
130134
131135 func muld (_x,_y) = fraction(_x, _y, DECIMAL_UNIT, HALFEVEN)
132136
133137
134138 func abs (_x) = if ((_x > 0))
135139 then _x
136140 else -(_x)
137141
138142
139143 func toCompositeKey (_key,_address) = ((_key + "_") + _address)
140144
141145
142146 func int (k) = valueOrErrorMessage(getInteger(this, k), ("no value for " + k))
143147
144148
145149 func cbalance () = int(k_balance)
146150
147151
148152 func fee () = int(k_fee)
149153
150154
151155 func initMarginRatio () = int(k_initMarginRatio)
152156
153157
154158 func qtAstR () = int(k_quoteAssetReserve)
155159
156160
157161 func bsAstR () = int(k_baseAssetReserve)
158162
159163
160164 func totalPositionSize () = int(k_totalPositionSize)
161165
162166
163167 func cumulativeNotional () = int(k_cumulativeNotional)
164168
165169
166170 func openInterestNotional () = int(k_openInterestNotional)
167171
168172
169173 func nextFundingBlockTimestamp () = int(k_nextFundingBlock)
170174
171175
172176 func fundingPeriodRaw () = int(k_fundingPeriod)
173177
174178
175179 func fundingPeriodDecimal () = (fundingPeriodRaw() * DECIMAL_UNIT)
176180
177181
178182 func fundingPeriodSeconds () = (fundingPeriodRaw() * SECONDS)
179183
180184
181185 func maintenanceMarginRatio () = int(k_maintenanceMarginRatio)
182186
183187
184188 func liquidationFeeRatio () = int(k_liquidationFeeRatio)
185189
186190
187191 func spreadLimit () = int(k_spreadLimit)
188192
189193
190194 func maxPriceImpact () = int(k_maxPriceImpact)
191195
192196
193197 func latestLongCumulativePremiumFraction () = int(k_latestLongCumulativePremiumFraction)
194198
195199
196200 func latestShortCumulativePremiumFraction () = int(k_latestShortCumulativePremiumFraction)
197201
198202
199203 func totalShortPositionSize () = int(k_totalShortPositionSize)
200204
201205
202206 func totalLongPositionSize () = int(k_totalLongPositionSize)
203207
204208
205209 func requireMoreMarginRatio (_marginRatio,_baseMarginRatio,_largerThanOrEqualTo) = {
206210 let remainingMarginRatio = (_marginRatio - _baseMarginRatio)
207211 if (if (_largerThanOrEqualTo)
208212 then (0 > remainingMarginRatio)
209213 else false)
210214 then throw("Invalid margin")
211215 else if (if (!(_largerThanOrEqualTo))
212216 then (remainingMarginRatio >= 0)
213217 else false)
214218 then throw("Invalid margin")
215219 else true
216220 }
217221
218222
219223 func latestCumulativePremiumFraction (_positionSize) = if ((_positionSize == 0))
220224 then throw("Should not be called with _positionSize == 0")
221225 else if ((_positionSize > 0))
222226 then latestLongCumulativePremiumFraction()
223227 else latestShortCumulativePremiumFraction()
224228
225229
226230 func getPosition (_trader) = {
227231 let positionSizeOpt = getInteger(this, toCompositeKey(k_positionSize, _trader))
228232 match positionSizeOpt {
229233 case positionSize: Int =>
230234 $Tuple4(positionSize, getIntegerValue(this, toCompositeKey(k_positionMargin, _trader)), getIntegerValue(this, toCompositeKey(k_positionOpenNotional, _trader)), getIntegerValue(this, toCompositeKey(k_positionLastUpdatedCumulativePremiumFraction, _trader)))
231235 case _ =>
232236 $Tuple4(0, 0, 0, 0)
233237 }
234238 }
235239
236240
237241 func requireOpenPosition (_trader) = if ((getPosition(_trader)._1 == 0))
238242 then throw("No open position")
239243 else true
240244
241245
242246 func initialized () = valueOrElse(getBoolean(this, k_initialized), false)
243247
244248
245249 func paused () = valueOrElse(getBoolean(this, k_paused), false)
246250
247251
248252 func updateReserve (_isAdd,_quoteAssetAmount,_baseAssetAmount) = if (_isAdd)
249253 then {
250254 let newBase = (bsAstR() - _baseAssetAmount)
251255 if ((0 >= newBase))
252256 then throw("Tx lead to base asset reserve <= 0, revert")
253257 else $Tuple4((qtAstR() + _quoteAssetAmount), newBase, (totalPositionSize() + _baseAssetAmount), (cumulativeNotional() + _quoteAssetAmount))
254258 }
255259 else {
256260 let newQuote = (qtAstR() - _quoteAssetAmount)
257261 if ((0 >= newQuote))
258262 then throw("Tx lead to base quote reserve <= 0, revert")
259263 else $Tuple4(newQuote, (bsAstR() + _baseAssetAmount), (totalPositionSize() - _baseAssetAmount), (cumulativeNotional() - _quoteAssetAmount))
260264 }
261265
262266
263267 func swapInput (_isAdd,_quoteAssetAmount) = {
264268 let _qtAstR = qtAstR()
265269 let _bsAstR = bsAstR()
266270 let priceBefore = divd(_qtAstR, _bsAstR)
267271 let amountBaseAssetBoughtWithoutPriceImpact = muld(_quoteAssetAmount, priceBefore)
268272 let k = muld(_qtAstR, _bsAstR)
269273 let quoteAssetReserveAfter = if (_isAdd)
270274 then (_qtAstR + _quoteAssetAmount)
271275 else (_qtAstR - _quoteAssetAmount)
272276 let baseAssetReserveAfter = divd(k, quoteAssetReserveAfter)
273277 let amountBaseAssetBoughtAbs = abs((baseAssetReserveAfter - _bsAstR))
274278 let amountBaseAssetBought = if (_isAdd)
275279 then amountBaseAssetBoughtAbs
276280 else -(amountBaseAssetBoughtAbs)
277281 let priceImpact = ((amountBaseAssetBoughtWithoutPriceImpact - amountBaseAssetBoughtAbs) / amountBaseAssetBoughtWithoutPriceImpact)
278282 let maxPriceImpactValue = maxPriceImpact()
279283 if ((priceImpact > maxPriceImpactValue))
280284 then throw(((("Price impact " + toString(priceImpact)) + " > max price impact ") + toString(maxPriceImpactValue)))
281285 else {
282- let $t01132811531 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
283- let quoteAssetReserveAfter1 = $t01132811531._1
284- let baseAssetReserveAfter1 = $t01132811531._2
285- let totalPositionSizeAfter1 = $t01132811531._3
286- let cumulativeNotionalAfter1 = $t01132811531._4
286+ let $t01143211635 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
287+ let quoteAssetReserveAfter1 = $t01143211635._1
288+ let baseAssetReserveAfter1 = $t01143211635._2
289+ let totalPositionSizeAfter1 = $t01143211635._3
290+ let cumulativeNotionalAfter1 = $t01143211635._4
287291 $Tuple5(amountBaseAssetBought, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1, cumulativeNotionalAfter1)
288292 }
289293 }
290294
291295
292296 func calcRemainMarginWithFundingPayment (_oldPositionSize,_oldPositionMargin,_oldPositionCumulativePremiumFraction,_marginDelta) = {
293297 let fundingPayment = if ((_oldPositionSize != 0))
294298 then {
295299 let _latestCumulativePremiumFraction = latestCumulativePremiumFraction(_oldPositionSize)
296300 muld((_latestCumulativePremiumFraction - _oldPositionCumulativePremiumFraction), _oldPositionSize)
297301 }
298302 else 0
299303 let signedMargin = ((_marginDelta - fundingPayment) + _oldPositionMargin)
300- let $t01227812405 = if ((0 > signedMargin))
304+ let $t01238212509 = if ((0 > signedMargin))
301305 then $Tuple2(0, abs(signedMargin))
302306 else $Tuple2(abs(signedMargin), 0)
303- let remainMargin = $t01227812405._1
304- let badDebt = $t01227812405._2
307+ let remainMargin = $t01238212509._1
308+ let badDebt = $t01238212509._2
305309 $Tuple3(remainMargin, badDebt, fundingPayment)
306310 }
307311
308312
309313 func swapOutput (_isAdd,_baseAssetAmount) = {
310314 let _quoteAssetReserve = qtAstR()
311315 let _baseAssetReserve = bsAstR()
312316 if ((_baseAssetAmount == 0))
313317 then throw("Invalid base asset amount")
314318 else {
315319 let k = muld(_quoteAssetReserve, _baseAssetReserve)
316320 let baseAssetPoolAmountAfter = if (_isAdd)
317321 then (_baseAssetReserve + _baseAssetAmount)
318322 else (_baseAssetReserve - _baseAssetAmount)
319323 let quoteAssetAfter = divd(k, baseAssetPoolAmountAfter)
320324 let quoteAssetSold = abs((quoteAssetAfter - _quoteAssetReserve))
321- let $t01324313436 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
322- let quoteAssetReserveAfter1 = $t01324313436._1
323- let baseAssetReserveAfter1 = $t01324313436._2
324- let totalPositionSizeAfter1 = $t01324313436._3
325- let cumulativeNotionalAfter1 = $t01324313436._4
325+ let $t01334713540 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
326+ let quoteAssetReserveAfter1 = $t01334713540._1
327+ let baseAssetReserveAfter1 = $t01334713540._2
328+ let totalPositionSizeAfter1 = $t01334713540._3
329+ let cumulativeNotionalAfter1 = $t01334713540._4
326330 $Tuple7(quoteAssetSold, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1, cumulativeNotionalAfter1, (totalLongPositionSize() - (if (_isAdd)
327331 then abs(_baseAssetAmount)
328332 else 0)), (totalShortPositionSize() - (if (!(_isAdd))
329333 then abs(_baseAssetAmount)
330334 else 0)))
331335 }
332336 }
333337
334338
335339 func getOracleTwapPrice () = {
336340 let oracle = valueOrErrorMessage(addressFromString(getStringValue(this, k_ora)), "")
337341 let priceKey = getStringValue(this, k_ora_key)
338- getIntegerValue(oracle, priceKey)
342+ let blockKey = getStringValue(this, k_ora_block_key)
343+ let lastValue = getIntegerValue(oracle, priceKey)
344+ lastValue
339345 }
340346
341347
342348 func getSpotPrice () = {
343349 let _quoteAssetReserve = qtAstR()
344350 let _baseAssetReserve = bsAstR()
345351 divd(_quoteAssetReserve, _baseAssetReserve)
346352 }
347353
348354
349355 func isOverFluctuationLimit () = {
350356 let oraclePrice = getOracleTwapPrice()
351357 let currentPrice = getSpotPrice()
352358 (divd(abs((oraclePrice - currentPrice)), oraclePrice) > spreadLimit())
353359 }
354360
355361
356362 func getPositionNotionalAndUnrealizedPnl (_trader,_option) = {
357- let $t01471014838 = getPosition(_trader)
358- let positionSize = $t01471014838._1
359- let positionMargin = $t01471014838._2
360- let positionOpenNotional = $t01471014838._3
361- let positionLstUpdCPF = $t01471014838._4
363+ let $t01517215300 = getPosition(_trader)
364+ let positionSize = $t01517215300._1
365+ let positionMargin = $t01517215300._2
366+ let positionOpenNotional = $t01517215300._3
367+ let positionLstUpdCPF = $t01517215300._4
362368 let positionSizeAbs = abs(positionSize)
363369 if ((positionSizeAbs == 0))
364370 then throw("Invalid position size")
365371 else {
366372 let isShort = (0 > positionSize)
367373 let positionNotional = if ((_option == PNL_OPTION_SPOT))
368374 then {
369- let $t01508515192 = swapOutput(!(isShort), positionSizeAbs)
370- let outPositionNotional = $t01508515192._1
371- let x1 = $t01508515192._2
372- let x2 = $t01508515192._3
373- let x3 = $t01508515192._4
375+ let $t01554715654 = swapOutput(!(isShort), positionSizeAbs)
376+ let outPositionNotional = $t01554715654._1
377+ let x1 = $t01554715654._2
378+ let x2 = $t01554715654._3
379+ let x3 = $t01554715654._4
374380 outPositionNotional
375381 }
376382 else (positionSizeAbs * getOracleTwapPrice())
377383 let unrealizedPnl = if (isShort)
378384 then (positionOpenNotional - positionNotional)
379385 else (positionNotional - positionOpenNotional)
380386 $Tuple2(positionNotional, unrealizedPnl)
381387 }
382388 }
383389
384390
385391 func getMarginRatioByOption (_trader,_option) = {
386- let $t01568715798 = getPosition(_trader)
387- let positionSize = $t01568715798._1
388- let positionMargin = $t01568715798._2
389- let pon = $t01568715798._3
390- let positionLstUpdCPF = $t01568715798._4
391- let $t01580415897 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
392- let positionNotional = $t01580415897._1
393- let unrealizedPnl = $t01580415897._2
394- let $t01590216068 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
395- let remainMargin = $t01590216068._1
396- let badDebt = $t01590216068._2
392+ let $t01614916260 = getPosition(_trader)
393+ let positionSize = $t01614916260._1
394+ let positionMargin = $t01614916260._2
395+ let pon = $t01614916260._3
396+ let positionLstUpdCPF = $t01614916260._4
397+ let $t01626616359 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
398+ let positionNotional = $t01626616359._1
399+ let unrealizedPnl = $t01626616359._2
400+ let $t01636416530 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
401+ let remainMargin = $t01636416530._1
402+ let badDebt = $t01636416530._2
397403 divd((remainMargin - badDebt), positionNotional)
398404 }
399405
400406
401407 func getMarginRatio (_trader) = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
402408
403409
404410 func internalClosePosition (_trader) = {
405- let $t01637416485 = getPosition(_trader)
406- let positionSize = $t01637416485._1
407- let positionMargin = $t01637416485._2
408- let pon = $t01637416485._3
409- let positionLstUpdCPF = $t01637416485._4
410- let $t01649116578 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
411- let x1 = $t01649116578._1
412- let unrealizedPnl = $t01649116578._2
413- let $t01658316751 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
414- let remainMargin = $t01658316751._1
415- let badDebt = $t01658316751._2
411+ let $t01683616947 = getPosition(_trader)
412+ let positionSize = $t01683616947._1
413+ let positionMargin = $t01683616947._2
414+ let pon = $t01683616947._3
415+ let positionLstUpdCPF = $t01683616947._4
416+ let $t01695317040 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
417+ let x1 = $t01695317040._1
418+ let unrealizedPnl = $t01695317040._2
419+ let $t01704517213 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
420+ let remainMargin = $t01704517213._1
421+ let badDebt = $t01704517213._2
416422 let exchangedPositionSize = -(positionSize)
417423 let realizedPnl = unrealizedPnl
418424 let marginToVault = -(remainMargin)
419- let $t01687817159 = swapOutput((positionSize > 0), abs(positionSize))
420- let exchangedQuoteAssetAmount = $t01687817159._1
421- let quoteAssetReserveAfter = $t01687817159._2
422- let baseAssetReserveAfter = $t01687817159._3
423- let totalPositionSizeAfter = $t01687817159._4
424- let cumulativeNotionalAfter = $t01687817159._5
425- let totalLongAfter = $t01687817159._6
426- let totalShortAfter = $t01687817159._7
425+ let $t01734017621 = swapOutput((positionSize > 0), abs(positionSize))
426+ let exchangedQuoteAssetAmount = $t01734017621._1
427+ let quoteAssetReserveAfter = $t01734017621._2
428+ let baseAssetReserveAfter = $t01734017621._3
429+ let totalPositionSizeAfter = $t01734017621._4
430+ let cumulativeNotionalAfter = $t01734017621._5
431+ let totalLongAfter = $t01734017621._6
432+ let totalShortAfter = $t01734017621._7
427433 let openInterestNotionalAfter = (openInterestNotional() - pon)
428434 $Tuple12(exchangedPositionSize, badDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, exchangedQuoteAssetAmount, totalLongAfter, totalShortAfter)
429435 }
430436
431437
432438 func getTwapSpotPrice () = {
433439 let minuteId = ((lastBlock.timestamp / 1000) / 60)
434440 let startMinuteId = (minuteId - TWAP_INTERVAL)
435441 let listStr = valueOrElse(getString(this, k_lastDataStr), "")
436442 let list = split(listStr, ",")
437443 func filterFn (accumulator,next) = if ((startMinuteId >= parseIntValue(next)))
438444 then (accumulator :+ parseIntValue(next))
439445 else accumulator
440446
441447 let listF = {
442448 let $l = list
443449 let $s = size($l)
444450 let $acc0 = nil
445451 func $f0_1 ($a,$i) = if (($i >= $s))
446452 then $a
447453 else filterFn($a, $l[$i])
448454
449455 func $f0_2 ($a,$i) = if (($i >= $s))
450456 then $a
451457 else throw("List size exceeds 20")
452458
453459 $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)
454460 }
455461 let maxIndex = if ((size(listF) > 0))
456462 then max(listF)
457463 else parseIntValue(list[0])
458464 let lastMinuteId = valueOrElse(getInteger(this, k_lastMinuteId), 0)
459465 let endLastCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(lastMinuteId))), 0)
460466 let endLastPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(lastMinuteId))), 0)
461467 let nowCumulativePrice = (endLastCumulativePrice + ((minuteId - lastMinuteId) * endLastPrice))
462468 let startLastCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(maxIndex))), 0)
463469 let startLastPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(maxIndex))), 0)
464470 let startCumulativePrice = (startLastCumulativePrice + ((startMinuteId - maxIndex) * startLastPrice))
465471 ((nowCumulativePrice - startCumulativePrice) / TWAP_INTERVAL)
466472 }
467473
468474
469475 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)]
470476
471477
472478 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)]
473479
474480
475481 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)]
476482
477483
478484 func appendTwap (price) = {
479485 let minuteId = ((lastBlock.timestamp / 1000) / 60)
480486 let previousMinuteId = valueOrElse(getInteger(this, k_lastMinuteId), 0)
481487 if ((previousMinuteId > minuteId))
482488 then throw("TWAP out-of-order")
483489 else {
484490 let lastMinuteId = if ((previousMinuteId == 0))
485491 then minuteId
486492 else previousMinuteId
487493 let listStr = valueOrElse(getString(this, k_lastDataStr), "")
488494 let oldList = split(listStr, ",")
489495 let list = if ((size(oldList) > TWAP_INTERVAL))
490496 then (removeByIndex(oldList, 0) :+ toString(minuteId))
491497 else (oldList :+ toString(minuteId))
492498 let prevCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(previousMinuteId))), 0)
493499 let prevPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(previousMinuteId))), price)
494500 let lastCumulativePrice = (prevCumulativePrice + ((minuteId - lastMinuteId) * prevPrice))
495501 func join (accumulator,val) = ((accumulator + val) + ",")
496502
497503 let newListStr = {
498504 let $l = list
499505 let $s = size($l)
500506 let $acc0 = ""
501507 func $f0_1 ($a,$i) = if (($i >= $s))
502508 then $a
503509 else join($a, $l[$i])
504510
505511 func $f0_2 ($a,$i) = if (($i >= $s))
506512 then $a
507513 else throw("List size exceeds 20")
508514
509515 $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)
510516 }
511517 let newListStrU = dropRight(newListStr, 1)
512518 let newListStrR = if ((take(newListStrU, 1) == ","))
513519 then drop(newListStrU, 1)
514520 else newListStrU
515521 [IntegerEntry(((k_twapDataLastCumulativePrice + "_") + toString(minuteId)), lastCumulativePrice), IntegerEntry(((k_twapDataLastPrice + "_") + toString(minuteId)), price), IntegerEntry(k_lastMinuteId, minuteId), StringEntry(k_lastDataStr, newListStrR)]
516522 }
517523 }
518524
519525
520526 func updateAmm (_qtAstR,_bsAstR,_totalPositionSizeAfter,_cumulativeNotionalAfter,_openInterestNotional,_totalLongPositionSize,_totalShortPositionSize) = if (((_totalLongPositionSize - _totalShortPositionSize) != _totalPositionSizeAfter))
521527 then throw(((((("Invalid AMM state data: " + toString(_totalLongPositionSize)) + " + ") + toString(_totalShortPositionSize)) + " != ") + toString(_totalPositionSizeAfter)))
522528 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)))
523529
524530
525531 func deletePosition (_address) = [DeleteEntry(toCompositeKey(k_positionSize, _address)), DeleteEntry(toCompositeKey(k_positionMargin, _address)), DeleteEntry(toCompositeKey(k_positionOpenNotional, _address)), DeleteEntry(toCompositeKey(k_positionLastUpdatedCumulativePremiumFraction, _address))]
526532
527533
528534 func withdraw (_address,_amount) = {
529535 let balance = assetBalance(this, quoteAsset())
530536 if ((_amount > balance))
531537 then throw(((("Unable to withdraw " + toString(_amount)) + " from contract balance ") + toString(balance)))
532538 else [ScriptTransfer(_address, _amount, quoteAsset())]
533539 }
534540
535541
536542 func updateBalance (i) = if ((0 > i))
537543 then throw("Balance")
538544 else [IntegerEntry(k_balance, i)]
539545
540546
541547 func transferFee (i) = [ScriptTransfer(stakingAddress(), i, quoteAsset())]
542548
543549
544550 @Callable(i)
545551 func pause () = if ((i.caller != adminAddress()))
546552 then throw("Invalid togglePause params")
547553 else [BooleanEntry(k_paused, true)]
548554
549555
550556
551557 @Callable(i)
552558 func unpause () = if ((i.caller != adminAddress()))
553559 then throw("Invalid togglePause params")
554560 else [BooleanEntry(k_paused, false)]
555561
556562
557563
558564 @Callable(i)
559565 func changeSettings (_initMarginRatio,_mmr,_liquidationFeeRatio,_fundingPeriod,_fee,_spreadLimit,_maxPriceImpact) = if ((i.caller != adminAddress()))
560566 then throw("Invalid changeSettings params")
561567 else updateSettings(_initMarginRatio, _mmr, _liquidationFeeRatio, _fundingPeriod, _fee, _spreadLimit, _maxPriceImpact)
562568
563569
564570
565571 @Callable(i)
566572 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))
567573 then true
568574 else (0 >= _bsAstR))
569575 then true
570576 else (0 >= _fundingPeriod))
571577 then true
572578 else (0 >= _initMarginRatio))
573579 then true
574580 else (0 >= _mmr))
575581 then true
576582 else (0 >= _liquidationFeeRatio))
577583 then true
578584 else (0 >= _fee))
579585 then true
580586 else (0 >= _spreadLimit))
581587 then true
582588 else (0 >= _maxPriceImpact))
583589 then true
584590 else initialized())
585591 then throw("Invalid initialize parameters")
586592 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)])
587593
588594
589595
590596 @Callable(i)
591597 func decreasePosition (_direction,_amount,_leverage,_minBaseAssetAmount) = if (if (if (if (if (if (if (if ((_direction != DIR_LONG))
592598 then (_direction != DIR_SHORT)
593599 else false)
594600 then true
595601 else (0 >= _amount))
596602 then true
597603 else if (((1 * DECIMAL_UNIT) > _leverage))
598604 then true
599605 else (_leverage > (3 * DECIMAL_UNIT)))
600606 then true
601607 else !(initialized()))
602608 then true
603609 else !(requireMoreMarginRatio(divd(DECIMAL_UNIT, _leverage), initMarginRatio(), true)))
604610 then true
605611 else !(requireOpenPosition(toString(i.caller))))
606612 then true
607613 else paused())
608614 then throw("Invalid decreasePosition parameters")
609615 else {
610- let $t02633926491 = getPosition(toString(i.caller))
611- let oldPositionSize = $t02633926491._1
612- let oldPositionMargin = $t02633926491._2
613- let oldPositionOpenNotional = $t02633926491._3
614- let oldPositionLstUpdCPF = $t02633926491._4
616+ let $t02680126953 = getPosition(toString(i.caller))
617+ let oldPositionSize = $t02680126953._1
618+ let oldPositionMargin = $t02680126953._2
619+ let oldPositionOpenNotional = $t02680126953._3
620+ let oldPositionLstUpdCPF = $t02680126953._4
615621 let isNewPosition = (oldPositionSize == 0)
616622 let isSameDirection = if ((oldPositionSize > 0))
617623 then (_direction == DIR_LONG)
618624 else (_direction == DIR_SHORT)
619625 let expandExisting = if (!(isNewPosition))
620626 then isSameDirection
621627 else false
622628 let isAdd = (_direction == DIR_LONG)
623- let $t02678029818 = if (if (isNewPosition)
629+ let $t02724230280 = if (if (isNewPosition)
624630 then true
625631 else expandExisting)
626632 then throw("Use increasePosition to open new or increase position")
627633 else {
628634 let openNotional = muld(_amount, _leverage)
629- let $t02728627402 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
630- let oldPositionNotional = $t02728627402._1
631- let unrealizedPnl = $t02728627402._2
635+ let $t02774827864 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
636+ let oldPositionNotional = $t02774827864._1
637+ let unrealizedPnl = $t02774827864._2
632638 if ((oldPositionNotional > openNotional))
633639 then {
634- let $t02746427694 = swapInput(isAdd, openNotional)
635- let exchangedPositionSize = $t02746427694._1
636- let quoteAssetReserveAfter = $t02746427694._2
637- let baseAssetReserveAfter = $t02746427694._3
638- let totalPositionSizeAfter = $t02746427694._4
639- let cumulativeNotionalAfter = $t02746427694._5
640+ let $t02792628156 = swapInput(isAdd, openNotional)
641+ let exchangedPositionSize = $t02792628156._1
642+ let quoteAssetReserveAfter = $t02792628156._2
643+ let baseAssetReserveAfter = $t02792628156._3
644+ let totalPositionSizeAfter = $t02792628156._4
645+ let cumulativeNotionalAfter = $t02792628156._5
640646 let exchangedPositionSizeAbs = abs(exchangedPositionSize)
641647 if (if ((_minBaseAssetAmount != 0))
642648 then (_minBaseAssetAmount > exchangedPositionSizeAbs)
643649 else false)
644650 then throw(((("Too little base asset exchanged, got " + toString(exchangedPositionSizeAbs)) + " expected ") + toString(_minBaseAssetAmount)))
645651 else {
646652 let realizedPnl = if ((oldPositionSize != 0))
647653 then divd(muld(unrealizedPnl, exchangedPositionSizeAbs), oldPositionSize)
648654 else 0
649- let $t02823428491 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
650- let remainMargin = $t02823428491._1
651- let badDebt = $t02823428491._2
652- let fundingPayment = $t02823428491._3
655+ let $t02869628953 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
656+ let remainMargin = $t02869628953._1
657+ let badDebt = $t02869628953._2
658+ let fundingPayment = $t02869628953._3
653659 let exchangedQuoteAssetAmount = openNotional
654660 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
655661 let remainOpenNotional = if ((oldPositionSize > 0))
656662 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
657663 else ((unrealizedPnlAfter + oldPositionNotional) - exchangedQuoteAssetAmount)
658664 let newPositionSize = (oldPositionSize + exchangedPositionSize)
659665 $Tuple11(newPositionSize, remainMargin, abs(remainOpenNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, (openInterestNotional() - openNotional), (totalLongPositionSize() - (if ((newPositionSize > 0))
660666 then abs(exchangedPositionSize)
661667 else 0)), (totalShortPositionSize() - (if ((0 > newPositionSize))
662668 then abs(exchangedPositionSize)
663669 else 0)))
664670 }
665671 }
666672 else throw("Close position first")
667673 }
668- let newPositionSize = $t02678029818._1
669- let newPositionRemainMargin = $t02678029818._2
670- let newPositionOpenNotional = $t02678029818._3
671- let newPositionLatestCPF = $t02678029818._4
672- let baseAssetReserveAfter = $t02678029818._5
673- let quoteAssetReserveAfter = $t02678029818._6
674- let totalPositionSizeAfter = $t02678029818._7
675- let cumulativeNotionalAfter = $t02678029818._8
676- let openInterestNotionalAfter = $t02678029818._9
677- let totalLongAfter = $t02678029818._10
678- let totalShortAfter = $t02678029818._11
674+ let newPositionSize = $t02724230280._1
675+ let newPositionRemainMargin = $t02724230280._2
676+ let newPositionOpenNotional = $t02724230280._3
677+ let newPositionLatestCPF = $t02724230280._4
678+ let baseAssetReserveAfter = $t02724230280._5
679+ let quoteAssetReserveAfter = $t02724230280._6
680+ let totalPositionSizeAfter = $t02724230280._7
681+ let cumulativeNotionalAfter = $t02724230280._8
682+ let openInterestNotionalAfter = $t02724230280._9
683+ let totalLongAfter = $t02724230280._10
684+ let totalShortAfter = $t02724230280._11
679685 (updatePosition(toString(i.caller), newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter))
680686 }
681687
682688
683689
684690 @Callable(i)
685691 func increasePosition (_direction,_leverage,_minBaseAssetAmount) = {
686692 let _rawAmount = i.payments[0].amount
687693 if (if (if (if (if (if (if (if ((_direction != DIR_LONG))
688694 then (_direction != DIR_SHORT)
689695 else false)
690696 then true
691697 else (0 >= _rawAmount))
692698 then true
693699 else if (((1 * DECIMAL_UNIT) > _leverage))
694700 then true
695701 else (_leverage > (3 * DECIMAL_UNIT)))
696702 then true
697703 else !(initialized()))
698704 then true
699705 else (i.payments[0].assetId != quoteAsset()))
700706 then true
701707 else !(requireMoreMarginRatio(divd(DECIMAL_UNIT, _leverage), initMarginRatio(), true)))
702708 then true
703709 else paused())
704710 then throw("Invalid increasePosition parameters")
705711 else {
706712 let feeAmount = muld(_rawAmount, fee())
707713 let _amount = (_rawAmount - feeAmount)
708- let $t03085430978 = getPosition(toString(i.caller))
709- let oldPositionSize = $t03085430978._1
710- let oldPositionMargin = $t03085430978._2
711- let oldPositionOpenNotional = $t03085430978._3
714+ let $t03131631440 = getPosition(toString(i.caller))
715+ let oldPositionSize = $t03131631440._1
716+ let oldPositionMargin = $t03131631440._2
717+ let oldPositionOpenNotional = $t03131631440._3
712718 let isNewPosition = (oldPositionSize == 0)
713719 let isSameDirection = if ((oldPositionSize > 0))
714720 then (_direction == DIR_LONG)
715721 else (_direction == DIR_SHORT)
716722 let expandExisting = if (!(isNewPosition))
717723 then isSameDirection
718724 else false
719725 let isAdd = (_direction == DIR_LONG)
720- let $t03126733734 = if (if (isNewPosition)
726+ let $t03172934196 = if (if (isNewPosition)
721727 then true
722728 else expandExisting)
723729 then {
724730 let openNotional = muld(_amount, _leverage)
725- let $t03169131897 = swapInput(isAdd, openNotional)
726- let amountBaseAssetBought = $t03169131897._1
727- let quoteAssetReserveAfter = $t03169131897._2
728- let baseAssetReserveAfter = $t03169131897._3
729- let totalPositionSizeAfter = $t03169131897._4
730- let cumulativeNotionalAfter = $t03169131897._5
731+ let $t03215332359 = swapInput(isAdd, openNotional)
732+ let amountBaseAssetBought = $t03215332359._1
733+ let quoteAssetReserveAfter = $t03215332359._2
734+ let baseAssetReserveAfter = $t03215332359._3
735+ let totalPositionSizeAfter = $t03215332359._4
736+ let cumulativeNotionalAfter = $t03215332359._5
731737 if (if ((_minBaseAssetAmount != 0))
732738 then (_minBaseAssetAmount > abs(amountBaseAssetBought))
733739 else false)
734740 then throw(((("Limit error: " + toString(abs(amountBaseAssetBought))) + " < ") + toString(_minBaseAssetAmount)))
735741 else {
736742 let newPositionSize = (oldPositionSize + amountBaseAssetBought)
737743 let positionLstUpdCPF = latestCumulativePremiumFraction(newPositionSize)
738744 let increaseMarginRequirement = divd(openNotional, _leverage)
739- let $t03235932595 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, positionLstUpdCPF, increaseMarginRequirement)
740- let remainMargin = $t03235932595._1
741- let x1 = $t03235932595._2
742- let x2 = $t03235932595._3
745+ let $t03282133057 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, positionLstUpdCPF, increaseMarginRequirement)
746+ let remainMargin = $t03282133057._1
747+ let x1 = $t03282133057._2
748+ let x2 = $t03282133057._3
743749 $Tuple11(newPositionSize, remainMargin, (oldPositionOpenNotional + openNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, (openInterestNotional() + openNotional), (totalLongPositionSize() + (if ((newPositionSize > 0))
744750 then abs(amountBaseAssetBought)
745751 else 0)), (totalShortPositionSize() + (if ((0 > newPositionSize))
746752 then abs(amountBaseAssetBought)
747753 else 0)))
748754 }
749755 }
750756 else {
751757 let openNotional = muld(_amount, _leverage)
752- let $t03342733543 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
753- let oldPositionNotional = $t03342733543._1
754- let unrealizedPnl = $t03342733543._2
758+ let $t03388934005 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
759+ let oldPositionNotional = $t03388934005._1
760+ let unrealizedPnl = $t03388934005._2
755761 if ((oldPositionNotional > openNotional))
756762 then throw("Use decreasePosition to decrease position size")
757763 else throw("Close position first")
758764 }
759- let newPositionSize = $t03126733734._1
760- let newPositionRemainMargin = $t03126733734._2
761- let newPositionOpenNotional = $t03126733734._3
762- let newPositionLatestCPF = $t03126733734._4
763- let baseAssetReserveAfter = $t03126733734._5
764- let quoteAssetReserveAfter = $t03126733734._6
765- let totalPositionSizeAfter = $t03126733734._7
766- let cumulativeNotionalAfter = $t03126733734._8
767- let openInterestNotionalAfter = $t03126733734._9
768- let totalLongAfter = $t03126733734._10
769- let totalShortAfter = $t03126733734._11
765+ let newPositionSize = $t03172934196._1
766+ let newPositionRemainMargin = $t03172934196._2
767+ let newPositionOpenNotional = $t03172934196._3
768+ let newPositionLatestCPF = $t03172934196._4
769+ let baseAssetReserveAfter = $t03172934196._5
770+ let quoteAssetReserveAfter = $t03172934196._6
771+ let totalPositionSizeAfter = $t03172934196._7
772+ let cumulativeNotionalAfter = $t03172934196._8
773+ let openInterestNotionalAfter = $t03172934196._9
774+ let totalLongAfter = $t03172934196._10
775+ let totalShortAfter = $t03172934196._11
770776 let feeToStakers = (feeAmount / 2)
771777 let feeToInsurance = (feeAmount - feeToStakers)
772778 let stake = invoke(quoteAssetStaking(), "lockNeutrinoSP", [toString(stakingAddress()), ALL_FEES], [AttachedPayment(quoteAsset(), _amount)])
773779 if ((stake == stake))
774780 then {
775781 let depositInsurance = invoke(insuranceAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), feeToInsurance)])
776782 if ((depositInsurance == depositInsurance))
777783 then (((updatePosition(toString(i.caller), newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter)) ++ transferFee(feeToStakers)) ++ updateBalance((cbalance() + _amount)))
778784 else throw("Strict value is not equal to itself.")
779785 }
780786 else throw("Strict value is not equal to itself.")
781787 }
782788 }
783789
784790
785791
786792 @Callable(i)
787793 func addMargin () = {
788794 let _rawAmount = i.payments[0].amount
789795 if (if (if (if ((i.payments[0].assetId != quoteAsset()))
790796 then true
791797 else !(requireOpenPosition(toString(i.caller))))
792798 then true
793799 else !(initialized()))
794800 then true
795801 else paused())
796802 then throw("Invalid addMargin parameters")
797803 else {
798804 let feeAmount = muld(_rawAmount, fee())
799805 let _amount = (_rawAmount - feeAmount)
800- let $t03501035162 = getPosition(toString(i.caller))
801- let oldPositionSize = $t03501035162._1
802- let oldPositionMargin = $t03501035162._2
803- let oldPositionOpenNotional = $t03501035162._3
804- let oldPositionLstUpdCPF = $t03501035162._4
806+ let $t03547235624 = getPosition(toString(i.caller))
807+ let oldPositionSize = $t03547235624._1
808+ let oldPositionMargin = $t03547235624._2
809+ let oldPositionOpenNotional = $t03547235624._3
810+ let oldPositionLstUpdCPF = $t03547235624._4
805811 let feeToStakers = (feeAmount / 2)
806812 let feeToInsurance = (feeAmount - feeToStakers)
807813 let stake = invoke(quoteAssetStaking(), "lockNeutrinoSP", [toString(stakingAddress()), ALL_FEES], [AttachedPayment(quoteAsset(), _amount)])
808814 if ((stake == stake))
809815 then {
810816 let depositInsurance = invoke(insuranceAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), feeToInsurance)])
811817 if ((depositInsurance == depositInsurance))
812818 then ((updatePosition(toString(i.caller), oldPositionSize, (oldPositionMargin + _amount), oldPositionOpenNotional, oldPositionLstUpdCPF) ++ transferFee(feeToStakers)) ++ updateBalance((cbalance() + _amount)))
813819 else throw("Strict value is not equal to itself.")
814820 }
815821 else throw("Strict value is not equal to itself.")
816822 }
817823 }
818824
819825
820826
821827 @Callable(i)
822828 func removeMargin (_amount) = if (if (if (if ((0 >= _amount))
823829 then true
824830 else !(requireOpenPosition(toString(i.caller))))
825831 then true
826832 else !(initialized()))
827833 then true
828834 else paused())
829835 then throw("Invalid removeMargin parameters")
830836 else {
831- let $t03608236234 = getPosition(toString(i.caller))
832- let oldPositionSize = $t03608236234._1
833- let oldPositionMargin = $t03608236234._2
834- let oldPositionOpenNotional = $t03608236234._3
835- let oldPositionLstUpdCPF = $t03608236234._4
837+ let $t03654436696 = getPosition(toString(i.caller))
838+ let oldPositionSize = $t03654436696._1
839+ let oldPositionMargin = $t03654436696._2
840+ let oldPositionOpenNotional = $t03654436696._3
841+ let oldPositionLstUpdCPF = $t03654436696._4
836842 let marginDelta = -(_amount)
837- let $t03627136450 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
838- let remainMargin = $t03627136450._1
839- let badDebt = $t03627136450._2
843+ let $t03673336912 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
844+ let remainMargin = $t03673336912._1
845+ let badDebt = $t03673336912._2
840846 if ((badDebt != 0))
841847 then throw("Invalid added margin amount")
842848 else {
843849 let unstake = invoke(quoteAssetStaking(), "unlockNeutrino", [_amount, toBase58String(quoteAsset())], nil)
844850 if ((unstake == unstake))
845851 then ((updatePosition(toString(i.caller), oldPositionSize, remainMargin, oldPositionOpenNotional, latestCumulativePremiumFraction(oldPositionSize)) ++ withdraw(i.caller, _amount)) ++ updateBalance((cbalance() - _amount)))
846852 else throw("Strict value is not equal to itself.")
847853 }
848854 }
849855
850856
851857
852858 @Callable(i)
853859 func closePosition () = if (if (if (!(requireOpenPosition(toString(i.caller))))
854860 then true
855861 else !(initialized()))
856862 then true
857863 else paused())
858864 then throw("Invalid closePosition parameters")
859865 else {
860- let $t03721037594 = internalClosePosition(toString(i.caller))
861- let x1 = $t03721037594._1
862- let positionBadDebt = $t03721037594._2
863- let realizedPnl = $t03721037594._3
864- let marginToVault = $t03721037594._4
865- let quoteAssetReserveAfter = $t03721037594._5
866- let baseAssetReserveAfter = $t03721037594._6
867- let totalPositionSizeAfter = $t03721037594._7
868- let cumulativeNotionalAfter = $t03721037594._8
869- let openInterestNotionalAfter = $t03721037594._9
870- let x2 = $t03721037594._10
871- let totalLongAfter = $t03721037594._11
872- let totalShortAfter = $t03721037594._12
866+ let $t03767238056 = internalClosePosition(toString(i.caller))
867+ let x1 = $t03767238056._1
868+ let positionBadDebt = $t03767238056._2
869+ let realizedPnl = $t03767238056._3
870+ let marginToVault = $t03767238056._4
871+ let quoteAssetReserveAfter = $t03767238056._5
872+ let baseAssetReserveAfter = $t03767238056._6
873+ let totalPositionSizeAfter = $t03767238056._7
874+ let cumulativeNotionalAfter = $t03767238056._8
875+ let openInterestNotionalAfter = $t03767238056._9
876+ let x2 = $t03767238056._10
877+ let totalLongAfter = $t03767238056._11
878+ let totalShortAfter = $t03767238056._12
873879 if ((positionBadDebt > 0))
874880 then throw("Unable to close position with bad debt")
875881 else {
876882 let withdrawAmount = abs(marginToVault)
877883 let ammBalance = (cbalance() - withdrawAmount)
878- let $t03780337945 = if ((0 > ammBalance))
884+ let $t03826538407 = if ((0 > ammBalance))
879885 then $Tuple2(0, abs(ammBalance))
880886 else $Tuple2(ammBalance, 0)
881- let ammNewBalance = $t03780337945._1
882- let getFromInsurance = $t03780337945._2
887+ let ammNewBalance = $t03826538407._1
888+ let getFromInsurance = $t03826538407._2
883889 let x = if ((getFromInsurance > 0))
884890 then {
885891 let withdrawInsurance = invoke(insuranceAddress(), "withdraw", [getFromInsurance], nil)
886892 if ((withdrawInsurance == withdrawInsurance))
887893 then nil
888894 else throw("Strict value is not equal to itself.")
889895 }
890896 else nil
891897 if ((x == x))
892898 then {
893899 let unstake = invoke(quoteAssetStaking(), "unlockNeutrino", [(withdrawAmount - getFromInsurance), toBase58String(quoteAsset())], nil)
894900 if ((unstake == unstake))
895901 then (((deletePosition(toString(i.caller)) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter)) ++ withdraw(i.caller, withdrawAmount)) ++ updateBalance(ammNewBalance))
896902 else throw("Strict value is not equal to itself.")
897903 }
898904 else throw("Strict value is not equal to itself.")
899905 }
900906 }
901907
902908
903909
904910 @Callable(i)
905911 func liquidate (_trader) = {
906912 let marginRatio = if (isOverFluctuationLimit())
907913 then getMarginRatioByOption(_trader, PNL_OPTION_ORACLE)
908914 else getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
909915 if (if (if (if (!(requireMoreMarginRatio(marginRatio, maintenanceMarginRatio(), false)))
910916 then true
911917 else !(requireOpenPosition(_trader)))
912918 then true
913919 else !(initialized()))
914920 then true
915921 else paused())
916922 then throw("Unable to liquidate")
917923 else {
918- let $t03938439811 = internalClosePosition(_trader)
919- let x1 = $t03938439811._1
920- let badDebt = $t03938439811._2
921- let x2 = $t03938439811._3
922- let marginToVault = $t03938439811._4
923- let quoteAssetReserveAfter = $t03938439811._5
924- let baseAssetReserveAfter = $t03938439811._6
925- let totalPositionSizeAfter = $t03938439811._7
926- let cumulativeNotionalAfter = $t03938439811._8
927- let openInterestNotionalAfter = $t03938439811._9
928- let exchangedQuoteAssetAmount = $t03938439811._10
929- let totalLongAfter = $t03938439811._11
930- let totalShortAfter = $t03938439811._12
924+ let $t03984640273 = internalClosePosition(_trader)
925+ let x1 = $t03984640273._1
926+ let badDebt = $t03984640273._2
927+ let x2 = $t03984640273._3
928+ let marginToVault = $t03984640273._4
929+ let quoteAssetReserveAfter = $t03984640273._5
930+ let baseAssetReserveAfter = $t03984640273._6
931+ let totalPositionSizeAfter = $t03984640273._7
932+ let cumulativeNotionalAfter = $t03984640273._8
933+ let openInterestNotionalAfter = $t03984640273._9
934+ let exchangedQuoteAssetAmount = $t03984640273._10
935+ let totalLongAfter = $t03984640273._11
936+ let totalShortAfter = $t03984640273._12
931937 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
932938 let feeToLiquidator = (liquidationPenalty / 2)
933939 let feeToInsurance = (liquidationPenalty - feeToLiquidator)
934940 let ammBadDebt = (cbalance() - liquidationPenalty)
935- let $t04020940344 = if ((0 > ammBadDebt))
941+ let $t04067140806 = if ((0 > ammBadDebt))
936942 then $Tuple2(0, abs(ammBadDebt))
937943 else $Tuple2(ammBadDebt, 0)
938- let newAmmBalance = $t04020940344._1
939- let takeFromInsurance = $t04020940344._2
944+ let newAmmBalance = $t04067140806._1
945+ let takeFromInsurance = $t04067140806._2
940946 let x = if ((takeFromInsurance > 0))
941947 then {
942948 let withdrawInsurance = invoke(insuranceAddress(), "withdraw", [takeFromInsurance], nil)
943949 if ((withdrawInsurance == withdrawInsurance))
944950 then nil
945951 else throw("Strict value is not equal to itself.")
946952 }
947953 else nil
948954 if ((x == x))
949955 then {
950956 let depositInsurance = invoke(insuranceAddress(), "deposit", nil, [AttachedPayment(quoteAsset(), feeToInsurance)])
951957 if ((depositInsurance == depositInsurance))
952958 then {
953959 let unstake = invoke(quoteAssetStaking(), "unlockNeutrino", [(feeToLiquidator - takeFromInsurance), toBase58String(quoteAsset())], nil)
954960 if ((unstake == unstake))
955961 then (((deletePosition(_trader) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter)) ++ withdraw(i.caller, feeToLiquidator)) ++ updateBalance(ammBadDebt))
956962 else throw("Strict value is not equal to itself.")
957963 }
958964 else throw("Strict value is not equal to itself.")
959965 }
960966 else throw("Strict value is not equal to itself.")
961967 }
962968 }
963969
964970
965971
966972 @Callable(i)
967973 func payFunding () = {
968974 let fundingBlockTimestamp = nextFundingBlockTimestamp()
969975 if (if (if ((fundingBlockTimestamp > lastBlock.timestamp))
970976 then true
971977 else !(initialized()))
972978 then true
973979 else paused())
974980 then throw(((("Invalid funding block timestamp: " + toString(lastBlock.timestamp)) + " < ") + toString(fundingBlockTimestamp)))
975981 else {
976982 let underlyingPrice = getOracleTwapPrice()
977983 let spotTwapPrice = getTwapSpotPrice()
978984 let premium = (spotTwapPrice - underlyingPrice)
979- let $t04171443510 = if (if ((totalShortPositionSize() == 0))
985+ let $t04217643511 = if (if ((totalShortPositionSize() == 0))
980986 then true
981987 else (totalLongPositionSize() == 0))
982- then $Tuple4(0, 0, 0, 0)
988+ then $Tuple2(0, 0)
983989 else if ((0 > premium))
984990 then {
985991 let shortPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
986- let shortFundingRate = divd(shortPremiumFraction, underlyingPrice)
987992 let longPremiumFraction = divd(muld(shortPremiumFraction, totalShortPositionSize()), totalLongPositionSize())
988- let longFundingRate = divd(muld(longPremiumFraction, HUNDRED_PERCENT), underlyingPrice)
989- $Tuple4(shortPremiumFraction, longPremiumFraction, shortFundingRate, longFundingRate)
993+ $Tuple2(shortPremiumFraction, longPremiumFraction)
990994 }
991995 else {
992996 let longPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
993- let longFundingRate = divd(longPremiumFraction, underlyingPrice)
994997 let shortPremiumFraction = divd(muld(longPremiumFraction, totalLongPositionSize()), totalShortPositionSize())
995- let shortFundingRate = divd(muld(shortPremiumFraction, HUNDRED_PERCENT), underlyingPrice)
996- $Tuple4(shortPremiumFraction, longPremiumFraction, shortFundingRate, longFundingRate)
998+ $Tuple2(shortPremiumFraction, longPremiumFraction)
997999 }
998- let shortPremiumFraction = $t04171443510._1
999- let longPremiumFraction = $t04171443510._2
1000- let shortFundingRate = $t04171443510._3
1001- let longFundingRate = $t04171443510._4
1002- updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), longFundingRate, shortFundingRate)
1000+ let shortPremiumFraction = $t04217643511._1
1001+ let longPremiumFraction = $t04217643511._2
1002+ updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), divd(longPremiumFraction, underlyingPrice), divd(shortPremiumFraction, underlyingPrice))
10031003 }
10041004 }
10051005
10061006
10071007
10081008 @Callable(i)
10091009 func v_get (_trader) = {
1010- let $t04383143884 = internalClosePosition(_trader)
1011- let x1 = $t04383143884._1
1012- let x2 = $t04383143884._2
1013- let x3 = $t04383143884._3
1014- let x4 = $t04383143884._4
1010+ let $t04388643939 = internalClosePosition(_trader)
1011+ let x1 = $t04388643939._1
1012+ let x2 = $t04388643939._2
1013+ let x3 = $t04388643939._3
1014+ let x4 = $t04388643939._4
10151015 throw((((s(x2) + s(x3)) + s(x4)) + s(getMarginRatio(_trader))))
10161016 }
10171017
10181018
10191019
10201020 @Callable(i)
10211021 func view_calcRemainMarginWithFundingPayment (_trader) = {
1022- let $t04403144142 = getPosition(_trader)
1023- let positionSize = $t04403144142._1
1024- let positionMargin = $t04403144142._2
1025- let pon = $t04403144142._3
1026- let positionLstUpdCPF = $t04403144142._4
1027- let $t04414744248 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1028- let positionNotional = $t04414744248._1
1029- let unrealizedPnl = $t04414744248._2
1030- let $t04425344435 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1031- let remainMargin = $t04425344435._1
1032- let badDebt = $t04425344435._2
1033- let fundingPayment = $t04425344435._3
1022+ let $t04408644197 = getPosition(_trader)
1023+ let positionSize = $t04408644197._1
1024+ let positionMargin = $t04408644197._2
1025+ let pon = $t04408644197._3
1026+ let positionLstUpdCPF = $t04408644197._4
1027+ let $t04420244303 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1028+ let positionNotional = $t04420244303._1
1029+ let unrealizedPnl = $t04420244303._2
1030+ let $t04430844490 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1031+ let remainMargin = $t04430844490._1
1032+ let badDebt = $t04430844490._2
1033+ let fundingPayment = $t04430844490._3
10341034 throw(((s(remainMargin) + s(fundingPayment)) + s(getMarginRatio(_trader))))
10351035 }
10361036
10371037
10381038 @Verifier(tx)
10391039 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], adminPublicKey())
10401040

github/deemru/w8io/169f3d6 
178.78 ms