tx · AoJjkLxMyJcLaeVNZCB6FiLfMTSWFtDbgL1v1HMmubdb

3MtZLxTgC6rE5h4iq9mc51D1dEwXHZroWWj:  -0.07500000 Waves

2023.01.07 19:15 [2394768] smart account 3MtZLxTgC6rE5h4iq9mc51D1dEwXHZroWWj > SELF 0.00000000 Waves

{ "type": 13, "id": "AoJjkLxMyJcLaeVNZCB6FiLfMTSWFtDbgL1v1HMmubdb", "fee": 7500000, "feeAssetId": null, "timestamp": 1673108141465, "version": 2, "chainId": 84, "sender": "3MtZLxTgC6rE5h4iq9mc51D1dEwXHZroWWj", "senderPublicKey": "9LXeFs1PpNBy1oVD8feMHJTasBVFs5sYfTiLmjMrgcwX", "proofs": [ "dySy9nrM5R36caBmM39pisBZLX5EvDRXAkyUFSXTVLrga4pwwpMb8cp5WamuGtrVUpCcHN7P2RUhGPW48PUKr1h" ], "script": "base64:BgJ6CAISABIAEgASABIDCgEBEgMKAQESDgoMAQEBAQEBAQEBAQEBEhQKEgEBAQEBAQEICAgIAQEBAQEBARIFCgMBAQESBgoEAQEBCBIAEgMKAQESBAoCAQESAwoBCBIAEgASAwoBCBIDCgEBEgASABIDCgEIEgASBAoCCAjDAQAJa19vcmFfa2V5AglrX29yYV9rZXkAD2tfb3JhX2Jsb2NrX2tleQIPa19vcmFfYmxvY2tfa2V5AA5rX29yYV9vcGVuX2tleQIOa19vcmFfb3Blbl9rZXkABWtfb3JhAgVrX29yYQAJa19iYWxhbmNlAglrX2JhbGFuY2UACmtfc2VxdWVuY2UCCmtfc2VxdWVuY2UADmtfcG9zaXRpb25TaXplAg5rX3Bvc2l0aW9uU2l6ZQAQa19wb3NpdGlvbk1hcmdpbgIQa19wb3NpdGlvbk1hcmdpbgAWa19wb3NpdGlvbk9wZW5Ob3Rpb25hbAIWa19wb3NpdGlvbk9wZW5Ob3Rpb25hbAAua19wb3NpdGlvbkxhc3RVcGRhdGVkQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgISa19wb3NpdGlvbkZyYWN0aW9uABJrX3Bvc2l0aW9uU2VxdWVuY2UCEmtfcG9zaXRpb25TZXF1ZW5jZQAPa19wb3NpdGlvbkFzc2V0Ag9rX3Bvc2l0aW9uQXNzZXQADWtfaW5pdGlhbGl6ZWQCDWtfaW5pdGlhbGl6ZWQACGtfcGF1c2VkAghrX3BhdXNlZAALa19jbG9zZU9ubHkCC2tfY2xvc2VPbmx5AAVrX2ZlZQIFa19mZWUAD2tfZnVuZGluZ1BlcmlvZAIPa19mdW5kaW5nUGVyaW9kABFrX2luaXRNYXJnaW5SYXRpbwIRa19pbml0TWFyZ2luUmF0aW8AGGtfbWFpbnRlbmFuY2VNYXJnaW5SYXRpbwIFa19tbXIAFWtfbGlxdWlkYXRpb25GZWVSYXRpbwIVa19saXF1aWRhdGlvbkZlZVJhdGlvABlrX3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAhZrX3BhcnRMaXF1aWRhdGlvblJhdGlvAA1rX3NwcmVhZExpbWl0Ag1rX3NwcmVhZExpbWl0ABBrX21heFByaWNlSW1wYWN0AhBrX21heFByaWNlSW1wYWN0ABBrX21heFByaWNlU3ByZWFkAhBrX21heFByaWNlU3ByZWFkABFrX21heE9wZW5Ob3Rpb25hbAIRa19tYXhPcGVuTm90aW9uYWwAFWtfZmVlVG9TdGFrZXJzUGVyY2VudAIVa19mZWVUb1N0YWtlcnNQZXJjZW50ABBrX21heE9yYWNsZURlbGF5AhBrX21heE9yYWNsZURlbGF5AA1rX2xhc3REYXRhU3RyAg1rX2xhc3REYXRhU3RyAA5rX2xhc3RNaW51dGVJZAIOa19sYXN0TWludXRlSWQAHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlAh1rX3R3YXBEYXRhTGFzdEN1bXVsYXRpdmVQcmljZQATa190d2FwRGF0YUxhc3RQcmljZQITa190d2FwRGF0YUxhc3RQcmljZQAaa190d2FwRGF0YVByZXZpb3VzTWludXRlSWQCGmtfdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkACVrX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAhtrX2xhdGVzdExvbmdQcmVtaXVtRnJhY3Rpb24AJmtfbGF0ZXN0U2hvcnRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAhxrX2xhdGVzdFNob3J0UHJlbWl1bUZyYWN0aW9uABJrX25leHRGdW5kaW5nQmxvY2sCHmtfbmV4dEZ1bmRpbmdCbG9ja01pblRpbWVzdGFtcAARa19sb25nRnVuZGluZ1JhdGUCEWtfbG9uZ0Z1bmRpbmdSYXRlABJrX3Nob3J0RnVuZGluZ1JhdGUCEmtfc2hvcnRGdW5kaW5nUmF0ZQATa19xdW90ZUFzc2V0UmVzZXJ2ZQIIa19xdEFzdFIAEmtfYmFzZUFzc2V0UmVzZXJ2ZQIIa19ic0FzdFIAEmtfcXVvdGVBc3NldFdlaWdodAIIa19xdEFzdFcAEWtfYmFzZUFzc2V0V2VpZ2h0AghrX2JzQXN0VwATa190b3RhbFBvc2l0aW9uU2l6ZQITa190b3RhbFBvc2l0aW9uU2l6ZQAXa190b3RhbExvbmdQb3NpdGlvblNpemUCF2tfdG90YWxMb25nUG9zaXRpb25TaXplABhrX3RvdGFsU2hvcnRQb3NpdGlvblNpemUCGGtfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAWa19vcGVuSW50ZXJlc3ROb3Rpb25hbAIWa19vcGVuSW50ZXJlc3ROb3Rpb25hbAATa19vcGVuSW50ZXJlc3RTaG9ydAITa19vcGVuSW50ZXJlc3RTaG9ydAASa19vcGVuSW50ZXJlc3RMb25nAhJrX29wZW5JbnRlcmVzdExvbmcAFGtfY29vcmRpbmF0b3JBZGRyZXNzAhRrX2Nvb3JkaW5hdG9yQWRkcmVzcwAPa192YXVsdF9hZGRyZXNzAg9rX3ZhdWx0X2FkZHJlc3MAD2tfYWRtaW5fYWRkcmVzcwIPa19hZG1pbl9hZGRyZXNzABJrX2FkbWluX3B1YmxpY19rZXkCEmtfYWRtaW5fcHVibGljX2tleQANa19xdW90ZV9hc3NldAINa19xdW90ZV9hc3NldAAPa19xdW90ZV9zdGFraW5nAg9rX3F1b3RlX3N0YWtpbmcAEWtfc3Rha2luZ19hZGRyZXNzAhFrX3N0YWtpbmdfYWRkcmVzcwAPa19taW5lcl9hZGRyZXNzAg9rX21pbmVyX2FkZHJlc3MAEGtfb3JkZXJzX2FkZHJlc3MCEGtfb3JkZXJzX2FkZHJlc3MAEmtfcmVmZXJyYWxfYWRkcmVzcwISa19yZWZlcnJhbF9hZGRyZXNzABRrX2NvbGxhdGVyYWxfYWRkcmVzcwIUa19jb2xsYXRlcmFsX2FkZHJlc3MAEmtfZXhjaGFuZ2VfYWRkcmVzcwISa19leGNoYW5nZV9hZGRyZXNzABVrX25mdF9tYW5hZ2VyX2FkZHJlc3MCFWtfbmZ0X21hbmFnZXJfYWRkcmVzcwAga190cmFkZXJfbWFya2V0X2Fzc2V0X2NvbGxhdGVyYWwCIGtfdHJhZGVyX21hcmtldF9hc3NldF9jb2xsYXRlcmFsAQ50b0NvbXBvc2l0ZUtleQIEX2tleQhfYWRkcmVzcwkArAICCQCsAgIFBF9rZXkCAV8FCF9hZGRyZXNzAQtjb29yZGluYXRvcgAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzBRRrX2Nvb3JkaW5hdG9yQWRkcmVzcwITQ29vcmRpbmF0b3Igbm90IHNldAEMYWRtaW5BZGRyZXNzAAkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABQ9rX2FkbWluX2FkZHJlc3MBDmFkbWluUHVibGljS2V5AAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABRJrX2FkbWluX3B1YmxpY19rZXkBCnF1b3RlQXNzZXQACQDZBAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFDWtfcXVvdGVfYXNzZXQBEXF1b3RlQXNzZXRTdGFraW5nAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFD2tfcXVvdGVfc3Rha2luZwIbUXVvdGUgYXNzZXQgc3Rha2luZyBub3Qgc2V0AQ5zdGFraW5nQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABRFrX3N0YWtpbmdfYWRkcmVzcwIPU3Rha2luZyBub3Qgc2V0AQx2YXVsdEFkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUPa192YXVsdF9hZGRyZXNzAg1WYXVsdCBub3Qgc2V0AQxtaW5lckFkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUPa19taW5lcl9hZGRyZXNzAg1NaW5lciBub3Qgc2V0AQ1vcmRlcnNBZGRyZXNzAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFEGtfb3JkZXJzX2FkZHJlc3MCDk9yZGVycyBub3Qgc2V0AQ9yZWZlcnJhbEFkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUSa19yZWZlcnJhbF9hZGRyZXNzAhBSZWZlcnJhbCBub3Qgc2V0ARFuZnRNYW5hZ2VyQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABRVrX25mdF9tYW5hZ2VyX2FkZHJlc3MCE05GVCBNYW5hZ2VyIG5vdCBzZXQBEWNvbGxhdGVyYWxBZGRyZXNzAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFFGtfY29sbGF0ZXJhbF9hZGRyZXNzAhpDb2xsYXRlcmFsIE1hbmFnZXIgbm90IHNldAELc3dhcEFkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIJAQtjb29yZGluYXRvcgAFEmtfZXhjaGFuZ2VfYWRkcmVzcwIPTm8gc3dhcCBhZGRyZXNzAhRJbnZhbGlkIHN3YXAgYWRkcmVzcwARa193aGl0ZWxpc3RfYXNzZXQCEWtfd2hpdGVsaXN0X2Fzc2V0ARBpc1doaXRlbGlzdEFzc2V0AQhfYXNzZXRJZAkBC3ZhbHVlT3JFbHNlAgkAmwgCCQERY29sbGF0ZXJhbEFkZHJlc3MACQEOdG9Db21wb3NpdGVLZXkCBRFrX3doaXRlbGlzdF9hc3NldAUIX2Fzc2V0SWQHAA1rX3Rva2VuX3BhcmFtAg1rX3Rva2VuX3BhcmFtAAxrX3Rva2VuX3R5cGUCDGtfdG9rZW5fdHlwZQAYRkVFX1JFRFVDVElPTl9UT0tFTl9UWVBFAg1mZWVfcmVkdWN0aW9uAAhESVJfTE9ORwABAAlESVJfU0hPUlQAAgANVFdBUF9JTlRFUlZBTAAPAA9PUkFDTEVfSU5URVJWQUwADwAHU0VDT05EUwDoBwAPREVDSU1BTF9OVU1CRVJTAAYADERFQ0lNQUxfVU5JVAkAaAIAAQkAaAIJAGgCCQBoAgkAaAIJAGgCAAoACgAKAAoACgAKAAdPTkVfREFZCQBoAgCAowUFDERFQ0lNQUxfVU5JVAAIQUxMX0ZFRVMAZAAPUE5MX09QVElPTl9TUE9UAAEAEVBOTF9PUFRJT05fT1JBQ0xFAAIBAXMBAl94CQCsAgIJAKQDAQUCX3gCASwBBGRpdmQCAl94Al95CQBuBAUCX3gFDERFQ0lNQUxfVU5JVAUCX3kFCEhBTEZFVkVOAQRtdWxkAgJfeAJfeQkAbgQFAl94BQJfeQUMREVDSU1BTF9VTklUBQhIQUxGRVZFTgEFc3FydGQBAl94CQEEc3FydAQFAl94BQ9ERUNJTUFMX05VTUJFUlMFD0RFQ0lNQUxfTlVNQkVSUwUISEFMRkVWRU4BBHBvd2QCAl94Al95CQBsBgUCX3gFD0RFQ0lNQUxfTlVNQkVSUwUCX3kFD0RFQ0lNQUxfTlVNQkVSUwUPREVDSU1BTF9OVU1CRVJTBQhIQUxGRVZFTgEFYmRpdmQCAl94Al95CQC9AgQFAl94CQC2AgEFDERFQ0lNQUxfVU5JVAUCX3kFCEhBTEZFVkVOAQVibXVsZAICX3gCX3kJAL0CBAUCX3gFAl95CQC2AgEFDERFQ0lNQUxfVU5JVAUISEFMRkVWRU4BBmJzcXJ0ZAECX3gJAQpzcXJ0QmlnSW50BAUCX3gFD0RFQ0lNQUxfTlVNQkVSUwUPREVDSU1BTF9OVU1CRVJTBQhIQUxGRVZFTgEFYnBvd2QCAl94Al95CQB2BgUCX3gFD0RFQ0lNQUxfTlVNQkVSUwUCX3kFD0RFQ0lNQUxfTlVNQkVSUwUPREVDSU1BTF9OVU1CRVJTBQhIQUxGRVZFTgEDYWJzAQJfeAMJAGYCBQJfeAAABQJfeAkBAS0BBQJfeAEEdm1heAICX3gCX3kDCQBnAgUCX3gFAl95BQJfeAUCX3kBCWxpc3RUb1N0cgEFX2xpc3QKAQVfam9pbgILYWNjdW11bGF0b3IDdmFsCQCsAgIJAKwCAgULYWNjdW11bGF0b3IFA3ZhbAIBLAQKbmV3TGlzdFN0cgoAAiRsBQVfbGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzACAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEFX2pvaW4CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAQLbmV3TGlzdFN0clUJALMCAgUKbmV3TGlzdFN0cgABBAtuZXdMaXN0U3RyUgMJAAACCQCvAgIFC25ld0xpc3RTdHJVAAECASwJALACAgULbmV3TGlzdFN0clUAAQULbmV3TGlzdFN0clUFC25ld0xpc3RTdHJSAQlzdHJUb0xpc3QBBF9zdHIJALUJAgUEX3N0cgIBLAELcHVzaFRvUXVldWUDBV9saXN0CF9tYXhTaXplBl92YWx1ZQMJAGYCCQCQAwEFBV9saXN0BQhfbWF4U2l6ZQkAzQgCCQDRCAIFBV9saXN0AAAFBl92YWx1ZQkAzQgCBQVfbGlzdAUGX3ZhbHVlAQNpbnQBAWsJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzBQFrCQCsAgICDW5vIHZhbHVlIGZvciAFAWsBBWludE9yAgFrA2RlZgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFrBQNkZWYBBHN0ckECCF9hZGRyZXNzBF9rZXkEA3ZhbAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFCF9hZGRyZXNzBQRfa2V5CQCsAgICEU5vIHZhbHVlIGZvciBrZXkgBQRfa2V5BQN2YWwBBGludEECCF9hZGRyZXNzBF9rZXkEA3ZhbAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFCF9hZGRyZXNzBQRfa2V5CQCsAgICEU5vIHZhbHVlIGZvciBrZXkgBQRfa2V5BQN2YWwBCGNiYWxhbmNlAAkBA2ludAEFCWtfYmFsYW5jZQEDZmVlAAkBA2ludAEFBWtfZmVlAQ9pbml0TWFyZ2luUmF0aW8ACQEDaW50AQURa19pbml0TWFyZ2luUmF0aW8BBnF0QXN0UgAJAQNpbnQBBRNrX3F1b3RlQXNzZXRSZXNlcnZlAQZic0FzdFIACQEDaW50AQUSa19iYXNlQXNzZXRSZXNlcnZlAQZxdEFzdFcACQEFaW50T3ICBRJrX3F1b3RlQXNzZXRXZWlnaHQFDERFQ0lNQUxfVU5JVAEGYnNBc3RXAAkBBWludE9yAgURa19iYXNlQXNzZXRXZWlnaHQFDERFQ0lNQUxfVU5JVAERdG90YWxQb3NpdGlvblNpemUACQEDaW50AQUTa190b3RhbFBvc2l0aW9uU2l6ZQEUb3BlbkludGVyZXN0Tm90aW9uYWwACQEDaW50AQUWa19vcGVuSW50ZXJlc3ROb3Rpb25hbAERb3BlbkludGVyZXN0U2hvcnQACQEDaW50AQUTa19vcGVuSW50ZXJlc3RTaG9ydAEQb3BlbkludGVyZXN0TG9uZwAJAQNpbnQBBRJrX29wZW5JbnRlcmVzdExvbmcBGW5leHRGdW5kaW5nQmxvY2tUaW1lc3RhbXAACQEDaW50AQUSa19uZXh0RnVuZGluZ0Jsb2NrARBmdW5kaW5nUGVyaW9kUmF3AAkBA2ludAEFD2tfZnVuZGluZ1BlcmlvZAEUZnVuZGluZ1BlcmlvZERlY2ltYWwACQBoAgkBEGZ1bmRpbmdQZXJpb2RSYXcABQxERUNJTUFMX1VOSVQBFGZ1bmRpbmdQZXJpb2RTZWNvbmRzAAkAaAIJARBmdW5kaW5nUGVyaW9kUmF3AAUHU0VDT05EUwEWbWFpbnRlbmFuY2VNYXJnaW5SYXRpbwAJAQNpbnQBBRhrX21haW50ZW5hbmNlTWFyZ2luUmF0aW8BE2xpcXVpZGF0aW9uRmVlUmF0aW8ACQEDaW50AQUVa19saXF1aWRhdGlvbkZlZVJhdGlvARdwYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwAJAQNpbnQBBRlrX3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAQtzcHJlYWRMaW1pdAAJAQNpbnQBBQ1rX3NwcmVhZExpbWl0AQ5tYXhQcmljZUltcGFjdAAJAQNpbnQBBRBrX21heFByaWNlSW1wYWN0AQ5tYXhQcmljZVNwcmVhZAAJAQNpbnQBBRBrX21heFByaWNlU3ByZWFkAQ9tYXhPcGVuTm90aW9uYWwACQEDaW50AQURa19tYXhPcGVuTm90aW9uYWwBI2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAkBA2ludAEFJWtfbGF0ZXN0TG9uZ0N1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24BJGxhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAJAQNpbnQBBSZrX2xhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgEWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAJAQNpbnQBBRhrX3RvdGFsU2hvcnRQb3NpdGlvblNpemUBFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAJAQNpbnQBBRdrX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQEMbGFzdFNlcXVlbmNlAAkBBWludE9yAgUKa19zZXF1ZW5jZQAAARNmZWVUb1N0YWtlcnNQZXJjZW50AAkBA2ludAEFFWtfZmVlVG9TdGFrZXJzUGVyY2VudAEObWF4T3JhY2xlRGVsYXkACQEDaW50AQUQa19tYXhPcmFjbGVEZWxheQEPZ2V0QWN0dWFsQ2FsbGVyAQFpCQELdmFsdWVPckVsc2UCCQCdCAIJAQ1vcmRlcnNBZGRyZXNzAAIIa19zZW5kZXIJAKUIAQgFAWkGY2FsbGVyARZyZXF1aXJlTW9yZU1hcmdpblJhdGlvAwxfbWFyZ2luUmF0aW8QX2Jhc2VNYXJnaW5SYXRpbxRfbGFyZ2VyVGhhbk9yRXF1YWxUbwQUcmVtYWluaW5nTWFyZ2luUmF0aW8JAGUCBQxfbWFyZ2luUmF0aW8FEF9iYXNlTWFyZ2luUmF0aW8DAwUUX2xhcmdlclRoYW5PckVxdWFsVG8JAGYCAAAFFHJlbWFpbmluZ01hcmdpblJhdGlvBwkAAgEJAKwCAgkArAICCQCsAgICEEludmFsaWQgbWFyZ2luOiAJAKQDAQUMX21hcmdpblJhdGlvAgMgPCAJAKQDAQUQX2Jhc2VNYXJnaW5SYXRpbwMDCQEBIQEFFF9sYXJnZXJUaGFuT3JFcXVhbFRvCQBnAgUUcmVtYWluaW5nTWFyZ2luUmF0aW8AAAcJAAIBCQCsAgIJAKwCAgkArAICAhBJbnZhbGlkIG1hcmdpbjogCQCkAwEFDF9tYXJnaW5SYXRpbwIDID4gCQCkAwEFEF9iYXNlTWFyZ2luUmF0aW8GAR9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQ1fcG9zaXRpb25TaXplAwkAAAIFDV9wb3NpdGlvblNpemUAAAkAAgECLFNob3VsZCBub3QgYmUgY2FsbGVkIHdpdGggX3Bvc2l0aW9uU2l6ZSA9PSAwAwkAZgIFDV9wb3NpdGlvblNpemUAAAkBI2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAkBJGxhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgABC2dldFBvc2l0aW9uAQdfdHJhZGVyBA9wb3NpdGlvblNpemVPcHQJAJoIAgUEdGhpcwkBDnRvQ29tcG9zaXRlS2V5AgUOa19wb3NpdGlvblNpemUFB190cmFkZXIEByRtYXRjaDAFD3Bvc2l0aW9uU2l6ZU9wdAMJAAECBQckbWF0Y2gwAgNJbnQEDHBvc2l0aW9uU2l6ZQUHJG1hdGNoMAkAlgoEBQxwb3NpdGlvblNpemUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFEGtfcG9zaXRpb25NYXJnaW4FB190cmFkZXIJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFFmtfcG9zaXRpb25PcGVuTm90aW9uYWwFB190cmFkZXIJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFLmtfcG9zaXRpb25MYXN0VXBkYXRlZEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FB190cmFkZXIJAJYKBAAAAAAAAAAAARBnZXRQb3NpdGlvbkFzc2V0AQdfdHJhZGVyBBBwb3NpdGlvbkFzc2V0T3B0CQCdCAIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFD2tfcG9zaXRpb25Bc3NldAUHX3RyYWRlcgQHJG1hdGNoMAUQcG9zaXRpb25Bc3NldE9wdAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEDXBvc2l0aW9uQXNzZXQFByRtYXRjaDAFDXBvc2l0aW9uQXNzZXQJANgEAQkBCnF1b3RlQXNzZXQAARNyZXF1aXJlT3BlblBvc2l0aW9uAQdfdHJhZGVyAwkAAAIICQELZ2V0UG9zaXRpb24BBQdfdHJhZGVyAl8xAAAJAAIBAhBObyBvcGVuIHBvc2l0aW9uBgELaW5pdGlhbGl6ZWQACQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFDWtfaW5pdGlhbGl6ZWQHAQZwYXVzZWQACQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFCGtfcGF1c2VkBwEJY2xvc2VPbmx5AAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzBQtrX2Nsb3NlT25seQcBDXVwZGF0ZVJlc2VydmUDBl9pc0FkZBFfcXVvdGVBc3NldEFtb3VudBBfYmFzZUFzc2V0QW1vdW50AwUGX2lzQWRkBAduZXdCYXNlCQBlAgkBBmJzQXN0UgAFEF9iYXNlQXNzZXRBbW91bnQDCQBnAgAABQduZXdCYXNlCQACAQIqVHggbGVhZCB0byBiYXNlIGFzc2V0IHJlc2VydmUgPD0gMCwgcmV2ZXJ0CQCVCgMJAGQCCQEGcXRBc3RSAAURX3F1b3RlQXNzZXRBbW91bnQFB25ld0Jhc2UJAGQCCQERdG90YWxQb3NpdGlvblNpemUABRBfYmFzZUFzc2V0QW1vdW50BAhuZXdRdW90ZQkAZQIJAQZxdEFzdFIABRFfcXVvdGVBc3NldEFtb3VudAMJAGcCAAAFCG5ld1F1b3RlCQACAQIqVHggbGVhZCB0byBiYXNlIHF1b3RlIHJlc2VydmUgPD0gMCwgcmV2ZXJ0CQCVCgMFCG5ld1F1b3RlCQBkAgkBBmJzQXN0UgAFEF9iYXNlQXNzZXRBbW91bnQJAGUCCQERdG90YWxQb3NpdGlvblNpemUABRBfYmFzZUFzc2V0QW1vdW50AQ1jYWxjSW52YXJpYW50AgdfcXRBc3RSB19ic0FzdFIEB2JxdEFzdFIJALYCAQUHX3F0QXN0UgQHYmJzQXN0UgkAtgIBBQdfYnNBc3RSCQEFYm11bGQCBQdicXRBc3RSBQdiYnNBc3RSAQlzd2FwSW5wdXQCBl9pc0FkZBFfcXVvdGVBc3NldEFtb3VudAQHX3F0QXN0UgkBBnF0QXN0UgAEB19ic0FzdFIJAQZic0FzdFIABAdfcXRBc3RXCQEGcXRBc3RXAAQHX2JzQXN0VwkBBmJzQXN0VwAEGHF1b3RlQXNzZXRBbW91bnRBZGp1c3RlZAkBBGRpdmQCBRFfcXVvdGVBc3NldEFtb3VudAUHX3F0QXN0VwQBawkBDWNhbGNJbnZhcmlhbnQCBQdfcXRBc3RSBQdfYnNBc3RSBBZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyAwUGX2lzQWRkCQBkAgUHX3F0QXN0UgUYcXVvdGVBc3NldEFtb3VudEFkanVzdGVkCQBlAgUHX3F0QXN0UgUYcXVvdGVBc3NldEFtb3VudEFkanVzdGVkBBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIJAKADAQkBBWJkaXZkAgUBawkAtgIBBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBBhhbW91bnRCYXNlQXNzZXRCb3VnaHRBYnMJAQNhYnMBCQBlAgUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBQdfYnNBc3RSBBVhbW91bnRCYXNlQXNzZXRCb3VnaHQDBQZfaXNBZGQFGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwkBAS0BBRhhbW91bnRCYXNlQXNzZXRCb3VnaHRBYnMEDSR0MDE2ODQzMTcwMTMJAQ11cGRhdGVSZXNlcnZlAwUGX2lzQWRkBRhxdW90ZUFzc2V0QW1vdW50QWRqdXN0ZWQFGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwQXcXVvdGVBc3NldFJlc2VydmVBZnRlcjEIBQ0kdDAxNjg0MzE3MDEzAl8xBBZiYXNlQXNzZXRSZXNlcnZlQWZ0ZXIxCAUNJHQwMTY4NDMxNzAxMwJfMgQXdG90YWxQb3NpdGlvblNpemVBZnRlcjEIBQ0kdDAxNjg0MzE3MDEzAl8zBAtwcmljZUJlZm9yZQkBBGRpdmQCCQEEbXVsZAIFB19xdEFzdFIFB19xdEFzdFcJAQRtdWxkAgUHX2JzQXN0UgUHX2JzQXN0VwQLbWFya2V0UHJpY2UJAQRkaXZkAgURX3F1b3RlQXNzZXRBbW91bnQFGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwQJcHJpY2VEaWZmCQEDYWJzAQkAZQIFC3ByaWNlQmVmb3JlBQttYXJrZXRQcmljZQQLcHJpY2VJbXBhY3QJAGUCBQxERUNJTUFMX1VOSVQJAQRkaXZkAgULcHJpY2VCZWZvcmUJAGQCBQtwcmljZUJlZm9yZQUJcHJpY2VEaWZmBBNtYXhQcmljZUltcGFjdFZhbHVlCQEObWF4UHJpY2VJbXBhY3QAAwkAZgIFC3ByaWNlSW1wYWN0BRNtYXhQcmljZUltcGFjdFZhbHVlCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAg1QcmljZSBpbXBhY3QgCQCkAwEFC3ByaWNlSW1wYWN0AhQgPiBtYXggcHJpY2UgaW1wYWN0IAkApAMBBRNtYXhQcmljZUltcGFjdFZhbHVlAhUgYmVmb3JlIHF1b3RlIGFzc2V0OiAJAKQDAQUHX3F0QXN0UgIUIGJlZm9yZSBiYXNlIGFzc2V0OiAJAKQDAQUHX2JzQXN0UgIhIHF1b3RlIGFzc2V0IGFtb3VudCB0byBleGNoYW5nZTogCQCkAwEFEV9xdW90ZUFzc2V0QW1vdW50Ag8gcHJpY2UgYmVmb3JlOiAJAKQDAQULcHJpY2VCZWZvcmUCDiBtYXJrZXRQcmljZTogCQCkAwEFC21hcmtldFByaWNlCQCWCgQFFWFtb3VudEJhc2VBc3NldEJvdWdodAUXcXVvdGVBc3NldFJlc2VydmVBZnRlcjEFFmJhc2VBc3NldFJlc2VydmVBZnRlcjEFF3RvdGFsUG9zaXRpb25TaXplQWZ0ZXIxASJjYWxjUmVtYWluTWFyZ2luV2l0aEZ1bmRpbmdQYXltZW50BBBfb2xkUG9zaXRpb25TaXplEl9vbGRQb3NpdGlvbk1hcmdpbiVfb2xkUG9zaXRpb25DdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uDF9tYXJnaW5EZWx0YQQOZnVuZGluZ1BheW1lbnQDCQECIT0CBRBfb2xkUG9zaXRpb25TaXplAAAEIF9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uCQEfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgEFEF9vbGRQb3NpdGlvblNpemUJAQRtdWxkAgkAZQIFIF9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uBSVfb2xkUG9zaXRpb25DdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uBRBfb2xkUG9zaXRpb25TaXplAAAEDHNpZ25lZE1hcmdpbgkAZAIJAGUCBQxfbWFyZ2luRGVsdGEFDmZ1bmRpbmdQYXltZW50BRJfb2xkUG9zaXRpb25NYXJnaW4EDSR0MDE4NTAwMTg2MjcDCQBmAgAABQxzaWduZWRNYXJnaW4JAJQKAgAACQEDYWJzAQUMc2lnbmVkTWFyZ2luCQCUCgIJAQNhYnMBBQxzaWduZWRNYXJnaW4AAAQMcmVtYWluTWFyZ2luCAUNJHQwMTg1MDAxODYyNwJfMQQHYmFkRGVidAgFDSR0MDE4NTAwMTg2MjcCXzIJAJUKAwUMcmVtYWluTWFyZ2luBQdiYWREZWJ0BQ5mdW5kaW5nUGF5bWVudAEWc3dhcE91dHB1dFdpdGhSZXNlcnZlcwcGX2lzQWRkEF9iYXNlQXNzZXRBbW91bnQUX2NoZWNrTWF4UHJpY2VJbXBhY3QSX3F1b3RlQXNzZXRSZXNlcnZlEV9xdW90ZUFzc2V0V2VpZ2h0EV9iYXNlQXNzZXRSZXNlcnZlEF9iYXNlQXNzZXRXZWlnaHQEC3ByaWNlQmVmb3JlCQEEZGl2ZAIJAQRtdWxkAgUSX3F1b3RlQXNzZXRSZXNlcnZlBRFfcXVvdGVBc3NldFdlaWdodAkBBG11bGQCBRFfYmFzZUFzc2V0UmVzZXJ2ZQUQX2Jhc2VBc3NldFdlaWdodAMJAAACBRBfYmFzZUFzc2V0QW1vdW50AAAJAAIBAhlJbnZhbGlkIGJhc2UgYXNzZXQgYW1vdW50BAFrCQENY2FsY0ludmFyaWFudAIFEl9xdW90ZUFzc2V0UmVzZXJ2ZQURX2Jhc2VBc3NldFJlc2VydmUEGGJhc2VBc3NldFBvb2xBbW91bnRBZnRlcgMFBl9pc0FkZAkAZAIFEV9iYXNlQXNzZXRSZXNlcnZlBRBfYmFzZUFzc2V0QW1vdW50CQBlAgURX2Jhc2VBc3NldFJlc2VydmUFEF9iYXNlQXNzZXRBbW91bnQED3F1b3RlQXNzZXRBZnRlcgkAoAMBCQEFYmRpdmQCBQFrCQC2AgEFGGJhc2VBc3NldFBvb2xBbW91bnRBZnRlcgQPcXVvdGVBc3NldERlbHRhCQEDYWJzAQkAZQIFD3F1b3RlQXNzZXRBZnRlcgUSX3F1b3RlQXNzZXRSZXNlcnZlBA5xdW90ZUFzc2V0U29sZAkBBG11bGQCBQ9xdW90ZUFzc2V0RGVsdGEFEV9xdW90ZUFzc2V0V2VpZ2h0BBNtYXhQcmljZUltcGFjdFZhbHVlCQEObWF4UHJpY2VJbXBhY3QABA0kdDAxOTc5NzE5OTU5CQENdXBkYXRlUmVzZXJ2ZQMJAQEhAQUGX2lzQWRkBQ9xdW90ZUFzc2V0RGVsdGEFEF9iYXNlQXNzZXRBbW91bnQEF3F1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIxCAUNJHQwMTk3OTcxOTk1OQJfMQQWYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyMQgFDSR0MDE5Nzk3MTk5NTkCXzIEF3RvdGFsUG9zaXRpb25TaXplQWZ0ZXIxCAUNJHQwMTk3OTcxOTk1OQJfMwQLbWFya2V0UHJpY2UJAQRkaXZkAgUOcXVvdGVBc3NldFNvbGQFEF9iYXNlQXNzZXRBbW91bnQECXByaWNlRGlmZgkBA2FicwEJAGUCBQtwcmljZUJlZm9yZQULbWFya2V0UHJpY2UEC3ByaWNlSW1wYWN0CQBlAgUMREVDSU1BTF9VTklUCQEEZGl2ZAIFC3ByaWNlQmVmb3JlCQBkAgULcHJpY2VCZWZvcmUFCXByaWNlRGlmZgMDCQBmAgULcHJpY2VJbXBhY3QFE21heFByaWNlSW1wYWN0VmFsdWUFFF9jaGVja01heFByaWNlSW1wYWN0BwkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgINUHJpY2UgaW1wYWN0IAkApAMBBQtwcmljZUltcGFjdAIUID4gbWF4IHByaWNlIGltcGFjdCAJAKQDAQUTbWF4UHJpY2VJbXBhY3RWYWx1ZQIVIGJlZm9yZSBxdW90ZSBhc3NldDogCQCkAwEFEl9xdW90ZUFzc2V0UmVzZXJ2ZQIUIGJlZm9yZSBiYXNlIGFzc2V0OiAJAKQDAQURX2Jhc2VBc3NldFJlc2VydmUCICBiYXNlIGFzc2V0IGFtb3VudCB0byBleGNoYW5nZTogCQCkAwEFEF9iYXNlQXNzZXRBbW91bnQCDyBwcmljZSBiZWZvcmU6IAkApAMBBQtwcmljZUJlZm9yZQIPIG1hcmtldCBwcmljZTogCQCkAwEFC21hcmtldFByaWNlCQCZCgcFDnF1b3RlQXNzZXRTb2xkBRdxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyMQUWYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyMQUXdG90YWxQb3NpdGlvblNpemVBZnRlcjEJAGUCCQEVdG90YWxMb25nUG9zaXRpb25TaXplAAMFBl9pc0FkZAkBA2FicwEFEF9iYXNlQXNzZXRBbW91bnQAAAkAZQIJARZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAMJAQEhAQUGX2lzQWRkCQEDYWJzAQUQX2Jhc2VBc3NldEFtb3VudAAABQtwcmljZUltcGFjdAEKc3dhcE91dHB1dAMGX2lzQWRkEF9iYXNlQXNzZXRBbW91bnQUX2NoZWNrTWF4UHJpY2VJbXBhY3QJARZzd2FwT3V0cHV0V2l0aFJlc2VydmVzBwUGX2lzQWRkBRBfYmFzZUFzc2V0QW1vdW50BRRfY2hlY2tNYXhQcmljZUltcGFjdAkBBnF0QXN0UgAJAQZxdEFzdFcACQEGYnNBc3RSAAkBBmJzQXN0VwABDmdldE9yYWNsZVByaWNlAAQGb3JhY2xlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUFa19vcmECAAQIcHJpY2VLZXkJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMFCWtfb3JhX2tleQQJbGFzdFZhbHVlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUGb3JhY2xlBQhwcmljZUtleQkArAICCQCsAgIJAKwCAgIiQ2FuIG5vdCBnZXQgb3JhY2xlIHByaWNlLiBPcmFjbGU6IAkApQgBBQZvcmFjbGUCBiBrZXk6IAUIcHJpY2VLZXkECGJsb2NrS2V5CQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFD2tfb3JhX2Jsb2NrX2tleQIAAwkBAiE9AgUIYmxvY2tLZXkCAAQMY3VycmVudEJsb2NrCAUJbGFzdEJsb2NrBmhlaWdodAQPbGFzdE9yYWNsZUJsb2NrCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUGb3JhY2xlBQhibG9ja0tleQkArAICCQCsAgIJAKwCAgIiQ2FuIG5vdCBnZXQgb3JhY2xlIGJsb2NrLiBPcmFjbGU6IAkApQgBBQZvcmFjbGUCBiBrZXk6IAUIYmxvY2tLZXkDCQBmAgkAZQIFDGN1cnJlbnRCbG9jawUPbGFzdE9yYWNsZUJsb2NrCQEObWF4T3JhY2xlRGVsYXkACQACAQkArAICCQCsAgIJAKwCAgImT3JhY2xlIHN0YWxlIGRhdGEuIExhc3Qgb3JhY2xlIGJsb2NrOiAJAKQDAQUPbGFzdE9yYWNsZUJsb2NrAhAgY3VycmVudCBibG9jazogCQCkAwEFDGN1cnJlbnRCbG9jawUJbGFzdFZhbHVlBQlsYXN0VmFsdWUBDmlzTWFya2V0Q2xvc2VkAAQGb3JhY2xlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUFa19vcmECAAQHb3BlbktleQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQ5rX29yYV9vcGVuX2tleQIAAwkBAiE9AgUHb3BlbktleQIABAZpc09wZW4JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmwgCBQZvcmFjbGUFB29wZW5LZXkJAKwCAgkArAICCQCsAgICK0NhbiBub3QgZ2V0IG9yYWNsZSBpcyBvcGVuL2Nsb3NlZC4gT3JhY2xlOiAJAKUIAQUGb3JhY2xlAgYga2V5OiAFB29wZW5LZXkJAQEhAQUGaXNPcGVuBwEMYWJzUHJpY2VEaWZmBQxfb3JhY2xlUHJpY2USX3F1b3RlQXNzZXRSZXNlcnZlEV9iYXNlQXNzZXRSZXNlcnZlB19xdEFzdFcHX2JzQXN0VwQKcHJpY2VBZnRlcgkBBGRpdmQCCQEEbXVsZAIFEl9xdW90ZUFzc2V0UmVzZXJ2ZQUHX3F0QXN0VwkBBG11bGQCBRFfYmFzZUFzc2V0UmVzZXJ2ZQUHX2JzQXN0VwQMYXZlcmFnZVByaWNlCQEEZGl2ZAIJAGQCBQxfb3JhY2xlUHJpY2UFCnByaWNlQWZ0ZXIJAGgCAAIFDERFQ0lNQUxfVU5JVAQMYWJzUHJpY2VEaWZmCQEEZGl2ZAIJAQNhYnMBCQBlAgUMX29yYWNsZVByaWNlBQpwcmljZUFmdGVyBQxhdmVyYWdlUHJpY2UFDGFic1ByaWNlRGlmZgEZcmVxdWlyZU5vdE92ZXJTcHJlYWRMaW1pdAISX3F1b3RlQXNzZXRSZXNlcnZlEV9iYXNlQXNzZXRSZXNlcnZlBAtvcmFjbGVQcmljZQkBDmdldE9yYWNsZVByaWNlAAQHX3F0QXN0VwkBBnF0QXN0VwAEB19ic0FzdFcJAQZic0FzdFcABBJhYnNQcmljZURpZmZCZWZvcmUJAQxhYnNQcmljZURpZmYFBQtvcmFjbGVQcmljZQkBBnF0QXN0UgAJAQZic0FzdFIABQdfcXRBc3RXBQdfYnNBc3RXBBFhYnNQcmljZURpZmZBZnRlcgkBDGFic1ByaWNlRGlmZgUFC29yYWNsZVByaWNlBRJfcXVvdGVBc3NldFJlc2VydmUFEV9iYXNlQXNzZXRSZXNlcnZlBQdfcXRBc3RXBQdfYnNBc3RXAwMJAGYCBRFhYnNQcmljZURpZmZBZnRlcgkBDm1heFByaWNlU3ByZWFkAAkAZgIFEWFic1ByaWNlRGlmZkFmdGVyBRJhYnNQcmljZURpZmZCZWZvcmUHCQACAQkArAICCQCsAgIJAKwCAgINUHJpY2Ugc3ByZWFkIAkApAMBBRFhYnNQcmljZURpZmZBZnRlcgIUID4gbWF4IHByaWNlIHNwcmVhZCAJAKQDAQkBDm1heFByaWNlU3ByZWFkAAYBHXJlcXVpcmVOb3RPdmVyTWF4T3Blbk5vdGlvbmFsAhFfbG9uZ09wZW5Ob3Rpb25hbBJfc2hvcnRPcGVuTm90aW9uYWwEEF9tYXhPcGVuTm90aW9uYWwJAQ9tYXhPcGVuTm90aW9uYWwAAwkAZgIFEV9sb25nT3Blbk5vdGlvbmFsBRBfbWF4T3Blbk5vdGlvbmFsCQACAQkArAICCQCsAgIJAKwCAgITTG9uZyBvcGVuIG5vdGlvbmFsIAkApAMBBRFfbG9uZ09wZW5Ob3Rpb25hbAIVID4gbWF4IG9wZW4gbm90aW9uYWwgCQCkAwEFEF9tYXhPcGVuTm90aW9uYWwDCQBmAgUSX3Nob3J0T3Blbk5vdGlvbmFsBRBfbWF4T3Blbk5vdGlvbmFsCQACAQkArAICCQCsAgIJAKwCAgIUU2hvcnQgb3BlbiBub3Rpb25hbCAJAKQDAQUSX3Nob3J0T3Blbk5vdGlvbmFsAhUgPiBtYXggb3BlbiBub3Rpb25hbCAJAKQDAQUQX21heE9wZW5Ob3Rpb25hbAYBDGdldFNwb3RQcmljZQAEEl9xdW90ZUFzc2V0UmVzZXJ2ZQkBBnF0QXN0UgAEEV9iYXNlQXNzZXRSZXNlcnZlCQEGYnNBc3RSAAQHX3F0QXN0VwkBBnF0QXN0VwAEB19ic0FzdFcJAQZic0FzdFcACQEEZGl2ZAIJAQRtdWxkAgUSX3F1b3RlQXNzZXRSZXNlcnZlBQdfcXRBc3RXCQEEbXVsZAIFEV9iYXNlQXNzZXRSZXNlcnZlBQdfYnNBc3RXARZpc092ZXJGbHVjdHVhdGlvbkxpbWl0AAQLb3JhY2xlUHJpY2UJAQ5nZXRPcmFjbGVQcmljZQAEDGN1cnJlbnRQcmljZQkBDGdldFNwb3RQcmljZQAJAGYCCQEEZGl2ZAIJAQNhYnMBCQBlAgULb3JhY2xlUHJpY2UFDGN1cnJlbnRQcmljZQULb3JhY2xlUHJpY2UJAQtzcHJlYWRMaW1pdAABH2dldFBvc2l0aW9uQWRqdXN0ZWRPcGVuTm90aW9uYWwGDV9wb3NpdGlvblNpemUHX29wdGlvbhJfcXVvdGVBc3NldFJlc2VydmURX3F1b3RlQXNzZXRXZWlnaHQRX2Jhc2VBc3NldFJlc2VydmUQX2Jhc2VBc3NldFdlaWdodAQPcG9zaXRpb25TaXplQWJzCQEDYWJzAQUNX3Bvc2l0aW9uU2l6ZQQHaXNTaG9ydAkAZgIAAAUNX3Bvc2l0aW9uU2l6ZQQQcG9zaXRpb25Ob3Rpb25hbAMJAAACBQdfb3B0aW9uBQ9QTkxfT1BUSU9OX1NQT1QEDSR0MDI0OTEwMjUxMzAJARZzd2FwT3V0cHV0V2l0aFJlc2VydmVzBwkBASEBBQdpc1Nob3J0BQ9wb3NpdGlvblNpemVBYnMHBRJfcXVvdGVBc3NldFJlc2VydmUFEV9xdW90ZUFzc2V0V2VpZ2h0BRFfYmFzZUFzc2V0UmVzZXJ2ZQUQX2Jhc2VBc3NldFdlaWdodAQTb3V0UG9zaXRpb25Ob3Rpb25hbAgFDSR0MDI0OTEwMjUxMzACXzEEAngxCAUNJHQwMjQ5MTAyNTEzMAJfMgQCeDIIBQ0kdDAyNDkxMDI1MTMwAl8zBAJ4MwgFDSR0MDI0OTEwMjUxMzACXzQFE291dFBvc2l0aW9uTm90aW9uYWwJAQRtdWxkAgUPcG9zaXRpb25TaXplQWJzCQEOZ2V0T3JhY2xlUHJpY2UABRBwb3NpdGlvbk5vdGlvbmFsAStnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubEJ5VmFsdWVzBw1fcG9zaXRpb25TaXplFV9wb3NpdGlvbk9wZW5Ob3Rpb25hbBJfcXVvdGVBc3NldFJlc2VydmURX3F1b3RlQXNzZXRXZWlnaHQRX2Jhc2VBc3NldFJlc2VydmUQX2Jhc2VBc3NldFdlaWdodAdfb3B0aW9uAwkAAAIFDV9wb3NpdGlvblNpemUAAAkAAgECFUludmFsaWQgcG9zaXRpb24gc2l6ZQQHaXNTaG9ydAkAZgIAAAUNX3Bvc2l0aW9uU2l6ZQQQcG9zaXRpb25Ob3Rpb25hbAkBH2dldFBvc2l0aW9uQWRqdXN0ZWRPcGVuTm90aW9uYWwGBQ1fcG9zaXRpb25TaXplBQdfb3B0aW9uBRJfcXVvdGVBc3NldFJlc2VydmUFEV9xdW90ZUFzc2V0V2VpZ2h0BRFfYmFzZUFzc2V0UmVzZXJ2ZQUQX2Jhc2VBc3NldFdlaWdodAQNdW5yZWFsaXplZFBubAMFB2lzU2hvcnQJAGUCBRVfcG9zaXRpb25PcGVuTm90aW9uYWwFEHBvc2l0aW9uTm90aW9uYWwJAGUCBRBwb3NpdGlvbk5vdGlvbmFsBRVfcG9zaXRpb25PcGVuTm90aW9uYWwJAJQKAgUQcG9zaXRpb25Ob3Rpb25hbAUNdW5yZWFsaXplZFBubAEjZ2V0UG9zaXRpb25Ob3Rpb25hbEFuZFVucmVhbGl6ZWRQbmwCB190cmFkZXIHX29wdGlvbgQNJHQwMjY1NTEyNjY3OQkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgQMcG9zaXRpb25TaXplCAUNJHQwMjY1NTEyNjY3OQJfMQQOcG9zaXRpb25NYXJnaW4IBQ0kdDAyNjU1MTI2Njc5Al8yBBRwb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDI2NTUxMjY2NzkCXzMEEXBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwMjY1NTEyNjY3OQJfNAkBK2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sQnlWYWx1ZXMHBQxwb3NpdGlvblNpemUFFHBvc2l0aW9uT3Blbk5vdGlvbmFsCQEGcXRBc3RSAAkBBnF0QXN0VwAJAQZic0FzdFIACQEGYnNBc3RXAAUHX29wdGlvbgEPY2FsY01hcmdpblJhdGlvAw1fcmVtYWluTWFyZ2luCF9iYWREZWJ0EV9wb3NpdGlvbk5vdGlvbmFsCQEEZGl2ZAIJAGUCBQ1fcmVtYWluTWFyZ2luBQhfYmFkRGVidAURX3Bvc2l0aW9uTm90aW9uYWwBFmdldE1hcmdpblJhdGlvQnlPcHRpb24CB190cmFkZXIHX29wdGlvbgQNJHQwMjcxOTIyNzMwMwkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgQMcG9zaXRpb25TaXplCAUNJHQwMjcxOTIyNzMwMwJfMQQOcG9zaXRpb25NYXJnaW4IBQ0kdDAyNzE5MjI3MzAzAl8yBANwb24IBQ0kdDAyNzE5MjI3MzAzAl8zBBFwb3NpdGlvbkxzdFVwZENQRggFDSR0MDI3MTkyMjczMDMCXzQEDSR0MDI3MzA5Mjc0MDIJASNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAIFB190cmFkZXIFB19vcHRpb24EEHBvc2l0aW9uTm90aW9uYWwIBQ0kdDAyNzMwOTI3NDAyAl8xBA11bnJlYWxpemVkUG5sCAUNJHQwMjczMDkyNzQwMgJfMgQNJHQwMjc0MDcyNzU3MwkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQxwb3NpdGlvblNpemUFDnBvc2l0aW9uTWFyZ2luBRFwb3NpdGlvbkxzdFVwZENQRgUNdW5yZWFsaXplZFBubAQMcmVtYWluTWFyZ2luCAUNJHQwMjc0MDcyNzU3MwJfMQQHYmFkRGVidAgFDSR0MDI3NDA3Mjc1NzMCXzIJAQ9jYWxjTWFyZ2luUmF0aW8DBQxyZW1haW5NYXJnaW4FB2JhZERlYnQFEHBvc2l0aW9uTm90aW9uYWwBDmdldE1hcmdpblJhdGlvAQdfdHJhZGVyCQEWZ2V0TWFyZ2luUmF0aW9CeU9wdGlvbgIFB190cmFkZXIFD1BOTF9PUFRJT05fU1BPVAEbZ2V0UGFydGlhbExpcXVpZGF0aW9uQW1vdW50AgdfdHJhZGVyDV9wb3NpdGlvblNpemUEDG1heGltdW1SYXRpbwkBBHZtYXgCCQEXcGFydGlhbExpcXVpZGF0aW9uUmF0aW8ACQBlAgUMREVDSU1BTF9VTklUCQEEZGl2ZAIJAQ5nZXRNYXJnaW5SYXRpbwEFB190cmFkZXIJARZtYWludGVuYW5jZU1hcmdpblJhdGlvAAQYbWF4RXhjaGFuZ2VkUG9zaXRpb25TaXplCQEEbXVsZAIJAQNhYnMBBQ1fcG9zaXRpb25TaXplBQxtYXhpbXVtUmF0aW8ECnN3YXBSZXN1bHQJAQpzd2FwT3V0cHV0AwkAZgIFDV9wb3NpdGlvblNpemUAAAUYbWF4RXhjaGFuZ2VkUG9zaXRpb25TaXplBwQcbWF4RXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAgFCnN3YXBSZXN1bHQCXzEEC3ByaWNlSW1wYWN0CAUKc3dhcFJlc3VsdAJfNwMJAGYCCQEObWF4UHJpY2VJbXBhY3QABQtwcmljZUltcGFjdAUcbWF4RXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAQVZXhjaGFuZ2VkUG9zaXRpb25TaXplCQEEbXVsZAIJAQNhYnMBBQ1fcG9zaXRpb25TaXplCQEXcGFydGlhbExpcXVpZGF0aW9uUmF0aW8ABBlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50CAkBCnN3YXBPdXRwdXQDCQBmAgUNX3Bvc2l0aW9uU2l6ZQAABRVleGNoYW5nZWRQb3NpdGlvblNpemUHAl8xBRlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50ARVpbnRlcm5hbENsb3NlUG9zaXRpb24CB190cmFkZXIUX2NoZWNrTWF4UHJpY2VJbXBhY3QEDSR0MDI4ODEzMjg5NDEJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIEDHBvc2l0aW9uU2l6ZQgFDSR0MDI4ODEzMjg5NDECXzEEDnBvc2l0aW9uTWFyZ2luCAUNJHQwMjg4MTMyODk0MQJfMgQUcG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDAyODgxMzI4OTQxAl8zBBFwb3NpdGlvbkxzdFVwZENQRggFDSR0MDI4ODEzMjg5NDECXzQEDXVucmVhbGl6ZWRQbmwICQEjZ2V0UG9zaXRpb25Ob3Rpb25hbEFuZFVucmVhbGl6ZWRQbmwCBQdfdHJhZGVyBQ9QTkxfT1BUSU9OX1NQT1QCXzIEDSR0MDI5MDM2MjkyMDQJASJjYWxjUmVtYWluTWFyZ2luV2l0aEZ1bmRpbmdQYXltZW50BAUMcG9zaXRpb25TaXplBQ5wb3NpdGlvbk1hcmdpbgURcG9zaXRpb25Mc3RVcGRDUEYFDXVucmVhbGl6ZWRQbmwEDHJlbWFpbk1hcmdpbggFDSR0MDI5MDM2MjkyMDQCXzEEB2JhZERlYnQIBQ0kdDAyOTAzNjI5MjA0Al8yBBVleGNoYW5nZWRQb3NpdGlvblNpemUJAQEtAQUMcG9zaXRpb25TaXplBAtyZWFsaXplZFBubAUNdW5yZWFsaXplZFBubAQNbWFyZ2luVG9WYXVsdAkBAS0BBQxyZW1haW5NYXJnaW4EDSR0MDI5MzMxMjk2MDUJAQpzd2FwT3V0cHV0AwkAZgIFDHBvc2l0aW9uU2l6ZQAACQEDYWJzAQUMcG9zaXRpb25TaXplBRRfY2hlY2tNYXhQcmljZUltcGFjdAQZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAgFDSR0MDI5MzMxMjk2MDUCXzEEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDAyOTMzMTI5NjA1Al8yBBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDAyOTMzMTI5NjA1Al8zBBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwMjkzMzEyOTYwNQJfNAQOdG90YWxMb25nQWZ0ZXIIBQ0kdDAyOTMzMTI5NjA1Al81BA90b3RhbFNob3J0QWZ0ZXIIBQ0kdDAyOTMzMTI5NjA1Al82BBlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCQBlAgkBFG9wZW5JbnRlcmVzdE5vdGlvbmFsAAUUcG9zaXRpb25PcGVuTm90aW9uYWwJAJ8KDQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplBQdiYWREZWJ0BQtyZWFsaXplZFBubAUNbWFyZ2luVG9WYXVsdAUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBRZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBRlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyBRlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50BQ50b3RhbExvbmdBZnRlcgUPdG90YWxTaG9ydEFmdGVyCQBlAgkBEG9wZW5JbnRlcmVzdExvbmcAAwkAZgIFDHBvc2l0aW9uU2l6ZQAABRRwb3NpdGlvbk9wZW5Ob3Rpb25hbAAACQBlAgkBEW9wZW5JbnRlcmVzdFNob3J0AAMJAGYCAAAFDHBvc2l0aW9uU2l6ZQUUcG9zaXRpb25PcGVuTm90aW9uYWwAAAEQZ2V0VHdhcFNwb3RQcmljZQAECG1pbnV0ZUlkCQBpAgkAaQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wAOgHADwEDXN0YXJ0TWludXRlSWQJAGUCBQhtaW51dGVJZAUNVFdBUF9JTlRFUlZBTAQHbGlzdFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQ1rX2xhc3REYXRhU3RyAgAEBGxpc3QJALUJAgUHbGlzdFN0cgIBLAoBCGZpbHRlckZuAgthY2N1bXVsYXRvcgRuZXh0AwkAZwIFDXN0YXJ0TWludXRlSWQJAQ1wYXJzZUludFZhbHVlAQUEbmV4dAkAzQgCBQthY2N1bXVsYXRvcgkBDXBhcnNlSW50VmFsdWUBBQRuZXh0BQthY2N1bXVsYXRvcgQFbGlzdEYKAAIkbAUEbGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZmlsdGVyRm4CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAQIbWF4SW5kZXgDCQBmAgkAkAMBBQVsaXN0RgAACQCWAwEFBWxpc3RGCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbGlzdAAABAxsYXN0TWludXRlSWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUOa19sYXN0TWludXRlSWQAAAQWZW5kTGFzdEN1bXVsYXRpdmVQcmljZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgUda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UCAV8JAKQDAQUMbGFzdE1pbnV0ZUlkAAAEDGVuZExhc3RQcmljZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgUTa190d2FwRGF0YUxhc3RQcmljZQIBXwkApAMBBQxsYXN0TWludXRlSWQAAAQSbm93Q3VtdWxhdGl2ZVByaWNlCQBkAgUWZW5kTGFzdEN1bXVsYXRpdmVQcmljZQkAaAIJAGUCBQhtaW51dGVJZAUMbGFzdE1pbnV0ZUlkBQxlbmRMYXN0UHJpY2UEGHN0YXJ0TGFzdEN1bXVsYXRpdmVQcmljZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgUda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UCAV8JAKQDAQUIbWF4SW5kZXgAAAQOc3RhcnRMYXN0UHJpY2UJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIFE2tfdHdhcERhdGFMYXN0UHJpY2UCAV8JAKQDAQUIbWF4SW5kZXgAAAQUc3RhcnRDdW11bGF0aXZlUHJpY2UJAGQCBRhzdGFydExhc3RDdW11bGF0aXZlUHJpY2UJAGgCCQBlAgUNc3RhcnRNaW51dGVJZAUIbWF4SW5kZXgFDnN0YXJ0TGFzdFByaWNlCQBpAgkAZQIFEm5vd0N1bXVsYXRpdmVQcmljZQUUc3RhcnRDdW11bGF0aXZlUHJpY2UFDVRXQVBfSU5URVJWQUwBE2dldFRlcm1pbmFsQW1tU3RhdGUABA1fcG9zaXRpb25TaXplCQERdG90YWxQb3NpdGlvblNpemUAAwkAAAIFDV9wb3NpdGlvblNpemUAAAkAlAoCCQEGcXRBc3RSAAkBBmJzQXN0UgAECWRpcmVjdGlvbgkAZgIFDV9wb3NpdGlvblNpemUAAAQNJHQwMzE3MjgzMTkwNwkBCnN3YXBPdXRwdXQDBQlkaXJlY3Rpb24JAQNhYnMBBQ1fcG9zaXRpb25TaXplBwQVY3VycmVudE5ldE1hcmtldFZhbHVlCAUNJHQwMzE3MjgzMTkwNwJfMQQZdGVybWluYWxRdW90ZUFzc2V0UmVzZXJ2ZQgFDSR0MDMxNzI4MzE5MDcCXzIEGHRlcm1pbmFsQmFzZUFzc2V0UmVzZXJ2ZQgFDSR0MDMxNzI4MzE5MDcCXzMJAJQKAgUZdGVybWluYWxRdW90ZUFzc2V0UmVzZXJ2ZQUYdGVybWluYWxCYXNlQXNzZXRSZXNlcnZlARNnZXRRdW90ZUFzc2V0V2VpZ2h0BBBiYXNlQXNzZXRSZXNlcnZlEXRvdGFsUG9zaXRpb25TaXplEXF1b3RlQXNzZXRSZXNlcnZlC3RhcmdldFByaWNlBAFiCQC2AgEFEGJhc2VBc3NldFJlc2VydmUEAnN6CQC2AgEFEXRvdGFsUG9zaXRpb25TaXplBAFxCQC2AgEFEXF1b3RlQXNzZXRSZXNlcnZlBAFwCQC2AgEFC3RhcmdldFByaWNlBAFrCQEFYm11bGQCBQFxBQFiBARuZXdCCQC3AgIFAWIFAnN6BARuZXdRCQEFYmRpdmQCBQFrBQRuZXdCBAF6CQEFYmRpdmQCBQRuZXdRBQRuZXdCBAZyZXN1bHQJAQViZGl2ZAIFAXAFAXoJAKADAQUGcmVzdWx0ARRnZXRTeW5jVGVybWluYWxQcmljZQMOX3Rlcm1pbmFsUHJpY2UHX3F0QXN0UgdfYnNBc3RSBA1fcG9zaXRpb25TaXplCQERdG90YWxQb3NpdGlvblNpemUAAwkAAAIFDV9wb3NpdGlvblNpemUAAAQJbmV3UXRBc3RXCQEEZGl2ZAIJAQRtdWxkAgUOX3Rlcm1pbmFsUHJpY2UFB19ic0FzdFIFB19xdEFzdFIJAJUKAwUJbmV3UXRBc3RXBQxERUNJTUFMX1VOSVQAAAQJZGlyZWN0aW9uCQBmAgUNX3Bvc2l0aW9uU2l6ZQAABBVjdXJyZW50TmV0TWFya2V0VmFsdWUICQEKc3dhcE91dHB1dAMFCWRpcmVjdGlvbgkBA2FicwEFDV9wb3NpdGlvblNpemUHAl8xBAluZXdRdEFzdFcJARNnZXRRdW90ZUFzc2V0V2VpZ2h0BAUHX2JzQXN0UgUNX3Bvc2l0aW9uU2l6ZQUHX3F0QXN0UgUOX3Rlcm1pbmFsUHJpY2UECW5ld0JzQXN0VwUMREVDSU1BTF9VTklUBA1tYXJnaW5Ub1ZhdWx0CAkBK2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sQnlWYWx1ZXMHBQ1fcG9zaXRpb25TaXplBRVjdXJyZW50TmV0TWFya2V0VmFsdWUFB19xdEFzdFIFCW5ld1F0QXN0VwUHX2JzQXN0UgUJbmV3QnNBc3RXBQ9QTkxfT1BUSU9OX1NQT1QCXzIJAJUKAwUJbmV3UXRBc3RXBQluZXdCc0FzdFcFDW1hcmdpblRvVmF1bHQBCmdldEZ1bmRpbmcABA91bmRlcmx5aW5nUHJpY2UJAQ5nZXRPcmFjbGVQcmljZQAEDXNwb3RUd2FwUHJpY2UJARBnZXRUd2FwU3BvdFByaWNlAAQHcHJlbWl1bQkAZQIFDXNwb3RUd2FwUHJpY2UFD3VuZGVybHlpbmdQcmljZQMDAwkAAAIJARZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAAABgkAAAIJARV0b3RhbExvbmdQb3NpdGlvblNpemUAAAAGCQEOaXNNYXJrZXRDbG9zZWQACQCUCgIAAAAAAwkAZgIAAAUHcHJlbWl1bQQUc2hvcnRQcmVtaXVtRnJhY3Rpb24JAQRkaXZkAgkBBG11bGQCBQdwcmVtaXVtCQEUZnVuZGluZ1BlcmlvZERlY2ltYWwABQdPTkVfREFZBBNsb25nUHJlbWl1bUZyYWN0aW9uCQEEZGl2ZAIJAQRtdWxkAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24JARZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAkBFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAJAJQKAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24FE2xvbmdQcmVtaXVtRnJhY3Rpb24EE2xvbmdQcmVtaXVtRnJhY3Rpb24JAQRkaXZkAgkBBG11bGQCBQdwcmVtaXVtCQEUZnVuZGluZ1BlcmlvZERlY2ltYWwABQdPTkVfREFZBBRzaG9ydFByZW1pdW1GcmFjdGlvbgkBBGRpdmQCCQEEbXVsZAIFE2xvbmdQcmVtaXVtRnJhY3Rpb24JARV0b3RhbExvbmdQb3NpdGlvblNpemUACQEWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAJAJQKAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24FE2xvbmdQcmVtaXVtRnJhY3Rpb24BDmdldEFkanVzdGVkRmVlAgtfYXJ0aWZhY3RJZBBfYmFzZUZlZURpc2NvdW50BApiYXNlRmVlUmF3CQEDZmVlAAQHYmFzZUZlZQkBBG11bGQCBQpiYXNlRmVlUmF3BRBfYmFzZUZlZURpc2NvdW50BA0kdDAzNDc2ODM1MjYzAwkBAiE9AgULX2FydGlmYWN0SWQCAAQMYXJ0aWZhY3RLaW5kCQEEc3RyQQIJARFuZnRNYW5hZ2VyQWRkcmVzcwAJAQ50b0NvbXBvc2l0ZUtleQIFDGtfdG9rZW5fdHlwZQULX2FydGlmYWN0SWQDCQAAAgUMYXJ0aWZhY3RLaW5kBRhGRUVfUkVEVUNUSU9OX1RPS0VOX1RZUEUECXJlZHVjdGlvbgkBBGludEECCQERbmZ0TWFuYWdlckFkZHJlc3MACQEOdG9Db21wb3NpdGVLZXkCBQ1rX3Rva2VuX3BhcmFtBQtfYXJ0aWZhY3RJZAQLYWRqdXN0ZWRGZWUJAQRtdWxkAgUHYmFzZUZlZQUJcmVkdWN0aW9uCQCUCgIFC2FkanVzdGVkRmVlBgkAAgECGUludmFsaWQgYXR0YWNoZWQgYXJ0aWZhY3QJAJQKAgUHYmFzZUZlZQcEC2FkanVzdGVkRmVlCAUNJHQwMzQ3NjgzNTI2MwJfMQQMYnVybkFydGlmYWN0CAUNJHQwMzQ3NjgzNTI2MwJfMgkAlAoCBQthZGp1c3RlZEZlZQUMYnVybkFydGlmYWN0ARdpc1NhbWVBc3NldE9yTm9Qb3NpdGlvbgIHX3RyYWRlcghfYXNzZXRJZAQPb2xkUG9zaXRpb25TaXplCAkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgJfMQMJAAACBQ9vbGRQb3NpdGlvblNpemUAAAYJAAACCQEQZ2V0UG9zaXRpb25Bc3NldAEFB190cmFkZXIFCF9hc3NldElkAQtpc1NhbWVBc3NldAIHX3RyYWRlcghfYXNzZXRJZAkAAAIJARBnZXRQb3NpdGlvbkFzc2V0AQUHX3RyYWRlcgUIX2Fzc2V0SWQBHmdldEJvcnJvd2VkQnlUcmFkZXJJbk1hcmtldEtleQMEX2FtbQhfYXNzZXRJZAdfdHJhZGVyCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBSBrX3RyYWRlcl9tYXJrZXRfYXNzZXRfY29sbGF0ZXJhbAIBXwUEX2FtbQIBXwUIX2Fzc2V0SWQCAV8FB190cmFkZXIBE2dldEJvcnJvd2VkQnlUcmFkZXIBB190cmFkZXIEDXBvc2l0aW9uQXNzZXQJARBnZXRQb3NpdGlvbkFzc2V0AQUHX3RyYWRlcgMJAAACBQ1wb3NpdGlvbkFzc2V0CQDYBAEJAQpxdW90ZUFzc2V0AAkAlAoCAAAFDXBvc2l0aW9uQXNzZXQEA2tleQkBHmdldEJvcnJvd2VkQnlUcmFkZXJJbk1hcmtldEtleQMJAKUIAQUEdGhpcwUNcG9zaXRpb25Bc3NldAUHX3RyYWRlcgQGYm9ycm93CQELdmFsdWVPckVsc2UCCQCaCAIJARFjb2xsYXRlcmFsQWRkcmVzcwAFA2tleQAACQCUCgIFBmJvcnJvdwUNcG9zaXRpb25Bc3NldAEYZ2V0Rm9yVHJhZGVyV2l0aEFydGlmYWN0AgdfdHJhZGVyC19hcnRpZmFjdElkBBBkb0dldEZlZURpc2NvdW50CQD8BwQJAQxtaW5lckFkZHJlc3MAAhJjb21wdXRlRmVlRGlzY291bnQJAMwIAgUHX3RyYWRlcgUDbmlsBQNuaWwDCQAAAgUQZG9HZXRGZWVEaXNjb3VudAUQZG9HZXRGZWVEaXNjb3VudAQLZmVlRGlzY291bnQEByRtYXRjaDAFEGRvR2V0RmVlRGlzY291bnQDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4CQACAQIhSW52YWxpZCBjb21wdXRlRmVlRGlzY291bnQgcmVzdWx0BA0kdDAzNjQ5NDM2NTY4CQEOZ2V0QWRqdXN0ZWRGZWUCBQtfYXJ0aWZhY3RJZAULZmVlRGlzY291bnQEC2FkanVzdGVkRmVlCAUNJHQwMzY0OTQzNjU2OAJfMQQMYnVybkFydGlmYWN0CAUNJHQwMzY0OTQzNjU2OAJfMgkAlAoCBQthZGp1c3RlZEZlZQUMYnVybkFydGlmYWN0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQ1nZXRBcnRpZmFjdElkAQFpBAphcnRpZmFjdElkAwkAZgIJAJADAQgFAWkIcGF5bWVudHMAAQkA2AQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIICQCRAwIIBQFpCHBheW1lbnRzAAEHYXNzZXRJZAISSW52YWxpZCBhcnRpZmFjdElkAgAFCmFydGlmYWN0SWQBDWRpc3RyaWJ1dGVGZWUBCl9mZWVBbW91bnQEDGZlZVRvU3Rha2VycwkBBG11bGQCBQpfZmVlQW1vdW50CQETZmVlVG9TdGFrZXJzUGVyY2VudAAECmZlZVRvVmF1bHQJAGUCBQpfZmVlQW1vdW50BQxmZWVUb1N0YWtlcnMJAJQKAgUMZmVlVG9TdGFrZXJzBQpmZWVUb1ZhdWx0AQ51cGRhdGVTZXR0aW5ncwwQX2luaXRNYXJnaW5SYXRpbwRfbW1yFF9saXF1aWRhdGlvbkZlZVJhdGlvDl9mdW5kaW5nUGVyaW9kBF9mZWUMX3NwcmVhZExpbWl0D19tYXhQcmljZUltcGFjdBhfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8PX21heFByaWNlU3ByZWFkEF9tYXhPcGVuTm90aW9uYWwUX2ZlZVRvU3Rha2Vyc1BlcmNlbnQPX21heE9yYWNsZURlbGF5CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrX2luaXRNYXJnaW5SYXRpbwUQX2luaXRNYXJnaW5SYXRpbwkAzAgCCQEMSW50ZWdlckVudHJ5AgUYa19tYWludGVuYW5jZU1hcmdpblJhdGlvBQRfbW1yCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRVrX2xpcXVpZGF0aW9uRmVlUmF0aW8FFF9saXF1aWRhdGlvbkZlZVJhdGlvCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9rX2Z1bmRpbmdQZXJpb2QFDl9mdW5kaW5nUGVyaW9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQVrX2ZlZQUEX2ZlZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUNa19zcHJlYWRMaW1pdAUMX3NwcmVhZExpbWl0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrX21heFByaWNlSW1wYWN0BQ9fbWF4UHJpY2VJbXBhY3QJAMwIAgkBDEludGVnZXJFbnRyeQIFGWtfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8FGF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwkAzAgCCQEMSW50ZWdlckVudHJ5AgUQa19tYXhQcmljZVNwcmVhZAUPX21heFByaWNlU3ByZWFkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrX21heE9wZW5Ob3Rpb25hbAUQX21heE9wZW5Ob3Rpb25hbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUVa19mZWVUb1N0YWtlcnNQZXJjZW50BRRfZmVlVG9TdGFrZXJzUGVyY2VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUQa19tYXhPcmFjbGVEZWxheQUUX2ZlZVRvU3Rha2Vyc1BlcmNlbnQFA25pbAENdXBkYXRlRnVuZGluZwURX25leHRGdW5kaW5nQmxvY2skX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uJV9sYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24QX2xvbmdGdW5kaW5nUmF0ZRFfc2hvcnRGdW5kaW5nUmF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUSa19uZXh0RnVuZGluZ0Jsb2NrBRFfbmV4dEZ1bmRpbmdCbG9jawkAzAgCCQEMSW50ZWdlckVudHJ5AgUla19sYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUkX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uCQDMCAIJAQxJbnRlZ2VyRW50cnkCBSZrX2xhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUlX2xhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkAzAgCCQEMSW50ZWdlckVudHJ5AgURa19sb25nRnVuZGluZ1JhdGUFEF9sb25nRnVuZGluZ1JhdGUJAMwIAgkBDEludGVnZXJFbnRyeQIFEmtfc2hvcnRGdW5kaW5nUmF0ZQURX3Nob3J0RnVuZGluZ1JhdGUFA25pbAETdXBkYXRlUG9zaXRpb25Bc3NldAIIX2FkZHJlc3MIX2Fzc2V0SWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUPa19wb3NpdGlvbkFzc2V0BQhfYWRkcmVzcwUIX2Fzc2V0SWQFA25pbAEfaW5jcmVtZW50UG9zaXRpb25TZXF1ZW5jZU51bWJlcgINaXNOZXdQb3NpdGlvbghfYWRkcmVzcwMFDWlzTmV3UG9zaXRpb24ED2N1cnJlbnRTZXF1ZW5jZQkBDGxhc3RTZXF1ZW5jZQAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFEmtfcG9zaXRpb25TZXF1ZW5jZQUIX2FkZHJlc3MJAGQCBQ9jdXJyZW50U2VxdWVuY2UAAQkAzAgCCQEMSW50ZWdlckVudHJ5AgUKa19zZXF1ZW5jZQkAZAIFD2N1cnJlbnRTZXF1ZW5jZQABBQNuaWwFA25pbAEOdXBkYXRlUG9zaXRpb24FCF9hZGRyZXNzBV9zaXplB19tYXJnaW4NX29wZW5Ob3Rpb25hbCBfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUOa19wb3NpdGlvblNpemUFCF9hZGRyZXNzBQVfc2l6ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUQa19wb3NpdGlvbk1hcmdpbgUIX2FkZHJlc3MFB19tYXJnaW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFFmtfcG9zaXRpb25PcGVuTm90aW9uYWwFCF9hZGRyZXNzBQ1fb3Blbk5vdGlvbmFsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBS5rX3Bvc2l0aW9uTGFzdFVwZGF0ZWRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uBQhfYWRkcmVzcwUgX2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FA25pbAEKYXBwZW5kVHdhcAEGX3ByaWNlBAhtaW51dGVJZAkAaQIJAGkCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcADoBwA8BBBwcmV2aW91c01pbnV0ZUlkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFDmtfbGFzdE1pbnV0ZUlkAAADCQBmAgUQcHJldmlvdXNNaW51dGVJZAUIbWludXRlSWQJAAIBAhFUV0FQIG91dC1vZi1vcmRlcgQMbGFzdE1pbnV0ZUlkAwkAAAIFEHByZXZpb3VzTWludXRlSWQAAAUIbWludXRlSWQFEHByZXZpb3VzTWludXRlSWQDCQBmAgUIbWludXRlSWQFEHByZXZpb3VzTWludXRlSWQEE3ByZXZDdW11bGF0aXZlUHJpY2UJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIFHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlAgFfCQCkAwEFEHByZXZpb3VzTWludXRlSWQAAAQJcHJldlByaWNlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgkArAICBRNrX3R3YXBEYXRhTGFzdFByaWNlAgFfCQCkAwEFEHByZXZpb3VzTWludXRlSWQFBl9wcmljZQQTbGFzdEN1bXVsYXRpdmVQcmljZQkAZAIFE3ByZXZDdW11bGF0aXZlUHJpY2UJAGgCCQBlAgUIbWludXRlSWQFDGxhc3RNaW51dGVJZAUJcHJldlByaWNlBARsaXN0CQELcHVzaFRvUXVldWUDCQEJc3RyVG9MaXN0AQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQ1rX2xhc3REYXRhU3RyAgAFDVRXQVBfSU5URVJWQUwJAKQDAQUIbWludXRlSWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlCQCkAwEFCG1pbnV0ZUlkBRNsYXN0Q3VtdWxhdGl2ZVByaWNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBRNrX3R3YXBEYXRhTGFzdFByaWNlCQCkAwEFCG1pbnV0ZUlkBQZfcHJpY2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFGmtfdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkCQCkAwEFCG1pbnV0ZUlkBRBwcmV2aW91c01pbnV0ZUlkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5rX2xhc3RNaW51dGVJZAUIbWludXRlSWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUNa19sYXN0RGF0YVN0cgkBCWxpc3RUb1N0cgEFBGxpc3QFA25pbAQYdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFGmtfdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkCQCkAwEFCG1pbnV0ZUlkAAAEE3ByZXZDdW11bGF0aXZlUHJpY2UJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBDnRvQ29tcG9zaXRlS2V5AgUda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UJAKQDAQUYdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkAAAECXByZXZQcmljZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEOdG9Db21wb3NpdGVLZXkCBRNrX3R3YXBEYXRhTGFzdFByaWNlCQCkAwEFGHR3YXBEYXRhUHJldmlvdXNNaW51dGVJZAUGX3ByaWNlBBNsYXN0Q3VtdWxhdGl2ZVByaWNlCQBkAgUTcHJldkN1bXVsYXRpdmVQcmljZQkAaAIJAGUCBQhtaW51dGVJZAUYdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkBQlwcmV2UHJpY2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlCQCkAwEFCG1pbnV0ZUlkBRNsYXN0Q3VtdWxhdGl2ZVByaWNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBRNrX3R3YXBEYXRhTGFzdFByaWNlCQCkAwEFCG1pbnV0ZUlkBQZfcHJpY2UFA25pbAERdXBkYXRlQW1tUmVzZXJ2ZXMCB19xdEFzdFIHX2JzQXN0UgkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa19xdW90ZUFzc2V0UmVzZXJ2ZQUHX3F0QXN0UgkAzAgCCQEMSW50ZWdlckVudHJ5AgUSa19iYXNlQXNzZXRSZXNlcnZlBQdfYnNBc3RSBQNuaWwBEHVwZGF0ZUFtbVdlaWdodHMCB19xdEFzdFcHX2JzQXN0VwkAzAgCCQEMSW50ZWdlckVudHJ5AgUSa19xdW90ZUFzc2V0V2VpZ2h0BQdfcXRBc3RXCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrX2Jhc2VBc3NldFdlaWdodAUHX2JzQXN0VwUDbmlsAQl1cGRhdGVBbW0IB19xdEFzdFIHX2JzQXN0UhdfdG90YWxQb3NpdGlvblNpemVBZnRlchVfb3BlbkludGVyZXN0Tm90aW9uYWwWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZRdfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZRZfdG90YWxMb25nT3Blbk5vdGlvbmFsF190b3RhbFNob3J0T3Blbk5vdGlvbmFsBAdfcXRBc3RXCQEGcXRBc3RXAAQHX2JzQXN0VwkBBmJzQXN0VwADCQECIT0CCQBlAgUWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQUXX3RvdGFsU2hvcnRQb3NpdGlvblNpemUFF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICGEludmFsaWQgQU1NIHN0YXRlIGRhdGE6IAkApAMBBRZfdG90YWxMb25nUG9zaXRpb25TaXplAgQgKyAgCQCkAwEFF190b3RhbFNob3J0UG9zaXRpb25TaXplAgQgIT0gCQCkAwEFF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCQDOCAIJAM4IAgkBEXVwZGF0ZUFtbVJlc2VydmVzAgUHX3F0QXN0UgUHX2JzQXN0UgkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa190b3RhbFBvc2l0aW9uU2l6ZQUXX3RvdGFsUG9zaXRpb25TaXplQWZ0ZXIJAMwIAgkBDEludGVnZXJFbnRyeQIFFmtfb3BlbkludGVyZXN0Tm90aW9uYWwFFV9vcGVuSW50ZXJlc3ROb3Rpb25hbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUXa190b3RhbExvbmdQb3NpdGlvblNpemUFFl90b3RhbExvbmdQb3NpdGlvblNpemUJAMwIAgkBDEludGVnZXJFbnRyeQIFGGtfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQUXX3RvdGFsU2hvcnRQb3NpdGlvblNpemUJAMwIAgkBDEludGVnZXJFbnRyeQIFEmtfb3BlbkludGVyZXN0TG9uZwUWX3RvdGFsTG9uZ09wZW5Ob3Rpb25hbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa19vcGVuSW50ZXJlc3RTaG9ydAUXX3RvdGFsU2hvcnRPcGVuTm90aW9uYWwFA25pbAkBCmFwcGVuZFR3YXABCQEEZGl2ZAIJAQRtdWxkAgUHX3F0QXN0UgUHX3F0QXN0VwkBBG11bGQCBQdfYnNBc3RSBQdfYnNBc3RXAQ5kZWxldGVQb3NpdGlvbgEIX2FkZHJlc3MJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBDnRvQ29tcG9zaXRlS2V5AgUOa19wb3NpdGlvblNpemUFCF9hZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ50b0NvbXBvc2l0ZUtleQIFEGtfcG9zaXRpb25NYXJnaW4FCF9hZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ50b0NvbXBvc2l0ZUtleQIFFmtfcG9zaXRpb25PcGVuTm90aW9uYWwFCF9hZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ50b0NvbXBvc2l0ZUtleQIFLmtfcG9zaXRpb25MYXN0VXBkYXRlZEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FCF9hZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ50b0NvbXBvc2l0ZUtleQIFD2tfcG9zaXRpb25Bc3NldAUIX2FkZHJlc3MFA25pbAEId2l0aGRyYXcCCF9hZGRyZXNzB19hbW91bnQEB2JhbGFuY2UJAPAHAgUEdGhpcwkBCnF1b3RlQXNzZXQAAwkAZgIFB19hbW91bnQFB2JhbGFuY2UJAAIBCQCsAgIJAKwCAgkArAICAhNVbmFibGUgdG8gd2l0aGRyYXcgCQCkAwEFB19hbW91bnQCFyBmcm9tIGNvbnRyYWN0IGJhbGFuY2UgCQCkAwEFB2JhbGFuY2UJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUIX2FkZHJlc3MFB19hbW91bnQJAQpxdW90ZUFzc2V0AAUDbmlsAQ11cGRhdGVCYWxhbmNlAQFpAwkAZgIAAAUBaQkAAgECB0JhbGFuY2UJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtfYmFsYW5jZQUBaQUDbmlsAQt0cmFuc2ZlckZlZQEBaQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQEOc3Rha2luZ0FkZHJlc3MABQFpCQEKcXVvdGVBc3NldAAFA25pbAEOZG9CdXJuQXJ0aWZhY3QCDV9idXJuQXJ0aWZhY3QBaQMFDV9idXJuQXJ0aWZhY3QJAMwIAgkBBEJ1cm4CCQETdmFsdWVPckVycm9yTWVzc2FnZQIICQCRAwIIBQFpCHBheW1lbnRzAAEHYXNzZXRJZAIQSW52YWxpZCBhcnRpZmFjdAABBQNuaWwFA25pbBcBaQEFcGF1c2UAAwkBAiE9AggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAkAAgECFEludmFsaWQgcGF1c2UgcGFyYW1zCQDMCAIJAQxCb29sZWFuRW50cnkCBQhrX3BhdXNlZAYFA25pbAFpAQd1bnBhdXNlAAMJAQIhPQIIBQFpBmNhbGxlcgkBDGFkbWluQWRkcmVzcwAJAAIBAhZJbnZhbGlkIHVucGF1c2UgcGFyYW1zCQDMCAIJAQxCb29sZWFuRW50cnkCBQhrX3BhdXNlZAcFA25pbAFpAQxzZXRDbG9zZU9ubHkAAwkBAiE9AggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAkAAgECG0ludmFsaWQgc2V0Q2xvc2VPbmx5IHBhcmFtcwkAzAgCCQEMQm9vbGVhbkVudHJ5AgULa19jbG9zZU9ubHkGBQNuaWwBaQEOdW5zZXRDbG9zZU9ubHkAAwkBAiE9AggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAkAAgECHUludmFsaWQgdW5zZXRDbG9zZU9ubHkgcGFyYW1zCQDMCAIJAQxCb29sZWFuRW50cnkCBQtrX2Nsb3NlT25seQcFA25pbAFpAQxhZGRMaXF1aWRpdHkBEV9xdW90ZUFzc2V0QW1vdW50AwMJAQIhPQIIBQFpBmNhbGxlcgkBDGFkbWluQWRkcmVzcwAGCQBnAgAABRFfcXVvdGVBc3NldEFtb3VudAkAAgECG0ludmFsaWQgYWRkTGlxdWlkaXR5IHBhcmFtcwQHX3F0QXN0UgkBBnF0QXN0UgAEB19ic0FzdFIJAQZic0FzdFIABAdfcXRBc3RXCQEGcXRBc3RXAAQHX2JzQXN0VwkBBmJzQXN0VwAEBXByaWNlCQEEZGl2ZAIJAQRtdWxkAgUHX3F0QXN0UgUHX3F0QXN0VwkBBG11bGQCBQdfYnNBc3RSBQdfYnNBc3RXBAtxdEFzdFJBZnRlcgkAZAIFB19xdEFzdFIFEV9xdW90ZUFzc2V0QW1vdW50BBRiYXNlQXNzZXRBbW91bnRUb0FkZAkAZQIJAQRkaXZkAgkBBG11bGQCBQtxdEFzdFJBZnRlcgUHX3F0QXN0VwUFcHJpY2UFB19ic0FzdFIEC2JzQXN0UkFmdGVyCQBkAgUHX2JzQXN0UgUUYmFzZUFzc2V0QW1vdW50VG9BZGQEDSR0MDQ1NTkwNDU3NDEJARRnZXRTeW5jVGVybWluYWxQcmljZQMJAQ5nZXRPcmFjbGVQcmljZQAFC3F0QXN0UkFmdGVyBQtic0FzdFJBZnRlcgQTbmV3UXVvdGVBc3NldFdlaWdodAgFDSR0MDQ1NTkwNDU3NDECXzEEEm5ld0Jhc2VBc3NldFdlaWdodAgFDSR0MDQ1NTkwNDU3NDECXzIEDW1hcmdpblRvVmF1bHQIBQ0kdDA0NTU5MDQ1NzQxAl8zBA1kb0V4Y2hhbmdlUG5MAwkBAiE9AgUNbWFyZ2luVG9WYXVsdAAABA1kb0V4Y2hhbmdlUG5MCQD8BwQJAQx2YXVsdEFkZHJlc3MAAhVleGNoYW5nZUZyZWVBbmRMb2NrZWQJAMwIAgUNbWFyZ2luVG9WYXVsdAUDbmlsBQNuaWwDCQAAAgUNZG9FeGNoYW5nZVBuTAUNZG9FeGNoYW5nZVBuTAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwDCQAAAgUNZG9FeGNoYW5nZVBuTAUNZG9FeGNoYW5nZVBuTAkAzggCCQERdXBkYXRlQW1tUmVzZXJ2ZXMCBQtxdEFzdFJBZnRlcgULYnNBc3RSQWZ0ZXIJARB1cGRhdGVBbW1XZWlnaHRzAgUTbmV3UXVvdGVBc3NldFdlaWdodAUSbmV3QmFzZUFzc2V0V2VpZ2h0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBD3JlbW92ZUxpcXVpZGl0eQERX3F1b3RlQXNzZXRBbW91bnQDAwkBAiE9AggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAYJAGcCAAAFEV9xdW90ZUFzc2V0QW1vdW50CQACAQIeSW52YWxpZCByZW1vdmVMaXF1aWRpdHkgcGFyYW1zBAdfcXRBc3RSCQEGcXRBc3RSAAQHX2JzQXN0UgkBBmJzQXN0UgAEB19xdEFzdFcJAQZxdEFzdFcABAdfYnNBc3RXCQEGYnNBc3RXAAQFcHJpY2UJAQRkaXZkAgkBBG11bGQCBQdfcXRBc3RSBQdfcXRBc3RXCQEEbXVsZAIFB19ic0FzdFIFB19ic0FzdFcEF2Jhc2VBc3NldEFtb3VudFRvUmVtb3ZlCQEEZGl2ZAIFEV9xdW90ZUFzc2V0QW1vdW50BQVwcmljZQQLcXRBc3RSQWZ0ZXIJAGUCBQdfcXRBc3RSBRFfcXVvdGVBc3NldEFtb3VudAQLYnNBc3RSQWZ0ZXIJAGUCBQdfYnNBc3RSBRdiYXNlQXNzZXRBbW91bnRUb1JlbW92ZQkBEXVwZGF0ZUFtbVJlc2VydmVzAgULcXRBc3RSQWZ0ZXIFC2JzQXN0UkFmdGVyAWkBDmNoYW5nZVNldHRpbmdzDBBfaW5pdE1hcmdpblJhdGlvBF9tbXIUX2xpcXVpZGF0aW9uRmVlUmF0aW8OX2Z1bmRpbmdQZXJpb2QEX2ZlZQxfc3ByZWFkTGltaXQPX21heFByaWNlSW1wYWN0GF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbw9fbWF4UHJpY2VTcHJlYWQQX21heE9wZW5Ob3Rpb25hbBRfZmVlVG9TdGFrZXJzUGVyY2VudA9fbWF4T3JhY2xlRGVsYXkDCQECIT0CCAUBaQZjYWxsZXIJAQxhZG1pbkFkZHJlc3MACQACAQIdSW52YWxpZCBjaGFuZ2VTZXR0aW5ncyBwYXJhbXMJAQ51cGRhdGVTZXR0aW5ncwwFEF9pbml0TWFyZ2luUmF0aW8FBF9tbXIFFF9saXF1aWRhdGlvbkZlZVJhdGlvBQ5fZnVuZGluZ1BlcmlvZAUEX2ZlZQUMX3NwcmVhZExpbWl0BQ9fbWF4UHJpY2VJbXBhY3QFGF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwUPX21heFByaWNlU3ByZWFkBRBfbWF4T3Blbk5vdGlvbmFsBRRfZmVlVG9TdGFrZXJzUGVyY2VudAUPX21heE9yYWNsZURlbGF5AWkBCmluaXRpYWxpemUSB19xdEFzdFIHX2JzQXN0Ug5fZnVuZGluZ1BlcmlvZBBfaW5pdE1hcmdpblJhdGlvBF9tbXIUX2xpcXVpZGF0aW9uRmVlUmF0aW8EX2ZlZQdfb3JhY2xlCl9vcmFjbGVLZXkPX29yYWNsZUJsb2NrS2V5DF9jb29yZGluYXRvcgxfc3ByZWFkTGltaXQPX21heFByaWNlSW1wYWN0GF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbw9fbWF4UHJpY2VTcHJlYWQQX21heE9wZW5Ob3Rpb25hbBRfZmVlVG9TdGFrZXJzUGVyY2VudA9fbWF4T3JhY2xlRGVsYXkDAwMDAwMDAwMDAwMDAwMDCQBnAgAABQdfcXRBc3RSBgkAZwIAAAUHX2JzQXN0UgYJAGcCAAAFDl9mdW5kaW5nUGVyaW9kBgkAZwIAAAUQX2luaXRNYXJnaW5SYXRpbwYJAGcCAAAFBF9tbXIGCQBnAgAABRRfbGlxdWlkYXRpb25GZWVSYXRpbwYJAGcCAAAFBF9mZWUGCQBnAgAABQxfc3ByZWFkTGltaXQGCQBnAgAABQ9fbWF4UHJpY2VJbXBhY3QGCQBnAgAABRhfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8GCQBnAgAABQ9fbWF4UHJpY2VTcHJlYWQGCQBnAgAABRBfbWF4T3Blbk5vdGlvbmFsBgkAZwIAAAUUX2ZlZVRvU3Rha2Vyc1BlcmNlbnQGCQBmAgUUX2ZlZVRvU3Rha2Vyc1BlcmNlbnQFDERFQ0lNQUxfVU5JVAYJAGcCAAAFD19tYXhPcmFjbGVEZWxheQYJAQtpbml0aWFsaXplZAAJAAIBAh1JbnZhbGlkIGluaXRpYWxpemUgcGFyYW1ldGVycwkAzggCCQDOCAIJAM4IAgkAzggCCQEJdXBkYXRlQW1tCAUHX3F0QXN0UgUHX2JzQXN0UgAAAAAAAAAAAAAAAAkBDnVwZGF0ZVNldHRpbmdzDAUQX2luaXRNYXJnaW5SYXRpbwUEX21tcgUUX2xpcXVpZGF0aW9uRmVlUmF0aW8FDl9mdW5kaW5nUGVyaW9kBQRfZmVlBQxfc3ByZWFkTGltaXQFD19tYXhQcmljZUltcGFjdAUYX3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvBQ9fbWF4UHJpY2VTcHJlYWQFEF9tYXhPcGVuTm90aW9uYWwFFF9mZWVUb1N0YWtlcnNQZXJjZW50BQ9fbWF4T3JhY2xlRGVsYXkJAQ11cGRhdGVGdW5kaW5nBQkAZAIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQ5fZnVuZGluZ1BlcmlvZAAAAAAAAAAACQENdXBkYXRlQmFsYW5jZQEAAAkAzAgCCQEMQm9vbGVhbkVudHJ5AgUNa19pbml0aWFsaXplZAYJAMwIAgkBC1N0cmluZ0VudHJ5AgUFa19vcmEFB19vcmFjbGUJAMwIAgkBC1N0cmluZ0VudHJ5AgUJa19vcmFfa2V5BQpfb3JhY2xlS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIFD2tfb3JhX2Jsb2NrX2tleQUPX29yYWNsZUJsb2NrS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIFFGtfY29vcmRpbmF0b3JBZGRyZXNzBQxfY29vcmRpbmF0b3IFA25pbAFpARBkZWNyZWFzZVBvc2l0aW9uAwdfYW1vdW50CV9sZXZlcmFnZRNfbWluQmFzZUFzc2V0QW1vdW50BARzeW5jCQD8BwQFBHRoaXMCGXN5bmNUZXJtaW5hbFByaWNlVG9PcmFjbGUFA25pbAUDbmlsAwkAAAIFBHN5bmMFBHN5bmMEB190cmFkZXIJAQ9nZXRBY3R1YWxDYWxsZXIBBQFpAwMDAwMDCQBnAgAABQdfYW1vdW50BgkBASEBCQELaW5pdGlhbGl6ZWQABgkBASEBCQEWcmVxdWlyZU1vcmVNYXJnaW5SYXRpbwMJAQRkaXZkAgUMREVDSU1BTF9VTklUBQlfbGV2ZXJhZ2UJAQ9pbml0TWFyZ2luUmF0aW8ABgYJAQEhAQkBE3JlcXVpcmVPcGVuUG9zaXRpb24BBQdfdHJhZGVyBgkBBnBhdXNlZAAGCQEOaXNNYXJrZXRDbG9zZWQACQACAQIjSW52YWxpZCBkZWNyZWFzZVBvc2l0aW9uIHBhcmFtZXRlcnMEDSR0MDQ5NjA4NDk3NDgJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIED29sZFBvc2l0aW9uU2l6ZQgFDSR0MDQ5NjA4NDk3NDgCXzEEEW9sZFBvc2l0aW9uTWFyZ2luCAUNJHQwNDk2MDg0OTc0OAJfMgQXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDA0OTYwODQ5NzQ4Al8zBBRvbGRQb3NpdGlvbkxzdFVwZENQRggFDSR0MDQ5NjA4NDk3NDgCXzQECl9kaXJlY3Rpb24DCQBmAgUPb2xkUG9zaXRpb25TaXplAAAFCURJUl9TSE9SVAUIRElSX0xPTkcEBWlzQWRkCQAAAgUKX2RpcmVjdGlvbgUIRElSX0xPTkcEDG9wZW5Ob3Rpb25hbAkBBG11bGQCBQdfYW1vdW50BQlfbGV2ZXJhZ2UEDSR0MDQ5OTIxNTAwMjUJASNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAIFB190cmFkZXIFD1BOTF9PUFRJT05fU1BPVAQTb2xkUG9zaXRpb25Ob3Rpb25hbAgFDSR0MDQ5OTIxNTAwMjUCXzEEDXVucmVhbGl6ZWRQbmwIBQ0kdDA0OTkyMTUwMDI1Al8yBA0kdDA1MDAzMTUyNjczAwkAZgIFE29sZFBvc2l0aW9uTm90aW9uYWwFDG9wZW5Ob3Rpb25hbAQNJHQwNTA0NDY1MDYzMAkBCXN3YXBJbnB1dAIFBWlzQWRkBQxvcGVuTm90aW9uYWwEFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQgFDSR0MDUwNDQ2NTA2MzACXzEEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1MDQ0NjUwNjMwAl8yBBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1MDQ0NjUwNjMwAl8zBBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNTA0NDY1MDYzMAJfNAQYZXhjaGFuZ2VkUG9zaXRpb25TaXplQWJzCQEDYWJzAQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplAwMJAQIhPQIFE19taW5CYXNlQXNzZXRBbW91bnQAAAkAZgIFE19taW5CYXNlQXNzZXRBbW91bnQFGGV4Y2hhbmdlZFBvc2l0aW9uU2l6ZUFicwcJAAIBCQCsAgIJAKwCAgkArAICAiVUb28gbGl0dGxlIGJhc2UgYXNzZXQgZXhjaGFuZ2VkLCBnb3QgCQCkAwEFGGV4Y2hhbmdlZFBvc2l0aW9uU2l6ZUFicwIKIGV4cGVjdGVkIAkApAMBBRNfbWluQmFzZUFzc2V0QW1vdW50BAtyZWFsaXplZFBubAkBBGRpdmQCCQEEbXVsZAIFDXVucmVhbGl6ZWRQbmwFGGV4Y2hhbmdlZFBvc2l0aW9uU2l6ZUFicwkBA2FicwEFD29sZFBvc2l0aW9uU2l6ZQQNJHQwNTEwNjc1MTI5NgkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQ9vbGRQb3NpdGlvblNpemUFEW9sZFBvc2l0aW9uTWFyZ2luBRRvbGRQb3NpdGlvbkxzdFVwZENQRgULcmVhbGl6ZWRQbmwEDHJlbWFpbk1hcmdpbggFDSR0MDUxMDY3NTEyOTYCXzEEB2JhZERlYnQIBQ0kdDA1MTA2NzUxMjk2Al8yBBlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50BQxvcGVuTm90aW9uYWwEEnVucmVhbGl6ZWRQbmxBZnRlcgkAZQIFDXVucmVhbGl6ZWRQbmwFC3JlYWxpemVkUG5sBBJyZW1haW5PcGVuTm90aW9uYWwDCQBmAgUPb2xkUG9zaXRpb25TaXplAAAJAGUCCQBlAgUTb2xkUG9zaXRpb25Ob3Rpb25hbAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAUSdW5yZWFsaXplZFBubEFmdGVyCQBlAgkAZAIFEnVucmVhbGl6ZWRQbmxBZnRlcgUTb2xkUG9zaXRpb25Ob3Rpb25hbAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAQPbmV3UG9zaXRpb25TaXplCQBkAgUPb2xkUG9zaXRpb25TaXplBRVleGNoYW5nZWRQb3NpdGlvblNpemUJAJ4KDAUPbmV3UG9zaXRpb25TaXplBQxyZW1haW5NYXJnaW4JAQNhYnMBBRJyZW1haW5PcGVuTm90aW9uYWwJAR9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQUPbmV3UG9zaXRpb25TaXplBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIJAGUCCQEUb3BlbkludGVyZXN0Tm90aW9uYWwABQxvcGVuTm90aW9uYWwJAGUCCQEVdG90YWxMb25nUG9zaXRpb25TaXplAAMJAGYCBQ9uZXdQb3NpdGlvblNpemUAAAkBA2FicwEFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQAACQBlAgkBFnRvdGFsU2hvcnRQb3NpdGlvblNpemUAAwkAZgIAAAUPbmV3UG9zaXRpb25TaXplCQEDYWJzAQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplAAAJAGUCCQEQb3BlbkludGVyZXN0TG9uZwADCQBmAgUPbmV3UG9zaXRpb25TaXplAAAFDG9wZW5Ob3Rpb25hbAAACQBlAgkBEW9wZW5JbnRlcmVzdFNob3J0AAMJAGYCAAAFD25ld1Bvc2l0aW9uU2l6ZQUMb3Blbk5vdGlvbmFsAAAJAAIBAhRDbG9zZSBwb3NpdGlvbiBmaXJzdAQPbmV3UG9zaXRpb25TaXplCAUNJHQwNTAwMzE1MjY3MwJfMQQXbmV3UG9zaXRpb25SZW1haW5NYXJnaW4IBQ0kdDA1MDAzMTUyNjczAl8yBBduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDUwMDMxNTI2NzMCXzMEFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCAUNJHQwNTAwMzE1MjY3MwJfNAQVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwNTAwMzE1MjY3MwJfNQQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDUwMDMxNTI2NzMCXzYEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDA1MDAzMTUyNjczAl83BBlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCAUNJHQwNTAwMzE1MjY3MwJfOAQOdG90YWxMb25nQWZ0ZXIIBQ0kdDA1MDAzMTUyNjczAl85BA90b3RhbFNob3J0QWZ0ZXIIBQ0kdDA1MDAzMTUyNjczA18xMAQadG90YWxMb25nT3BlbkludGVyZXN0QWZ0ZXIIBQ0kdDA1MDAzMTUyNjczA18xMQQbdG90YWxTaG9ydE9wZW5JbnRlcmVzdEFmdGVyCAUNJHQwNTAwMzE1MjY3MwNfMTIEDm5vdGlmeU5vdGlvbmFsCQD8BwQJAQxtaW5lckFkZHJlc3MAAg5ub3RpZnlOb3Rpb25hbAkAzAgCBQdfdHJhZGVyCQDMCAIFF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsBQNuaWwFA25pbAMJAAACBQ5ub3RpZnlOb3Rpb25hbAUObm90aWZ5Tm90aW9uYWwJAM4IAgkBDnVwZGF0ZVBvc2l0aW9uBQUHX3RyYWRlcgUPbmV3UG9zaXRpb25TaXplBRduZXdQb3NpdGlvblJlbWFpbk1hcmdpbgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCQEJdXBkYXRlQW1tCAUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBRZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBRlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyBQ50b3RhbExvbmdBZnRlcgUPdG90YWxTaG9ydEFmdGVyBRp0b3RhbExvbmdPcGVuSW50ZXJlc3RBZnRlcgUbdG90YWxTaG9ydE9wZW5JbnRlcmVzdEFmdGVyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEGluY3JlYXNlUG9zaXRpb24ECl9kaXJlY3Rpb24JX2xldmVyYWdlE19taW5CYXNlQXNzZXRBbW91bnQIX3JlZkxpbmsEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQHX3RyYWRlcgkBD2dldEFjdHVhbENhbGxlcgEFAWkECl9yYXdBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAhfYXNzZXRJZAgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBAtfYXNzZXRJZFN0cgkA2AQBCQEFdmFsdWUBBQhfYXNzZXRJZAQMaXNRdW90ZUFzc2V0CQAAAgUIX2Fzc2V0SWQJAQpxdW90ZUFzc2V0AAQRaXNDb2xsYXRlcmFsQXNzZXQJARBpc1doaXRlbGlzdEFzc2V0AQULX2Fzc2V0SWRTdHIDAwMDAwMDAwMDCQECIT0CBQpfZGlyZWN0aW9uBQhESVJfTE9ORwkBAiE9AgUKX2RpcmVjdGlvbgUJRElSX1NIT1JUBwYJAGcCAAAFCl9yYXdBbW91bnQGCQEBIQEJAQtpbml0aWFsaXplZAAGAwkBASEBBQxpc1F1b3RlQXNzZXQJAQEhAQURaXNDb2xsYXRlcmFsQXNzZXQHBgkBASEBCQEXaXNTYW1lQXNzZXRPck5vUG9zaXRpb24CBQdfdHJhZGVyBQtfYXNzZXRJZFN0cgYJAQEhAQkBFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8DCQEEZGl2ZAIFDERFQ0lNQUxfVU5JVAUJX2xldmVyYWdlCQEPaW5pdE1hcmdpblJhdGlvAAYGCQEGcGF1c2VkAAYJAQljbG9zZU9ubHkABgkBDmlzTWFya2V0Q2xvc2VkAAkAAgECI0ludmFsaWQgaW5jcmVhc2VQb3NpdGlvbiBwYXJhbWV0ZXJzBA0kdDA1NDEzNTU0MjIwCQEYZ2V0Rm9yVHJhZGVyV2l0aEFydGlmYWN0AgUHX3RyYWRlcgkBDWdldEFydGlmYWN0SWQBBQFpBAthZGp1c3RlZEZlZQgFDSR0MDU0MTM1NTQyMjACXzEEDGJ1cm5BcnRpZmFjdAgFDSR0MDU0MTM1NTQyMjACXzIEDHJhd0ZlZUFtb3VudAkBBG11bGQCBQpfcmF3QW1vdW50BQthZGp1c3RlZEZlZQQHX2Ftb3VudAkAZQIFCl9yYXdBbW91bnQFDHJhd0ZlZUFtb3VudAQTZGlzdHJpYnV0ZUZlZUFtb3VudAMFEWlzQ29sbGF0ZXJhbEFzc2V0BAhkb0JvcnJvdwkA/AcECQERY29sbGF0ZXJhbEFkZHJlc3MAAgZib3Jyb3cJAMwIAgUHX3RyYWRlcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQhfYXNzZXRJZAUHX2Ftb3VudAUDbmlsAwkAAAIFCGRvQm9ycm93BQhkb0JvcnJvdwQNYmFsYW5jZUJlZm9yZQkA8AcCBQR0aGlzCQEKcXVvdGVBc3NldAADCQAAAgUNYmFsYW5jZUJlZm9yZQUNYmFsYW5jZUJlZm9yZQQGZG9Td2FwCQD8BwQJAQtzd2FwQWRkcmVzcwACBHN3YXAJAMwIAgkA2AQBCQEKcXVvdGVBc3NldAAJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCF9hc3NldElkBQxyYXdGZWVBbW91bnQFA25pbAMJAAACBQZkb1N3YXAFBmRvU3dhcAQMYmFsYW5jZUFmdGVyCQDwBwIFBHRoaXMJAQpxdW90ZUFzc2V0AAMJAAACBQxiYWxhbmNlQWZ0ZXIFDGJhbGFuY2VBZnRlcgQPZXhjaGFuZ2VkQW1vdW50CQBlAgUMYmFsYW5jZUFmdGVyBQ1iYWxhbmNlQmVmb3JlAwkAAAIFD2V4Y2hhbmdlZEFtb3VudAUPZXhjaGFuZ2VkQW1vdW50BQ9leGNoYW5nZWRBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FDHJhd0ZlZUFtb3VudAMJAAACBRNkaXN0cmlidXRlRmVlQW1vdW50BRNkaXN0cmlidXRlRmVlQW1vdW50BA5yZWZlcnJlckZlZUFueQkA/AcECQEPcmVmZXJyYWxBZGRyZXNzAAIVYWNjZXB0UGF5bWVudFdpdGhMaW5rCQDMCAIFB190cmFkZXIJAMwIAgUIX3JlZkxpbmsFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABRNkaXN0cmlidXRlRmVlQW1vdW50BQNuaWwDCQAAAgUOcmVmZXJyZXJGZWVBbnkFDnJlZmVycmVyRmVlQW55BAtyZWZlcnJlckZlZQQHJG1hdGNoMAUOcmVmZXJyZXJGZWVBbnkDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4CQACAQITSW52YWxpZCByZWZlcnJlckZlZQQJZmVlQW1vdW50CQBlAgUTZGlzdHJpYnV0ZUZlZUFtb3VudAULcmVmZXJyZXJGZWUEDSR0MDU1NTM2NTU2NzYJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIED29sZFBvc2l0aW9uU2l6ZQgFDSR0MDU1NTM2NTU2NzYCXzEEEW9sZFBvc2l0aW9uTWFyZ2luCAUNJHQwNTU1MzY1NTY3NgJfMgQXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDA1NTUzNjU1Njc2Al8zBBRvbGRQb3NpdGlvbkxzdFVwZENQRggFDSR0MDU1NTM2NTU2NzYCXzQEDWlzTmV3UG9zaXRpb24JAAACBQ9vbGRQb3NpdGlvblNpemUAAAQPaXNTYW1lRGlyZWN0aW9uAwkAZgIFD29sZFBvc2l0aW9uU2l6ZQAACQAAAgUKX2RpcmVjdGlvbgUIRElSX0xPTkcJAAACBQpfZGlyZWN0aW9uBQlESVJfU0hPUlQEDmV4cGFuZEV4aXN0aW5nAwkBASEBBQ1pc05ld1Bvc2l0aW9uBQ9pc1NhbWVEaXJlY3Rpb24HBAVpc0FkZAkAAAIFCl9kaXJlY3Rpb24FCERJUl9MT05HBA0kdDA1NTk2NTU4OTI3AwMFDWlzTmV3UG9zaXRpb24GBQ5leHBhbmRFeGlzdGluZwQMb3Blbk5vdGlvbmFsCQEEbXVsZAIFB19hbW91bnQFCV9sZXZlcmFnZQQNJHQwNTY0Mjc1NjYwMAkBCXN3YXBJbnB1dAIFBWlzQWRkBQxvcGVuTm90aW9uYWwEFWFtb3VudEJhc2VBc3NldEJvdWdodAgFDSR0MDU2NDI3NTY2MDACXzEEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1NjQyNzU2NjAwAl8yBBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1NjQyNzU2NjAwAl8zBBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNTY0Mjc1NjYwMAJfNAMDCQECIT0CBRNfbWluQmFzZUFzc2V0QW1vdW50AAAJAGYCBRNfbWluQmFzZUFzc2V0QW1vdW50CQEDYWJzAQUVYW1vdW50QmFzZUFzc2V0Qm91Z2h0BwkAAgEJAKwCAgkArAICCQCsAgICDUxpbWl0IGVycm9yOiAJAKQDAQkBA2FicwEFFWFtb3VudEJhc2VBc3NldEJvdWdodAIDIDwgCQCkAwEFE19taW5CYXNlQXNzZXRBbW91bnQED25ld1Bvc2l0aW9uU2l6ZQkAZAIFD29sZFBvc2l0aW9uU2l6ZQUVYW1vdW50QmFzZUFzc2V0Qm91Z2h0BBp0b3RhbExvbmdPcGVuSW50ZXJlc3RBZnRlcgkAZAIJARBvcGVuSW50ZXJlc3RMb25nAAMJAGYCBQ9uZXdQb3NpdGlvblNpemUAAAUMb3Blbk5vdGlvbmFsAAAEG3RvdGFsU2hvcnRPcGVuSW50ZXJlc3RBZnRlcgkAZAIJARFvcGVuSW50ZXJlc3RTaG9ydAADCQBmAgAABQ9uZXdQb3NpdGlvblNpemUFDG9wZW5Ob3Rpb25hbAAABA0kdDA1NzE0NjU3MzY3CQEiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAQFD29sZFBvc2l0aW9uU2l6ZQURb2xkUG9zaXRpb25NYXJnaW4FFG9sZFBvc2l0aW9uTHN0VXBkQ1BGBQdfYW1vdW50BAxyZW1haW5NYXJnaW4IBQ0kdDA1NzE0NjU3MzY3Al8xBAJ4MQgFDSR0MDU3MTQ2NTczNjcCXzIEAngyCAUNJHQwNTcxNDY1NzM2NwJfMwMJAQEhAQkBGXJlcXVpcmVOb3RPdmVyU3ByZWFkTGltaXQCBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIJAAIBAhVPdmVyIG1heCBzcHJlYWQgbGltaXQDCQEBIQEJAR1yZXF1aXJlTm90T3Zlck1heE9wZW5Ob3Rpb25hbAIFGnRvdGFsTG9uZ09wZW5JbnRlcmVzdEFmdGVyBRt0b3RhbFNob3J0T3BlbkludGVyZXN0QWZ0ZXIJAAIBAhZPdmVyIG1heCBvcGVuIG5vdGlvbmFsCQCeCgwFD25ld1Bvc2l0aW9uU2l6ZQUMcmVtYWluTWFyZ2luCQBkAgUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwFDG9wZW5Ob3Rpb25hbAkBH2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24BBQ9uZXdQb3NpdGlvblNpemUFFWJhc2VBc3NldFJlc2VydmVBZnRlcgUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUWdG90YWxQb3NpdGlvblNpemVBZnRlcgkAZAIJARRvcGVuSW50ZXJlc3ROb3Rpb25hbAAFDG9wZW5Ob3Rpb25hbAkAZAIJARV0b3RhbExvbmdQb3NpdGlvblNpemUAAwkAZgIFD25ld1Bvc2l0aW9uU2l6ZQAACQEDYWJzAQUVYW1vdW50QmFzZUFzc2V0Qm91Z2h0AAAJAGQCCQEWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQADCQBmAgAABQ9uZXdQb3NpdGlvblNpemUJAQNhYnMBBRVhbW91bnRCYXNlQXNzZXRCb3VnaHQAAAUadG90YWxMb25nT3BlbkludGVyZXN0QWZ0ZXIFG3RvdGFsU2hvcnRPcGVuSW50ZXJlc3RBZnRlcgQMb3Blbk5vdGlvbmFsCQEEbXVsZAIFB19hbW91bnQFCV9sZXZlcmFnZQQNJHQwNTg2Mjc1ODc0MwkBI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAgkApQgBCAUBaQZjYWxsZXIFD1BOTF9PUFRJT05fU1BPVAQTb2xkUG9zaXRpb25Ob3Rpb25hbAgFDSR0MDU4NjI3NTg3NDMCXzEEDXVucmVhbGl6ZWRQbmwIBQ0kdDA1ODYyNzU4NzQzAl8yAwkAZgIFE29sZFBvc2l0aW9uTm90aW9uYWwFDG9wZW5Ob3Rpb25hbAkAAgECLlVzZSBkZWNyZWFzZVBvc2l0aW9uIHRvIGRlY3JlYXNlIHBvc2l0aW9uIHNpemUJAAIBAhRDbG9zZSBwb3NpdGlvbiBmaXJzdAQPbmV3UG9zaXRpb25TaXplCAUNJHQwNTU5NjU1ODkyNwJfMQQXbmV3UG9zaXRpb25SZW1haW5NYXJnaW4IBQ0kdDA1NTk2NTU4OTI3Al8yBBduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDU1OTY1NTg5MjcCXzMEFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCAUNJHQwNTU5NjU1ODkyNwJfNAQVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwNTU5NjU1ODkyNwJfNQQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDU1OTY1NTg5MjcCXzYEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDA1NTk2NTU4OTI3Al83BBlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCAUNJHQwNTU5NjU1ODkyNwJfOAQOdG90YWxMb25nQWZ0ZXIIBQ0kdDA1NTk2NTU4OTI3Al85BA90b3RhbFNob3J0QWZ0ZXIIBQ0kdDA1NTk2NTU4OTI3A18xMAQadG90YWxMb25nT3BlbkludGVyZXN0QWZ0ZXIIBQ0kdDA1NTk2NTU4OTI3A18xMQQbdG90YWxTaG9ydE9wZW5JbnRlcmVzdEFmdGVyCAUNJHQwNTU5NjU1ODkyNwNfMTIEDSR0MDU4OTMzNTg5OTAJAQ1kaXN0cmlidXRlRmVlAQUJZmVlQW1vdW50BAxmZWVUb1N0YWtlcnMIBQ0kdDA1ODkzMzU4OTkwAl8xBApmZWVUb1ZhdWx0CAUNJHQwNTg5MzM1ODk5MAJfMgQFc3Rha2UDBQxpc1F1b3RlQXNzZXQEBXN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAglhZGRMb2NrZWQJAMwIAgcFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQdfYW1vdW50BQNuaWwDCQAAAgUFc3Rha2UFBXN0YWtlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBQVzdGFrZQUFc3Rha2UEEGRlcG9zaXRJbnN1cmFuY2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACB2FkZEZyZWUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQpmZWVUb1ZhdWx0BQNuaWwDCQAAAgUQZGVwb3NpdEluc3VyYW5jZQUQZGVwb3NpdEluc3VyYW5jZQQJbm90aWZ5RmVlCQD8BwQJAQxtaW5lckFkZHJlc3MAAgpub3RpZnlGZWVzCQDMCAIFB190cmFkZXIJAMwIAgUJZmVlQW1vdW50BQNuaWwFA25pbAMJAAACBQlub3RpZnlGZWUFCW5vdGlmeUZlZQQObm90aWZ5Tm90aW9uYWwJAPwHBAkBDG1pbmVyQWRkcmVzcwACDm5vdGlmeU5vdGlvbmFsCQDMCAIFB190cmFkZXIJAMwIAgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFA25pbAUDbmlsAwkAAAIFDm5vdGlmeU5vdGlvbmFsBQ5ub3RpZnlOb3Rpb25hbAkAzggCCQDOCAIJAM4IAgkAzggCCQDOCAIJAM4IAgkBDnVwZGF0ZVBvc2l0aW9uBQUHX3RyYWRlcgUPbmV3UG9zaXRpb25TaXplBRduZXdQb3NpdGlvblJlbWFpbk1hcmdpbgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCQEfaW5jcmVtZW50UG9zaXRpb25TZXF1ZW5jZU51bWJlcgIFDWlzTmV3UG9zaXRpb24FB190cmFkZXIJARN1cGRhdGVQb3NpdGlvbkFzc2V0AgUHX3RyYWRlcgULX2Fzc2V0SWRTdHIJAQl1cGRhdGVBbW0IBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIFDnRvdGFsTG9uZ0FmdGVyBQ90b3RhbFNob3J0QWZ0ZXIFGnRvdGFsTG9uZ09wZW5JbnRlcmVzdEFmdGVyBRt0b3RhbFNob3J0T3BlbkludGVyZXN0QWZ0ZXIJAQt0cmFuc2ZlckZlZQEFDGZlZVRvU3Rha2VycwkBDXVwZGF0ZUJhbGFuY2UBCQBkAgkBCGNiYWxhbmNlAAUHX2Ftb3VudAkBDmRvQnVybkFydGlmYWN0AgUMYnVybkFydGlmYWN0BQFpCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCWFkZE1hcmdpbgAEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQHX3RyYWRlcgkApQgBCAUBaQZjYWxsZXIECl9yYXdBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAhfYXNzZXRJZAgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBAtfYXNzZXRJZFN0cgkA2AQBCQEFdmFsdWUBBQhfYXNzZXRJZAQMaXNRdW90ZUFzc2V0CQAAAgUIX2Fzc2V0SWQJAQpxdW90ZUFzc2V0AAQRaXNDb2xsYXRlcmFsQXNzZXQJARBpc1doaXRlbGlzdEFzc2V0AQULX2Fzc2V0SWRTdHIDAwMDAwMDAwkBASEBBQxpc1F1b3RlQXNzZXQJAQEhAQURaXNDb2xsYXRlcmFsQXNzZXQHBgkBASEBCQETcmVxdWlyZU9wZW5Qb3NpdGlvbgEJAKUIAQgFAWkGY2FsbGVyBgkBASEBCQELaXNTYW1lQXNzZXQCBQdfdHJhZGVyBQtfYXNzZXRJZFN0cgYJAQEhAQkBC2luaXRpYWxpemVkAAYJAQZwYXVzZWQABgkBCWNsb3NlT25seQAGCQEOaXNNYXJrZXRDbG9zZWQACQACAQIcSW52YWxpZCBhZGRNYXJnaW4gcGFyYW1ldGVycwQNJHQwNjA5NjI2MTA0NwkBGGdldEZvclRyYWRlcldpdGhBcnRpZmFjdAIFB190cmFkZXIJAQ1nZXRBcnRpZmFjdElkAQUBaQQLYWRqdXN0ZWRGZWUIBQ0kdDA2MDk2MjYxMDQ3Al8xBAxidXJuQXJ0aWZhY3QIBQ0kdDA2MDk2MjYxMDQ3Al8yBAxyYXdGZWVBbW91bnQJAQRtdWxkAgUKX3Jhd0Ftb3VudAULYWRqdXN0ZWRGZWUEB19hbW91bnQJAGUCBQpfcmF3QW1vdW50BQxyYXdGZWVBbW91bnQEE2Rpc3RyaWJ1dGVGZWVBbW91bnQDBRFpc0NvbGxhdGVyYWxBc3NldAQIZG9Cb3Jyb3cJAPwHBAkBEWNvbGxhdGVyYWxBZGRyZXNzAAIGYm9ycm93CQDMCAIFB190cmFkZXIFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUIX2Fzc2V0SWQFB19hbW91bnQFA25pbAMJAAACBQhkb0JvcnJvdwUIZG9Cb3Jyb3cEDWJhbGFuY2VCZWZvcmUJAPAHAgUEdGhpcwkBCnF1b3RlQXNzZXQAAwkAAAIFDWJhbGFuY2VCZWZvcmUFDWJhbGFuY2VCZWZvcmUEBmRvU3dhcAkA/AcECQELc3dhcEFkZHJlc3MAAgRzd2FwCQDMCAIJANgEAQkBCnF1b3RlQXNzZXQACQDMCAIAAAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQhfYXNzZXRJZAUMcmF3RmVlQW1vdW50BQNuaWwDCQAAAgUGZG9Td2FwBQZkb1N3YXAEDGJhbGFuY2VBZnRlcgkA8AcCBQR0aGlzCQEKcXVvdGVBc3NldAADCQAAAgUMYmFsYW5jZUFmdGVyBQxiYWxhbmNlQWZ0ZXIED2V4Y2hhbmdlZEFtb3VudAkAZQIFDGJhbGFuY2VBZnRlcgUNYmFsYW5jZUJlZm9yZQMJAAACBQ9leGNoYW5nZWRBbW91bnQFD2V4Y2hhbmdlZEFtb3VudAUPZXhjaGFuZ2VkQW1vdW50CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQxyYXdGZWVBbW91bnQDCQAAAgUTZGlzdHJpYnV0ZUZlZUFtb3VudAUTZGlzdHJpYnV0ZUZlZUFtb3VudAQOcmVmZXJyZXJGZWVBbnkJAPwHBAkBD3JlZmVycmFsQWRkcmVzcwACDWFjY2VwdFBheW1lbnQJAMwIAgUHX3RyYWRlcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFE2Rpc3RyaWJ1dGVGZWVBbW91bnQFA25pbAMJAAACBQ5yZWZlcnJlckZlZUFueQUOcmVmZXJyZXJGZWVBbnkEC3JlZmVycmVyRmVlBAckbWF0Y2gwBQ5yZWZlcnJlckZlZUFueQMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAhNJbnZhbGlkIHJlZmVycmVyRmVlBAlmZWVBbW91bnQJAGUCBRNkaXN0cmlidXRlRmVlQW1vdW50BQtyZWZlcnJlckZlZQQNJHQwNjIzNDY2MjQ4NgkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgQPb2xkUG9zaXRpb25TaXplCAUNJHQwNjIzNDY2MjQ4NgJfMQQRb2xkUG9zaXRpb25NYXJnaW4IBQ0kdDA2MjM0NjYyNDg2Al8yBBdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDYyMzQ2NjI0ODYCXzMEFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwNjIzNDY2MjQ4NgJfNAQNJHQwNjI0OTI2MjU0OQkBDWRpc3RyaWJ1dGVGZWUBBQlmZWVBbW91bnQEDGZlZVRvU3Rha2VycwgFDSR0MDYyNDkyNjI1NDkCXzEECmZlZVRvVmF1bHQIBQ0kdDA2MjQ5MjYyNTQ5Al8yBAVzdGFrZQMFDGlzUXVvdGVBc3NldAQFc3Rha2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACCWFkZExvY2tlZAkAzAgCBwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFB19hbW91bnQFA25pbAMJAAACBQVzdGFrZQUFc3Rha2UFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAwkAAAIFBXN0YWtlBQVzdGFrZQQQZGVwb3NpdEluc3VyYW5jZQkA/AcECQEMdmF1bHRBZGRyZXNzAAIHYWRkRnJlZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFCmZlZVRvVmF1bHQFA25pbAMJAAACBRBkZXBvc2l0SW5zdXJhbmNlBRBkZXBvc2l0SW5zdXJhbmNlBAlub3RpZnlGZWUJAPwHBAkBDG1pbmVyQWRkcmVzcwACCm5vdGlmeUZlZXMJAMwIAgUHX3RyYWRlcgkAzAgCBQlmZWVBbW91bnQFA25pbAUDbmlsAwkAAAIFCW5vdGlmeUZlZQUJbm90aWZ5RmVlCQDOCAIJAM4IAgkAzggCCQEOdXBkYXRlUG9zaXRpb24FBQdfdHJhZGVyBQ9vbGRQb3NpdGlvblNpemUJAGQCBRFvbGRQb3NpdGlvbk1hcmdpbgUHX2Ftb3VudAUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwFFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCQELdHJhbnNmZXJGZWUBBQxmZWVUb1N0YWtlcnMJAQ11cGRhdGVCYWxhbmNlAQkAZAIJAQhjYmFsYW5jZQAFB19hbW91bnQJAQ5kb0J1cm5BcnRpZmFjdAIFDGJ1cm5BcnRpZmFjdAUBaQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQxyZW1vdmVNYXJnaW4BB19hbW91bnQEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQHX3RyYWRlcgkApQgBCAUBaQZjYWxsZXIDAwMDAwkAZwIAAAUHX2Ftb3VudAYJAQEhAQkBE3JlcXVpcmVPcGVuUG9zaXRpb24BBQdfdHJhZGVyBgkBASEBCQELaW5pdGlhbGl6ZWQABgkBBnBhdXNlZAAGCQEOaXNNYXJrZXRDbG9zZWQACQACAQIfSW52YWxpZCByZW1vdmVNYXJnaW4gcGFyYW1ldGVycwQNJHQwNjM2ODU2MzgyNQkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgQPb2xkUG9zaXRpb25TaXplCAUNJHQwNjM2ODU2MzgyNQJfMQQRb2xkUG9zaXRpb25NYXJnaW4IBQ0kdDA2MzY4NTYzODI1Al8yBBdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDYzNjg1NjM4MjUCXzMEFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwNjM2ODU2MzgyNQJfNAQLbWFyZ2luRGVsdGEJAQEtAQUHX2Ftb3VudAQNJHQwNjM4NjI2NDA0MQkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQ9vbGRQb3NpdGlvblNpemUFEW9sZFBvc2l0aW9uTWFyZ2luBRRvbGRQb3NpdGlvbkxzdFVwZENQRgULbWFyZ2luRGVsdGEEDHJlbWFpbk1hcmdpbggFDSR0MDYzODYyNjQwNDECXzEEB2JhZERlYnQIBQ0kdDA2Mzg2MjY0MDQxAl8yAwkBAiE9AgUHYmFkRGVidAAACQACAQIdSW52YWxpZCByZW1vdmVkIG1hcmdpbiBhbW91bnQEC21hcmdpblJhdGlvCQEPY2FsY01hcmdpblJhdGlvAwUMcmVtYWluTWFyZ2luBQdiYWREZWJ0BRdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAMJAQEhAQkBFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8DBQttYXJnaW5SYXRpbwkBD2luaXRNYXJnaW5SYXRpbwAGCQACAQkArAICCQCsAgIJAKwCAgIZVG9vIG11Y2ggbWFyZ2luIHJlbW92ZWQ6IAkApAMBBQttYXJnaW5SYXRpbwIDIDwgCQCkAwEJAQ9pbml0TWFyZ2luUmF0aW8ABA1xdW90ZUFzc2V0U3RyCQDYBAEJAQpxdW90ZUFzc2V0AAQNJHQwNjQ0ODU2NDUzOQkBE2dldEJvcnJvd2VkQnlUcmFkZXIBBQdfdHJhZGVyBAhib3Jyb3dlZAgFDSR0MDY0NDg1NjQ1MzkCXzEEB2Fzc2V0SWQIBQ0kdDA2NDQ4NTY0NTM5Al8yBAd0b1JlcGF5AwkAZgIFB19hbW91bnQFCGJvcnJvd2VkBQhib3Jyb3dlZAUHX2Ftb3VudAQKdG9XaXRoZHJhdwMJAGYCBQhib3Jyb3dlZAUHX2Ftb3VudAAACQBlAgUHX2Ftb3VudAUIYm9ycm93ZWQEC2ZpbmFsQm9ycm93CQBlAgUIYm9ycm93ZWQFB3RvUmVwYXkEFXN3aXRjaFBvc2l0aW9uVG9RdW90ZQMJAGYCBQtmaW5hbEJvcnJvdwAABQNuaWwJARN1cGRhdGVQb3NpdGlvbkFzc2V0AgUHX3RyYWRlcgUNcXVvdGVBc3NldFN0cgQNZG9TYW5pdHlDaGVjawMJAQIhPQIJAGQCBQd0b1JlcGF5BQp0b1dpdGhkcmF3BQdfYW1vdW50CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCHRvUmVwYXk9CQCkAwEFB3RvUmVwYXkCDiArIHRvV2l0aGRyYXc9CQCkAwEFCnRvV2l0aGRyYXcCBCAhPSAJAKQDAQUHX2Ftb3VudAUDbmlsAwkAAAIFDWRvU2FuaXR5Q2hlY2sFDWRvU2FuaXR5Q2hlY2sECWRvVW5zdGFrZQMJAGYCBQp0b1dpdGhkcmF3AAAECWRvVW5zdGFrZQkA/AcECQEMdmF1bHRBZGRyZXNzAAIOd2l0aGRyYXdMb2NrZWQJAMwIAgUKdG9XaXRoZHJhdwUDbmlsBQNuaWwDCQAAAgUJZG9VbnN0YWtlBQlkb1Vuc3Rha2UFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAwkAAAIFCWRvVW5zdGFrZQUJZG9VbnN0YWtlBBZyZXR1cm5Db2xsYXRlcmFsQWN0aW9uAwkAZgIFB3RvUmVwYXkAAAQHZG9SZXBheQkA/AcECQERY29sbGF0ZXJhbEFkZHJlc3MAAgVyZXBheQkAzAgCBQdfdHJhZGVyCQDMCAIFB3RvUmVwYXkJAMwIAgUHYXNzZXRJZAUDbmlsBQNuaWwDCQAAAgUHZG9SZXBheQUHZG9SZXBheQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFB3RvUmVwYXkJANkEAQUHYXNzZXRJZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwDCQAAAgUWcmV0dXJuQ29sbGF0ZXJhbEFjdGlvbgUWcmV0dXJuQ29sbGF0ZXJhbEFjdGlvbgkAzggCCQDOCAIJAM4IAgkAzggCCQEOdXBkYXRlUG9zaXRpb24FBQdfdHJhZGVyBQ9vbGRQb3NpdGlvblNpemUFDHJlbWFpbk1hcmdpbgUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwJAR9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQUPb2xkUG9zaXRpb25TaXplAwkAZgIFCnRvV2l0aGRyYXcAAAkBCHdpdGhkcmF3AggFAWkGY2FsbGVyBQp0b1dpdGhkcmF3BQNuaWwJAQ11cGRhdGVCYWxhbmNlAQkAZQIJAQhjYmFsYW5jZQAFB19hbW91bnQFFXN3aXRjaFBvc2l0aW9uVG9RdW90ZQUWcmV0dXJuQ29sbGF0ZXJhbEFjdGlvbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ1jbG9zZVBvc2l0aW9uAgVfc2l6ZRRfbWluUXVvdGVBc3NldEFtb3VudAQEc3luYwkA/AcEBQR0aGlzAhlzeW5jVGVybWluYWxQcmljZVRvT3JhY2xlBQNuaWwFA25pbAMJAAACBQRzeW5jBQRzeW5jBAdfdHJhZGVyCQEPZ2V0QWN0dWFsQ2FsbGVyAQUBaQQOX3RyYWRlckFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQdfdHJhZGVyAg5JbnZhbGlkIGNhbGxlcgMDAwMDAwkBASEBCQETcmVxdWlyZU9wZW5Qb3NpdGlvbgEFB190cmFkZXIGCQEBIQEJAQtpbml0aWFsaXplZAAGCQEGcGF1c2VkAAYJAGcCAAAFBV9zaXplBgkAZgIAAAUUX21pblF1b3RlQXNzZXRBbW91bnQGCQEOaXNNYXJrZXRDbG9zZWQACQACAQIgSW52YWxpZCBjbG9zZVBvc2l0aW9uIHBhcmFtZXRlcnMEDSR0MDY2NzIzNjY4NjMJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIED29sZFBvc2l0aW9uU2l6ZQgFDSR0MDY2NzIzNjY4NjMCXzEEEW9sZFBvc2l0aW9uTWFyZ2luCAUNJHQwNjY3MjM2Njg2MwJfMgQXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDA2NjcyMzY2ODYzAl8zBBRvbGRQb3NpdGlvbkxzdFVwZENQRggFDSR0MDY2NzIzNjY4NjMCXzQEDSR0MDY2ODY5NzE5OTkDCQBmAgkBA2FicwEFD29sZFBvc2l0aW9uU2l6ZQUFX3NpemUECl9kaXJlY3Rpb24DCQBmAgUPb2xkUG9zaXRpb25TaXplAAAFCURJUl9TSE9SVAUIRElSX0xPTkcEBWlzQWRkCQAAAgUKX2RpcmVjdGlvbgUIRElSX0xPTkcEDSR0MDY3NDYwNjc2ODIJAQpzd2FwT3V0cHV0AwkAZgIFD29sZFBvc2l0aW9uU2l6ZQAABQVfc2l6ZQYEGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQIBQ0kdDA2NzQ2MDY3NjgyAl8xBBZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwNjc0NjA2NzY4MgJfMgQVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwNjc0NjA2NzY4MgJfMwQWdG90YWxQb3NpdGlvblNpemVBZnRlcggFDSR0MDY3NDYwNjc2ODICXzQEFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQMJAGYCBQ9vbGRQb3NpdGlvblNpemUAAAkBAS0BBQVfc2l6ZQUFX3NpemUEDSR0MDY3NzczNjc5MjcJASNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAIFB190cmFkZXIFD1BOTF9PUFRJT05fU1BPVAQTb2xkUG9zaXRpb25Ob3Rpb25hbAgFDSR0MDY3NzczNjc5MjcCXzEEDXVucmVhbGl6ZWRQbmwIBQ0kdDA2Nzc3MzY3OTI3Al8yBAJtcgkBFmdldE1hcmdpblJhdGlvQnlPcHRpb24CBQdfdHJhZGVyBQ9QTkxfT1BUSU9OX1NQT1QEDXJlYWxpemVkUmF0aW8JAQRkaXZkAgkBA2FicwEFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQkBA2FicwEFD29sZFBvc2l0aW9uU2l6ZQQLcmVhbGl6ZWRQbmwJAQRtdWxkAgUNdW5yZWFsaXplZFBubAUNcmVhbGl6ZWRSYXRpbwQScmVtYWluTWFyZ2luQmVmb3JlCAkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQ9vbGRQb3NpdGlvblNpemUFEW9sZFBvc2l0aW9uTWFyZ2luBRRvbGRQb3NpdGlvbkxzdFVwZENQRgUNdW5yZWFsaXplZFBubAJfMQQNJHQwNjg0Mjg2ODY1NgkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQ9vbGRQb3NpdGlvblNpemUFEW9sZFBvc2l0aW9uTWFyZ2luBRRvbGRQb3NpdGlvbkxzdFVwZENQRgULcmVhbGl6ZWRQbmwEAngxCAUNJHQwNjg0Mjg2ODY1NgJfMQQPcG9zaXRpb25CYWREZWJ0CAUNJHQwNjg0Mjg2ODY1NgJfMgQOZnVuZGluZ1BheW1lbnQIBQ0kdDA2ODQyODY4NjU2Al8zBBJ1bnJlYWxpemVkUG5sQWZ0ZXIJAGUCBQ11bnJlYWxpemVkUG5sBQtyZWFsaXplZFBubAQScmVtYWluT3Blbk5vdGlvbmFsAwkAZgIFD29sZFBvc2l0aW9uU2l6ZQAACQBlAgkAZQIFE29sZFBvc2l0aW9uTm90aW9uYWwFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQFEnVucmVhbGl6ZWRQbmxBZnRlcgkAZQIJAGQCBRJ1bnJlYWxpemVkUG5sQWZ0ZXIFE29sZFBvc2l0aW9uTm90aW9uYWwFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQEF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsCQEDYWJzAQUScmVtYWluT3Blbk5vdGlvbmFsBBFuZXdQb3NpdGlvbk1hcmdpbgMJAGYCBQ9vbGRQb3NpdGlvblNpemUAAAkAZQIJAQRtdWxkAgkAZAIFF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsBRJ1bnJlYWxpemVkUG5sQWZ0ZXIFAm1yBRJ1bnJlYWxpemVkUG5sQWZ0ZXIJAGUCCQEEbXVsZAIJAGUCBRduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAUSdW5yZWFsaXplZFBubEFmdGVyBQJtcgUSdW5yZWFsaXplZFBubEFmdGVyBBFvcGVuTm90aW9uYWxEZWx0YQkAZQIFF29sZFBvc2l0aW9uT3Blbk5vdGlvbmFsBRduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAQPbmV3UG9zaXRpb25TaXplCQBkAgUPb2xkUG9zaXRpb25TaXplBRVleGNoYW5nZWRQb3NpdGlvblNpemUEFG5ld1Bvc2l0aW9uTHN0VXBkQ1BGCQEfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgEFD25ld1Bvc2l0aW9uU2l6ZQQZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgkAZQIJARRvcGVuSW50ZXJlc3ROb3Rpb25hbAAFEW9wZW5Ob3Rpb25hbERlbHRhAwMJAQIhPQIFFF9taW5RdW90ZUFzc2V0QW1vdW50AAAJAGYCBRRfbWluUXVvdGVBc3NldEFtb3VudAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAcJAAIBCQCsAgIJAKwCAgkArAICAg1MaW1pdCBlcnJvcjogCQCkAwEFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQCAyA8IAkApAMBBRRfbWluUXVvdGVBc3NldEFtb3VudAkAoQoPBQ9uZXdQb3NpdGlvblNpemUFEW5ld1Bvc2l0aW9uTWFyZ2luBRduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAUUbmV3UG9zaXRpb25Mc3RVcGRDUEYFD3Bvc2l0aW9uQmFkRGVidAULcmVhbGl6ZWRQbmwJAGUCBRJyZW1haW5NYXJnaW5CZWZvcmUJAGQCBRFuZXdQb3NpdGlvbk1hcmdpbgUSdW5yZWFsaXplZFBubEFmdGVyBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIJAGUCCQEVdG90YWxMb25nUG9zaXRpb25TaXplAAMJAGYCBQ9uZXdQb3NpdGlvblNpemUAAAkBA2FicwEFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQAACQBlAgkBFnRvdGFsU2hvcnRQb3NpdGlvblNpemUAAwkAZgIAAAUPbmV3UG9zaXRpb25TaXplCQEDYWJzAQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplAAAJAGUCCQEQb3BlbkludGVyZXN0TG9uZwADCQBmAgUPbmV3UG9zaXRpb25TaXplAAAFEW9wZW5Ob3Rpb25hbERlbHRhAAAJAGUCCQERb3BlbkludGVyZXN0U2hvcnQAAwkAZgIAAAUPbmV3UG9zaXRpb25TaXplBRFvcGVuTm90aW9uYWxEZWx0YQAAAwkAZgIFBV9zaXplCQEDYWJzAQUPb2xkUG9zaXRpb25TaXplCQACAQIgSW52YWxpZCBjbG9zZVBvc2l0aW9uIHBhcmFtZXRlcnMEDSR0MDcwOTQwNzEzNTkJARVpbnRlcm5hbENsb3NlUG9zaXRpb24CBQdfdHJhZGVyBgQZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAgFDSR0MDcwOTQwNzEzNTkCXzEED3Bvc2l0aW9uQmFkRGVidAgFDSR0MDcwOTQwNzEzNTkCXzIEC3JlYWxpemVkUG5sCAUNJHQwNzA5NDA3MTM1OQJfMwQNbWFyZ2luVG9WYXVsdAgFDSR0MDcwOTQwNzEzNTkCXzQEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA3MDk0MDcxMzU5Al81BBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA3MDk0MDcxMzU5Al82BBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNzA5NDA3MTM1OQJfNwQZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcggFDSR0MDcwOTQwNzEzNTkCXzgEAngyCAUNJHQwNzA5NDA3MTM1OQJfOQQOdG90YWxMb25nQWZ0ZXIIBQ0kdDA3MDk0MDcxMzU5A18xMAQPdG90YWxTaG9ydEFmdGVyCAUNJHQwNzA5NDA3MTM1OQNfMTEEGnRvdGFsTG9uZ09wZW5JbnRlcmVzdEFmdGVyCAUNJHQwNzA5NDA3MTM1OQNfMTIEG3RvdGFsU2hvcnRPcGVuSW50ZXJlc3RBZnRlcggFDSR0MDcwOTQwNzEzNTkDXzEzAwMJAQIhPQIFFF9taW5RdW90ZUFzc2V0QW1vdW50AAAJAGYCBRRfbWluUXVvdGVBc3NldEFtb3VudAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAcJAAIBCQCsAgIJAKwCAgkArAICAg1MaW1pdCBlcnJvcjogCQCkAwEFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQCAyA8IAkApAMBBRRfbWluUXVvdGVBc3NldEFtb3VudAkAoQoPAAAAAAAAAAAFD3Bvc2l0aW9uQmFkRGVidAULcmVhbGl6ZWRQbmwFDW1hcmdpblRvVmF1bHQFFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFFWJhc2VBc3NldFJlc2VydmVBZnRlcgUWdG90YWxQb3NpdGlvblNpemVBZnRlcgUZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgUOdG90YWxMb25nQWZ0ZXIFD3RvdGFsU2hvcnRBZnRlcgUadG90YWxMb25nT3BlbkludGVyZXN0QWZ0ZXIFG3RvdGFsU2hvcnRPcGVuSW50ZXJlc3RBZnRlcgQPbmV3UG9zaXRpb25TaXplCAUNJHQwNjY4Njk3MTk5OQJfMQQRbmV3UG9zaXRpb25NYXJnaW4IBQ0kdDA2Njg2OTcxOTk5Al8yBBduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDY2ODY5NzE5OTkCXzMEFG5ld1Bvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwNjY4Njk3MTk5OQJfNAQPcG9zaXRpb25CYWREZWJ0CAUNJHQwNjY4Njk3MTk5OQJfNQQLcmVhbGl6ZWRQbmwIBQ0kdDA2Njg2OTcxOTk5Al82BA1tYXJnaW5Ub1ZhdWx0CAUNJHQwNjY4Njk3MTk5OQJfNwQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDY2ODY5NzE5OTkCXzgEFWJhc2VBc3NldFJlc2VydmVBZnRlcggFDSR0MDY2ODY5NzE5OTkCXzkEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDA2Njg2OTcxOTk5A18xMAQZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcggFDSR0MDY2ODY5NzE5OTkDXzExBA50b3RhbExvbmdBZnRlcggFDSR0MDY2ODY5NzE5OTkDXzEyBA90b3RhbFNob3J0QWZ0ZXIIBQ0kdDA2Njg2OTcxOTk5A18xMwQadG90YWxMb25nT3BlbkludGVyZXN0QWZ0ZXIIBQ0kdDA2Njg2OTcxOTk5A18xNAQbdG90YWxTaG9ydE9wZW5JbnRlcmVzdEFmdGVyCAUNJHQwNjY4Njk3MTk5OQNfMTUDCQBmAgUPcG9zaXRpb25CYWREZWJ0AAAJAAIBAiZVbmFibGUgdG8gY2xvc2UgcG9zaXRpb24gd2l0aCBiYWQgZGVidAQOd2l0aGRyYXdBbW91bnQJAQNhYnMBBQ1tYXJnaW5Ub1ZhdWx0BAphbW1CYWxhbmNlCQBlAgkBCGNiYWxhbmNlAAUOd2l0aGRyYXdBbW91bnQEDSR0MDcyMjA4NzI0MTUDCQBmAgAABQphbW1CYWxhbmNlCQCUCgIAAAkBA2FicwEFCmFtbUJhbGFuY2UJAJQKAgUKYW1tQmFsYW5jZQAABA1hbW1OZXdCYWxhbmNlCAUNJHQwNzIyMDg3MjQxNQJfMQQDeDExCAUNJHQwNzIyMDg3MjQxNQJfMgQNJHQwNzI0MjI3MjQ3NgkBE2dldEJvcnJvd2VkQnlUcmFkZXIBBQdfdHJhZGVyBAhib3Jyb3dlZAgFDSR0MDcyNDIyNzI0NzYCXzEEB2Fzc2V0SWQIBQ0kdDA3MjQyMjcyNDc2Al8yBA0kdDA3MjQ5MTczMzUwAwkAZgIFCGJvcnJvd2VkAAADCQBnAgUOd2l0aGRyYXdBbW91bnQFCGJvcnJvd2VkBAdkb1JlcGF5CQD8BwQJARFjb2xsYXRlcmFsQWRkcmVzcwACBXJlcGF5CQDMCAIFB190cmFkZXIJAMwIAgUIYm9ycm93ZWQJAMwIAgUHYXNzZXRJZAUDbmlsBQNuaWwDCQAAAgUHZG9SZXBheQUHZG9SZXBheQkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFDl90cmFkZXJBZGRyZXNzBQhib3Jyb3dlZAkA2QQBBQdhc3NldElkBQNuaWwJAGUCBQ53aXRoZHJhd0Ftb3VudAUIYm9ycm93ZWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4ED3JlYWxpemVBbmRDbG9zZQkA/AcECQERY29sbGF0ZXJhbEFkZHJlc3MAAhhyZWFsaXplUGFydGlhbGx5QW5kQ2xvc2UJAMwIAgUHX3RyYWRlcgkAzAgCBQ53aXRoZHJhd0Ftb3VudAkAzAgCBQdhc3NldElkBQNuaWwFA25pbAMJAAACBQ9yZWFsaXplQW5kQ2xvc2UFD3JlYWxpemVBbmRDbG9zZQkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFDl90cmFkZXJBZGRyZXNzBQ53aXRoZHJhd0Ftb3VudAkA2QQBBQdhc3NldElkBQNuaWwAAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlAoCBQNuaWwFDndpdGhkcmF3QW1vdW50AwkAAAIFDSR0MDcyNDkxNzMzNTAFDSR0MDcyNDkxNzMzNTAEE3F1b3RlV2l0aGRyYXdBbW91bnQIBQ0kdDA3MjQ5MTczMzUwAl8yBBRzZW5kQ29sbGF0ZXJhbEFjdGlvbggFDSR0MDcyNDkxNzMzNTACXzEEB3Vuc3Rha2UDCQBmAgUTcXVvdGVXaXRoZHJhd0Ftb3VudAAABAd1bnN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAg53aXRoZHJhd0xvY2tlZAkAzAgCBRNxdW90ZVdpdGhkcmF3QW1vdW50BQNuaWwFA25pbAMJAAACBQd1bnN0YWtlBQd1bnN0YWtlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBQd1bnN0YWtlBQd1bnN0YWtlBA5ub3RpZnlOb3Rpb25hbAkA/AcECQEMbWluZXJBZGRyZXNzAAIObm90aWZ5Tm90aW9uYWwJAMwIAgUHX3RyYWRlcgkAzAgCAAAFA25pbAUDbmlsAwkAAAIFDm5vdGlmeU5vdGlvbmFsBQ5ub3RpZnlOb3Rpb25hbAkAzggCCQDOCAIJAM4IAgkAzggCAwkAAAIFD25ld1Bvc2l0aW9uU2l6ZQAACQEOZGVsZXRlUG9zaXRpb24BBQdfdHJhZGVyCQEOdXBkYXRlUG9zaXRpb24FBQdfdHJhZGVyBQ9uZXdQb3NpdGlvblNpemUFEW5ld1Bvc2l0aW9uTWFyZ2luBRduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAUUbmV3UG9zaXRpb25Mc3RVcGRDUEYJAQl1cGRhdGVBbW0IBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIFDnRvdGFsTG9uZ0FmdGVyBQ90b3RhbFNob3J0QWZ0ZXIFGnRvdGFsTG9uZ09wZW5JbnRlcmVzdEFmdGVyBRt0b3RhbFNob3J0T3BlbkludGVyZXN0QWZ0ZXIDCQBmAgUTcXVvdGVXaXRoZHJhd0Ftb3VudAAACQEId2l0aGRyYXcCBQ5fdHJhZGVyQWRkcmVzcwUTcXVvdGVXaXRoZHJhd0Ftb3VudAUDbmlsCQENdXBkYXRlQmFsYW5jZQEFDWFtbU5ld0JhbGFuY2UFFHNlbmRDb2xsYXRlcmFsQWN0aW9uCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCWxpcXVpZGF0ZQEHX3RyYWRlcgQEc3luYwkA/AcEBQR0aGlzAhlzeW5jVGVybWluYWxQcmljZVRvT3JhY2xlBQNuaWwFA25pbAMJAAACBQRzeW5jBQRzeW5jBA9zcG90TWFyZ2luUmF0aW8JARZnZXRNYXJnaW5SYXRpb0J5T3B0aW9uAgUHX3RyYWRlcgUPUE5MX09QVElPTl9TUE9UBAttYXJnaW5SYXRpbwMJARZpc092ZXJGbHVjdHVhdGlvbkxpbWl0AAQRb3JhY2xlTWFyZ2luUmF0aW8JARZnZXRNYXJnaW5SYXRpb0J5T3B0aW9uAgUHX3RyYWRlcgURUE5MX09QVElPTl9PUkFDTEUJAQR2bWF4AgUPc3BvdE1hcmdpblJhdGlvBRFvcmFjbGVNYXJnaW5SYXRpbwUPc3BvdE1hcmdpblJhdGlvAwMDAwMJAQEhAQkBFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8DBQttYXJnaW5SYXRpbwkBFm1haW50ZW5hbmNlTWFyZ2luUmF0aW8ABwYJAQEhAQkBE3JlcXVpcmVPcGVuUG9zaXRpb24BBQdfdHJhZGVyBgkBASEBCQELaW5pdGlhbGl6ZWQABgkBBnBhdXNlZAAGCQEOaXNNYXJrZXRDbG9zZWQACQACAQITVW5hYmxlIHRvIGxpcXVpZGF0ZQMDAwkAZgIFD3Nwb3RNYXJnaW5SYXRpbwkBE2xpcXVpZGF0aW9uRmVlUmF0aW8ACQBmAgkBF3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAAAABwkAZgIFDERFQ0lNQUxfVU5JVAkBF3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAAcEDSR0MDc1NjcxNzU4MjEJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIED29sZFBvc2l0aW9uU2l6ZQgFDSR0MDc1NjcxNzU4MjECXzEEEW9sZFBvc2l0aW9uTWFyZ2luCAUNJHQwNzU2NzE3NTgyMQJfMgQXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDA3NTY3MTc1ODIxAl8zBBRvbGRQb3NpdGlvbkxzdFVwZENQRggFDSR0MDc1NjcxNzU4MjECXzQECl9kaXJlY3Rpb24DCQBmAgUPb2xkUG9zaXRpb25TaXplAAAFCURJUl9TSE9SVAUIRElSX0xPTkcEBWlzQWRkCQAAAgUKX2RpcmVjdGlvbgUIRElSX0xPTkcEGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQJARtnZXRQYXJ0aWFsTGlxdWlkYXRpb25BbW91bnQCBQdfdHJhZGVyBQ9vbGRQb3NpdGlvblNpemUEDSR0MDc2MDQ2NzYxNTAJASNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAIFB190cmFkZXIFD1BOTF9PUFRJT05fU1BPVAQTb2xkUG9zaXRpb25Ob3Rpb25hbAgFDSR0MDc2MDQ2NzYxNTACXzEEDXVucmVhbGl6ZWRQbmwIBQ0kdDA3NjA0Njc2MTUwAl8yBA0kdDA3NjE1ODc2MzQ1CQEJc3dhcElucHV0AgUFaXNBZGQFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQEFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQgFDSR0MDc2MTU4NzYzNDUCXzEEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA3NjE1ODc2MzQ1Al8yBBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA3NjE1ODc2MzQ1Al8zBBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNzYxNTg3NjM0NQJfNAQQbGlxdWlkYXRpb25SYXRpbwkBBGRpdmQCCQEDYWJzAQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplCQEDYWJzAQUPb2xkUG9zaXRpb25TaXplBAtyZWFsaXplZFBubAkBBG11bGQCBQ11bnJlYWxpemVkUG5sBRBsaXF1aWRhdGlvblJhdGlvBA0kdDA3NjYzNDc2ODY3CQEiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAQFD29sZFBvc2l0aW9uU2l6ZQURb2xkUG9zaXRpb25NYXJnaW4FFG9sZFBvc2l0aW9uTHN0VXBkQ1BGBQtyZWFsaXplZFBubAQMcmVtYWluTWFyZ2luCAUNJHQwNzY2MzQ3Njg2NwJfMQQHYmFkRGVidAgFDSR0MDc2NjM0NzY4NjcCXzIEDmZ1bmRpbmdQYXltZW50CAUNJHQwNzY2MzQ3Njg2NwJfMwQSdW5yZWFsaXplZFBubEFmdGVyCQBlAgUNdW5yZWFsaXplZFBubAULcmVhbGl6ZWRQbmwEEnJlbWFpbk9wZW5Ob3Rpb25hbAMJAGYCBQ9vbGRQb3NpdGlvblNpemUAAAkAZQIJAGUCBRNvbGRQb3NpdGlvbk5vdGlvbmFsBRlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50BRJ1bnJlYWxpemVkUG5sQWZ0ZXIJAGUCCQBkAgUSdW5yZWFsaXplZFBubEFmdGVyBRNvbGRQb3NpdGlvbk5vdGlvbmFsBRlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50BBJsaXF1aWRhdGlvblBlbmFsdHkJAQRtdWxkAgUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAkBE2xpcXVpZGF0aW9uRmVlUmF0aW8ABA9mZWVUb0xpcXVpZGF0b3IJAGkCBRJsaXF1aWRhdGlvblBlbmFsdHkAAgQKZmVlVG9WYXVsdAkAZQIFEmxpcXVpZGF0aW9uUGVuYWx0eQUPZmVlVG9MaXF1aWRhdG9yBBFuZXdQb3NpdGlvbk1hcmdpbgkAZQIFDHJlbWFpbk1hcmdpbgUSbGlxdWlkYXRpb25QZW5hbHR5BA9uZXdQb3NpdGlvblNpemUJAGQCBQ9vbGRQb3NpdGlvblNpemUFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQQXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwJAQNhYnMBBRJyZW1haW5PcGVuTm90aW9uYWwEEW9wZW5Ob3Rpb25hbERlbHRhCQBlAgUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwFF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsBBRuZXdQb3NpdGlvbkxzdFVwZENQRgkBH2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24BBQ9uZXdQb3NpdGlvblNpemUEGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIJAGUCCQEUb3BlbkludGVyZXN0Tm90aW9uYWwABRFvcGVuTm90aW9uYWxEZWx0YQQKYW1tQmFsYW5jZQkAZQIJAQhjYmFsYW5jZQAFEmxpcXVpZGF0aW9uUGVuYWx0eQQNJHQwNzgxMDg3ODIzNwMJAGYCAAAFCmFtbUJhbGFuY2UJAJQKAgAACQEDYWJzAQUKYW1tQmFsYW5jZQkAlAoCBQphbW1CYWxhbmNlAAAEDW5ld0FtbUJhbGFuY2UIBQ0kdDA3ODEwODc4MjM3Al8xBAN4MTEIBQ0kdDA3ODEwODc4MjM3Al8yBA0kdDA3ODI0NTc4Mjk5CQETZ2V0Qm9ycm93ZWRCeVRyYWRlcgEFB190cmFkZXIECGJvcnJvd2VkCAUNJHQwNzgyNDU3ODI5OQJfMQQHYXNzZXRJZAgFDSR0MDc4MjQ1NzgyOTkCXzIEFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAMJAGYCBQhib3Jyb3dlZAAABBBjb2xsYXRlcmFsVG9TZWxsCQEEbXVsZAIFCGJvcnJvd2VkBRBsaXF1aWRhdGlvblJhdGlvBA9yZWFsaXplQW5kQ2xvc2UJAPwHBAkBEWNvbGxhdGVyYWxBZGRyZXNzAAIQcmVhbGl6ZVBhcnRpYWxseQkAzAgCBQdfdHJhZGVyCQDMCAIFB2Fzc2V0SWQJAMwIAgUQY29sbGF0ZXJhbFRvU2VsbAUDbmlsBQNuaWwDCQAAAgUPcmVhbGl6ZUFuZENsb3NlBQ9yZWFsaXplQW5kQ2xvc2UFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAwkAAAIFFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAUVZG9MaXF1aWRhdGVDb2xsYXRlcmFsBAd1bnN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAg53aXRoZHJhd0xvY2tlZAkAzAgCBRJsaXF1aWRhdGlvblBlbmFsdHkFA25pbAUDbmlsAwkAAAIFB3Vuc3Rha2UFB3Vuc3Rha2UEEGRlcG9zaXRJbnN1cmFuY2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACB2FkZEZyZWUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQpmZWVUb1ZhdWx0BQNuaWwDCQAAAgUQZGVwb3NpdEluc3VyYW5jZQUQZGVwb3NpdEluc3VyYW5jZQQObm90aWZ5Tm90aW9uYWwJAPwHBAkBDG1pbmVyQWRkcmVzcwACDm5vdGlmeU5vdGlvbmFsCQDMCAIFB190cmFkZXIJAMwIAgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFA25pbAUDbmlsAwkAAAIFDm5vdGlmeU5vdGlvbmFsBQ5ub3RpZnlOb3Rpb25hbAkAzggCCQDOCAIJAM4IAgkBDnVwZGF0ZVBvc2l0aW9uBQUHX3RyYWRlcgUPbmV3UG9zaXRpb25TaXplBRFuZXdQb3NpdGlvbk1hcmdpbgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFFG5ld1Bvc2l0aW9uTHN0VXBkQ1BGCQEJdXBkYXRlQW1tCAUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBRZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBRlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCQBlAgkBFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQADCQBmAgUPbmV3UG9zaXRpb25TaXplAAAJAQNhYnMBBRVleGNoYW5nZWRQb3NpdGlvblNpemUAAAkAZQIJARZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAMJAGYCAAAFD25ld1Bvc2l0aW9uU2l6ZQkBA2FicwEFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQAACQBlAgkBEG9wZW5JbnRlcmVzdExvbmcAAwkAZgIFD25ld1Bvc2l0aW9uU2l6ZQAABRFvcGVuTm90aW9uYWxEZWx0YQAACQBlAgkBEW9wZW5JbnRlcmVzdFNob3J0AAMJAGYCAAAFD25ld1Bvc2l0aW9uU2l6ZQURb3Blbk5vdGlvbmFsRGVsdGEAAAkBCHdpdGhkcmF3AggFAWkGY2FsbGVyBQ9mZWVUb0xpcXVpZGF0b3IJAQ11cGRhdGVCYWxhbmNlAQUNbmV3QW1tQmFsYW5jZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQNJHQwNzk5Nzg4MDQ3MwkBFWludGVybmFsQ2xvc2VQb3NpdGlvbgIFB190cmFkZXIHBAJ4MQgFDSR0MDc5OTc4ODA0NzMCXzEEB2JhZERlYnQIBQ0kdDA3OTk3ODgwNDczAl8yBAJ4MggFDSR0MDc5OTc4ODA0NzMCXzMEAngzCAUNJHQwNzk5Nzg4MDQ3MwJfNAQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDc5OTc4ODA0NzMCXzUEFWJhc2VBc3NldFJlc2VydmVBZnRlcggFDSR0MDc5OTc4ODA0NzMCXzYEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDA3OTk3ODgwNDczAl83BBlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCAUNJHQwNzk5Nzg4MDQ3MwJfOAQZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAgFDSR0MDc5OTc4ODA0NzMCXzkEDnRvdGFsTG9uZ0FmdGVyCAUNJHQwNzk5Nzg4MDQ3MwNfMTAED3RvdGFsU2hvcnRBZnRlcggFDSR0MDc5OTc4ODA0NzMDXzExBBp0b3RhbExvbmdPcGVuSW50ZXJlc3RBZnRlcggFDSR0MDc5OTc4ODA0NzMDXzEyBBt0b3RhbFNob3J0T3BlbkludGVyZXN0QWZ0ZXIIBQ0kdDA3OTk3ODgwNDczA18xMwQSbGlxdWlkYXRpb25QZW5hbHR5CQEEbXVsZAIFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQJARNsaXF1aWRhdGlvbkZlZVJhdGlvAAQPZmVlVG9MaXF1aWRhdG9yCQBpAgUSbGlxdWlkYXRpb25QZW5hbHR5AAIECmZlZVRvVmF1bHQJAGUCBRJsaXF1aWRhdGlvblBlbmFsdHkFD2ZlZVRvTGlxdWlkYXRvcgQKYW1tQmFsYW5jZQkAZQIJAQhjYmFsYW5jZQAFEmxpcXVpZGF0aW9uUGVuYWx0eQQNJHQwODA4ODE4MTAxMAMJAGYCAAAFCmFtbUJhbGFuY2UJAJQKAgAACQEDYWJzAQUKYW1tQmFsYW5jZQkAlAoCBQphbW1CYWxhbmNlAAAEDW5ld0FtbUJhbGFuY2UIBQ0kdDA4MDg4MTgxMDEwAl8xBAN4MTEIBQ0kdDA4MDg4MTgxMDEwAl8yBA0kdDA4MTAxODgxMDcyCQETZ2V0Qm9ycm93ZWRCeVRyYWRlcgEFB190cmFkZXIECGJvcnJvd2VkCAUNJHQwODEwMTg4MTA3MgJfMQQHYXNzZXRJZAgFDSR0MDgxMDE4ODEwNzICXzIEFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAMJAGYCBQhib3Jyb3dlZAAABA9yZWFsaXplQW5kQ2xvc2UJAPwHBAkBEWNvbGxhdGVyYWxBZGRyZXNzAAIYcmVhbGl6ZVBhcnRpYWxseUFuZENsb3NlCQDMCAIFB190cmFkZXIJAMwIAgAACQDMCAIFB2Fzc2V0SWQFA25pbAUDbmlsAwkAAAIFD3JlYWxpemVBbmRDbG9zZQUPcmVhbGl6ZUFuZENsb3NlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBRVkb0xpcXVpZGF0ZUNvbGxhdGVyYWwFFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAQBeAMJAGYCBQdiYWREZWJ0AAAEC2xvY2tCYWREZWJ0CQD8BwQJAQx2YXVsdEFkZHJlc3MAAhVleGNoYW5nZUZyZWVBbmRMb2NrZWQJAMwIAgUHYmFkRGVidAUDbmlsBQNuaWwDCQAAAgULbG9ja0JhZERlYnQFC2xvY2tCYWREZWJ0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBQF4BQF4BAd1bnN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAg53aXRoZHJhd0xvY2tlZAkAzAgCBRJsaXF1aWRhdGlvblBlbmFsdHkFA25pbAUDbmlsAwkAAAIFB3Vuc3Rha2UFB3Vuc3Rha2UEEGRlcG9zaXRJbnN1cmFuY2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACB2FkZEZyZWUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQpmZWVUb1ZhdWx0BQNuaWwDCQAAAgUQZGVwb3NpdEluc3VyYW5jZQUQZGVwb3NpdEluc3VyYW5jZQQObm90aWZ5Tm90aW9uYWwJAPwHBAkBDG1pbmVyQWRkcmVzcwACDm5vdGlmeU5vdGlvbmFsCQDMCAIFB190cmFkZXIJAMwIAgAABQNuaWwFA25pbAMJAAACBQ5ub3RpZnlOb3Rpb25hbAUObm90aWZ5Tm90aW9uYWwJAM4IAgkAzggCCQDOCAIJAQ5kZWxldGVQb3NpdGlvbgEFB190cmFkZXIJAQl1cGRhdGVBbW0IBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIFDnRvdGFsTG9uZ0FmdGVyBQ90b3RhbFNob3J0QWZ0ZXIFGnRvdGFsTG9uZ09wZW5JbnRlcmVzdEFmdGVyBRt0b3RhbFNob3J0T3BlbkludGVyZXN0QWZ0ZXIJAQh3aXRoZHJhdwIIBQFpBmNhbGxlcgUPZmVlVG9MaXF1aWRhdG9yCQENdXBkYXRlQmFsYW5jZQEFDW5ld0FtbUJhbGFuY2UJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKcGF5RnVuZGluZwAEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQVZnVuZGluZ0Jsb2NrVGltZXN0YW1wCQEZbmV4dEZ1bmRpbmdCbG9ja1RpbWVzdGFtcAADAwMJAGYCBRVmdW5kaW5nQmxvY2tUaW1lc3RhbXAIBQlsYXN0QmxvY2sJdGltZXN0YW1wBgkBASEBCQELaW5pdGlhbGl6ZWQABgkBBnBhdXNlZAAJAAIBCQCsAgIJAKwCAgkArAICAiFJbnZhbGlkIGZ1bmRpbmcgYmxvY2sgdGltZXN0YW1wOiAJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXACAyA8IAkApAMBBRVmdW5kaW5nQmxvY2tUaW1lc3RhbXAED3VuZGVybHlpbmdQcmljZQkBDmdldE9yYWNsZVByaWNlAAQNJHQwODI5NDQ4MzAwNgkBCmdldEZ1bmRpbmcABBRzaG9ydFByZW1pdW1GcmFjdGlvbggFDSR0MDgyOTQ0ODMwMDYCXzEEE2xvbmdQcmVtaXVtRnJhY3Rpb24IBQ0kdDA4Mjk0NDgzMDA2Al8yCQENdXBkYXRlRnVuZGluZwUJAGQCBRVmdW5kaW5nQmxvY2tUaW1lc3RhbXAJARRmdW5kaW5nUGVyaW9kU2Vjb25kcwAJAGQCCQEjbGF0ZXN0TG9uZ0N1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24ABRNsb25nUHJlbWl1bUZyYWN0aW9uCQBkAgkBJGxhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAFFHNob3J0UHJlbWl1bUZyYWN0aW9uCQEEZGl2ZAIFE2xvbmdQcmVtaXVtRnJhY3Rpb24FD3VuZGVybHlpbmdQcmljZQkBBGRpdmQCBRRzaG9ydFByZW1pdW1GcmFjdGlvbgUPdW5kZXJseWluZ1ByaWNlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBGXN5bmNUZXJtaW5hbFByaWNlVG9PcmFjbGUABAdfcXRBc3RSCQEGcXRBc3RSAAQHX2JzQXN0UgkBBmJzQXN0UgAEDSR0MDgzNDM4ODM1NzMJARRnZXRTeW5jVGVybWluYWxQcmljZQMJAQ5nZXRPcmFjbGVQcmljZQAFB19xdEFzdFIFB19ic0FzdFIEE25ld1F1b3RlQXNzZXRXZWlnaHQIBQ0kdDA4MzQzODgzNTczAl8xBBJuZXdCYXNlQXNzZXRXZWlnaHQIBQ0kdDA4MzQzODgzNTczAl8yBA1tYXJnaW5Ub1ZhdWx0CAUNJHQwODM0Mzg4MzU3MwJfMwQNZG9FeGNoYW5nZVBuTAMJAQIhPQIFDW1hcmdpblRvVmF1bHQAAAQNZG9FeGNoYW5nZVBuTAkA/AcECQEMdmF1bHRBZGRyZXNzAAIVZXhjaGFuZ2VGcmVlQW5kTG9ja2VkCQDMCAIFDW1hcmdpblRvVmF1bHQFA25pbAUDbmlsAwkAAAIFDWRvRXhjaGFuZ2VQbkwFDWRvRXhjaGFuZ2VQbkwFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAwkAAAIFDWRvRXhjaGFuZ2VQbkwFDWRvRXhjaGFuZ2VQbkwJAM4IAgkBEHVwZGF0ZUFtbVdlaWdodHMCBRNuZXdRdW90ZUFzc2V0V2VpZ2h0BRJuZXdCYXNlQXNzZXRXZWlnaHQJAQphcHBlbmRUd2FwAQkBBGRpdmQCCQEEbXVsZAIFB19xdEFzdFIFE25ld1F1b3RlQXNzZXRXZWlnaHQJAQRtdWxkAgUHX2JzQXN0UgUSbmV3QmFzZUFzc2V0V2VpZ2h0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBJ3ZpZXdfY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAEHX3RyYWRlcgQEc3luYwkA/AcEBQR0aGlzAhlzeW5jVGVybWluYWxQcmljZVRvT3JhY2xlBQNuaWwFA25pbAMJAAACBQRzeW5jBQRzeW5jBA0kdDA4NDE0Mjg0MjQzCQELZ2V0UG9zaXRpb24BBQdfdHJhZGVyBAxwb3NpdGlvblNpemUIBQ0kdDA4NDE0Mjg0MjQzAl8xBA5wb3NpdGlvbk1hcmdpbggFDSR0MDg0MTQyODQyNDMCXzIEA3BvbggFDSR0MDg0MTQyODQyNDMCXzMEEXBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwODQxNDI4NDI0MwJfNAQNJHQwODQyNDY4NDM0NwkBI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAgUHX3RyYWRlcgUPUE5MX09QVElPTl9TUE9UBBBwb3NpdGlvbk5vdGlvbmFsCAUNJHQwODQyNDY4NDM0NwJfMQQNdW5yZWFsaXplZFBubAgFDSR0MDg0MjQ2ODQzNDcCXzIEDSR0MDg0MzUwODQ1MjIJASJjYWxjUmVtYWluTWFyZ2luV2l0aEZ1bmRpbmdQYXltZW50BAUMcG9zaXRpb25TaXplBQ5wb3NpdGlvbk1hcmdpbgURcG9zaXRpb25Mc3RVcGRDUEYFDXVucmVhbGl6ZWRQbmwEDHJlbWFpbk1hcmdpbggFDSR0MDg0MzUwODQ1MjICXzEEB2JhZERlYnQIBQ0kdDA4NDM1MDg0NTIyAl8yBA5mdW5kaW5nUGF5bWVudAgFDSR0MDg0MzUwODQ1MjICXzMJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkBAXMBBQxyZW1haW5NYXJnaW4JAQFzAQUOZnVuZGluZ1BheW1lbnQJAQFzAQkBDmdldE1hcmdpblJhdGlvAQUHX3RyYWRlcgkBAXMBBQ11bnJlYWxpemVkUG5sCQEBcwEFB2JhZERlYnQJAQFzAQUQcG9zaXRpb25Ob3Rpb25hbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARV2aWV3X2dldFBlZ0FkanVzdENvc3QBBl9wcmljZQQHX3F0QXN0UgkBBnF0QXN0UgAEB19ic0FzdFIJAQZic0FzdFIABAZyZXN1bHQJARRnZXRTeW5jVGVybWluYWxQcmljZQMFBl9wcmljZQUHX3F0QXN0UgUHX2JzQXN0UgkAAgEJAKQDAQgFBnJlc3VsdAJfMwFpARh2aWV3X2dldFRlcm1pbmFsQW1tUHJpY2UABA0kdDA4NDkzODg1MDE5CQETZ2V0VGVybWluYWxBbW1TdGF0ZQAEGXRlcm1pbmFsUXVvdGVBc3NldFJlc2VydmUIBQ0kdDA4NDkzODg1MDE5Al8xBBh0ZXJtaW5hbEJhc2VBc3NldFJlc2VydmUIBQ0kdDA4NDkzODg1MDE5Al8yBAVwcmljZQkBBGRpdmQCCQEEbXVsZAIFGXRlcm1pbmFsUXVvdGVBc3NldFJlc2VydmUJAQZxdEFzdFcACQEEbXVsZAIFGHRlcm1pbmFsQmFzZUFzc2V0UmVzZXJ2ZQkBBmJzQXN0VwAJAAIBCQCkAwEFBXByaWNlAWkBD3ZpZXdfZ2V0RnVuZGluZwAED3VuZGVybHlpbmdQcmljZQkBDmdldE9yYWNsZVByaWNlAAQNJHQwODUyMzQ4NTI5NgkBCmdldEZ1bmRpbmcABBRzaG9ydFByZW1pdW1GcmFjdGlvbggFDSR0MDg1MjM0ODUyOTYCXzEEE2xvbmdQcmVtaXVtRnJhY3Rpb24IBQ0kdDA4NTIzNDg1Mjk2Al8yBAtsb25nRnVuZGluZwkBBGRpdmQCBRNsb25nUHJlbWl1bUZyYWN0aW9uBQ91bmRlcmx5aW5nUHJpY2UEDHNob3J0RnVuZGluZwkBBGRpdmQCBRRzaG9ydFByZW1pdW1GcmFjdGlvbgUPdW5kZXJseWluZ1ByaWNlCQACAQkArAICCQCsAgIJAKwCAgkBAXMBBQtsb25nRnVuZGluZwkBAXMBBQxzaG9ydEZ1bmRpbmcJAQFzAQkBEGdldFR3YXBTcG90UHJpY2UACQEBcwEJAQ5nZXRPcmFjbGVQcmljZQABaQEYdmlld19nZXRCb3Jyb3dlZEJ5VHJhZGVyAQdfdHJhZGVyBA0kdDA4NTU4Mjg1NjM2CQETZ2V0Qm9ycm93ZWRCeVRyYWRlcgEFB190cmFkZXIECGJvcnJvd2VkCAUNJHQwODU1ODI4NTYzNgJfMQQHYXNzZXRJZAgFDSR0MDg1NTgyODU2MzYCXzIJAAIBCQCsAgIJAQFzAQUIYm9ycm93ZWQFB2Fzc2V0SWQBaQEQY29tcHV0ZVNwb3RQcmljZQAEBnJlc3VsdAkBDGdldFNwb3RQcmljZQAJAJQKAgUDbmlsBQZyZXN1bHQBaQEfY29tcHV0ZUZlZUZvclRyYWRlcldpdGhBcnRpZmFjdAIHX3RyYWRlcgtfYXJ0aWZhY3RJZAQGcmVzdWx0CQEYZ2V0Rm9yVHJhZGVyV2l0aEFydGlmYWN0AgUHX3RyYWRlcgULX2FydGlmYWN0SWQJAJQKAgUDbmlsBQZyZXN1bHQBAnR4AQZ2ZXJpZnkACQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACQEOYWRtaW5QdWJsaWNLZXkAvswaUQ==", "height": 2394768, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: F7Fmc9ZzKXaZG2poZBc1ofzf5Ai72Ed7G3ciscLJYtui Next: B9tMwGkBe2tBYWSY9jaYtBX9R2RjNpbJHBiaHTDeNY75 Diff:
OldNewDifferences
448448 }
449449
450450
451-func calcInvariant (_qtAstR,_qtAstW,_bsAstR,_bsAstW) = {
451+func calcInvariant (_qtAstR,_bsAstR) = {
452452 let bqtAstR = toBigInt(_qtAstR)
453- let bqtAstW = toBigInt(_qtAstW)
454453 let bbsAstR = toBigInt(_bsAstR)
455- let bbsAstW = toBigInt(_bsAstW)
456- bmuld(bmuld(bqtAstR, bqtAstW), bmuld(bbsAstR, bbsAstW))
454+ bmuld(bqtAstR, bbsAstR)
457455 }
458456
459457
462460 let _bsAstR = bsAstR()
463461 let _qtAstW = qtAstW()
464462 let _bsAstW = bsAstW()
465- let k = calcInvariant(_qtAstR, _qtAstW, _bsAstR, _bsAstW)
463+ let quoteAssetAmountAdjusted = divd(_quoteAssetAmount, _qtAstW)
464+ let k = calcInvariant(_qtAstR, _bsAstR)
466465 let quoteAssetReserveAfter = if (_isAdd)
467- then (_qtAstR + _quoteAssetAmount)
468- else (_qtAstR - _quoteAssetAmount)
469- let baseAssetReserveAfter = toInt(bdivd(k, toBigInt(muld(quoteAssetReserveAfter, _qtAstW))))
470- let amountBaseAssetBoughtAbs = divd(abs((baseAssetReserveAfter - _bsAstR)), _qtAstW)
466+ then (_qtAstR + quoteAssetAmountAdjusted)
467+ else (_qtAstR - quoteAssetAmountAdjusted)
468+ let baseAssetReserveAfter = toInt(bdivd(k, toBigInt(quoteAssetReserveAfter)))
469+ let amountBaseAssetBoughtAbs = abs((baseAssetReserveAfter - _bsAstR))
471470 let amountBaseAssetBought = if (_isAdd)
472471 then amountBaseAssetBoughtAbs
473472 else -(amountBaseAssetBoughtAbs)
474- let $t01693717100 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
475- let quoteAssetReserveAfter1 = $t01693717100._1
476- let baseAssetReserveAfter1 = $t01693717100._2
477- let totalPositionSizeAfter1 = $t01693717100._3
473+ let $t01684317013 = updateReserve(_isAdd, quoteAssetAmountAdjusted, amountBaseAssetBoughtAbs)
474+ let quoteAssetReserveAfter1 = $t01684317013._1
475+ let baseAssetReserveAfter1 = $t01684317013._2
476+ let totalPositionSizeAfter1 = $t01684317013._3
478477 let priceBefore = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
479478 let marketPrice = divd(_quoteAssetAmount, amountBaseAssetBoughtAbs)
480479 let priceDiff = abs((priceBefore - marketPrice))
494493 }
495494 else 0
496495 let signedMargin = ((_marginDelta - fundingPayment) + _oldPositionMargin)
497- let $t01858718714 = if ((0 > signedMargin))
496+ let $t01850018627 = if ((0 > signedMargin))
498497 then $Tuple2(0, abs(signedMargin))
499498 else $Tuple2(abs(signedMargin), 0)
500- let remainMargin = $t01858718714._1
501- let badDebt = $t01858718714._2
499+ let remainMargin = $t01850018627._1
500+ let badDebt = $t01850018627._2
502501 $Tuple3(remainMargin, badDebt, fundingPayment)
503502 }
504503
508507 if ((_baseAssetAmount == 0))
509508 then throw("Invalid base asset amount")
510509 else {
511- let k = calcInvariant(_quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
510+ let k = calcInvariant(_quoteAssetReserve, _baseAssetReserve)
512511 let baseAssetPoolAmountAfter = if (_isAdd)
513512 then (_baseAssetReserve + _baseAssetAmount)
514513 else (_baseAssetReserve - _baseAssetAmount)
515- let quoteAssetAfter = toInt(bdivd(k, toBigInt(muld(baseAssetPoolAmountAfter, _baseAssetWeight))))
516- let quoteAssetSold = abs((quoteAssetAfter - muld(_quoteAssetReserve, _quoteAssetWeight)))
514+ let quoteAssetAfter = toInt(bdivd(k, toBigInt(baseAssetPoolAmountAfter)))
515+ let quoteAssetDelta = abs((quoteAssetAfter - _quoteAssetReserve))
516+ let quoteAssetSold = muld(quoteAssetDelta, _quoteAssetWeight)
517517 let maxPriceImpactValue = maxPriceImpact()
518- let $t01990220063 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
519- let quoteAssetReserveAfter1 = $t01990220063._1
520- let baseAssetReserveAfter1 = $t01990220063._2
521- let totalPositionSizeAfter1 = $t01990220063._3
518+ let $t01979719959 = updateReserve(!(_isAdd), quoteAssetDelta, _baseAssetAmount)
519+ let quoteAssetReserveAfter1 = $t01979719959._1
520+ let baseAssetReserveAfter1 = $t01979719959._2
521+ let totalPositionSizeAfter1 = $t01979719959._3
522522 let marketPrice = divd(quoteAssetSold, _baseAssetAmount)
523523 let priceDiff = abs((priceBefore - marketPrice))
524524 let priceImpact = (DECIMAL_UNIT - divd(priceBefore, (priceBefore + priceDiff)))
620620 let isShort = (0 > _positionSize)
621621 let positionNotional = if ((_option == PNL_OPTION_SPOT))
622622 then {
623- let $t02501425234 = swapOutputWithReserves(!(isShort), positionSizeAbs, false, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
624- let outPositionNotional = $t02501425234._1
625- let x1 = $t02501425234._2
626- let x2 = $t02501425234._3
627- let x3 = $t02501425234._4
623+ let $t02491025130 = swapOutputWithReserves(!(isShort), positionSizeAbs, false, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
624+ let outPositionNotional = $t02491025130._1
625+ let x1 = $t02491025130._2
626+ let x2 = $t02491025130._3
627+ let x3 = $t02491025130._4
628628 outPositionNotional
629629 }
630630 else muld(positionSizeAbs, getOraclePrice())
645645
646646
647647 func getPositionNotionalAndUnrealizedPnl (_trader,_option) = {
648- let $t02665526783 = getPosition(_trader)
649- let positionSize = $t02665526783._1
650- let positionMargin = $t02665526783._2
651- let positionOpenNotional = $t02665526783._3
652- let positionLstUpdCPF = $t02665526783._4
648+ let $t02655126679 = getPosition(_trader)
649+ let positionSize = $t02655126679._1
650+ let positionMargin = $t02655126679._2
651+ let positionOpenNotional = $t02655126679._3
652+ let positionLstUpdCPF = $t02655126679._4
653653 getPositionNotionalAndUnrealizedPnlByValues(positionSize, positionOpenNotional, qtAstR(), qtAstW(), bsAstR(), bsAstW(), _option)
654654 }
655655
658658
659659
660660 func getMarginRatioByOption (_trader,_option) = {
661- let $t02729627407 = getPosition(_trader)
662- let positionSize = $t02729627407._1
663- let positionMargin = $t02729627407._2
664- let pon = $t02729627407._3
665- let positionLstUpdCPF = $t02729627407._4
666- let $t02741327506 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
667- let positionNotional = $t02741327506._1
668- let unrealizedPnl = $t02741327506._2
669- let $t02751127677 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
670- let remainMargin = $t02751127677._1
671- let badDebt = $t02751127677._2
661+ let $t02719227303 = getPosition(_trader)
662+ let positionSize = $t02719227303._1
663+ let positionMargin = $t02719227303._2
664+ let pon = $t02719227303._3
665+ let positionLstUpdCPF = $t02719227303._4
666+ let $t02730927402 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
667+ let positionNotional = $t02730927402._1
668+ let unrealizedPnl = $t02730927402._2
669+ let $t02740727573 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
670+ let remainMargin = $t02740727573._1
671+ let badDebt = $t02740727573._2
672672 calcMarginRatio(remainMargin, badDebt, positionNotional)
673673 }
674674
693693
694694
695695 func internalClosePosition (_trader,_checkMaxPriceImpact) = {
696- let $t02891729045 = getPosition(_trader)
697- let positionSize = $t02891729045._1
698- let positionMargin = $t02891729045._2
699- let positionOpenNotional = $t02891729045._3
700- let positionLstUpdCPF = $t02891729045._4
696+ let $t02881328941 = getPosition(_trader)
697+ let positionSize = $t02881328941._1
698+ let positionMargin = $t02881328941._2
699+ let positionOpenNotional = $t02881328941._3
700+ let positionLstUpdCPF = $t02881328941._4
701701 let unrealizedPnl = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)._2
702- let $t02914029308 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
703- let remainMargin = $t02914029308._1
704- let badDebt = $t02914029308._2
702+ let $t02903629204 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
703+ let remainMargin = $t02903629204._1
704+ let badDebt = $t02903629204._2
705705 let exchangedPositionSize = -(positionSize)
706706 let realizedPnl = unrealizedPnl
707707 let marginToVault = -(remainMargin)
708- let $t02943529709 = swapOutput((positionSize > 0), abs(positionSize), _checkMaxPriceImpact)
709- let exchangedQuoteAssetAmount = $t02943529709._1
710- let quoteAssetReserveAfter = $t02943529709._2
711- let baseAssetReserveAfter = $t02943529709._3
712- let totalPositionSizeAfter = $t02943529709._4
713- let totalLongAfter = $t02943529709._5
714- let totalShortAfter = $t02943529709._6
708+ let $t02933129605 = swapOutput((positionSize > 0), abs(positionSize), _checkMaxPriceImpact)
709+ let exchangedQuoteAssetAmount = $t02933129605._1
710+ let quoteAssetReserveAfter = $t02933129605._2
711+ let baseAssetReserveAfter = $t02933129605._3
712+ let totalPositionSizeAfter = $t02933129605._4
713+ let totalLongAfter = $t02933129605._5
714+ let totalShortAfter = $t02933129605._6
715715 let openInterestNotionalAfter = (openInterestNotional() - positionOpenNotional)
716716 $Tuple13(exchangedPositionSize, badDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, exchangedQuoteAssetAmount, totalLongAfter, totalShortAfter, (openInterestLong() - (if ((positionSize > 0))
717717 then positionOpenNotional
764764 then $Tuple2(qtAstR(), bsAstR())
765765 else {
766766 let direction = (_positionSize > 0)
767- let $t03183232011 = swapOutput(direction, abs(_positionSize), false)
768- let currentNetMarketValue = $t03183232011._1
769- let terminalQuoteAssetReserve = $t03183232011._2
770- let terminalBaseAssetReserve = $t03183232011._3
767+ let $t03172831907 = swapOutput(direction, abs(_positionSize), false)
768+ let currentNetMarketValue = $t03172831907._1
769+ let terminalQuoteAssetReserve = $t03172831907._2
770+ let terminalBaseAssetReserve = $t03172831907._3
771771 $Tuple2(terminalQuoteAssetReserve, terminalBaseAssetReserve)
772772 }
773773 }
778778 let sz = toBigInt(totalPositionSize)
779779 let q = toBigInt(quoteAssetReserve)
780780 let p = toBigInt(targetPrice)
781- let bs2 = bpowd((b + sz), toBigInt((2 * DECIMAL_UNIT)))
782- let qbs2 = bmuld(q, bs2)
783- let ps4 = (toBigInt(4) * bmuld(p, sz))
784- let sqr = bsqrtd(bmuld(qbs2, (q - ps4)))
785- let bq = bmuld(b, q)
786- let qs = bmuld(q, sz)
787- let top = ((-(sqr) + bq) + qs)
788- let bot = (toBigInt(2) * bmuld(q, sz))
789- let result = bdivd(top, bot)
781+ let k = bmuld(q, b)
782+ let newB = (b + sz)
783+ let newQ = bdivd(k, newB)
784+ let z = bdivd(newQ, newB)
785+ let result = bdivd(p, z)
790786 toInt(result)
791787 }
792788
836832 func getAdjustedFee (_artifactId,_baseFeeDiscount) = {
837833 let baseFeeRaw = fee()
838834 let baseFee = muld(baseFeeRaw, _baseFeeDiscount)
839- let $t03505935554 = if ((_artifactId != ""))
835+ let $t03476835263 = if ((_artifactId != ""))
840836 then {
841837 let artifactKind = strA(nftManagerAddress(), toCompositeKey(k_token_type, _artifactId))
842838 if ((artifactKind == FEE_REDUCTION_TOKEN_TYPE))
848844 else throw("Invalid attached artifact")
849845 }
850846 else $Tuple2(baseFee, false)
851- let adjustedFee = $t03505935554._1
852- let burnArtifact = $t03505935554._2
847+ let adjustedFee = $t03476835263._1
848+ let burnArtifact = $t03476835263._2
853849 $Tuple2(adjustedFee, burnArtifact)
854850 }
855851
890886 case _ =>
891887 throw("Invalid computeFeeDiscount result")
892888 }
893- let $t03678536859 = getAdjustedFee(_artifactId, feeDiscount)
894- let adjustedFee = $t03678536859._1
895- let burnArtifact = $t03678536859._2
889+ let $t03649436568 = getAdjustedFee(_artifactId, feeDiscount)
890+ let adjustedFee = $t03649436568._1
891+ let burnArtifact = $t03649436568._2
896892 $Tuple2(adjustedFee, burnArtifact)
897893 }
898894 else throw("Strict value is not equal to itself.")
10431039 let qtAstRAfter = (_qtAstR + _quoteAssetAmount)
10441040 let baseAssetAmountToAdd = (divd(muld(qtAstRAfter, _qtAstW), price) - _bsAstR)
10451041 let bsAstRAfter = (_bsAstR + baseAssetAmountToAdd)
1046- let $t04588146032 = getSyncTerminalPrice(getOraclePrice(), qtAstRAfter, bsAstRAfter)
1047- let newQuoteAssetWeight = $t04588146032._1
1048- let newBaseAssetWeight = $t04588146032._2
1049- let marginToVault = $t04588146032._3
1042+ let $t04559045741 = getSyncTerminalPrice(getOraclePrice(), qtAstRAfter, bsAstRAfter)
1043+ let newQuoteAssetWeight = $t04559045741._1
1044+ let newBaseAssetWeight = $t04559045741._2
1045+ let marginToVault = $t04559045741._3
10501046 let doExchangePnL = if ((marginToVault != 0))
10511047 then {
10521048 let doExchangePnL = invoke(vaultAddress(), "exchangeFreeAndLocked", [marginToVault], nil)
11441140 else isMarketClosed())
11451141 then throw("Invalid decreasePosition parameters")
11461142 else {
1147- let $t04989950039 = getPosition(_trader)
1148- let oldPositionSize = $t04989950039._1
1149- let oldPositionMargin = $t04989950039._2
1150- let oldPositionOpenNotional = $t04989950039._3
1151- let oldPositionLstUpdCPF = $t04989950039._4
1143+ let $t04960849748 = getPosition(_trader)
1144+ let oldPositionSize = $t04960849748._1
1145+ let oldPositionMargin = $t04960849748._2
1146+ let oldPositionOpenNotional = $t04960849748._3
1147+ let oldPositionLstUpdCPF = $t04960849748._4
11521148 let _direction = if ((oldPositionSize > 0))
11531149 then DIR_SHORT
11541150 else DIR_LONG
11551151 let isAdd = (_direction == DIR_LONG)
11561152 let openNotional = muld(_amount, _leverage)
1157- let $t05021250316 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1158- let oldPositionNotional = $t05021250316._1
1159- let unrealizedPnl = $t05021250316._2
1160- let $t05032252964 = if ((oldPositionNotional > openNotional))
1153+ let $t04992150025 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1154+ let oldPositionNotional = $t04992150025._1
1155+ let unrealizedPnl = $t04992150025._2
1156+ let $t05003152673 = if ((oldPositionNotional > openNotional))
11611157 then {
1162- let $t05073750921 = swapInput(isAdd, openNotional)
1163- let exchangedPositionSize = $t05073750921._1
1164- let quoteAssetReserveAfter = $t05073750921._2
1165- let baseAssetReserveAfter = $t05073750921._3
1166- let totalPositionSizeAfter = $t05073750921._4
1158+ let $t05044650630 = swapInput(isAdd, openNotional)
1159+ let exchangedPositionSize = $t05044650630._1
1160+ let quoteAssetReserveAfter = $t05044650630._2
1161+ let baseAssetReserveAfter = $t05044650630._3
1162+ let totalPositionSizeAfter = $t05044650630._4
11671163 let exchangedPositionSizeAbs = abs(exchangedPositionSize)
11681164 if (if ((_minBaseAssetAmount != 0))
11691165 then (_minBaseAssetAmount > exchangedPositionSizeAbs)
11711167 then throw(((("Too little base asset exchanged, got " + toString(exchangedPositionSizeAbs)) + " expected ") + toString(_minBaseAssetAmount)))
11721168 else {
11731169 let realizedPnl = divd(muld(unrealizedPnl, exchangedPositionSizeAbs), abs(oldPositionSize))
1174- let $t05135851587 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1175- let remainMargin = $t05135851587._1
1176- let badDebt = $t05135851587._2
1170+ let $t05106751296 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1171+ let remainMargin = $t05106751296._1
1172+ let badDebt = $t05106751296._2
11771173 let exchangedQuoteAssetAmount = openNotional
11781174 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
11791175 let remainOpenNotional = if ((oldPositionSize > 0))
11921188 }
11931189 }
11941190 else throw("Close position first")
1195- let newPositionSize = $t05032252964._1
1196- let newPositionRemainMargin = $t05032252964._2
1197- let newPositionOpenNotional = $t05032252964._3
1198- let newPositionLatestCPF = $t05032252964._4
1199- let baseAssetReserveAfter = $t05032252964._5
1200- let quoteAssetReserveAfter = $t05032252964._6
1201- let totalPositionSizeAfter = $t05032252964._7
1202- let openInterestNotionalAfter = $t05032252964._8
1203- let totalLongAfter = $t05032252964._9
1204- let totalShortAfter = $t05032252964._10
1205- let totalLongOpenInterestAfter = $t05032252964._11
1206- let totalShortOpenInterestAfter = $t05032252964._12
1191+ let newPositionSize = $t05003152673._1
1192+ let newPositionRemainMargin = $t05003152673._2
1193+ let newPositionOpenNotional = $t05003152673._3
1194+ let newPositionLatestCPF = $t05003152673._4
1195+ let baseAssetReserveAfter = $t05003152673._5
1196+ let quoteAssetReserveAfter = $t05003152673._6
1197+ let totalPositionSizeAfter = $t05003152673._7
1198+ let openInterestNotionalAfter = $t05003152673._8
1199+ let totalLongAfter = $t05003152673._9
1200+ let totalShortAfter = $t05003152673._10
1201+ let totalLongOpenInterestAfter = $t05003152673._11
1202+ let totalShortOpenInterestAfter = $t05003152673._12
12071203 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, newPositionOpenNotional], nil)
12081204 if ((notifyNotional == notifyNotional))
12091205 then (updatePosition(_trader, newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter))
12491245 else isMarketClosed())
12501246 then throw("Invalid increasePosition parameters")
12511247 else {
1252- let $t05442654511 = getForTraderWithArtifact(_trader, getArtifactId(i))
1253- let adjustedFee = $t05442654511._1
1254- let burnArtifact = $t05442654511._2
1248+ let $t05413554220 = getForTraderWithArtifact(_trader, getArtifactId(i))
1249+ let adjustedFee = $t05413554220._1
1250+ let burnArtifact = $t05413554220._2
12551251 let rawFeeAmount = muld(_rawAmount, adjustedFee)
12561252 let _amount = (_rawAmount - rawFeeAmount)
12571253 let distributeFeeAmount = if (isCollateralAsset)
12941290 throw("Invalid referrerFee")
12951291 }
12961292 let feeAmount = (distributeFeeAmount - referrerFee)
1297- let $t05582755967 = getPosition(_trader)
1298- let oldPositionSize = $t05582755967._1
1299- let oldPositionMargin = $t05582755967._2
1300- let oldPositionOpenNotional = $t05582755967._3
1301- let oldPositionLstUpdCPF = $t05582755967._4
1293+ let $t05553655676 = getPosition(_trader)
1294+ let oldPositionSize = $t05553655676._1
1295+ let oldPositionMargin = $t05553655676._2
1296+ let oldPositionOpenNotional = $t05553655676._3
1297+ let oldPositionLstUpdCPF = $t05553655676._4
13021298 let isNewPosition = (oldPositionSize == 0)
13031299 let isSameDirection = if ((oldPositionSize > 0))
13041300 then (_direction == DIR_LONG)
13071303 then isSameDirection
13081304 else false
13091305 let isAdd = (_direction == DIR_LONG)
1310- let $t05625659297 = if (if (isNewPosition)
1306+ let $t05596558927 = if (if (isNewPosition)
13111307 then true
13121308 else expandExisting)
13131309 then {
13141310 let openNotional = muld(_amount, _leverage)
1315- let $t05671856891 = swapInput(isAdd, openNotional)
1316- let amountBaseAssetBought = $t05671856891._1
1317- let quoteAssetReserveAfter = $t05671856891._2
1318- let baseAssetReserveAfter = $t05671856891._3
1319- let totalPositionSizeAfter = $t05671856891._4
1311+ let $t05642756600 = swapInput(isAdd, openNotional)
1312+ let amountBaseAssetBought = $t05642756600._1
1313+ let quoteAssetReserveAfter = $t05642756600._2
1314+ let baseAssetReserveAfter = $t05642756600._3
1315+ let totalPositionSizeAfter = $t05642756600._4
13201316 if (if ((_minBaseAssetAmount != 0))
13211317 then (_minBaseAssetAmount > abs(amountBaseAssetBought))
13221318 else false)
13291325 let totalShortOpenInterestAfter = (openInterestShort() + (if ((0 > newPositionSize))
13301326 then openNotional
13311327 else 0))
1332- let increaseMarginRequirement = divd(openNotional, _leverage)
1333- let $t05749957738 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
1334- let remainMargin = $t05749957738._1
1335- let x1 = $t05749957738._2
1336- let x2 = $t05749957738._3
1328+ let $t05714657367 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, _amount)
1329+ let remainMargin = $t05714657367._1
1330+ let x1 = $t05714657367._2
1331+ let x2 = $t05714657367._3
13371332 if (!(requireNotOverSpreadLimit(quoteAssetReserveAfter, baseAssetReserveAfter)))
13381333 then throw("Over max spread limit")
13391334 else if (!(requireNotOverMaxOpenNotional(totalLongOpenInterestAfter, totalShortOpenInterestAfter)))
13471342 }
13481343 else {
13491344 let openNotional = muld(_amount, _leverage)
1350- let $t05899759113 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1351- let oldPositionNotional = $t05899759113._1
1352- let unrealizedPnl = $t05899759113._2
1345+ let $t05862758743 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1346+ let oldPositionNotional = $t05862758743._1
1347+ let unrealizedPnl = $t05862758743._2
13531348 if ((oldPositionNotional > openNotional))
13541349 then throw("Use decreasePosition to decrease position size")
13551350 else throw("Close position first")
13561351 }
1357- let newPositionSize = $t05625659297._1
1358- let newPositionRemainMargin = $t05625659297._2
1359- let newPositionOpenNotional = $t05625659297._3
1360- let newPositionLatestCPF = $t05625659297._4
1361- let baseAssetReserveAfter = $t05625659297._5
1362- let quoteAssetReserveAfter = $t05625659297._6
1363- let totalPositionSizeAfter = $t05625659297._7
1364- let openInterestNotionalAfter = $t05625659297._8
1365- let totalLongAfter = $t05625659297._9
1366- let totalShortAfter = $t05625659297._10
1367- let totalLongOpenInterestAfter = $t05625659297._11
1368- let totalShortOpenInterestAfter = $t05625659297._12
1369- let $t05930359360 = distributeFee(feeAmount)
1370- let feeToStakers = $t05930359360._1
1371- let feeToVault = $t05930359360._2
1352+ let newPositionSize = $t05596558927._1
1353+ let newPositionRemainMargin = $t05596558927._2
1354+ let newPositionOpenNotional = $t05596558927._3
1355+ let newPositionLatestCPF = $t05596558927._4
1356+ let baseAssetReserveAfter = $t05596558927._5
1357+ let quoteAssetReserveAfter = $t05596558927._6
1358+ let totalPositionSizeAfter = $t05596558927._7
1359+ let openInterestNotionalAfter = $t05596558927._8
1360+ let totalLongAfter = $t05596558927._9
1361+ let totalShortAfter = $t05596558927._10
1362+ let totalLongOpenInterestAfter = $t05596558927._11
1363+ let totalShortOpenInterestAfter = $t05596558927._12
1364+ let $t05893358990 = distributeFee(feeAmount)
1365+ let feeToStakers = $t05893358990._1
1366+ let feeToVault = $t05893358990._2
13721367 let stake = if (isQuoteAsset)
13731368 then {
13741369 let stake = invoke(vaultAddress(), "addLocked", [false], [AttachedPayment(quoteAsset(), _amount)])
14341429 else isMarketClosed())
14351430 then throw("Invalid addMargin parameters")
14361431 else {
1437- let $t06133261417 = getForTraderWithArtifact(_trader, getArtifactId(i))
1438- let adjustedFee = $t06133261417._1
1439- let burnArtifact = $t06133261417._2
1432+ let $t06096261047 = getForTraderWithArtifact(_trader, getArtifactId(i))
1433+ let adjustedFee = $t06096261047._1
1434+ let burnArtifact = $t06096261047._2
14401435 let rawFeeAmount = muld(_rawAmount, adjustedFee)
14411436 let _amount = (_rawAmount - rawFeeAmount)
14421437 let distributeFeeAmount = if (isCollateralAsset)
14791474 throw("Invalid referrerFee")
14801475 }
14811476 let feeAmount = (distributeFeeAmount - referrerFee)
1482- let $t06271662856 = getPosition(_trader)
1483- let oldPositionSize = $t06271662856._1
1484- let oldPositionMargin = $t06271662856._2
1485- let oldPositionOpenNotional = $t06271662856._3
1486- let oldPositionLstUpdCPF = $t06271662856._4
1487- let $t06286262919 = distributeFee(feeAmount)
1488- let feeToStakers = $t06286262919._1
1489- let feeToVault = $t06286262919._2
1477+ let $t06234662486 = getPosition(_trader)
1478+ let oldPositionSize = $t06234662486._1
1479+ let oldPositionMargin = $t06234662486._2
1480+ let oldPositionOpenNotional = $t06234662486._3
1481+ let oldPositionLstUpdCPF = $t06234662486._4
1482+ let $t06249262549 = distributeFee(feeAmount)
1483+ let feeToStakers = $t06249262549._1
1484+ let feeToVault = $t06249262549._2
14901485 let stake = if (isQuoteAsset)
14911486 then {
14921487 let stake = invoke(vaultAddress(), "addLocked", [false], [AttachedPayment(quoteAsset(), _amount)])
15361531 else isMarketClosed())
15371532 then throw("Invalid removeMargin parameters")
15381533 else {
1539- let $t06405564195 = getPosition(_trader)
1540- let oldPositionSize = $t06405564195._1
1541- let oldPositionMargin = $t06405564195._2
1542- let oldPositionOpenNotional = $t06405564195._3
1543- let oldPositionLstUpdCPF = $t06405564195._4
1534+ let $t06368563825 = getPosition(_trader)
1535+ let oldPositionSize = $t06368563825._1
1536+ let oldPositionMargin = $t06368563825._2
1537+ let oldPositionOpenNotional = $t06368563825._3
1538+ let oldPositionLstUpdCPF = $t06368563825._4
15441539 let marginDelta = -(_amount)
1545- let $t06423264411 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1546- let remainMargin = $t06423264411._1
1547- let badDebt = $t06423264411._2
1540+ let $t06386264041 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1541+ let remainMargin = $t06386264041._1
1542+ let badDebt = $t06386264041._2
15481543 if ((badDebt != 0))
15491544 then throw("Invalid removed margin amount")
15501545 else {
15531548 then throw(((("Too much margin removed: " + toString(marginRatio)) + " < ") + toString(initMarginRatio())))
15541549 else {
15551550 let quoteAssetStr = toBase58String(quoteAsset())
1556- let $t06485564909 = getBorrowedByTrader(_trader)
1557- let borrowed = $t06485564909._1
1558- let assetId = $t06485564909._2
1551+ let $t06448564539 = getBorrowedByTrader(_trader)
1552+ let borrowed = $t06448564539._1
1553+ let assetId = $t06448564539._2
15591554 let toRepay = if ((_amount > borrowed))
15601555 then borrowed
15611556 else _amount
16271622 else isMarketClosed())
16281623 then throw("Invalid closePosition parameters")
16291624 else {
1630- let $t06709367233 = getPosition(_trader)
1631- let oldPositionSize = $t06709367233._1
1632- let oldPositionMargin = $t06709367233._2
1633- let oldPositionOpenNotional = $t06709367233._3
1634- let oldPositionLstUpdCPF = $t06709367233._4
1635- let $t06723972369 = if ((abs(oldPositionSize) > _size))
1625+ let $t06672366863 = getPosition(_trader)
1626+ let oldPositionSize = $t06672366863._1
1627+ let oldPositionMargin = $t06672366863._2
1628+ let oldPositionOpenNotional = $t06672366863._3
1629+ let oldPositionLstUpdCPF = $t06672366863._4
1630+ let $t06686971999 = if ((abs(oldPositionSize) > _size))
16361631 then {
16371632 let _direction = if ((oldPositionSize > 0))
16381633 then DIR_SHORT
16391634 else DIR_LONG
16401635 let isAdd = (_direction == DIR_LONG)
1641- let $t06783068052 = swapOutput((oldPositionSize > 0), _size, true)
1642- let exchangedQuoteAssetAmount = $t06783068052._1
1643- let quoteAssetReserveAfter = $t06783068052._2
1644- let baseAssetReserveAfter = $t06783068052._3
1645- let totalPositionSizeAfter = $t06783068052._4
1636+ let $t06746067682 = swapOutput((oldPositionSize > 0), _size, true)
1637+ let exchangedQuoteAssetAmount = $t06746067682._1
1638+ let quoteAssetReserveAfter = $t06746067682._2
1639+ let baseAssetReserveAfter = $t06746067682._3
1640+ let totalPositionSizeAfter = $t06746067682._4
16461641 let exchangedPositionSize = if ((oldPositionSize > 0))
16471642 then -(_size)
16481643 else _size
1649- let $t06814368297 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1650- let oldPositionNotional = $t06814368297._1
1651- let unrealizedPnl = $t06814368297._2
1644+ let $t06777367927 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1645+ let oldPositionNotional = $t06777367927._1
1646+ let unrealizedPnl = $t06777367927._2
16521647 let mr = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
16531648 let realizedRatio = divd(abs(exchangedPositionSize), abs(oldPositionSize))
16541649 let realizedPnl = muld(unrealizedPnl, realizedRatio)
16551650 let remainMarginBefore = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, unrealizedPnl)._1
1656- let $t06879869026 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1657- let x1 = $t06879869026._1
1658- let positionBadDebt = $t06879869026._2
1659- let fundingPayment = $t06879869026._3
1651+ let $t06842868656 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1652+ let x1 = $t06842868656._1
1653+ let positionBadDebt = $t06842868656._2
1654+ let fundingPayment = $t06842868656._3
16601655 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
16611656 let remainOpenNotional = if ((oldPositionSize > 0))
16621657 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
16861681 else if ((_size > abs(oldPositionSize)))
16871682 then throw("Invalid closePosition parameters")
16881683 else {
1689- let $t07131071729 = internalClosePosition(_trader, true)
1690- let exchangedQuoteAssetAmount = $t07131071729._1
1691- let positionBadDebt = $t07131071729._2
1692- let realizedPnl = $t07131071729._3
1693- let marginToVault = $t07131071729._4
1694- let quoteAssetReserveAfter = $t07131071729._5
1695- let baseAssetReserveAfter = $t07131071729._6
1696- let totalPositionSizeAfter = $t07131071729._7
1697- let openInterestNotionalAfter = $t07131071729._8
1698- let x2 = $t07131071729._9
1699- let totalLongAfter = $t07131071729._10
1700- let totalShortAfter = $t07131071729._11
1701- let totalLongOpenInterestAfter = $t07131071729._12
1702- let totalShortOpenInterestAfter = $t07131071729._13
1684+ let $t07094071359 = internalClosePosition(_trader, true)
1685+ let exchangedQuoteAssetAmount = $t07094071359._1
1686+ let positionBadDebt = $t07094071359._2
1687+ let realizedPnl = $t07094071359._3
1688+ let marginToVault = $t07094071359._4
1689+ let quoteAssetReserveAfter = $t07094071359._5
1690+ let baseAssetReserveAfter = $t07094071359._6
1691+ let totalPositionSizeAfter = $t07094071359._7
1692+ let openInterestNotionalAfter = $t07094071359._8
1693+ let x2 = $t07094071359._9
1694+ let totalLongAfter = $t07094071359._10
1695+ let totalShortAfter = $t07094071359._11
1696+ let totalLongOpenInterestAfter = $t07094071359._12
1697+ let totalShortOpenInterestAfter = $t07094071359._13
17031698 if (if ((_minQuoteAssetAmount != 0))
17041699 then (_minQuoteAssetAmount > exchangedQuoteAssetAmount)
17051700 else false)
17061701 then throw(((("Limit error: " + toString(exchangedQuoteAssetAmount)) + " < ") + toString(_minQuoteAssetAmount)))
17071702 else $Tuple15(0, 0, 0, 0, positionBadDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter)
17081703 }
1709- let newPositionSize = $t06723972369._1
1710- let newPositionMargin = $t06723972369._2
1711- let newPositionOpenNotional = $t06723972369._3
1712- let newPositionLstUpdCPF = $t06723972369._4
1713- let positionBadDebt = $t06723972369._5
1714- let realizedPnl = $t06723972369._6
1715- let marginToVault = $t06723972369._7
1716- let quoteAssetReserveAfter = $t06723972369._8
1717- let baseAssetReserveAfter = $t06723972369._9
1718- let totalPositionSizeAfter = $t06723972369._10
1719- let openInterestNotionalAfter = $t06723972369._11
1720- let totalLongAfter = $t06723972369._12
1721- let totalShortAfter = $t06723972369._13
1722- let totalLongOpenInterestAfter = $t06723972369._14
1723- let totalShortOpenInterestAfter = $t06723972369._15
1704+ let newPositionSize = $t06686971999._1
1705+ let newPositionMargin = $t06686971999._2
1706+ let newPositionOpenNotional = $t06686971999._3
1707+ let newPositionLstUpdCPF = $t06686971999._4
1708+ let positionBadDebt = $t06686971999._5
1709+ let realizedPnl = $t06686971999._6
1710+ let marginToVault = $t06686971999._7
1711+ let quoteAssetReserveAfter = $t06686971999._8
1712+ let baseAssetReserveAfter = $t06686971999._9
1713+ let totalPositionSizeAfter = $t06686971999._10
1714+ let openInterestNotionalAfter = $t06686971999._11
1715+ let totalLongAfter = $t06686971999._12
1716+ let totalShortAfter = $t06686971999._13
1717+ let totalLongOpenInterestAfter = $t06686971999._14
1718+ let totalShortOpenInterestAfter = $t06686971999._15
17241719 if ((positionBadDebt > 0))
17251720 then throw("Unable to close position with bad debt")
17261721 else {
17271722 let withdrawAmount = abs(marginToVault)
17281723 let ammBalance = (cbalance() - withdrawAmount)
1729- let $t07257872785 = if ((0 > ammBalance))
1724+ let $t07220872415 = if ((0 > ammBalance))
17301725 then $Tuple2(0, abs(ammBalance))
17311726 else $Tuple2(ammBalance, 0)
1732- let ammNewBalance = $t07257872785._1
1733- let x11 = $t07257872785._2
1734- let $t07279272846 = getBorrowedByTrader(_trader)
1735- let borrowed = $t07279272846._1
1736- let assetId = $t07279272846._2
1737- let $t07286173720 = if ((borrowed > 0))
1727+ let ammNewBalance = $t07220872415._1
1728+ let x11 = $t07220872415._2
1729+ let $t07242272476 = getBorrowedByTrader(_trader)
1730+ let borrowed = $t07242272476._1
1731+ let assetId = $t07242272476._2
1732+ let $t07249173350 = if ((borrowed > 0))
17381733 then if ((withdrawAmount >= borrowed))
17391734 then {
17401735 let doRepay = invoke(collateralAddress(), "repay", [_trader, borrowed, assetId], nil)
17491744 else throw("Strict value is not equal to itself.")
17501745 }
17511746 else $Tuple2(nil, withdrawAmount)
1752- if (($t07286173720 == $t07286173720))
1747+ if (($t07249173350 == $t07249173350))
17531748 then {
1754- let quoteWithdrawAmount = $t07286173720._2
1755- let sendCollateralAction = $t07286173720._1
1749+ let quoteWithdrawAmount = $t07249173350._2
1750+ let sendCollateralAction = $t07249173350._1
17561751 let unstake = if ((quoteWithdrawAmount > 0))
17571752 then {
17581753 let unstake = invoke(vaultAddress(), "withdrawLocked", [quoteWithdrawAmount], nil)
18111806 then (DECIMAL_UNIT > partialLiquidationRatio())
18121807 else false)
18131808 then {
1814- let $t07604176191 = getPosition(_trader)
1815- let oldPositionSize = $t07604176191._1
1816- let oldPositionMargin = $t07604176191._2
1817- let oldPositionOpenNotional = $t07604176191._3
1818- let oldPositionLstUpdCPF = $t07604176191._4
1809+ let $t07567175821 = getPosition(_trader)
1810+ let oldPositionSize = $t07567175821._1
1811+ let oldPositionMargin = $t07567175821._2
1812+ let oldPositionOpenNotional = $t07567175821._3
1813+ let oldPositionLstUpdCPF = $t07567175821._4
18191814 let _direction = if ((oldPositionSize > 0))
18201815 then DIR_SHORT
18211816 else DIR_LONG
18221817 let isAdd = (_direction == DIR_LONG)
18231818 let exchangedQuoteAssetAmount = getPartialLiquidationAmount(_trader, oldPositionSize)
1824- let $t07641676520 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1825- let oldPositionNotional = $t07641676520._1
1826- let unrealizedPnl = $t07641676520._2
1827- let $t07652876715 = swapInput(isAdd, exchangedQuoteAssetAmount)
1828- let exchangedPositionSize = $t07652876715._1
1829- let quoteAssetReserveAfter = $t07652876715._2
1830- let baseAssetReserveAfter = $t07652876715._3
1831- let totalPositionSizeAfter = $t07652876715._4
1819+ let $t07604676150 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1820+ let oldPositionNotional = $t07604676150._1
1821+ let unrealizedPnl = $t07604676150._2
1822+ let $t07615876345 = swapInput(isAdd, exchangedQuoteAssetAmount)
1823+ let exchangedPositionSize = $t07615876345._1
1824+ let quoteAssetReserveAfter = $t07615876345._2
1825+ let baseAssetReserveAfter = $t07615876345._3
1826+ let totalPositionSizeAfter = $t07615876345._4
18321827 let liquidationRatio = divd(abs(exchangedPositionSize), abs(oldPositionSize))
18331828 let realizedPnl = muld(unrealizedPnl, liquidationRatio)
1834- let $t07700477237 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1835- let remainMargin = $t07700477237._1
1836- let badDebt = $t07700477237._2
1837- let fundingPayment = $t07700477237._3
1829+ let $t07663476867 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1830+ let remainMargin = $t07663476867._1
1831+ let badDebt = $t07663476867._2
1832+ let fundingPayment = $t07663476867._3
18381833 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
18391834 let remainOpenNotional = if ((oldPositionSize > 0))
18401835 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
18491844 let newPositionLstUpdCPF = latestCumulativePremiumFraction(newPositionSize)
18501845 let openInterestNotionalAfter = (openInterestNotional() - openNotionalDelta)
18511846 let ammBalance = (cbalance() - liquidationPenalty)
1852- let $t07847878607 = if ((0 > ammBalance))
1847+ let $t07810878237 = if ((0 > ammBalance))
18531848 then $Tuple2(0, abs(ammBalance))
18541849 else $Tuple2(ammBalance, 0)
1855- let newAmmBalance = $t07847878607._1
1856- let x11 = $t07847878607._2
1857- let $t07861578669 = getBorrowedByTrader(_trader)
1858- let borrowed = $t07861578669._1
1859- let assetId = $t07861578669._2
1850+ let newAmmBalance = $t07810878237._1
1851+ let x11 = $t07810878237._2
1852+ let $t07824578299 = getBorrowedByTrader(_trader)
1853+ let borrowed = $t07824578299._1
1854+ let assetId = $t07824578299._2
18601855 let doLiquidateCollateral = if ((borrowed > 0))
18611856 then {
18621857 let collateralToSell = muld(borrowed, liquidationRatio)
18941889 else throw("Strict value is not equal to itself.")
18951890 }
18961891 else {
1897- let $t08034880843 = internalClosePosition(_trader, false)
1898- let x1 = $t08034880843._1
1899- let badDebt = $t08034880843._2
1900- let x2 = $t08034880843._3
1901- let x3 = $t08034880843._4
1902- let quoteAssetReserveAfter = $t08034880843._5
1903- let baseAssetReserveAfter = $t08034880843._6
1904- let totalPositionSizeAfter = $t08034880843._7
1905- let openInterestNotionalAfter = $t08034880843._8
1906- let exchangedQuoteAssetAmount = $t08034880843._9
1907- let totalLongAfter = $t08034880843._10
1908- let totalShortAfter = $t08034880843._11
1909- let totalLongOpenInterestAfter = $t08034880843._12
1910- let totalShortOpenInterestAfter = $t08034880843._13
1892+ let $t07997880473 = internalClosePosition(_trader, false)
1893+ let x1 = $t07997880473._1
1894+ let badDebt = $t07997880473._2
1895+ let x2 = $t07997880473._3
1896+ let x3 = $t07997880473._4
1897+ let quoteAssetReserveAfter = $t07997880473._5
1898+ let baseAssetReserveAfter = $t07997880473._6
1899+ let totalPositionSizeAfter = $t07997880473._7
1900+ let openInterestNotionalAfter = $t07997880473._8
1901+ let exchangedQuoteAssetAmount = $t07997880473._9
1902+ let totalLongAfter = $t07997880473._10
1903+ let totalShortAfter = $t07997880473._11
1904+ let totalLongOpenInterestAfter = $t07997880473._12
1905+ let totalShortOpenInterestAfter = $t07997880473._13
19111906 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
19121907 let feeToLiquidator = (liquidationPenalty / 2)
19131908 let feeToVault = (liquidationPenalty - feeToLiquidator)
19141909 let ammBalance = (cbalance() - liquidationPenalty)
1915- let $t08125181380 = if ((0 > ammBalance))
1910+ let $t08088181010 = if ((0 > ammBalance))
19161911 then $Tuple2(0, abs(ammBalance))
19171912 else $Tuple2(ammBalance, 0)
1918- let newAmmBalance = $t08125181380._1
1919- let x11 = $t08125181380._2
1920- let $t08138881442 = getBorrowedByTrader(_trader)
1921- let borrowed = $t08138881442._1
1922- let assetId = $t08138881442._2
1913+ let newAmmBalance = $t08088181010._1
1914+ let x11 = $t08088181010._2
1915+ let $t08101881072 = getBorrowedByTrader(_trader)
1916+ let borrowed = $t08101881072._1
1917+ let assetId = $t08101881072._2
19231918 let doLiquidateCollateral = if ((borrowed > 0))
19241919 then {
19251920 let realizeAndClose = invoke(collateralAddress(), "realizePartiallyAndClose", [_trader, 0, assetId], nil)
19791974 then throw(((("Invalid funding block timestamp: " + toString(lastBlock.timestamp)) + " < ") + toString(fundingBlockTimestamp)))
19801975 else {
19811976 let underlyingPrice = getOraclePrice()
1982- let $t08331483376 = getFunding()
1983- let shortPremiumFraction = $t08331483376._1
1984- let longPremiumFraction = $t08331483376._2
1977+ let $t08294483006 = getFunding()
1978+ let shortPremiumFraction = $t08294483006._1
1979+ let longPremiumFraction = $t08294483006._2
19851980 updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), divd(longPremiumFraction, underlyingPrice), divd(shortPremiumFraction, underlyingPrice))
19861981 }
19871982 }
19941989 func syncTerminalPriceToOracle () = {
19951990 let _qtAstR = qtAstR()
19961991 let _bsAstR = bsAstR()
1997- let $t08380883943 = getSyncTerminalPrice(getOraclePrice(), _qtAstR, _bsAstR)
1998- let newQuoteAssetWeight = $t08380883943._1
1999- let newBaseAssetWeight = $t08380883943._2
2000- let marginToVault = $t08380883943._3
1992+ let $t08343883573 = getSyncTerminalPrice(getOraclePrice(), _qtAstR, _bsAstR)
1993+ let newQuoteAssetWeight = $t08343883573._1
1994+ let newBaseAssetWeight = $t08343883573._2
1995+ let marginToVault = $t08343883573._3
20011996 let doExchangePnL = if ((marginToVault != 0))
20021997 then {
20031998 let doExchangePnL = invoke(vaultAddress(), "exchangeFreeAndLocked", [marginToVault], nil)
20182013 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
20192014 if ((sync == sync))
20202015 then {
2021- let $t08451284613 = getPosition(_trader)
2022- let positionSize = $t08451284613._1
2023- let positionMargin = $t08451284613._2
2024- let pon = $t08451284613._3
2025- let positionLstUpdCPF = $t08451284613._4
2026- let $t08461684717 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
2027- let positionNotional = $t08461684717._1
2028- let unrealizedPnl = $t08461684717._2
2029- let $t08472084892 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
2030- let remainMargin = $t08472084892._1
2031- let badDebt = $t08472084892._2
2032- let fundingPayment = $t08472084892._3
2016+ let $t08414284243 = getPosition(_trader)
2017+ let positionSize = $t08414284243._1
2018+ let positionMargin = $t08414284243._2
2019+ let pon = $t08414284243._3
2020+ let positionLstUpdCPF = $t08414284243._4
2021+ let $t08424684347 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
2022+ let positionNotional = $t08424684347._1
2023+ let unrealizedPnl = $t08424684347._2
2024+ let $t08435084522 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
2025+ let remainMargin = $t08435084522._1
2026+ let badDebt = $t08435084522._2
2027+ let fundingPayment = $t08435084522._3
20332028 throw((((((s(remainMargin) + s(fundingPayment)) + s(getMarginRatio(_trader))) + s(unrealizedPnl)) + s(badDebt)) + s(positionNotional)))
20342029 }
20352030 else throw("Strict value is not equal to itself.")
20492044
20502045 @Callable(i)
20512046 func view_getTerminalAmmPrice () = {
2052- let $t08530885389 = getTerminalAmmState()
2053- let terminalQuoteAssetReserve = $t08530885389._1
2054- let terminalBaseAssetReserve = $t08530885389._2
2047+ let $t08493885019 = getTerminalAmmState()
2048+ let terminalQuoteAssetReserve = $t08493885019._1
2049+ let terminalBaseAssetReserve = $t08493885019._2
20552050 let price = divd(muld(terminalQuoteAssetReserve, qtAstW()), muld(terminalBaseAssetReserve, bsAstW()))
20562051 throw(toString(price))
20572052 }
20612056 @Callable(i)
20622057 func view_getFunding () = {
20632058 let underlyingPrice = getOraclePrice()
2064- let $t08560485666 = getFunding()
2065- let shortPremiumFraction = $t08560485666._1
2066- let longPremiumFraction = $t08560485666._2
2059+ let $t08523485296 = getFunding()
2060+ let shortPremiumFraction = $t08523485296._1
2061+ let longPremiumFraction = $t08523485296._2
20672062 let longFunding = divd(longPremiumFraction, underlyingPrice)
20682063 let shortFunding = divd(shortPremiumFraction, underlyingPrice)
20692064 throw((((s(longFunding) + s(shortFunding)) + s(getTwapSpotPrice())) + s(getOraclePrice())))
20732068
20742069 @Callable(i)
20752070 func view_getBorrowedByTrader (_trader) = {
2076- let $t08595286006 = getBorrowedByTrader(_trader)
2077- let borrowed = $t08595286006._1
2078- let assetId = $t08595286006._2
2071+ let $t08558285636 = getBorrowedByTrader(_trader)
2072+ let borrowed = $t08558285636._1
2073+ let assetId = $t08558285636._2
20792074 throw((s(borrowed) + assetId))
20802075 }
20812076
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let k_ora_key = "k_ora_key"
55
66 let k_ora_block_key = "k_ora_block_key"
77
88 let k_ora_open_key = "k_ora_open_key"
99
1010 let k_ora = "k_ora"
1111
1212 let k_balance = "k_balance"
1313
1414 let k_sequence = "k_sequence"
1515
1616 let k_positionSize = "k_positionSize"
1717
1818 let k_positionMargin = "k_positionMargin"
1919
2020 let k_positionOpenNotional = "k_positionOpenNotional"
2121
2222 let k_positionLastUpdatedCumulativePremiumFraction = "k_positionFraction"
2323
2424 let k_positionSequence = "k_positionSequence"
2525
2626 let k_positionAsset = "k_positionAsset"
2727
2828 let k_initialized = "k_initialized"
2929
3030 let k_paused = "k_paused"
3131
3232 let k_closeOnly = "k_closeOnly"
3333
3434 let k_fee = "k_fee"
3535
3636 let k_fundingPeriod = "k_fundingPeriod"
3737
3838 let k_initMarginRatio = "k_initMarginRatio"
3939
4040 let k_maintenanceMarginRatio = "k_mmr"
4141
4242 let k_liquidationFeeRatio = "k_liquidationFeeRatio"
4343
4444 let k_partialLiquidationRatio = "k_partLiquidationRatio"
4545
4646 let k_spreadLimit = "k_spreadLimit"
4747
4848 let k_maxPriceImpact = "k_maxPriceImpact"
4949
5050 let k_maxPriceSpread = "k_maxPriceSpread"
5151
5252 let k_maxOpenNotional = "k_maxOpenNotional"
5353
5454 let k_feeToStakersPercent = "k_feeToStakersPercent"
5555
5656 let k_maxOracleDelay = "k_maxOracleDelay"
5757
5858 let k_lastDataStr = "k_lastDataStr"
5959
6060 let k_lastMinuteId = "k_lastMinuteId"
6161
6262 let k_twapDataLastCumulativePrice = "k_twapDataLastCumulativePrice"
6363
6464 let k_twapDataLastPrice = "k_twapDataLastPrice"
6565
6666 let k_twapDataPreviousMinuteId = "k_twapDataPreviousMinuteId"
6767
6868 let k_latestLongCumulativePremiumFraction = "k_latestLongPremiumFraction"
6969
7070 let k_latestShortCumulativePremiumFraction = "k_latestShortPremiumFraction"
7171
7272 let k_nextFundingBlock = "k_nextFundingBlockMinTimestamp"
7373
7474 let k_longFundingRate = "k_longFundingRate"
7575
7676 let k_shortFundingRate = "k_shortFundingRate"
7777
7878 let k_quoteAssetReserve = "k_qtAstR"
7979
8080 let k_baseAssetReserve = "k_bsAstR"
8181
8282 let k_quoteAssetWeight = "k_qtAstW"
8383
8484 let k_baseAssetWeight = "k_bsAstW"
8585
8686 let k_totalPositionSize = "k_totalPositionSize"
8787
8888 let k_totalLongPositionSize = "k_totalLongPositionSize"
8989
9090 let k_totalShortPositionSize = "k_totalShortPositionSize"
9191
9292 let k_openInterestNotional = "k_openInterestNotional"
9393
9494 let k_openInterestShort = "k_openInterestShort"
9595
9696 let k_openInterestLong = "k_openInterestLong"
9797
9898 let k_coordinatorAddress = "k_coordinatorAddress"
9999
100100 let k_vault_address = "k_vault_address"
101101
102102 let k_admin_address = "k_admin_address"
103103
104104 let k_admin_public_key = "k_admin_public_key"
105105
106106 let k_quote_asset = "k_quote_asset"
107107
108108 let k_quote_staking = "k_quote_staking"
109109
110110 let k_staking_address = "k_staking_address"
111111
112112 let k_miner_address = "k_miner_address"
113113
114114 let k_orders_address = "k_orders_address"
115115
116116 let k_referral_address = "k_referral_address"
117117
118118 let k_collateral_address = "k_collateral_address"
119119
120120 let k_exchange_address = "k_exchange_address"
121121
122122 let k_nft_manager_address = "k_nft_manager_address"
123123
124124 let k_trader_market_asset_collateral = "k_trader_market_asset_collateral"
125125
126126 func toCompositeKey (_key,_address) = ((_key + "_") + _address)
127127
128128
129129 func coordinator () = valueOrErrorMessage(addressFromString(getStringValue(this, k_coordinatorAddress)), "Coordinator not set")
130130
131131
132132 func adminAddress () = addressFromString(getStringValue(coordinator(), k_admin_address))
133133
134134
135135 func adminPublicKey () = fromBase58String(getStringValue(coordinator(), k_admin_public_key))
136136
137137
138138 func quoteAsset () = fromBase58String(getStringValue(coordinator(), k_quote_asset))
139139
140140
141141 func quoteAssetStaking () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_quote_staking)), "Quote asset staking not set")
142142
143143
144144 func stakingAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_staking_address)), "Staking not set")
145145
146146
147147 func vaultAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_vault_address)), "Vault not set")
148148
149149
150150 func minerAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_miner_address)), "Miner not set")
151151
152152
153153 func ordersAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_orders_address)), "Orders not set")
154154
155155
156156 func referralAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_referral_address)), "Referral not set")
157157
158158
159159 func nftManagerAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_nft_manager_address)), "NFT Manager not set")
160160
161161
162162 func collateralAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_collateral_address)), "Collateral Manager not set")
163163
164164
165165 func swapAddress () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(coordinator(), k_exchange_address), "No swap address")), "Invalid swap address")
166166
167167
168168 let k_whitelist_asset = "k_whitelist_asset"
169169
170170 func isWhitelistAsset (_assetId) = valueOrElse(getBoolean(collateralAddress(), toCompositeKey(k_whitelist_asset, _assetId)), false)
171171
172172
173173 let k_token_param = "k_token_param"
174174
175175 let k_token_type = "k_token_type"
176176
177177 let FEE_REDUCTION_TOKEN_TYPE = "fee_reduction"
178178
179179 let DIR_LONG = 1
180180
181181 let DIR_SHORT = 2
182182
183183 let TWAP_INTERVAL = 15
184184
185185 let ORACLE_INTERVAL = 15
186186
187187 let SECONDS = 1000
188188
189189 let DECIMAL_NUMBERS = 6
190190
191191 let DECIMAL_UNIT = (1 * (((((10 * 10) * 10) * 10) * 10) * 10))
192192
193193 let ONE_DAY = (86400 * DECIMAL_UNIT)
194194
195195 let ALL_FEES = 100
196196
197197 let PNL_OPTION_SPOT = 1
198198
199199 let PNL_OPTION_ORACLE = 2
200200
201201 func s (_x) = (toString(_x) + ",")
202202
203203
204204 func divd (_x,_y) = fraction(_x, DECIMAL_UNIT, _y, HALFEVEN)
205205
206206
207207 func muld (_x,_y) = fraction(_x, _y, DECIMAL_UNIT, HALFEVEN)
208208
209209
210210 func sqrtd (_x) = sqrt(_x, DECIMAL_NUMBERS, DECIMAL_NUMBERS, HALFEVEN)
211211
212212
213213 func powd (_x,_y) = pow(_x, DECIMAL_NUMBERS, _y, DECIMAL_NUMBERS, DECIMAL_NUMBERS, HALFEVEN)
214214
215215
216216 func bdivd (_x,_y) = fraction(_x, toBigInt(DECIMAL_UNIT), _y, HALFEVEN)
217217
218218
219219 func bmuld (_x,_y) = fraction(_x, _y, toBigInt(DECIMAL_UNIT), HALFEVEN)
220220
221221
222222 func bsqrtd (_x) = sqrtBigInt(_x, DECIMAL_NUMBERS, DECIMAL_NUMBERS, HALFEVEN)
223223
224224
225225 func bpowd (_x,_y) = pow(_x, DECIMAL_NUMBERS, _y, DECIMAL_NUMBERS, DECIMAL_NUMBERS, HALFEVEN)
226226
227227
228228 func abs (_x) = if ((_x > 0))
229229 then _x
230230 else -(_x)
231231
232232
233233 func vmax (_x,_y) = if ((_x >= _y))
234234 then _x
235235 else _y
236236
237237
238238 func listToStr (_list) = {
239239 func _join (accumulator,val) = ((accumulator + val) + ",")
240240
241241 let newListStr = {
242242 let $l = _list
243243 let $s = size($l)
244244 let $acc0 = ""
245245 func $f0_1 ($a,$i) = if (($i >= $s))
246246 then $a
247247 else _join($a, $l[$i])
248248
249249 func $f0_2 ($a,$i) = if (($i >= $s))
250250 then $a
251251 else throw("List size exceeds 20")
252252
253253 $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)
254254 }
255255 let newListStrU = dropRight(newListStr, 1)
256256 let newListStrR = if ((take(newListStrU, 1) == ","))
257257 then drop(newListStrU, 1)
258258 else newListStrU
259259 newListStrR
260260 }
261261
262262
263263 func strToList (_str) = split(_str, ",")
264264
265265
266266 func pushToQueue (_list,_maxSize,_value) = if ((size(_list) > _maxSize))
267267 then (removeByIndex(_list, 0) :+ _value)
268268 else (_list :+ _value)
269269
270270
271271 func int (k) = valueOrErrorMessage(getInteger(this, k), ("no value for " + k))
272272
273273
274274 func intOr (k,def) = valueOrElse(getInteger(this, k), def)
275275
276276
277277 func strA (_address,_key) = {
278278 let val = valueOrErrorMessage(getString(_address, _key), ("No value for key " + _key))
279279 val
280280 }
281281
282282
283283 func intA (_address,_key) = {
284284 let val = valueOrErrorMessage(getInteger(_address, _key), ("No value for key " + _key))
285285 val
286286 }
287287
288288
289289 func cbalance () = int(k_balance)
290290
291291
292292 func fee () = int(k_fee)
293293
294294
295295 func initMarginRatio () = int(k_initMarginRatio)
296296
297297
298298 func qtAstR () = int(k_quoteAssetReserve)
299299
300300
301301 func bsAstR () = int(k_baseAssetReserve)
302302
303303
304304 func qtAstW () = intOr(k_quoteAssetWeight, DECIMAL_UNIT)
305305
306306
307307 func bsAstW () = intOr(k_baseAssetWeight, DECIMAL_UNIT)
308308
309309
310310 func totalPositionSize () = int(k_totalPositionSize)
311311
312312
313313 func openInterestNotional () = int(k_openInterestNotional)
314314
315315
316316 func openInterestShort () = int(k_openInterestShort)
317317
318318
319319 func openInterestLong () = int(k_openInterestLong)
320320
321321
322322 func nextFundingBlockTimestamp () = int(k_nextFundingBlock)
323323
324324
325325 func fundingPeriodRaw () = int(k_fundingPeriod)
326326
327327
328328 func fundingPeriodDecimal () = (fundingPeriodRaw() * DECIMAL_UNIT)
329329
330330
331331 func fundingPeriodSeconds () = (fundingPeriodRaw() * SECONDS)
332332
333333
334334 func maintenanceMarginRatio () = int(k_maintenanceMarginRatio)
335335
336336
337337 func liquidationFeeRatio () = int(k_liquidationFeeRatio)
338338
339339
340340 func partialLiquidationRatio () = int(k_partialLiquidationRatio)
341341
342342
343343 func spreadLimit () = int(k_spreadLimit)
344344
345345
346346 func maxPriceImpact () = int(k_maxPriceImpact)
347347
348348
349349 func maxPriceSpread () = int(k_maxPriceSpread)
350350
351351
352352 func maxOpenNotional () = int(k_maxOpenNotional)
353353
354354
355355 func latestLongCumulativePremiumFraction () = int(k_latestLongCumulativePremiumFraction)
356356
357357
358358 func latestShortCumulativePremiumFraction () = int(k_latestShortCumulativePremiumFraction)
359359
360360
361361 func totalShortPositionSize () = int(k_totalShortPositionSize)
362362
363363
364364 func totalLongPositionSize () = int(k_totalLongPositionSize)
365365
366366
367367 func lastSequence () = intOr(k_sequence, 0)
368368
369369
370370 func feeToStakersPercent () = int(k_feeToStakersPercent)
371371
372372
373373 func maxOracleDelay () = int(k_maxOracleDelay)
374374
375375
376376 func getActualCaller (i) = valueOrElse(getString(ordersAddress(), "k_sender"), toString(i.caller))
377377
378378
379379 func requireMoreMarginRatio (_marginRatio,_baseMarginRatio,_largerThanOrEqualTo) = {
380380 let remainingMarginRatio = (_marginRatio - _baseMarginRatio)
381381 if (if (_largerThanOrEqualTo)
382382 then (0 > remainingMarginRatio)
383383 else false)
384384 then throw(((("Invalid margin: " + toString(_marginRatio)) + " < ") + toString(_baseMarginRatio)))
385385 else if (if (!(_largerThanOrEqualTo))
386386 then (remainingMarginRatio >= 0)
387387 else false)
388388 then throw(((("Invalid margin: " + toString(_marginRatio)) + " > ") + toString(_baseMarginRatio)))
389389 else true
390390 }
391391
392392
393393 func latestCumulativePremiumFraction (_positionSize) = if ((_positionSize == 0))
394394 then throw("Should not be called with _positionSize == 0")
395395 else if ((_positionSize > 0))
396396 then latestLongCumulativePremiumFraction()
397397 else latestShortCumulativePremiumFraction()
398398
399399
400400 func getPosition (_trader) = {
401401 let positionSizeOpt = getInteger(this, toCompositeKey(k_positionSize, _trader))
402402 match positionSizeOpt {
403403 case positionSize: Int =>
404404 $Tuple4(positionSize, getIntegerValue(this, toCompositeKey(k_positionMargin, _trader)), getIntegerValue(this, toCompositeKey(k_positionOpenNotional, _trader)), getIntegerValue(this, toCompositeKey(k_positionLastUpdatedCumulativePremiumFraction, _trader)))
405405 case _ =>
406406 $Tuple4(0, 0, 0, 0)
407407 }
408408 }
409409
410410
411411 func getPositionAsset (_trader) = {
412412 let positionAssetOpt = getString(this, toCompositeKey(k_positionAsset, _trader))
413413 match positionAssetOpt {
414414 case positionAsset: String =>
415415 positionAsset
416416 case _ =>
417417 toBase58String(quoteAsset())
418418 }
419419 }
420420
421421
422422 func requireOpenPosition (_trader) = if ((getPosition(_trader)._1 == 0))
423423 then throw("No open position")
424424 else true
425425
426426
427427 func initialized () = valueOrElse(getBoolean(this, k_initialized), false)
428428
429429
430430 func paused () = valueOrElse(getBoolean(this, k_paused), false)
431431
432432
433433 func closeOnly () = valueOrElse(getBoolean(this, k_closeOnly), false)
434434
435435
436436 func updateReserve (_isAdd,_quoteAssetAmount,_baseAssetAmount) = if (_isAdd)
437437 then {
438438 let newBase = (bsAstR() - _baseAssetAmount)
439439 if ((0 >= newBase))
440440 then throw("Tx lead to base asset reserve <= 0, revert")
441441 else $Tuple3((qtAstR() + _quoteAssetAmount), newBase, (totalPositionSize() + _baseAssetAmount))
442442 }
443443 else {
444444 let newQuote = (qtAstR() - _quoteAssetAmount)
445445 if ((0 >= newQuote))
446446 then throw("Tx lead to base quote reserve <= 0, revert")
447447 else $Tuple3(newQuote, (bsAstR() + _baseAssetAmount), (totalPositionSize() - _baseAssetAmount))
448448 }
449449
450450
451-func calcInvariant (_qtAstR,_qtAstW,_bsAstR,_bsAstW) = {
451+func calcInvariant (_qtAstR,_bsAstR) = {
452452 let bqtAstR = toBigInt(_qtAstR)
453- let bqtAstW = toBigInt(_qtAstW)
454453 let bbsAstR = toBigInt(_bsAstR)
455- let bbsAstW = toBigInt(_bsAstW)
456- bmuld(bmuld(bqtAstR, bqtAstW), bmuld(bbsAstR, bbsAstW))
454+ bmuld(bqtAstR, bbsAstR)
457455 }
458456
459457
460458 func swapInput (_isAdd,_quoteAssetAmount) = {
461459 let _qtAstR = qtAstR()
462460 let _bsAstR = bsAstR()
463461 let _qtAstW = qtAstW()
464462 let _bsAstW = bsAstW()
465- let k = calcInvariant(_qtAstR, _qtAstW, _bsAstR, _bsAstW)
463+ let quoteAssetAmountAdjusted = divd(_quoteAssetAmount, _qtAstW)
464+ let k = calcInvariant(_qtAstR, _bsAstR)
466465 let quoteAssetReserveAfter = if (_isAdd)
467- then (_qtAstR + _quoteAssetAmount)
468- else (_qtAstR - _quoteAssetAmount)
469- let baseAssetReserveAfter = toInt(bdivd(k, toBigInt(muld(quoteAssetReserveAfter, _qtAstW))))
470- let amountBaseAssetBoughtAbs = divd(abs((baseAssetReserveAfter - _bsAstR)), _qtAstW)
466+ then (_qtAstR + quoteAssetAmountAdjusted)
467+ else (_qtAstR - quoteAssetAmountAdjusted)
468+ let baseAssetReserveAfter = toInt(bdivd(k, toBigInt(quoteAssetReserveAfter)))
469+ let amountBaseAssetBoughtAbs = abs((baseAssetReserveAfter - _bsAstR))
471470 let amountBaseAssetBought = if (_isAdd)
472471 then amountBaseAssetBoughtAbs
473472 else -(amountBaseAssetBoughtAbs)
474- let $t01693717100 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
475- let quoteAssetReserveAfter1 = $t01693717100._1
476- let baseAssetReserveAfter1 = $t01693717100._2
477- let totalPositionSizeAfter1 = $t01693717100._3
473+ let $t01684317013 = updateReserve(_isAdd, quoteAssetAmountAdjusted, amountBaseAssetBoughtAbs)
474+ let quoteAssetReserveAfter1 = $t01684317013._1
475+ let baseAssetReserveAfter1 = $t01684317013._2
476+ let totalPositionSizeAfter1 = $t01684317013._3
478477 let priceBefore = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
479478 let marketPrice = divd(_quoteAssetAmount, amountBaseAssetBoughtAbs)
480479 let priceDiff = abs((priceBefore - marketPrice))
481480 let priceImpact = (DECIMAL_UNIT - divd(priceBefore, (priceBefore + priceDiff)))
482481 let maxPriceImpactValue = maxPriceImpact()
483482 if ((priceImpact > maxPriceImpactValue))
484483 then throw(((((((((((((("Price impact " + toString(priceImpact)) + " > max price impact ") + toString(maxPriceImpactValue)) + " before quote asset: ") + toString(_qtAstR)) + " before base asset: ") + toString(_bsAstR)) + " quote asset amount to exchange: ") + toString(_quoteAssetAmount)) + " price before: ") + toString(priceBefore)) + " marketPrice: ") + toString(marketPrice)))
485484 else $Tuple4(amountBaseAssetBought, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1)
486485 }
487486
488487
489488 func calcRemainMarginWithFundingPayment (_oldPositionSize,_oldPositionMargin,_oldPositionCumulativePremiumFraction,_marginDelta) = {
490489 let fundingPayment = if ((_oldPositionSize != 0))
491490 then {
492491 let _latestCumulativePremiumFraction = latestCumulativePremiumFraction(_oldPositionSize)
493492 muld((_latestCumulativePremiumFraction - _oldPositionCumulativePremiumFraction), _oldPositionSize)
494493 }
495494 else 0
496495 let signedMargin = ((_marginDelta - fundingPayment) + _oldPositionMargin)
497- let $t01858718714 = if ((0 > signedMargin))
496+ let $t01850018627 = if ((0 > signedMargin))
498497 then $Tuple2(0, abs(signedMargin))
499498 else $Tuple2(abs(signedMargin), 0)
500- let remainMargin = $t01858718714._1
501- let badDebt = $t01858718714._2
499+ let remainMargin = $t01850018627._1
500+ let badDebt = $t01850018627._2
502501 $Tuple3(remainMargin, badDebt, fundingPayment)
503502 }
504503
505504
506505 func swapOutputWithReserves (_isAdd,_baseAssetAmount,_checkMaxPriceImpact,_quoteAssetReserve,_quoteAssetWeight,_baseAssetReserve,_baseAssetWeight) = {
507506 let priceBefore = divd(muld(_quoteAssetReserve, _quoteAssetWeight), muld(_baseAssetReserve, _baseAssetWeight))
508507 if ((_baseAssetAmount == 0))
509508 then throw("Invalid base asset amount")
510509 else {
511- let k = calcInvariant(_quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
510+ let k = calcInvariant(_quoteAssetReserve, _baseAssetReserve)
512511 let baseAssetPoolAmountAfter = if (_isAdd)
513512 then (_baseAssetReserve + _baseAssetAmount)
514513 else (_baseAssetReserve - _baseAssetAmount)
515- let quoteAssetAfter = toInt(bdivd(k, toBigInt(muld(baseAssetPoolAmountAfter, _baseAssetWeight))))
516- let quoteAssetSold = abs((quoteAssetAfter - muld(_quoteAssetReserve, _quoteAssetWeight)))
514+ let quoteAssetAfter = toInt(bdivd(k, toBigInt(baseAssetPoolAmountAfter)))
515+ let quoteAssetDelta = abs((quoteAssetAfter - _quoteAssetReserve))
516+ let quoteAssetSold = muld(quoteAssetDelta, _quoteAssetWeight)
517517 let maxPriceImpactValue = maxPriceImpact()
518- let $t01990220063 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
519- let quoteAssetReserveAfter1 = $t01990220063._1
520- let baseAssetReserveAfter1 = $t01990220063._2
521- let totalPositionSizeAfter1 = $t01990220063._3
518+ let $t01979719959 = updateReserve(!(_isAdd), quoteAssetDelta, _baseAssetAmount)
519+ let quoteAssetReserveAfter1 = $t01979719959._1
520+ let baseAssetReserveAfter1 = $t01979719959._2
521+ let totalPositionSizeAfter1 = $t01979719959._3
522522 let marketPrice = divd(quoteAssetSold, _baseAssetAmount)
523523 let priceDiff = abs((priceBefore - marketPrice))
524524 let priceImpact = (DECIMAL_UNIT - divd(priceBefore, (priceBefore + priceDiff)))
525525 if (if ((priceImpact > maxPriceImpactValue))
526526 then _checkMaxPriceImpact
527527 else false)
528528 then throw(((((((((((((("Price impact " + toString(priceImpact)) + " > max price impact ") + toString(maxPriceImpactValue)) + " before quote asset: ") + toString(_quoteAssetReserve)) + " before base asset: ") + toString(_baseAssetReserve)) + " base asset amount to exchange: ") + toString(_baseAssetAmount)) + " price before: ") + toString(priceBefore)) + " market price: ") + toString(marketPrice)))
529529 else $Tuple7(quoteAssetSold, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1, (totalLongPositionSize() - (if (_isAdd)
530530 then abs(_baseAssetAmount)
531531 else 0)), (totalShortPositionSize() - (if (!(_isAdd))
532532 then abs(_baseAssetAmount)
533533 else 0)), priceImpact)
534534 }
535535 }
536536
537537
538538 func swapOutput (_isAdd,_baseAssetAmount,_checkMaxPriceImpact) = swapOutputWithReserves(_isAdd, _baseAssetAmount, _checkMaxPriceImpact, qtAstR(), qtAstW(), bsAstR(), bsAstW())
539539
540540
541541 func getOraclePrice () = {
542542 let oracle = valueOrErrorMessage(addressFromString(getStringValue(this, k_ora)), "")
543543 let priceKey = getStringValue(this, k_ora_key)
544544 let lastValue = valueOrErrorMessage(getInteger(oracle, priceKey), ((("Can not get oracle price. Oracle: " + toString(oracle)) + " key: ") + priceKey))
545545 let blockKey = valueOrElse(getString(this, k_ora_block_key), "")
546546 if ((blockKey != ""))
547547 then {
548548 let currentBlock = lastBlock.height
549549 let lastOracleBlock = valueOrErrorMessage(getInteger(oracle, blockKey), ((("Can not get oracle block. Oracle: " + toString(oracle)) + " key: ") + blockKey))
550550 if (((currentBlock - lastOracleBlock) > maxOracleDelay()))
551551 then throw(((("Oracle stale data. Last oracle block: " + toString(lastOracleBlock)) + " current block: ") + toString(currentBlock)))
552552 else lastValue
553553 }
554554 else lastValue
555555 }
556556
557557
558558 func isMarketClosed () = {
559559 let oracle = valueOrErrorMessage(addressFromString(getStringValue(this, k_ora)), "")
560560 let openKey = valueOrElse(getString(this, k_ora_open_key), "")
561561 if ((openKey != ""))
562562 then {
563563 let isOpen = valueOrErrorMessage(getBoolean(oracle, openKey), ((("Can not get oracle is open/closed. Oracle: " + toString(oracle)) + " key: ") + openKey))
564564 !(isOpen)
565565 }
566566 else false
567567 }
568568
569569
570570 func absPriceDiff (_oraclePrice,_quoteAssetReserve,_baseAssetReserve,_qtAstW,_bsAstW) = {
571571 let priceAfter = divd(muld(_quoteAssetReserve, _qtAstW), muld(_baseAssetReserve, _bsAstW))
572572 let averagePrice = divd((_oraclePrice + priceAfter), (2 * DECIMAL_UNIT))
573573 let absPriceDiff = divd(abs((_oraclePrice - priceAfter)), averagePrice)
574574 absPriceDiff
575575 }
576576
577577
578578 func requireNotOverSpreadLimit (_quoteAssetReserve,_baseAssetReserve) = {
579579 let oraclePrice = getOraclePrice()
580580 let _qtAstW = qtAstW()
581581 let _bsAstW = bsAstW()
582582 let absPriceDiffBefore = absPriceDiff(oraclePrice, qtAstR(), bsAstR(), _qtAstW, _bsAstW)
583583 let absPriceDiffAfter = absPriceDiff(oraclePrice, _quoteAssetReserve, _baseAssetReserve, _qtAstW, _bsAstW)
584584 if (if ((absPriceDiffAfter > maxPriceSpread()))
585585 then (absPriceDiffAfter > absPriceDiffBefore)
586586 else false)
587587 then throw(((("Price spread " + toString(absPriceDiffAfter)) + " > max price spread ") + toString(maxPriceSpread())))
588588 else true
589589 }
590590
591591
592592 func requireNotOverMaxOpenNotional (_longOpenNotional,_shortOpenNotional) = {
593593 let _maxOpenNotional = maxOpenNotional()
594594 if ((_longOpenNotional > _maxOpenNotional))
595595 then throw(((("Long open notional " + toString(_longOpenNotional)) + " > max open notional ") + toString(_maxOpenNotional)))
596596 else if ((_shortOpenNotional > _maxOpenNotional))
597597 then throw(((("Short open notional " + toString(_shortOpenNotional)) + " > max open notional ") + toString(_maxOpenNotional)))
598598 else true
599599 }
600600
601601
602602 func getSpotPrice () = {
603603 let _quoteAssetReserve = qtAstR()
604604 let _baseAssetReserve = bsAstR()
605605 let _qtAstW = qtAstW()
606606 let _bsAstW = bsAstW()
607607 divd(muld(_quoteAssetReserve, _qtAstW), muld(_baseAssetReserve, _bsAstW))
608608 }
609609
610610
611611 func isOverFluctuationLimit () = {
612612 let oraclePrice = getOraclePrice()
613613 let currentPrice = getSpotPrice()
614614 (divd(abs((oraclePrice - currentPrice)), oraclePrice) > spreadLimit())
615615 }
616616
617617
618618 func getPositionAdjustedOpenNotional (_positionSize,_option,_quoteAssetReserve,_quoteAssetWeight,_baseAssetReserve,_baseAssetWeight) = {
619619 let positionSizeAbs = abs(_positionSize)
620620 let isShort = (0 > _positionSize)
621621 let positionNotional = if ((_option == PNL_OPTION_SPOT))
622622 then {
623- let $t02501425234 = swapOutputWithReserves(!(isShort), positionSizeAbs, false, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
624- let outPositionNotional = $t02501425234._1
625- let x1 = $t02501425234._2
626- let x2 = $t02501425234._3
627- let x3 = $t02501425234._4
623+ let $t02491025130 = swapOutputWithReserves(!(isShort), positionSizeAbs, false, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
624+ let outPositionNotional = $t02491025130._1
625+ let x1 = $t02491025130._2
626+ let x2 = $t02491025130._3
627+ let x3 = $t02491025130._4
628628 outPositionNotional
629629 }
630630 else muld(positionSizeAbs, getOraclePrice())
631631 positionNotional
632632 }
633633
634634
635635 func getPositionNotionalAndUnrealizedPnlByValues (_positionSize,_positionOpenNotional,_quoteAssetReserve,_quoteAssetWeight,_baseAssetReserve,_baseAssetWeight,_option) = if ((_positionSize == 0))
636636 then throw("Invalid position size")
637637 else {
638638 let isShort = (0 > _positionSize)
639639 let positionNotional = getPositionAdjustedOpenNotional(_positionSize, _option, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
640640 let unrealizedPnl = if (isShort)
641641 then (_positionOpenNotional - positionNotional)
642642 else (positionNotional - _positionOpenNotional)
643643 $Tuple2(positionNotional, unrealizedPnl)
644644 }
645645
646646
647647 func getPositionNotionalAndUnrealizedPnl (_trader,_option) = {
648- let $t02665526783 = getPosition(_trader)
649- let positionSize = $t02665526783._1
650- let positionMargin = $t02665526783._2
651- let positionOpenNotional = $t02665526783._3
652- let positionLstUpdCPF = $t02665526783._4
648+ let $t02655126679 = getPosition(_trader)
649+ let positionSize = $t02655126679._1
650+ let positionMargin = $t02655126679._2
651+ let positionOpenNotional = $t02655126679._3
652+ let positionLstUpdCPF = $t02655126679._4
653653 getPositionNotionalAndUnrealizedPnlByValues(positionSize, positionOpenNotional, qtAstR(), qtAstW(), bsAstR(), bsAstW(), _option)
654654 }
655655
656656
657657 func calcMarginRatio (_remainMargin,_badDebt,_positionNotional) = divd((_remainMargin - _badDebt), _positionNotional)
658658
659659
660660 func getMarginRatioByOption (_trader,_option) = {
661- let $t02729627407 = getPosition(_trader)
662- let positionSize = $t02729627407._1
663- let positionMargin = $t02729627407._2
664- let pon = $t02729627407._3
665- let positionLstUpdCPF = $t02729627407._4
666- let $t02741327506 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
667- let positionNotional = $t02741327506._1
668- let unrealizedPnl = $t02741327506._2
669- let $t02751127677 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
670- let remainMargin = $t02751127677._1
671- let badDebt = $t02751127677._2
661+ let $t02719227303 = getPosition(_trader)
662+ let positionSize = $t02719227303._1
663+ let positionMargin = $t02719227303._2
664+ let pon = $t02719227303._3
665+ let positionLstUpdCPF = $t02719227303._4
666+ let $t02730927402 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
667+ let positionNotional = $t02730927402._1
668+ let unrealizedPnl = $t02730927402._2
669+ let $t02740727573 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
670+ let remainMargin = $t02740727573._1
671+ let badDebt = $t02740727573._2
672672 calcMarginRatio(remainMargin, badDebt, positionNotional)
673673 }
674674
675675
676676 func getMarginRatio (_trader) = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
677677
678678
679679 func getPartialLiquidationAmount (_trader,_positionSize) = {
680680 let maximumRatio = vmax(partialLiquidationRatio(), (DECIMAL_UNIT - divd(getMarginRatio(_trader), maintenanceMarginRatio())))
681681 let maxExchangedPositionSize = muld(abs(_positionSize), maximumRatio)
682682 let swapResult = swapOutput((_positionSize > 0), maxExchangedPositionSize, false)
683683 let maxExchangedQuoteAssetAmount = swapResult._1
684684 let priceImpact = swapResult._7
685685 if ((maxPriceImpact() > priceImpact))
686686 then maxExchangedQuoteAssetAmount
687687 else {
688688 let exchangedPositionSize = muld(abs(_positionSize), partialLiquidationRatio())
689689 let exchangedQuoteAssetAmount = swapOutput((_positionSize > 0), exchangedPositionSize, false)._1
690690 exchangedQuoteAssetAmount
691691 }
692692 }
693693
694694
695695 func internalClosePosition (_trader,_checkMaxPriceImpact) = {
696- let $t02891729045 = getPosition(_trader)
697- let positionSize = $t02891729045._1
698- let positionMargin = $t02891729045._2
699- let positionOpenNotional = $t02891729045._3
700- let positionLstUpdCPF = $t02891729045._4
696+ let $t02881328941 = getPosition(_trader)
697+ let positionSize = $t02881328941._1
698+ let positionMargin = $t02881328941._2
699+ let positionOpenNotional = $t02881328941._3
700+ let positionLstUpdCPF = $t02881328941._4
701701 let unrealizedPnl = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)._2
702- let $t02914029308 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
703- let remainMargin = $t02914029308._1
704- let badDebt = $t02914029308._2
702+ let $t02903629204 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
703+ let remainMargin = $t02903629204._1
704+ let badDebt = $t02903629204._2
705705 let exchangedPositionSize = -(positionSize)
706706 let realizedPnl = unrealizedPnl
707707 let marginToVault = -(remainMargin)
708- let $t02943529709 = swapOutput((positionSize > 0), abs(positionSize), _checkMaxPriceImpact)
709- let exchangedQuoteAssetAmount = $t02943529709._1
710- let quoteAssetReserveAfter = $t02943529709._2
711- let baseAssetReserveAfter = $t02943529709._3
712- let totalPositionSizeAfter = $t02943529709._4
713- let totalLongAfter = $t02943529709._5
714- let totalShortAfter = $t02943529709._6
708+ let $t02933129605 = swapOutput((positionSize > 0), abs(positionSize), _checkMaxPriceImpact)
709+ let exchangedQuoteAssetAmount = $t02933129605._1
710+ let quoteAssetReserveAfter = $t02933129605._2
711+ let baseAssetReserveAfter = $t02933129605._3
712+ let totalPositionSizeAfter = $t02933129605._4
713+ let totalLongAfter = $t02933129605._5
714+ let totalShortAfter = $t02933129605._6
715715 let openInterestNotionalAfter = (openInterestNotional() - positionOpenNotional)
716716 $Tuple13(exchangedPositionSize, badDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, exchangedQuoteAssetAmount, totalLongAfter, totalShortAfter, (openInterestLong() - (if ((positionSize > 0))
717717 then positionOpenNotional
718718 else 0)), (openInterestShort() - (if ((0 > positionSize))
719719 then positionOpenNotional
720720 else 0)))
721721 }
722722
723723
724724 func getTwapSpotPrice () = {
725725 let minuteId = ((lastBlock.timestamp / 1000) / 60)
726726 let startMinuteId = (minuteId - TWAP_INTERVAL)
727727 let listStr = valueOrElse(getString(this, k_lastDataStr), "")
728728 let list = split(listStr, ",")
729729 func filterFn (accumulator,next) = if ((startMinuteId >= parseIntValue(next)))
730730 then (accumulator :+ parseIntValue(next))
731731 else accumulator
732732
733733 let listF = {
734734 let $l = list
735735 let $s = size($l)
736736 let $acc0 = nil
737737 func $f0_1 ($a,$i) = if (($i >= $s))
738738 then $a
739739 else filterFn($a, $l[$i])
740740
741741 func $f0_2 ($a,$i) = if (($i >= $s))
742742 then $a
743743 else throw("List size exceeds 20")
744744
745745 $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)
746746 }
747747 let maxIndex = if ((size(listF) > 0))
748748 then max(listF)
749749 else parseIntValue(list[0])
750750 let lastMinuteId = valueOrElse(getInteger(this, k_lastMinuteId), 0)
751751 let endLastCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(lastMinuteId))), 0)
752752 let endLastPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(lastMinuteId))), 0)
753753 let nowCumulativePrice = (endLastCumulativePrice + ((minuteId - lastMinuteId) * endLastPrice))
754754 let startLastCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(maxIndex))), 0)
755755 let startLastPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(maxIndex))), 0)
756756 let startCumulativePrice = (startLastCumulativePrice + ((startMinuteId - maxIndex) * startLastPrice))
757757 ((nowCumulativePrice - startCumulativePrice) / TWAP_INTERVAL)
758758 }
759759
760760
761761 func getTerminalAmmState () = {
762762 let _positionSize = totalPositionSize()
763763 if ((_positionSize == 0))
764764 then $Tuple2(qtAstR(), bsAstR())
765765 else {
766766 let direction = (_positionSize > 0)
767- let $t03183232011 = swapOutput(direction, abs(_positionSize), false)
768- let currentNetMarketValue = $t03183232011._1
769- let terminalQuoteAssetReserve = $t03183232011._2
770- let terminalBaseAssetReserve = $t03183232011._3
767+ let $t03172831907 = swapOutput(direction, abs(_positionSize), false)
768+ let currentNetMarketValue = $t03172831907._1
769+ let terminalQuoteAssetReserve = $t03172831907._2
770+ let terminalBaseAssetReserve = $t03172831907._3
771771 $Tuple2(terminalQuoteAssetReserve, terminalBaseAssetReserve)
772772 }
773773 }
774774
775775
776776 func getQuoteAssetWeight (baseAssetReserve,totalPositionSize,quoteAssetReserve,targetPrice) = {
777777 let b = toBigInt(baseAssetReserve)
778778 let sz = toBigInt(totalPositionSize)
779779 let q = toBigInt(quoteAssetReserve)
780780 let p = toBigInt(targetPrice)
781- let bs2 = bpowd((b + sz), toBigInt((2 * DECIMAL_UNIT)))
782- let qbs2 = bmuld(q, bs2)
783- let ps4 = (toBigInt(4) * bmuld(p, sz))
784- let sqr = bsqrtd(bmuld(qbs2, (q - ps4)))
785- let bq = bmuld(b, q)
786- let qs = bmuld(q, sz)
787- let top = ((-(sqr) + bq) + qs)
788- let bot = (toBigInt(2) * bmuld(q, sz))
789- let result = bdivd(top, bot)
781+ let k = bmuld(q, b)
782+ let newB = (b + sz)
783+ let newQ = bdivd(k, newB)
784+ let z = bdivd(newQ, newB)
785+ let result = bdivd(p, z)
790786 toInt(result)
791787 }
792788
793789
794790 func getSyncTerminalPrice (_terminalPrice,_qtAstR,_bsAstR) = {
795791 let _positionSize = totalPositionSize()
796792 if ((_positionSize == 0))
797793 then {
798794 let newQtAstW = divd(muld(_terminalPrice, _bsAstR), _qtAstR)
799795 $Tuple3(newQtAstW, DECIMAL_UNIT, 0)
800796 }
801797 else {
802798 let direction = (_positionSize > 0)
803799 let currentNetMarketValue = swapOutput(direction, abs(_positionSize), false)._1
804800 let newQtAstW = getQuoteAssetWeight(_bsAstR, _positionSize, _qtAstR, _terminalPrice)
805801 let newBsAstW = DECIMAL_UNIT
806802 let marginToVault = getPositionNotionalAndUnrealizedPnlByValues(_positionSize, currentNetMarketValue, _qtAstR, newQtAstW, _bsAstR, newBsAstW, PNL_OPTION_SPOT)._2
807803 $Tuple3(newQtAstW, newBsAstW, marginToVault)
808804 }
809805 }
810806
811807
812808 func getFunding () = {
813809 let underlyingPrice = getOraclePrice()
814810 let spotTwapPrice = getTwapSpotPrice()
815811 let premium = (spotTwapPrice - underlyingPrice)
816812 if (if (if ((totalShortPositionSize() == 0))
817813 then true
818814 else (totalLongPositionSize() == 0))
819815 then true
820816 else isMarketClosed())
821817 then $Tuple2(0, 0)
822818 else if ((0 > premium))
823819 then {
824820 let shortPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
825821 let longPremiumFraction = divd(muld(shortPremiumFraction, totalShortPositionSize()), totalLongPositionSize())
826822 $Tuple2(shortPremiumFraction, longPremiumFraction)
827823 }
828824 else {
829825 let longPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
830826 let shortPremiumFraction = divd(muld(longPremiumFraction, totalLongPositionSize()), totalShortPositionSize())
831827 $Tuple2(shortPremiumFraction, longPremiumFraction)
832828 }
833829 }
834830
835831
836832 func getAdjustedFee (_artifactId,_baseFeeDiscount) = {
837833 let baseFeeRaw = fee()
838834 let baseFee = muld(baseFeeRaw, _baseFeeDiscount)
839- let $t03505935554 = if ((_artifactId != ""))
835+ let $t03476835263 = if ((_artifactId != ""))
840836 then {
841837 let artifactKind = strA(nftManagerAddress(), toCompositeKey(k_token_type, _artifactId))
842838 if ((artifactKind == FEE_REDUCTION_TOKEN_TYPE))
843839 then {
844840 let reduction = intA(nftManagerAddress(), toCompositeKey(k_token_param, _artifactId))
845841 let adjustedFee = muld(baseFee, reduction)
846842 $Tuple2(adjustedFee, true)
847843 }
848844 else throw("Invalid attached artifact")
849845 }
850846 else $Tuple2(baseFee, false)
851- let adjustedFee = $t03505935554._1
852- let burnArtifact = $t03505935554._2
847+ let adjustedFee = $t03476835263._1
848+ let burnArtifact = $t03476835263._2
853849 $Tuple2(adjustedFee, burnArtifact)
854850 }
855851
856852
857853 func isSameAssetOrNoPosition (_trader,_assetId) = {
858854 let oldPositionSize = getPosition(_trader)._1
859855 if ((oldPositionSize == 0))
860856 then true
861857 else (getPositionAsset(_trader) == _assetId)
862858 }
863859
864860
865861 func isSameAsset (_trader,_assetId) = (getPositionAsset(_trader) == _assetId)
866862
867863
868864 func getBorrowedByTraderInMarketKey (_amm,_assetId,_trader) = ((((((k_trader_market_asset_collateral + "_") + _amm) + "_") + _assetId) + "_") + _trader)
869865
870866
871867 func getBorrowedByTrader (_trader) = {
872868 let positionAsset = getPositionAsset(_trader)
873869 if ((positionAsset == toBase58String(quoteAsset())))
874870 then $Tuple2(0, positionAsset)
875871 else {
876872 let key = getBorrowedByTraderInMarketKey(toString(this), positionAsset, _trader)
877873 let borrow = valueOrElse(getInteger(collateralAddress(), key), 0)
878874 $Tuple2(borrow, positionAsset)
879875 }
880876 }
881877
882878
883879 func getForTraderWithArtifact (_trader,_artifactId) = {
884880 let doGetFeeDiscount = invoke(minerAddress(), "computeFeeDiscount", [_trader], nil)
885881 if ((doGetFeeDiscount == doGetFeeDiscount))
886882 then {
887883 let feeDiscount = match doGetFeeDiscount {
888884 case x: Int =>
889885 x
890886 case _ =>
891887 throw("Invalid computeFeeDiscount result")
892888 }
893- let $t03678536859 = getAdjustedFee(_artifactId, feeDiscount)
894- let adjustedFee = $t03678536859._1
895- let burnArtifact = $t03678536859._2
889+ let $t03649436568 = getAdjustedFee(_artifactId, feeDiscount)
890+ let adjustedFee = $t03649436568._1
891+ let burnArtifact = $t03649436568._2
896892 $Tuple2(adjustedFee, burnArtifact)
897893 }
898894 else throw("Strict value is not equal to itself.")
899895 }
900896
901897
902898 func getArtifactId (i) = {
903899 let artifactId = if ((size(i.payments) > 1))
904900 then toBase58String(valueOrErrorMessage(i.payments[1].assetId, "Invalid artifactId"))
905901 else ""
906902 artifactId
907903 }
908904
909905
910906 func distributeFee (_feeAmount) = {
911907 let feeToStakers = muld(_feeAmount, feeToStakersPercent())
912908 let feeToVault = (_feeAmount - feeToStakers)
913909 $Tuple2(feeToStakers, feeToVault)
914910 }
915911
916912
917913 func updateSettings (_initMarginRatio,_mmr,_liquidationFeeRatio,_fundingPeriod,_fee,_spreadLimit,_maxPriceImpact,_partialLiquidationRatio,_maxPriceSpread,_maxOpenNotional,_feeToStakersPercent,_maxOracleDelay) = [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), IntegerEntry(k_partialLiquidationRatio, _partialLiquidationRatio), IntegerEntry(k_maxPriceSpread, _maxPriceSpread), IntegerEntry(k_maxOpenNotional, _maxOpenNotional), IntegerEntry(k_feeToStakersPercent, _feeToStakersPercent), IntegerEntry(k_maxOracleDelay, _feeToStakersPercent)]
918914
919915
920916 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)]
921917
922918
923919 func updatePositionAsset (_address,_assetId) = [StringEntry(toCompositeKey(k_positionAsset, _address), _assetId)]
924920
925921
926922 func incrementPositionSequenceNumber (isNewPosition,_address) = if (isNewPosition)
927923 then {
928924 let currentSequence = lastSequence()
929925 [IntegerEntry(toCompositeKey(k_positionSequence, _address), (currentSequence + 1)), IntegerEntry(k_sequence, (currentSequence + 1))]
930926 }
931927 else nil
932928
933929
934930 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)]
935931
936932
937933 func appendTwap (_price) = {
938934 let minuteId = ((lastBlock.timestamp / 1000) / 60)
939935 let previousMinuteId = valueOrElse(getInteger(this, k_lastMinuteId), 0)
940936 if ((previousMinuteId > minuteId))
941937 then throw("TWAP out-of-order")
942938 else {
943939 let lastMinuteId = if ((previousMinuteId == 0))
944940 then minuteId
945941 else previousMinuteId
946942 if ((minuteId > previousMinuteId))
947943 then {
948944 let prevCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(previousMinuteId))), 0)
949945 let prevPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(previousMinuteId))), _price)
950946 let lastCumulativePrice = (prevCumulativePrice + ((minuteId - lastMinuteId) * prevPrice))
951947 let list = pushToQueue(strToList(valueOrElse(getString(this, k_lastDataStr), "")), TWAP_INTERVAL, toString(minuteId))
952948 [IntegerEntry(toCompositeKey(k_twapDataLastCumulativePrice, toString(minuteId)), lastCumulativePrice), IntegerEntry(toCompositeKey(k_twapDataLastPrice, toString(minuteId)), _price), IntegerEntry(toCompositeKey(k_twapDataPreviousMinuteId, toString(minuteId)), previousMinuteId), IntegerEntry(k_lastMinuteId, minuteId), StringEntry(k_lastDataStr, listToStr(list))]
953949 }
954950 else {
955951 let twapDataPreviousMinuteId = valueOrElse(getInteger(this, toCompositeKey(k_twapDataPreviousMinuteId, toString(minuteId))), 0)
956952 let prevCumulativePrice = valueOrElse(getInteger(this, toCompositeKey(k_twapDataLastCumulativePrice, toString(twapDataPreviousMinuteId))), 0)
957953 let prevPrice = valueOrElse(getInteger(this, toCompositeKey(k_twapDataLastPrice, toString(twapDataPreviousMinuteId))), _price)
958954 let lastCumulativePrice = (prevCumulativePrice + ((minuteId - twapDataPreviousMinuteId) * prevPrice))
959955 [IntegerEntry(toCompositeKey(k_twapDataLastCumulativePrice, toString(minuteId)), lastCumulativePrice), IntegerEntry(toCompositeKey(k_twapDataLastPrice, toString(minuteId)), _price)]
960956 }
961957 }
962958 }
963959
964960
965961 func updateAmmReserves (_qtAstR,_bsAstR) = [IntegerEntry(k_quoteAssetReserve, _qtAstR), IntegerEntry(k_baseAssetReserve, _bsAstR)]
966962
967963
968964 func updateAmmWeights (_qtAstW,_bsAstW) = [IntegerEntry(k_quoteAssetWeight, _qtAstW), IntegerEntry(k_baseAssetWeight, _bsAstW)]
969965
970966
971967 func updateAmm (_qtAstR,_bsAstR,_totalPositionSizeAfter,_openInterestNotional,_totalLongPositionSize,_totalShortPositionSize,_totalLongOpenNotional,_totalShortOpenNotional) = {
972968 let _qtAstW = qtAstW()
973969 let _bsAstW = bsAstW()
974970 if (((_totalLongPositionSize - _totalShortPositionSize) != _totalPositionSizeAfter))
975971 then throw(((((("Invalid AMM state data: " + toString(_totalLongPositionSize)) + " + ") + toString(_totalShortPositionSize)) + " != ") + toString(_totalPositionSizeAfter)))
976972 else ((updateAmmReserves(_qtAstR, _bsAstR) ++ [IntegerEntry(k_totalPositionSize, _totalPositionSizeAfter), IntegerEntry(k_openInterestNotional, _openInterestNotional), IntegerEntry(k_totalLongPositionSize, _totalLongPositionSize), IntegerEntry(k_totalShortPositionSize, _totalShortPositionSize), IntegerEntry(k_openInterestLong, _totalLongOpenNotional), IntegerEntry(k_openInterestShort, _totalShortOpenNotional)]) ++ appendTwap(divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))))
977973 }
978974
979975
980976 func deletePosition (_address) = [DeleteEntry(toCompositeKey(k_positionSize, _address)), DeleteEntry(toCompositeKey(k_positionMargin, _address)), DeleteEntry(toCompositeKey(k_positionOpenNotional, _address)), DeleteEntry(toCompositeKey(k_positionLastUpdatedCumulativePremiumFraction, _address)), DeleteEntry(toCompositeKey(k_positionAsset, _address))]
981977
982978
983979 func withdraw (_address,_amount) = {
984980 let balance = assetBalance(this, quoteAsset())
985981 if ((_amount > balance))
986982 then throw(((("Unable to withdraw " + toString(_amount)) + " from contract balance ") + toString(balance)))
987983 else [ScriptTransfer(_address, _amount, quoteAsset())]
988984 }
989985
990986
991987 func updateBalance (i) = if ((0 > i))
992988 then throw("Balance")
993989 else [IntegerEntry(k_balance, i)]
994990
995991
996992 func transferFee (i) = [ScriptTransfer(stakingAddress(), i, quoteAsset())]
997993
998994
999995 func doBurnArtifact (_burnArtifact,i) = if (_burnArtifact)
1000996 then [Burn(valueOrErrorMessage(i.payments[1].assetId, "Invalid artifact"), 1)]
1001997 else nil
1002998
1003999
10041000 @Callable(i)
10051001 func pause () = if ((i.caller != adminAddress()))
10061002 then throw("Invalid pause params")
10071003 else [BooleanEntry(k_paused, true)]
10081004
10091005
10101006
10111007 @Callable(i)
10121008 func unpause () = if ((i.caller != adminAddress()))
10131009 then throw("Invalid unpause params")
10141010 else [BooleanEntry(k_paused, false)]
10151011
10161012
10171013
10181014 @Callable(i)
10191015 func setCloseOnly () = if ((i.caller != adminAddress()))
10201016 then throw("Invalid setCloseOnly params")
10211017 else [BooleanEntry(k_closeOnly, true)]
10221018
10231019
10241020
10251021 @Callable(i)
10261022 func unsetCloseOnly () = if ((i.caller != adminAddress()))
10271023 then throw("Invalid unsetCloseOnly params")
10281024 else [BooleanEntry(k_closeOnly, false)]
10291025
10301026
10311027
10321028 @Callable(i)
10331029 func addLiquidity (_quoteAssetAmount) = if (if ((i.caller != adminAddress()))
10341030 then true
10351031 else (0 >= _quoteAssetAmount))
10361032 then throw("Invalid addLiquidity params")
10371033 else {
10381034 let _qtAstR = qtAstR()
10391035 let _bsAstR = bsAstR()
10401036 let _qtAstW = qtAstW()
10411037 let _bsAstW = bsAstW()
10421038 let price = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
10431039 let qtAstRAfter = (_qtAstR + _quoteAssetAmount)
10441040 let baseAssetAmountToAdd = (divd(muld(qtAstRAfter, _qtAstW), price) - _bsAstR)
10451041 let bsAstRAfter = (_bsAstR + baseAssetAmountToAdd)
1046- let $t04588146032 = getSyncTerminalPrice(getOraclePrice(), qtAstRAfter, bsAstRAfter)
1047- let newQuoteAssetWeight = $t04588146032._1
1048- let newBaseAssetWeight = $t04588146032._2
1049- let marginToVault = $t04588146032._3
1042+ let $t04559045741 = getSyncTerminalPrice(getOraclePrice(), qtAstRAfter, bsAstRAfter)
1043+ let newQuoteAssetWeight = $t04559045741._1
1044+ let newBaseAssetWeight = $t04559045741._2
1045+ let marginToVault = $t04559045741._3
10501046 let doExchangePnL = if ((marginToVault != 0))
10511047 then {
10521048 let doExchangePnL = invoke(vaultAddress(), "exchangeFreeAndLocked", [marginToVault], nil)
10531049 if ((doExchangePnL == doExchangePnL))
10541050 then nil
10551051 else throw("Strict value is not equal to itself.")
10561052 }
10571053 else nil
10581054 if ((doExchangePnL == doExchangePnL))
10591055 then (updateAmmReserves(qtAstRAfter, bsAstRAfter) ++ updateAmmWeights(newQuoteAssetWeight, newBaseAssetWeight))
10601056 else throw("Strict value is not equal to itself.")
10611057 }
10621058
10631059
10641060
10651061 @Callable(i)
10661062 func removeLiquidity (_quoteAssetAmount) = if (if ((i.caller != adminAddress()))
10671063 then true
10681064 else (0 >= _quoteAssetAmount))
10691065 then throw("Invalid removeLiquidity params")
10701066 else {
10711067 let _qtAstR = qtAstR()
10721068 let _bsAstR = bsAstR()
10731069 let _qtAstW = qtAstW()
10741070 let _bsAstW = bsAstW()
10751071 let price = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
10761072 let baseAssetAmountToRemove = divd(_quoteAssetAmount, price)
10771073 let qtAstRAfter = (_qtAstR - _quoteAssetAmount)
10781074 let bsAstRAfter = (_bsAstR - baseAssetAmountToRemove)
10791075 updateAmmReserves(qtAstRAfter, bsAstRAfter)
10801076 }
10811077
10821078
10831079
10841080 @Callable(i)
10851081 func changeSettings (_initMarginRatio,_mmr,_liquidationFeeRatio,_fundingPeriod,_fee,_spreadLimit,_maxPriceImpact,_partialLiquidationRatio,_maxPriceSpread,_maxOpenNotional,_feeToStakersPercent,_maxOracleDelay) = if ((i.caller != adminAddress()))
10861082 then throw("Invalid changeSettings params")
10871083 else updateSettings(_initMarginRatio, _mmr, _liquidationFeeRatio, _fundingPeriod, _fee, _spreadLimit, _maxPriceImpact, _partialLiquidationRatio, _maxPriceSpread, _maxOpenNotional, _feeToStakersPercent, _maxOracleDelay)
10881084
10891085
10901086
10911087 @Callable(i)
10921088 func initialize (_qtAstR,_bsAstR,_fundingPeriod,_initMarginRatio,_mmr,_liquidationFeeRatio,_fee,_oracle,_oracleKey,_oracleBlockKey,_coordinator,_spreadLimit,_maxPriceImpact,_partialLiquidationRatio,_maxPriceSpread,_maxOpenNotional,_feeToStakersPercent,_maxOracleDelay) = if (if (if (if (if (if (if (if (if (if (if (if (if (if (if (if ((0 >= _qtAstR))
10931089 then true
10941090 else (0 >= _bsAstR))
10951091 then true
10961092 else (0 >= _fundingPeriod))
10971093 then true
10981094 else (0 >= _initMarginRatio))
10991095 then true
11001096 else (0 >= _mmr))
11011097 then true
11021098 else (0 >= _liquidationFeeRatio))
11031099 then true
11041100 else (0 >= _fee))
11051101 then true
11061102 else (0 >= _spreadLimit))
11071103 then true
11081104 else (0 >= _maxPriceImpact))
11091105 then true
11101106 else (0 >= _partialLiquidationRatio))
11111107 then true
11121108 else (0 >= _maxPriceSpread))
11131109 then true
11141110 else (0 >= _maxOpenNotional))
11151111 then true
11161112 else (0 >= _feeToStakersPercent))
11171113 then true
11181114 else (_feeToStakersPercent > DECIMAL_UNIT))
11191115 then true
11201116 else (0 >= _maxOracleDelay))
11211117 then true
11221118 else initialized())
11231119 then throw("Invalid initialize parameters")
11241120 else ((((updateAmm(_qtAstR, _bsAstR, 0, 0, 0, 0, 0, 0) ++ updateSettings(_initMarginRatio, _mmr, _liquidationFeeRatio, _fundingPeriod, _fee, _spreadLimit, _maxPriceImpact, _partialLiquidationRatio, _maxPriceSpread, _maxOpenNotional, _feeToStakersPercent, _maxOracleDelay)) ++ 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_ora_block_key, _oracleBlockKey), StringEntry(k_coordinatorAddress, _coordinator)])
11251121
11261122
11271123
11281124 @Callable(i)
11291125 func decreasePosition (_amount,_leverage,_minBaseAssetAmount) = {
11301126 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
11311127 if ((sync == sync))
11321128 then {
11331129 let _trader = getActualCaller(i)
11341130 if (if (if (if (if (if ((0 >= _amount))
11351131 then true
11361132 else !(initialized()))
11371133 then true
11381134 else !(requireMoreMarginRatio(divd(DECIMAL_UNIT, _leverage), initMarginRatio(), true)))
11391135 then true
11401136 else !(requireOpenPosition(_trader)))
11411137 then true
11421138 else paused())
11431139 then true
11441140 else isMarketClosed())
11451141 then throw("Invalid decreasePosition parameters")
11461142 else {
1147- let $t04989950039 = getPosition(_trader)
1148- let oldPositionSize = $t04989950039._1
1149- let oldPositionMargin = $t04989950039._2
1150- let oldPositionOpenNotional = $t04989950039._3
1151- let oldPositionLstUpdCPF = $t04989950039._4
1143+ let $t04960849748 = getPosition(_trader)
1144+ let oldPositionSize = $t04960849748._1
1145+ let oldPositionMargin = $t04960849748._2
1146+ let oldPositionOpenNotional = $t04960849748._3
1147+ let oldPositionLstUpdCPF = $t04960849748._4
11521148 let _direction = if ((oldPositionSize > 0))
11531149 then DIR_SHORT
11541150 else DIR_LONG
11551151 let isAdd = (_direction == DIR_LONG)
11561152 let openNotional = muld(_amount, _leverage)
1157- let $t05021250316 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1158- let oldPositionNotional = $t05021250316._1
1159- let unrealizedPnl = $t05021250316._2
1160- let $t05032252964 = if ((oldPositionNotional > openNotional))
1153+ let $t04992150025 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1154+ let oldPositionNotional = $t04992150025._1
1155+ let unrealizedPnl = $t04992150025._2
1156+ let $t05003152673 = if ((oldPositionNotional > openNotional))
11611157 then {
1162- let $t05073750921 = swapInput(isAdd, openNotional)
1163- let exchangedPositionSize = $t05073750921._1
1164- let quoteAssetReserveAfter = $t05073750921._2
1165- let baseAssetReserveAfter = $t05073750921._3
1166- let totalPositionSizeAfter = $t05073750921._4
1158+ let $t05044650630 = swapInput(isAdd, openNotional)
1159+ let exchangedPositionSize = $t05044650630._1
1160+ let quoteAssetReserveAfter = $t05044650630._2
1161+ let baseAssetReserveAfter = $t05044650630._3
1162+ let totalPositionSizeAfter = $t05044650630._4
11671163 let exchangedPositionSizeAbs = abs(exchangedPositionSize)
11681164 if (if ((_minBaseAssetAmount != 0))
11691165 then (_minBaseAssetAmount > exchangedPositionSizeAbs)
11701166 else false)
11711167 then throw(((("Too little base asset exchanged, got " + toString(exchangedPositionSizeAbs)) + " expected ") + toString(_minBaseAssetAmount)))
11721168 else {
11731169 let realizedPnl = divd(muld(unrealizedPnl, exchangedPositionSizeAbs), abs(oldPositionSize))
1174- let $t05135851587 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1175- let remainMargin = $t05135851587._1
1176- let badDebt = $t05135851587._2
1170+ let $t05106751296 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1171+ let remainMargin = $t05106751296._1
1172+ let badDebt = $t05106751296._2
11771173 let exchangedQuoteAssetAmount = openNotional
11781174 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
11791175 let remainOpenNotional = if ((oldPositionSize > 0))
11801176 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
11811177 else ((unrealizedPnlAfter + oldPositionNotional) - exchangedQuoteAssetAmount)
11821178 let newPositionSize = (oldPositionSize + exchangedPositionSize)
11831179 $Tuple12(newPositionSize, remainMargin, abs(remainOpenNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, (openInterestNotional() - openNotional), (totalLongPositionSize() - (if ((newPositionSize > 0))
11841180 then abs(exchangedPositionSize)
11851181 else 0)), (totalShortPositionSize() - (if ((0 > newPositionSize))
11861182 then abs(exchangedPositionSize)
11871183 else 0)), (openInterestLong() - (if ((newPositionSize > 0))
11881184 then openNotional
11891185 else 0)), (openInterestShort() - (if ((0 > newPositionSize))
11901186 then openNotional
11911187 else 0)))
11921188 }
11931189 }
11941190 else throw("Close position first")
1195- let newPositionSize = $t05032252964._1
1196- let newPositionRemainMargin = $t05032252964._2
1197- let newPositionOpenNotional = $t05032252964._3
1198- let newPositionLatestCPF = $t05032252964._4
1199- let baseAssetReserveAfter = $t05032252964._5
1200- let quoteAssetReserveAfter = $t05032252964._6
1201- let totalPositionSizeAfter = $t05032252964._7
1202- let openInterestNotionalAfter = $t05032252964._8
1203- let totalLongAfter = $t05032252964._9
1204- let totalShortAfter = $t05032252964._10
1205- let totalLongOpenInterestAfter = $t05032252964._11
1206- let totalShortOpenInterestAfter = $t05032252964._12
1191+ let newPositionSize = $t05003152673._1
1192+ let newPositionRemainMargin = $t05003152673._2
1193+ let newPositionOpenNotional = $t05003152673._3
1194+ let newPositionLatestCPF = $t05003152673._4
1195+ let baseAssetReserveAfter = $t05003152673._5
1196+ let quoteAssetReserveAfter = $t05003152673._6
1197+ let totalPositionSizeAfter = $t05003152673._7
1198+ let openInterestNotionalAfter = $t05003152673._8
1199+ let totalLongAfter = $t05003152673._9
1200+ let totalShortAfter = $t05003152673._10
1201+ let totalLongOpenInterestAfter = $t05003152673._11
1202+ let totalShortOpenInterestAfter = $t05003152673._12
12071203 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, newPositionOpenNotional], nil)
12081204 if ((notifyNotional == notifyNotional))
12091205 then (updatePosition(_trader, newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter))
12101206 else throw("Strict value is not equal to itself.")
12111207 }
12121208 }
12131209 else throw("Strict value is not equal to itself.")
12141210 }
12151211
12161212
12171213
12181214 @Callable(i)
12191215 func increasePosition (_direction,_leverage,_minBaseAssetAmount,_refLink) = {
12201216 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
12211217 if ((sync == sync))
12221218 then {
12231219 let _trader = getActualCaller(i)
12241220 let _rawAmount = i.payments[0].amount
12251221 let _assetId = i.payments[0].assetId
12261222 let _assetIdStr = toBase58String(value(_assetId))
12271223 let isQuoteAsset = (_assetId == quoteAsset())
12281224 let isCollateralAsset = isWhitelistAsset(_assetIdStr)
12291225 if (if (if (if (if (if (if (if (if (if ((_direction != DIR_LONG))
12301226 then (_direction != DIR_SHORT)
12311227 else false)
12321228 then true
12331229 else (0 >= _rawAmount))
12341230 then true
12351231 else !(initialized()))
12361232 then true
12371233 else if (!(isQuoteAsset))
12381234 then !(isCollateralAsset)
12391235 else false)
12401236 then true
12411237 else !(isSameAssetOrNoPosition(_trader, _assetIdStr)))
12421238 then true
12431239 else !(requireMoreMarginRatio(divd(DECIMAL_UNIT, _leverage), initMarginRatio(), true)))
12441240 then true
12451241 else paused())
12461242 then true
12471243 else closeOnly())
12481244 then true
12491245 else isMarketClosed())
12501246 then throw("Invalid increasePosition parameters")
12511247 else {
1252- let $t05442654511 = getForTraderWithArtifact(_trader, getArtifactId(i))
1253- let adjustedFee = $t05442654511._1
1254- let burnArtifact = $t05442654511._2
1248+ let $t05413554220 = getForTraderWithArtifact(_trader, getArtifactId(i))
1249+ let adjustedFee = $t05413554220._1
1250+ let burnArtifact = $t05413554220._2
12551251 let rawFeeAmount = muld(_rawAmount, adjustedFee)
12561252 let _amount = (_rawAmount - rawFeeAmount)
12571253 let distributeFeeAmount = if (isCollateralAsset)
12581254 then {
12591255 let doBorrow = invoke(collateralAddress(), "borrow", [_trader], [AttachedPayment(_assetId, _amount)])
12601256 if ((doBorrow == doBorrow))
12611257 then {
12621258 let balanceBefore = assetBalance(this, quoteAsset())
12631259 if ((balanceBefore == balanceBefore))
12641260 then {
12651261 let doSwap = invoke(swapAddress(), "swap", [toBase58String(quoteAsset()), 0], [AttachedPayment(_assetId, rawFeeAmount)])
12661262 if ((doSwap == doSwap))
12671263 then {
12681264 let balanceAfter = assetBalance(this, quoteAsset())
12691265 if ((balanceAfter == balanceAfter))
12701266 then {
12711267 let exchangedAmount = (balanceAfter - balanceBefore)
12721268 if ((exchangedAmount == exchangedAmount))
12731269 then exchangedAmount
12741270 else throw("Strict value is not equal to itself.")
12751271 }
12761272 else throw("Strict value is not equal to itself.")
12771273 }
12781274 else throw("Strict value is not equal to itself.")
12791275 }
12801276 else throw("Strict value is not equal to itself.")
12811277 }
12821278 else throw("Strict value is not equal to itself.")
12831279 }
12841280 else rawFeeAmount
12851281 if ((distributeFeeAmount == distributeFeeAmount))
12861282 then {
12871283 let referrerFeeAny = invoke(referralAddress(), "acceptPaymentWithLink", [_trader, _refLink], [AttachedPayment(quoteAsset(), distributeFeeAmount)])
12881284 if ((referrerFeeAny == referrerFeeAny))
12891285 then {
12901286 let referrerFee = match referrerFeeAny {
12911287 case x: Int =>
12921288 x
12931289 case _ =>
12941290 throw("Invalid referrerFee")
12951291 }
12961292 let feeAmount = (distributeFeeAmount - referrerFee)
1297- let $t05582755967 = getPosition(_trader)
1298- let oldPositionSize = $t05582755967._1
1299- let oldPositionMargin = $t05582755967._2
1300- let oldPositionOpenNotional = $t05582755967._3
1301- let oldPositionLstUpdCPF = $t05582755967._4
1293+ let $t05553655676 = getPosition(_trader)
1294+ let oldPositionSize = $t05553655676._1
1295+ let oldPositionMargin = $t05553655676._2
1296+ let oldPositionOpenNotional = $t05553655676._3
1297+ let oldPositionLstUpdCPF = $t05553655676._4
13021298 let isNewPosition = (oldPositionSize == 0)
13031299 let isSameDirection = if ((oldPositionSize > 0))
13041300 then (_direction == DIR_LONG)
13051301 else (_direction == DIR_SHORT)
13061302 let expandExisting = if (!(isNewPosition))
13071303 then isSameDirection
13081304 else false
13091305 let isAdd = (_direction == DIR_LONG)
1310- let $t05625659297 = if (if (isNewPosition)
1306+ let $t05596558927 = if (if (isNewPosition)
13111307 then true
13121308 else expandExisting)
13131309 then {
13141310 let openNotional = muld(_amount, _leverage)
1315- let $t05671856891 = swapInput(isAdd, openNotional)
1316- let amountBaseAssetBought = $t05671856891._1
1317- let quoteAssetReserveAfter = $t05671856891._2
1318- let baseAssetReserveAfter = $t05671856891._3
1319- let totalPositionSizeAfter = $t05671856891._4
1311+ let $t05642756600 = swapInput(isAdd, openNotional)
1312+ let amountBaseAssetBought = $t05642756600._1
1313+ let quoteAssetReserveAfter = $t05642756600._2
1314+ let baseAssetReserveAfter = $t05642756600._3
1315+ let totalPositionSizeAfter = $t05642756600._4
13201316 if (if ((_minBaseAssetAmount != 0))
13211317 then (_minBaseAssetAmount > abs(amountBaseAssetBought))
13221318 else false)
13231319 then throw(((("Limit error: " + toString(abs(amountBaseAssetBought))) + " < ") + toString(_minBaseAssetAmount)))
13241320 else {
13251321 let newPositionSize = (oldPositionSize + amountBaseAssetBought)
13261322 let totalLongOpenInterestAfter = (openInterestLong() + (if ((newPositionSize > 0))
13271323 then openNotional
13281324 else 0))
13291325 let totalShortOpenInterestAfter = (openInterestShort() + (if ((0 > newPositionSize))
13301326 then openNotional
13311327 else 0))
1332- let increaseMarginRequirement = divd(openNotional, _leverage)
1333- let $t05749957738 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
1334- let remainMargin = $t05749957738._1
1335- let x1 = $t05749957738._2
1336- let x2 = $t05749957738._3
1328+ let $t05714657367 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, _amount)
1329+ let remainMargin = $t05714657367._1
1330+ let x1 = $t05714657367._2
1331+ let x2 = $t05714657367._3
13371332 if (!(requireNotOverSpreadLimit(quoteAssetReserveAfter, baseAssetReserveAfter)))
13381333 then throw("Over max spread limit")
13391334 else if (!(requireNotOverMaxOpenNotional(totalLongOpenInterestAfter, totalShortOpenInterestAfter)))
13401335 then throw("Over max open notional")
13411336 else $Tuple12(newPositionSize, remainMargin, (oldPositionOpenNotional + openNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, (openInterestNotional() + openNotional), (totalLongPositionSize() + (if ((newPositionSize > 0))
13421337 then abs(amountBaseAssetBought)
13431338 else 0)), (totalShortPositionSize() + (if ((0 > newPositionSize))
13441339 then abs(amountBaseAssetBought)
13451340 else 0)), totalLongOpenInterestAfter, totalShortOpenInterestAfter)
13461341 }
13471342 }
13481343 else {
13491344 let openNotional = muld(_amount, _leverage)
1350- let $t05899759113 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1351- let oldPositionNotional = $t05899759113._1
1352- let unrealizedPnl = $t05899759113._2
1345+ let $t05862758743 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1346+ let oldPositionNotional = $t05862758743._1
1347+ let unrealizedPnl = $t05862758743._2
13531348 if ((oldPositionNotional > openNotional))
13541349 then throw("Use decreasePosition to decrease position size")
13551350 else throw("Close position first")
13561351 }
1357- let newPositionSize = $t05625659297._1
1358- let newPositionRemainMargin = $t05625659297._2
1359- let newPositionOpenNotional = $t05625659297._3
1360- let newPositionLatestCPF = $t05625659297._4
1361- let baseAssetReserveAfter = $t05625659297._5
1362- let quoteAssetReserveAfter = $t05625659297._6
1363- let totalPositionSizeAfter = $t05625659297._7
1364- let openInterestNotionalAfter = $t05625659297._8
1365- let totalLongAfter = $t05625659297._9
1366- let totalShortAfter = $t05625659297._10
1367- let totalLongOpenInterestAfter = $t05625659297._11
1368- let totalShortOpenInterestAfter = $t05625659297._12
1369- let $t05930359360 = distributeFee(feeAmount)
1370- let feeToStakers = $t05930359360._1
1371- let feeToVault = $t05930359360._2
1352+ let newPositionSize = $t05596558927._1
1353+ let newPositionRemainMargin = $t05596558927._2
1354+ let newPositionOpenNotional = $t05596558927._3
1355+ let newPositionLatestCPF = $t05596558927._4
1356+ let baseAssetReserveAfter = $t05596558927._5
1357+ let quoteAssetReserveAfter = $t05596558927._6
1358+ let totalPositionSizeAfter = $t05596558927._7
1359+ let openInterestNotionalAfter = $t05596558927._8
1360+ let totalLongAfter = $t05596558927._9
1361+ let totalShortAfter = $t05596558927._10
1362+ let totalLongOpenInterestAfter = $t05596558927._11
1363+ let totalShortOpenInterestAfter = $t05596558927._12
1364+ let $t05893358990 = distributeFee(feeAmount)
1365+ let feeToStakers = $t05893358990._1
1366+ let feeToVault = $t05893358990._2
13721367 let stake = if (isQuoteAsset)
13731368 then {
13741369 let stake = invoke(vaultAddress(), "addLocked", [false], [AttachedPayment(quoteAsset(), _amount)])
13751370 if ((stake == stake))
13761371 then nil
13771372 else throw("Strict value is not equal to itself.")
13781373 }
13791374 else nil
13801375 if ((stake == stake))
13811376 then {
13821377 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToVault)])
13831378 if ((depositInsurance == depositInsurance))
13841379 then {
13851380 let notifyFee = invoke(minerAddress(), "notifyFees", [_trader, feeAmount], nil)
13861381 if ((notifyFee == notifyFee))
13871382 then {
13881383 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, newPositionOpenNotional], nil)
13891384 if ((notifyNotional == notifyNotional))
13901385 then ((((((updatePosition(_trader, newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ incrementPositionSequenceNumber(isNewPosition, _trader)) ++ updatePositionAsset(_trader, _assetIdStr)) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter)) ++ transferFee(feeToStakers)) ++ updateBalance((cbalance() + _amount))) ++ doBurnArtifact(burnArtifact, i))
13911386 else throw("Strict value is not equal to itself.")
13921387 }
13931388 else throw("Strict value is not equal to itself.")
13941389 }
13951390 else throw("Strict value is not equal to itself.")
13961391 }
13971392 else throw("Strict value is not equal to itself.")
13981393 }
13991394 else throw("Strict value is not equal to itself.")
14001395 }
14011396 else throw("Strict value is not equal to itself.")
14021397 }
14031398 }
14041399 else throw("Strict value is not equal to itself.")
14051400 }
14061401
14071402
14081403
14091404 @Callable(i)
14101405 func addMargin () = {
14111406 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
14121407 if ((sync == sync))
14131408 then {
14141409 let _trader = toString(i.caller)
14151410 let _rawAmount = i.payments[0].amount
14161411 let _assetId = i.payments[0].assetId
14171412 let _assetIdStr = toBase58String(value(_assetId))
14181413 let isQuoteAsset = (_assetId == quoteAsset())
14191414 let isCollateralAsset = isWhitelistAsset(_assetIdStr)
14201415 if (if (if (if (if (if (if (if (!(isQuoteAsset))
14211416 then !(isCollateralAsset)
14221417 else false)
14231418 then true
14241419 else !(requireOpenPosition(toString(i.caller))))
14251420 then true
14261421 else !(isSameAsset(_trader, _assetIdStr)))
14271422 then true
14281423 else !(initialized()))
14291424 then true
14301425 else paused())
14311426 then true
14321427 else closeOnly())
14331428 then true
14341429 else isMarketClosed())
14351430 then throw("Invalid addMargin parameters")
14361431 else {
1437- let $t06133261417 = getForTraderWithArtifact(_trader, getArtifactId(i))
1438- let adjustedFee = $t06133261417._1
1439- let burnArtifact = $t06133261417._2
1432+ let $t06096261047 = getForTraderWithArtifact(_trader, getArtifactId(i))
1433+ let adjustedFee = $t06096261047._1
1434+ let burnArtifact = $t06096261047._2
14401435 let rawFeeAmount = muld(_rawAmount, adjustedFee)
14411436 let _amount = (_rawAmount - rawFeeAmount)
14421437 let distributeFeeAmount = if (isCollateralAsset)
14431438 then {
14441439 let doBorrow = invoke(collateralAddress(), "borrow", [_trader], [AttachedPayment(_assetId, _amount)])
14451440 if ((doBorrow == doBorrow))
14461441 then {
14471442 let balanceBefore = assetBalance(this, quoteAsset())
14481443 if ((balanceBefore == balanceBefore))
14491444 then {
14501445 let doSwap = invoke(swapAddress(), "swap", [toBase58String(quoteAsset()), 0], [AttachedPayment(_assetId, rawFeeAmount)])
14511446 if ((doSwap == doSwap))
14521447 then {
14531448 let balanceAfter = assetBalance(this, quoteAsset())
14541449 if ((balanceAfter == balanceAfter))
14551450 then {
14561451 let exchangedAmount = (balanceAfter - balanceBefore)
14571452 if ((exchangedAmount == exchangedAmount))
14581453 then exchangedAmount
14591454 else throw("Strict value is not equal to itself.")
14601455 }
14611456 else throw("Strict value is not equal to itself.")
14621457 }
14631458 else throw("Strict value is not equal to itself.")
14641459 }
14651460 else throw("Strict value is not equal to itself.")
14661461 }
14671462 else throw("Strict value is not equal to itself.")
14681463 }
14691464 else rawFeeAmount
14701465 if ((distributeFeeAmount == distributeFeeAmount))
14711466 then {
14721467 let referrerFeeAny = invoke(referralAddress(), "acceptPayment", [_trader], [AttachedPayment(quoteAsset(), distributeFeeAmount)])
14731468 if ((referrerFeeAny == referrerFeeAny))
14741469 then {
14751470 let referrerFee = match referrerFeeAny {
14761471 case x: Int =>
14771472 x
14781473 case _ =>
14791474 throw("Invalid referrerFee")
14801475 }
14811476 let feeAmount = (distributeFeeAmount - referrerFee)
1482- let $t06271662856 = getPosition(_trader)
1483- let oldPositionSize = $t06271662856._1
1484- let oldPositionMargin = $t06271662856._2
1485- let oldPositionOpenNotional = $t06271662856._3
1486- let oldPositionLstUpdCPF = $t06271662856._4
1487- let $t06286262919 = distributeFee(feeAmount)
1488- let feeToStakers = $t06286262919._1
1489- let feeToVault = $t06286262919._2
1477+ let $t06234662486 = getPosition(_trader)
1478+ let oldPositionSize = $t06234662486._1
1479+ let oldPositionMargin = $t06234662486._2
1480+ let oldPositionOpenNotional = $t06234662486._3
1481+ let oldPositionLstUpdCPF = $t06234662486._4
1482+ let $t06249262549 = distributeFee(feeAmount)
1483+ let feeToStakers = $t06249262549._1
1484+ let feeToVault = $t06249262549._2
14901485 let stake = if (isQuoteAsset)
14911486 then {
14921487 let stake = invoke(vaultAddress(), "addLocked", [false], [AttachedPayment(quoteAsset(), _amount)])
14931488 if ((stake == stake))
14941489 then nil
14951490 else throw("Strict value is not equal to itself.")
14961491 }
14971492 else nil
14981493 if ((stake == stake))
14991494 then {
15001495 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToVault)])
15011496 if ((depositInsurance == depositInsurance))
15021497 then {
15031498 let notifyFee = invoke(minerAddress(), "notifyFees", [_trader, feeAmount], nil)
15041499 if ((notifyFee == notifyFee))
15051500 then (((updatePosition(_trader, oldPositionSize, (oldPositionMargin + _amount), oldPositionOpenNotional, oldPositionLstUpdCPF) ++ transferFee(feeToStakers)) ++ updateBalance((cbalance() + _amount))) ++ doBurnArtifact(burnArtifact, i))
15061501 else throw("Strict value is not equal to itself.")
15071502 }
15081503 else throw("Strict value is not equal to itself.")
15091504 }
15101505 else throw("Strict value is not equal to itself.")
15111506 }
15121507 else throw("Strict value is not equal to itself.")
15131508 }
15141509 else throw("Strict value is not equal to itself.")
15151510 }
15161511 }
15171512 else throw("Strict value is not equal to itself.")
15181513 }
15191514
15201515
15211516
15221517 @Callable(i)
15231518 func removeMargin (_amount) = {
15241519 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
15251520 if ((sync == sync))
15261521 then {
15271522 let _trader = toString(i.caller)
15281523 if (if (if (if (if ((0 >= _amount))
15291524 then true
15301525 else !(requireOpenPosition(_trader)))
15311526 then true
15321527 else !(initialized()))
15331528 then true
15341529 else paused())
15351530 then true
15361531 else isMarketClosed())
15371532 then throw("Invalid removeMargin parameters")
15381533 else {
1539- let $t06405564195 = getPosition(_trader)
1540- let oldPositionSize = $t06405564195._1
1541- let oldPositionMargin = $t06405564195._2
1542- let oldPositionOpenNotional = $t06405564195._3
1543- let oldPositionLstUpdCPF = $t06405564195._4
1534+ let $t06368563825 = getPosition(_trader)
1535+ let oldPositionSize = $t06368563825._1
1536+ let oldPositionMargin = $t06368563825._2
1537+ let oldPositionOpenNotional = $t06368563825._3
1538+ let oldPositionLstUpdCPF = $t06368563825._4
15441539 let marginDelta = -(_amount)
1545- let $t06423264411 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1546- let remainMargin = $t06423264411._1
1547- let badDebt = $t06423264411._2
1540+ let $t06386264041 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1541+ let remainMargin = $t06386264041._1
1542+ let badDebt = $t06386264041._2
15481543 if ((badDebt != 0))
15491544 then throw("Invalid removed margin amount")
15501545 else {
15511546 let marginRatio = calcMarginRatio(remainMargin, badDebt, oldPositionOpenNotional)
15521547 if (!(requireMoreMarginRatio(marginRatio, initMarginRatio(), true)))
15531548 then throw(((("Too much margin removed: " + toString(marginRatio)) + " < ") + toString(initMarginRatio())))
15541549 else {
15551550 let quoteAssetStr = toBase58String(quoteAsset())
1556- let $t06485564909 = getBorrowedByTrader(_trader)
1557- let borrowed = $t06485564909._1
1558- let assetId = $t06485564909._2
1551+ let $t06448564539 = getBorrowedByTrader(_trader)
1552+ let borrowed = $t06448564539._1
1553+ let assetId = $t06448564539._2
15591554 let toRepay = if ((_amount > borrowed))
15601555 then borrowed
15611556 else _amount
15621557 let toWithdraw = if ((borrowed > _amount))
15631558 then 0
15641559 else (_amount - borrowed)
15651560 let finalBorrow = (borrowed - toRepay)
15661561 let switchPositionToQuote = if ((finalBorrow > 0))
15671562 then nil
15681563 else updatePositionAsset(_trader, quoteAssetStr)
15691564 let doSanityCheck = if (((toRepay + toWithdraw) != _amount))
15701565 then throw(((((("toRepay=" + toString(toRepay)) + " + toWithdraw=") + toString(toWithdraw)) + " != ") + toString(_amount)))
15711566 else nil
15721567 if ((doSanityCheck == doSanityCheck))
15731568 then {
15741569 let doUnstake = if ((toWithdraw > 0))
15751570 then {
15761571 let doUnstake = invoke(vaultAddress(), "withdrawLocked", [toWithdraw], nil)
15771572 if ((doUnstake == doUnstake))
15781573 then nil
15791574 else throw("Strict value is not equal to itself.")
15801575 }
15811576 else nil
15821577 if ((doUnstake == doUnstake))
15831578 then {
15841579 let returnCollateralAction = if ((toRepay > 0))
15851580 then {
15861581 let doRepay = invoke(collateralAddress(), "repay", [_trader, toRepay, assetId], nil)
15871582 if ((doRepay == doRepay))
15881583 then [ScriptTransfer(i.caller, toRepay, fromBase58String(assetId))]
15891584 else throw("Strict value is not equal to itself.")
15901585 }
15911586 else nil
15921587 if ((returnCollateralAction == returnCollateralAction))
15931588 then ((((updatePosition(_trader, oldPositionSize, remainMargin, oldPositionOpenNotional, latestCumulativePremiumFraction(oldPositionSize)) ++ (if ((toWithdraw > 0))
15941589 then withdraw(i.caller, toWithdraw)
15951590 else nil)) ++ updateBalance((cbalance() - _amount))) ++ switchPositionToQuote) ++ returnCollateralAction)
15961591 else throw("Strict value is not equal to itself.")
15971592 }
15981593 else throw("Strict value is not equal to itself.")
15991594 }
16001595 else throw("Strict value is not equal to itself.")
16011596 }
16021597 }
16031598 }
16041599 }
16051600 else throw("Strict value is not equal to itself.")
16061601 }
16071602
16081603
16091604
16101605 @Callable(i)
16111606 func closePosition (_size,_minQuoteAssetAmount) = {
16121607 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
16131608 if ((sync == sync))
16141609 then {
16151610 let _trader = getActualCaller(i)
16161611 let _traderAddress = valueOrErrorMessage(addressFromString(_trader), "Invalid caller")
16171612 if (if (if (if (if (if (!(requireOpenPosition(_trader)))
16181613 then true
16191614 else !(initialized()))
16201615 then true
16211616 else paused())
16221617 then true
16231618 else (0 >= _size))
16241619 then true
16251620 else (0 > _minQuoteAssetAmount))
16261621 then true
16271622 else isMarketClosed())
16281623 then throw("Invalid closePosition parameters")
16291624 else {
1630- let $t06709367233 = getPosition(_trader)
1631- let oldPositionSize = $t06709367233._1
1632- let oldPositionMargin = $t06709367233._2
1633- let oldPositionOpenNotional = $t06709367233._3
1634- let oldPositionLstUpdCPF = $t06709367233._4
1635- let $t06723972369 = if ((abs(oldPositionSize) > _size))
1625+ let $t06672366863 = getPosition(_trader)
1626+ let oldPositionSize = $t06672366863._1
1627+ let oldPositionMargin = $t06672366863._2
1628+ let oldPositionOpenNotional = $t06672366863._3
1629+ let oldPositionLstUpdCPF = $t06672366863._4
1630+ let $t06686971999 = if ((abs(oldPositionSize) > _size))
16361631 then {
16371632 let _direction = if ((oldPositionSize > 0))
16381633 then DIR_SHORT
16391634 else DIR_LONG
16401635 let isAdd = (_direction == DIR_LONG)
1641- let $t06783068052 = swapOutput((oldPositionSize > 0), _size, true)
1642- let exchangedQuoteAssetAmount = $t06783068052._1
1643- let quoteAssetReserveAfter = $t06783068052._2
1644- let baseAssetReserveAfter = $t06783068052._3
1645- let totalPositionSizeAfter = $t06783068052._4
1636+ let $t06746067682 = swapOutput((oldPositionSize > 0), _size, true)
1637+ let exchangedQuoteAssetAmount = $t06746067682._1
1638+ let quoteAssetReserveAfter = $t06746067682._2
1639+ let baseAssetReserveAfter = $t06746067682._3
1640+ let totalPositionSizeAfter = $t06746067682._4
16461641 let exchangedPositionSize = if ((oldPositionSize > 0))
16471642 then -(_size)
16481643 else _size
1649- let $t06814368297 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1650- let oldPositionNotional = $t06814368297._1
1651- let unrealizedPnl = $t06814368297._2
1644+ let $t06777367927 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1645+ let oldPositionNotional = $t06777367927._1
1646+ let unrealizedPnl = $t06777367927._2
16521647 let mr = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
16531648 let realizedRatio = divd(abs(exchangedPositionSize), abs(oldPositionSize))
16541649 let realizedPnl = muld(unrealizedPnl, realizedRatio)
16551650 let remainMarginBefore = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, unrealizedPnl)._1
1656- let $t06879869026 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1657- let x1 = $t06879869026._1
1658- let positionBadDebt = $t06879869026._2
1659- let fundingPayment = $t06879869026._3
1651+ let $t06842868656 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1652+ let x1 = $t06842868656._1
1653+ let positionBadDebt = $t06842868656._2
1654+ let fundingPayment = $t06842868656._3
16601655 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
16611656 let remainOpenNotional = if ((oldPositionSize > 0))
16621657 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
16631658 else ((unrealizedPnlAfter + oldPositionNotional) - exchangedQuoteAssetAmount)
16641659 let newPositionOpenNotional = abs(remainOpenNotional)
16651660 let newPositionMargin = if ((oldPositionSize > 0))
16661661 then (muld((newPositionOpenNotional + unrealizedPnlAfter), mr) - unrealizedPnlAfter)
16671662 else (muld((newPositionOpenNotional - unrealizedPnlAfter), mr) - unrealizedPnlAfter)
16681663 let openNotionalDelta = (oldPositionOpenNotional - newPositionOpenNotional)
16691664 let newPositionSize = (oldPositionSize + exchangedPositionSize)
16701665 let newPositionLstUpdCPF = latestCumulativePremiumFraction(newPositionSize)
16711666 let openInterestNotionalAfter = (openInterestNotional() - openNotionalDelta)
16721667 if (if ((_minQuoteAssetAmount != 0))
16731668 then (_minQuoteAssetAmount > exchangedQuoteAssetAmount)
16741669 else false)
16751670 then throw(((("Limit error: " + toString(exchangedQuoteAssetAmount)) + " < ") + toString(_minQuoteAssetAmount)))
16761671 else $Tuple15(newPositionSize, newPositionMargin, newPositionOpenNotional, newPositionLstUpdCPF, positionBadDebt, realizedPnl, (remainMarginBefore - (newPositionMargin + unrealizedPnlAfter)), quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, (totalLongPositionSize() - (if ((newPositionSize > 0))
16771672 then abs(exchangedPositionSize)
16781673 else 0)), (totalShortPositionSize() - (if ((0 > newPositionSize))
16791674 then abs(exchangedPositionSize)
16801675 else 0)), (openInterestLong() - (if ((newPositionSize > 0))
16811676 then openNotionalDelta
16821677 else 0)), (openInterestShort() - (if ((0 > newPositionSize))
16831678 then openNotionalDelta
16841679 else 0)))
16851680 }
16861681 else if ((_size > abs(oldPositionSize)))
16871682 then throw("Invalid closePosition parameters")
16881683 else {
1689- let $t07131071729 = internalClosePosition(_trader, true)
1690- let exchangedQuoteAssetAmount = $t07131071729._1
1691- let positionBadDebt = $t07131071729._2
1692- let realizedPnl = $t07131071729._3
1693- let marginToVault = $t07131071729._4
1694- let quoteAssetReserveAfter = $t07131071729._5
1695- let baseAssetReserveAfter = $t07131071729._6
1696- let totalPositionSizeAfter = $t07131071729._7
1697- let openInterestNotionalAfter = $t07131071729._8
1698- let x2 = $t07131071729._9
1699- let totalLongAfter = $t07131071729._10
1700- let totalShortAfter = $t07131071729._11
1701- let totalLongOpenInterestAfter = $t07131071729._12
1702- let totalShortOpenInterestAfter = $t07131071729._13
1684+ let $t07094071359 = internalClosePosition(_trader, true)
1685+ let exchangedQuoteAssetAmount = $t07094071359._1
1686+ let positionBadDebt = $t07094071359._2
1687+ let realizedPnl = $t07094071359._3
1688+ let marginToVault = $t07094071359._4
1689+ let quoteAssetReserveAfter = $t07094071359._5
1690+ let baseAssetReserveAfter = $t07094071359._6
1691+ let totalPositionSizeAfter = $t07094071359._7
1692+ let openInterestNotionalAfter = $t07094071359._8
1693+ let x2 = $t07094071359._9
1694+ let totalLongAfter = $t07094071359._10
1695+ let totalShortAfter = $t07094071359._11
1696+ let totalLongOpenInterestAfter = $t07094071359._12
1697+ let totalShortOpenInterestAfter = $t07094071359._13
17031698 if (if ((_minQuoteAssetAmount != 0))
17041699 then (_minQuoteAssetAmount > exchangedQuoteAssetAmount)
17051700 else false)
17061701 then throw(((("Limit error: " + toString(exchangedQuoteAssetAmount)) + " < ") + toString(_minQuoteAssetAmount)))
17071702 else $Tuple15(0, 0, 0, 0, positionBadDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter)
17081703 }
1709- let newPositionSize = $t06723972369._1
1710- let newPositionMargin = $t06723972369._2
1711- let newPositionOpenNotional = $t06723972369._3
1712- let newPositionLstUpdCPF = $t06723972369._4
1713- let positionBadDebt = $t06723972369._5
1714- let realizedPnl = $t06723972369._6
1715- let marginToVault = $t06723972369._7
1716- let quoteAssetReserveAfter = $t06723972369._8
1717- let baseAssetReserveAfter = $t06723972369._9
1718- let totalPositionSizeAfter = $t06723972369._10
1719- let openInterestNotionalAfter = $t06723972369._11
1720- let totalLongAfter = $t06723972369._12
1721- let totalShortAfter = $t06723972369._13
1722- let totalLongOpenInterestAfter = $t06723972369._14
1723- let totalShortOpenInterestAfter = $t06723972369._15
1704+ let newPositionSize = $t06686971999._1
1705+ let newPositionMargin = $t06686971999._2
1706+ let newPositionOpenNotional = $t06686971999._3
1707+ let newPositionLstUpdCPF = $t06686971999._4
1708+ let positionBadDebt = $t06686971999._5
1709+ let realizedPnl = $t06686971999._6
1710+ let marginToVault = $t06686971999._7
1711+ let quoteAssetReserveAfter = $t06686971999._8
1712+ let baseAssetReserveAfter = $t06686971999._9
1713+ let totalPositionSizeAfter = $t06686971999._10
1714+ let openInterestNotionalAfter = $t06686971999._11
1715+ let totalLongAfter = $t06686971999._12
1716+ let totalShortAfter = $t06686971999._13
1717+ let totalLongOpenInterestAfter = $t06686971999._14
1718+ let totalShortOpenInterestAfter = $t06686971999._15
17241719 if ((positionBadDebt > 0))
17251720 then throw("Unable to close position with bad debt")
17261721 else {
17271722 let withdrawAmount = abs(marginToVault)
17281723 let ammBalance = (cbalance() - withdrawAmount)
1729- let $t07257872785 = if ((0 > ammBalance))
1724+ let $t07220872415 = if ((0 > ammBalance))
17301725 then $Tuple2(0, abs(ammBalance))
17311726 else $Tuple2(ammBalance, 0)
1732- let ammNewBalance = $t07257872785._1
1733- let x11 = $t07257872785._2
1734- let $t07279272846 = getBorrowedByTrader(_trader)
1735- let borrowed = $t07279272846._1
1736- let assetId = $t07279272846._2
1737- let $t07286173720 = if ((borrowed > 0))
1727+ let ammNewBalance = $t07220872415._1
1728+ let x11 = $t07220872415._2
1729+ let $t07242272476 = getBorrowedByTrader(_trader)
1730+ let borrowed = $t07242272476._1
1731+ let assetId = $t07242272476._2
1732+ let $t07249173350 = if ((borrowed > 0))
17381733 then if ((withdrawAmount >= borrowed))
17391734 then {
17401735 let doRepay = invoke(collateralAddress(), "repay", [_trader, borrowed, assetId], nil)
17411736 if ((doRepay == doRepay))
17421737 then $Tuple2([ScriptTransfer(_traderAddress, borrowed, fromBase58String(assetId))], (withdrawAmount - borrowed))
17431738 else throw("Strict value is not equal to itself.")
17441739 }
17451740 else {
17461741 let realizeAndClose = invoke(collateralAddress(), "realizePartiallyAndClose", [_trader, withdrawAmount, assetId], nil)
17471742 if ((realizeAndClose == realizeAndClose))
17481743 then $Tuple2([ScriptTransfer(_traderAddress, withdrawAmount, fromBase58String(assetId))], 0)
17491744 else throw("Strict value is not equal to itself.")
17501745 }
17511746 else $Tuple2(nil, withdrawAmount)
1752- if (($t07286173720 == $t07286173720))
1747+ if (($t07249173350 == $t07249173350))
17531748 then {
1754- let quoteWithdrawAmount = $t07286173720._2
1755- let sendCollateralAction = $t07286173720._1
1749+ let quoteWithdrawAmount = $t07249173350._2
1750+ let sendCollateralAction = $t07249173350._1
17561751 let unstake = if ((quoteWithdrawAmount > 0))
17571752 then {
17581753 let unstake = invoke(vaultAddress(), "withdrawLocked", [quoteWithdrawAmount], nil)
17591754 if ((unstake == unstake))
17601755 then nil
17611756 else throw("Strict value is not equal to itself.")
17621757 }
17631758 else nil
17641759 if ((unstake == unstake))
17651760 then {
17661761 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, 0], nil)
17671762 if ((notifyNotional == notifyNotional))
17681763 then (((((if ((newPositionSize == 0))
17691764 then deletePosition(_trader)
17701765 else updatePosition(_trader, newPositionSize, newPositionMargin, newPositionOpenNotional, newPositionLstUpdCPF)) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter)) ++ (if ((quoteWithdrawAmount > 0))
17711766 then withdraw(_traderAddress, quoteWithdrawAmount)
17721767 else nil)) ++ updateBalance(ammNewBalance)) ++ sendCollateralAction)
17731768 else throw("Strict value is not equal to itself.")
17741769 }
17751770 else throw("Strict value is not equal to itself.")
17761771 }
17771772 else throw("Strict value is not equal to itself.")
17781773 }
17791774 }
17801775 }
17811776 else throw("Strict value is not equal to itself.")
17821777 }
17831778
17841779
17851780
17861781 @Callable(i)
17871782 func liquidate (_trader) = {
17881783 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
17891784 if ((sync == sync))
17901785 then {
17911786 let spotMarginRatio = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
17921787 let marginRatio = if (isOverFluctuationLimit())
17931788 then {
17941789 let oracleMarginRatio = getMarginRatioByOption(_trader, PNL_OPTION_ORACLE)
17951790 vmax(spotMarginRatio, oracleMarginRatio)
17961791 }
17971792 else spotMarginRatio
17981793 if (if (if (if (if (!(requireMoreMarginRatio(marginRatio, maintenanceMarginRatio(), false)))
17991794 then true
18001795 else !(requireOpenPosition(_trader)))
18011796 then true
18021797 else !(initialized()))
18031798 then true
18041799 else paused())
18051800 then true
18061801 else isMarketClosed())
18071802 then throw("Unable to liquidate")
18081803 else if (if (if ((spotMarginRatio > liquidationFeeRatio()))
18091804 then (partialLiquidationRatio() > 0)
18101805 else false)
18111806 then (DECIMAL_UNIT > partialLiquidationRatio())
18121807 else false)
18131808 then {
1814- let $t07604176191 = getPosition(_trader)
1815- let oldPositionSize = $t07604176191._1
1816- let oldPositionMargin = $t07604176191._2
1817- let oldPositionOpenNotional = $t07604176191._3
1818- let oldPositionLstUpdCPF = $t07604176191._4
1809+ let $t07567175821 = getPosition(_trader)
1810+ let oldPositionSize = $t07567175821._1
1811+ let oldPositionMargin = $t07567175821._2
1812+ let oldPositionOpenNotional = $t07567175821._3
1813+ let oldPositionLstUpdCPF = $t07567175821._4
18191814 let _direction = if ((oldPositionSize > 0))
18201815 then DIR_SHORT
18211816 else DIR_LONG
18221817 let isAdd = (_direction == DIR_LONG)
18231818 let exchangedQuoteAssetAmount = getPartialLiquidationAmount(_trader, oldPositionSize)
1824- let $t07641676520 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1825- let oldPositionNotional = $t07641676520._1
1826- let unrealizedPnl = $t07641676520._2
1827- let $t07652876715 = swapInput(isAdd, exchangedQuoteAssetAmount)
1828- let exchangedPositionSize = $t07652876715._1
1829- let quoteAssetReserveAfter = $t07652876715._2
1830- let baseAssetReserveAfter = $t07652876715._3
1831- let totalPositionSizeAfter = $t07652876715._4
1819+ let $t07604676150 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1820+ let oldPositionNotional = $t07604676150._1
1821+ let unrealizedPnl = $t07604676150._2
1822+ let $t07615876345 = swapInput(isAdd, exchangedQuoteAssetAmount)
1823+ let exchangedPositionSize = $t07615876345._1
1824+ let quoteAssetReserveAfter = $t07615876345._2
1825+ let baseAssetReserveAfter = $t07615876345._3
1826+ let totalPositionSizeAfter = $t07615876345._4
18321827 let liquidationRatio = divd(abs(exchangedPositionSize), abs(oldPositionSize))
18331828 let realizedPnl = muld(unrealizedPnl, liquidationRatio)
1834- let $t07700477237 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1835- let remainMargin = $t07700477237._1
1836- let badDebt = $t07700477237._2
1837- let fundingPayment = $t07700477237._3
1829+ let $t07663476867 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1830+ let remainMargin = $t07663476867._1
1831+ let badDebt = $t07663476867._2
1832+ let fundingPayment = $t07663476867._3
18381833 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
18391834 let remainOpenNotional = if ((oldPositionSize > 0))
18401835 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
18411836 else ((unrealizedPnlAfter + oldPositionNotional) - exchangedQuoteAssetAmount)
18421837 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
18431838 let feeToLiquidator = (liquidationPenalty / 2)
18441839 let feeToVault = (liquidationPenalty - feeToLiquidator)
18451840 let newPositionMargin = (remainMargin - liquidationPenalty)
18461841 let newPositionSize = (oldPositionSize + exchangedPositionSize)
18471842 let newPositionOpenNotional = abs(remainOpenNotional)
18481843 let openNotionalDelta = (oldPositionOpenNotional - newPositionOpenNotional)
18491844 let newPositionLstUpdCPF = latestCumulativePremiumFraction(newPositionSize)
18501845 let openInterestNotionalAfter = (openInterestNotional() - openNotionalDelta)
18511846 let ammBalance = (cbalance() - liquidationPenalty)
1852- let $t07847878607 = if ((0 > ammBalance))
1847+ let $t07810878237 = if ((0 > ammBalance))
18531848 then $Tuple2(0, abs(ammBalance))
18541849 else $Tuple2(ammBalance, 0)
1855- let newAmmBalance = $t07847878607._1
1856- let x11 = $t07847878607._2
1857- let $t07861578669 = getBorrowedByTrader(_trader)
1858- let borrowed = $t07861578669._1
1859- let assetId = $t07861578669._2
1850+ let newAmmBalance = $t07810878237._1
1851+ let x11 = $t07810878237._2
1852+ let $t07824578299 = getBorrowedByTrader(_trader)
1853+ let borrowed = $t07824578299._1
1854+ let assetId = $t07824578299._2
18601855 let doLiquidateCollateral = if ((borrowed > 0))
18611856 then {
18621857 let collateralToSell = muld(borrowed, liquidationRatio)
18631858 let realizeAndClose = invoke(collateralAddress(), "realizePartially", [_trader, assetId, collateralToSell], nil)
18641859 if ((realizeAndClose == realizeAndClose))
18651860 then nil
18661861 else throw("Strict value is not equal to itself.")
18671862 }
18681863 else nil
18691864 if ((doLiquidateCollateral == doLiquidateCollateral))
18701865 then {
18711866 let unstake = invoke(vaultAddress(), "withdrawLocked", [liquidationPenalty], nil)
18721867 if ((unstake == unstake))
18731868 then {
18741869 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToVault)])
18751870 if ((depositInsurance == depositInsurance))
18761871 then {
18771872 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, newPositionOpenNotional], nil)
18781873 if ((notifyNotional == notifyNotional))
18791874 then (((updatePosition(_trader, newPositionSize, newPositionMargin, newPositionOpenNotional, newPositionLstUpdCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, (totalLongPositionSize() - (if ((newPositionSize > 0))
18801875 then abs(exchangedPositionSize)
18811876 else 0)), (totalShortPositionSize() - (if ((0 > newPositionSize))
18821877 then abs(exchangedPositionSize)
18831878 else 0)), (openInterestLong() - (if ((newPositionSize > 0))
18841879 then openNotionalDelta
18851880 else 0)), (openInterestShort() - (if ((0 > newPositionSize))
18861881 then openNotionalDelta
18871882 else 0)))) ++ withdraw(i.caller, feeToLiquidator)) ++ updateBalance(newAmmBalance))
18881883 else throw("Strict value is not equal to itself.")
18891884 }
18901885 else throw("Strict value is not equal to itself.")
18911886 }
18921887 else throw("Strict value is not equal to itself.")
18931888 }
18941889 else throw("Strict value is not equal to itself.")
18951890 }
18961891 else {
1897- let $t08034880843 = internalClosePosition(_trader, false)
1898- let x1 = $t08034880843._1
1899- let badDebt = $t08034880843._2
1900- let x2 = $t08034880843._3
1901- let x3 = $t08034880843._4
1902- let quoteAssetReserveAfter = $t08034880843._5
1903- let baseAssetReserveAfter = $t08034880843._6
1904- let totalPositionSizeAfter = $t08034880843._7
1905- let openInterestNotionalAfter = $t08034880843._8
1906- let exchangedQuoteAssetAmount = $t08034880843._9
1907- let totalLongAfter = $t08034880843._10
1908- let totalShortAfter = $t08034880843._11
1909- let totalLongOpenInterestAfter = $t08034880843._12
1910- let totalShortOpenInterestAfter = $t08034880843._13
1892+ let $t07997880473 = internalClosePosition(_trader, false)
1893+ let x1 = $t07997880473._1
1894+ let badDebt = $t07997880473._2
1895+ let x2 = $t07997880473._3
1896+ let x3 = $t07997880473._4
1897+ let quoteAssetReserveAfter = $t07997880473._5
1898+ let baseAssetReserveAfter = $t07997880473._6
1899+ let totalPositionSizeAfter = $t07997880473._7
1900+ let openInterestNotionalAfter = $t07997880473._8
1901+ let exchangedQuoteAssetAmount = $t07997880473._9
1902+ let totalLongAfter = $t07997880473._10
1903+ let totalShortAfter = $t07997880473._11
1904+ let totalLongOpenInterestAfter = $t07997880473._12
1905+ let totalShortOpenInterestAfter = $t07997880473._13
19111906 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
19121907 let feeToLiquidator = (liquidationPenalty / 2)
19131908 let feeToVault = (liquidationPenalty - feeToLiquidator)
19141909 let ammBalance = (cbalance() - liquidationPenalty)
1915- let $t08125181380 = if ((0 > ammBalance))
1910+ let $t08088181010 = if ((0 > ammBalance))
19161911 then $Tuple2(0, abs(ammBalance))
19171912 else $Tuple2(ammBalance, 0)
1918- let newAmmBalance = $t08125181380._1
1919- let x11 = $t08125181380._2
1920- let $t08138881442 = getBorrowedByTrader(_trader)
1921- let borrowed = $t08138881442._1
1922- let assetId = $t08138881442._2
1913+ let newAmmBalance = $t08088181010._1
1914+ let x11 = $t08088181010._2
1915+ let $t08101881072 = getBorrowedByTrader(_trader)
1916+ let borrowed = $t08101881072._1
1917+ let assetId = $t08101881072._2
19231918 let doLiquidateCollateral = if ((borrowed > 0))
19241919 then {
19251920 let realizeAndClose = invoke(collateralAddress(), "realizePartiallyAndClose", [_trader, 0, assetId], nil)
19261921 if ((realizeAndClose == realizeAndClose))
19271922 then nil
19281923 else throw("Strict value is not equal to itself.")
19291924 }
19301925 else nil
19311926 if ((doLiquidateCollateral == doLiquidateCollateral))
19321927 then {
19331928 let x = if ((badDebt > 0))
19341929 then {
19351930 let lockBadDebt = invoke(vaultAddress(), "exchangeFreeAndLocked", [badDebt], nil)
19361931 if ((lockBadDebt == lockBadDebt))
19371932 then nil
19381933 else throw("Strict value is not equal to itself.")
19391934 }
19401935 else nil
19411936 if ((x == x))
19421937 then {
19431938 let unstake = invoke(vaultAddress(), "withdrawLocked", [liquidationPenalty], nil)
19441939 if ((unstake == unstake))
19451940 then {
19461941 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToVault)])
19471942 if ((depositInsurance == depositInsurance))
19481943 then {
19491944 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, 0], nil)
19501945 if ((notifyNotional == notifyNotional))
19511946 then (((deletePosition(_trader) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter)) ++ withdraw(i.caller, feeToLiquidator)) ++ updateBalance(newAmmBalance))
19521947 else throw("Strict value is not equal to itself.")
19531948 }
19541949 else throw("Strict value is not equal to itself.")
19551950 }
19561951 else throw("Strict value is not equal to itself.")
19571952 }
19581953 else throw("Strict value is not equal to itself.")
19591954 }
19601955 else throw("Strict value is not equal to itself.")
19611956 }
19621957 }
19631958 else throw("Strict value is not equal to itself.")
19641959 }
19651960
19661961
19671962
19681963 @Callable(i)
19691964 func payFunding () = {
19701965 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
19711966 if ((sync == sync))
19721967 then {
19731968 let fundingBlockTimestamp = nextFundingBlockTimestamp()
19741969 if (if (if ((fundingBlockTimestamp > lastBlock.timestamp))
19751970 then true
19761971 else !(initialized()))
19771972 then true
19781973 else paused())
19791974 then throw(((("Invalid funding block timestamp: " + toString(lastBlock.timestamp)) + " < ") + toString(fundingBlockTimestamp)))
19801975 else {
19811976 let underlyingPrice = getOraclePrice()
1982- let $t08331483376 = getFunding()
1983- let shortPremiumFraction = $t08331483376._1
1984- let longPremiumFraction = $t08331483376._2
1977+ let $t08294483006 = getFunding()
1978+ let shortPremiumFraction = $t08294483006._1
1979+ let longPremiumFraction = $t08294483006._2
19851980 updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), divd(longPremiumFraction, underlyingPrice), divd(shortPremiumFraction, underlyingPrice))
19861981 }
19871982 }
19881983 else throw("Strict value is not equal to itself.")
19891984 }
19901985
19911986
19921987
19931988 @Callable(i)
19941989 func syncTerminalPriceToOracle () = {
19951990 let _qtAstR = qtAstR()
19961991 let _bsAstR = bsAstR()
1997- let $t08380883943 = getSyncTerminalPrice(getOraclePrice(), _qtAstR, _bsAstR)
1998- let newQuoteAssetWeight = $t08380883943._1
1999- let newBaseAssetWeight = $t08380883943._2
2000- let marginToVault = $t08380883943._3
1992+ let $t08343883573 = getSyncTerminalPrice(getOraclePrice(), _qtAstR, _bsAstR)
1993+ let newQuoteAssetWeight = $t08343883573._1
1994+ let newBaseAssetWeight = $t08343883573._2
1995+ let marginToVault = $t08343883573._3
20011996 let doExchangePnL = if ((marginToVault != 0))
20021997 then {
20031998 let doExchangePnL = invoke(vaultAddress(), "exchangeFreeAndLocked", [marginToVault], nil)
20041999 if ((doExchangePnL == doExchangePnL))
20052000 then nil
20062001 else throw("Strict value is not equal to itself.")
20072002 }
20082003 else nil
20092004 if ((doExchangePnL == doExchangePnL))
20102005 then (updateAmmWeights(newQuoteAssetWeight, newBaseAssetWeight) ++ appendTwap(divd(muld(_qtAstR, newQuoteAssetWeight), muld(_bsAstR, newBaseAssetWeight))))
20112006 else throw("Strict value is not equal to itself.")
20122007 }
20132008
20142009
20152010
20162011 @Callable(i)
20172012 func view_calcRemainMarginWithFundingPayment (_trader) = {
20182013 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
20192014 if ((sync == sync))
20202015 then {
2021- let $t08451284613 = getPosition(_trader)
2022- let positionSize = $t08451284613._1
2023- let positionMargin = $t08451284613._2
2024- let pon = $t08451284613._3
2025- let positionLstUpdCPF = $t08451284613._4
2026- let $t08461684717 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
2027- let positionNotional = $t08461684717._1
2028- let unrealizedPnl = $t08461684717._2
2029- let $t08472084892 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
2030- let remainMargin = $t08472084892._1
2031- let badDebt = $t08472084892._2
2032- let fundingPayment = $t08472084892._3
2016+ let $t08414284243 = getPosition(_trader)
2017+ let positionSize = $t08414284243._1
2018+ let positionMargin = $t08414284243._2
2019+ let pon = $t08414284243._3
2020+ let positionLstUpdCPF = $t08414284243._4
2021+ let $t08424684347 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
2022+ let positionNotional = $t08424684347._1
2023+ let unrealizedPnl = $t08424684347._2
2024+ let $t08435084522 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
2025+ let remainMargin = $t08435084522._1
2026+ let badDebt = $t08435084522._2
2027+ let fundingPayment = $t08435084522._3
20332028 throw((((((s(remainMargin) + s(fundingPayment)) + s(getMarginRatio(_trader))) + s(unrealizedPnl)) + s(badDebt)) + s(positionNotional)))
20342029 }
20352030 else throw("Strict value is not equal to itself.")
20362031 }
20372032
20382033
20392034
20402035 @Callable(i)
20412036 func view_getPegAdjustCost (_price) = {
20422037 let _qtAstR = qtAstR()
20432038 let _bsAstR = bsAstR()
20442039 let result = getSyncTerminalPrice(_price, _qtAstR, _bsAstR)
20452040 throw(toString(result._3))
20462041 }
20472042
20482043
20492044
20502045 @Callable(i)
20512046 func view_getTerminalAmmPrice () = {
2052- let $t08530885389 = getTerminalAmmState()
2053- let terminalQuoteAssetReserve = $t08530885389._1
2054- let terminalBaseAssetReserve = $t08530885389._2
2047+ let $t08493885019 = getTerminalAmmState()
2048+ let terminalQuoteAssetReserve = $t08493885019._1
2049+ let terminalBaseAssetReserve = $t08493885019._2
20552050 let price = divd(muld(terminalQuoteAssetReserve, qtAstW()), muld(terminalBaseAssetReserve, bsAstW()))
20562051 throw(toString(price))
20572052 }
20582053
20592054
20602055
20612056 @Callable(i)
20622057 func view_getFunding () = {
20632058 let underlyingPrice = getOraclePrice()
2064- let $t08560485666 = getFunding()
2065- let shortPremiumFraction = $t08560485666._1
2066- let longPremiumFraction = $t08560485666._2
2059+ let $t08523485296 = getFunding()
2060+ let shortPremiumFraction = $t08523485296._1
2061+ let longPremiumFraction = $t08523485296._2
20672062 let longFunding = divd(longPremiumFraction, underlyingPrice)
20682063 let shortFunding = divd(shortPremiumFraction, underlyingPrice)
20692064 throw((((s(longFunding) + s(shortFunding)) + s(getTwapSpotPrice())) + s(getOraclePrice())))
20702065 }
20712066
20722067
20732068
20742069 @Callable(i)
20752070 func view_getBorrowedByTrader (_trader) = {
2076- let $t08595286006 = getBorrowedByTrader(_trader)
2077- let borrowed = $t08595286006._1
2078- let assetId = $t08595286006._2
2071+ let $t08558285636 = getBorrowedByTrader(_trader)
2072+ let borrowed = $t08558285636._1
2073+ let assetId = $t08558285636._2
20792074 throw((s(borrowed) + assetId))
20802075 }
20812076
20822077
20832078
20842079 @Callable(i)
20852080 func computeSpotPrice () = {
20862081 let result = getSpotPrice()
20872082 $Tuple2(nil, result)
20882083 }
20892084
20902085
20912086
20922087 @Callable(i)
20932088 func computeFeeForTraderWithArtifact (_trader,_artifactId) = {
20942089 let result = getForTraderWithArtifact(_trader, _artifactId)
20952090 $Tuple2(nil, result)
20962091 }
20972092
20982093
20992094 @Verifier(tx)
21002095 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], adminPublicKey())
21012096

github/deemru/w8io/873ac7e 
416.76 ms