tx · 5LKvTSH76LxRz3oKWL61zSii1nngsWqFndasbF5wgAbU

3N4SpfepyNLLb4Uc8e3xvkZew64HMcZ23oX:  -0.07500000 Waves

2023.01.04 14:52 [2390361] smart account 3N4SpfepyNLLb4Uc8e3xvkZew64HMcZ23oX > SELF 0.00000000 Waves

{ "type": 13, "id": "5LKvTSH76LxRz3oKWL61zSii1nngsWqFndasbF5wgAbU", "fee": 7500000, "feeAssetId": null, "timestamp": 1672843972673, "version": 2, "chainId": 84, "sender": "3N4SpfepyNLLb4Uc8e3xvkZew64HMcZ23oX", "senderPublicKey": "Gqr4yqnGvyo3GmKz59Qs1qfyDm5XhT134DCjiBhmD8jW", "proofs": [ "3ZrCQsZAZkU6sCGrGeT1bzv3M8ntGJYoJdFA51w5SR1GUThxgfAuhCkbmExtZ9RaugRhNuFB5Bg8ZYfp1thzHL5h" ], "script": "base64:BgJ6CAISABIAEgASABIDCgEBEgMKAQESDgoMAQEBAQEBAQEBAQEBEhQKEgEBAQEBAQEICAgIAQEBAQEBARIFCgMBAQESBgoEAQEBCBIAEgMKAQESBAoCAQESAwoBCBIAEgASAwoBCBIDCgEBEgASABIDCgEIEgASBAoCCAjDAQAJa19vcmFfa2V5AglrX29yYV9rZXkAD2tfb3JhX2Jsb2NrX2tleQIPa19vcmFfYmxvY2tfa2V5AA5rX29yYV9vcGVuX2tleQIOa19vcmFfb3Blbl9rZXkABWtfb3JhAgVrX29yYQAJa19iYWxhbmNlAglrX2JhbGFuY2UACmtfc2VxdWVuY2UCCmtfc2VxdWVuY2UADmtfcG9zaXRpb25TaXplAg5rX3Bvc2l0aW9uU2l6ZQAQa19wb3NpdGlvbk1hcmdpbgIQa19wb3NpdGlvbk1hcmdpbgAWa19wb3NpdGlvbk9wZW5Ob3Rpb25hbAIWa19wb3NpdGlvbk9wZW5Ob3Rpb25hbAAua19wb3NpdGlvbkxhc3RVcGRhdGVkQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgISa19wb3NpdGlvbkZyYWN0aW9uABJrX3Bvc2l0aW9uU2VxdWVuY2UCEmtfcG9zaXRpb25TZXF1ZW5jZQAPa19wb3NpdGlvbkFzc2V0Ag9rX3Bvc2l0aW9uQXNzZXQADWtfaW5pdGlhbGl6ZWQCDWtfaW5pdGlhbGl6ZWQACGtfcGF1c2VkAghrX3BhdXNlZAALa19jbG9zZU9ubHkCC2tfY2xvc2VPbmx5AAVrX2ZlZQIFa19mZWUAD2tfZnVuZGluZ1BlcmlvZAIPa19mdW5kaW5nUGVyaW9kABFrX2luaXRNYXJnaW5SYXRpbwIRa19pbml0TWFyZ2luUmF0aW8AGGtfbWFpbnRlbmFuY2VNYXJnaW5SYXRpbwIFa19tbXIAFWtfbGlxdWlkYXRpb25GZWVSYXRpbwIVa19saXF1aWRhdGlvbkZlZVJhdGlvABlrX3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAhZrX3BhcnRMaXF1aWRhdGlvblJhdGlvAA1rX3NwcmVhZExpbWl0Ag1rX3NwcmVhZExpbWl0ABBrX21heFByaWNlSW1wYWN0AhBrX21heFByaWNlSW1wYWN0ABBrX21heFByaWNlU3ByZWFkAhBrX21heFByaWNlU3ByZWFkABFrX21heE9wZW5Ob3Rpb25hbAIRa19tYXhPcGVuTm90aW9uYWwAFWtfZmVlVG9TdGFrZXJzUGVyY2VudAIVa19mZWVUb1N0YWtlcnNQZXJjZW50ABBrX21heE9yYWNsZURlbGF5AhBrX21heE9yYWNsZURlbGF5AA1rX2xhc3REYXRhU3RyAg1rX2xhc3REYXRhU3RyAA5rX2xhc3RNaW51dGVJZAIOa19sYXN0TWludXRlSWQAHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlAh1rX3R3YXBEYXRhTGFzdEN1bXVsYXRpdmVQcmljZQATa190d2FwRGF0YUxhc3RQcmljZQITa190d2FwRGF0YUxhc3RQcmljZQAaa190d2FwRGF0YVByZXZpb3VzTWludXRlSWQCGmtfdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkACVrX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAhtrX2xhdGVzdExvbmdQcmVtaXVtRnJhY3Rpb24AJmtfbGF0ZXN0U2hvcnRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAhxrX2xhdGVzdFNob3J0UHJlbWl1bUZyYWN0aW9uABJrX25leHRGdW5kaW5nQmxvY2sCHmtfbmV4dEZ1bmRpbmdCbG9ja01pblRpbWVzdGFtcAARa19sb25nRnVuZGluZ1JhdGUCEWtfbG9uZ0Z1bmRpbmdSYXRlABJrX3Nob3J0RnVuZGluZ1JhdGUCEmtfc2hvcnRGdW5kaW5nUmF0ZQATa19xdW90ZUFzc2V0UmVzZXJ2ZQIIa19xdEFzdFIAEmtfYmFzZUFzc2V0UmVzZXJ2ZQIIa19ic0FzdFIAEmtfcXVvdGVBc3NldFdlaWdodAIIa19xdEFzdFcAEWtfYmFzZUFzc2V0V2VpZ2h0AghrX2JzQXN0VwATa190b3RhbFBvc2l0aW9uU2l6ZQITa190b3RhbFBvc2l0aW9uU2l6ZQAXa190b3RhbExvbmdQb3NpdGlvblNpemUCF2tfdG90YWxMb25nUG9zaXRpb25TaXplABhrX3RvdGFsU2hvcnRQb3NpdGlvblNpemUCGGtfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAWa19vcGVuSW50ZXJlc3ROb3Rpb25hbAIWa19vcGVuSW50ZXJlc3ROb3Rpb25hbAATa19vcGVuSW50ZXJlc3RTaG9ydAITa19vcGVuSW50ZXJlc3RTaG9ydAASa19vcGVuSW50ZXJlc3RMb25nAhJrX29wZW5JbnRlcmVzdExvbmcAFGtfY29vcmRpbmF0b3JBZGRyZXNzAhRrX2Nvb3JkaW5hdG9yQWRkcmVzcwAPa192YXVsdF9hZGRyZXNzAg9rX3ZhdWx0X2FkZHJlc3MAD2tfYWRtaW5fYWRkcmVzcwIPa19hZG1pbl9hZGRyZXNzABJrX2FkbWluX3B1YmxpY19rZXkCEmtfYWRtaW5fcHVibGljX2tleQANa19xdW90ZV9hc3NldAINa19xdW90ZV9hc3NldAAPa19xdW90ZV9zdGFraW5nAg9rX3F1b3RlX3N0YWtpbmcAEWtfc3Rha2luZ19hZGRyZXNzAhFrX3N0YWtpbmdfYWRkcmVzcwAPa19taW5lcl9hZGRyZXNzAg9rX21pbmVyX2FkZHJlc3MAEGtfb3JkZXJzX2FkZHJlc3MCEGtfb3JkZXJzX2FkZHJlc3MAEmtfcmVmZXJyYWxfYWRkcmVzcwISa19yZWZlcnJhbF9hZGRyZXNzABRrX2NvbGxhdGVyYWxfYWRkcmVzcwIUa19jb2xsYXRlcmFsX2FkZHJlc3MAEmtfZXhjaGFuZ2VfYWRkcmVzcwISa19leGNoYW5nZV9hZGRyZXNzABVrX25mdF9tYW5hZ2VyX2FkZHJlc3MCFWtfbmZ0X21hbmFnZXJfYWRkcmVzcwAga190cmFkZXJfbWFya2V0X2Fzc2V0X2NvbGxhdGVyYWwCIGtfdHJhZGVyX21hcmtldF9hc3NldF9jb2xsYXRlcmFsAQ50b0NvbXBvc2l0ZUtleQIEX2tleQhfYWRkcmVzcwkArAICCQCsAgIFBF9rZXkCAV8FCF9hZGRyZXNzAQtjb29yZGluYXRvcgAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzBRRrX2Nvb3JkaW5hdG9yQWRkcmVzcwITQ29vcmRpbmF0b3Igbm90IHNldAEMYWRtaW5BZGRyZXNzAAkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABQ9rX2FkbWluX2FkZHJlc3MBDmFkbWluUHVibGljS2V5AAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABRJrX2FkbWluX3B1YmxpY19rZXkBCnF1b3RlQXNzZXQACQDZBAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFDWtfcXVvdGVfYXNzZXQBEXF1b3RlQXNzZXRTdGFraW5nAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFD2tfcXVvdGVfc3Rha2luZwIbUXVvdGUgYXNzZXQgc3Rha2luZyBub3Qgc2V0AQ5zdGFraW5nQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABRFrX3N0YWtpbmdfYWRkcmVzcwIPU3Rha2luZyBub3Qgc2V0AQx2YXVsdEFkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUPa192YXVsdF9hZGRyZXNzAg1WYXVsdCBub3Qgc2V0AQxtaW5lckFkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUPa19taW5lcl9hZGRyZXNzAg1NaW5lciBub3Qgc2V0AQ1vcmRlcnNBZGRyZXNzAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFEGtfb3JkZXJzX2FkZHJlc3MCDk9yZGVycyBub3Qgc2V0AQ9yZWZlcnJhbEFkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUSa19yZWZlcnJhbF9hZGRyZXNzAhBSZWZlcnJhbCBub3Qgc2V0ARFuZnRNYW5hZ2VyQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABRVrX25mdF9tYW5hZ2VyX2FkZHJlc3MCE05GVCBNYW5hZ2VyIG5vdCBzZXQBEWNvbGxhdGVyYWxBZGRyZXNzAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFFGtfY29sbGF0ZXJhbF9hZGRyZXNzAhpDb2xsYXRlcmFsIE1hbmFnZXIgbm90IHNldAELc3dhcEFkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIJAQtjb29yZGluYXRvcgAFEmtfZXhjaGFuZ2VfYWRkcmVzcwIPTm8gc3dhcCBhZGRyZXNzAhRJbnZhbGlkIHN3YXAgYWRkcmVzcwARa193aGl0ZWxpc3RfYXNzZXQCEWtfd2hpdGVsaXN0X2Fzc2V0ARBpc1doaXRlbGlzdEFzc2V0AQhfYXNzZXRJZAkBC3ZhbHVlT3JFbHNlAgkAmwgCCQERY29sbGF0ZXJhbEFkZHJlc3MACQEOdG9Db21wb3NpdGVLZXkCBRFrX3doaXRlbGlzdF9hc3NldAUIX2Fzc2V0SWQHAA1rX3Rva2VuX3BhcmFtAg1rX3Rva2VuX3BhcmFtAAxrX3Rva2VuX3R5cGUCDGtfdG9rZW5fdHlwZQAYRkVFX1JFRFVDVElPTl9UT0tFTl9UWVBFAg1mZWVfcmVkdWN0aW9uAAhESVJfTE9ORwABAAlESVJfU0hPUlQAAgANVFdBUF9JTlRFUlZBTAAPAA9PUkFDTEVfSU5URVJWQUwADwAHU0VDT05EUwDoBwAPREVDSU1BTF9OVU1CRVJTAAYADERFQ0lNQUxfVU5JVAkAaAIAAQkAaAIJAGgCCQBoAgkAaAIJAGgCAAoACgAKAAoACgAKAAdPTkVfREFZCQBoAgCAowUFDERFQ0lNQUxfVU5JVAAIQUxMX0ZFRVMAZAAPUE5MX09QVElPTl9TUE9UAAEAEVBOTF9PUFRJT05fT1JBQ0xFAAIBAXMBAl94CQCsAgIJAKQDAQUCX3gCASwBBGRpdmQCAl94Al95CQBuBAUCX3gFDERFQ0lNQUxfVU5JVAUCX3kFCEhBTEZFVkVOAQRtdWxkAgJfeAJfeQkAbgQFAl94BQJfeQUMREVDSU1BTF9VTklUBQhIQUxGRVZFTgEFc3FydGQBAl94CQEEc3FydAQFAl94BQ9ERUNJTUFMX05VTUJFUlMFD0RFQ0lNQUxfTlVNQkVSUwUISEFMRkVWRU4BBHBvd2QCAl94Al95CQBsBgUCX3gFD0RFQ0lNQUxfTlVNQkVSUwUCX3kFD0RFQ0lNQUxfTlVNQkVSUwUPREVDSU1BTF9OVU1CRVJTBQhIQUxGRVZFTgEFYmRpdmQCAl94Al95CQC9AgQFAl94CQC2AgEFDERFQ0lNQUxfVU5JVAUCX3kFCEhBTEZFVkVOAQVibXVsZAICX3gCX3kJAL0CBAUCX3gFAl95CQC2AgEFDERFQ0lNQUxfVU5JVAUISEFMRkVWRU4BBmJzcXJ0ZAECX3gJAQpzcXJ0QmlnSW50BAUCX3gFD0RFQ0lNQUxfTlVNQkVSUwUPREVDSU1BTF9OVU1CRVJTBQhIQUxGRVZFTgEFYnBvd2QCAl94Al95CQB2BgUCX3gFD0RFQ0lNQUxfTlVNQkVSUwUCX3kFD0RFQ0lNQUxfTlVNQkVSUwUPREVDSU1BTF9OVU1CRVJTBQhIQUxGRVZFTgEDYWJzAQJfeAMJAGYCBQJfeAAABQJfeAkBAS0BBQJfeAEEdm1heAICX3gCX3kDCQBnAgUCX3gFAl95BQJfeAUCX3kBCWxpc3RUb1N0cgEFX2xpc3QKAQVfam9pbgILYWNjdW11bGF0b3IDdmFsCQCsAgIJAKwCAgULYWNjdW11bGF0b3IFA3ZhbAIBLAQKbmV3TGlzdFN0cgoAAiRsBQVfbGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzACAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEFX2pvaW4CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAQLbmV3TGlzdFN0clUJALMCAgUKbmV3TGlzdFN0cgABBAtuZXdMaXN0U3RyUgMJAAACCQCvAgIFC25ld0xpc3RTdHJVAAECASwJALACAgULbmV3TGlzdFN0clUAAQULbmV3TGlzdFN0clUFC25ld0xpc3RTdHJSAQlzdHJUb0xpc3QBBF9zdHIJALUJAgUEX3N0cgIBLAELcHVzaFRvUXVldWUDBV9saXN0CF9tYXhTaXplBl92YWx1ZQMJAGYCCQCQAwEFBV9saXN0BQhfbWF4U2l6ZQkAzQgCCQDRCAIFBV9saXN0AAAFBl92YWx1ZQkAzQgCBQVfbGlzdAUGX3ZhbHVlAQNpbnQBAWsJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzBQFrCQCsAgICDW5vIHZhbHVlIGZvciAFAWsBBWludE9yAgFrA2RlZgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFrBQNkZWYBBHN0ckECCF9hZGRyZXNzBF9rZXkEA3ZhbAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFCF9hZGRyZXNzBQRfa2V5CQCsAgICEU5vIHZhbHVlIGZvciBrZXkgBQRfa2V5BQN2YWwBBGludEECCF9hZGRyZXNzBF9rZXkEA3ZhbAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFCF9hZGRyZXNzBQRfa2V5CQCsAgICEU5vIHZhbHVlIGZvciBrZXkgBQRfa2V5BQN2YWwBCGNiYWxhbmNlAAkBA2ludAEFCWtfYmFsYW5jZQEDZmVlAAkBA2ludAEFBWtfZmVlAQ9pbml0TWFyZ2luUmF0aW8ACQEDaW50AQURa19pbml0TWFyZ2luUmF0aW8BBnF0QXN0UgAJAQNpbnQBBRNrX3F1b3RlQXNzZXRSZXNlcnZlAQZic0FzdFIACQEDaW50AQUSa19iYXNlQXNzZXRSZXNlcnZlAQZxdEFzdFcACQEFaW50T3ICBRJrX3F1b3RlQXNzZXRXZWlnaHQFDERFQ0lNQUxfVU5JVAEGYnNBc3RXAAkBBWludE9yAgURa19iYXNlQXNzZXRXZWlnaHQFDERFQ0lNQUxfVU5JVAERdG90YWxQb3NpdGlvblNpemUACQEDaW50AQUTa190b3RhbFBvc2l0aW9uU2l6ZQEUb3BlbkludGVyZXN0Tm90aW9uYWwACQEDaW50AQUWa19vcGVuSW50ZXJlc3ROb3Rpb25hbAERb3BlbkludGVyZXN0U2hvcnQACQEDaW50AQUTa19vcGVuSW50ZXJlc3RTaG9ydAEQb3BlbkludGVyZXN0TG9uZwAJAQNpbnQBBRJrX29wZW5JbnRlcmVzdExvbmcBGW5leHRGdW5kaW5nQmxvY2tUaW1lc3RhbXAACQEDaW50AQUSa19uZXh0RnVuZGluZ0Jsb2NrARBmdW5kaW5nUGVyaW9kUmF3AAkBA2ludAEFD2tfZnVuZGluZ1BlcmlvZAEUZnVuZGluZ1BlcmlvZERlY2ltYWwACQBoAgkBEGZ1bmRpbmdQZXJpb2RSYXcABQxERUNJTUFMX1VOSVQBFGZ1bmRpbmdQZXJpb2RTZWNvbmRzAAkAaAIJARBmdW5kaW5nUGVyaW9kUmF3AAUHU0VDT05EUwEWbWFpbnRlbmFuY2VNYXJnaW5SYXRpbwAJAQNpbnQBBRhrX21haW50ZW5hbmNlTWFyZ2luUmF0aW8BE2xpcXVpZGF0aW9uRmVlUmF0aW8ACQEDaW50AQUVa19saXF1aWRhdGlvbkZlZVJhdGlvARdwYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwAJAQNpbnQBBRlrX3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAQtzcHJlYWRMaW1pdAAJAQNpbnQBBQ1rX3NwcmVhZExpbWl0AQ5tYXhQcmljZUltcGFjdAAJAQNpbnQBBRBrX21heFByaWNlSW1wYWN0AQ5tYXhQcmljZVNwcmVhZAAJAQNpbnQBBRBrX21heFByaWNlU3ByZWFkAQ9tYXhPcGVuTm90aW9uYWwACQEDaW50AQURa19tYXhPcGVuTm90aW9uYWwBI2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAkBA2ludAEFJWtfbGF0ZXN0TG9uZ0N1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24BJGxhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAJAQNpbnQBBSZrX2xhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgEWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAJAQNpbnQBBRhrX3RvdGFsU2hvcnRQb3NpdGlvblNpemUBFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAJAQNpbnQBBRdrX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQEMbGFzdFNlcXVlbmNlAAkBBWludE9yAgUKa19zZXF1ZW5jZQAAARNmZWVUb1N0YWtlcnNQZXJjZW50AAkBA2ludAEFFWtfZmVlVG9TdGFrZXJzUGVyY2VudAEObWF4T3JhY2xlRGVsYXkACQEDaW50AQUQa19tYXhPcmFjbGVEZWxheQEPZ2V0QWN0dWFsQ2FsbGVyAQFpCQELdmFsdWVPckVsc2UCCQCdCAIJAQ1vcmRlcnNBZGRyZXNzAAIIa19zZW5kZXIJAKUIAQgFAWkGY2FsbGVyARZyZXF1aXJlTW9yZU1hcmdpblJhdGlvAwxfbWFyZ2luUmF0aW8QX2Jhc2VNYXJnaW5SYXRpbxRfbGFyZ2VyVGhhbk9yRXF1YWxUbwQUcmVtYWluaW5nTWFyZ2luUmF0aW8JAGUCBQxfbWFyZ2luUmF0aW8FEF9iYXNlTWFyZ2luUmF0aW8DAwUUX2xhcmdlclRoYW5PckVxdWFsVG8JAGYCAAAFFHJlbWFpbmluZ01hcmdpblJhdGlvBwkAAgEJAKwCAgkArAICCQCsAgICEEludmFsaWQgbWFyZ2luOiAJAKQDAQUMX21hcmdpblJhdGlvAgMgPCAJAKQDAQUQX2Jhc2VNYXJnaW5SYXRpbwMDCQEBIQEFFF9sYXJnZXJUaGFuT3JFcXVhbFRvCQBnAgUUcmVtYWluaW5nTWFyZ2luUmF0aW8AAAcJAAIBCQCsAgIJAKwCAgkArAICAhBJbnZhbGlkIG1hcmdpbjogCQCkAwEFDF9tYXJnaW5SYXRpbwIDID4gCQCkAwEFEF9iYXNlTWFyZ2luUmF0aW8GAR9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQ1fcG9zaXRpb25TaXplAwkAAAIFDV9wb3NpdGlvblNpemUAAAkAAgECLFNob3VsZCBub3QgYmUgY2FsbGVkIHdpdGggX3Bvc2l0aW9uU2l6ZSA9PSAwAwkAZgIFDV9wb3NpdGlvblNpemUAAAkBI2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAkBJGxhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgABC2dldFBvc2l0aW9uAQdfdHJhZGVyBA9wb3NpdGlvblNpemVPcHQJAJoIAgUEdGhpcwkBDnRvQ29tcG9zaXRlS2V5AgUOa19wb3NpdGlvblNpemUFB190cmFkZXIEByRtYXRjaDAFD3Bvc2l0aW9uU2l6ZU9wdAMJAAECBQckbWF0Y2gwAgNJbnQEDHBvc2l0aW9uU2l6ZQUHJG1hdGNoMAkAlgoEBQxwb3NpdGlvblNpemUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFEGtfcG9zaXRpb25NYXJnaW4FB190cmFkZXIJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFFmtfcG9zaXRpb25PcGVuTm90aW9uYWwFB190cmFkZXIJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFLmtfcG9zaXRpb25MYXN0VXBkYXRlZEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FB190cmFkZXIJAJYKBAAAAAAAAAAAARBnZXRQb3NpdGlvbkFzc2V0AQdfdHJhZGVyBBBwb3NpdGlvbkFzc2V0T3B0CQCdCAIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFD2tfcG9zaXRpb25Bc3NldAUHX3RyYWRlcgQHJG1hdGNoMAUQcG9zaXRpb25Bc3NldE9wdAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEDXBvc2l0aW9uQXNzZXQFByRtYXRjaDAFDXBvc2l0aW9uQXNzZXQJANgEAQkBCnF1b3RlQXNzZXQAARNyZXF1aXJlT3BlblBvc2l0aW9uAQdfdHJhZGVyAwkAAAIICQELZ2V0UG9zaXRpb24BBQdfdHJhZGVyAl8xAAAJAAIBAhBObyBvcGVuIHBvc2l0aW9uBgELaW5pdGlhbGl6ZWQACQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFDWtfaW5pdGlhbGl6ZWQHAQZwYXVzZWQACQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFCGtfcGF1c2VkBwEJY2xvc2VPbmx5AAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzBQtrX2Nsb3NlT25seQcBDXVwZGF0ZVJlc2VydmUDBl9pc0FkZBFfcXVvdGVBc3NldEFtb3VudBBfYmFzZUFzc2V0QW1vdW50AwUGX2lzQWRkBAduZXdCYXNlCQBlAgkBBmJzQXN0UgAFEF9iYXNlQXNzZXRBbW91bnQDCQBnAgAABQduZXdCYXNlCQACAQIqVHggbGVhZCB0byBiYXNlIGFzc2V0IHJlc2VydmUgPD0gMCwgcmV2ZXJ0CQCVCgMJAGQCCQEGcXRBc3RSAAURX3F1b3RlQXNzZXRBbW91bnQFB25ld0Jhc2UJAGQCCQERdG90YWxQb3NpdGlvblNpemUABRBfYmFzZUFzc2V0QW1vdW50BAhuZXdRdW90ZQkAZQIJAQZxdEFzdFIABRFfcXVvdGVBc3NldEFtb3VudAMJAGcCAAAFCG5ld1F1b3RlCQACAQIqVHggbGVhZCB0byBiYXNlIHF1b3RlIHJlc2VydmUgPD0gMCwgcmV2ZXJ0CQCVCgMFCG5ld1F1b3RlCQBkAgkBBmJzQXN0UgAFEF9iYXNlQXNzZXRBbW91bnQJAGUCCQERdG90YWxQb3NpdGlvblNpemUABRBfYmFzZUFzc2V0QW1vdW50AQ1jYWxjSW52YXJpYW50BAdfcXRBc3RSB19xdEFzdFcHX2JzQXN0UgdfYnNBc3RXBAdicXRBc3RSCQC2AgEFB19xdEFzdFIEB2JxdEFzdFcJALYCAQUHX3F0QXN0VwQHYmJzQXN0UgkAtgIBBQdfYnNBc3RSBAdiYnNBc3RXCQC2AgEFB19ic0FzdFcJAQVibXVsZAIJAQVibXVsZAIFB2JxdEFzdFIFB2JxdEFzdFcJAQVibXVsZAIFB2Jic0FzdFIFB2Jic0FzdFcBCXN3YXBJbnB1dAIGX2lzQWRkEV9xdW90ZUFzc2V0QW1vdW50BAdfcXRBc3RSCQEGcXRBc3RSAAQHX2JzQXN0UgkBBmJzQXN0UgAEB19xdEFzdFcJAQZxdEFzdFcABAdfYnNBc3RXCQEGYnNBc3RXAAQBawkBDWNhbGNJbnZhcmlhbnQEBQdfcXRBc3RSBQdfcXRBc3RXBQdfYnNBc3RSBQdfYnNBc3RXBBZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyAwUGX2lzQWRkCQBkAgUHX3F0QXN0UgURX3F1b3RlQXNzZXRBbW91bnQJAGUCBQdfcXRBc3RSBRFfcXVvdGVBc3NldEFtb3VudAQVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCQCgAwEJAQViZGl2ZAIFAWsJALYCAQkBBG11bGQCBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBQdfcXRBc3RXBBhhbW91bnRCYXNlQXNzZXRCb3VnaHRBYnMJAQRkaXZkAgkBA2FicwEJAGUCBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFB19ic0FzdFIFB19xdEFzdFcEFWFtb3VudEJhc2VBc3NldEJvdWdodAMFBl9pc0FkZAUYYW1vdW50QmFzZUFzc2V0Qm91Z2h0QWJzCQEBLQEFGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwQNJHQwMTY5MzcxNzEwMAkBDXVwZGF0ZVJlc2VydmUDBQZfaXNBZGQFEV9xdW90ZUFzc2V0QW1vdW50BRhhbW91bnRCYXNlQXNzZXRCb3VnaHRBYnMEF3F1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIxCAUNJHQwMTY5MzcxNzEwMAJfMQQWYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyMQgFDSR0MDE2OTM3MTcxMDACXzIEF3RvdGFsUG9zaXRpb25TaXplQWZ0ZXIxCAUNJHQwMTY5MzcxNzEwMAJfMwQLcHJpY2VCZWZvcmUJAQRkaXZkAgkBBG11bGQCBQdfcXRBc3RSBQdfcXRBc3RXCQEEbXVsZAIFB19ic0FzdFIFB19ic0FzdFcEC21hcmtldFByaWNlCQEEZGl2ZAIFEV9xdW90ZUFzc2V0QW1vdW50BRhhbW91bnRCYXNlQXNzZXRCb3VnaHRBYnMECXByaWNlRGlmZgkBA2FicwEJAGUCBQtwcmljZUJlZm9yZQULbWFya2V0UHJpY2UEC3ByaWNlSW1wYWN0CQBlAgUMREVDSU1BTF9VTklUCQEEZGl2ZAIFC3ByaWNlQmVmb3JlCQBkAgULcHJpY2VCZWZvcmUFCXByaWNlRGlmZgQTbWF4UHJpY2VJbXBhY3RWYWx1ZQkBDm1heFByaWNlSW1wYWN0AAMJAGYCBQtwcmljZUltcGFjdAUTbWF4UHJpY2VJbXBhY3RWYWx1ZQkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgINUHJpY2UgaW1wYWN0IAkApAMBBQtwcmljZUltcGFjdAIUID4gbWF4IHByaWNlIGltcGFjdCAJAKQDAQUTbWF4UHJpY2VJbXBhY3RWYWx1ZQIVIGJlZm9yZSBxdW90ZSBhc3NldDogCQCkAwEFB19xdEFzdFICFCBiZWZvcmUgYmFzZSBhc3NldDogCQCkAwEFB19ic0FzdFICISBxdW90ZSBhc3NldCBhbW91bnQgdG8gZXhjaGFuZ2U6IAkApAMBBRFfcXVvdGVBc3NldEFtb3VudAIPIHByaWNlIGJlZm9yZTogCQCkAwEFC3ByaWNlQmVmb3JlAg4gbWFya2V0UHJpY2U6IAkApAMBBQttYXJrZXRQcmljZQkAlgoEBRVhbW91bnRCYXNlQXNzZXRCb3VnaHQFF3F1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIxBRZiYXNlQXNzZXRSZXNlcnZlQWZ0ZXIxBRd0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyMQEiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAQQX29sZFBvc2l0aW9uU2l6ZRJfb2xkUG9zaXRpb25NYXJnaW4lX29sZFBvc2l0aW9uQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgxfbWFyZ2luRGVsdGEEDmZ1bmRpbmdQYXltZW50AwkBAiE9AgUQX29sZFBvc2l0aW9uU2l6ZQAABCBfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkBH2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24BBRBfb2xkUG9zaXRpb25TaXplCQEEbXVsZAIJAGUCBSBfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUlX29sZFBvc2l0aW9uQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUQX29sZFBvc2l0aW9uU2l6ZQAABAxzaWduZWRNYXJnaW4JAGQCCQBlAgUMX21hcmdpbkRlbHRhBQ5mdW5kaW5nUGF5bWVudAUSX29sZFBvc2l0aW9uTWFyZ2luBA0kdDAxODU4NzE4NzE0AwkAZgIAAAUMc2lnbmVkTWFyZ2luCQCUCgIAAAkBA2FicwEFDHNpZ25lZE1hcmdpbgkAlAoCCQEDYWJzAQUMc2lnbmVkTWFyZ2luAAAEDHJlbWFpbk1hcmdpbggFDSR0MDE4NTg3MTg3MTQCXzEEB2JhZERlYnQIBQ0kdDAxODU4NzE4NzE0Al8yCQCVCgMFDHJlbWFpbk1hcmdpbgUHYmFkRGVidAUOZnVuZGluZ1BheW1lbnQBFnN3YXBPdXRwdXRXaXRoUmVzZXJ2ZXMHBl9pc0FkZBBfYmFzZUFzc2V0QW1vdW50FF9jaGVja01heFByaWNlSW1wYWN0El9xdW90ZUFzc2V0UmVzZXJ2ZRFfcXVvdGVBc3NldFdlaWdodBFfYmFzZUFzc2V0UmVzZXJ2ZRBfYmFzZUFzc2V0V2VpZ2h0BAtwcmljZUJlZm9yZQkBBGRpdmQCCQEEbXVsZAIFEl9xdW90ZUFzc2V0UmVzZXJ2ZQURX3F1b3RlQXNzZXRXZWlnaHQJAQRtdWxkAgURX2Jhc2VBc3NldFJlc2VydmUFEF9iYXNlQXNzZXRXZWlnaHQDCQAAAgUQX2Jhc2VBc3NldEFtb3VudAAACQACAQIZSW52YWxpZCBiYXNlIGFzc2V0IGFtb3VudAQBawkBDWNhbGNJbnZhcmlhbnQEBRJfcXVvdGVBc3NldFJlc2VydmUFEV9xdW90ZUFzc2V0V2VpZ2h0BRFfYmFzZUFzc2V0UmVzZXJ2ZQUQX2Jhc2VBc3NldFdlaWdodAQYYmFzZUFzc2V0UG9vbEFtb3VudEFmdGVyAwUGX2lzQWRkCQBkAgURX2Jhc2VBc3NldFJlc2VydmUFEF9iYXNlQXNzZXRBbW91bnQJAGUCBRFfYmFzZUFzc2V0UmVzZXJ2ZQUQX2Jhc2VBc3NldEFtb3VudAQPcXVvdGVBc3NldEFmdGVyCQCgAwEJAQViZGl2ZAIFAWsJALYCAQkBBG11bGQCBRhiYXNlQXNzZXRQb29sQW1vdW50QWZ0ZXIFEF9iYXNlQXNzZXRXZWlnaHQEDnF1b3RlQXNzZXRTb2xkCQEDYWJzAQkAZQIFD3F1b3RlQXNzZXRBZnRlcgkBBG11bGQCBRJfcXVvdGVBc3NldFJlc2VydmUFEV9xdW90ZUFzc2V0V2VpZ2h0BBNtYXhQcmljZUltcGFjdFZhbHVlCQEObWF4UHJpY2VJbXBhY3QABA0kdDAxOTkwMjIwMDYzCQENdXBkYXRlUmVzZXJ2ZQMJAQEhAQUGX2lzQWRkBQ5xdW90ZUFzc2V0U29sZAUQX2Jhc2VBc3NldEFtb3VudAQXcXVvdGVBc3NldFJlc2VydmVBZnRlcjEIBQ0kdDAxOTkwMjIwMDYzAl8xBBZiYXNlQXNzZXRSZXNlcnZlQWZ0ZXIxCAUNJHQwMTk5MDIyMDA2MwJfMgQXdG90YWxQb3NpdGlvblNpemVBZnRlcjEIBQ0kdDAxOTkwMjIwMDYzAl8zBAttYXJrZXRQcmljZQkBBGRpdmQCBQ5xdW90ZUFzc2V0U29sZAUQX2Jhc2VBc3NldEFtb3VudAQJcHJpY2VEaWZmCQEDYWJzAQkAZQIFC3ByaWNlQmVmb3JlBQttYXJrZXRQcmljZQQLcHJpY2VJbXBhY3QJAGUCBQxERUNJTUFMX1VOSVQJAQRkaXZkAgULcHJpY2VCZWZvcmUJAGQCBQtwcmljZUJlZm9yZQUJcHJpY2VEaWZmAwMJAGYCBQtwcmljZUltcGFjdAUTbWF4UHJpY2VJbXBhY3RWYWx1ZQUUX2NoZWNrTWF4UHJpY2VJbXBhY3QHCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAg1QcmljZSBpbXBhY3QgCQCkAwEFC3ByaWNlSW1wYWN0AhQgPiBtYXggcHJpY2UgaW1wYWN0IAkApAMBBRNtYXhQcmljZUltcGFjdFZhbHVlAhUgYmVmb3JlIHF1b3RlIGFzc2V0OiAJAKQDAQUSX3F1b3RlQXNzZXRSZXNlcnZlAhQgYmVmb3JlIGJhc2UgYXNzZXQ6IAkApAMBBRFfYmFzZUFzc2V0UmVzZXJ2ZQIgIGJhc2UgYXNzZXQgYW1vdW50IHRvIGV4Y2hhbmdlOiAJAKQDAQUQX2Jhc2VBc3NldEFtb3VudAIPIHByaWNlIGJlZm9yZTogCQCkAwEFC3ByaWNlQmVmb3JlAg8gbWFya2V0IHByaWNlOiAJAKQDAQULbWFya2V0UHJpY2UJAJkKBwUOcXVvdGVBc3NldFNvbGQFF3F1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIxBRZiYXNlQXNzZXRSZXNlcnZlQWZ0ZXIxBRd0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyMQkAZQIJARV0b3RhbExvbmdQb3NpdGlvblNpemUAAwUGX2lzQWRkCQEDYWJzAQUQX2Jhc2VBc3NldEFtb3VudAAACQBlAgkBFnRvdGFsU2hvcnRQb3NpdGlvblNpemUAAwkBASEBBQZfaXNBZGQJAQNhYnMBBRBfYmFzZUFzc2V0QW1vdW50AAAFC3ByaWNlSW1wYWN0AQpzd2FwT3V0cHV0AwZfaXNBZGQQX2Jhc2VBc3NldEFtb3VudBRfY2hlY2tNYXhQcmljZUltcGFjdAkBFnN3YXBPdXRwdXRXaXRoUmVzZXJ2ZXMHBQZfaXNBZGQFEF9iYXNlQXNzZXRBbW91bnQFFF9jaGVja01heFByaWNlSW1wYWN0CQEGcXRBc3RSAAkBBnF0QXN0VwAJAQZic0FzdFIACQEGYnNBc3RXAAEOZ2V0T3JhY2xlUHJpY2UABAZvcmFjbGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzBQVrX29yYQIABAhwcmljZUtleQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUJa19vcmFfa2V5BAlsYXN0VmFsdWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQZvcmFjbGUFCHByaWNlS2V5CQCsAgIJAKwCAgkArAICAiJDYW4gbm90IGdldCBvcmFjbGUgcHJpY2UuIE9yYWNsZTogCQClCAEFBm9yYWNsZQIGIGtleTogBQhwcmljZUtleQQIYmxvY2tLZXkJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUPa19vcmFfYmxvY2tfa2V5AgADCQECIT0CBQhibG9ja0tleQIABAxjdXJyZW50QmxvY2sIBQlsYXN0QmxvY2sGaGVpZ2h0BA9sYXN0T3JhY2xlQmxvY2sJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQZvcmFjbGUFCGJsb2NrS2V5CQCsAgIJAKwCAgkArAICAiJDYW4gbm90IGdldCBvcmFjbGUgYmxvY2suIE9yYWNsZTogCQClCAEFBm9yYWNsZQIGIGtleTogBQhibG9ja0tleQMJAGYCCQBlAgUMY3VycmVudEJsb2NrBQ9sYXN0T3JhY2xlQmxvY2sJAQ5tYXhPcmFjbGVEZWxheQAJAAIBCQCsAgIJAKwCAgkArAICAiZPcmFjbGUgc3RhbGUgZGF0YS4gTGFzdCBvcmFjbGUgYmxvY2s6IAkApAMBBQ9sYXN0T3JhY2xlQmxvY2sCECBjdXJyZW50IGJsb2NrOiAJAKQDAQUMY3VycmVudEJsb2NrBQlsYXN0VmFsdWUFCWxhc3RWYWx1ZQEOaXNNYXJrZXRDbG9zZWQABAZvcmFjbGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzBQVrX29yYQIABAdvcGVuS2V5CQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFDmtfb3JhX29wZW5fa2V5AgADCQECIT0CBQdvcGVuS2V5AgAEBmlzT3BlbgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCbCAIFBm9yYWNsZQUHb3BlbktleQkArAICCQCsAgIJAKwCAgIrQ2FuIG5vdCBnZXQgb3JhY2xlIGlzIG9wZW4vY2xvc2VkLiBPcmFjbGU6IAkApQgBBQZvcmFjbGUCBiBrZXk6IAUHb3BlbktleQkBASEBBQZpc09wZW4HAQxhYnNQcmljZURpZmYFDF9vcmFjbGVQcmljZRJfcXVvdGVBc3NldFJlc2VydmURX2Jhc2VBc3NldFJlc2VydmUHX3F0QXN0VwdfYnNBc3RXBApwcmljZUFmdGVyCQEEZGl2ZAIJAQRtdWxkAgUSX3F1b3RlQXNzZXRSZXNlcnZlBQdfcXRBc3RXCQEEbXVsZAIFEV9iYXNlQXNzZXRSZXNlcnZlBQdfYnNBc3RXBAxhdmVyYWdlUHJpY2UJAQRkaXZkAgkAZAIFDF9vcmFjbGVQcmljZQUKcHJpY2VBZnRlcgkAaAIAAgUMREVDSU1BTF9VTklUBAxhYnNQcmljZURpZmYJAQRkaXZkAgkBA2FicwEJAGUCBQxfb3JhY2xlUHJpY2UFCnByaWNlQWZ0ZXIFDGF2ZXJhZ2VQcmljZQUMYWJzUHJpY2VEaWZmARlyZXF1aXJlTm90T3ZlclNwcmVhZExpbWl0AhJfcXVvdGVBc3NldFJlc2VydmURX2Jhc2VBc3NldFJlc2VydmUEC29yYWNsZVByaWNlCQEOZ2V0T3JhY2xlUHJpY2UABAdfcXRBc3RXCQEGcXRBc3RXAAQHX2JzQXN0VwkBBmJzQXN0VwAEEmFic1ByaWNlRGlmZkJlZm9yZQkBDGFic1ByaWNlRGlmZgUFC29yYWNsZVByaWNlCQEGcXRBc3RSAAkBBmJzQXN0UgAFB19xdEFzdFcFB19ic0FzdFcEEWFic1ByaWNlRGlmZkFmdGVyCQEMYWJzUHJpY2VEaWZmBQULb3JhY2xlUHJpY2UFEl9xdW90ZUFzc2V0UmVzZXJ2ZQURX2Jhc2VBc3NldFJlc2VydmUFB19xdEFzdFcFB19ic0FzdFcDAwkAZgIFEWFic1ByaWNlRGlmZkFmdGVyCQEObWF4UHJpY2VTcHJlYWQACQBmAgURYWJzUHJpY2VEaWZmQWZ0ZXIFEmFic1ByaWNlRGlmZkJlZm9yZQcJAAIBCQCsAgIJAKwCAgkArAICAg1QcmljZSBzcHJlYWQgCQCkAwEFEWFic1ByaWNlRGlmZkFmdGVyAhQgPiBtYXggcHJpY2Ugc3ByZWFkIAkApAMBCQEObWF4UHJpY2VTcHJlYWQABgEdcmVxdWlyZU5vdE92ZXJNYXhPcGVuTm90aW9uYWwCEV9sb25nT3Blbk5vdGlvbmFsEl9zaG9ydE9wZW5Ob3Rpb25hbAQQX21heE9wZW5Ob3Rpb25hbAkBD21heE9wZW5Ob3Rpb25hbAADCQBmAgURX2xvbmdPcGVuTm90aW9uYWwFEF9tYXhPcGVuTm90aW9uYWwJAAIBCQCsAgIJAKwCAgkArAICAhNMb25nIG9wZW4gbm90aW9uYWwgCQCkAwEFEV9sb25nT3Blbk5vdGlvbmFsAhUgPiBtYXggb3BlbiBub3Rpb25hbCAJAKQDAQUQX21heE9wZW5Ob3Rpb25hbAMJAGYCBRJfc2hvcnRPcGVuTm90aW9uYWwFEF9tYXhPcGVuTm90aW9uYWwJAAIBCQCsAgIJAKwCAgkArAICAhRTaG9ydCBvcGVuIG5vdGlvbmFsIAkApAMBBRJfc2hvcnRPcGVuTm90aW9uYWwCFSA+IG1heCBvcGVuIG5vdGlvbmFsIAkApAMBBRBfbWF4T3Blbk5vdGlvbmFsBgEMZ2V0U3BvdFByaWNlAAQSX3F1b3RlQXNzZXRSZXNlcnZlCQEGcXRBc3RSAAQRX2Jhc2VBc3NldFJlc2VydmUJAQZic0FzdFIABAdfcXRBc3RXCQEGcXRBc3RXAAQHX2JzQXN0VwkBBmJzQXN0VwAJAQRkaXZkAgkBBG11bGQCBRJfcXVvdGVBc3NldFJlc2VydmUFB19xdEFzdFcJAQRtdWxkAgURX2Jhc2VBc3NldFJlc2VydmUFB19ic0FzdFcBFmlzT3ZlckZsdWN0dWF0aW9uTGltaXQABAtvcmFjbGVQcmljZQkBDmdldE9yYWNsZVByaWNlAAQMY3VycmVudFByaWNlCQEMZ2V0U3BvdFByaWNlAAkAZgIJAQRkaXZkAgkBA2FicwEJAGUCBQtvcmFjbGVQcmljZQUMY3VycmVudFByaWNlBQtvcmFjbGVQcmljZQkBC3NwcmVhZExpbWl0AAEfZ2V0UG9zaXRpb25BZGp1c3RlZE9wZW5Ob3Rpb25hbAYNX3Bvc2l0aW9uU2l6ZQdfb3B0aW9uEl9xdW90ZUFzc2V0UmVzZXJ2ZRFfcXVvdGVBc3NldFdlaWdodBFfYmFzZUFzc2V0UmVzZXJ2ZRBfYmFzZUFzc2V0V2VpZ2h0BA9wb3NpdGlvblNpemVBYnMJAQNhYnMBBQ1fcG9zaXRpb25TaXplBAdpc1Nob3J0CQBmAgAABQ1fcG9zaXRpb25TaXplBBBwb3NpdGlvbk5vdGlvbmFsAwkAAAIFB19vcHRpb24FD1BOTF9PUFRJT05fU1BPVAQNJHQwMjUwMTQyNTIzNAkBFnN3YXBPdXRwdXRXaXRoUmVzZXJ2ZXMHCQEBIQEFB2lzU2hvcnQFD3Bvc2l0aW9uU2l6ZUFicwcFEl9xdW90ZUFzc2V0UmVzZXJ2ZQURX3F1b3RlQXNzZXRXZWlnaHQFEV9iYXNlQXNzZXRSZXNlcnZlBRBfYmFzZUFzc2V0V2VpZ2h0BBNvdXRQb3NpdGlvbk5vdGlvbmFsCAUNJHQwMjUwMTQyNTIzNAJfMQQCeDEIBQ0kdDAyNTAxNDI1MjM0Al8yBAJ4MggFDSR0MDI1MDE0MjUyMzQCXzMEAngzCAUNJHQwMjUwMTQyNTIzNAJfNAUTb3V0UG9zaXRpb25Ob3Rpb25hbAkBBG11bGQCBQ9wb3NpdGlvblNpemVBYnMJAQ5nZXRPcmFjbGVQcmljZQAFEHBvc2l0aW9uTm90aW9uYWwBK2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sQnlWYWx1ZXMHDV9wb3NpdGlvblNpemUVX3Bvc2l0aW9uT3Blbk5vdGlvbmFsEl9xdW90ZUFzc2V0UmVzZXJ2ZRFfcXVvdGVBc3NldFdlaWdodBFfYmFzZUFzc2V0UmVzZXJ2ZRBfYmFzZUFzc2V0V2VpZ2h0B19vcHRpb24DCQAAAgUNX3Bvc2l0aW9uU2l6ZQAACQACAQIVSW52YWxpZCBwb3NpdGlvbiBzaXplBAdpc1Nob3J0CQBmAgAABQ1fcG9zaXRpb25TaXplBBBwb3NpdGlvbk5vdGlvbmFsCQEfZ2V0UG9zaXRpb25BZGp1c3RlZE9wZW5Ob3Rpb25hbAYFDV9wb3NpdGlvblNpemUFB19vcHRpb24FEl9xdW90ZUFzc2V0UmVzZXJ2ZQURX3F1b3RlQXNzZXRXZWlnaHQFEV9iYXNlQXNzZXRSZXNlcnZlBRBfYmFzZUFzc2V0V2VpZ2h0BA11bnJlYWxpemVkUG5sAwUHaXNTaG9ydAkAZQIFFV9wb3NpdGlvbk9wZW5Ob3Rpb25hbAUQcG9zaXRpb25Ob3Rpb25hbAkAZQIFEHBvc2l0aW9uTm90aW9uYWwFFV9wb3NpdGlvbk9wZW5Ob3Rpb25hbAkAlAoCBRBwb3NpdGlvbk5vdGlvbmFsBQ11bnJlYWxpemVkUG5sASNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAIHX3RyYWRlcgdfb3B0aW9uBA0kdDAyNjY1NTI2NzgzCQELZ2V0UG9zaXRpb24BBQdfdHJhZGVyBAxwb3NpdGlvblNpemUIBQ0kdDAyNjY1NTI2NzgzAl8xBA5wb3NpdGlvbk1hcmdpbggFDSR0MDI2NjU1MjY3ODMCXzIEFHBvc2l0aW9uT3Blbk5vdGlvbmFsCAUNJHQwMjY2NTUyNjc4MwJfMwQRcG9zaXRpb25Mc3RVcGRDUEYIBQ0kdDAyNjY1NTI2NzgzAl80CQErZ2V0UG9zaXRpb25Ob3Rpb25hbEFuZFVucmVhbGl6ZWRQbmxCeVZhbHVlcwcFDHBvc2l0aW9uU2l6ZQUUcG9zaXRpb25PcGVuTm90aW9uYWwJAQZxdEFzdFIACQEGcXRBc3RXAAkBBmJzQXN0UgAJAQZic0FzdFcABQdfb3B0aW9uAQ9jYWxjTWFyZ2luUmF0aW8DDV9yZW1haW5NYXJnaW4IX2JhZERlYnQRX3Bvc2l0aW9uTm90aW9uYWwJAQRkaXZkAgkAZQIFDV9yZW1haW5NYXJnaW4FCF9iYWREZWJ0BRFfcG9zaXRpb25Ob3Rpb25hbAEWZ2V0TWFyZ2luUmF0aW9CeU9wdGlvbgIHX3RyYWRlcgdfb3B0aW9uBA0kdDAyNzI5NjI3NDA3CQELZ2V0UG9zaXRpb24BBQdfdHJhZGVyBAxwb3NpdGlvblNpemUIBQ0kdDAyNzI5NjI3NDA3Al8xBA5wb3NpdGlvbk1hcmdpbggFDSR0MDI3Mjk2Mjc0MDcCXzIEA3BvbggFDSR0MDI3Mjk2Mjc0MDcCXzMEEXBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwMjcyOTYyNzQwNwJfNAQNJHQwMjc0MTMyNzUwNgkBI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAgUHX3RyYWRlcgUHX29wdGlvbgQQcG9zaXRpb25Ob3Rpb25hbAgFDSR0MDI3NDEzMjc1MDYCXzEEDXVucmVhbGl6ZWRQbmwIBQ0kdDAyNzQxMzI3NTA2Al8yBA0kdDAyNzUxMTI3Njc3CQEiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAQFDHBvc2l0aW9uU2l6ZQUOcG9zaXRpb25NYXJnaW4FEXBvc2l0aW9uTHN0VXBkQ1BGBQ11bnJlYWxpemVkUG5sBAxyZW1haW5NYXJnaW4IBQ0kdDAyNzUxMTI3Njc3Al8xBAdiYWREZWJ0CAUNJHQwMjc1MTEyNzY3NwJfMgkBD2NhbGNNYXJnaW5SYXRpbwMFDHJlbWFpbk1hcmdpbgUHYmFkRGVidAUQcG9zaXRpb25Ob3Rpb25hbAEOZ2V0TWFyZ2luUmF0aW8BB190cmFkZXIJARZnZXRNYXJnaW5SYXRpb0J5T3B0aW9uAgUHX3RyYWRlcgUPUE5MX09QVElPTl9TUE9UARtnZXRQYXJ0aWFsTGlxdWlkYXRpb25BbW91bnQCB190cmFkZXINX3Bvc2l0aW9uU2l6ZQQMbWF4aW11bVJhdGlvCQEEdm1heAIJARdwYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwAJAGUCBQxERUNJTUFMX1VOSVQJAQRkaXZkAgkBDmdldE1hcmdpblJhdGlvAQUHX3RyYWRlcgkBFm1haW50ZW5hbmNlTWFyZ2luUmF0aW8ABBhtYXhFeGNoYW5nZWRQb3NpdGlvblNpemUJAQRtdWxkAgkBA2FicwEFDV9wb3NpdGlvblNpemUFDG1heGltdW1SYXRpbwQKc3dhcFJlc3VsdAkBCnN3YXBPdXRwdXQDCQBmAgUNX3Bvc2l0aW9uU2l6ZQAABRhtYXhFeGNoYW5nZWRQb3NpdGlvblNpemUHBBxtYXhFeGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50CAUKc3dhcFJlc3VsdAJfMQQLcHJpY2VJbXBhY3QIBQpzd2FwUmVzdWx0Al83AwkAZgIJAQ5tYXhQcmljZUltcGFjdAAFC3ByaWNlSW1wYWN0BRxtYXhFeGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50BBVleGNoYW5nZWRQb3NpdGlvblNpemUJAQRtdWxkAgkBA2FicwEFDV9wb3NpdGlvblNpemUJARdwYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwAEGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQICQEKc3dhcE91dHB1dAMJAGYCBQ1fcG9zaXRpb25TaXplAAAFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQcCXzEFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQBFWludGVybmFsQ2xvc2VQb3NpdGlvbgIHX3RyYWRlchRfY2hlY2tNYXhQcmljZUltcGFjdAQNJHQwMjg5MTcyOTA0NQkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgQMcG9zaXRpb25TaXplCAUNJHQwMjg5MTcyOTA0NQJfMQQOcG9zaXRpb25NYXJnaW4IBQ0kdDAyODkxNzI5MDQ1Al8yBBRwb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDI4OTE3MjkwNDUCXzMEEXBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwMjg5MTcyOTA0NQJfNAQNdW5yZWFsaXplZFBubAgJASNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAIFB190cmFkZXIFD1BOTF9PUFRJT05fU1BPVAJfMgQNJHQwMjkxNDAyOTMwOAkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQxwb3NpdGlvblNpemUFDnBvc2l0aW9uTWFyZ2luBRFwb3NpdGlvbkxzdFVwZENQRgUNdW5yZWFsaXplZFBubAQMcmVtYWluTWFyZ2luCAUNJHQwMjkxNDAyOTMwOAJfMQQHYmFkRGVidAgFDSR0MDI5MTQwMjkzMDgCXzIEFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQkBAS0BBQxwb3NpdGlvblNpemUEC3JlYWxpemVkUG5sBQ11bnJlYWxpemVkUG5sBA1tYXJnaW5Ub1ZhdWx0CQEBLQEFDHJlbWFpbk1hcmdpbgQNJHQwMjk0MzUyOTcwOQkBCnN3YXBPdXRwdXQDCQBmAgUMcG9zaXRpb25TaXplAAAJAQNhYnMBBQxwb3NpdGlvblNpemUFFF9jaGVja01heFByaWNlSW1wYWN0BBlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50CAUNJHQwMjk0MzUyOTcwOQJfMQQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDI5NDM1Mjk3MDkCXzIEFWJhc2VBc3NldFJlc2VydmVBZnRlcggFDSR0MDI5NDM1Mjk3MDkCXzMEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDAyOTQzNTI5NzA5Al80BA50b3RhbExvbmdBZnRlcggFDSR0MDI5NDM1Mjk3MDkCXzUED3RvdGFsU2hvcnRBZnRlcggFDSR0MDI5NDM1Mjk3MDkCXzYEGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIJAGUCCQEUb3BlbkludGVyZXN0Tm90aW9uYWwABRRwb3NpdGlvbk9wZW5Ob3Rpb25hbAkAnwoNBRVleGNoYW5nZWRQb3NpdGlvblNpemUFB2JhZERlYnQFC3JlYWxpemVkUG5sBQ1tYXJnaW5Ub1ZhdWx0BRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQFDnRvdGFsTG9uZ0FmdGVyBQ90b3RhbFNob3J0QWZ0ZXIJAGUCCQEQb3BlbkludGVyZXN0TG9uZwADCQBmAgUMcG9zaXRpb25TaXplAAAFFHBvc2l0aW9uT3Blbk5vdGlvbmFsAAAJAGUCCQERb3BlbkludGVyZXN0U2hvcnQAAwkAZgIAAAUMcG9zaXRpb25TaXplBRRwb3NpdGlvbk9wZW5Ob3Rpb25hbAAAARBnZXRUd2FwU3BvdFByaWNlAAQIbWludXRlSWQJAGkCCQBpAggFCWxhc3RCbG9jawl0aW1lc3RhbXAA6AcAPAQNc3RhcnRNaW51dGVJZAkAZQIFCG1pbnV0ZUlkBQ1UV0FQX0lOVEVSVkFMBAdsaXN0U3RyCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFDWtfbGFzdERhdGFTdHICAAQEbGlzdAkAtQkCBQdsaXN0U3RyAgEsCgEIZmlsdGVyRm4CC2FjY3VtdWxhdG9yBG5leHQDCQBnAgUNc3RhcnRNaW51dGVJZAkBDXBhcnNlSW50VmFsdWUBBQRuZXh0CQDNCAIFC2FjY3VtdWxhdG9yCQENcGFyc2VJbnRWYWx1ZQEFBG5leHQFC2FjY3VtdWxhdG9yBAVsaXN0RgoAAiRsBQRsaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmaWx0ZXJGbgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMjAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUBAhtYXhJbmRleAMJAGYCCQCQAwEFBWxpc3RGAAAJAJYDAQUFbGlzdEYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQRsaXN0AAAEDGxhc3RNaW51dGVJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQ5rX2xhc3RNaW51dGVJZAAABBZlbmRMYXN0Q3VtdWxhdGl2ZVByaWNlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgkArAICBR1rX3R3YXBEYXRhTGFzdEN1bXVsYXRpdmVQcmljZQIBXwkApAMBBQxsYXN0TWludXRlSWQAAAQMZW5kTGFzdFByaWNlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgkArAICBRNrX3R3YXBEYXRhTGFzdFByaWNlAgFfCQCkAwEFDGxhc3RNaW51dGVJZAAABBJub3dDdW11bGF0aXZlUHJpY2UJAGQCBRZlbmRMYXN0Q3VtdWxhdGl2ZVByaWNlCQBoAgkAZQIFCG1pbnV0ZUlkBQxsYXN0TWludXRlSWQFDGVuZExhc3RQcmljZQQYc3RhcnRMYXN0Q3VtdWxhdGl2ZVByaWNlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgkArAICBR1rX3R3YXBEYXRhTGFzdEN1bXVsYXRpdmVQcmljZQIBXwkApAMBBQhtYXhJbmRleAAABA5zdGFydExhc3RQcmljZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgUTa190d2FwRGF0YUxhc3RQcmljZQIBXwkApAMBBQhtYXhJbmRleAAABBRzdGFydEN1bXVsYXRpdmVQcmljZQkAZAIFGHN0YXJ0TGFzdEN1bXVsYXRpdmVQcmljZQkAaAIJAGUCBQ1zdGFydE1pbnV0ZUlkBQhtYXhJbmRleAUOc3RhcnRMYXN0UHJpY2UJAGkCCQBlAgUSbm93Q3VtdWxhdGl2ZVByaWNlBRRzdGFydEN1bXVsYXRpdmVQcmljZQUNVFdBUF9JTlRFUlZBTAETZ2V0VGVybWluYWxBbW1TdGF0ZQAEDV9wb3NpdGlvblNpemUJARF0b3RhbFBvc2l0aW9uU2l6ZQADCQAAAgUNX3Bvc2l0aW9uU2l6ZQAACQCUCgIJAQZxdEFzdFIACQEGYnNBc3RSAAQJZGlyZWN0aW9uCQBmAgUNX3Bvc2l0aW9uU2l6ZQAABA0kdDAzMTgzMjMyMDExCQEKc3dhcE91dHB1dAMFCWRpcmVjdGlvbgkBA2FicwEFDV9wb3NpdGlvblNpemUHBBVjdXJyZW50TmV0TWFya2V0VmFsdWUIBQ0kdDAzMTgzMjMyMDExAl8xBBl0ZXJtaW5hbFF1b3RlQXNzZXRSZXNlcnZlCAUNJHQwMzE4MzIzMjAxMQJfMgQYdGVybWluYWxCYXNlQXNzZXRSZXNlcnZlCAUNJHQwMzE4MzIzMjAxMQJfMwkAlAoCBRl0ZXJtaW5hbFF1b3RlQXNzZXRSZXNlcnZlBRh0ZXJtaW5hbEJhc2VBc3NldFJlc2VydmUBE2dldFF1b3RlQXNzZXRXZWlnaHQEEGJhc2VBc3NldFJlc2VydmURdG90YWxQb3NpdGlvblNpemURcXVvdGVBc3NldFJlc2VydmULdGFyZ2V0UHJpY2UEAWIJALYCAQUQYmFzZUFzc2V0UmVzZXJ2ZQQCc3oJALYCAQURdG90YWxQb3NpdGlvblNpemUEAXEJALYCAQURcXVvdGVBc3NldFJlc2VydmUEAXAJALYCAQULdGFyZ2V0UHJpY2UEA2JzMgkBBWJwb3dkAgkAtwICBQFiBQJzegkAtgIBCQBoAgACBQxERUNJTUFMX1VOSVQEBHFiczIJAQVibXVsZAIFAXEFA2JzMgQDcHM0CQC5AgIJALYCAQAECQEFYm11bGQCBQFwBQJzegQDc3FyCQEGYnNxcnRkAQkBBWJtdWxkAgUEcWJzMgkAuAICBQFxBQNwczQEAmJxCQEFYm11bGQCBQFiBQFxBAJxcwkBBWJtdWxkAgUBcQUCc3oEA3RvcAkAtwICCQC3AgIJAL4CAQUDc3FyBQJicQUCcXMEA2JvdAkAuQICCQC2AgEAAgkBBWJtdWxkAgUBcQUCc3oEBnJlc3VsdAkBBWJkaXZkAgUDdG9wBQNib3QJAKADAQUGcmVzdWx0ARRnZXRTeW5jVGVybWluYWxQcmljZQMOX3Rlcm1pbmFsUHJpY2UHX3F0QXN0UgdfYnNBc3RSBA1fcG9zaXRpb25TaXplCQERdG90YWxQb3NpdGlvblNpemUAAwkAAAIFDV9wb3NpdGlvblNpemUAAAQJbmV3UXRBc3RXCQEEZGl2ZAIJAQRtdWxkAgUOX3Rlcm1pbmFsUHJpY2UFB19ic0FzdFIFB19xdEFzdFIJAJUKAwUJbmV3UXRBc3RXBQxERUNJTUFMX1VOSVQAAAQJZGlyZWN0aW9uCQBmAgUNX3Bvc2l0aW9uU2l6ZQAABBVjdXJyZW50TmV0TWFya2V0VmFsdWUICQEKc3dhcE91dHB1dAMFCWRpcmVjdGlvbgkBA2FicwEFDV9wb3NpdGlvblNpemUHAl8xBAluZXdRdEFzdFcJARNnZXRRdW90ZUFzc2V0V2VpZ2h0BAUHX2JzQXN0UgUNX3Bvc2l0aW9uU2l6ZQUHX3F0QXN0UgUOX3Rlcm1pbmFsUHJpY2UECW5ld0JzQXN0VwUMREVDSU1BTF9VTklUBA1tYXJnaW5Ub1ZhdWx0CAkBK2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sQnlWYWx1ZXMHBQ1fcG9zaXRpb25TaXplBRVjdXJyZW50TmV0TWFya2V0VmFsdWUFB19xdEFzdFIFCW5ld1F0QXN0VwUHX2JzQXN0UgUJbmV3QnNBc3RXBQ9QTkxfT1BUSU9OX1NQT1QCXzIJAJUKAwUJbmV3UXRBc3RXBQluZXdCc0FzdFcFDW1hcmdpblRvVmF1bHQBCmdldEZ1bmRpbmcABA91bmRlcmx5aW5nUHJpY2UJAQ5nZXRPcmFjbGVQcmljZQAEDXNwb3RUd2FwUHJpY2UJARBnZXRUd2FwU3BvdFByaWNlAAQHcHJlbWl1bQkAZQIFDXNwb3RUd2FwUHJpY2UFD3VuZGVybHlpbmdQcmljZQMDAwkAAAIJARZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAAABgkAAAIJARV0b3RhbExvbmdQb3NpdGlvblNpemUAAAAGCQEOaXNNYXJrZXRDbG9zZWQACQCUCgIAAAAAAwkAZgIAAAUHcHJlbWl1bQQUc2hvcnRQcmVtaXVtRnJhY3Rpb24JAQRkaXZkAgkBBG11bGQCBQdwcmVtaXVtCQEUZnVuZGluZ1BlcmlvZERlY2ltYWwABQdPTkVfREFZBBNsb25nUHJlbWl1bUZyYWN0aW9uCQEEZGl2ZAIJAQRtdWxkAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24JARZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAkBFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAJAJQKAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24FE2xvbmdQcmVtaXVtRnJhY3Rpb24EE2xvbmdQcmVtaXVtRnJhY3Rpb24JAQRkaXZkAgkBBG11bGQCBQdwcmVtaXVtCQEUZnVuZGluZ1BlcmlvZERlY2ltYWwABQdPTkVfREFZBBRzaG9ydFByZW1pdW1GcmFjdGlvbgkBBGRpdmQCCQEEbXVsZAIFE2xvbmdQcmVtaXVtRnJhY3Rpb24JARV0b3RhbExvbmdQb3NpdGlvblNpemUACQEWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAJAJQKAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24FE2xvbmdQcmVtaXVtRnJhY3Rpb24BDmdldEFkanVzdGVkRmVlAgtfYXJ0aWZhY3RJZBBfYmFzZUZlZURpc2NvdW50BApiYXNlRmVlUmF3CQEDZmVlAAQHYmFzZUZlZQkBBG11bGQCBQpiYXNlRmVlUmF3BRBfYmFzZUZlZURpc2NvdW50BA0kdDAzNTA1OTM1NTU0AwkBAiE9AgULX2FydGlmYWN0SWQCAAQMYXJ0aWZhY3RLaW5kCQEEc3RyQQIJARFuZnRNYW5hZ2VyQWRkcmVzcwAJAQ50b0NvbXBvc2l0ZUtleQIFDGtfdG9rZW5fdHlwZQULX2FydGlmYWN0SWQDCQAAAgUMYXJ0aWZhY3RLaW5kBRhGRUVfUkVEVUNUSU9OX1RPS0VOX1RZUEUECXJlZHVjdGlvbgkBBGludEECCQERbmZ0TWFuYWdlckFkZHJlc3MACQEOdG9Db21wb3NpdGVLZXkCBQ1rX3Rva2VuX3BhcmFtBQtfYXJ0aWZhY3RJZAQLYWRqdXN0ZWRGZWUJAQRtdWxkAgUHYmFzZUZlZQUJcmVkdWN0aW9uCQCUCgIFC2FkanVzdGVkRmVlBgkAAgECGUludmFsaWQgYXR0YWNoZWQgYXJ0aWZhY3QJAJQKAgUHYmFzZUZlZQcEC2FkanVzdGVkRmVlCAUNJHQwMzUwNTkzNTU1NAJfMQQMYnVybkFydGlmYWN0CAUNJHQwMzUwNTkzNTU1NAJfMgkAlAoCBQthZGp1c3RlZEZlZQUMYnVybkFydGlmYWN0ARdpc1NhbWVBc3NldE9yTm9Qb3NpdGlvbgIHX3RyYWRlcghfYXNzZXRJZAQPb2xkUG9zaXRpb25TaXplCAkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgJfMQMJAAACBQ9vbGRQb3NpdGlvblNpemUAAAYJAAACCQEQZ2V0UG9zaXRpb25Bc3NldAEFB190cmFkZXIFCF9hc3NldElkAQtpc1NhbWVBc3NldAIHX3RyYWRlcghfYXNzZXRJZAkAAAIJARBnZXRQb3NpdGlvbkFzc2V0AQUHX3RyYWRlcgUIX2Fzc2V0SWQBHmdldEJvcnJvd2VkQnlUcmFkZXJJbk1hcmtldEtleQMEX2FtbQhfYXNzZXRJZAdfdHJhZGVyCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBSBrX3RyYWRlcl9tYXJrZXRfYXNzZXRfY29sbGF0ZXJhbAIBXwUEX2FtbQIBXwUIX2Fzc2V0SWQCAV8FB190cmFkZXIBE2dldEJvcnJvd2VkQnlUcmFkZXIBB190cmFkZXIEDXBvc2l0aW9uQXNzZXQJARBnZXRQb3NpdGlvbkFzc2V0AQUHX3RyYWRlcgMJAAACBQ1wb3NpdGlvbkFzc2V0CQDYBAEJAQpxdW90ZUFzc2V0AAkAlAoCAAAFDXBvc2l0aW9uQXNzZXQEA2tleQkBHmdldEJvcnJvd2VkQnlUcmFkZXJJbk1hcmtldEtleQMJAKUIAQUEdGhpcwUNcG9zaXRpb25Bc3NldAUHX3RyYWRlcgQGYm9ycm93CQELdmFsdWVPckVsc2UCCQCaCAIJARFjb2xsYXRlcmFsQWRkcmVzcwAFA2tleQAACQCUCgIFBmJvcnJvdwUNcG9zaXRpb25Bc3NldAEYZ2V0Rm9yVHJhZGVyV2l0aEFydGlmYWN0AgdfdHJhZGVyC19hcnRpZmFjdElkBBBkb0dldEZlZURpc2NvdW50CQD8BwQJAQxtaW5lckFkZHJlc3MAAhJjb21wdXRlRmVlRGlzY291bnQJAMwIAgUHX3RyYWRlcgUDbmlsBQNuaWwDCQAAAgUQZG9HZXRGZWVEaXNjb3VudAUQZG9HZXRGZWVEaXNjb3VudAQLZmVlRGlzY291bnQEByRtYXRjaDAFEGRvR2V0RmVlRGlzY291bnQDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4CQACAQIhSW52YWxpZCBjb21wdXRlRmVlRGlzY291bnQgcmVzdWx0BA0kdDAzNjc4NTM2ODU5CQEOZ2V0QWRqdXN0ZWRGZWUCBQtfYXJ0aWZhY3RJZAULZmVlRGlzY291bnQEC2FkanVzdGVkRmVlCAUNJHQwMzY3ODUzNjg1OQJfMQQMYnVybkFydGlmYWN0CAUNJHQwMzY3ODUzNjg1OQJfMgkAlAoCBQthZGp1c3RlZEZlZQUMYnVybkFydGlmYWN0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQ1nZXRBcnRpZmFjdElkAQFpBAphcnRpZmFjdElkAwkAZgIJAJADAQgFAWkIcGF5bWVudHMAAQkA2AQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIICQCRAwIIBQFpCHBheW1lbnRzAAEHYXNzZXRJZAISSW52YWxpZCBhcnRpZmFjdElkAgAFCmFydGlmYWN0SWQBDWRpc3RyaWJ1dGVGZWUBCl9mZWVBbW91bnQEDGZlZVRvU3Rha2VycwkBBG11bGQCBQpfZmVlQW1vdW50CQETZmVlVG9TdGFrZXJzUGVyY2VudAAECmZlZVRvVmF1bHQJAGUCBQpfZmVlQW1vdW50BQxmZWVUb1N0YWtlcnMJAJQKAgUMZmVlVG9TdGFrZXJzBQpmZWVUb1ZhdWx0AQ51cGRhdGVTZXR0aW5ncwwQX2luaXRNYXJnaW5SYXRpbwRfbW1yFF9saXF1aWRhdGlvbkZlZVJhdGlvDl9mdW5kaW5nUGVyaW9kBF9mZWUMX3NwcmVhZExpbWl0D19tYXhQcmljZUltcGFjdBhfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8PX21heFByaWNlU3ByZWFkEF9tYXhPcGVuTm90aW9uYWwUX2ZlZVRvU3Rha2Vyc1BlcmNlbnQPX21heE9yYWNsZURlbGF5CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrX2luaXRNYXJnaW5SYXRpbwUQX2luaXRNYXJnaW5SYXRpbwkAzAgCCQEMSW50ZWdlckVudHJ5AgUYa19tYWludGVuYW5jZU1hcmdpblJhdGlvBQRfbW1yCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRVrX2xpcXVpZGF0aW9uRmVlUmF0aW8FFF9saXF1aWRhdGlvbkZlZVJhdGlvCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9rX2Z1bmRpbmdQZXJpb2QFDl9mdW5kaW5nUGVyaW9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQVrX2ZlZQUEX2ZlZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUNa19zcHJlYWRMaW1pdAUMX3NwcmVhZExpbWl0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrX21heFByaWNlSW1wYWN0BQ9fbWF4UHJpY2VJbXBhY3QJAMwIAgkBDEludGVnZXJFbnRyeQIFGWtfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8FGF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwkAzAgCCQEMSW50ZWdlckVudHJ5AgUQa19tYXhQcmljZVNwcmVhZAUPX21heFByaWNlU3ByZWFkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrX21heE9wZW5Ob3Rpb25hbAUQX21heE9wZW5Ob3Rpb25hbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUVa19mZWVUb1N0YWtlcnNQZXJjZW50BRRfZmVlVG9TdGFrZXJzUGVyY2VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUQa19tYXhPcmFjbGVEZWxheQUUX2ZlZVRvU3Rha2Vyc1BlcmNlbnQFA25pbAENdXBkYXRlRnVuZGluZwURX25leHRGdW5kaW5nQmxvY2skX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uJV9sYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24QX2xvbmdGdW5kaW5nUmF0ZRFfc2hvcnRGdW5kaW5nUmF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUSa19uZXh0RnVuZGluZ0Jsb2NrBRFfbmV4dEZ1bmRpbmdCbG9jawkAzAgCCQEMSW50ZWdlckVudHJ5AgUla19sYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUkX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uCQDMCAIJAQxJbnRlZ2VyRW50cnkCBSZrX2xhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUlX2xhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkAzAgCCQEMSW50ZWdlckVudHJ5AgURa19sb25nRnVuZGluZ1JhdGUFEF9sb25nRnVuZGluZ1JhdGUJAMwIAgkBDEludGVnZXJFbnRyeQIFEmtfc2hvcnRGdW5kaW5nUmF0ZQURX3Nob3J0RnVuZGluZ1JhdGUFA25pbAETdXBkYXRlUG9zaXRpb25Bc3NldAIIX2FkZHJlc3MIX2Fzc2V0SWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUPa19wb3NpdGlvbkFzc2V0BQhfYWRkcmVzcwUIX2Fzc2V0SWQFA25pbAEfaW5jcmVtZW50UG9zaXRpb25TZXF1ZW5jZU51bWJlcgINaXNOZXdQb3NpdGlvbghfYWRkcmVzcwMFDWlzTmV3UG9zaXRpb24ED2N1cnJlbnRTZXF1ZW5jZQkBDGxhc3RTZXF1ZW5jZQAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFEmtfcG9zaXRpb25TZXF1ZW5jZQUIX2FkZHJlc3MJAGQCBQ9jdXJyZW50U2VxdWVuY2UAAQkAzAgCCQEMSW50ZWdlckVudHJ5AgUKa19zZXF1ZW5jZQkAZAIFD2N1cnJlbnRTZXF1ZW5jZQABBQNuaWwFA25pbAEOdXBkYXRlUG9zaXRpb24FCF9hZGRyZXNzBV9zaXplB19tYXJnaW4NX29wZW5Ob3Rpb25hbCBfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUOa19wb3NpdGlvblNpemUFCF9hZGRyZXNzBQVfc2l6ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUQa19wb3NpdGlvbk1hcmdpbgUIX2FkZHJlc3MFB19tYXJnaW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFFmtfcG9zaXRpb25PcGVuTm90aW9uYWwFCF9hZGRyZXNzBQ1fb3Blbk5vdGlvbmFsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBS5rX3Bvc2l0aW9uTGFzdFVwZGF0ZWRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uBQhfYWRkcmVzcwUgX2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FA25pbAEKYXBwZW5kVHdhcAEGX3ByaWNlBAhtaW51dGVJZAkAaQIJAGkCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcADoBwA8BBBwcmV2aW91c01pbnV0ZUlkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFDmtfbGFzdE1pbnV0ZUlkAAADCQBmAgUQcHJldmlvdXNNaW51dGVJZAUIbWludXRlSWQJAAIBAhFUV0FQIG91dC1vZi1vcmRlcgQMbGFzdE1pbnV0ZUlkAwkAAAIFEHByZXZpb3VzTWludXRlSWQAAAUIbWludXRlSWQFEHByZXZpb3VzTWludXRlSWQDCQBmAgUIbWludXRlSWQFEHByZXZpb3VzTWludXRlSWQEE3ByZXZDdW11bGF0aXZlUHJpY2UJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIFHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlAgFfCQCkAwEFEHByZXZpb3VzTWludXRlSWQAAAQJcHJldlByaWNlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgkArAICBRNrX3R3YXBEYXRhTGFzdFByaWNlAgFfCQCkAwEFEHByZXZpb3VzTWludXRlSWQFBl9wcmljZQQTbGFzdEN1bXVsYXRpdmVQcmljZQkAZAIFE3ByZXZDdW11bGF0aXZlUHJpY2UJAGgCCQBlAgUIbWludXRlSWQFDGxhc3RNaW51dGVJZAUJcHJldlByaWNlBARsaXN0CQELcHVzaFRvUXVldWUDCQEJc3RyVG9MaXN0AQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQ1rX2xhc3REYXRhU3RyAgAFDVRXQVBfSU5URVJWQUwJAKQDAQUIbWludXRlSWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlCQCkAwEFCG1pbnV0ZUlkBRNsYXN0Q3VtdWxhdGl2ZVByaWNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBRNrX3R3YXBEYXRhTGFzdFByaWNlCQCkAwEFCG1pbnV0ZUlkBQZfcHJpY2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFGmtfdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkCQCkAwEFCG1pbnV0ZUlkBRBwcmV2aW91c01pbnV0ZUlkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5rX2xhc3RNaW51dGVJZAUIbWludXRlSWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUNa19sYXN0RGF0YVN0cgkBCWxpc3RUb1N0cgEFBGxpc3QFA25pbAQYdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFGmtfdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkCQCkAwEFCG1pbnV0ZUlkAAAEE3ByZXZDdW11bGF0aXZlUHJpY2UJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBDnRvQ29tcG9zaXRlS2V5AgUda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UJAKQDAQUYdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkAAAECXByZXZQcmljZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEOdG9Db21wb3NpdGVLZXkCBRNrX3R3YXBEYXRhTGFzdFByaWNlCQCkAwEFGHR3YXBEYXRhUHJldmlvdXNNaW51dGVJZAUGX3ByaWNlBBNsYXN0Q3VtdWxhdGl2ZVByaWNlCQBkAgUTcHJldkN1bXVsYXRpdmVQcmljZQkAaAIJAGUCBQhtaW51dGVJZAUYdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkBQlwcmV2UHJpY2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlCQCkAwEFCG1pbnV0ZUlkBRNsYXN0Q3VtdWxhdGl2ZVByaWNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBRNrX3R3YXBEYXRhTGFzdFByaWNlCQCkAwEFCG1pbnV0ZUlkBQZfcHJpY2UFA25pbAERdXBkYXRlQW1tUmVzZXJ2ZXMCB19xdEFzdFIHX2JzQXN0UgkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa19xdW90ZUFzc2V0UmVzZXJ2ZQUHX3F0QXN0UgkAzAgCCQEMSW50ZWdlckVudHJ5AgUSa19iYXNlQXNzZXRSZXNlcnZlBQdfYnNBc3RSBQNuaWwBEHVwZGF0ZUFtbVdlaWdodHMCB19xdEFzdFcHX2JzQXN0VwkAzAgCCQEMSW50ZWdlckVudHJ5AgUSa19xdW90ZUFzc2V0V2VpZ2h0BQdfcXRBc3RXCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrX2Jhc2VBc3NldFdlaWdodAUHX2JzQXN0VwUDbmlsAQl1cGRhdGVBbW0IB19xdEFzdFIHX2JzQXN0UhdfdG90YWxQb3NpdGlvblNpemVBZnRlchVfb3BlbkludGVyZXN0Tm90aW9uYWwWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZRdfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZRZfdG90YWxMb25nT3Blbk5vdGlvbmFsF190b3RhbFNob3J0T3Blbk5vdGlvbmFsBAdfcXRBc3RXCQEGcXRBc3RXAAQHX2JzQXN0VwkBBmJzQXN0VwADCQECIT0CCQBlAgUWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQUXX3RvdGFsU2hvcnRQb3NpdGlvblNpemUFF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICGEludmFsaWQgQU1NIHN0YXRlIGRhdGE6IAkApAMBBRZfdG90YWxMb25nUG9zaXRpb25TaXplAgQgKyAgCQCkAwEFF190b3RhbFNob3J0UG9zaXRpb25TaXplAgQgIT0gCQCkAwEFF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCQDOCAIJAM4IAgkBEXVwZGF0ZUFtbVJlc2VydmVzAgUHX3F0QXN0UgUHX2JzQXN0UgkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa190b3RhbFBvc2l0aW9uU2l6ZQUXX3RvdGFsUG9zaXRpb25TaXplQWZ0ZXIJAMwIAgkBDEludGVnZXJFbnRyeQIFFmtfb3BlbkludGVyZXN0Tm90aW9uYWwFFV9vcGVuSW50ZXJlc3ROb3Rpb25hbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUXa190b3RhbExvbmdQb3NpdGlvblNpemUFFl90b3RhbExvbmdQb3NpdGlvblNpemUJAMwIAgkBDEludGVnZXJFbnRyeQIFGGtfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQUXX3RvdGFsU2hvcnRQb3NpdGlvblNpemUJAMwIAgkBDEludGVnZXJFbnRyeQIFEmtfb3BlbkludGVyZXN0TG9uZwUWX3RvdGFsTG9uZ09wZW5Ob3Rpb25hbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa19vcGVuSW50ZXJlc3RTaG9ydAUXX3RvdGFsU2hvcnRPcGVuTm90aW9uYWwFA25pbAkBCmFwcGVuZFR3YXABCQEEZGl2ZAIJAQRtdWxkAgUHX3F0QXN0UgUHX3F0QXN0VwkBBG11bGQCBQdfYnNBc3RSBQdfYnNBc3RXAQ5kZWxldGVQb3NpdGlvbgEIX2FkZHJlc3MJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBDnRvQ29tcG9zaXRlS2V5AgUOa19wb3NpdGlvblNpemUFCF9hZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ50b0NvbXBvc2l0ZUtleQIFEGtfcG9zaXRpb25NYXJnaW4FCF9hZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ50b0NvbXBvc2l0ZUtleQIFFmtfcG9zaXRpb25PcGVuTm90aW9uYWwFCF9hZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ50b0NvbXBvc2l0ZUtleQIFLmtfcG9zaXRpb25MYXN0VXBkYXRlZEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FCF9hZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ50b0NvbXBvc2l0ZUtleQIFD2tfcG9zaXRpb25Bc3NldAUIX2FkZHJlc3MFA25pbAEId2l0aGRyYXcCCF9hZGRyZXNzB19hbW91bnQEB2JhbGFuY2UJAPAHAgUEdGhpcwkBCnF1b3RlQXNzZXQAAwkAZgIFB19hbW91bnQFB2JhbGFuY2UJAAIBCQCsAgIJAKwCAgkArAICAhNVbmFibGUgdG8gd2l0aGRyYXcgCQCkAwEFB19hbW91bnQCFyBmcm9tIGNvbnRyYWN0IGJhbGFuY2UgCQCkAwEFB2JhbGFuY2UJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUIX2FkZHJlc3MFB19hbW91bnQJAQpxdW90ZUFzc2V0AAUDbmlsAQ11cGRhdGVCYWxhbmNlAQFpAwkAZgIAAAUBaQkAAgECB0JhbGFuY2UJAMwIAgkBDEludGVnZXJFbnRyeQIFCWtfYmFsYW5jZQUBaQUDbmlsAQt0cmFuc2ZlckZlZQEBaQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQEOc3Rha2luZ0FkZHJlc3MABQFpCQEKcXVvdGVBc3NldAAFA25pbAEOZG9CdXJuQXJ0aWZhY3QCDV9idXJuQXJ0aWZhY3QBaQMFDV9idXJuQXJ0aWZhY3QJAMwIAgkBBEJ1cm4CCQETdmFsdWVPckVycm9yTWVzc2FnZQIICQCRAwIIBQFpCHBheW1lbnRzAAEHYXNzZXRJZAIQSW52YWxpZCBhcnRpZmFjdAABBQNuaWwFA25pbBcBaQEFcGF1c2UAAwkBAiE9AggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAkAAgECFEludmFsaWQgcGF1c2UgcGFyYW1zCQDMCAIJAQxCb29sZWFuRW50cnkCBQhrX3BhdXNlZAYFA25pbAFpAQd1bnBhdXNlAAMJAQIhPQIIBQFpBmNhbGxlcgkBDGFkbWluQWRkcmVzcwAJAAIBAhZJbnZhbGlkIHVucGF1c2UgcGFyYW1zCQDMCAIJAQxCb29sZWFuRW50cnkCBQhrX3BhdXNlZAcFA25pbAFpAQxzZXRDbG9zZU9ubHkAAwkBAiE9AggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAkAAgECG0ludmFsaWQgc2V0Q2xvc2VPbmx5IHBhcmFtcwkAzAgCCQEMQm9vbGVhbkVudHJ5AgULa19jbG9zZU9ubHkGBQNuaWwBaQEOdW5zZXRDbG9zZU9ubHkAAwkBAiE9AggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAkAAgECHUludmFsaWQgdW5zZXRDbG9zZU9ubHkgcGFyYW1zCQDMCAIJAQxCb29sZWFuRW50cnkCBQtrX2Nsb3NlT25seQcFA25pbAFpAQxhZGRMaXF1aWRpdHkBEV9xdW90ZUFzc2V0QW1vdW50AwMJAQIhPQIIBQFpBmNhbGxlcgkBDGFkbWluQWRkcmVzcwAGCQBnAgAABRFfcXVvdGVBc3NldEFtb3VudAkAAgECG0ludmFsaWQgYWRkTGlxdWlkaXR5IHBhcmFtcwQHX3F0QXN0UgkBBnF0QXN0UgAEB19ic0FzdFIJAQZic0FzdFIABAdfcXRBc3RXCQEGcXRBc3RXAAQHX2JzQXN0VwkBBmJzQXN0VwAEBXByaWNlCQEEZGl2ZAIJAQRtdWxkAgUHX3F0QXN0UgUHX3F0QXN0VwkBBG11bGQCBQdfYnNBc3RSBQdfYnNBc3RXBAtxdEFzdFJBZnRlcgkAZAIFB19xdEFzdFIFEV9xdW90ZUFzc2V0QW1vdW50BBRiYXNlQXNzZXRBbW91bnRUb0FkZAkAZQIJAQRkaXZkAgkBBG11bGQCBQtxdEFzdFJBZnRlcgUHX3F0QXN0VwUFcHJpY2UFB19ic0FzdFIEC2JzQXN0UkFmdGVyCQBkAgUHX2JzQXN0UgUUYmFzZUFzc2V0QW1vdW50VG9BZGQEDSR0MDQ1ODgxNDYwMzIJARRnZXRTeW5jVGVybWluYWxQcmljZQMJAQ5nZXRPcmFjbGVQcmljZQAFC3F0QXN0UkFmdGVyBQtic0FzdFJBZnRlcgQTbmV3UXVvdGVBc3NldFdlaWdodAgFDSR0MDQ1ODgxNDYwMzICXzEEEm5ld0Jhc2VBc3NldFdlaWdodAgFDSR0MDQ1ODgxNDYwMzICXzIEDW1hcmdpblRvVmF1bHQIBQ0kdDA0NTg4MTQ2MDMyAl8zBA1kb0V4Y2hhbmdlUG5MAwkBAiE9AgUNbWFyZ2luVG9WYXVsdAAABA1kb0V4Y2hhbmdlUG5MCQD8BwQJAQx2YXVsdEFkZHJlc3MAAhVleGNoYW5nZUZyZWVBbmRMb2NrZWQJAMwIAgUNbWFyZ2luVG9WYXVsdAUDbmlsBQNuaWwDCQAAAgUNZG9FeGNoYW5nZVBuTAUNZG9FeGNoYW5nZVBuTAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwDCQAAAgUNZG9FeGNoYW5nZVBuTAUNZG9FeGNoYW5nZVBuTAkAzggCCQERdXBkYXRlQW1tUmVzZXJ2ZXMCBQtxdEFzdFJBZnRlcgULYnNBc3RSQWZ0ZXIJARB1cGRhdGVBbW1XZWlnaHRzAgUTbmV3UXVvdGVBc3NldFdlaWdodAUSbmV3QmFzZUFzc2V0V2VpZ2h0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBD3JlbW92ZUxpcXVpZGl0eQERX3F1b3RlQXNzZXRBbW91bnQDAwkBAiE9AggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAYJAGcCAAAFEV9xdW90ZUFzc2V0QW1vdW50CQACAQIeSW52YWxpZCByZW1vdmVMaXF1aWRpdHkgcGFyYW1zBAdfcXRBc3RSCQEGcXRBc3RSAAQHX2JzQXN0UgkBBmJzQXN0UgAEB19xdEFzdFcJAQZxdEFzdFcABAdfYnNBc3RXCQEGYnNBc3RXAAQFcHJpY2UJAQRkaXZkAgkBBG11bGQCBQdfcXRBc3RSBQdfcXRBc3RXCQEEbXVsZAIFB19ic0FzdFIFB19ic0FzdFcEF2Jhc2VBc3NldEFtb3VudFRvUmVtb3ZlCQEEZGl2ZAIFEV9xdW90ZUFzc2V0QW1vdW50BQVwcmljZQQLcXRBc3RSQWZ0ZXIJAGUCBQdfcXRBc3RSBRFfcXVvdGVBc3NldEFtb3VudAQLYnNBc3RSQWZ0ZXIJAGUCBQdfYnNBc3RSBRdiYXNlQXNzZXRBbW91bnRUb1JlbW92ZQkBEXVwZGF0ZUFtbVJlc2VydmVzAgULcXRBc3RSQWZ0ZXIFC2JzQXN0UkFmdGVyAWkBDmNoYW5nZVNldHRpbmdzDBBfaW5pdE1hcmdpblJhdGlvBF9tbXIUX2xpcXVpZGF0aW9uRmVlUmF0aW8OX2Z1bmRpbmdQZXJpb2QEX2ZlZQxfc3ByZWFkTGltaXQPX21heFByaWNlSW1wYWN0GF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbw9fbWF4UHJpY2VTcHJlYWQQX21heE9wZW5Ob3Rpb25hbBRfZmVlVG9TdGFrZXJzUGVyY2VudA9fbWF4T3JhY2xlRGVsYXkDCQECIT0CCAUBaQZjYWxsZXIJAQxhZG1pbkFkZHJlc3MACQACAQIdSW52YWxpZCBjaGFuZ2VTZXR0aW5ncyBwYXJhbXMJAQ51cGRhdGVTZXR0aW5ncwwFEF9pbml0TWFyZ2luUmF0aW8FBF9tbXIFFF9saXF1aWRhdGlvbkZlZVJhdGlvBQ5fZnVuZGluZ1BlcmlvZAUEX2ZlZQUMX3NwcmVhZExpbWl0BQ9fbWF4UHJpY2VJbXBhY3QFGF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwUPX21heFByaWNlU3ByZWFkBRBfbWF4T3Blbk5vdGlvbmFsBRRfZmVlVG9TdGFrZXJzUGVyY2VudAUPX21heE9yYWNsZURlbGF5AWkBCmluaXRpYWxpemUSB19xdEFzdFIHX2JzQXN0Ug5fZnVuZGluZ1BlcmlvZBBfaW5pdE1hcmdpblJhdGlvBF9tbXIUX2xpcXVpZGF0aW9uRmVlUmF0aW8EX2ZlZQdfb3JhY2xlCl9vcmFjbGVLZXkPX29yYWNsZUJsb2NrS2V5DF9jb29yZGluYXRvcgxfc3ByZWFkTGltaXQPX21heFByaWNlSW1wYWN0GF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbw9fbWF4UHJpY2VTcHJlYWQQX21heE9wZW5Ob3Rpb25hbBRfZmVlVG9TdGFrZXJzUGVyY2VudA9fbWF4T3JhY2xlRGVsYXkDAwMDAwMDAwMDAwMDAwMDCQBnAgAABQdfcXRBc3RSBgkAZwIAAAUHX2JzQXN0UgYJAGcCAAAFDl9mdW5kaW5nUGVyaW9kBgkAZwIAAAUQX2luaXRNYXJnaW5SYXRpbwYJAGcCAAAFBF9tbXIGCQBnAgAABRRfbGlxdWlkYXRpb25GZWVSYXRpbwYJAGcCAAAFBF9mZWUGCQBnAgAABQxfc3ByZWFkTGltaXQGCQBnAgAABQ9fbWF4UHJpY2VJbXBhY3QGCQBnAgAABRhfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8GCQBnAgAABQ9fbWF4UHJpY2VTcHJlYWQGCQBnAgAABRBfbWF4T3Blbk5vdGlvbmFsBgkAZwIAAAUUX2ZlZVRvU3Rha2Vyc1BlcmNlbnQGCQBmAgUUX2ZlZVRvU3Rha2Vyc1BlcmNlbnQFDERFQ0lNQUxfVU5JVAYJAGcCAAAFD19tYXhPcmFjbGVEZWxheQYJAQtpbml0aWFsaXplZAAJAAIBAh1JbnZhbGlkIGluaXRpYWxpemUgcGFyYW1ldGVycwkAzggCCQDOCAIJAM4IAgkAzggCCQEJdXBkYXRlQW1tCAUHX3F0QXN0UgUHX2JzQXN0UgAAAAAAAAAAAAAAAAkBDnVwZGF0ZVNldHRpbmdzDAUQX2luaXRNYXJnaW5SYXRpbwUEX21tcgUUX2xpcXVpZGF0aW9uRmVlUmF0aW8FDl9mdW5kaW5nUGVyaW9kBQRfZmVlBQxfc3ByZWFkTGltaXQFD19tYXhQcmljZUltcGFjdAUYX3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvBQ9fbWF4UHJpY2VTcHJlYWQFEF9tYXhPcGVuTm90aW9uYWwFFF9mZWVUb1N0YWtlcnNQZXJjZW50BQ9fbWF4T3JhY2xlRGVsYXkJAQ11cGRhdGVGdW5kaW5nBQkAZAIIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQ5fZnVuZGluZ1BlcmlvZAAAAAAAAAAACQENdXBkYXRlQmFsYW5jZQEAAAkAzAgCCQEMQm9vbGVhbkVudHJ5AgUNa19pbml0aWFsaXplZAYJAMwIAgkBC1N0cmluZ0VudHJ5AgUFa19vcmEFB19vcmFjbGUJAMwIAgkBC1N0cmluZ0VudHJ5AgUJa19vcmFfa2V5BQpfb3JhY2xlS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIFD2tfb3JhX2Jsb2NrX2tleQUPX29yYWNsZUJsb2NrS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIFFGtfY29vcmRpbmF0b3JBZGRyZXNzBQxfY29vcmRpbmF0b3IFA25pbAFpARBkZWNyZWFzZVBvc2l0aW9uAwdfYW1vdW50CV9sZXZlcmFnZRNfbWluQmFzZUFzc2V0QW1vdW50BARzeW5jCQD8BwQFBHRoaXMCGXN5bmNUZXJtaW5hbFByaWNlVG9PcmFjbGUFA25pbAUDbmlsAwkAAAIFBHN5bmMFBHN5bmMEB190cmFkZXIJAQ9nZXRBY3R1YWxDYWxsZXIBBQFpAwMDAwMDCQBnAgAABQdfYW1vdW50BgkBASEBCQELaW5pdGlhbGl6ZWQABgkBASEBCQEWcmVxdWlyZU1vcmVNYXJnaW5SYXRpbwMJAQRkaXZkAgUMREVDSU1BTF9VTklUBQlfbGV2ZXJhZ2UJAQ9pbml0TWFyZ2luUmF0aW8ABgYJAQEhAQkBE3JlcXVpcmVPcGVuUG9zaXRpb24BBQdfdHJhZGVyBgkBBnBhdXNlZAAGCQEOaXNNYXJrZXRDbG9zZWQACQACAQIjSW52YWxpZCBkZWNyZWFzZVBvc2l0aW9uIHBhcmFtZXRlcnMEDSR0MDQ5ODk5NTAwMzkJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIED29sZFBvc2l0aW9uU2l6ZQgFDSR0MDQ5ODk5NTAwMzkCXzEEEW9sZFBvc2l0aW9uTWFyZ2luCAUNJHQwNDk4OTk1MDAzOQJfMgQXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDA0OTg5OTUwMDM5Al8zBBRvbGRQb3NpdGlvbkxzdFVwZENQRggFDSR0MDQ5ODk5NTAwMzkCXzQECl9kaXJlY3Rpb24DCQBmAgUPb2xkUG9zaXRpb25TaXplAAAFCURJUl9TSE9SVAUIRElSX0xPTkcEBWlzQWRkCQAAAgUKX2RpcmVjdGlvbgUIRElSX0xPTkcEDG9wZW5Ob3Rpb25hbAkBBG11bGQCBQdfYW1vdW50BQlfbGV2ZXJhZ2UEDSR0MDUwMjEyNTAzMTYJASNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAIFB190cmFkZXIFD1BOTF9PUFRJT05fU1BPVAQTb2xkUG9zaXRpb25Ob3Rpb25hbAgFDSR0MDUwMjEyNTAzMTYCXzEEDXVucmVhbGl6ZWRQbmwIBQ0kdDA1MDIxMjUwMzE2Al8yBA0kdDA1MDMyMjUyOTY0AwkAZgIFE29sZFBvc2l0aW9uTm90aW9uYWwFDG9wZW5Ob3Rpb25hbAQNJHQwNTA3Mzc1MDkyMQkBCXN3YXBJbnB1dAIFBWlzQWRkBQxvcGVuTm90aW9uYWwEFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQgFDSR0MDUwNzM3NTA5MjECXzEEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1MDczNzUwOTIxAl8yBBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1MDczNzUwOTIxAl8zBBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNTA3Mzc1MDkyMQJfNAQYZXhjaGFuZ2VkUG9zaXRpb25TaXplQWJzCQEDYWJzAQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplAwMJAQIhPQIFE19taW5CYXNlQXNzZXRBbW91bnQAAAkAZgIFE19taW5CYXNlQXNzZXRBbW91bnQFGGV4Y2hhbmdlZFBvc2l0aW9uU2l6ZUFicwcJAAIBCQCsAgIJAKwCAgkArAICAiVUb28gbGl0dGxlIGJhc2UgYXNzZXQgZXhjaGFuZ2VkLCBnb3QgCQCkAwEFGGV4Y2hhbmdlZFBvc2l0aW9uU2l6ZUFicwIKIGV4cGVjdGVkIAkApAMBBRNfbWluQmFzZUFzc2V0QW1vdW50BAtyZWFsaXplZFBubAkBBGRpdmQCCQEEbXVsZAIFDXVucmVhbGl6ZWRQbmwFGGV4Y2hhbmdlZFBvc2l0aW9uU2l6ZUFicwkBA2FicwEFD29sZFBvc2l0aW9uU2l6ZQQNJHQwNTEzNTg1MTU4NwkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQ9vbGRQb3NpdGlvblNpemUFEW9sZFBvc2l0aW9uTWFyZ2luBRRvbGRQb3NpdGlvbkxzdFVwZENQRgULcmVhbGl6ZWRQbmwEDHJlbWFpbk1hcmdpbggFDSR0MDUxMzU4NTE1ODcCXzEEB2JhZERlYnQIBQ0kdDA1MTM1ODUxNTg3Al8yBBlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50BQxvcGVuTm90aW9uYWwEEnVucmVhbGl6ZWRQbmxBZnRlcgkAZQIFDXVucmVhbGl6ZWRQbmwFC3JlYWxpemVkUG5sBBJyZW1haW5PcGVuTm90aW9uYWwDCQBmAgUPb2xkUG9zaXRpb25TaXplAAAJAGUCCQBlAgUTb2xkUG9zaXRpb25Ob3Rpb25hbAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAUSdW5yZWFsaXplZFBubEFmdGVyCQBlAgkAZAIFEnVucmVhbGl6ZWRQbmxBZnRlcgUTb2xkUG9zaXRpb25Ob3Rpb25hbAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAQPbmV3UG9zaXRpb25TaXplCQBkAgUPb2xkUG9zaXRpb25TaXplBRVleGNoYW5nZWRQb3NpdGlvblNpemUJAJ4KDAUPbmV3UG9zaXRpb25TaXplBQxyZW1haW5NYXJnaW4JAQNhYnMBBRJyZW1haW5PcGVuTm90aW9uYWwJAR9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQUPbmV3UG9zaXRpb25TaXplBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIJAGUCCQEUb3BlbkludGVyZXN0Tm90aW9uYWwABQxvcGVuTm90aW9uYWwJAGUCCQEVdG90YWxMb25nUG9zaXRpb25TaXplAAMJAGYCBQ9uZXdQb3NpdGlvblNpemUAAAkBA2FicwEFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQAACQBlAgkBFnRvdGFsU2hvcnRQb3NpdGlvblNpemUAAwkAZgIAAAUPbmV3UG9zaXRpb25TaXplCQEDYWJzAQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplAAAJAGUCCQEQb3BlbkludGVyZXN0TG9uZwADCQBmAgUPbmV3UG9zaXRpb25TaXplAAAFDG9wZW5Ob3Rpb25hbAAACQBlAgkBEW9wZW5JbnRlcmVzdFNob3J0AAMJAGYCAAAFD25ld1Bvc2l0aW9uU2l6ZQUMb3Blbk5vdGlvbmFsAAAJAAIBAhRDbG9zZSBwb3NpdGlvbiBmaXJzdAQPbmV3UG9zaXRpb25TaXplCAUNJHQwNTAzMjI1Mjk2NAJfMQQXbmV3UG9zaXRpb25SZW1haW5NYXJnaW4IBQ0kdDA1MDMyMjUyOTY0Al8yBBduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDUwMzIyNTI5NjQCXzMEFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCAUNJHQwNTAzMjI1Mjk2NAJfNAQVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwNTAzMjI1Mjk2NAJfNQQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDUwMzIyNTI5NjQCXzYEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDA1MDMyMjUyOTY0Al83BBlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCAUNJHQwNTAzMjI1Mjk2NAJfOAQOdG90YWxMb25nQWZ0ZXIIBQ0kdDA1MDMyMjUyOTY0Al85BA90b3RhbFNob3J0QWZ0ZXIIBQ0kdDA1MDMyMjUyOTY0A18xMAQadG90YWxMb25nT3BlbkludGVyZXN0QWZ0ZXIIBQ0kdDA1MDMyMjUyOTY0A18xMQQbdG90YWxTaG9ydE9wZW5JbnRlcmVzdEFmdGVyCAUNJHQwNTAzMjI1Mjk2NANfMTIEDm5vdGlmeU5vdGlvbmFsCQD8BwQJAQxtaW5lckFkZHJlc3MAAg5ub3RpZnlOb3Rpb25hbAkAzAgCBQdfdHJhZGVyCQDMCAIFF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsBQNuaWwFA25pbAMJAAACBQ5ub3RpZnlOb3Rpb25hbAUObm90aWZ5Tm90aW9uYWwJAM4IAgkBDnVwZGF0ZVBvc2l0aW9uBQUHX3RyYWRlcgUPbmV3UG9zaXRpb25TaXplBRduZXdQb3NpdGlvblJlbWFpbk1hcmdpbgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCQEJdXBkYXRlQW1tCAUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBRZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBRlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyBQ50b3RhbExvbmdBZnRlcgUPdG90YWxTaG9ydEFmdGVyBRp0b3RhbExvbmdPcGVuSW50ZXJlc3RBZnRlcgUbdG90YWxTaG9ydE9wZW5JbnRlcmVzdEFmdGVyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEGluY3JlYXNlUG9zaXRpb24ECl9kaXJlY3Rpb24JX2xldmVyYWdlE19taW5CYXNlQXNzZXRBbW91bnQIX3JlZkxpbmsEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQHX3RyYWRlcgkBD2dldEFjdHVhbENhbGxlcgEFAWkECl9yYXdBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAhfYXNzZXRJZAgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBAtfYXNzZXRJZFN0cgkA2AQBCQEFdmFsdWUBBQhfYXNzZXRJZAQMaXNRdW90ZUFzc2V0CQAAAgUIX2Fzc2V0SWQJAQpxdW90ZUFzc2V0AAQRaXNDb2xsYXRlcmFsQXNzZXQJARBpc1doaXRlbGlzdEFzc2V0AQULX2Fzc2V0SWRTdHIDAwMDAwMDAwMDCQECIT0CBQpfZGlyZWN0aW9uBQhESVJfTE9ORwkBAiE9AgUKX2RpcmVjdGlvbgUJRElSX1NIT1JUBwYJAGcCAAAFCl9yYXdBbW91bnQGCQEBIQEJAQtpbml0aWFsaXplZAAGAwkBASEBBQxpc1F1b3RlQXNzZXQJAQEhAQURaXNDb2xsYXRlcmFsQXNzZXQHBgkBASEBCQEXaXNTYW1lQXNzZXRPck5vUG9zaXRpb24CBQdfdHJhZGVyBQtfYXNzZXRJZFN0cgYJAQEhAQkBFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8DCQEEZGl2ZAIFDERFQ0lNQUxfVU5JVAUJX2xldmVyYWdlCQEPaW5pdE1hcmdpblJhdGlvAAYGCQEGcGF1c2VkAAYJAQljbG9zZU9ubHkABgkBDmlzTWFya2V0Q2xvc2VkAAkAAgECI0ludmFsaWQgaW5jcmVhc2VQb3NpdGlvbiBwYXJhbWV0ZXJzBA0kdDA1NDQyNjU0NTExCQEYZ2V0Rm9yVHJhZGVyV2l0aEFydGlmYWN0AgUHX3RyYWRlcgkBDWdldEFydGlmYWN0SWQBBQFpBAthZGp1c3RlZEZlZQgFDSR0MDU0NDI2NTQ1MTECXzEEDGJ1cm5BcnRpZmFjdAgFDSR0MDU0NDI2NTQ1MTECXzIEDHJhd0ZlZUFtb3VudAkBBG11bGQCBQpfcmF3QW1vdW50BQthZGp1c3RlZEZlZQQHX2Ftb3VudAkAZQIFCl9yYXdBbW91bnQFDHJhd0ZlZUFtb3VudAQTZGlzdHJpYnV0ZUZlZUFtb3VudAMFEWlzQ29sbGF0ZXJhbEFzc2V0BAhkb0JvcnJvdwkA/AcECQERY29sbGF0ZXJhbEFkZHJlc3MAAgZib3Jyb3cJAMwIAgUHX3RyYWRlcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQhfYXNzZXRJZAUHX2Ftb3VudAUDbmlsAwkAAAIFCGRvQm9ycm93BQhkb0JvcnJvdwQNYmFsYW5jZUJlZm9yZQkA8AcCBQR0aGlzCQEKcXVvdGVBc3NldAADCQAAAgUNYmFsYW5jZUJlZm9yZQUNYmFsYW5jZUJlZm9yZQQGZG9Td2FwCQD8BwQJAQtzd2FwQWRkcmVzcwACBHN3YXAJAMwIAgkA2AQBCQEKcXVvdGVBc3NldAAJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCF9hc3NldElkBQxyYXdGZWVBbW91bnQFA25pbAMJAAACBQZkb1N3YXAFBmRvU3dhcAQMYmFsYW5jZUFmdGVyCQDwBwIFBHRoaXMJAQpxdW90ZUFzc2V0AAMJAAACBQxiYWxhbmNlQWZ0ZXIFDGJhbGFuY2VBZnRlcgQPZXhjaGFuZ2VkQW1vdW50CQBlAgUMYmFsYW5jZUFmdGVyBQ1iYWxhbmNlQmVmb3JlAwkAAAIFD2V4Y2hhbmdlZEFtb3VudAUPZXhjaGFuZ2VkQW1vdW50BQ9leGNoYW5nZWRBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FDHJhd0ZlZUFtb3VudAMJAAACBRNkaXN0cmlidXRlRmVlQW1vdW50BRNkaXN0cmlidXRlRmVlQW1vdW50BA5yZWZlcnJlckZlZUFueQkA/AcECQEPcmVmZXJyYWxBZGRyZXNzAAIVYWNjZXB0UGF5bWVudFdpdGhMaW5rCQDMCAIFB190cmFkZXIJAMwIAgUIX3JlZkxpbmsFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABRNkaXN0cmlidXRlRmVlQW1vdW50BQNuaWwDCQAAAgUOcmVmZXJyZXJGZWVBbnkFDnJlZmVycmVyRmVlQW55BAtyZWZlcnJlckZlZQQHJG1hdGNoMAUOcmVmZXJyZXJGZWVBbnkDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4CQACAQITSW52YWxpZCByZWZlcnJlckZlZQQJZmVlQW1vdW50CQBlAgUTZGlzdHJpYnV0ZUZlZUFtb3VudAULcmVmZXJyZXJGZWUEDSR0MDU1ODI3NTU5NjcJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIED29sZFBvc2l0aW9uU2l6ZQgFDSR0MDU1ODI3NTU5NjcCXzEEEW9sZFBvc2l0aW9uTWFyZ2luCAUNJHQwNTU4Mjc1NTk2NwJfMgQXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDA1NTgyNzU1OTY3Al8zBBRvbGRQb3NpdGlvbkxzdFVwZENQRggFDSR0MDU1ODI3NTU5NjcCXzQEDWlzTmV3UG9zaXRpb24JAAACBQ9vbGRQb3NpdGlvblNpemUAAAQPaXNTYW1lRGlyZWN0aW9uAwkAZgIFD29sZFBvc2l0aW9uU2l6ZQAACQAAAgUKX2RpcmVjdGlvbgUIRElSX0xPTkcJAAACBQpfZGlyZWN0aW9uBQlESVJfU0hPUlQEDmV4cGFuZEV4aXN0aW5nAwkBASEBBQ1pc05ld1Bvc2l0aW9uBQ9pc1NhbWVEaXJlY3Rpb24HBAVpc0FkZAkAAAIFCl9kaXJlY3Rpb24FCERJUl9MT05HBA0kdDA1NjI1NjU5Mjk3AwMFDWlzTmV3UG9zaXRpb24GBQ5leHBhbmRFeGlzdGluZwQMb3Blbk5vdGlvbmFsCQEEbXVsZAIFB19hbW91bnQFCV9sZXZlcmFnZQQNJHQwNTY3MTg1Njg5MQkBCXN3YXBJbnB1dAIFBWlzQWRkBQxvcGVuTm90aW9uYWwEFWFtb3VudEJhc2VBc3NldEJvdWdodAgFDSR0MDU2NzE4NTY4OTECXzEEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1NjcxODU2ODkxAl8yBBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1NjcxODU2ODkxAl8zBBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNTY3MTg1Njg5MQJfNAMDCQECIT0CBRNfbWluQmFzZUFzc2V0QW1vdW50AAAJAGYCBRNfbWluQmFzZUFzc2V0QW1vdW50CQEDYWJzAQUVYW1vdW50QmFzZUFzc2V0Qm91Z2h0BwkAAgEJAKwCAgkArAICCQCsAgICDUxpbWl0IGVycm9yOiAJAKQDAQkBA2FicwEFFWFtb3VudEJhc2VBc3NldEJvdWdodAIDIDwgCQCkAwEFE19taW5CYXNlQXNzZXRBbW91bnQED25ld1Bvc2l0aW9uU2l6ZQkAZAIFD29sZFBvc2l0aW9uU2l6ZQUVYW1vdW50QmFzZUFzc2V0Qm91Z2h0BBp0b3RhbExvbmdPcGVuSW50ZXJlc3RBZnRlcgkAZAIJARBvcGVuSW50ZXJlc3RMb25nAAMJAGYCBQ9uZXdQb3NpdGlvblNpemUAAAUMb3Blbk5vdGlvbmFsAAAEG3RvdGFsU2hvcnRPcGVuSW50ZXJlc3RBZnRlcgkAZAIJARFvcGVuSW50ZXJlc3RTaG9ydAADCQBmAgAABQ9uZXdQb3NpdGlvblNpemUFDG9wZW5Ob3Rpb25hbAAABBlpbmNyZWFzZU1hcmdpblJlcXVpcmVtZW50CQEEZGl2ZAIFDG9wZW5Ob3Rpb25hbAUJX2xldmVyYWdlBA0kdDA1NzQ5OTU3NzM4CQEiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAQFD29sZFBvc2l0aW9uU2l6ZQURb2xkUG9zaXRpb25NYXJnaW4FFG9sZFBvc2l0aW9uTHN0VXBkQ1BGBRlpbmNyZWFzZU1hcmdpblJlcXVpcmVtZW50BAxyZW1haW5NYXJnaW4IBQ0kdDA1NzQ5OTU3NzM4Al8xBAJ4MQgFDSR0MDU3NDk5NTc3MzgCXzIEAngyCAUNJHQwNTc0OTk1NzczOAJfMwMJAQEhAQkBGXJlcXVpcmVOb3RPdmVyU3ByZWFkTGltaXQCBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIJAAIBAhVPdmVyIG1heCBzcHJlYWQgbGltaXQDCQEBIQEJAR1yZXF1aXJlTm90T3Zlck1heE9wZW5Ob3Rpb25hbAIFGnRvdGFsTG9uZ09wZW5JbnRlcmVzdEFmdGVyBRt0b3RhbFNob3J0T3BlbkludGVyZXN0QWZ0ZXIJAAIBAhZPdmVyIG1heCBvcGVuIG5vdGlvbmFsCQCeCgwFD25ld1Bvc2l0aW9uU2l6ZQUMcmVtYWluTWFyZ2luCQBkAgUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwFDG9wZW5Ob3Rpb25hbAkBH2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24BBQ9uZXdQb3NpdGlvblNpemUFFWJhc2VBc3NldFJlc2VydmVBZnRlcgUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUWdG90YWxQb3NpdGlvblNpemVBZnRlcgkAZAIJARRvcGVuSW50ZXJlc3ROb3Rpb25hbAAFDG9wZW5Ob3Rpb25hbAkAZAIJARV0b3RhbExvbmdQb3NpdGlvblNpemUAAwkAZgIFD25ld1Bvc2l0aW9uU2l6ZQAACQEDYWJzAQUVYW1vdW50QmFzZUFzc2V0Qm91Z2h0AAAJAGQCCQEWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQADCQBmAgAABQ9uZXdQb3NpdGlvblNpemUJAQNhYnMBBRVhbW91bnRCYXNlQXNzZXRCb3VnaHQAAAUadG90YWxMb25nT3BlbkludGVyZXN0QWZ0ZXIFG3RvdGFsU2hvcnRPcGVuSW50ZXJlc3RBZnRlcgQMb3Blbk5vdGlvbmFsCQEEbXVsZAIFB19hbW91bnQFCV9sZXZlcmFnZQQNJHQwNTg5OTc1OTExMwkBI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAgkApQgBCAUBaQZjYWxsZXIFD1BOTF9PUFRJT05fU1BPVAQTb2xkUG9zaXRpb25Ob3Rpb25hbAgFDSR0MDU4OTk3NTkxMTMCXzEEDXVucmVhbGl6ZWRQbmwIBQ0kdDA1ODk5NzU5MTEzAl8yAwkAZgIFE29sZFBvc2l0aW9uTm90aW9uYWwFDG9wZW5Ob3Rpb25hbAkAAgECLlVzZSBkZWNyZWFzZVBvc2l0aW9uIHRvIGRlY3JlYXNlIHBvc2l0aW9uIHNpemUJAAIBAhRDbG9zZSBwb3NpdGlvbiBmaXJzdAQPbmV3UG9zaXRpb25TaXplCAUNJHQwNTYyNTY1OTI5NwJfMQQXbmV3UG9zaXRpb25SZW1haW5NYXJnaW4IBQ0kdDA1NjI1NjU5Mjk3Al8yBBduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDU2MjU2NTkyOTcCXzMEFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCAUNJHQwNTYyNTY1OTI5NwJfNAQVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwNTYyNTY1OTI5NwJfNQQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDU2MjU2NTkyOTcCXzYEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDA1NjI1NjU5Mjk3Al83BBlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCAUNJHQwNTYyNTY1OTI5NwJfOAQOdG90YWxMb25nQWZ0ZXIIBQ0kdDA1NjI1NjU5Mjk3Al85BA90b3RhbFNob3J0QWZ0ZXIIBQ0kdDA1NjI1NjU5Mjk3A18xMAQadG90YWxMb25nT3BlbkludGVyZXN0QWZ0ZXIIBQ0kdDA1NjI1NjU5Mjk3A18xMQQbdG90YWxTaG9ydE9wZW5JbnRlcmVzdEFmdGVyCAUNJHQwNTYyNTY1OTI5NwNfMTIEDSR0MDU5MzAzNTkzNjAJAQ1kaXN0cmlidXRlRmVlAQUJZmVlQW1vdW50BAxmZWVUb1N0YWtlcnMIBQ0kdDA1OTMwMzU5MzYwAl8xBApmZWVUb1ZhdWx0CAUNJHQwNTkzMDM1OTM2MAJfMgQFc3Rha2UDBQxpc1F1b3RlQXNzZXQEBXN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAglhZGRMb2NrZWQJAMwIAgcFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQdfYW1vdW50BQNuaWwDCQAAAgUFc3Rha2UFBXN0YWtlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBQVzdGFrZQUFc3Rha2UEEGRlcG9zaXRJbnN1cmFuY2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACB2FkZEZyZWUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQpmZWVUb1ZhdWx0BQNuaWwDCQAAAgUQZGVwb3NpdEluc3VyYW5jZQUQZGVwb3NpdEluc3VyYW5jZQQJbm90aWZ5RmVlCQD8BwQJAQxtaW5lckFkZHJlc3MAAgpub3RpZnlGZWVzCQDMCAIFB190cmFkZXIJAMwIAgUJZmVlQW1vdW50BQNuaWwFA25pbAMJAAACBQlub3RpZnlGZWUFCW5vdGlmeUZlZQQObm90aWZ5Tm90aW9uYWwJAPwHBAkBDG1pbmVyQWRkcmVzcwACDm5vdGlmeU5vdGlvbmFsCQDMCAIFB190cmFkZXIJAMwIAgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFA25pbAUDbmlsAwkAAAIFDm5vdGlmeU5vdGlvbmFsBQ5ub3RpZnlOb3Rpb25hbAkAzggCCQDOCAIJAM4IAgkAzggCCQDOCAIJAM4IAgkBDnVwZGF0ZVBvc2l0aW9uBQUHX3RyYWRlcgUPbmV3UG9zaXRpb25TaXplBRduZXdQb3NpdGlvblJlbWFpbk1hcmdpbgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCQEfaW5jcmVtZW50UG9zaXRpb25TZXF1ZW5jZU51bWJlcgIFDWlzTmV3UG9zaXRpb24FB190cmFkZXIJARN1cGRhdGVQb3NpdGlvbkFzc2V0AgUHX3RyYWRlcgULX2Fzc2V0SWRTdHIJAQl1cGRhdGVBbW0IBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIFDnRvdGFsTG9uZ0FmdGVyBQ90b3RhbFNob3J0QWZ0ZXIFGnRvdGFsTG9uZ09wZW5JbnRlcmVzdEFmdGVyBRt0b3RhbFNob3J0T3BlbkludGVyZXN0QWZ0ZXIJAQt0cmFuc2ZlckZlZQEFDGZlZVRvU3Rha2VycwkBDXVwZGF0ZUJhbGFuY2UBCQBkAgkBCGNiYWxhbmNlAAUHX2Ftb3VudAkBDmRvQnVybkFydGlmYWN0AgUMYnVybkFydGlmYWN0BQFpCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCWFkZE1hcmdpbgAEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQHX3RyYWRlcgkApQgBCAUBaQZjYWxsZXIECl9yYXdBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAhfYXNzZXRJZAgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBAtfYXNzZXRJZFN0cgkA2AQBCQEFdmFsdWUBBQhfYXNzZXRJZAQMaXNRdW90ZUFzc2V0CQAAAgUIX2Fzc2V0SWQJAQpxdW90ZUFzc2V0AAQRaXNDb2xsYXRlcmFsQXNzZXQJARBpc1doaXRlbGlzdEFzc2V0AQULX2Fzc2V0SWRTdHIDAwMDAwMDAwkBASEBBQxpc1F1b3RlQXNzZXQJAQEhAQURaXNDb2xsYXRlcmFsQXNzZXQHBgkBASEBCQETcmVxdWlyZU9wZW5Qb3NpdGlvbgEJAKUIAQgFAWkGY2FsbGVyBgkBASEBCQELaXNTYW1lQXNzZXQCBQdfdHJhZGVyBQtfYXNzZXRJZFN0cgYJAQEhAQkBC2luaXRpYWxpemVkAAYJAQZwYXVzZWQABgkBCWNsb3NlT25seQAGCQEOaXNNYXJrZXRDbG9zZWQACQACAQIcSW52YWxpZCBhZGRNYXJnaW4gcGFyYW1ldGVycwQNJHQwNjEzMzI2MTQxNwkBGGdldEZvclRyYWRlcldpdGhBcnRpZmFjdAIFB190cmFkZXIJAQ1nZXRBcnRpZmFjdElkAQUBaQQLYWRqdXN0ZWRGZWUIBQ0kdDA2MTMzMjYxNDE3Al8xBAxidXJuQXJ0aWZhY3QIBQ0kdDA2MTMzMjYxNDE3Al8yBAxyYXdGZWVBbW91bnQJAQRtdWxkAgUKX3Jhd0Ftb3VudAULYWRqdXN0ZWRGZWUEB19hbW91bnQJAGUCBQpfcmF3QW1vdW50BQxyYXdGZWVBbW91bnQEE2Rpc3RyaWJ1dGVGZWVBbW91bnQDBRFpc0NvbGxhdGVyYWxBc3NldAQIZG9Cb3Jyb3cJAPwHBAkBEWNvbGxhdGVyYWxBZGRyZXNzAAIGYm9ycm93CQDMCAIFB190cmFkZXIFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUIX2Fzc2V0SWQFB19hbW91bnQFA25pbAMJAAACBQhkb0JvcnJvdwUIZG9Cb3Jyb3cEDWJhbGFuY2VCZWZvcmUJAPAHAgUEdGhpcwkBCnF1b3RlQXNzZXQAAwkAAAIFDWJhbGFuY2VCZWZvcmUFDWJhbGFuY2VCZWZvcmUEBmRvU3dhcAkA/AcECQELc3dhcEFkZHJlc3MAAgRzd2FwCQDMCAIJANgEAQkBCnF1b3RlQXNzZXQACQDMCAIAAAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQhfYXNzZXRJZAUMcmF3RmVlQW1vdW50BQNuaWwDCQAAAgUGZG9Td2FwBQZkb1N3YXAEDGJhbGFuY2VBZnRlcgkA8AcCBQR0aGlzCQEKcXVvdGVBc3NldAADCQAAAgUMYmFsYW5jZUFmdGVyBQxiYWxhbmNlQWZ0ZXIED2V4Y2hhbmdlZEFtb3VudAkAZQIFDGJhbGFuY2VBZnRlcgUNYmFsYW5jZUJlZm9yZQMJAAACBQ9leGNoYW5nZWRBbW91bnQFD2V4Y2hhbmdlZEFtb3VudAUPZXhjaGFuZ2VkQW1vdW50CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQxyYXdGZWVBbW91bnQDCQAAAgUTZGlzdHJpYnV0ZUZlZUFtb3VudAUTZGlzdHJpYnV0ZUZlZUFtb3VudAQOcmVmZXJyZXJGZWVBbnkJAPwHBAkBD3JlZmVycmFsQWRkcmVzcwACDWFjY2VwdFBheW1lbnQJAMwIAgUHX3RyYWRlcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFE2Rpc3RyaWJ1dGVGZWVBbW91bnQFA25pbAMJAAACBQ5yZWZlcnJlckZlZUFueQUOcmVmZXJyZXJGZWVBbnkEC3JlZmVycmVyRmVlBAckbWF0Y2gwBQ5yZWZlcnJlckZlZUFueQMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAhNJbnZhbGlkIHJlZmVycmVyRmVlBAlmZWVBbW91bnQJAGUCBRNkaXN0cmlidXRlRmVlQW1vdW50BQtyZWZlcnJlckZlZQQNJHQwNjI3MTY2Mjg1NgkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgQPb2xkUG9zaXRpb25TaXplCAUNJHQwNjI3MTY2Mjg1NgJfMQQRb2xkUG9zaXRpb25NYXJnaW4IBQ0kdDA2MjcxNjYyODU2Al8yBBdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDYyNzE2NjI4NTYCXzMEFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwNjI3MTY2Mjg1NgJfNAQNJHQwNjI4NjI2MjkxOQkBDWRpc3RyaWJ1dGVGZWUBBQlmZWVBbW91bnQEDGZlZVRvU3Rha2VycwgFDSR0MDYyODYyNjI5MTkCXzEECmZlZVRvVmF1bHQIBQ0kdDA2Mjg2MjYyOTE5Al8yBAVzdGFrZQMFDGlzUXVvdGVBc3NldAQFc3Rha2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACCWFkZExvY2tlZAkAzAgCBwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFB19hbW91bnQFA25pbAMJAAACBQVzdGFrZQUFc3Rha2UFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAwkAAAIFBXN0YWtlBQVzdGFrZQQQZGVwb3NpdEluc3VyYW5jZQkA/AcECQEMdmF1bHRBZGRyZXNzAAIHYWRkRnJlZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFCmZlZVRvVmF1bHQFA25pbAMJAAACBRBkZXBvc2l0SW5zdXJhbmNlBRBkZXBvc2l0SW5zdXJhbmNlBAlub3RpZnlGZWUJAPwHBAkBDG1pbmVyQWRkcmVzcwACCm5vdGlmeUZlZXMJAMwIAgUHX3RyYWRlcgkAzAgCBQlmZWVBbW91bnQFA25pbAUDbmlsAwkAAAIFCW5vdGlmeUZlZQUJbm90aWZ5RmVlCQDOCAIJAM4IAgkAzggCCQEOdXBkYXRlUG9zaXRpb24FBQdfdHJhZGVyBQ9vbGRQb3NpdGlvblNpemUJAGQCBRFvbGRQb3NpdGlvbk1hcmdpbgUHX2Ftb3VudAUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwFFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCQELdHJhbnNmZXJGZWUBBQxmZWVUb1N0YWtlcnMJAQ11cGRhdGVCYWxhbmNlAQkAZAIJAQhjYmFsYW5jZQAFB19hbW91bnQJAQ5kb0J1cm5BcnRpZmFjdAIFDGJ1cm5BcnRpZmFjdAUBaQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQxyZW1vdmVNYXJnaW4BB19hbW91bnQEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQHX3RyYWRlcgkApQgBCAUBaQZjYWxsZXIDAwMDAwkAZwIAAAUHX2Ftb3VudAYJAQEhAQkBE3JlcXVpcmVPcGVuUG9zaXRpb24BBQdfdHJhZGVyBgkBASEBCQELaW5pdGlhbGl6ZWQABgkBBnBhdXNlZAAGCQEOaXNNYXJrZXRDbG9zZWQACQACAQIfSW52YWxpZCByZW1vdmVNYXJnaW4gcGFyYW1ldGVycwQNJHQwNjQwNTU2NDE5NQkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgQPb2xkUG9zaXRpb25TaXplCAUNJHQwNjQwNTU2NDE5NQJfMQQRb2xkUG9zaXRpb25NYXJnaW4IBQ0kdDA2NDA1NTY0MTk1Al8yBBdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDY0MDU1NjQxOTUCXzMEFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwNjQwNTU2NDE5NQJfNAQLbWFyZ2luRGVsdGEJAQEtAQUHX2Ftb3VudAQNJHQwNjQyMzI2NDQxMQkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQ9vbGRQb3NpdGlvblNpemUFEW9sZFBvc2l0aW9uTWFyZ2luBRRvbGRQb3NpdGlvbkxzdFVwZENQRgULbWFyZ2luRGVsdGEEDHJlbWFpbk1hcmdpbggFDSR0MDY0MjMyNjQ0MTECXzEEB2JhZERlYnQIBQ0kdDA2NDIzMjY0NDExAl8yAwkBAiE9AgUHYmFkRGVidAAACQACAQIdSW52YWxpZCByZW1vdmVkIG1hcmdpbiBhbW91bnQEC21hcmdpblJhdGlvCQEPY2FsY01hcmdpblJhdGlvAwUMcmVtYWluTWFyZ2luBQdiYWREZWJ0BRdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAMJAQEhAQkBFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8DBQttYXJnaW5SYXRpbwkBD2luaXRNYXJnaW5SYXRpbwAGCQACAQkArAICCQCsAgIJAKwCAgIZVG9vIG11Y2ggbWFyZ2luIHJlbW92ZWQ6IAkApAMBBQttYXJnaW5SYXRpbwIDIDwgCQCkAwEJAQ9pbml0TWFyZ2luUmF0aW8ABA1xdW90ZUFzc2V0U3RyCQDYBAEJAQpxdW90ZUFzc2V0AAQNJHQwNjQ4NTU2NDkwOQkBE2dldEJvcnJvd2VkQnlUcmFkZXIBBQdfdHJhZGVyBAhib3Jyb3dlZAgFDSR0MDY0ODU1NjQ5MDkCXzEEB2Fzc2V0SWQIBQ0kdDA2NDg1NTY0OTA5Al8yBAd0b1JlcGF5AwkAZgIFB19hbW91bnQFCGJvcnJvd2VkBQhib3Jyb3dlZAUHX2Ftb3VudAQKdG9XaXRoZHJhdwMJAGYCBQhib3Jyb3dlZAUHX2Ftb3VudAAACQBlAgUHX2Ftb3VudAUIYm9ycm93ZWQEC2ZpbmFsQm9ycm93CQBlAgUIYm9ycm93ZWQFB3RvUmVwYXkEFXN3aXRjaFBvc2l0aW9uVG9RdW90ZQMJAGYCBQtmaW5hbEJvcnJvdwAABQNuaWwJARN1cGRhdGVQb3NpdGlvbkFzc2V0AgUHX3RyYWRlcgUNcXVvdGVBc3NldFN0cgQNZG9TYW5pdHlDaGVjawMJAQIhPQIJAGQCBQd0b1JlcGF5BQp0b1dpdGhkcmF3BQdfYW1vdW50CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICCHRvUmVwYXk9CQCkAwEFB3RvUmVwYXkCDiArIHRvV2l0aGRyYXc9CQCkAwEFCnRvV2l0aGRyYXcCBCAhPSAJAKQDAQUHX2Ftb3VudAUDbmlsAwkAAAIFDWRvU2FuaXR5Q2hlY2sFDWRvU2FuaXR5Q2hlY2sECWRvVW5zdGFrZQMJAGYCBQp0b1dpdGhkcmF3AAAECWRvVW5zdGFrZQkA/AcECQEMdmF1bHRBZGRyZXNzAAIOd2l0aGRyYXdMb2NrZWQJAMwIAgUKdG9XaXRoZHJhdwUDbmlsBQNuaWwDCQAAAgUJZG9VbnN0YWtlBQlkb1Vuc3Rha2UFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAwkAAAIFCWRvVW5zdGFrZQUJZG9VbnN0YWtlBBZyZXR1cm5Db2xsYXRlcmFsQWN0aW9uAwkAZgIFB3RvUmVwYXkAAAQHZG9SZXBheQkA/AcECQERY29sbGF0ZXJhbEFkZHJlc3MAAgVyZXBheQkAzAgCBQdfdHJhZGVyCQDMCAIFB3RvUmVwYXkJAMwIAgUHYXNzZXRJZAUDbmlsBQNuaWwDCQAAAgUHZG9SZXBheQUHZG9SZXBheQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFB3RvUmVwYXkJANkEAQUHYXNzZXRJZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwDCQAAAgUWcmV0dXJuQ29sbGF0ZXJhbEFjdGlvbgUWcmV0dXJuQ29sbGF0ZXJhbEFjdGlvbgkAzggCCQDOCAIJAM4IAgkAzggCCQEOdXBkYXRlUG9zaXRpb24FBQdfdHJhZGVyBQ9vbGRQb3NpdGlvblNpemUFDHJlbWFpbk1hcmdpbgUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwJAR9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQUPb2xkUG9zaXRpb25TaXplAwkAZgIFCnRvV2l0aGRyYXcAAAkBCHdpdGhkcmF3AggFAWkGY2FsbGVyBQp0b1dpdGhkcmF3BQNuaWwJAQ11cGRhdGVCYWxhbmNlAQkAZQIJAQhjYmFsYW5jZQAFB19hbW91bnQFFXN3aXRjaFBvc2l0aW9uVG9RdW90ZQUWcmV0dXJuQ29sbGF0ZXJhbEFjdGlvbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ1jbG9zZVBvc2l0aW9uAgVfc2l6ZRRfbWluUXVvdGVBc3NldEFtb3VudAQEc3luYwkA/AcEBQR0aGlzAhlzeW5jVGVybWluYWxQcmljZVRvT3JhY2xlBQNuaWwFA25pbAMJAAACBQRzeW5jBQRzeW5jBAdfdHJhZGVyCQEPZ2V0QWN0dWFsQ2FsbGVyAQUBaQQOX3RyYWRlckFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQdfdHJhZGVyAg5JbnZhbGlkIGNhbGxlcgMDAwMDAwkBASEBCQETcmVxdWlyZU9wZW5Qb3NpdGlvbgEFB190cmFkZXIGCQEBIQEJAQtpbml0aWFsaXplZAAGCQEGcGF1c2VkAAYJAGcCAAAFBV9zaXplBgkAZgIAAAUUX21pblF1b3RlQXNzZXRBbW91bnQGCQEOaXNNYXJrZXRDbG9zZWQACQACAQIgSW52YWxpZCBjbG9zZVBvc2l0aW9uIHBhcmFtZXRlcnMEDSR0MDY3MDkzNjcyMzMJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIED29sZFBvc2l0aW9uU2l6ZQgFDSR0MDY3MDkzNjcyMzMCXzEEEW9sZFBvc2l0aW9uTWFyZ2luCAUNJHQwNjcwOTM2NzIzMwJfMgQXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDA2NzA5MzY3MjMzAl8zBBRvbGRQb3NpdGlvbkxzdFVwZENQRggFDSR0MDY3MDkzNjcyMzMCXzQEDSR0MDY3MjM5NzIzNjkDCQBmAgkBA2FicwEFD29sZFBvc2l0aW9uU2l6ZQUFX3NpemUECl9kaXJlY3Rpb24DCQBmAgUPb2xkUG9zaXRpb25TaXplAAAFCURJUl9TSE9SVAUIRElSX0xPTkcEBWlzQWRkCQAAAgUKX2RpcmVjdGlvbgUIRElSX0xPTkcEDSR0MDY3ODMwNjgwNTIJAQpzd2FwT3V0cHV0AwkAZgIFD29sZFBvc2l0aW9uU2l6ZQAABQVfc2l6ZQYEGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQIBQ0kdDA2NzgzMDY4MDUyAl8xBBZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwNjc4MzA2ODA1MgJfMgQVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwNjc4MzA2ODA1MgJfMwQWdG90YWxQb3NpdGlvblNpemVBZnRlcggFDSR0MDY3ODMwNjgwNTICXzQEFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQMJAGYCBQ9vbGRQb3NpdGlvblNpemUAAAkBAS0BBQVfc2l6ZQUFX3NpemUEDSR0MDY4MTQzNjgyOTcJASNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAIFB190cmFkZXIFD1BOTF9PUFRJT05fU1BPVAQTb2xkUG9zaXRpb25Ob3Rpb25hbAgFDSR0MDY4MTQzNjgyOTcCXzEEDXVucmVhbGl6ZWRQbmwIBQ0kdDA2ODE0MzY4Mjk3Al8yBAJtcgkBFmdldE1hcmdpblJhdGlvQnlPcHRpb24CBQdfdHJhZGVyBQ9QTkxfT1BUSU9OX1NQT1QEDXJlYWxpemVkUmF0aW8JAQRkaXZkAgkBA2FicwEFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQkBA2FicwEFD29sZFBvc2l0aW9uU2l6ZQQLcmVhbGl6ZWRQbmwJAQRtdWxkAgUNdW5yZWFsaXplZFBubAUNcmVhbGl6ZWRSYXRpbwQScmVtYWluTWFyZ2luQmVmb3JlCAkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQ9vbGRQb3NpdGlvblNpemUFEW9sZFBvc2l0aW9uTWFyZ2luBRRvbGRQb3NpdGlvbkxzdFVwZENQRgUNdW5yZWFsaXplZFBubAJfMQQNJHQwNjg3OTg2OTAyNgkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQ9vbGRQb3NpdGlvblNpemUFEW9sZFBvc2l0aW9uTWFyZ2luBRRvbGRQb3NpdGlvbkxzdFVwZENQRgULcmVhbGl6ZWRQbmwEAngxCAUNJHQwNjg3OTg2OTAyNgJfMQQPcG9zaXRpb25CYWREZWJ0CAUNJHQwNjg3OTg2OTAyNgJfMgQOZnVuZGluZ1BheW1lbnQIBQ0kdDA2ODc5ODY5MDI2Al8zBBJ1bnJlYWxpemVkUG5sQWZ0ZXIJAGUCBQ11bnJlYWxpemVkUG5sBQtyZWFsaXplZFBubAQScmVtYWluT3Blbk5vdGlvbmFsAwkAZgIFD29sZFBvc2l0aW9uU2l6ZQAACQBlAgkAZQIFE29sZFBvc2l0aW9uTm90aW9uYWwFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQFEnVucmVhbGl6ZWRQbmxBZnRlcgkAZQIJAGQCBRJ1bnJlYWxpemVkUG5sQWZ0ZXIFE29sZFBvc2l0aW9uTm90aW9uYWwFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQEF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsCQEDYWJzAQUScmVtYWluT3Blbk5vdGlvbmFsBBFuZXdQb3NpdGlvbk1hcmdpbgMJAGYCBQ9vbGRQb3NpdGlvblNpemUAAAkAZQIJAQRtdWxkAgkAZAIFF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsBRJ1bnJlYWxpemVkUG5sQWZ0ZXIFAm1yBRJ1bnJlYWxpemVkUG5sQWZ0ZXIJAGUCCQEEbXVsZAIJAGUCBRduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAUSdW5yZWFsaXplZFBubEFmdGVyBQJtcgUSdW5yZWFsaXplZFBubEFmdGVyBBFvcGVuTm90aW9uYWxEZWx0YQkAZQIFF29sZFBvc2l0aW9uT3Blbk5vdGlvbmFsBRduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAQPbmV3UG9zaXRpb25TaXplCQBkAgUPb2xkUG9zaXRpb25TaXplBRVleGNoYW5nZWRQb3NpdGlvblNpemUEFG5ld1Bvc2l0aW9uTHN0VXBkQ1BGCQEfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgEFD25ld1Bvc2l0aW9uU2l6ZQQZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgkAZQIJARRvcGVuSW50ZXJlc3ROb3Rpb25hbAAFEW9wZW5Ob3Rpb25hbERlbHRhAwMJAQIhPQIFFF9taW5RdW90ZUFzc2V0QW1vdW50AAAJAGYCBRRfbWluUXVvdGVBc3NldEFtb3VudAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAcJAAIBCQCsAgIJAKwCAgkArAICAg1MaW1pdCBlcnJvcjogCQCkAwEFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQCAyA8IAkApAMBBRRfbWluUXVvdGVBc3NldEFtb3VudAkAoQoPBQ9uZXdQb3NpdGlvblNpemUFEW5ld1Bvc2l0aW9uTWFyZ2luBRduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAUUbmV3UG9zaXRpb25Mc3RVcGRDUEYFD3Bvc2l0aW9uQmFkRGVidAULcmVhbGl6ZWRQbmwJAGUCBRJyZW1haW5NYXJnaW5CZWZvcmUJAGQCBRFuZXdQb3NpdGlvbk1hcmdpbgUSdW5yZWFsaXplZFBubEFmdGVyBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIJAGUCCQEVdG90YWxMb25nUG9zaXRpb25TaXplAAMJAGYCBQ9uZXdQb3NpdGlvblNpemUAAAkBA2FicwEFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQAACQBlAgkBFnRvdGFsU2hvcnRQb3NpdGlvblNpemUAAwkAZgIAAAUPbmV3UG9zaXRpb25TaXplCQEDYWJzAQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplAAAJAGUCCQEQb3BlbkludGVyZXN0TG9uZwADCQBmAgUPbmV3UG9zaXRpb25TaXplAAAFEW9wZW5Ob3Rpb25hbERlbHRhAAAJAGUCCQERb3BlbkludGVyZXN0U2hvcnQAAwkAZgIAAAUPbmV3UG9zaXRpb25TaXplBRFvcGVuTm90aW9uYWxEZWx0YQAAAwkAZgIFBV9zaXplCQEDYWJzAQUPb2xkUG9zaXRpb25TaXplCQACAQIgSW52YWxpZCBjbG9zZVBvc2l0aW9uIHBhcmFtZXRlcnMEDSR0MDcxMzEwNzE3MjkJARVpbnRlcm5hbENsb3NlUG9zaXRpb24CBQdfdHJhZGVyBgQZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAgFDSR0MDcxMzEwNzE3MjkCXzEED3Bvc2l0aW9uQmFkRGVidAgFDSR0MDcxMzEwNzE3MjkCXzIEC3JlYWxpemVkUG5sCAUNJHQwNzEzMTA3MTcyOQJfMwQNbWFyZ2luVG9WYXVsdAgFDSR0MDcxMzEwNzE3MjkCXzQEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA3MTMxMDcxNzI5Al81BBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA3MTMxMDcxNzI5Al82BBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNzEzMTA3MTcyOQJfNwQZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcggFDSR0MDcxMzEwNzE3MjkCXzgEAngyCAUNJHQwNzEzMTA3MTcyOQJfOQQOdG90YWxMb25nQWZ0ZXIIBQ0kdDA3MTMxMDcxNzI5A18xMAQPdG90YWxTaG9ydEFmdGVyCAUNJHQwNzEzMTA3MTcyOQNfMTEEGnRvdGFsTG9uZ09wZW5JbnRlcmVzdEFmdGVyCAUNJHQwNzEzMTA3MTcyOQNfMTIEG3RvdGFsU2hvcnRPcGVuSW50ZXJlc3RBZnRlcggFDSR0MDcxMzEwNzE3MjkDXzEzAwMJAQIhPQIFFF9taW5RdW90ZUFzc2V0QW1vdW50AAAJAGYCBRRfbWluUXVvdGVBc3NldEFtb3VudAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAcJAAIBCQCsAgIJAKwCAgkArAICAg1MaW1pdCBlcnJvcjogCQCkAwEFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQCAyA8IAkApAMBBRRfbWluUXVvdGVBc3NldEFtb3VudAkAoQoPAAAAAAAAAAAFD3Bvc2l0aW9uQmFkRGVidAULcmVhbGl6ZWRQbmwFDW1hcmdpblRvVmF1bHQFFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFFWJhc2VBc3NldFJlc2VydmVBZnRlcgUWdG90YWxQb3NpdGlvblNpemVBZnRlcgUZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgUOdG90YWxMb25nQWZ0ZXIFD3RvdGFsU2hvcnRBZnRlcgUadG90YWxMb25nT3BlbkludGVyZXN0QWZ0ZXIFG3RvdGFsU2hvcnRPcGVuSW50ZXJlc3RBZnRlcgQPbmV3UG9zaXRpb25TaXplCAUNJHQwNjcyMzk3MjM2OQJfMQQRbmV3UG9zaXRpb25NYXJnaW4IBQ0kdDA2NzIzOTcyMzY5Al8yBBduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDY3MjM5NzIzNjkCXzMEFG5ld1Bvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwNjcyMzk3MjM2OQJfNAQPcG9zaXRpb25CYWREZWJ0CAUNJHQwNjcyMzk3MjM2OQJfNQQLcmVhbGl6ZWRQbmwIBQ0kdDA2NzIzOTcyMzY5Al82BA1tYXJnaW5Ub1ZhdWx0CAUNJHQwNjcyMzk3MjM2OQJfNwQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDY3MjM5NzIzNjkCXzgEFWJhc2VBc3NldFJlc2VydmVBZnRlcggFDSR0MDY3MjM5NzIzNjkCXzkEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDA2NzIzOTcyMzY5A18xMAQZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcggFDSR0MDY3MjM5NzIzNjkDXzExBA50b3RhbExvbmdBZnRlcggFDSR0MDY3MjM5NzIzNjkDXzEyBA90b3RhbFNob3J0QWZ0ZXIIBQ0kdDA2NzIzOTcyMzY5A18xMwQadG90YWxMb25nT3BlbkludGVyZXN0QWZ0ZXIIBQ0kdDA2NzIzOTcyMzY5A18xNAQbdG90YWxTaG9ydE9wZW5JbnRlcmVzdEFmdGVyCAUNJHQwNjcyMzk3MjM2OQNfMTUDCQBmAgUPcG9zaXRpb25CYWREZWJ0AAAJAAIBAiZVbmFibGUgdG8gY2xvc2UgcG9zaXRpb24gd2l0aCBiYWQgZGVidAQOd2l0aGRyYXdBbW91bnQJAQNhYnMBBQ1tYXJnaW5Ub1ZhdWx0BAphbW1CYWxhbmNlCQBlAgkBCGNiYWxhbmNlAAUOd2l0aGRyYXdBbW91bnQEDSR0MDcyNTc4NzI3ODUDCQBmAgAABQphbW1CYWxhbmNlCQCUCgIAAAkBA2FicwEFCmFtbUJhbGFuY2UJAJQKAgUKYW1tQmFsYW5jZQAABA1hbW1OZXdCYWxhbmNlCAUNJHQwNzI1Nzg3Mjc4NQJfMQQDeDExCAUNJHQwNzI1Nzg3Mjc4NQJfMgQNJHQwNzI3OTI3Mjg0NgkBE2dldEJvcnJvd2VkQnlUcmFkZXIBBQdfdHJhZGVyBAhib3Jyb3dlZAgFDSR0MDcyNzkyNzI4NDYCXzEEB2Fzc2V0SWQIBQ0kdDA3Mjc5MjcyODQ2Al8yBA0kdDA3Mjg2MTczNzIwAwkAZgIFCGJvcnJvd2VkAAADCQBnAgUOd2l0aGRyYXdBbW91bnQFCGJvcnJvd2VkBAdkb1JlcGF5CQD8BwQJARFjb2xsYXRlcmFsQWRkcmVzcwACBXJlcGF5CQDMCAIFB190cmFkZXIJAMwIAgUIYm9ycm93ZWQJAMwIAgUHYXNzZXRJZAUDbmlsBQNuaWwDCQAAAgUHZG9SZXBheQUHZG9SZXBheQkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFDl90cmFkZXJBZGRyZXNzBQhib3Jyb3dlZAkA2QQBBQdhc3NldElkBQNuaWwJAGUCBQ53aXRoZHJhd0Ftb3VudAUIYm9ycm93ZWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4ED3JlYWxpemVBbmRDbG9zZQkA/AcECQERY29sbGF0ZXJhbEFkZHJlc3MAAhhyZWFsaXplUGFydGlhbGx5QW5kQ2xvc2UJAMwIAgUHX3RyYWRlcgkAzAgCBQ53aXRoZHJhd0Ftb3VudAkAzAgCBQdhc3NldElkBQNuaWwFA25pbAMJAAACBQ9yZWFsaXplQW5kQ2xvc2UFD3JlYWxpemVBbmRDbG9zZQkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFDl90cmFkZXJBZGRyZXNzBQ53aXRoZHJhd0Ftb3VudAkA2QQBBQdhc3NldElkBQNuaWwAAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlAoCBQNuaWwFDndpdGhkcmF3QW1vdW50AwkAAAIFDSR0MDcyODYxNzM3MjAFDSR0MDcyODYxNzM3MjAEE3F1b3RlV2l0aGRyYXdBbW91bnQIBQ0kdDA3Mjg2MTczNzIwAl8yBBRzZW5kQ29sbGF0ZXJhbEFjdGlvbggFDSR0MDcyODYxNzM3MjACXzEEB3Vuc3Rha2UDCQBmAgUTcXVvdGVXaXRoZHJhd0Ftb3VudAAABAd1bnN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAg53aXRoZHJhd0xvY2tlZAkAzAgCBRNxdW90ZVdpdGhkcmF3QW1vdW50BQNuaWwFA25pbAMJAAACBQd1bnN0YWtlBQd1bnN0YWtlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBQd1bnN0YWtlBQd1bnN0YWtlBA5ub3RpZnlOb3Rpb25hbAkA/AcECQEMbWluZXJBZGRyZXNzAAIObm90aWZ5Tm90aW9uYWwJAMwIAgUHX3RyYWRlcgkAzAgCAAAFA25pbAUDbmlsAwkAAAIFDm5vdGlmeU5vdGlvbmFsBQ5ub3RpZnlOb3Rpb25hbAkAzggCCQDOCAIJAM4IAgkAzggCAwkAAAIFD25ld1Bvc2l0aW9uU2l6ZQAACQEOZGVsZXRlUG9zaXRpb24BBQdfdHJhZGVyCQEOdXBkYXRlUG9zaXRpb24FBQdfdHJhZGVyBQ9uZXdQb3NpdGlvblNpemUFEW5ld1Bvc2l0aW9uTWFyZ2luBRduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAUUbmV3UG9zaXRpb25Mc3RVcGRDUEYJAQl1cGRhdGVBbW0IBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIFDnRvdGFsTG9uZ0FmdGVyBQ90b3RhbFNob3J0QWZ0ZXIFGnRvdGFsTG9uZ09wZW5JbnRlcmVzdEFmdGVyBRt0b3RhbFNob3J0T3BlbkludGVyZXN0QWZ0ZXIDCQBmAgUTcXVvdGVXaXRoZHJhd0Ftb3VudAAACQEId2l0aGRyYXcCBQ5fdHJhZGVyQWRkcmVzcwUTcXVvdGVXaXRoZHJhd0Ftb3VudAUDbmlsCQENdXBkYXRlQmFsYW5jZQEFDWFtbU5ld0JhbGFuY2UFFHNlbmRDb2xsYXRlcmFsQWN0aW9uCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCWxpcXVpZGF0ZQEHX3RyYWRlcgQEc3luYwkA/AcEBQR0aGlzAhlzeW5jVGVybWluYWxQcmljZVRvT3JhY2xlBQNuaWwFA25pbAMJAAACBQRzeW5jBQRzeW5jBA9zcG90TWFyZ2luUmF0aW8JARZnZXRNYXJnaW5SYXRpb0J5T3B0aW9uAgUHX3RyYWRlcgUPUE5MX09QVElPTl9TUE9UBAttYXJnaW5SYXRpbwMJARZpc092ZXJGbHVjdHVhdGlvbkxpbWl0AAQRb3JhY2xlTWFyZ2luUmF0aW8JARZnZXRNYXJnaW5SYXRpb0J5T3B0aW9uAgUHX3RyYWRlcgURUE5MX09QVElPTl9PUkFDTEUJAQR2bWF4AgUPc3BvdE1hcmdpblJhdGlvBRFvcmFjbGVNYXJnaW5SYXRpbwUPc3BvdE1hcmdpblJhdGlvAwMDAwMJAQEhAQkBFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8DBQttYXJnaW5SYXRpbwkBFm1haW50ZW5hbmNlTWFyZ2luUmF0aW8ABwYJAQEhAQkBE3JlcXVpcmVPcGVuUG9zaXRpb24BBQdfdHJhZGVyBgkBASEBCQELaW5pdGlhbGl6ZWQABgkBBnBhdXNlZAAGCQEOaXNNYXJrZXRDbG9zZWQACQACAQITVW5hYmxlIHRvIGxpcXVpZGF0ZQMDAwkAZgIFD3Nwb3RNYXJnaW5SYXRpbwkBE2xpcXVpZGF0aW9uRmVlUmF0aW8ACQBmAgkBF3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAAAABwkAZgIFDERFQ0lNQUxfVU5JVAkBF3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAAcEDSR0MDc2MDQxNzYxOTEJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIED29sZFBvc2l0aW9uU2l6ZQgFDSR0MDc2MDQxNzYxOTECXzEEEW9sZFBvc2l0aW9uTWFyZ2luCAUNJHQwNzYwNDE3NjE5MQJfMgQXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDA3NjA0MTc2MTkxAl8zBBRvbGRQb3NpdGlvbkxzdFVwZENQRggFDSR0MDc2MDQxNzYxOTECXzQECl9kaXJlY3Rpb24DCQBmAgUPb2xkUG9zaXRpb25TaXplAAAFCURJUl9TSE9SVAUIRElSX0xPTkcEBWlzQWRkCQAAAgUKX2RpcmVjdGlvbgUIRElSX0xPTkcEGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQJARtnZXRQYXJ0aWFsTGlxdWlkYXRpb25BbW91bnQCBQdfdHJhZGVyBQ9vbGRQb3NpdGlvblNpemUEDSR0MDc2NDE2NzY1MjAJASNnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubAIFB190cmFkZXIFD1BOTF9PUFRJT05fU1BPVAQTb2xkUG9zaXRpb25Ob3Rpb25hbAgFDSR0MDc2NDE2NzY1MjACXzEEDXVucmVhbGl6ZWRQbmwIBQ0kdDA3NjQxNjc2NTIwAl8yBA0kdDA3NjUyODc2NzE1CQEJc3dhcElucHV0AgUFaXNBZGQFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQEFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQgFDSR0MDc2NTI4NzY3MTUCXzEEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA3NjUyODc2NzE1Al8yBBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA3NjUyODc2NzE1Al8zBBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNzY1Mjg3NjcxNQJfNAQQbGlxdWlkYXRpb25SYXRpbwkBBGRpdmQCCQEDYWJzAQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplCQEDYWJzAQUPb2xkUG9zaXRpb25TaXplBAtyZWFsaXplZFBubAkBBG11bGQCBQ11bnJlYWxpemVkUG5sBRBsaXF1aWRhdGlvblJhdGlvBA0kdDA3NzAwNDc3MjM3CQEiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAQFD29sZFBvc2l0aW9uU2l6ZQURb2xkUG9zaXRpb25NYXJnaW4FFG9sZFBvc2l0aW9uTHN0VXBkQ1BGBQtyZWFsaXplZFBubAQMcmVtYWluTWFyZ2luCAUNJHQwNzcwMDQ3NzIzNwJfMQQHYmFkRGVidAgFDSR0MDc3MDA0NzcyMzcCXzIEDmZ1bmRpbmdQYXltZW50CAUNJHQwNzcwMDQ3NzIzNwJfMwQSdW5yZWFsaXplZFBubEFmdGVyCQBlAgUNdW5yZWFsaXplZFBubAULcmVhbGl6ZWRQbmwEEnJlbWFpbk9wZW5Ob3Rpb25hbAMJAGYCBQ9vbGRQb3NpdGlvblNpemUAAAkAZQIJAGUCBRNvbGRQb3NpdGlvbk5vdGlvbmFsBRlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50BRJ1bnJlYWxpemVkUG5sQWZ0ZXIJAGUCCQBkAgUSdW5yZWFsaXplZFBubEFmdGVyBRNvbGRQb3NpdGlvbk5vdGlvbmFsBRlleGNoYW5nZWRRdW90ZUFzc2V0QW1vdW50BBJsaXF1aWRhdGlvblBlbmFsdHkJAQRtdWxkAgUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAkBE2xpcXVpZGF0aW9uRmVlUmF0aW8ABA9mZWVUb0xpcXVpZGF0b3IJAGkCBRJsaXF1aWRhdGlvblBlbmFsdHkAAgQKZmVlVG9WYXVsdAkAZQIFEmxpcXVpZGF0aW9uUGVuYWx0eQUPZmVlVG9MaXF1aWRhdG9yBBFuZXdQb3NpdGlvbk1hcmdpbgkAZQIFDHJlbWFpbk1hcmdpbgUSbGlxdWlkYXRpb25QZW5hbHR5BA9uZXdQb3NpdGlvblNpemUJAGQCBQ9vbGRQb3NpdGlvblNpemUFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQQXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwJAQNhYnMBBRJyZW1haW5PcGVuTm90aW9uYWwEEW9wZW5Ob3Rpb25hbERlbHRhCQBlAgUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwFF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsBBRuZXdQb3NpdGlvbkxzdFVwZENQRgkBH2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24BBQ9uZXdQb3NpdGlvblNpemUEGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIJAGUCCQEUb3BlbkludGVyZXN0Tm90aW9uYWwABRFvcGVuTm90aW9uYWxEZWx0YQQKYW1tQmFsYW5jZQkAZQIJAQhjYmFsYW5jZQAFEmxpcXVpZGF0aW9uUGVuYWx0eQQNJHQwNzg0Nzg3ODYwNwMJAGYCAAAFCmFtbUJhbGFuY2UJAJQKAgAACQEDYWJzAQUKYW1tQmFsYW5jZQkAlAoCBQphbW1CYWxhbmNlAAAEDW5ld0FtbUJhbGFuY2UIBQ0kdDA3ODQ3ODc4NjA3Al8xBAN4MTEIBQ0kdDA3ODQ3ODc4NjA3Al8yBA0kdDA3ODYxNTc4NjY5CQETZ2V0Qm9ycm93ZWRCeVRyYWRlcgEFB190cmFkZXIECGJvcnJvd2VkCAUNJHQwNzg2MTU3ODY2OQJfMQQHYXNzZXRJZAgFDSR0MDc4NjE1Nzg2NjkCXzIEFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAMJAGYCBQhib3Jyb3dlZAAABBBjb2xsYXRlcmFsVG9TZWxsCQEEbXVsZAIFCGJvcnJvd2VkBRBsaXF1aWRhdGlvblJhdGlvBA9yZWFsaXplQW5kQ2xvc2UJAPwHBAkBEWNvbGxhdGVyYWxBZGRyZXNzAAIQcmVhbGl6ZVBhcnRpYWxseQkAzAgCBQdfdHJhZGVyCQDMCAIFB2Fzc2V0SWQJAMwIAgUQY29sbGF0ZXJhbFRvU2VsbAUDbmlsBQNuaWwDCQAAAgUPcmVhbGl6ZUFuZENsb3NlBQ9yZWFsaXplQW5kQ2xvc2UFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAwkAAAIFFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAUVZG9MaXF1aWRhdGVDb2xsYXRlcmFsBAd1bnN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAg53aXRoZHJhd0xvY2tlZAkAzAgCBRJsaXF1aWRhdGlvblBlbmFsdHkFA25pbAUDbmlsAwkAAAIFB3Vuc3Rha2UFB3Vuc3Rha2UEEGRlcG9zaXRJbnN1cmFuY2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACB2FkZEZyZWUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQpmZWVUb1ZhdWx0BQNuaWwDCQAAAgUQZGVwb3NpdEluc3VyYW5jZQUQZGVwb3NpdEluc3VyYW5jZQQObm90aWZ5Tm90aW9uYWwJAPwHBAkBDG1pbmVyQWRkcmVzcwACDm5vdGlmeU5vdGlvbmFsCQDMCAIFB190cmFkZXIJAMwIAgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFA25pbAUDbmlsAwkAAAIFDm5vdGlmeU5vdGlvbmFsBQ5ub3RpZnlOb3Rpb25hbAkAzggCCQDOCAIJAM4IAgkBDnVwZGF0ZVBvc2l0aW9uBQUHX3RyYWRlcgUPbmV3UG9zaXRpb25TaXplBRFuZXdQb3NpdGlvbk1hcmdpbgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFFG5ld1Bvc2l0aW9uTHN0VXBkQ1BGCQEJdXBkYXRlQW1tCAUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBRZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBRlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCQBlAgkBFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQADCQBmAgUPbmV3UG9zaXRpb25TaXplAAAJAQNhYnMBBRVleGNoYW5nZWRQb3NpdGlvblNpemUAAAkAZQIJARZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAMJAGYCAAAFD25ld1Bvc2l0aW9uU2l6ZQkBA2FicwEFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQAACQBlAgkBEG9wZW5JbnRlcmVzdExvbmcAAwkAZgIFD25ld1Bvc2l0aW9uU2l6ZQAABRFvcGVuTm90aW9uYWxEZWx0YQAACQBlAgkBEW9wZW5JbnRlcmVzdFNob3J0AAMJAGYCAAAFD25ld1Bvc2l0aW9uU2l6ZQURb3Blbk5vdGlvbmFsRGVsdGEAAAkBCHdpdGhkcmF3AggFAWkGY2FsbGVyBQ9mZWVUb0xpcXVpZGF0b3IJAQ11cGRhdGVCYWxhbmNlAQUNbmV3QW1tQmFsYW5jZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQNJHQwODAzNDg4MDg0MwkBFWludGVybmFsQ2xvc2VQb3NpdGlvbgIFB190cmFkZXIHBAJ4MQgFDSR0MDgwMzQ4ODA4NDMCXzEEB2JhZERlYnQIBQ0kdDA4MDM0ODgwODQzAl8yBAJ4MggFDSR0MDgwMzQ4ODA4NDMCXzMEAngzCAUNJHQwODAzNDg4MDg0MwJfNAQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDgwMzQ4ODA4NDMCXzUEFWJhc2VBc3NldFJlc2VydmVBZnRlcggFDSR0MDgwMzQ4ODA4NDMCXzYEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDA4MDM0ODgwODQzAl83BBlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCAUNJHQwODAzNDg4MDg0MwJfOAQZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAgFDSR0MDgwMzQ4ODA4NDMCXzkEDnRvdGFsTG9uZ0FmdGVyCAUNJHQwODAzNDg4MDg0MwNfMTAED3RvdGFsU2hvcnRBZnRlcggFDSR0MDgwMzQ4ODA4NDMDXzExBBp0b3RhbExvbmdPcGVuSW50ZXJlc3RBZnRlcggFDSR0MDgwMzQ4ODA4NDMDXzEyBBt0b3RhbFNob3J0T3BlbkludGVyZXN0QWZ0ZXIIBQ0kdDA4MDM0ODgwODQzA18xMwQSbGlxdWlkYXRpb25QZW5hbHR5CQEEbXVsZAIFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQJARNsaXF1aWRhdGlvbkZlZVJhdGlvAAQPZmVlVG9MaXF1aWRhdG9yCQBpAgUSbGlxdWlkYXRpb25QZW5hbHR5AAIECmZlZVRvVmF1bHQJAGUCBRJsaXF1aWRhdGlvblBlbmFsdHkFD2ZlZVRvTGlxdWlkYXRvcgQKYW1tQmFsYW5jZQkAZQIJAQhjYmFsYW5jZQAFEmxpcXVpZGF0aW9uUGVuYWx0eQQNJHQwODEyNTE4MTM4MAMJAGYCAAAFCmFtbUJhbGFuY2UJAJQKAgAACQEDYWJzAQUKYW1tQmFsYW5jZQkAlAoCBQphbW1CYWxhbmNlAAAEDW5ld0FtbUJhbGFuY2UIBQ0kdDA4MTI1MTgxMzgwAl8xBAN4MTEIBQ0kdDA4MTI1MTgxMzgwAl8yBA0kdDA4MTM4ODgxNDQyCQETZ2V0Qm9ycm93ZWRCeVRyYWRlcgEFB190cmFkZXIECGJvcnJvd2VkCAUNJHQwODEzODg4MTQ0MgJfMQQHYXNzZXRJZAgFDSR0MDgxMzg4ODE0NDICXzIEFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAMJAGYCBQhib3Jyb3dlZAAABA9yZWFsaXplQW5kQ2xvc2UJAPwHBAkBEWNvbGxhdGVyYWxBZGRyZXNzAAIYcmVhbGl6ZVBhcnRpYWxseUFuZENsb3NlCQDMCAIFB190cmFkZXIJAMwIAgAACQDMCAIFB2Fzc2V0SWQFA25pbAUDbmlsAwkAAAIFD3JlYWxpemVBbmRDbG9zZQUPcmVhbGl6ZUFuZENsb3NlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBRVkb0xpcXVpZGF0ZUNvbGxhdGVyYWwFFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAQBeAMJAGYCBQdiYWREZWJ0AAAEC2xvY2tCYWREZWJ0CQD8BwQJAQx2YXVsdEFkZHJlc3MAAhVleGNoYW5nZUZyZWVBbmRMb2NrZWQJAMwIAgUHYmFkRGVidAUDbmlsBQNuaWwDCQAAAgULbG9ja0JhZERlYnQFC2xvY2tCYWREZWJ0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBQF4BQF4BAd1bnN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAg53aXRoZHJhd0xvY2tlZAkAzAgCBRJsaXF1aWRhdGlvblBlbmFsdHkFA25pbAUDbmlsAwkAAAIFB3Vuc3Rha2UFB3Vuc3Rha2UEEGRlcG9zaXRJbnN1cmFuY2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACB2FkZEZyZWUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQpmZWVUb1ZhdWx0BQNuaWwDCQAAAgUQZGVwb3NpdEluc3VyYW5jZQUQZGVwb3NpdEluc3VyYW5jZQQObm90aWZ5Tm90aW9uYWwJAPwHBAkBDG1pbmVyQWRkcmVzcwACDm5vdGlmeU5vdGlvbmFsCQDMCAIFB190cmFkZXIJAMwIAgAABQNuaWwFA25pbAMJAAACBQ5ub3RpZnlOb3Rpb25hbAUObm90aWZ5Tm90aW9uYWwJAM4IAgkAzggCCQDOCAIJAQ5kZWxldGVQb3NpdGlvbgEFB190cmFkZXIJAQl1cGRhdGVBbW0IBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIFDnRvdGFsTG9uZ0FmdGVyBQ90b3RhbFNob3J0QWZ0ZXIFGnRvdGFsTG9uZ09wZW5JbnRlcmVzdEFmdGVyBRt0b3RhbFNob3J0T3BlbkludGVyZXN0QWZ0ZXIJAQh3aXRoZHJhdwIIBQFpBmNhbGxlcgUPZmVlVG9MaXF1aWRhdG9yCQENdXBkYXRlQmFsYW5jZQEFDW5ld0FtbUJhbGFuY2UJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKcGF5RnVuZGluZwAEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQVZnVuZGluZ0Jsb2NrVGltZXN0YW1wCQEZbmV4dEZ1bmRpbmdCbG9ja1RpbWVzdGFtcAADAwMJAGYCBRVmdW5kaW5nQmxvY2tUaW1lc3RhbXAIBQlsYXN0QmxvY2sJdGltZXN0YW1wBgkBASEBCQELaW5pdGlhbGl6ZWQABgkBBnBhdXNlZAAJAAIBCQCsAgIJAKwCAgkArAICAiFJbnZhbGlkIGZ1bmRpbmcgYmxvY2sgdGltZXN0YW1wOiAJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXACAyA8IAkApAMBBRVmdW5kaW5nQmxvY2tUaW1lc3RhbXAED3VuZGVybHlpbmdQcmljZQkBDmdldE9yYWNsZVByaWNlAAQNJHQwODMzMTQ4MzM3NgkBCmdldEZ1bmRpbmcABBRzaG9ydFByZW1pdW1GcmFjdGlvbggFDSR0MDgzMzE0ODMzNzYCXzEEE2xvbmdQcmVtaXVtRnJhY3Rpb24IBQ0kdDA4MzMxNDgzMzc2Al8yCQENdXBkYXRlRnVuZGluZwUJAGQCBRVmdW5kaW5nQmxvY2tUaW1lc3RhbXAJARRmdW5kaW5nUGVyaW9kU2Vjb25kcwAJAGQCCQEjbGF0ZXN0TG9uZ0N1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24ABRNsb25nUHJlbWl1bUZyYWN0aW9uCQBkAgkBJGxhdGVzdFNob3J0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAFFHNob3J0UHJlbWl1bUZyYWN0aW9uCQEEZGl2ZAIFE2xvbmdQcmVtaXVtRnJhY3Rpb24FD3VuZGVybHlpbmdQcmljZQkBBGRpdmQCBRRzaG9ydFByZW1pdW1GcmFjdGlvbgUPdW5kZXJseWluZ1ByaWNlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBGXN5bmNUZXJtaW5hbFByaWNlVG9PcmFjbGUABAdfcXRBc3RSCQEGcXRBc3RSAAQHX2JzQXN0UgkBBmJzQXN0UgAEDSR0MDgzODA4ODM5NDMJARRnZXRTeW5jVGVybWluYWxQcmljZQMJAQ5nZXRPcmFjbGVQcmljZQAFB19xdEFzdFIFB19ic0FzdFIEE25ld1F1b3RlQXNzZXRXZWlnaHQIBQ0kdDA4MzgwODgzOTQzAl8xBBJuZXdCYXNlQXNzZXRXZWlnaHQIBQ0kdDA4MzgwODgzOTQzAl8yBA1tYXJnaW5Ub1ZhdWx0CAUNJHQwODM4MDg4Mzk0MwJfMwQNZG9FeGNoYW5nZVBuTAMJAQIhPQIFDW1hcmdpblRvVmF1bHQAAAQNZG9FeGNoYW5nZVBuTAkA/AcECQEMdmF1bHRBZGRyZXNzAAIVZXhjaGFuZ2VGcmVlQW5kTG9ja2VkCQDMCAIFDW1hcmdpblRvVmF1bHQFA25pbAUDbmlsAwkAAAIFDWRvRXhjaGFuZ2VQbkwFDWRvRXhjaGFuZ2VQbkwFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAwkAAAIFDWRvRXhjaGFuZ2VQbkwFDWRvRXhjaGFuZ2VQbkwJAM4IAgkBEHVwZGF0ZUFtbVdlaWdodHMCBRNuZXdRdW90ZUFzc2V0V2VpZ2h0BRJuZXdCYXNlQXNzZXRXZWlnaHQJAQphcHBlbmRUd2FwAQkBBGRpdmQCCQEEbXVsZAIFB19xdEFzdFIFE25ld1F1b3RlQXNzZXRXZWlnaHQJAQRtdWxkAgUHX2JzQXN0UgUSbmV3QmFzZUFzc2V0V2VpZ2h0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBJ3ZpZXdfY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAEHX3RyYWRlcgQEc3luYwkA/AcEBQR0aGlzAhlzeW5jVGVybWluYWxQcmljZVRvT3JhY2xlBQNuaWwFA25pbAMJAAACBQRzeW5jBQRzeW5jBA0kdDA4NDUxMjg0NjEzCQELZ2V0UG9zaXRpb24BBQdfdHJhZGVyBAxwb3NpdGlvblNpemUIBQ0kdDA4NDUxMjg0NjEzAl8xBA5wb3NpdGlvbk1hcmdpbggFDSR0MDg0NTEyODQ2MTMCXzIEA3BvbggFDSR0MDg0NTEyODQ2MTMCXzMEEXBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwODQ1MTI4NDYxMwJfNAQNJHQwODQ2MTY4NDcxNwkBI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAgUHX3RyYWRlcgUPUE5MX09QVElPTl9TUE9UBBBwb3NpdGlvbk5vdGlvbmFsCAUNJHQwODQ2MTY4NDcxNwJfMQQNdW5yZWFsaXplZFBubAgFDSR0MDg0NjE2ODQ3MTcCXzIEDSR0MDg0NzIwODQ4OTIJASJjYWxjUmVtYWluTWFyZ2luV2l0aEZ1bmRpbmdQYXltZW50BAUMcG9zaXRpb25TaXplBQ5wb3NpdGlvbk1hcmdpbgURcG9zaXRpb25Mc3RVcGRDUEYFDXVucmVhbGl6ZWRQbmwEDHJlbWFpbk1hcmdpbggFDSR0MDg0NzIwODQ4OTICXzEEB2JhZERlYnQIBQ0kdDA4NDcyMDg0ODkyAl8yBA5mdW5kaW5nUGF5bWVudAgFDSR0MDg0NzIwODQ4OTICXzMJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkBAXMBBQxyZW1haW5NYXJnaW4JAQFzAQUOZnVuZGluZ1BheW1lbnQJAQFzAQkBDmdldE1hcmdpblJhdGlvAQUHX3RyYWRlcgkBAXMBBQ11bnJlYWxpemVkUG5sCQEBcwEFB2JhZERlYnQJAQFzAQUQcG9zaXRpb25Ob3Rpb25hbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARV2aWV3X2dldFBlZ0FkanVzdENvc3QBBl9wcmljZQQHX3F0QXN0UgkBBnF0QXN0UgAEB19ic0FzdFIJAQZic0FzdFIABAZyZXN1bHQJARRnZXRTeW5jVGVybWluYWxQcmljZQMFBl9wcmljZQUHX3F0QXN0UgUHX2JzQXN0UgkAAgEJAKQDAQgFBnJlc3VsdAJfMwFpARh2aWV3X2dldFRlcm1pbmFsQW1tUHJpY2UABA0kdDA4NTMwODg1Mzg5CQETZ2V0VGVybWluYWxBbW1TdGF0ZQAEGXRlcm1pbmFsUXVvdGVBc3NldFJlc2VydmUIBQ0kdDA4NTMwODg1Mzg5Al8xBBh0ZXJtaW5hbEJhc2VBc3NldFJlc2VydmUIBQ0kdDA4NTMwODg1Mzg5Al8yBAVwcmljZQkBBGRpdmQCCQEEbXVsZAIFGXRlcm1pbmFsUXVvdGVBc3NldFJlc2VydmUJAQZxdEFzdFcACQEEbXVsZAIFGHRlcm1pbmFsQmFzZUFzc2V0UmVzZXJ2ZQkBBmJzQXN0VwAJAAIBCQCkAwEFBXByaWNlAWkBD3ZpZXdfZ2V0RnVuZGluZwAED3VuZGVybHlpbmdQcmljZQkBDmdldE9yYWNsZVByaWNlAAQNJHQwODU2MDQ4NTY2NgkBCmdldEZ1bmRpbmcABBRzaG9ydFByZW1pdW1GcmFjdGlvbggFDSR0MDg1NjA0ODU2NjYCXzEEE2xvbmdQcmVtaXVtRnJhY3Rpb24IBQ0kdDA4NTYwNDg1NjY2Al8yBAtsb25nRnVuZGluZwkBBGRpdmQCBRNsb25nUHJlbWl1bUZyYWN0aW9uBQ91bmRlcmx5aW5nUHJpY2UEDHNob3J0RnVuZGluZwkBBGRpdmQCBRRzaG9ydFByZW1pdW1GcmFjdGlvbgUPdW5kZXJseWluZ1ByaWNlCQACAQkArAICCQCsAgIJAKwCAgkBAXMBBQtsb25nRnVuZGluZwkBAXMBBQxzaG9ydEZ1bmRpbmcJAQFzAQkBEGdldFR3YXBTcG90UHJpY2UACQEBcwEJAQ5nZXRPcmFjbGVQcmljZQABaQEYdmlld19nZXRCb3Jyb3dlZEJ5VHJhZGVyAQdfdHJhZGVyBA0kdDA4NTk1Mjg2MDA2CQETZ2V0Qm9ycm93ZWRCeVRyYWRlcgEFB190cmFkZXIECGJvcnJvd2VkCAUNJHQwODU5NTI4NjAwNgJfMQQHYXNzZXRJZAgFDSR0MDg1OTUyODYwMDYCXzIJAAIBCQCsAgIJAQFzAQUIYm9ycm93ZWQFB2Fzc2V0SWQBaQEQY29tcHV0ZVNwb3RQcmljZQAEBnJlc3VsdAkBDGdldFNwb3RQcmljZQAJAJQKAgUDbmlsBQZyZXN1bHQBaQEfY29tcHV0ZUZlZUZvclRyYWRlcldpdGhBcnRpZmFjdAIHX3RyYWRlcgtfYXJ0aWZhY3RJZAQGcmVzdWx0CQEYZ2V0Rm9yVHJhZGVyV2l0aEFydGlmYWN0AgUHX3RyYWRlcgULX2FydGlmYWN0SWQJAJQKAgUDbmlsBQZyZXN1bHQBAnR4AQZ2ZXJpZnkACQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACQEOYWRtaW5QdWJsaWNLZXkADgyvMw==", "height": 2390361, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 445QpJqbK2UXvSBxJUQwL1hYHgVqBCYXhGs8aU9Mo72s Next: 9Qbou3trG9mGcuEut5xcMGnwXwM1Yr4pmpiDYPjxvhHQ Diff:
OldNewDifferences
381381 if (if (_largerThanOrEqualTo)
382382 then (0 > remainingMarginRatio)
383383 else false)
384- then throw("Invalid margin")
384+ then throw(((("Invalid margin: " + toString(_marginRatio)) + " < ") + toString(_baseMarginRatio)))
385385 else if (if (!(_largerThanOrEqualTo))
386386 then (remainingMarginRatio >= 0)
387387 else false)
388- then throw("Invalid margin")
388+ then throw(((("Invalid margin: " + toString(_marginRatio)) + " > ") + toString(_baseMarginRatio)))
389389 else true
390390 }
391391
471471 let amountBaseAssetBought = if (_isAdd)
472472 then amountBaseAssetBoughtAbs
473473 else -(amountBaseAssetBoughtAbs)
474- let $t01680516968 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
475- let quoteAssetReserveAfter1 = $t01680516968._1
476- let baseAssetReserveAfter1 = $t01680516968._2
477- let totalPositionSizeAfter1 = $t01680516968._3
474+ let $t01693717100 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
475+ let quoteAssetReserveAfter1 = $t01693717100._1
476+ let baseAssetReserveAfter1 = $t01693717100._2
477+ let totalPositionSizeAfter1 = $t01693717100._3
478478 let priceBefore = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
479479 let marketPrice = divd(_quoteAssetAmount, amountBaseAssetBoughtAbs)
480480 let priceDiff = abs((priceBefore - marketPrice))
494494 }
495495 else 0
496496 let signedMargin = ((_marginDelta - fundingPayment) + _oldPositionMargin)
497- let $t01845518582 = if ((0 > signedMargin))
497+ let $t01858718714 = if ((0 > signedMargin))
498498 then $Tuple2(0, abs(signedMargin))
499499 else $Tuple2(abs(signedMargin), 0)
500- let remainMargin = $t01845518582._1
501- let badDebt = $t01845518582._2
500+ let remainMargin = $t01858718714._1
501+ let badDebt = $t01858718714._2
502502 $Tuple3(remainMargin, badDebt, fundingPayment)
503503 }
504504
515515 let quoteAssetAfter = toInt(bdivd(k, toBigInt(muld(baseAssetPoolAmountAfter, _baseAssetWeight))))
516516 let quoteAssetSold = abs((quoteAssetAfter - muld(_quoteAssetReserve, _quoteAssetWeight)))
517517 let maxPriceImpactValue = maxPriceImpact()
518- let $t01977019931 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
519- let quoteAssetReserveAfter1 = $t01977019931._1
520- let baseAssetReserveAfter1 = $t01977019931._2
521- let totalPositionSizeAfter1 = $t01977019931._3
518+ let $t01990220063 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
519+ let quoteAssetReserveAfter1 = $t01990220063._1
520+ let baseAssetReserveAfter1 = $t01990220063._2
521+ let totalPositionSizeAfter1 = $t01990220063._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 $t02488225102 = swapOutputWithReserves(!(isShort), positionSizeAbs, false, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
624- let outPositionNotional = $t02488225102._1
625- let x1 = $t02488225102._2
626- let x2 = $t02488225102._3
627- let x3 = $t02488225102._4
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
628628 outPositionNotional
629629 }
630630 else muld(positionSizeAbs, getOraclePrice())
645645
646646
647647 func getPositionNotionalAndUnrealizedPnl (_trader,_option) = {
648- let $t02652326651 = getPosition(_trader)
649- let positionSize = $t02652326651._1
650- let positionMargin = $t02652326651._2
651- let positionOpenNotional = $t02652326651._3
652- let positionLstUpdCPF = $t02652326651._4
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
653653 getPositionNotionalAndUnrealizedPnlByValues(positionSize, positionOpenNotional, qtAstR(), qtAstW(), bsAstR(), bsAstW(), _option)
654654 }
655655
658658
659659
660660 func getMarginRatioByOption (_trader,_option) = {
661- let $t02716427275 = getPosition(_trader)
662- let positionSize = $t02716427275._1
663- let positionMargin = $t02716427275._2
664- let pon = $t02716427275._3
665- let positionLstUpdCPF = $t02716427275._4
666- let $t02728127374 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
667- let positionNotional = $t02728127374._1
668- let unrealizedPnl = $t02728127374._2
669- let $t02737927545 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
670- let remainMargin = $t02737927545._1
671- let badDebt = $t02737927545._2
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
672672 calcMarginRatio(remainMargin, badDebt, positionNotional)
673673 }
674674
693693
694694
695695 func internalClosePosition (_trader,_checkMaxPriceImpact) = {
696- let $t02878528913 = getPosition(_trader)
697- let positionSize = $t02878528913._1
698- let positionMargin = $t02878528913._2
699- let positionOpenNotional = $t02878528913._3
700- let positionLstUpdCPF = $t02878528913._4
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
701701 let unrealizedPnl = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)._2
702- let $t02900829176 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
703- let remainMargin = $t02900829176._1
704- let badDebt = $t02900829176._2
702+ let $t02914029308 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
703+ let remainMargin = $t02914029308._1
704+ let badDebt = $t02914029308._2
705705 let exchangedPositionSize = -(positionSize)
706706 let realizedPnl = unrealizedPnl
707707 let marginToVault = -(remainMargin)
708- let $t02930329577 = swapOutput((positionSize > 0), abs(positionSize), _checkMaxPriceImpact)
709- let exchangedQuoteAssetAmount = $t02930329577._1
710- let quoteAssetReserveAfter = $t02930329577._2
711- let baseAssetReserveAfter = $t02930329577._3
712- let totalPositionSizeAfter = $t02930329577._4
713- let totalLongAfter = $t02930329577._5
714- let totalShortAfter = $t02930329577._6
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
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 $t03170031879 = swapOutput(direction, abs(_positionSize), false)
768- let currentNetMarketValue = $t03170031879._1
769- let terminalQuoteAssetReserve = $t03170031879._2
770- let terminalBaseAssetReserve = $t03170031879._3
767+ let $t03183232011 = swapOutput(direction, abs(_positionSize), false)
768+ let currentNetMarketValue = $t03183232011._1
769+ let terminalQuoteAssetReserve = $t03183232011._2
770+ let terminalBaseAssetReserve = $t03183232011._3
771771 $Tuple2(terminalQuoteAssetReserve, terminalBaseAssetReserve)
772772 }
773773 }
836836 func getAdjustedFee (_artifactId,_baseFeeDiscount) = {
837837 let baseFeeRaw = fee()
838838 let baseFee = muld(baseFeeRaw, _baseFeeDiscount)
839- let $t03492735422 = if ((_artifactId != ""))
839+ let $t03505935554 = if ((_artifactId != ""))
840840 then {
841841 let artifactKind = strA(nftManagerAddress(), toCompositeKey(k_token_type, _artifactId))
842842 if ((artifactKind == FEE_REDUCTION_TOKEN_TYPE))
848848 else throw("Invalid attached artifact")
849849 }
850850 else $Tuple2(baseFee, false)
851- let adjustedFee = $t03492735422._1
852- let burnArtifact = $t03492735422._2
851+ let adjustedFee = $t03505935554._1
852+ let burnArtifact = $t03505935554._2
853853 $Tuple2(adjustedFee, burnArtifact)
854854 }
855855
890890 case _ =>
891891 throw("Invalid computeFeeDiscount result")
892892 }
893- let $t03665336727 = getAdjustedFee(_artifactId, feeDiscount)
894- let adjustedFee = $t03665336727._1
895- let burnArtifact = $t03665336727._2
893+ let $t03678536859 = getAdjustedFee(_artifactId, feeDiscount)
894+ let adjustedFee = $t03678536859._1
895+ let burnArtifact = $t03678536859._2
896896 $Tuple2(adjustedFee, burnArtifact)
897897 }
898898 else throw("Strict value is not equal to itself.")
10431043 let qtAstRAfter = (_qtAstR + _quoteAssetAmount)
10441044 let baseAssetAmountToAdd = (divd(muld(qtAstRAfter, _qtAstW), price) - _bsAstR)
10451045 let bsAstRAfter = (_bsAstR + baseAssetAmountToAdd)
1046- let $t04574945900 = getSyncTerminalPrice(getOraclePrice(), qtAstRAfter, bsAstRAfter)
1047- let newQuoteAssetWeight = $t04574945900._1
1048- let newBaseAssetWeight = $t04574945900._2
1049- let marginToVault = $t04574945900._3
1046+ let $t04588146032 = getSyncTerminalPrice(getOraclePrice(), qtAstRAfter, bsAstRAfter)
1047+ let newQuoteAssetWeight = $t04588146032._1
1048+ let newBaseAssetWeight = $t04588146032._2
1049+ let marginToVault = $t04588146032._3
10501050 let doExchangePnL = if ((marginToVault != 0))
10511051 then {
10521052 let doExchangePnL = invoke(vaultAddress(), "exchangeFreeAndLocked", [marginToVault], nil)
11441144 else isMarketClosed())
11451145 then throw("Invalid decreasePosition parameters")
11461146 else {
1147- let $t04976749907 = getPosition(_trader)
1148- let oldPositionSize = $t04976749907._1
1149- let oldPositionMargin = $t04976749907._2
1150- let oldPositionOpenNotional = $t04976749907._3
1151- let oldPositionLstUpdCPF = $t04976749907._4
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
11521152 let _direction = if ((oldPositionSize > 0))
11531153 then DIR_SHORT
11541154 else DIR_LONG
11551155 let isAdd = (_direction == DIR_LONG)
11561156 let openNotional = muld(_amount, _leverage)
1157- let $t05008050184 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1158- let oldPositionNotional = $t05008050184._1
1159- let unrealizedPnl = $t05008050184._2
1160- let $t05019052832 = if ((oldPositionNotional > openNotional))
1157+ let $t05021250316 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1158+ let oldPositionNotional = $t05021250316._1
1159+ let unrealizedPnl = $t05021250316._2
1160+ let $t05032252964 = if ((oldPositionNotional > openNotional))
11611161 then {
1162- let $t05060550789 = swapInput(isAdd, openNotional)
1163- let exchangedPositionSize = $t05060550789._1
1164- let quoteAssetReserveAfter = $t05060550789._2
1165- let baseAssetReserveAfter = $t05060550789._3
1166- let totalPositionSizeAfter = $t05060550789._4
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
11671167 let exchangedPositionSizeAbs = abs(exchangedPositionSize)
11681168 if (if ((_minBaseAssetAmount != 0))
11691169 then (_minBaseAssetAmount > exchangedPositionSizeAbs)
11711171 then throw(((("Too little base asset exchanged, got " + toString(exchangedPositionSizeAbs)) + " expected ") + toString(_minBaseAssetAmount)))
11721172 else {
11731173 let realizedPnl = divd(muld(unrealizedPnl, exchangedPositionSizeAbs), abs(oldPositionSize))
1174- let $t05122651455 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1175- let remainMargin = $t05122651455._1
1176- let badDebt = $t05122651455._2
1174+ let $t05135851587 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1175+ let remainMargin = $t05135851587._1
1176+ let badDebt = $t05135851587._2
11771177 let exchangedQuoteAssetAmount = openNotional
11781178 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
11791179 let remainOpenNotional = if ((oldPositionSize > 0))
11921192 }
11931193 }
11941194 else throw("Close position first")
1195- let newPositionSize = $t05019052832._1
1196- let newPositionRemainMargin = $t05019052832._2
1197- let newPositionOpenNotional = $t05019052832._3
1198- let newPositionLatestCPF = $t05019052832._4
1199- let baseAssetReserveAfter = $t05019052832._5
1200- let quoteAssetReserveAfter = $t05019052832._6
1201- let totalPositionSizeAfter = $t05019052832._7
1202- let openInterestNotionalAfter = $t05019052832._8
1203- let totalLongAfter = $t05019052832._9
1204- let totalShortAfter = $t05019052832._10
1205- let totalLongOpenInterestAfter = $t05019052832._11
1206- let totalShortOpenInterestAfter = $t05019052832._12
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
12071207 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, newPositionOpenNotional], nil)
12081208 if ((notifyNotional == notifyNotional))
12091209 then (updatePosition(_trader, newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter))
12491249 else isMarketClosed())
12501250 then throw("Invalid increasePosition parameters")
12511251 else {
1252- let $t05429454379 = getForTraderWithArtifact(_trader, getArtifactId(i))
1253- let adjustedFee = $t05429454379._1
1254- let burnArtifact = $t05429454379._2
1252+ let $t05442654511 = getForTraderWithArtifact(_trader, getArtifactId(i))
1253+ let adjustedFee = $t05442654511._1
1254+ let burnArtifact = $t05442654511._2
12551255 let rawFeeAmount = muld(_rawAmount, adjustedFee)
12561256 let _amount = (_rawAmount - rawFeeAmount)
12571257 let distributeFeeAmount = if (isCollateralAsset)
12941294 throw("Invalid referrerFee")
12951295 }
12961296 let feeAmount = (distributeFeeAmount - referrerFee)
1297- let $t05569555835 = getPosition(_trader)
1298- let oldPositionSize = $t05569555835._1
1299- let oldPositionMargin = $t05569555835._2
1300- let oldPositionOpenNotional = $t05569555835._3
1301- let oldPositionLstUpdCPF = $t05569555835._4
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
13021302 let isNewPosition = (oldPositionSize == 0)
13031303 let isSameDirection = if ((oldPositionSize > 0))
13041304 then (_direction == DIR_LONG)
13071307 then isSameDirection
13081308 else false
13091309 let isAdd = (_direction == DIR_LONG)
1310- let $t05612459165 = if (if (isNewPosition)
1310+ let $t05625659297 = if (if (isNewPosition)
13111311 then true
13121312 else expandExisting)
13131313 then {
13141314 let openNotional = muld(_amount, _leverage)
1315- let $t05658656759 = swapInput(isAdd, openNotional)
1316- let amountBaseAssetBought = $t05658656759._1
1317- let quoteAssetReserveAfter = $t05658656759._2
1318- let baseAssetReserveAfter = $t05658656759._3
1319- let totalPositionSizeAfter = $t05658656759._4
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
13201320 if (if ((_minBaseAssetAmount != 0))
13211321 then (_minBaseAssetAmount > abs(amountBaseAssetBought))
13221322 else false)
13301330 then openNotional
13311331 else 0))
13321332 let increaseMarginRequirement = divd(openNotional, _leverage)
1333- let $t05736757606 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
1334- let remainMargin = $t05736757606._1
1335- let x1 = $t05736757606._2
1336- let x2 = $t05736757606._3
1333+ let $t05749957738 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
1334+ let remainMargin = $t05749957738._1
1335+ let x1 = $t05749957738._2
1336+ let x2 = $t05749957738._3
13371337 if (!(requireNotOverSpreadLimit(quoteAssetReserveAfter, baseAssetReserveAfter)))
13381338 then throw("Over max spread limit")
13391339 else if (!(requireNotOverMaxOpenNotional(totalLongOpenInterestAfter, totalShortOpenInterestAfter)))
13471347 }
13481348 else {
13491349 let openNotional = muld(_amount, _leverage)
1350- let $t05886558981 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1351- let oldPositionNotional = $t05886558981._1
1352- let unrealizedPnl = $t05886558981._2
1350+ let $t05899759113 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1351+ let oldPositionNotional = $t05899759113._1
1352+ let unrealizedPnl = $t05899759113._2
13531353 if ((oldPositionNotional > openNotional))
13541354 then throw("Use decreasePosition to decrease position size")
13551355 else throw("Close position first")
13561356 }
1357- let newPositionSize = $t05612459165._1
1358- let newPositionRemainMargin = $t05612459165._2
1359- let newPositionOpenNotional = $t05612459165._3
1360- let newPositionLatestCPF = $t05612459165._4
1361- let baseAssetReserveAfter = $t05612459165._5
1362- let quoteAssetReserveAfter = $t05612459165._6
1363- let totalPositionSizeAfter = $t05612459165._7
1364- let openInterestNotionalAfter = $t05612459165._8
1365- let totalLongAfter = $t05612459165._9
1366- let totalShortAfter = $t05612459165._10
1367- let totalLongOpenInterestAfter = $t05612459165._11
1368- let totalShortOpenInterestAfter = $t05612459165._12
1369- let $t05917159228 = distributeFee(feeAmount)
1370- let feeToStakers = $t05917159228._1
1371- let feeToVault = $t05917159228._2
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
13721372 let stake = if (isQuoteAsset)
13731373 then {
13741374 let stake = invoke(vaultAddress(), "addLocked", [false], [AttachedPayment(quoteAsset(), _amount)])
14341434 else isMarketClosed())
14351435 then throw("Invalid addMargin parameters")
14361436 else {
1437- let $t06120061285 = getForTraderWithArtifact(_trader, getArtifactId(i))
1438- let adjustedFee = $t06120061285._1
1439- let burnArtifact = $t06120061285._2
1437+ let $t06133261417 = getForTraderWithArtifact(_trader, getArtifactId(i))
1438+ let adjustedFee = $t06133261417._1
1439+ let burnArtifact = $t06133261417._2
14401440 let rawFeeAmount = muld(_rawAmount, adjustedFee)
14411441 let _amount = (_rawAmount - rawFeeAmount)
14421442 let distributeFeeAmount = if (isCollateralAsset)
14791479 throw("Invalid referrerFee")
14801480 }
14811481 let feeAmount = (distributeFeeAmount - referrerFee)
1482- let $t06258462724 = getPosition(_trader)
1483- let oldPositionSize = $t06258462724._1
1484- let oldPositionMargin = $t06258462724._2
1485- let oldPositionOpenNotional = $t06258462724._3
1486- let oldPositionLstUpdCPF = $t06258462724._4
1487- let $t06273062787 = distributeFee(feeAmount)
1488- let feeToStakers = $t06273062787._1
1489- let feeToVault = $t06273062787._2
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
14901490 let stake = if (isQuoteAsset)
14911491 then {
14921492 let stake = invoke(vaultAddress(), "addLocked", [false], [AttachedPayment(quoteAsset(), _amount)])
15361536 else isMarketClosed())
15371537 then throw("Invalid removeMargin parameters")
15381538 else {
1539- let $t06392364063 = getPosition(_trader)
1540- let oldPositionSize = $t06392364063._1
1541- let oldPositionMargin = $t06392364063._2
1542- let oldPositionOpenNotional = $t06392364063._3
1543- let oldPositionLstUpdCPF = $t06392364063._4
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
15441544 let marginDelta = -(_amount)
1545- let $t06410064279 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1546- let remainMargin = $t06410064279._1
1547- let badDebt = $t06410064279._2
1545+ let $t06423264411 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1546+ let remainMargin = $t06423264411._1
1547+ let badDebt = $t06423264411._2
15481548 if ((badDebt != 0))
15491549 then throw("Invalid removed margin amount")
15501550 else {
15531553 then throw(((("Too much margin removed: " + toString(marginRatio)) + " < ") + toString(initMarginRatio())))
15541554 else {
15551555 let quoteAssetStr = toBase58String(quoteAsset())
1556- let $t06472364777 = getBorrowedByTrader(_trader)
1557- let borrowed = $t06472364777._1
1558- let assetId = $t06472364777._2
1556+ let $t06485564909 = getBorrowedByTrader(_trader)
1557+ let borrowed = $t06485564909._1
1558+ let assetId = $t06485564909._2
15591559 let toRepay = if ((_amount > borrowed))
15601560 then borrowed
15611561 else _amount
16271627 else isMarketClosed())
16281628 then throw("Invalid closePosition parameters")
16291629 else {
1630- let $t06696167101 = getPosition(_trader)
1631- let oldPositionSize = $t06696167101._1
1632- let oldPositionMargin = $t06696167101._2
1633- let oldPositionOpenNotional = $t06696167101._3
1634- let oldPositionLstUpdCPF = $t06696167101._4
1635- let $t06710772237 = if ((abs(oldPositionSize) > _size))
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))
16361636 then {
16371637 let _direction = if ((oldPositionSize > 0))
16381638 then DIR_SHORT
16391639 else DIR_LONG
16401640 let isAdd = (_direction == DIR_LONG)
1641- let $t06769867920 = swapOutput((oldPositionSize > 0), _size, true)
1642- let exchangedQuoteAssetAmount = $t06769867920._1
1643- let quoteAssetReserveAfter = $t06769867920._2
1644- let baseAssetReserveAfter = $t06769867920._3
1645- let totalPositionSizeAfter = $t06769867920._4
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
16461646 let exchangedPositionSize = if ((oldPositionSize > 0))
16471647 then -(_size)
16481648 else _size
1649- let $t06801168165 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1650- let oldPositionNotional = $t06801168165._1
1651- let unrealizedPnl = $t06801168165._2
1649+ let $t06814368297 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1650+ let oldPositionNotional = $t06814368297._1
1651+ let unrealizedPnl = $t06814368297._2
16521652 let mr = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
16531653 let realizedRatio = divd(abs(exchangedPositionSize), abs(oldPositionSize))
16541654 let realizedPnl = muld(unrealizedPnl, realizedRatio)
16551655 let remainMarginBefore = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, unrealizedPnl)._1
1656- let $t06866668894 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1657- let x1 = $t06866668894._1
1658- let positionBadDebt = $t06866668894._2
1659- let fundingPayment = $t06866668894._3
1656+ let $t06879869026 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1657+ let x1 = $t06879869026._1
1658+ let positionBadDebt = $t06879869026._2
1659+ let fundingPayment = $t06879869026._3
16601660 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
16611661 let remainOpenNotional = if ((oldPositionSize > 0))
16621662 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
16861686 else if ((_size > abs(oldPositionSize)))
16871687 then throw("Invalid closePosition parameters")
16881688 else {
1689- let $t07117871597 = internalClosePosition(_trader, true)
1690- let exchangedQuoteAssetAmount = $t07117871597._1
1691- let positionBadDebt = $t07117871597._2
1692- let realizedPnl = $t07117871597._3
1693- let marginToVault = $t07117871597._4
1694- let quoteAssetReserveAfter = $t07117871597._5
1695- let baseAssetReserveAfter = $t07117871597._6
1696- let totalPositionSizeAfter = $t07117871597._7
1697- let openInterestNotionalAfter = $t07117871597._8
1698- let x2 = $t07117871597._9
1699- let totalLongAfter = $t07117871597._10
1700- let totalShortAfter = $t07117871597._11
1701- let totalLongOpenInterestAfter = $t07117871597._12
1702- let totalShortOpenInterestAfter = $t07117871597._13
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
17031703 if (if ((_minQuoteAssetAmount != 0))
17041704 then (_minQuoteAssetAmount > exchangedQuoteAssetAmount)
17051705 else false)
17061706 then throw(((("Limit error: " + toString(exchangedQuoteAssetAmount)) + " < ") + toString(_minQuoteAssetAmount)))
17071707 else $Tuple15(0, 0, 0, 0, positionBadDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter)
17081708 }
1709- let newPositionSize = $t06710772237._1
1710- let newPositionMargin = $t06710772237._2
1711- let newPositionOpenNotional = $t06710772237._3
1712- let newPositionLstUpdCPF = $t06710772237._4
1713- let positionBadDebt = $t06710772237._5
1714- let realizedPnl = $t06710772237._6
1715- let marginToVault = $t06710772237._7
1716- let quoteAssetReserveAfter = $t06710772237._8
1717- let baseAssetReserveAfter = $t06710772237._9
1718- let totalPositionSizeAfter = $t06710772237._10
1719- let openInterestNotionalAfter = $t06710772237._11
1720- let totalLongAfter = $t06710772237._12
1721- let totalShortAfter = $t06710772237._13
1722- let totalLongOpenInterestAfter = $t06710772237._14
1723- let totalShortOpenInterestAfter = $t06710772237._15
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
17241724 if ((positionBadDebt > 0))
17251725 then throw("Unable to close position with bad debt")
17261726 else {
17271727 let withdrawAmount = abs(marginToVault)
17281728 let ammBalance = (cbalance() - withdrawAmount)
1729- let $t07244672653 = if ((0 > ammBalance))
1729+ let $t07257872785 = if ((0 > ammBalance))
17301730 then $Tuple2(0, abs(ammBalance))
17311731 else $Tuple2(ammBalance, 0)
1732- let ammNewBalance = $t07244672653._1
1733- let x11 = $t07244672653._2
1734- let $t07266072714 = getBorrowedByTrader(_trader)
1735- let borrowed = $t07266072714._1
1736- let assetId = $t07266072714._2
1737- let $t07272973588 = if ((borrowed > 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))
17381738 then if ((withdrawAmount >= borrowed))
17391739 then {
17401740 let doRepay = invoke(collateralAddress(), "repay", [_trader, borrowed, assetId], nil)
17491749 else throw("Strict value is not equal to itself.")
17501750 }
17511751 else $Tuple2(nil, withdrawAmount)
1752- if (($t07272973588 == $t07272973588))
1752+ if (($t07286173720 == $t07286173720))
17531753 then {
1754- let quoteWithdrawAmount = $t07272973588._2
1755- let sendCollateralAction = $t07272973588._1
1754+ let quoteWithdrawAmount = $t07286173720._2
1755+ let sendCollateralAction = $t07286173720._1
17561756 let unstake = if ((quoteWithdrawAmount > 0))
17571757 then {
17581758 let unstake = invoke(vaultAddress(), "withdrawLocked", [quoteWithdrawAmount], nil)
18111811 then (DECIMAL_UNIT > partialLiquidationRatio())
18121812 else false)
18131813 then {
1814- let $t07590976059 = getPosition(_trader)
1815- let oldPositionSize = $t07590976059._1
1816- let oldPositionMargin = $t07590976059._2
1817- let oldPositionOpenNotional = $t07590976059._3
1818- let oldPositionLstUpdCPF = $t07590976059._4
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
18191819 let _direction = if ((oldPositionSize > 0))
18201820 then DIR_SHORT
18211821 else DIR_LONG
18221822 let isAdd = (_direction == DIR_LONG)
18231823 let exchangedQuoteAssetAmount = getPartialLiquidationAmount(_trader, oldPositionSize)
1824- let $t07628476388 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1825- let oldPositionNotional = $t07628476388._1
1826- let unrealizedPnl = $t07628476388._2
1827- let $t07639676583 = swapInput(isAdd, exchangedQuoteAssetAmount)
1828- let exchangedPositionSize = $t07639676583._1
1829- let quoteAssetReserveAfter = $t07639676583._2
1830- let baseAssetReserveAfter = $t07639676583._3
1831- let totalPositionSizeAfter = $t07639676583._4
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
18321832 let liquidationRatio = divd(abs(exchangedPositionSize), abs(oldPositionSize))
18331833 let realizedPnl = muld(unrealizedPnl, liquidationRatio)
1834- let $t07687277105 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1835- let remainMargin = $t07687277105._1
1836- let badDebt = $t07687277105._2
1837- let fundingPayment = $t07687277105._3
1834+ let $t07700477237 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1835+ let remainMargin = $t07700477237._1
1836+ let badDebt = $t07700477237._2
1837+ let fundingPayment = $t07700477237._3
18381838 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
18391839 let remainOpenNotional = if ((oldPositionSize > 0))
18401840 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
18491849 let newPositionLstUpdCPF = latestCumulativePremiumFraction(newPositionSize)
18501850 let openInterestNotionalAfter = (openInterestNotional() - openNotionalDelta)
18511851 let ammBalance = (cbalance() - liquidationPenalty)
1852- let $t07834678475 = if ((0 > ammBalance))
1852+ let $t07847878607 = if ((0 > ammBalance))
18531853 then $Tuple2(0, abs(ammBalance))
18541854 else $Tuple2(ammBalance, 0)
1855- let newAmmBalance = $t07834678475._1
1856- let x11 = $t07834678475._2
1857- let $t07848378537 = getBorrowedByTrader(_trader)
1858- let borrowed = $t07848378537._1
1859- let assetId = $t07848378537._2
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
18601860 let doLiquidateCollateral = if ((borrowed > 0))
18611861 then {
18621862 let collateralToSell = muld(borrowed, liquidationRatio)
18941894 else throw("Strict value is not equal to itself.")
18951895 }
18961896 else {
1897- let $t08021680711 = internalClosePosition(_trader, false)
1898- let x1 = $t08021680711._1
1899- let badDebt = $t08021680711._2
1900- let x2 = $t08021680711._3
1901- let x3 = $t08021680711._4
1902- let quoteAssetReserveAfter = $t08021680711._5
1903- let baseAssetReserveAfter = $t08021680711._6
1904- let totalPositionSizeAfter = $t08021680711._7
1905- let openInterestNotionalAfter = $t08021680711._8
1906- let exchangedQuoteAssetAmount = $t08021680711._9
1907- let totalLongAfter = $t08021680711._10
1908- let totalShortAfter = $t08021680711._11
1909- let totalLongOpenInterestAfter = $t08021680711._12
1910- let totalShortOpenInterestAfter = $t08021680711._13
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
19111911 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
19121912 let feeToLiquidator = (liquidationPenalty / 2)
19131913 let feeToVault = (liquidationPenalty - feeToLiquidator)
19141914 let ammBalance = (cbalance() - liquidationPenalty)
1915- let $t08111981248 = if ((0 > ammBalance))
1915+ let $t08125181380 = if ((0 > ammBalance))
19161916 then $Tuple2(0, abs(ammBalance))
19171917 else $Tuple2(ammBalance, 0)
1918- let newAmmBalance = $t08111981248._1
1919- let x11 = $t08111981248._2
1920- let $t08125681310 = getBorrowedByTrader(_trader)
1921- let borrowed = $t08125681310._1
1922- let assetId = $t08125681310._2
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
19231923 let doLiquidateCollateral = if ((borrowed > 0))
19241924 then {
19251925 let realizeAndClose = invoke(collateralAddress(), "realizePartiallyAndClose", [_trader, 0, assetId], nil)
19791979 then throw(((("Invalid funding block timestamp: " + toString(lastBlock.timestamp)) + " < ") + toString(fundingBlockTimestamp)))
19801980 else {
19811981 let underlyingPrice = getOraclePrice()
1982- let $t08318283244 = getFunding()
1983- let shortPremiumFraction = $t08318283244._1
1984- let longPremiumFraction = $t08318283244._2
1982+ let $t08331483376 = getFunding()
1983+ let shortPremiumFraction = $t08331483376._1
1984+ let longPremiumFraction = $t08331483376._2
19851985 updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), divd(longPremiumFraction, underlyingPrice), divd(shortPremiumFraction, underlyingPrice))
19861986 }
19871987 }
19941994 func syncTerminalPriceToOracle () = {
19951995 let _qtAstR = qtAstR()
19961996 let _bsAstR = bsAstR()
1997- let $t08367683811 = getSyncTerminalPrice(getOraclePrice(), _qtAstR, _bsAstR)
1998- let newQuoteAssetWeight = $t08367683811._1
1999- let newBaseAssetWeight = $t08367683811._2
2000- let marginToVault = $t08367683811._3
1997+ let $t08380883943 = getSyncTerminalPrice(getOraclePrice(), _qtAstR, _bsAstR)
1998+ let newQuoteAssetWeight = $t08380883943._1
1999+ let newBaseAssetWeight = $t08380883943._2
2000+ let marginToVault = $t08380883943._3
20012001 let doExchangePnL = if ((marginToVault != 0))
20022002 then {
20032003 let doExchangePnL = invoke(vaultAddress(), "exchangeFreeAndLocked", [marginToVault], nil)
20182018 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
20192019 if ((sync == sync))
20202020 then {
2021- let $t08438084481 = getPosition(_trader)
2022- let positionSize = $t08438084481._1
2023- let positionMargin = $t08438084481._2
2024- let pon = $t08438084481._3
2025- let positionLstUpdCPF = $t08438084481._4
2026- let $t08448484585 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
2027- let positionNotional = $t08448484585._1
2028- let unrealizedPnl = $t08448484585._2
2029- let $t08458884760 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
2030- let remainMargin = $t08458884760._1
2031- let badDebt = $t08458884760._2
2032- let fundingPayment = $t08458884760._3
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
20332033 throw((((((s(remainMargin) + s(fundingPayment)) + s(getMarginRatio(_trader))) + s(unrealizedPnl)) + s(badDebt)) + s(positionNotional)))
20342034 }
20352035 else throw("Strict value is not equal to itself.")
20492049
20502050 @Callable(i)
20512051 func view_getTerminalAmmPrice () = {
2052- let $t08517685257 = getTerminalAmmState()
2053- let terminalQuoteAssetReserve = $t08517685257._1
2054- let terminalBaseAssetReserve = $t08517685257._2
2052+ let $t08530885389 = getTerminalAmmState()
2053+ let terminalQuoteAssetReserve = $t08530885389._1
2054+ let terminalBaseAssetReserve = $t08530885389._2
20552055 let price = divd(muld(terminalQuoteAssetReserve, qtAstW()), muld(terminalBaseAssetReserve, bsAstW()))
20562056 throw(toString(price))
20572057 }
20612061 @Callable(i)
20622062 func view_getFunding () = {
20632063 let underlyingPrice = getOraclePrice()
2064- let $t08547285534 = getFunding()
2065- let shortPremiumFraction = $t08547285534._1
2066- let longPremiumFraction = $t08547285534._2
2064+ let $t08560485666 = getFunding()
2065+ let shortPremiumFraction = $t08560485666._1
2066+ let longPremiumFraction = $t08560485666._2
20672067 let longFunding = divd(longPremiumFraction, underlyingPrice)
20682068 let shortFunding = divd(shortPremiumFraction, underlyingPrice)
20692069 throw((((s(longFunding) + s(shortFunding)) + s(getTwapSpotPrice())) + s(getOraclePrice())))
20732073
20742074 @Callable(i)
20752075 func view_getBorrowedByTrader (_trader) = {
2076- let $t08582085874 = getBorrowedByTrader(_trader)
2077- let borrowed = $t08582085874._1
2078- let assetId = $t08582085874._2
2076+ let $t08595286006 = getBorrowedByTrader(_trader)
2077+ let borrowed = $t08595286006._1
2078+ let assetId = $t08595286006._2
20792079 throw((s(borrowed) + assetId))
20802080 }
20812081
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)
384- then throw("Invalid margin")
384+ then throw(((("Invalid margin: " + toString(_marginRatio)) + " < ") + toString(_baseMarginRatio)))
385385 else if (if (!(_largerThanOrEqualTo))
386386 then (remainingMarginRatio >= 0)
387387 else false)
388- then throw("Invalid margin")
388+ 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
451451 func calcInvariant (_qtAstR,_qtAstW,_bsAstR,_bsAstW) = {
452452 let bqtAstR = toBigInt(_qtAstR)
453453 let bqtAstW = toBigInt(_qtAstW)
454454 let bbsAstR = toBigInt(_bsAstR)
455455 let bbsAstW = toBigInt(_bsAstW)
456456 bmuld(bmuld(bqtAstR, bqtAstW), bmuld(bbsAstR, bbsAstW))
457457 }
458458
459459
460460 func swapInput (_isAdd,_quoteAssetAmount) = {
461461 let _qtAstR = qtAstR()
462462 let _bsAstR = bsAstR()
463463 let _qtAstW = qtAstW()
464464 let _bsAstW = bsAstW()
465465 let k = calcInvariant(_qtAstR, _qtAstW, _bsAstR, _bsAstW)
466466 let quoteAssetReserveAfter = if (_isAdd)
467467 then (_qtAstR + _quoteAssetAmount)
468468 else (_qtAstR - _quoteAssetAmount)
469469 let baseAssetReserveAfter = toInt(bdivd(k, toBigInt(muld(quoteAssetReserveAfter, _qtAstW))))
470470 let amountBaseAssetBoughtAbs = divd(abs((baseAssetReserveAfter - _bsAstR)), _qtAstW)
471471 let amountBaseAssetBought = if (_isAdd)
472472 then amountBaseAssetBoughtAbs
473473 else -(amountBaseAssetBoughtAbs)
474- let $t01680516968 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
475- let quoteAssetReserveAfter1 = $t01680516968._1
476- let baseAssetReserveAfter1 = $t01680516968._2
477- let totalPositionSizeAfter1 = $t01680516968._3
474+ let $t01693717100 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
475+ let quoteAssetReserveAfter1 = $t01693717100._1
476+ let baseAssetReserveAfter1 = $t01693717100._2
477+ let totalPositionSizeAfter1 = $t01693717100._3
478478 let priceBefore = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
479479 let marketPrice = divd(_quoteAssetAmount, amountBaseAssetBoughtAbs)
480480 let priceDiff = abs((priceBefore - marketPrice))
481481 let priceImpact = (DECIMAL_UNIT - divd(priceBefore, (priceBefore + priceDiff)))
482482 let maxPriceImpactValue = maxPriceImpact()
483483 if ((priceImpact > maxPriceImpactValue))
484484 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)))
485485 else $Tuple4(amountBaseAssetBought, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1)
486486 }
487487
488488
489489 func calcRemainMarginWithFundingPayment (_oldPositionSize,_oldPositionMargin,_oldPositionCumulativePremiumFraction,_marginDelta) = {
490490 let fundingPayment = if ((_oldPositionSize != 0))
491491 then {
492492 let _latestCumulativePremiumFraction = latestCumulativePremiumFraction(_oldPositionSize)
493493 muld((_latestCumulativePremiumFraction - _oldPositionCumulativePremiumFraction), _oldPositionSize)
494494 }
495495 else 0
496496 let signedMargin = ((_marginDelta - fundingPayment) + _oldPositionMargin)
497- let $t01845518582 = if ((0 > signedMargin))
497+ let $t01858718714 = if ((0 > signedMargin))
498498 then $Tuple2(0, abs(signedMargin))
499499 else $Tuple2(abs(signedMargin), 0)
500- let remainMargin = $t01845518582._1
501- let badDebt = $t01845518582._2
500+ let remainMargin = $t01858718714._1
501+ let badDebt = $t01858718714._2
502502 $Tuple3(remainMargin, badDebt, fundingPayment)
503503 }
504504
505505
506506 func swapOutputWithReserves (_isAdd,_baseAssetAmount,_checkMaxPriceImpact,_quoteAssetReserve,_quoteAssetWeight,_baseAssetReserve,_baseAssetWeight) = {
507507 let priceBefore = divd(muld(_quoteAssetReserve, _quoteAssetWeight), muld(_baseAssetReserve, _baseAssetWeight))
508508 if ((_baseAssetAmount == 0))
509509 then throw("Invalid base asset amount")
510510 else {
511511 let k = calcInvariant(_quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
512512 let baseAssetPoolAmountAfter = if (_isAdd)
513513 then (_baseAssetReserve + _baseAssetAmount)
514514 else (_baseAssetReserve - _baseAssetAmount)
515515 let quoteAssetAfter = toInt(bdivd(k, toBigInt(muld(baseAssetPoolAmountAfter, _baseAssetWeight))))
516516 let quoteAssetSold = abs((quoteAssetAfter - muld(_quoteAssetReserve, _quoteAssetWeight)))
517517 let maxPriceImpactValue = maxPriceImpact()
518- let $t01977019931 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
519- let quoteAssetReserveAfter1 = $t01977019931._1
520- let baseAssetReserveAfter1 = $t01977019931._2
521- let totalPositionSizeAfter1 = $t01977019931._3
518+ let $t01990220063 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
519+ let quoteAssetReserveAfter1 = $t01990220063._1
520+ let baseAssetReserveAfter1 = $t01990220063._2
521+ let totalPositionSizeAfter1 = $t01990220063._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 $t02488225102 = swapOutputWithReserves(!(isShort), positionSizeAbs, false, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
624- let outPositionNotional = $t02488225102._1
625- let x1 = $t02488225102._2
626- let x2 = $t02488225102._3
627- let x3 = $t02488225102._4
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
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 $t02652326651 = getPosition(_trader)
649- let positionSize = $t02652326651._1
650- let positionMargin = $t02652326651._2
651- let positionOpenNotional = $t02652326651._3
652- let positionLstUpdCPF = $t02652326651._4
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
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 $t02716427275 = getPosition(_trader)
662- let positionSize = $t02716427275._1
663- let positionMargin = $t02716427275._2
664- let pon = $t02716427275._3
665- let positionLstUpdCPF = $t02716427275._4
666- let $t02728127374 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
667- let positionNotional = $t02728127374._1
668- let unrealizedPnl = $t02728127374._2
669- let $t02737927545 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
670- let remainMargin = $t02737927545._1
671- let badDebt = $t02737927545._2
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
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 $t02878528913 = getPosition(_trader)
697- let positionSize = $t02878528913._1
698- let positionMargin = $t02878528913._2
699- let positionOpenNotional = $t02878528913._3
700- let positionLstUpdCPF = $t02878528913._4
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
701701 let unrealizedPnl = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)._2
702- let $t02900829176 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
703- let remainMargin = $t02900829176._1
704- let badDebt = $t02900829176._2
702+ let $t02914029308 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
703+ let remainMargin = $t02914029308._1
704+ let badDebt = $t02914029308._2
705705 let exchangedPositionSize = -(positionSize)
706706 let realizedPnl = unrealizedPnl
707707 let marginToVault = -(remainMargin)
708- let $t02930329577 = swapOutput((positionSize > 0), abs(positionSize), _checkMaxPriceImpact)
709- let exchangedQuoteAssetAmount = $t02930329577._1
710- let quoteAssetReserveAfter = $t02930329577._2
711- let baseAssetReserveAfter = $t02930329577._3
712- let totalPositionSizeAfter = $t02930329577._4
713- let totalLongAfter = $t02930329577._5
714- let totalShortAfter = $t02930329577._6
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
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 $t03170031879 = swapOutput(direction, abs(_positionSize), false)
768- let currentNetMarketValue = $t03170031879._1
769- let terminalQuoteAssetReserve = $t03170031879._2
770- let terminalBaseAssetReserve = $t03170031879._3
767+ let $t03183232011 = swapOutput(direction, abs(_positionSize), false)
768+ let currentNetMarketValue = $t03183232011._1
769+ let terminalQuoteAssetReserve = $t03183232011._2
770+ let terminalBaseAssetReserve = $t03183232011._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)
781781 let bs2 = bpowd((b + sz), toBigInt((2 * DECIMAL_UNIT)))
782782 let qbs2 = bmuld(q, bs2)
783783 let ps4 = (toBigInt(4) * bmuld(p, sz))
784784 let sqr = bsqrtd(bmuld(qbs2, (q - ps4)))
785785 let bq = bmuld(b, q)
786786 let qs = bmuld(q, sz)
787787 let top = ((-(sqr) + bq) + qs)
788788 let bot = (toBigInt(2) * bmuld(q, sz))
789789 let result = bdivd(top, bot)
790790 toInt(result)
791791 }
792792
793793
794794 func getSyncTerminalPrice (_terminalPrice,_qtAstR,_bsAstR) = {
795795 let _positionSize = totalPositionSize()
796796 if ((_positionSize == 0))
797797 then {
798798 let newQtAstW = divd(muld(_terminalPrice, _bsAstR), _qtAstR)
799799 $Tuple3(newQtAstW, DECIMAL_UNIT, 0)
800800 }
801801 else {
802802 let direction = (_positionSize > 0)
803803 let currentNetMarketValue = swapOutput(direction, abs(_positionSize), false)._1
804804 let newQtAstW = getQuoteAssetWeight(_bsAstR, _positionSize, _qtAstR, _terminalPrice)
805805 let newBsAstW = DECIMAL_UNIT
806806 let marginToVault = getPositionNotionalAndUnrealizedPnlByValues(_positionSize, currentNetMarketValue, _qtAstR, newQtAstW, _bsAstR, newBsAstW, PNL_OPTION_SPOT)._2
807807 $Tuple3(newQtAstW, newBsAstW, marginToVault)
808808 }
809809 }
810810
811811
812812 func getFunding () = {
813813 let underlyingPrice = getOraclePrice()
814814 let spotTwapPrice = getTwapSpotPrice()
815815 let premium = (spotTwapPrice - underlyingPrice)
816816 if (if (if ((totalShortPositionSize() == 0))
817817 then true
818818 else (totalLongPositionSize() == 0))
819819 then true
820820 else isMarketClosed())
821821 then $Tuple2(0, 0)
822822 else if ((0 > premium))
823823 then {
824824 let shortPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
825825 let longPremiumFraction = divd(muld(shortPremiumFraction, totalShortPositionSize()), totalLongPositionSize())
826826 $Tuple2(shortPremiumFraction, longPremiumFraction)
827827 }
828828 else {
829829 let longPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
830830 let shortPremiumFraction = divd(muld(longPremiumFraction, totalLongPositionSize()), totalShortPositionSize())
831831 $Tuple2(shortPremiumFraction, longPremiumFraction)
832832 }
833833 }
834834
835835
836836 func getAdjustedFee (_artifactId,_baseFeeDiscount) = {
837837 let baseFeeRaw = fee()
838838 let baseFee = muld(baseFeeRaw, _baseFeeDiscount)
839- let $t03492735422 = if ((_artifactId != ""))
839+ let $t03505935554 = if ((_artifactId != ""))
840840 then {
841841 let artifactKind = strA(nftManagerAddress(), toCompositeKey(k_token_type, _artifactId))
842842 if ((artifactKind == FEE_REDUCTION_TOKEN_TYPE))
843843 then {
844844 let reduction = intA(nftManagerAddress(), toCompositeKey(k_token_param, _artifactId))
845845 let adjustedFee = muld(baseFee, reduction)
846846 $Tuple2(adjustedFee, true)
847847 }
848848 else throw("Invalid attached artifact")
849849 }
850850 else $Tuple2(baseFee, false)
851- let adjustedFee = $t03492735422._1
852- let burnArtifact = $t03492735422._2
851+ let adjustedFee = $t03505935554._1
852+ let burnArtifact = $t03505935554._2
853853 $Tuple2(adjustedFee, burnArtifact)
854854 }
855855
856856
857857 func isSameAssetOrNoPosition (_trader,_assetId) = {
858858 let oldPositionSize = getPosition(_trader)._1
859859 if ((oldPositionSize == 0))
860860 then true
861861 else (getPositionAsset(_trader) == _assetId)
862862 }
863863
864864
865865 func isSameAsset (_trader,_assetId) = (getPositionAsset(_trader) == _assetId)
866866
867867
868868 func getBorrowedByTraderInMarketKey (_amm,_assetId,_trader) = ((((((k_trader_market_asset_collateral + "_") + _amm) + "_") + _assetId) + "_") + _trader)
869869
870870
871871 func getBorrowedByTrader (_trader) = {
872872 let positionAsset = getPositionAsset(_trader)
873873 if ((positionAsset == toBase58String(quoteAsset())))
874874 then $Tuple2(0, positionAsset)
875875 else {
876876 let key = getBorrowedByTraderInMarketKey(toString(this), positionAsset, _trader)
877877 let borrow = valueOrElse(getInteger(collateralAddress(), key), 0)
878878 $Tuple2(borrow, positionAsset)
879879 }
880880 }
881881
882882
883883 func getForTraderWithArtifact (_trader,_artifactId) = {
884884 let doGetFeeDiscount = invoke(minerAddress(), "computeFeeDiscount", [_trader], nil)
885885 if ((doGetFeeDiscount == doGetFeeDiscount))
886886 then {
887887 let feeDiscount = match doGetFeeDiscount {
888888 case x: Int =>
889889 x
890890 case _ =>
891891 throw("Invalid computeFeeDiscount result")
892892 }
893- let $t03665336727 = getAdjustedFee(_artifactId, feeDiscount)
894- let adjustedFee = $t03665336727._1
895- let burnArtifact = $t03665336727._2
893+ let $t03678536859 = getAdjustedFee(_artifactId, feeDiscount)
894+ let adjustedFee = $t03678536859._1
895+ let burnArtifact = $t03678536859._2
896896 $Tuple2(adjustedFee, burnArtifact)
897897 }
898898 else throw("Strict value is not equal to itself.")
899899 }
900900
901901
902902 func getArtifactId (i) = {
903903 let artifactId = if ((size(i.payments) > 1))
904904 then toBase58String(valueOrErrorMessage(i.payments[1].assetId, "Invalid artifactId"))
905905 else ""
906906 artifactId
907907 }
908908
909909
910910 func distributeFee (_feeAmount) = {
911911 let feeToStakers = muld(_feeAmount, feeToStakersPercent())
912912 let feeToVault = (_feeAmount - feeToStakers)
913913 $Tuple2(feeToStakers, feeToVault)
914914 }
915915
916916
917917 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)]
918918
919919
920920 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)]
921921
922922
923923 func updatePositionAsset (_address,_assetId) = [StringEntry(toCompositeKey(k_positionAsset, _address), _assetId)]
924924
925925
926926 func incrementPositionSequenceNumber (isNewPosition,_address) = if (isNewPosition)
927927 then {
928928 let currentSequence = lastSequence()
929929 [IntegerEntry(toCompositeKey(k_positionSequence, _address), (currentSequence + 1)), IntegerEntry(k_sequence, (currentSequence + 1))]
930930 }
931931 else nil
932932
933933
934934 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)]
935935
936936
937937 func appendTwap (_price) = {
938938 let minuteId = ((lastBlock.timestamp / 1000) / 60)
939939 let previousMinuteId = valueOrElse(getInteger(this, k_lastMinuteId), 0)
940940 if ((previousMinuteId > minuteId))
941941 then throw("TWAP out-of-order")
942942 else {
943943 let lastMinuteId = if ((previousMinuteId == 0))
944944 then minuteId
945945 else previousMinuteId
946946 if ((minuteId > previousMinuteId))
947947 then {
948948 let prevCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(previousMinuteId))), 0)
949949 let prevPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(previousMinuteId))), _price)
950950 let lastCumulativePrice = (prevCumulativePrice + ((minuteId - lastMinuteId) * prevPrice))
951951 let list = pushToQueue(strToList(valueOrElse(getString(this, k_lastDataStr), "")), TWAP_INTERVAL, toString(minuteId))
952952 [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))]
953953 }
954954 else {
955955 let twapDataPreviousMinuteId = valueOrElse(getInteger(this, toCompositeKey(k_twapDataPreviousMinuteId, toString(minuteId))), 0)
956956 let prevCumulativePrice = valueOrElse(getInteger(this, toCompositeKey(k_twapDataLastCumulativePrice, toString(twapDataPreviousMinuteId))), 0)
957957 let prevPrice = valueOrElse(getInteger(this, toCompositeKey(k_twapDataLastPrice, toString(twapDataPreviousMinuteId))), _price)
958958 let lastCumulativePrice = (prevCumulativePrice + ((minuteId - twapDataPreviousMinuteId) * prevPrice))
959959 [IntegerEntry(toCompositeKey(k_twapDataLastCumulativePrice, toString(minuteId)), lastCumulativePrice), IntegerEntry(toCompositeKey(k_twapDataLastPrice, toString(minuteId)), _price)]
960960 }
961961 }
962962 }
963963
964964
965965 func updateAmmReserves (_qtAstR,_bsAstR) = [IntegerEntry(k_quoteAssetReserve, _qtAstR), IntegerEntry(k_baseAssetReserve, _bsAstR)]
966966
967967
968968 func updateAmmWeights (_qtAstW,_bsAstW) = [IntegerEntry(k_quoteAssetWeight, _qtAstW), IntegerEntry(k_baseAssetWeight, _bsAstW)]
969969
970970
971971 func updateAmm (_qtAstR,_bsAstR,_totalPositionSizeAfter,_openInterestNotional,_totalLongPositionSize,_totalShortPositionSize,_totalLongOpenNotional,_totalShortOpenNotional) = {
972972 let _qtAstW = qtAstW()
973973 let _bsAstW = bsAstW()
974974 if (((_totalLongPositionSize - _totalShortPositionSize) != _totalPositionSizeAfter))
975975 then throw(((((("Invalid AMM state data: " + toString(_totalLongPositionSize)) + " + ") + toString(_totalShortPositionSize)) + " != ") + toString(_totalPositionSizeAfter)))
976976 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))))
977977 }
978978
979979
980980 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))]
981981
982982
983983 func withdraw (_address,_amount) = {
984984 let balance = assetBalance(this, quoteAsset())
985985 if ((_amount > balance))
986986 then throw(((("Unable to withdraw " + toString(_amount)) + " from contract balance ") + toString(balance)))
987987 else [ScriptTransfer(_address, _amount, quoteAsset())]
988988 }
989989
990990
991991 func updateBalance (i) = if ((0 > i))
992992 then throw("Balance")
993993 else [IntegerEntry(k_balance, i)]
994994
995995
996996 func transferFee (i) = [ScriptTransfer(stakingAddress(), i, quoteAsset())]
997997
998998
999999 func doBurnArtifact (_burnArtifact,i) = if (_burnArtifact)
10001000 then [Burn(valueOrErrorMessage(i.payments[1].assetId, "Invalid artifact"), 1)]
10011001 else nil
10021002
10031003
10041004 @Callable(i)
10051005 func pause () = if ((i.caller != adminAddress()))
10061006 then throw("Invalid pause params")
10071007 else [BooleanEntry(k_paused, true)]
10081008
10091009
10101010
10111011 @Callable(i)
10121012 func unpause () = if ((i.caller != adminAddress()))
10131013 then throw("Invalid unpause params")
10141014 else [BooleanEntry(k_paused, false)]
10151015
10161016
10171017
10181018 @Callable(i)
10191019 func setCloseOnly () = if ((i.caller != adminAddress()))
10201020 then throw("Invalid setCloseOnly params")
10211021 else [BooleanEntry(k_closeOnly, true)]
10221022
10231023
10241024
10251025 @Callable(i)
10261026 func unsetCloseOnly () = if ((i.caller != adminAddress()))
10271027 then throw("Invalid unsetCloseOnly params")
10281028 else [BooleanEntry(k_closeOnly, false)]
10291029
10301030
10311031
10321032 @Callable(i)
10331033 func addLiquidity (_quoteAssetAmount) = if (if ((i.caller != adminAddress()))
10341034 then true
10351035 else (0 >= _quoteAssetAmount))
10361036 then throw("Invalid addLiquidity params")
10371037 else {
10381038 let _qtAstR = qtAstR()
10391039 let _bsAstR = bsAstR()
10401040 let _qtAstW = qtAstW()
10411041 let _bsAstW = bsAstW()
10421042 let price = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
10431043 let qtAstRAfter = (_qtAstR + _quoteAssetAmount)
10441044 let baseAssetAmountToAdd = (divd(muld(qtAstRAfter, _qtAstW), price) - _bsAstR)
10451045 let bsAstRAfter = (_bsAstR + baseAssetAmountToAdd)
1046- let $t04574945900 = getSyncTerminalPrice(getOraclePrice(), qtAstRAfter, bsAstRAfter)
1047- let newQuoteAssetWeight = $t04574945900._1
1048- let newBaseAssetWeight = $t04574945900._2
1049- let marginToVault = $t04574945900._3
1046+ let $t04588146032 = getSyncTerminalPrice(getOraclePrice(), qtAstRAfter, bsAstRAfter)
1047+ let newQuoteAssetWeight = $t04588146032._1
1048+ let newBaseAssetWeight = $t04588146032._2
1049+ let marginToVault = $t04588146032._3
10501050 let doExchangePnL = if ((marginToVault != 0))
10511051 then {
10521052 let doExchangePnL = invoke(vaultAddress(), "exchangeFreeAndLocked", [marginToVault], nil)
10531053 if ((doExchangePnL == doExchangePnL))
10541054 then nil
10551055 else throw("Strict value is not equal to itself.")
10561056 }
10571057 else nil
10581058 if ((doExchangePnL == doExchangePnL))
10591059 then (updateAmmReserves(qtAstRAfter, bsAstRAfter) ++ updateAmmWeights(newQuoteAssetWeight, newBaseAssetWeight))
10601060 else throw("Strict value is not equal to itself.")
10611061 }
10621062
10631063
10641064
10651065 @Callable(i)
10661066 func removeLiquidity (_quoteAssetAmount) = if (if ((i.caller != adminAddress()))
10671067 then true
10681068 else (0 >= _quoteAssetAmount))
10691069 then throw("Invalid removeLiquidity params")
10701070 else {
10711071 let _qtAstR = qtAstR()
10721072 let _bsAstR = bsAstR()
10731073 let _qtAstW = qtAstW()
10741074 let _bsAstW = bsAstW()
10751075 let price = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
10761076 let baseAssetAmountToRemove = divd(_quoteAssetAmount, price)
10771077 let qtAstRAfter = (_qtAstR - _quoteAssetAmount)
10781078 let bsAstRAfter = (_bsAstR - baseAssetAmountToRemove)
10791079 updateAmmReserves(qtAstRAfter, bsAstRAfter)
10801080 }
10811081
10821082
10831083
10841084 @Callable(i)
10851085 func changeSettings (_initMarginRatio,_mmr,_liquidationFeeRatio,_fundingPeriod,_fee,_spreadLimit,_maxPriceImpact,_partialLiquidationRatio,_maxPriceSpread,_maxOpenNotional,_feeToStakersPercent,_maxOracleDelay) = if ((i.caller != adminAddress()))
10861086 then throw("Invalid changeSettings params")
10871087 else updateSettings(_initMarginRatio, _mmr, _liquidationFeeRatio, _fundingPeriod, _fee, _spreadLimit, _maxPriceImpact, _partialLiquidationRatio, _maxPriceSpread, _maxOpenNotional, _feeToStakersPercent, _maxOracleDelay)
10881088
10891089
10901090
10911091 @Callable(i)
10921092 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))
10931093 then true
10941094 else (0 >= _bsAstR))
10951095 then true
10961096 else (0 >= _fundingPeriod))
10971097 then true
10981098 else (0 >= _initMarginRatio))
10991099 then true
11001100 else (0 >= _mmr))
11011101 then true
11021102 else (0 >= _liquidationFeeRatio))
11031103 then true
11041104 else (0 >= _fee))
11051105 then true
11061106 else (0 >= _spreadLimit))
11071107 then true
11081108 else (0 >= _maxPriceImpact))
11091109 then true
11101110 else (0 >= _partialLiquidationRatio))
11111111 then true
11121112 else (0 >= _maxPriceSpread))
11131113 then true
11141114 else (0 >= _maxOpenNotional))
11151115 then true
11161116 else (0 >= _feeToStakersPercent))
11171117 then true
11181118 else (_feeToStakersPercent > DECIMAL_UNIT))
11191119 then true
11201120 else (0 >= _maxOracleDelay))
11211121 then true
11221122 else initialized())
11231123 then throw("Invalid initialize parameters")
11241124 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)])
11251125
11261126
11271127
11281128 @Callable(i)
11291129 func decreasePosition (_amount,_leverage,_minBaseAssetAmount) = {
11301130 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
11311131 if ((sync == sync))
11321132 then {
11331133 let _trader = getActualCaller(i)
11341134 if (if (if (if (if (if ((0 >= _amount))
11351135 then true
11361136 else !(initialized()))
11371137 then true
11381138 else !(requireMoreMarginRatio(divd(DECIMAL_UNIT, _leverage), initMarginRatio(), true)))
11391139 then true
11401140 else !(requireOpenPosition(_trader)))
11411141 then true
11421142 else paused())
11431143 then true
11441144 else isMarketClosed())
11451145 then throw("Invalid decreasePosition parameters")
11461146 else {
1147- let $t04976749907 = getPosition(_trader)
1148- let oldPositionSize = $t04976749907._1
1149- let oldPositionMargin = $t04976749907._2
1150- let oldPositionOpenNotional = $t04976749907._3
1151- let oldPositionLstUpdCPF = $t04976749907._4
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
11521152 let _direction = if ((oldPositionSize > 0))
11531153 then DIR_SHORT
11541154 else DIR_LONG
11551155 let isAdd = (_direction == DIR_LONG)
11561156 let openNotional = muld(_amount, _leverage)
1157- let $t05008050184 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1158- let oldPositionNotional = $t05008050184._1
1159- let unrealizedPnl = $t05008050184._2
1160- let $t05019052832 = if ((oldPositionNotional > openNotional))
1157+ let $t05021250316 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1158+ let oldPositionNotional = $t05021250316._1
1159+ let unrealizedPnl = $t05021250316._2
1160+ let $t05032252964 = if ((oldPositionNotional > openNotional))
11611161 then {
1162- let $t05060550789 = swapInput(isAdd, openNotional)
1163- let exchangedPositionSize = $t05060550789._1
1164- let quoteAssetReserveAfter = $t05060550789._2
1165- let baseAssetReserveAfter = $t05060550789._3
1166- let totalPositionSizeAfter = $t05060550789._4
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
11671167 let exchangedPositionSizeAbs = abs(exchangedPositionSize)
11681168 if (if ((_minBaseAssetAmount != 0))
11691169 then (_minBaseAssetAmount > exchangedPositionSizeAbs)
11701170 else false)
11711171 then throw(((("Too little base asset exchanged, got " + toString(exchangedPositionSizeAbs)) + " expected ") + toString(_minBaseAssetAmount)))
11721172 else {
11731173 let realizedPnl = divd(muld(unrealizedPnl, exchangedPositionSizeAbs), abs(oldPositionSize))
1174- let $t05122651455 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1175- let remainMargin = $t05122651455._1
1176- let badDebt = $t05122651455._2
1174+ let $t05135851587 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1175+ let remainMargin = $t05135851587._1
1176+ let badDebt = $t05135851587._2
11771177 let exchangedQuoteAssetAmount = openNotional
11781178 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
11791179 let remainOpenNotional = if ((oldPositionSize > 0))
11801180 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
11811181 else ((unrealizedPnlAfter + oldPositionNotional) - exchangedQuoteAssetAmount)
11821182 let newPositionSize = (oldPositionSize + exchangedPositionSize)
11831183 $Tuple12(newPositionSize, remainMargin, abs(remainOpenNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, (openInterestNotional() - openNotional), (totalLongPositionSize() - (if ((newPositionSize > 0))
11841184 then abs(exchangedPositionSize)
11851185 else 0)), (totalShortPositionSize() - (if ((0 > newPositionSize))
11861186 then abs(exchangedPositionSize)
11871187 else 0)), (openInterestLong() - (if ((newPositionSize > 0))
11881188 then openNotional
11891189 else 0)), (openInterestShort() - (if ((0 > newPositionSize))
11901190 then openNotional
11911191 else 0)))
11921192 }
11931193 }
11941194 else throw("Close position first")
1195- let newPositionSize = $t05019052832._1
1196- let newPositionRemainMargin = $t05019052832._2
1197- let newPositionOpenNotional = $t05019052832._3
1198- let newPositionLatestCPF = $t05019052832._4
1199- let baseAssetReserveAfter = $t05019052832._5
1200- let quoteAssetReserveAfter = $t05019052832._6
1201- let totalPositionSizeAfter = $t05019052832._7
1202- let openInterestNotionalAfter = $t05019052832._8
1203- let totalLongAfter = $t05019052832._9
1204- let totalShortAfter = $t05019052832._10
1205- let totalLongOpenInterestAfter = $t05019052832._11
1206- let totalShortOpenInterestAfter = $t05019052832._12
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
12071207 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, newPositionOpenNotional], nil)
12081208 if ((notifyNotional == notifyNotional))
12091209 then (updatePosition(_trader, newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter))
12101210 else throw("Strict value is not equal to itself.")
12111211 }
12121212 }
12131213 else throw("Strict value is not equal to itself.")
12141214 }
12151215
12161216
12171217
12181218 @Callable(i)
12191219 func increasePosition (_direction,_leverage,_minBaseAssetAmount,_refLink) = {
12201220 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
12211221 if ((sync == sync))
12221222 then {
12231223 let _trader = getActualCaller(i)
12241224 let _rawAmount = i.payments[0].amount
12251225 let _assetId = i.payments[0].assetId
12261226 let _assetIdStr = toBase58String(value(_assetId))
12271227 let isQuoteAsset = (_assetId == quoteAsset())
12281228 let isCollateralAsset = isWhitelistAsset(_assetIdStr)
12291229 if (if (if (if (if (if (if (if (if (if ((_direction != DIR_LONG))
12301230 then (_direction != DIR_SHORT)
12311231 else false)
12321232 then true
12331233 else (0 >= _rawAmount))
12341234 then true
12351235 else !(initialized()))
12361236 then true
12371237 else if (!(isQuoteAsset))
12381238 then !(isCollateralAsset)
12391239 else false)
12401240 then true
12411241 else !(isSameAssetOrNoPosition(_trader, _assetIdStr)))
12421242 then true
12431243 else !(requireMoreMarginRatio(divd(DECIMAL_UNIT, _leverage), initMarginRatio(), true)))
12441244 then true
12451245 else paused())
12461246 then true
12471247 else closeOnly())
12481248 then true
12491249 else isMarketClosed())
12501250 then throw("Invalid increasePosition parameters")
12511251 else {
1252- let $t05429454379 = getForTraderWithArtifact(_trader, getArtifactId(i))
1253- let adjustedFee = $t05429454379._1
1254- let burnArtifact = $t05429454379._2
1252+ let $t05442654511 = getForTraderWithArtifact(_trader, getArtifactId(i))
1253+ let adjustedFee = $t05442654511._1
1254+ let burnArtifact = $t05442654511._2
12551255 let rawFeeAmount = muld(_rawAmount, adjustedFee)
12561256 let _amount = (_rawAmount - rawFeeAmount)
12571257 let distributeFeeAmount = if (isCollateralAsset)
12581258 then {
12591259 let doBorrow = invoke(collateralAddress(), "borrow", [_trader], [AttachedPayment(_assetId, _amount)])
12601260 if ((doBorrow == doBorrow))
12611261 then {
12621262 let balanceBefore = assetBalance(this, quoteAsset())
12631263 if ((balanceBefore == balanceBefore))
12641264 then {
12651265 let doSwap = invoke(swapAddress(), "swap", [toBase58String(quoteAsset()), 0], [AttachedPayment(_assetId, rawFeeAmount)])
12661266 if ((doSwap == doSwap))
12671267 then {
12681268 let balanceAfter = assetBalance(this, quoteAsset())
12691269 if ((balanceAfter == balanceAfter))
12701270 then {
12711271 let exchangedAmount = (balanceAfter - balanceBefore)
12721272 if ((exchangedAmount == exchangedAmount))
12731273 then exchangedAmount
12741274 else throw("Strict value is not equal to itself.")
12751275 }
12761276 else throw("Strict value is not equal to itself.")
12771277 }
12781278 else throw("Strict value is not equal to itself.")
12791279 }
12801280 else throw("Strict value is not equal to itself.")
12811281 }
12821282 else throw("Strict value is not equal to itself.")
12831283 }
12841284 else rawFeeAmount
12851285 if ((distributeFeeAmount == distributeFeeAmount))
12861286 then {
12871287 let referrerFeeAny = invoke(referralAddress(), "acceptPaymentWithLink", [_trader, _refLink], [AttachedPayment(quoteAsset(), distributeFeeAmount)])
12881288 if ((referrerFeeAny == referrerFeeAny))
12891289 then {
12901290 let referrerFee = match referrerFeeAny {
12911291 case x: Int =>
12921292 x
12931293 case _ =>
12941294 throw("Invalid referrerFee")
12951295 }
12961296 let feeAmount = (distributeFeeAmount - referrerFee)
1297- let $t05569555835 = getPosition(_trader)
1298- let oldPositionSize = $t05569555835._1
1299- let oldPositionMargin = $t05569555835._2
1300- let oldPositionOpenNotional = $t05569555835._3
1301- let oldPositionLstUpdCPF = $t05569555835._4
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
13021302 let isNewPosition = (oldPositionSize == 0)
13031303 let isSameDirection = if ((oldPositionSize > 0))
13041304 then (_direction == DIR_LONG)
13051305 else (_direction == DIR_SHORT)
13061306 let expandExisting = if (!(isNewPosition))
13071307 then isSameDirection
13081308 else false
13091309 let isAdd = (_direction == DIR_LONG)
1310- let $t05612459165 = if (if (isNewPosition)
1310+ let $t05625659297 = if (if (isNewPosition)
13111311 then true
13121312 else expandExisting)
13131313 then {
13141314 let openNotional = muld(_amount, _leverage)
1315- let $t05658656759 = swapInput(isAdd, openNotional)
1316- let amountBaseAssetBought = $t05658656759._1
1317- let quoteAssetReserveAfter = $t05658656759._2
1318- let baseAssetReserveAfter = $t05658656759._3
1319- let totalPositionSizeAfter = $t05658656759._4
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
13201320 if (if ((_minBaseAssetAmount != 0))
13211321 then (_minBaseAssetAmount > abs(amountBaseAssetBought))
13221322 else false)
13231323 then throw(((("Limit error: " + toString(abs(amountBaseAssetBought))) + " < ") + toString(_minBaseAssetAmount)))
13241324 else {
13251325 let newPositionSize = (oldPositionSize + amountBaseAssetBought)
13261326 let totalLongOpenInterestAfter = (openInterestLong() + (if ((newPositionSize > 0))
13271327 then openNotional
13281328 else 0))
13291329 let totalShortOpenInterestAfter = (openInterestShort() + (if ((0 > newPositionSize))
13301330 then openNotional
13311331 else 0))
13321332 let increaseMarginRequirement = divd(openNotional, _leverage)
1333- let $t05736757606 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
1334- let remainMargin = $t05736757606._1
1335- let x1 = $t05736757606._2
1336- let x2 = $t05736757606._3
1333+ let $t05749957738 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
1334+ let remainMargin = $t05749957738._1
1335+ let x1 = $t05749957738._2
1336+ let x2 = $t05749957738._3
13371337 if (!(requireNotOverSpreadLimit(quoteAssetReserveAfter, baseAssetReserveAfter)))
13381338 then throw("Over max spread limit")
13391339 else if (!(requireNotOverMaxOpenNotional(totalLongOpenInterestAfter, totalShortOpenInterestAfter)))
13401340 then throw("Over max open notional")
13411341 else $Tuple12(newPositionSize, remainMargin, (oldPositionOpenNotional + openNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, (openInterestNotional() + openNotional), (totalLongPositionSize() + (if ((newPositionSize > 0))
13421342 then abs(amountBaseAssetBought)
13431343 else 0)), (totalShortPositionSize() + (if ((0 > newPositionSize))
13441344 then abs(amountBaseAssetBought)
13451345 else 0)), totalLongOpenInterestAfter, totalShortOpenInterestAfter)
13461346 }
13471347 }
13481348 else {
13491349 let openNotional = muld(_amount, _leverage)
1350- let $t05886558981 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1351- let oldPositionNotional = $t05886558981._1
1352- let unrealizedPnl = $t05886558981._2
1350+ let $t05899759113 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1351+ let oldPositionNotional = $t05899759113._1
1352+ let unrealizedPnl = $t05899759113._2
13531353 if ((oldPositionNotional > openNotional))
13541354 then throw("Use decreasePosition to decrease position size")
13551355 else throw("Close position first")
13561356 }
1357- let newPositionSize = $t05612459165._1
1358- let newPositionRemainMargin = $t05612459165._2
1359- let newPositionOpenNotional = $t05612459165._3
1360- let newPositionLatestCPF = $t05612459165._4
1361- let baseAssetReserveAfter = $t05612459165._5
1362- let quoteAssetReserveAfter = $t05612459165._6
1363- let totalPositionSizeAfter = $t05612459165._7
1364- let openInterestNotionalAfter = $t05612459165._8
1365- let totalLongAfter = $t05612459165._9
1366- let totalShortAfter = $t05612459165._10
1367- let totalLongOpenInterestAfter = $t05612459165._11
1368- let totalShortOpenInterestAfter = $t05612459165._12
1369- let $t05917159228 = distributeFee(feeAmount)
1370- let feeToStakers = $t05917159228._1
1371- let feeToVault = $t05917159228._2
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
13721372 let stake = if (isQuoteAsset)
13731373 then {
13741374 let stake = invoke(vaultAddress(), "addLocked", [false], [AttachedPayment(quoteAsset(), _amount)])
13751375 if ((stake == stake))
13761376 then nil
13771377 else throw("Strict value is not equal to itself.")
13781378 }
13791379 else nil
13801380 if ((stake == stake))
13811381 then {
13821382 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToVault)])
13831383 if ((depositInsurance == depositInsurance))
13841384 then {
13851385 let notifyFee = invoke(minerAddress(), "notifyFees", [_trader, feeAmount], nil)
13861386 if ((notifyFee == notifyFee))
13871387 then {
13881388 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, newPositionOpenNotional], nil)
13891389 if ((notifyNotional == notifyNotional))
13901390 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))
13911391 else throw("Strict value is not equal to itself.")
13921392 }
13931393 else throw("Strict value is not equal to itself.")
13941394 }
13951395 else throw("Strict value is not equal to itself.")
13961396 }
13971397 else throw("Strict value is not equal to itself.")
13981398 }
13991399 else throw("Strict value is not equal to itself.")
14001400 }
14011401 else throw("Strict value is not equal to itself.")
14021402 }
14031403 }
14041404 else throw("Strict value is not equal to itself.")
14051405 }
14061406
14071407
14081408
14091409 @Callable(i)
14101410 func addMargin () = {
14111411 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
14121412 if ((sync == sync))
14131413 then {
14141414 let _trader = toString(i.caller)
14151415 let _rawAmount = i.payments[0].amount
14161416 let _assetId = i.payments[0].assetId
14171417 let _assetIdStr = toBase58String(value(_assetId))
14181418 let isQuoteAsset = (_assetId == quoteAsset())
14191419 let isCollateralAsset = isWhitelistAsset(_assetIdStr)
14201420 if (if (if (if (if (if (if (if (!(isQuoteAsset))
14211421 then !(isCollateralAsset)
14221422 else false)
14231423 then true
14241424 else !(requireOpenPosition(toString(i.caller))))
14251425 then true
14261426 else !(isSameAsset(_trader, _assetIdStr)))
14271427 then true
14281428 else !(initialized()))
14291429 then true
14301430 else paused())
14311431 then true
14321432 else closeOnly())
14331433 then true
14341434 else isMarketClosed())
14351435 then throw("Invalid addMargin parameters")
14361436 else {
1437- let $t06120061285 = getForTraderWithArtifact(_trader, getArtifactId(i))
1438- let adjustedFee = $t06120061285._1
1439- let burnArtifact = $t06120061285._2
1437+ let $t06133261417 = getForTraderWithArtifact(_trader, getArtifactId(i))
1438+ let adjustedFee = $t06133261417._1
1439+ let burnArtifact = $t06133261417._2
14401440 let rawFeeAmount = muld(_rawAmount, adjustedFee)
14411441 let _amount = (_rawAmount - rawFeeAmount)
14421442 let distributeFeeAmount = if (isCollateralAsset)
14431443 then {
14441444 let doBorrow = invoke(collateralAddress(), "borrow", [_trader], [AttachedPayment(_assetId, _amount)])
14451445 if ((doBorrow == doBorrow))
14461446 then {
14471447 let balanceBefore = assetBalance(this, quoteAsset())
14481448 if ((balanceBefore == balanceBefore))
14491449 then {
14501450 let doSwap = invoke(swapAddress(), "swap", [toBase58String(quoteAsset()), 0], [AttachedPayment(_assetId, rawFeeAmount)])
14511451 if ((doSwap == doSwap))
14521452 then {
14531453 let balanceAfter = assetBalance(this, quoteAsset())
14541454 if ((balanceAfter == balanceAfter))
14551455 then {
14561456 let exchangedAmount = (balanceAfter - balanceBefore)
14571457 if ((exchangedAmount == exchangedAmount))
14581458 then exchangedAmount
14591459 else throw("Strict value is not equal to itself.")
14601460 }
14611461 else throw("Strict value is not equal to itself.")
14621462 }
14631463 else throw("Strict value is not equal to itself.")
14641464 }
14651465 else throw("Strict value is not equal to itself.")
14661466 }
14671467 else throw("Strict value is not equal to itself.")
14681468 }
14691469 else rawFeeAmount
14701470 if ((distributeFeeAmount == distributeFeeAmount))
14711471 then {
14721472 let referrerFeeAny = invoke(referralAddress(), "acceptPayment", [_trader], [AttachedPayment(quoteAsset(), distributeFeeAmount)])
14731473 if ((referrerFeeAny == referrerFeeAny))
14741474 then {
14751475 let referrerFee = match referrerFeeAny {
14761476 case x: Int =>
14771477 x
14781478 case _ =>
14791479 throw("Invalid referrerFee")
14801480 }
14811481 let feeAmount = (distributeFeeAmount - referrerFee)
1482- let $t06258462724 = getPosition(_trader)
1483- let oldPositionSize = $t06258462724._1
1484- let oldPositionMargin = $t06258462724._2
1485- let oldPositionOpenNotional = $t06258462724._3
1486- let oldPositionLstUpdCPF = $t06258462724._4
1487- let $t06273062787 = distributeFee(feeAmount)
1488- let feeToStakers = $t06273062787._1
1489- let feeToVault = $t06273062787._2
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
14901490 let stake = if (isQuoteAsset)
14911491 then {
14921492 let stake = invoke(vaultAddress(), "addLocked", [false], [AttachedPayment(quoteAsset(), _amount)])
14931493 if ((stake == stake))
14941494 then nil
14951495 else throw("Strict value is not equal to itself.")
14961496 }
14971497 else nil
14981498 if ((stake == stake))
14991499 then {
15001500 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToVault)])
15011501 if ((depositInsurance == depositInsurance))
15021502 then {
15031503 let notifyFee = invoke(minerAddress(), "notifyFees", [_trader, feeAmount], nil)
15041504 if ((notifyFee == notifyFee))
15051505 then (((updatePosition(_trader, oldPositionSize, (oldPositionMargin + _amount), oldPositionOpenNotional, oldPositionLstUpdCPF) ++ transferFee(feeToStakers)) ++ updateBalance((cbalance() + _amount))) ++ doBurnArtifact(burnArtifact, i))
15061506 else throw("Strict value is not equal to itself.")
15071507 }
15081508 else throw("Strict value is not equal to itself.")
15091509 }
15101510 else throw("Strict value is not equal to itself.")
15111511 }
15121512 else throw("Strict value is not equal to itself.")
15131513 }
15141514 else throw("Strict value is not equal to itself.")
15151515 }
15161516 }
15171517 else throw("Strict value is not equal to itself.")
15181518 }
15191519
15201520
15211521
15221522 @Callable(i)
15231523 func removeMargin (_amount) = {
15241524 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
15251525 if ((sync == sync))
15261526 then {
15271527 let _trader = toString(i.caller)
15281528 if (if (if (if (if ((0 >= _amount))
15291529 then true
15301530 else !(requireOpenPosition(_trader)))
15311531 then true
15321532 else !(initialized()))
15331533 then true
15341534 else paused())
15351535 then true
15361536 else isMarketClosed())
15371537 then throw("Invalid removeMargin parameters")
15381538 else {
1539- let $t06392364063 = getPosition(_trader)
1540- let oldPositionSize = $t06392364063._1
1541- let oldPositionMargin = $t06392364063._2
1542- let oldPositionOpenNotional = $t06392364063._3
1543- let oldPositionLstUpdCPF = $t06392364063._4
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
15441544 let marginDelta = -(_amount)
1545- let $t06410064279 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1546- let remainMargin = $t06410064279._1
1547- let badDebt = $t06410064279._2
1545+ let $t06423264411 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1546+ let remainMargin = $t06423264411._1
1547+ let badDebt = $t06423264411._2
15481548 if ((badDebt != 0))
15491549 then throw("Invalid removed margin amount")
15501550 else {
15511551 let marginRatio = calcMarginRatio(remainMargin, badDebt, oldPositionOpenNotional)
15521552 if (!(requireMoreMarginRatio(marginRatio, initMarginRatio(), true)))
15531553 then throw(((("Too much margin removed: " + toString(marginRatio)) + " < ") + toString(initMarginRatio())))
15541554 else {
15551555 let quoteAssetStr = toBase58String(quoteAsset())
1556- let $t06472364777 = getBorrowedByTrader(_trader)
1557- let borrowed = $t06472364777._1
1558- let assetId = $t06472364777._2
1556+ let $t06485564909 = getBorrowedByTrader(_trader)
1557+ let borrowed = $t06485564909._1
1558+ let assetId = $t06485564909._2
15591559 let toRepay = if ((_amount > borrowed))
15601560 then borrowed
15611561 else _amount
15621562 let toWithdraw = if ((borrowed > _amount))
15631563 then 0
15641564 else (_amount - borrowed)
15651565 let finalBorrow = (borrowed - toRepay)
15661566 let switchPositionToQuote = if ((finalBorrow > 0))
15671567 then nil
15681568 else updatePositionAsset(_trader, quoteAssetStr)
15691569 let doSanityCheck = if (((toRepay + toWithdraw) != _amount))
15701570 then throw(((((("toRepay=" + toString(toRepay)) + " + toWithdraw=") + toString(toWithdraw)) + " != ") + toString(_amount)))
15711571 else nil
15721572 if ((doSanityCheck == doSanityCheck))
15731573 then {
15741574 let doUnstake = if ((toWithdraw > 0))
15751575 then {
15761576 let doUnstake = invoke(vaultAddress(), "withdrawLocked", [toWithdraw], nil)
15771577 if ((doUnstake == doUnstake))
15781578 then nil
15791579 else throw("Strict value is not equal to itself.")
15801580 }
15811581 else nil
15821582 if ((doUnstake == doUnstake))
15831583 then {
15841584 let returnCollateralAction = if ((toRepay > 0))
15851585 then {
15861586 let doRepay = invoke(collateralAddress(), "repay", [_trader, toRepay, assetId], nil)
15871587 if ((doRepay == doRepay))
15881588 then [ScriptTransfer(i.caller, toRepay, fromBase58String(assetId))]
15891589 else throw("Strict value is not equal to itself.")
15901590 }
15911591 else nil
15921592 if ((returnCollateralAction == returnCollateralAction))
15931593 then ((((updatePosition(_trader, oldPositionSize, remainMargin, oldPositionOpenNotional, latestCumulativePremiumFraction(oldPositionSize)) ++ (if ((toWithdraw > 0))
15941594 then withdraw(i.caller, toWithdraw)
15951595 else nil)) ++ updateBalance((cbalance() - _amount))) ++ switchPositionToQuote) ++ returnCollateralAction)
15961596 else throw("Strict value is not equal to itself.")
15971597 }
15981598 else throw("Strict value is not equal to itself.")
15991599 }
16001600 else throw("Strict value is not equal to itself.")
16011601 }
16021602 }
16031603 }
16041604 }
16051605 else throw("Strict value is not equal to itself.")
16061606 }
16071607
16081608
16091609
16101610 @Callable(i)
16111611 func closePosition (_size,_minQuoteAssetAmount) = {
16121612 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
16131613 if ((sync == sync))
16141614 then {
16151615 let _trader = getActualCaller(i)
16161616 let _traderAddress = valueOrErrorMessage(addressFromString(_trader), "Invalid caller")
16171617 if (if (if (if (if (if (!(requireOpenPosition(_trader)))
16181618 then true
16191619 else !(initialized()))
16201620 then true
16211621 else paused())
16221622 then true
16231623 else (0 >= _size))
16241624 then true
16251625 else (0 > _minQuoteAssetAmount))
16261626 then true
16271627 else isMarketClosed())
16281628 then throw("Invalid closePosition parameters")
16291629 else {
1630- let $t06696167101 = getPosition(_trader)
1631- let oldPositionSize = $t06696167101._1
1632- let oldPositionMargin = $t06696167101._2
1633- let oldPositionOpenNotional = $t06696167101._3
1634- let oldPositionLstUpdCPF = $t06696167101._4
1635- let $t06710772237 = if ((abs(oldPositionSize) > _size))
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))
16361636 then {
16371637 let _direction = if ((oldPositionSize > 0))
16381638 then DIR_SHORT
16391639 else DIR_LONG
16401640 let isAdd = (_direction == DIR_LONG)
1641- let $t06769867920 = swapOutput((oldPositionSize > 0), _size, true)
1642- let exchangedQuoteAssetAmount = $t06769867920._1
1643- let quoteAssetReserveAfter = $t06769867920._2
1644- let baseAssetReserveAfter = $t06769867920._3
1645- let totalPositionSizeAfter = $t06769867920._4
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
16461646 let exchangedPositionSize = if ((oldPositionSize > 0))
16471647 then -(_size)
16481648 else _size
1649- let $t06801168165 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1650- let oldPositionNotional = $t06801168165._1
1651- let unrealizedPnl = $t06801168165._2
1649+ let $t06814368297 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1650+ let oldPositionNotional = $t06814368297._1
1651+ let unrealizedPnl = $t06814368297._2
16521652 let mr = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
16531653 let realizedRatio = divd(abs(exchangedPositionSize), abs(oldPositionSize))
16541654 let realizedPnl = muld(unrealizedPnl, realizedRatio)
16551655 let remainMarginBefore = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, unrealizedPnl)._1
1656- let $t06866668894 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1657- let x1 = $t06866668894._1
1658- let positionBadDebt = $t06866668894._2
1659- let fundingPayment = $t06866668894._3
1656+ let $t06879869026 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1657+ let x1 = $t06879869026._1
1658+ let positionBadDebt = $t06879869026._2
1659+ let fundingPayment = $t06879869026._3
16601660 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
16611661 let remainOpenNotional = if ((oldPositionSize > 0))
16621662 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
16631663 else ((unrealizedPnlAfter + oldPositionNotional) - exchangedQuoteAssetAmount)
16641664 let newPositionOpenNotional = abs(remainOpenNotional)
16651665 let newPositionMargin = if ((oldPositionSize > 0))
16661666 then (muld((newPositionOpenNotional + unrealizedPnlAfter), mr) - unrealizedPnlAfter)
16671667 else (muld((newPositionOpenNotional - unrealizedPnlAfter), mr) - unrealizedPnlAfter)
16681668 let openNotionalDelta = (oldPositionOpenNotional - newPositionOpenNotional)
16691669 let newPositionSize = (oldPositionSize + exchangedPositionSize)
16701670 let newPositionLstUpdCPF = latestCumulativePremiumFraction(newPositionSize)
16711671 let openInterestNotionalAfter = (openInterestNotional() - openNotionalDelta)
16721672 if (if ((_minQuoteAssetAmount != 0))
16731673 then (_minQuoteAssetAmount > exchangedQuoteAssetAmount)
16741674 else false)
16751675 then throw(((("Limit error: " + toString(exchangedQuoteAssetAmount)) + " < ") + toString(_minQuoteAssetAmount)))
16761676 else $Tuple15(newPositionSize, newPositionMargin, newPositionOpenNotional, newPositionLstUpdCPF, positionBadDebt, realizedPnl, (remainMarginBefore - (newPositionMargin + unrealizedPnlAfter)), quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, (totalLongPositionSize() - (if ((newPositionSize > 0))
16771677 then abs(exchangedPositionSize)
16781678 else 0)), (totalShortPositionSize() - (if ((0 > newPositionSize))
16791679 then abs(exchangedPositionSize)
16801680 else 0)), (openInterestLong() - (if ((newPositionSize > 0))
16811681 then openNotionalDelta
16821682 else 0)), (openInterestShort() - (if ((0 > newPositionSize))
16831683 then openNotionalDelta
16841684 else 0)))
16851685 }
16861686 else if ((_size > abs(oldPositionSize)))
16871687 then throw("Invalid closePosition parameters")
16881688 else {
1689- let $t07117871597 = internalClosePosition(_trader, true)
1690- let exchangedQuoteAssetAmount = $t07117871597._1
1691- let positionBadDebt = $t07117871597._2
1692- let realizedPnl = $t07117871597._3
1693- let marginToVault = $t07117871597._4
1694- let quoteAssetReserveAfter = $t07117871597._5
1695- let baseAssetReserveAfter = $t07117871597._6
1696- let totalPositionSizeAfter = $t07117871597._7
1697- let openInterestNotionalAfter = $t07117871597._8
1698- let x2 = $t07117871597._9
1699- let totalLongAfter = $t07117871597._10
1700- let totalShortAfter = $t07117871597._11
1701- let totalLongOpenInterestAfter = $t07117871597._12
1702- let totalShortOpenInterestAfter = $t07117871597._13
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
17031703 if (if ((_minQuoteAssetAmount != 0))
17041704 then (_minQuoteAssetAmount > exchangedQuoteAssetAmount)
17051705 else false)
17061706 then throw(((("Limit error: " + toString(exchangedQuoteAssetAmount)) + " < ") + toString(_minQuoteAssetAmount)))
17071707 else $Tuple15(0, 0, 0, 0, positionBadDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter)
17081708 }
1709- let newPositionSize = $t06710772237._1
1710- let newPositionMargin = $t06710772237._2
1711- let newPositionOpenNotional = $t06710772237._3
1712- let newPositionLstUpdCPF = $t06710772237._4
1713- let positionBadDebt = $t06710772237._5
1714- let realizedPnl = $t06710772237._6
1715- let marginToVault = $t06710772237._7
1716- let quoteAssetReserveAfter = $t06710772237._8
1717- let baseAssetReserveAfter = $t06710772237._9
1718- let totalPositionSizeAfter = $t06710772237._10
1719- let openInterestNotionalAfter = $t06710772237._11
1720- let totalLongAfter = $t06710772237._12
1721- let totalShortAfter = $t06710772237._13
1722- let totalLongOpenInterestAfter = $t06710772237._14
1723- let totalShortOpenInterestAfter = $t06710772237._15
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
17241724 if ((positionBadDebt > 0))
17251725 then throw("Unable to close position with bad debt")
17261726 else {
17271727 let withdrawAmount = abs(marginToVault)
17281728 let ammBalance = (cbalance() - withdrawAmount)
1729- let $t07244672653 = if ((0 > ammBalance))
1729+ let $t07257872785 = if ((0 > ammBalance))
17301730 then $Tuple2(0, abs(ammBalance))
17311731 else $Tuple2(ammBalance, 0)
1732- let ammNewBalance = $t07244672653._1
1733- let x11 = $t07244672653._2
1734- let $t07266072714 = getBorrowedByTrader(_trader)
1735- let borrowed = $t07266072714._1
1736- let assetId = $t07266072714._2
1737- let $t07272973588 = if ((borrowed > 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))
17381738 then if ((withdrawAmount >= borrowed))
17391739 then {
17401740 let doRepay = invoke(collateralAddress(), "repay", [_trader, borrowed, assetId], nil)
17411741 if ((doRepay == doRepay))
17421742 then $Tuple2([ScriptTransfer(_traderAddress, borrowed, fromBase58String(assetId))], (withdrawAmount - borrowed))
17431743 else throw("Strict value is not equal to itself.")
17441744 }
17451745 else {
17461746 let realizeAndClose = invoke(collateralAddress(), "realizePartiallyAndClose", [_trader, withdrawAmount, assetId], nil)
17471747 if ((realizeAndClose == realizeAndClose))
17481748 then $Tuple2([ScriptTransfer(_traderAddress, withdrawAmount, fromBase58String(assetId))], 0)
17491749 else throw("Strict value is not equal to itself.")
17501750 }
17511751 else $Tuple2(nil, withdrawAmount)
1752- if (($t07272973588 == $t07272973588))
1752+ if (($t07286173720 == $t07286173720))
17531753 then {
1754- let quoteWithdrawAmount = $t07272973588._2
1755- let sendCollateralAction = $t07272973588._1
1754+ let quoteWithdrawAmount = $t07286173720._2
1755+ let sendCollateralAction = $t07286173720._1
17561756 let unstake = if ((quoteWithdrawAmount > 0))
17571757 then {
17581758 let unstake = invoke(vaultAddress(), "withdrawLocked", [quoteWithdrawAmount], nil)
17591759 if ((unstake == unstake))
17601760 then nil
17611761 else throw("Strict value is not equal to itself.")
17621762 }
17631763 else nil
17641764 if ((unstake == unstake))
17651765 then {
17661766 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, 0], nil)
17671767 if ((notifyNotional == notifyNotional))
17681768 then (((((if ((newPositionSize == 0))
17691769 then deletePosition(_trader)
17701770 else updatePosition(_trader, newPositionSize, newPositionMargin, newPositionOpenNotional, newPositionLstUpdCPF)) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter)) ++ (if ((quoteWithdrawAmount > 0))
17711771 then withdraw(_traderAddress, quoteWithdrawAmount)
17721772 else nil)) ++ updateBalance(ammNewBalance)) ++ sendCollateralAction)
17731773 else throw("Strict value is not equal to itself.")
17741774 }
17751775 else throw("Strict value is not equal to itself.")
17761776 }
17771777 else throw("Strict value is not equal to itself.")
17781778 }
17791779 }
17801780 }
17811781 else throw("Strict value is not equal to itself.")
17821782 }
17831783
17841784
17851785
17861786 @Callable(i)
17871787 func liquidate (_trader) = {
17881788 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
17891789 if ((sync == sync))
17901790 then {
17911791 let spotMarginRatio = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
17921792 let marginRatio = if (isOverFluctuationLimit())
17931793 then {
17941794 let oracleMarginRatio = getMarginRatioByOption(_trader, PNL_OPTION_ORACLE)
17951795 vmax(spotMarginRatio, oracleMarginRatio)
17961796 }
17971797 else spotMarginRatio
17981798 if (if (if (if (if (!(requireMoreMarginRatio(marginRatio, maintenanceMarginRatio(), false)))
17991799 then true
18001800 else !(requireOpenPosition(_trader)))
18011801 then true
18021802 else !(initialized()))
18031803 then true
18041804 else paused())
18051805 then true
18061806 else isMarketClosed())
18071807 then throw("Unable to liquidate")
18081808 else if (if (if ((spotMarginRatio > liquidationFeeRatio()))
18091809 then (partialLiquidationRatio() > 0)
18101810 else false)
18111811 then (DECIMAL_UNIT > partialLiquidationRatio())
18121812 else false)
18131813 then {
1814- let $t07590976059 = getPosition(_trader)
1815- let oldPositionSize = $t07590976059._1
1816- let oldPositionMargin = $t07590976059._2
1817- let oldPositionOpenNotional = $t07590976059._3
1818- let oldPositionLstUpdCPF = $t07590976059._4
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
18191819 let _direction = if ((oldPositionSize > 0))
18201820 then DIR_SHORT
18211821 else DIR_LONG
18221822 let isAdd = (_direction == DIR_LONG)
18231823 let exchangedQuoteAssetAmount = getPartialLiquidationAmount(_trader, oldPositionSize)
1824- let $t07628476388 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1825- let oldPositionNotional = $t07628476388._1
1826- let unrealizedPnl = $t07628476388._2
1827- let $t07639676583 = swapInput(isAdd, exchangedQuoteAssetAmount)
1828- let exchangedPositionSize = $t07639676583._1
1829- let quoteAssetReserveAfter = $t07639676583._2
1830- let baseAssetReserveAfter = $t07639676583._3
1831- let totalPositionSizeAfter = $t07639676583._4
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
18321832 let liquidationRatio = divd(abs(exchangedPositionSize), abs(oldPositionSize))
18331833 let realizedPnl = muld(unrealizedPnl, liquidationRatio)
1834- let $t07687277105 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1835- let remainMargin = $t07687277105._1
1836- let badDebt = $t07687277105._2
1837- let fundingPayment = $t07687277105._3
1834+ let $t07700477237 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1835+ let remainMargin = $t07700477237._1
1836+ let badDebt = $t07700477237._2
1837+ let fundingPayment = $t07700477237._3
18381838 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
18391839 let remainOpenNotional = if ((oldPositionSize > 0))
18401840 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
18411841 else ((unrealizedPnlAfter + oldPositionNotional) - exchangedQuoteAssetAmount)
18421842 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
18431843 let feeToLiquidator = (liquidationPenalty / 2)
18441844 let feeToVault = (liquidationPenalty - feeToLiquidator)
18451845 let newPositionMargin = (remainMargin - liquidationPenalty)
18461846 let newPositionSize = (oldPositionSize + exchangedPositionSize)
18471847 let newPositionOpenNotional = abs(remainOpenNotional)
18481848 let openNotionalDelta = (oldPositionOpenNotional - newPositionOpenNotional)
18491849 let newPositionLstUpdCPF = latestCumulativePremiumFraction(newPositionSize)
18501850 let openInterestNotionalAfter = (openInterestNotional() - openNotionalDelta)
18511851 let ammBalance = (cbalance() - liquidationPenalty)
1852- let $t07834678475 = if ((0 > ammBalance))
1852+ let $t07847878607 = if ((0 > ammBalance))
18531853 then $Tuple2(0, abs(ammBalance))
18541854 else $Tuple2(ammBalance, 0)
1855- let newAmmBalance = $t07834678475._1
1856- let x11 = $t07834678475._2
1857- let $t07848378537 = getBorrowedByTrader(_trader)
1858- let borrowed = $t07848378537._1
1859- let assetId = $t07848378537._2
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
18601860 let doLiquidateCollateral = if ((borrowed > 0))
18611861 then {
18621862 let collateralToSell = muld(borrowed, liquidationRatio)
18631863 let realizeAndClose = invoke(collateralAddress(), "realizePartially", [_trader, assetId, collateralToSell], nil)
18641864 if ((realizeAndClose == realizeAndClose))
18651865 then nil
18661866 else throw("Strict value is not equal to itself.")
18671867 }
18681868 else nil
18691869 if ((doLiquidateCollateral == doLiquidateCollateral))
18701870 then {
18711871 let unstake = invoke(vaultAddress(), "withdrawLocked", [liquidationPenalty], nil)
18721872 if ((unstake == unstake))
18731873 then {
18741874 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToVault)])
18751875 if ((depositInsurance == depositInsurance))
18761876 then {
18771877 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, newPositionOpenNotional], nil)
18781878 if ((notifyNotional == notifyNotional))
18791879 then (((updatePosition(_trader, newPositionSize, newPositionMargin, newPositionOpenNotional, newPositionLstUpdCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, (totalLongPositionSize() - (if ((newPositionSize > 0))
18801880 then abs(exchangedPositionSize)
18811881 else 0)), (totalShortPositionSize() - (if ((0 > newPositionSize))
18821882 then abs(exchangedPositionSize)
18831883 else 0)), (openInterestLong() - (if ((newPositionSize > 0))
18841884 then openNotionalDelta
18851885 else 0)), (openInterestShort() - (if ((0 > newPositionSize))
18861886 then openNotionalDelta
18871887 else 0)))) ++ withdraw(i.caller, feeToLiquidator)) ++ updateBalance(newAmmBalance))
18881888 else throw("Strict value is not equal to itself.")
18891889 }
18901890 else throw("Strict value is not equal to itself.")
18911891 }
18921892 else throw("Strict value is not equal to itself.")
18931893 }
18941894 else throw("Strict value is not equal to itself.")
18951895 }
18961896 else {
1897- let $t08021680711 = internalClosePosition(_trader, false)
1898- let x1 = $t08021680711._1
1899- let badDebt = $t08021680711._2
1900- let x2 = $t08021680711._3
1901- let x3 = $t08021680711._4
1902- let quoteAssetReserveAfter = $t08021680711._5
1903- let baseAssetReserveAfter = $t08021680711._6
1904- let totalPositionSizeAfter = $t08021680711._7
1905- let openInterestNotionalAfter = $t08021680711._8
1906- let exchangedQuoteAssetAmount = $t08021680711._9
1907- let totalLongAfter = $t08021680711._10
1908- let totalShortAfter = $t08021680711._11
1909- let totalLongOpenInterestAfter = $t08021680711._12
1910- let totalShortOpenInterestAfter = $t08021680711._13
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
19111911 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
19121912 let feeToLiquidator = (liquidationPenalty / 2)
19131913 let feeToVault = (liquidationPenalty - feeToLiquidator)
19141914 let ammBalance = (cbalance() - liquidationPenalty)
1915- let $t08111981248 = if ((0 > ammBalance))
1915+ let $t08125181380 = if ((0 > ammBalance))
19161916 then $Tuple2(0, abs(ammBalance))
19171917 else $Tuple2(ammBalance, 0)
1918- let newAmmBalance = $t08111981248._1
1919- let x11 = $t08111981248._2
1920- let $t08125681310 = getBorrowedByTrader(_trader)
1921- let borrowed = $t08125681310._1
1922- let assetId = $t08125681310._2
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
19231923 let doLiquidateCollateral = if ((borrowed > 0))
19241924 then {
19251925 let realizeAndClose = invoke(collateralAddress(), "realizePartiallyAndClose", [_trader, 0, assetId], nil)
19261926 if ((realizeAndClose == realizeAndClose))
19271927 then nil
19281928 else throw("Strict value is not equal to itself.")
19291929 }
19301930 else nil
19311931 if ((doLiquidateCollateral == doLiquidateCollateral))
19321932 then {
19331933 let x = if ((badDebt > 0))
19341934 then {
19351935 let lockBadDebt = invoke(vaultAddress(), "exchangeFreeAndLocked", [badDebt], nil)
19361936 if ((lockBadDebt == lockBadDebt))
19371937 then nil
19381938 else throw("Strict value is not equal to itself.")
19391939 }
19401940 else nil
19411941 if ((x == x))
19421942 then {
19431943 let unstake = invoke(vaultAddress(), "withdrawLocked", [liquidationPenalty], nil)
19441944 if ((unstake == unstake))
19451945 then {
19461946 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToVault)])
19471947 if ((depositInsurance == depositInsurance))
19481948 then {
19491949 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, 0], nil)
19501950 if ((notifyNotional == notifyNotional))
19511951 then (((deletePosition(_trader) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter, totalLongOpenInterestAfter, totalShortOpenInterestAfter)) ++ withdraw(i.caller, feeToLiquidator)) ++ updateBalance(newAmmBalance))
19521952 else throw("Strict value is not equal to itself.")
19531953 }
19541954 else throw("Strict value is not equal to itself.")
19551955 }
19561956 else throw("Strict value is not equal to itself.")
19571957 }
19581958 else throw("Strict value is not equal to itself.")
19591959 }
19601960 else throw("Strict value is not equal to itself.")
19611961 }
19621962 }
19631963 else throw("Strict value is not equal to itself.")
19641964 }
19651965
19661966
19671967
19681968 @Callable(i)
19691969 func payFunding () = {
19701970 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
19711971 if ((sync == sync))
19721972 then {
19731973 let fundingBlockTimestamp = nextFundingBlockTimestamp()
19741974 if (if (if ((fundingBlockTimestamp > lastBlock.timestamp))
19751975 then true
19761976 else !(initialized()))
19771977 then true
19781978 else paused())
19791979 then throw(((("Invalid funding block timestamp: " + toString(lastBlock.timestamp)) + " < ") + toString(fundingBlockTimestamp)))
19801980 else {
19811981 let underlyingPrice = getOraclePrice()
1982- let $t08318283244 = getFunding()
1983- let shortPremiumFraction = $t08318283244._1
1984- let longPremiumFraction = $t08318283244._2
1982+ let $t08331483376 = getFunding()
1983+ let shortPremiumFraction = $t08331483376._1
1984+ let longPremiumFraction = $t08331483376._2
19851985 updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), divd(longPremiumFraction, underlyingPrice), divd(shortPremiumFraction, underlyingPrice))
19861986 }
19871987 }
19881988 else throw("Strict value is not equal to itself.")
19891989 }
19901990
19911991
19921992
19931993 @Callable(i)
19941994 func syncTerminalPriceToOracle () = {
19951995 let _qtAstR = qtAstR()
19961996 let _bsAstR = bsAstR()
1997- let $t08367683811 = getSyncTerminalPrice(getOraclePrice(), _qtAstR, _bsAstR)
1998- let newQuoteAssetWeight = $t08367683811._1
1999- let newBaseAssetWeight = $t08367683811._2
2000- let marginToVault = $t08367683811._3
1997+ let $t08380883943 = getSyncTerminalPrice(getOraclePrice(), _qtAstR, _bsAstR)
1998+ let newQuoteAssetWeight = $t08380883943._1
1999+ let newBaseAssetWeight = $t08380883943._2
2000+ let marginToVault = $t08380883943._3
20012001 let doExchangePnL = if ((marginToVault != 0))
20022002 then {
20032003 let doExchangePnL = invoke(vaultAddress(), "exchangeFreeAndLocked", [marginToVault], nil)
20042004 if ((doExchangePnL == doExchangePnL))
20052005 then nil
20062006 else throw("Strict value is not equal to itself.")
20072007 }
20082008 else nil
20092009 if ((doExchangePnL == doExchangePnL))
20102010 then (updateAmmWeights(newQuoteAssetWeight, newBaseAssetWeight) ++ appendTwap(divd(muld(_qtAstR, newQuoteAssetWeight), muld(_bsAstR, newBaseAssetWeight))))
20112011 else throw("Strict value is not equal to itself.")
20122012 }
20132013
20142014
20152015
20162016 @Callable(i)
20172017 func view_calcRemainMarginWithFundingPayment (_trader) = {
20182018 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
20192019 if ((sync == sync))
20202020 then {
2021- let $t08438084481 = getPosition(_trader)
2022- let positionSize = $t08438084481._1
2023- let positionMargin = $t08438084481._2
2024- let pon = $t08438084481._3
2025- let positionLstUpdCPF = $t08438084481._4
2026- let $t08448484585 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
2027- let positionNotional = $t08448484585._1
2028- let unrealizedPnl = $t08448484585._2
2029- let $t08458884760 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
2030- let remainMargin = $t08458884760._1
2031- let badDebt = $t08458884760._2
2032- let fundingPayment = $t08458884760._3
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
20332033 throw((((((s(remainMargin) + s(fundingPayment)) + s(getMarginRatio(_trader))) + s(unrealizedPnl)) + s(badDebt)) + s(positionNotional)))
20342034 }
20352035 else throw("Strict value is not equal to itself.")
20362036 }
20372037
20382038
20392039
20402040 @Callable(i)
20412041 func view_getPegAdjustCost (_price) = {
20422042 let _qtAstR = qtAstR()
20432043 let _bsAstR = bsAstR()
20442044 let result = getSyncTerminalPrice(_price, _qtAstR, _bsAstR)
20452045 throw(toString(result._3))
20462046 }
20472047
20482048
20492049
20502050 @Callable(i)
20512051 func view_getTerminalAmmPrice () = {
2052- let $t08517685257 = getTerminalAmmState()
2053- let terminalQuoteAssetReserve = $t08517685257._1
2054- let terminalBaseAssetReserve = $t08517685257._2
2052+ let $t08530885389 = getTerminalAmmState()
2053+ let terminalQuoteAssetReserve = $t08530885389._1
2054+ let terminalBaseAssetReserve = $t08530885389._2
20552055 let price = divd(muld(terminalQuoteAssetReserve, qtAstW()), muld(terminalBaseAssetReserve, bsAstW()))
20562056 throw(toString(price))
20572057 }
20582058
20592059
20602060
20612061 @Callable(i)
20622062 func view_getFunding () = {
20632063 let underlyingPrice = getOraclePrice()
2064- let $t08547285534 = getFunding()
2065- let shortPremiumFraction = $t08547285534._1
2066- let longPremiumFraction = $t08547285534._2
2064+ let $t08560485666 = getFunding()
2065+ let shortPremiumFraction = $t08560485666._1
2066+ let longPremiumFraction = $t08560485666._2
20672067 let longFunding = divd(longPremiumFraction, underlyingPrice)
20682068 let shortFunding = divd(shortPremiumFraction, underlyingPrice)
20692069 throw((((s(longFunding) + s(shortFunding)) + s(getTwapSpotPrice())) + s(getOraclePrice())))
20702070 }
20712071
20722072
20732073
20742074 @Callable(i)
20752075 func view_getBorrowedByTrader (_trader) = {
2076- let $t08582085874 = getBorrowedByTrader(_trader)
2077- let borrowed = $t08582085874._1
2078- let assetId = $t08582085874._2
2076+ let $t08595286006 = getBorrowedByTrader(_trader)
2077+ let borrowed = $t08595286006._1
2078+ let assetId = $t08595286006._2
20792079 throw((s(borrowed) + assetId))
20802080 }
20812081
20822082
20832083
20842084 @Callable(i)
20852085 func computeSpotPrice () = {
20862086 let result = getSpotPrice()
20872087 $Tuple2(nil, result)
20882088 }
20892089
20902090
20912091
20922092 @Callable(i)
20932093 func computeFeeForTraderWithArtifact (_trader,_artifactId) = {
20942094 let result = getForTraderWithArtifact(_trader, _artifactId)
20952095 $Tuple2(nil, result)
20962096 }
20972097
20982098
20992099 @Verifier(tx)
21002100 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], adminPublicKey())
21012101

github/deemru/w8io/169f3d6 
305.03 ms