tx · CjPr1ZUbvHhwCp5H3doEPXc15xKDeNpQkf3Wk5L56KHH

3MtMZPVohRyxckRk11RZM4geun6itShmcXy:  -0.07000000 Waves

2022.11.29 21:15 [2338737] smart account 3MtMZPVohRyxckRk11RZM4geun6itShmcXy > SELF 0.00000000 Waves

{ "type": 13, "id": "CjPr1ZUbvHhwCp5H3doEPXc15xKDeNpQkf3Wk5L56KHH", "fee": 7000000, "feeAssetId": null, "timestamp": 1669745783122, "version": 2, "chainId": 84, "sender": "3MtMZPVohRyxckRk11RZM4geun6itShmcXy", "senderPublicKey": "AcX4fkfjTbNodAULoBzLJcZwKsACkfzdq78cpEww7RP8", "proofs": [ "54phxHWiYeWyGdnsiTu2LoiRDxhE5xCPvs3u1D4HDUEN2ZejGyiEZVSp3hC8Sznj9TTNNE6qcDciePojnZVDNqpZ" ], "script": "base64:BgJtCAISABIAEgMKAQESAwoBARILCgkBAQEBAQEBAQESEAoOAQEBAQEBAQgICAEBAQESAwoBARIFCgMBAQESBgoEAQEBCBIAEgMKAQESABIDCgEIEgASABIDCgEIEgMKAQgSAwoBARIAEgASAwoBCLABAAlrX29yYV9rZXkCCWtfb3JhX2tleQAPa19vcmFfYmxvY2tfa2V5Ag9rX29yYV9ibG9ja19rZXkABWtfb3JhAgVrX29yYQAJa19iYWxhbmNlAglrX2JhbGFuY2UADmtfcG9zaXRpb25TaXplAg5rX3Bvc2l0aW9uU2l6ZQAQa19wb3NpdGlvbk1hcmdpbgIQa19wb3NpdGlvbk1hcmdpbgAWa19wb3NpdGlvbk9wZW5Ob3Rpb25hbAIWa19wb3NpdGlvbk9wZW5Ob3Rpb25hbAAua19wb3NpdGlvbkxhc3RVcGRhdGVkQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgISa19wb3NpdGlvbkZyYWN0aW9uABRrX3Bvc2l0aW9uQ2xvc2VkRGF0ZQIUa19wb3NpdGlvbkNsb3NlZERhdGUAD2tfcG9zaXRpb25Bc3NldAIPa19wb3NpdGlvbkFzc2V0AA1rX2luaXRpYWxpemVkAg1rX2luaXRpYWxpemVkAAhrX3BhdXNlZAIIa19wYXVzZWQABWtfZmVlAgVrX2ZlZQAPa19mdW5kaW5nUGVyaW9kAg9rX2Z1bmRpbmdQZXJpb2QAEWtfaW5pdE1hcmdpblJhdGlvAhFrX2luaXRNYXJnaW5SYXRpbwAYa19tYWludGVuYW5jZU1hcmdpblJhdGlvAgVrX21tcgAVa19saXF1aWRhdGlvbkZlZVJhdGlvAhVrX2xpcXVpZGF0aW9uRmVlUmF0aW8AGWtfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8CFmtfcGFydExpcXVpZGF0aW9uUmF0aW8ADWtfc3ByZWFkTGltaXQCDWtfc3ByZWFkTGltaXQAEGtfbWF4UHJpY2VJbXBhY3QCEGtfbWF4UHJpY2VJbXBhY3QAEGtfbWF4UHJpY2VTcHJlYWQCEGtfbWF4UHJpY2VTcHJlYWQADWtfbGFzdERhdGFTdHICDWtfbGFzdERhdGFTdHIADmtfbGFzdE1pbnV0ZUlkAg5rX2xhc3RNaW51dGVJZAAda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UCHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlABNrX3R3YXBEYXRhTGFzdFByaWNlAhNrX3R3YXBEYXRhTGFzdFByaWNlABprX3R3YXBEYXRhUHJldmlvdXNNaW51dGVJZAIaa190d2FwRGF0YVByZXZpb3VzTWludXRlSWQAJWtfbGF0ZXN0TG9uZ0N1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24CG2tfbGF0ZXN0TG9uZ1ByZW1pdW1GcmFjdGlvbgAma19sYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24CHGtfbGF0ZXN0U2hvcnRQcmVtaXVtRnJhY3Rpb24AEmtfbmV4dEZ1bmRpbmdCbG9jawIea19uZXh0RnVuZGluZ0Jsb2NrTWluVGltZXN0YW1wABFrX2xvbmdGdW5kaW5nUmF0ZQIRa19sb25nRnVuZGluZ1JhdGUAEmtfc2hvcnRGdW5kaW5nUmF0ZQISa19zaG9ydEZ1bmRpbmdSYXRlABNrX3F1b3RlQXNzZXRSZXNlcnZlAghrX3F0QXN0UgASa19iYXNlQXNzZXRSZXNlcnZlAghrX2JzQXN0UgASa19xdW90ZUFzc2V0V2VpZ2h0AghrX3F0QXN0VwARa19iYXNlQXNzZXRXZWlnaHQCCGtfYnNBc3RXABNrX3RvdGFsUG9zaXRpb25TaXplAhNrX3RvdGFsUG9zaXRpb25TaXplABdrX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQIXa190b3RhbExvbmdQb3NpdGlvblNpemUAGGtfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQIYa190b3RhbFNob3J0UG9zaXRpb25TaXplABRrX2N1bXVsYXRpdmVOb3Rpb25hbAIUa19jdW11bGF0aXZlTm90aW9uYWwAFmtfb3BlbkludGVyZXN0Tm90aW9uYWwCFmtfb3BlbkludGVyZXN0Tm90aW9uYWwAFGtfY29vcmRpbmF0b3JBZGRyZXNzAhRrX2Nvb3JkaW5hdG9yQWRkcmVzcwAPa192YXVsdF9hZGRyZXNzAg9rX3ZhdWx0X2FkZHJlc3MAD2tfYWRtaW5fYWRkcmVzcwIPa19hZG1pbl9hZGRyZXNzABJrX2FkbWluX3B1YmxpY19rZXkCEmtfYWRtaW5fcHVibGljX2tleQANa19xdW90ZV9hc3NldAINa19xdW90ZV9hc3NldAAPa19xdW90ZV9zdGFraW5nAg9rX3F1b3RlX3N0YWtpbmcAEWtfc3Rha2luZ19hZGRyZXNzAhFrX3N0YWtpbmdfYWRkcmVzcwAPa19taW5lcl9hZGRyZXNzAg9rX21pbmVyX2FkZHJlc3MAEGtfb3JkZXJzX2FkZHJlc3MCEGtfb3JkZXJzX2FkZHJlc3MAEmtfcmVmZXJyYWxfYWRkcmVzcwISa19yZWZlcnJhbF9hZGRyZXNzABFrX21hbmFnZXJfYWRkcmVzcwIRa19tYW5hZ2VyX2FkZHJlc3MAFGtfY29sbGF0ZXJhbF9hZGRyZXNzAhRrX2NvbGxhdGVyYWxfYWRkcmVzcwASa19leGNoYW5nZV9hZGRyZXNzAhJrX2V4Y2hhbmdlX2FkZHJlc3MAFWtfbmZ0X21hbmFnZXJfYWRkcmVzcwIVa19uZnRfbWFuYWdlcl9hZGRyZXNzACBrX3RyYWRlcl9tYXJrZXRfYXNzZXRfY29sbGF0ZXJhbAIga190cmFkZXJfbWFya2V0X2Fzc2V0X2NvbGxhdGVyYWwBDnRvQ29tcG9zaXRlS2V5AgRfa2V5CF9hZGRyZXNzCQCsAgIJAKwCAgUEX2tleQIBXwUIX2FkZHJlc3MBC2Nvb3JkaW5hdG9yAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMFFGtfY29vcmRpbmF0b3JBZGRyZXNzAhNDb29yZGluYXRvciBub3Qgc2V0AQxhZG1pbkFkZHJlc3MACQCmCAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFD2tfYWRtaW5fYWRkcmVzcwEOYWRtaW5QdWJsaWNLZXkACQDZBAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFEmtfYWRtaW5fcHVibGljX2tleQEKcXVvdGVBc3NldAAJANkEAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUNa19xdW90ZV9hc3NldAERcXVvdGVBc3NldFN0YWtpbmcACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUPa19xdW90ZV9zdGFraW5nAhtRdW90ZSBhc3NldCBzdGFraW5nIG5vdCBzZXQBDnN0YWtpbmdBZGRyZXNzAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFEWtfc3Rha2luZ19hZGRyZXNzAg9TdGFraW5nIG5vdCBzZXQBDHZhdWx0QWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABQ9rX3ZhdWx0X2FkZHJlc3MCDVZhdWx0IG5vdCBzZXQBDG1pbmVyQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABQ9rX21pbmVyX2FkZHJlc3MCDU1pbmVyIG5vdCBzZXQBDW9yZGVyc0FkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUQa19vcmRlcnNfYWRkcmVzcwIOT3JkZXJzIG5vdCBzZXQBD3JlZmVycmFsQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQERQGV4dHJOYXRpdmUoMTA1MykCCQELY29vcmRpbmF0b3IABRJrX3JlZmVycmFsX2FkZHJlc3MCEFJlZmVycmFsIG5vdCBzZXQBEW5mdE1hbmFnZXJBZGRyZXNzAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARFAZXh0ck5hdGl2ZSgxMDUzKQIJAQtjb29yZGluYXRvcgAFFWtfbmZ0X21hbmFnZXJfYWRkcmVzcwITTkZUIE1hbmFnZXIgbm90IHNldAERY29sbGF0ZXJhbEFkZHJlc3MACQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgkBC2Nvb3JkaW5hdG9yAAUUa19jb2xsYXRlcmFsX2FkZHJlc3MCGkNvbGxhdGVyYWwgTWFuYWdlciBub3Qgc2V0AQtzd2FwQWRkcmVzcwAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgkBC2Nvb3JkaW5hdG9yAAUSa19leGNoYW5nZV9hZGRyZXNzAg9ObyBzd2FwIGFkZHJlc3MCFEludmFsaWQgc3dhcCBhZGRyZXNzABFrX3doaXRlbGlzdF9hc3NldAIRa193aGl0ZWxpc3RfYXNzZXQBEGlzV2hpdGVsaXN0QXNzZXQBCF9hc3NldElkCQELdmFsdWVPckVsc2UCCQCbCAIJARFjb2xsYXRlcmFsQWRkcmVzcwAJAQ50b0NvbXBvc2l0ZUtleQIFEWtfd2hpdGVsaXN0X2Fzc2V0BQhfYXNzZXRJZAcADWtfdG9rZW5fcGFyYW0CDWtfdG9rZW5fcGFyYW0ADGtfdG9rZW5fdHlwZQIMa190b2tlbl90eXBlABhGRUVfUkVEVUNUSU9OX1RPS0VOX1RZUEUCDWZlZV9yZWR1Y3Rpb24ACERJUl9MT05HAAEACURJUl9TSE9SVAACAA1UV0FQX0lOVEVSVkFMAA8AD09SQUNMRV9JTlRFUlZBTAAPAAdTRUNPTkRTAOgHAA9ERUNJTUFMX05VTUJFUlMABgAMREVDSU1BTF9VTklUCQBoAgABCQBoAgkAaAIJAGgCCQBoAgkAaAIACgAKAAoACgAKAAoAB09ORV9EQVkJAGgCAICjBQUMREVDSU1BTF9VTklUAAhBTExfRkVFUwBkAA9QTkxfT1BUSU9OX1NQT1QAAQARUE5MX09QVElPTl9PUkFDTEUAAgEBcwECX3gJAKwCAgkApAMBBQJfeAIBLAEEZGl2ZAICX3gCX3kJAG4EBQJfeAUMREVDSU1BTF9VTklUBQJfeQUISEFMRkVWRU4BBG11bGQCAl94Al95CQBuBAUCX3gFAl95BQxERUNJTUFMX1VOSVQFCEhBTEZFVkVOAQVzcXJ0ZAECX3gJAQRzcXJ0BAUCX3gFD0RFQ0lNQUxfTlVNQkVSUwUPREVDSU1BTF9OVU1CRVJTBQhIQUxGRVZFTgEEcG93ZAICX3gCX3kJAGwGBQJfeAUPREVDSU1BTF9OVU1CRVJTBQJfeQUPREVDSU1BTF9OVU1CRVJTBQ9ERUNJTUFMX05VTUJFUlMFCEhBTEZFVkVOAQViZGl2ZAICX3gCX3kJAL0CBAUCX3gJALYCAQUMREVDSU1BTF9VTklUBQJfeQUISEFMRkVWRU4BBWJtdWxkAgJfeAJfeQkAvQIEBQJfeAUCX3kJALYCAQUMREVDSU1BTF9VTklUBQhIQUxGRVZFTgEGYnNxcnRkAQJfeAkBCnNxcnRCaWdJbnQEBQJfeAUPREVDSU1BTF9OVU1CRVJTBQ9ERUNJTUFMX05VTUJFUlMFCEhBTEZFVkVOAQVicG93ZAICX3gCX3kJAHYGBQJfeAUPREVDSU1BTF9OVU1CRVJTBQJfeQUPREVDSU1BTF9OVU1CRVJTBQ9ERUNJTUFMX05VTUJFUlMFCEhBTEZFVkVOAQNhYnMBAl94AwkAZgIFAl94AAAFAl94CQEBLQEFAl94AQR2bWF4AgJfeAJfeQMJAGcCBQJfeAUCX3kFAl94BQJfeQEJbGlzdFRvU3RyAQVfbGlzdAoBBV9qb2luAgthY2N1bXVsYXRvcgN2YWwJAKwCAgkArAICBQthY2N1bXVsYXRvcgUDdmFsAgEsBApuZXdMaXN0U3RyCgACJGwFBV9saXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAIACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQVfam9pbgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMjAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUBAtuZXdMaXN0U3RyVQkAswICBQpuZXdMaXN0U3RyAAEEC25ld0xpc3RTdHJSAwkAAAIJAK8CAgULbmV3TGlzdFN0clUAAQIBLAkAsAICBQtuZXdMaXN0U3RyVQABBQtuZXdMaXN0U3RyVQULbmV3TGlzdFN0clIBCXN0clRvTGlzdAEEX3N0cgkAtQkCBQRfc3RyAgEsAQtwdXNoVG9RdWV1ZQMFX2xpc3QIX21heFNpemUGX3ZhbHVlAwkAZgIJAJADAQUFX2xpc3QFCF9tYXhTaXplCQDNCAIJANEIAgUFX2xpc3QAAAUGX3ZhbHVlCQDNCAIFBV9saXN0BQZfdmFsdWUBA2ludAEBawkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMFAWsJAKwCAgINbm8gdmFsdWUgZm9yIAUBawEFaW50T3ICAWsDZGVmCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWsFA2RlZgEEc3RyQQIIX2FkZHJlc3MEX2tleQQDdmFsCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUIX2FkZHJlc3MFBF9rZXkJAKwCAgIRTm8gdmFsdWUgZm9yIGtleSAFBF9rZXkFA3ZhbAEEaW50QQIIX2FkZHJlc3MEX2tleQQDdmFsCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUIX2FkZHJlc3MFBF9rZXkJAKwCAgIRTm8gdmFsdWUgZm9yIGtleSAFBF9rZXkFA3ZhbAEIY2JhbGFuY2UACQEDaW50AQUJa19iYWxhbmNlAQNmZWUACQEDaW50AQUFa19mZWUBD2luaXRNYXJnaW5SYXRpbwAJAQNpbnQBBRFrX2luaXRNYXJnaW5SYXRpbwEGcXRBc3RSAAkBA2ludAEFE2tfcXVvdGVBc3NldFJlc2VydmUBBmJzQXN0UgAJAQNpbnQBBRJrX2Jhc2VBc3NldFJlc2VydmUBBnF0QXN0VwAJAQVpbnRPcgIFEmtfcXVvdGVBc3NldFdlaWdodAUMREVDSU1BTF9VTklUAQZic0FzdFcACQEFaW50T3ICBRFrX2Jhc2VBc3NldFdlaWdodAUMREVDSU1BTF9VTklUARF0b3RhbFBvc2l0aW9uU2l6ZQAJAQNpbnQBBRNrX3RvdGFsUG9zaXRpb25TaXplARJjdW11bGF0aXZlTm90aW9uYWwACQEDaW50AQUUa19jdW11bGF0aXZlTm90aW9uYWwBFG9wZW5JbnRlcmVzdE5vdGlvbmFsAAkBA2ludAEFFmtfb3BlbkludGVyZXN0Tm90aW9uYWwBGW5leHRGdW5kaW5nQmxvY2tUaW1lc3RhbXAACQEDaW50AQUSa19uZXh0RnVuZGluZ0Jsb2NrARBmdW5kaW5nUGVyaW9kUmF3AAkBA2ludAEFD2tfZnVuZGluZ1BlcmlvZAEUZnVuZGluZ1BlcmlvZERlY2ltYWwACQBoAgkBEGZ1bmRpbmdQZXJpb2RSYXcABQxERUNJTUFMX1VOSVQBFGZ1bmRpbmdQZXJpb2RTZWNvbmRzAAkAaAIJARBmdW5kaW5nUGVyaW9kUmF3AAUHU0VDT05EUwEWbWFpbnRlbmFuY2VNYXJnaW5SYXRpbwAJAQNpbnQBBRhrX21haW50ZW5hbmNlTWFyZ2luUmF0aW8BE2xpcXVpZGF0aW9uRmVlUmF0aW8ACQEDaW50AQUVa19saXF1aWRhdGlvbkZlZVJhdGlvARdwYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwAJAQNpbnQBBRlrX3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAQtzcHJlYWRMaW1pdAAJAQNpbnQBBQ1rX3NwcmVhZExpbWl0AQ5tYXhQcmljZUltcGFjdAAJAQNpbnQBBRBrX21heFByaWNlSW1wYWN0AQ5tYXhQcmljZVNwcmVhZAAJAQNpbnQBBRBrX21heFByaWNlU3ByZWFkASNsYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgAJAQNpbnQBBSVrX2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uASRsYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24ACQEDaW50AQUma19sYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24BFnRvdGFsU2hvcnRQb3NpdGlvblNpemUACQEDaW50AQUYa190b3RhbFNob3J0UG9zaXRpb25TaXplARV0b3RhbExvbmdQb3NpdGlvblNpemUACQEDaW50AQUXa190b3RhbExvbmdQb3NpdGlvblNpemUBD2dldEFjdHVhbENhbGxlcgEBaQkBC3ZhbHVlT3JFbHNlAgkAnQgCCQENb3JkZXJzQWRkcmVzcwACCGtfc2VuZGVyCQClCAEIBQFpBmNhbGxlcgEWcmVxdWlyZU1vcmVNYXJnaW5SYXRpbwMMX21hcmdpblJhdGlvEF9iYXNlTWFyZ2luUmF0aW8UX2xhcmdlclRoYW5PckVxdWFsVG8EFHJlbWFpbmluZ01hcmdpblJhdGlvCQBlAgUMX21hcmdpblJhdGlvBRBfYmFzZU1hcmdpblJhdGlvAwMFFF9sYXJnZXJUaGFuT3JFcXVhbFRvCQBmAgAABRRyZW1haW5pbmdNYXJnaW5SYXRpbwcJAAIBAg5JbnZhbGlkIG1hcmdpbgMDCQEBIQEFFF9sYXJnZXJUaGFuT3JFcXVhbFRvCQBnAgUUcmVtYWluaW5nTWFyZ2luUmF0aW8AAAcJAAIBAg5JbnZhbGlkIG1hcmdpbgYBH2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24BDV9wb3NpdGlvblNpemUDCQAAAgUNX3Bvc2l0aW9uU2l6ZQAACQACAQIsU2hvdWxkIG5vdCBiZSBjYWxsZWQgd2l0aCBfcG9zaXRpb25TaXplID09IDADCQBmAgUNX3Bvc2l0aW9uU2l6ZQAACQEjbGF0ZXN0TG9uZ0N1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24ACQEkbGF0ZXN0U2hvcnRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAELZ2V0UG9zaXRpb24BB190cmFkZXIED3Bvc2l0aW9uU2l6ZU9wdAkAmggCBQR0aGlzCQEOdG9Db21wb3NpdGVLZXkCBQ5rX3Bvc2l0aW9uU2l6ZQUHX3RyYWRlcgQHJG1hdGNoMAUPcG9zaXRpb25TaXplT3B0AwkAAQIFByRtYXRjaDACA0ludAQMcG9zaXRpb25TaXplBQckbWF0Y2gwCQCWCgQFDHBvc2l0aW9uU2l6ZQkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkBDnRvQ29tcG9zaXRlS2V5AgUQa19wb3NpdGlvbk1hcmdpbgUHX3RyYWRlcgkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkBDnRvQ29tcG9zaXRlS2V5AgUWa19wb3NpdGlvbk9wZW5Ob3Rpb25hbAUHX3RyYWRlcgkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkBDnRvQ29tcG9zaXRlS2V5AgUua19wb3NpdGlvbkxhc3RVcGRhdGVkQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUHX3RyYWRlcgkAlgoEAAAAAAAAAAABEGdldFBvc2l0aW9uQXNzZXQBB190cmFkZXIEEHBvc2l0aW9uQXNzZXRPcHQJAJ0IAgUEdGhpcwkBDnRvQ29tcG9zaXRlS2V5AgUPa19wb3NpdGlvbkFzc2V0BQdfdHJhZGVyBAckbWF0Y2gwBRBwb3NpdGlvbkFzc2V0T3B0AwkAAQIFByRtYXRjaDACBlN0cmluZwQNcG9zaXRpb25Bc3NldAUHJG1hdGNoMAUNcG9zaXRpb25Bc3NldAkA2AQBCQEKcXVvdGVBc3NldAABE3JlcXVpcmVPcGVuUG9zaXRpb24BB190cmFkZXIDCQAAAggJAQtnZXRQb3NpdGlvbgEFB190cmFkZXICXzEAAAkAAgECEE5vIG9wZW4gcG9zaXRpb24GAQtpbml0aWFsaXplZAAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUEdGhpcwUNa19pbml0aWFsaXplZAcBBnBhdXNlZAAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUEdGhpcwUIa19wYXVzZWQHAQ11cGRhdGVSZXNlcnZlAwZfaXNBZGQRX3F1b3RlQXNzZXRBbW91bnQQX2Jhc2VBc3NldEFtb3VudAMFBl9pc0FkZAQHbmV3QmFzZQkAZQIJAQZic0FzdFIABRBfYmFzZUFzc2V0QW1vdW50AwkAZwIAAAUHbmV3QmFzZQkAAgECKlR4IGxlYWQgdG8gYmFzZSBhc3NldCByZXNlcnZlIDw9IDAsIHJldmVydAkAlgoECQBkAgkBBnF0QXN0UgAFEV9xdW90ZUFzc2V0QW1vdW50BQduZXdCYXNlCQBkAgkBEXRvdGFsUG9zaXRpb25TaXplAAUQX2Jhc2VBc3NldEFtb3VudAkAZAIJARJjdW11bGF0aXZlTm90aW9uYWwABRFfcXVvdGVBc3NldEFtb3VudAQIbmV3UXVvdGUJAGUCCQEGcXRBc3RSAAURX3F1b3RlQXNzZXRBbW91bnQDCQBnAgAABQhuZXdRdW90ZQkAAgECKlR4IGxlYWQgdG8gYmFzZSBxdW90ZSByZXNlcnZlIDw9IDAsIHJldmVydAkAlgoEBQhuZXdRdW90ZQkAZAIJAQZic0FzdFIABRBfYmFzZUFzc2V0QW1vdW50CQBlAgkBEXRvdGFsUG9zaXRpb25TaXplAAUQX2Jhc2VBc3NldEFtb3VudAkAZQIJARJjdW11bGF0aXZlTm90aW9uYWwABRFfcXVvdGVBc3NldEFtb3VudAENY2FsY0ludmFyaWFudAQHX3F0QXN0UgdfcXRBc3RXB19ic0FzdFIHX2JzQXN0VwkBBG11bGQCCQEEbXVsZAIFB19xdEFzdFIFB19xdEFzdFcJAQRtdWxkAgUHX2JzQXN0UgUHX2JzQXN0VwEJc3dhcElucHV0AgZfaXNBZGQRX3F1b3RlQXNzZXRBbW91bnQEB19xdEFzdFIJAQZxdEFzdFIABAdfYnNBc3RSCQEGYnNBc3RSAAQHX3F0QXN0VwkBBnF0QXN0VwAEB19ic0FzdFcJAQZic0FzdFcABAFrCQENY2FsY0ludmFyaWFudAQFB19xdEFzdFIFB19xdEFzdFcFB19ic0FzdFIFB19ic0FzdFcEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIDBQZfaXNBZGQJAGQCBQdfcXRBc3RSBRFfcXVvdGVBc3NldEFtb3VudAkAZQIFB19xdEFzdFIFEV9xdW90ZUFzc2V0QW1vdW50BBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIJAQRkaXZkAgUBawUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgQYYW1vdW50QmFzZUFzc2V0Qm91Z2h0QWJzCQEEZGl2ZAIJAQNhYnMBCQBlAgUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBQdfYnNBc3RSBQdfcXRBc3RXBBVhbW91bnRCYXNlQXNzZXRCb3VnaHQDBQZfaXNBZGQFGGFtb3VudEJhc2VBc3NldEJvdWdodEFicwkBAS0BBRhhbW91bnRCYXNlQXNzZXRCb3VnaHRBYnMEDSR0MDE2MzE5MTY1MTIJAQ11cGRhdGVSZXNlcnZlAwUGX2lzQWRkBRFfcXVvdGVBc3NldEFtb3VudAUYYW1vdW50QmFzZUFzc2V0Qm91Z2h0QWJzBBdxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyMQgFDSR0MDE2MzE5MTY1MTICXzEEFmJhc2VBc3NldFJlc2VydmVBZnRlcjEIBQ0kdDAxNjMxOTE2NTEyAl8yBBd0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyMQgFDSR0MDE2MzE5MTY1MTICXzMEGGN1bXVsYXRpdmVOb3Rpb25hbEFmdGVyMQgFDSR0MDE2MzE5MTY1MTICXzQEC3ByaWNlQmVmb3JlCQEEZGl2ZAIJAQRtdWxkAgUHX3F0QXN0UgUHX3F0QXN0VwkBBG11bGQCBQdfYnNBc3RSBQdfYnNBc3RXBAttYXJrZXRQcmljZQkBBGRpdmQCBRFfcXVvdGVBc3NldEFtb3VudAUYYW1vdW50QmFzZUFzc2V0Qm91Z2h0QWJzBAlwcmljZURpZmYJAQNhYnMBCQBlAgULcHJpY2VCZWZvcmUFC21hcmtldFByaWNlBAtwcmljZUltcGFjdAkAZQIFDERFQ0lNQUxfVU5JVAkBBGRpdmQCBQtwcmljZUJlZm9yZQkAZAIFC3ByaWNlQmVmb3JlBQlwcmljZURpZmYEE21heFByaWNlSW1wYWN0VmFsdWUJAQ5tYXhQcmljZUltcGFjdAADCQBmAgULcHJpY2VJbXBhY3QFE21heFByaWNlSW1wYWN0VmFsdWUJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICDVByaWNlIGltcGFjdCAJAKQDAQULcHJpY2VJbXBhY3QCFCA+IG1heCBwcmljZSBpbXBhY3QgCQCkAwEFE21heFByaWNlSW1wYWN0VmFsdWUCFSBiZWZvcmUgcXVvdGUgYXNzZXQ6IAkApAMBBQdfcXRBc3RSAhQgYmVmb3JlIGJhc2UgYXNzZXQ6IAkApAMBBQdfYnNBc3RSAiEgcXVvdGUgYXNzZXQgYW1vdW50IHRvIGV4Y2hhbmdlOiAJAKQDAQURX3F1b3RlQXNzZXRBbW91bnQCDyBwcmljZSBiZWZvcmU6IAkApAMBBQtwcmljZUJlZm9yZQIOIG1hcmtldFByaWNlOiAJAKQDAQULbWFya2V0UHJpY2UJAJcKBQUVYW1vdW50QmFzZUFzc2V0Qm91Z2h0BRdxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyMQUWYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyMQUXdG90YWxQb3NpdGlvblNpemVBZnRlcjEFGGN1bXVsYXRpdmVOb3Rpb25hbEFmdGVyMQEiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAQQX29sZFBvc2l0aW9uU2l6ZRJfb2xkUG9zaXRpb25NYXJnaW4lX29sZFBvc2l0aW9uQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgxfbWFyZ2luRGVsdGEEDmZ1bmRpbmdQYXltZW50AwkBAiE9AgUQX29sZFBvc2l0aW9uU2l6ZQAABCBfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkBH2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24BBRBfb2xkUG9zaXRpb25TaXplCQEEbXVsZAIJAGUCBSBfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUlX29sZFBvc2l0aW9uQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUQX29sZFBvc2l0aW9uU2l6ZQAABAxzaWduZWRNYXJnaW4JAGQCCQBlAgUMX21hcmdpbkRlbHRhBQ5mdW5kaW5nUGF5bWVudAUSX29sZFBvc2l0aW9uTWFyZ2luBA0kdDAxODAzMTE4MTU4AwkAZgIAAAUMc2lnbmVkTWFyZ2luCQCUCgIAAAkBA2FicwEFDHNpZ25lZE1hcmdpbgkAlAoCCQEDYWJzAQUMc2lnbmVkTWFyZ2luAAAEDHJlbWFpbk1hcmdpbggFDSR0MDE4MDMxMTgxNTgCXzEEB2JhZERlYnQIBQ0kdDAxODAzMTE4MTU4Al8yCQCVCgMFDHJlbWFpbk1hcmdpbgUHYmFkRGVidAUOZnVuZGluZ1BheW1lbnQBFnN3YXBPdXRwdXRXaXRoUmVzZXJ2ZXMHBl9pc0FkZBBfYmFzZUFzc2V0QW1vdW50FF9jaGVja01heFByaWNlSW1wYWN0El9xdW90ZUFzc2V0UmVzZXJ2ZRFfcXVvdGVBc3NldFdlaWdodBFfYmFzZUFzc2V0UmVzZXJ2ZRBfYmFzZUFzc2V0V2VpZ2h0BAtwcmljZUJlZm9yZQkBBGRpdmQCCQEEbXVsZAIFEl9xdW90ZUFzc2V0UmVzZXJ2ZQURX3F1b3RlQXNzZXRXZWlnaHQJAQRtdWxkAgURX2Jhc2VBc3NldFJlc2VydmUFEF9iYXNlQXNzZXRXZWlnaHQDCQAAAgUQX2Jhc2VBc3NldEFtb3VudAAACQACAQIZSW52YWxpZCBiYXNlIGFzc2V0IGFtb3VudAQBawkBDWNhbGNJbnZhcmlhbnQEBRJfcXVvdGVBc3NldFJlc2VydmUFEV9xdW90ZUFzc2V0V2VpZ2h0BRFfYmFzZUFzc2V0UmVzZXJ2ZQUQX2Jhc2VBc3NldFdlaWdodAQYYmFzZUFzc2V0UG9vbEFtb3VudEFmdGVyAwUGX2lzQWRkCQBkAgURX2Jhc2VBc3NldFJlc2VydmUFEF9iYXNlQXNzZXRBbW91bnQJAGUCBRFfYmFzZUFzc2V0UmVzZXJ2ZQUQX2Jhc2VBc3NldEFtb3VudAQPcXVvdGVBc3NldEFmdGVyCQEEZGl2ZAIFAWsJAQRtdWxkAgUYYmFzZUFzc2V0UG9vbEFtb3VudEFmdGVyBRBfYmFzZUFzc2V0V2VpZ2h0BA5xdW90ZUFzc2V0U29sZAkBA2FicwEJAGUCBQ9xdW90ZUFzc2V0QWZ0ZXIJAQRtdWxkAgUSX3F1b3RlQXNzZXRSZXNlcnZlBRFfcXVvdGVBc3NldFdlaWdodAQTbWF4UHJpY2VJbXBhY3RWYWx1ZQkBDm1heFByaWNlSW1wYWN0AAQNJHQwMTkzMjYxOTUxOQkBDXVwZGF0ZVJlc2VydmUDCQEBIQEFBl9pc0FkZAUOcXVvdGVBc3NldFNvbGQFEF9iYXNlQXNzZXRBbW91bnQEF3F1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIxCAUNJHQwMTkzMjYxOTUxOQJfMQQWYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyMQgFDSR0MDE5MzI2MTk1MTkCXzIEF3RvdGFsUG9zaXRpb25TaXplQWZ0ZXIxCAUNJHQwMTkzMjYxOTUxOQJfMwQYY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIxCAUNJHQwMTkzMjYxOTUxOQJfNAQLbWFya2V0UHJpY2UJAQRkaXZkAgUOcXVvdGVBc3NldFNvbGQFEF9iYXNlQXNzZXRBbW91bnQECXByaWNlRGlmZgkBA2FicwEJAGUCBQtwcmljZUJlZm9yZQULbWFya2V0UHJpY2UEC3ByaWNlSW1wYWN0CQBlAgUMREVDSU1BTF9VTklUCQEEZGl2ZAIFC3ByaWNlQmVmb3JlCQBkAgULcHJpY2VCZWZvcmUFCXByaWNlRGlmZgMDCQBmAgULcHJpY2VJbXBhY3QFE21heFByaWNlSW1wYWN0VmFsdWUFFF9jaGVja01heFByaWNlSW1wYWN0BwkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgINUHJpY2UgaW1wYWN0IAkApAMBBQtwcmljZUltcGFjdAIUID4gbWF4IHByaWNlIGltcGFjdCAJAKQDAQUTbWF4UHJpY2VJbXBhY3RWYWx1ZQIVIGJlZm9yZSBxdW90ZSBhc3NldDogCQCkAwEFEl9xdW90ZUFzc2V0UmVzZXJ2ZQIUIGJlZm9yZSBiYXNlIGFzc2V0OiAJAKQDAQURX2Jhc2VBc3NldFJlc2VydmUCICBiYXNlIGFzc2V0IGFtb3VudCB0byBleGNoYW5nZTogCQCkAwEFEF9iYXNlQXNzZXRBbW91bnQCDyBwcmljZSBiZWZvcmU6IAkApAMBBQtwcmljZUJlZm9yZQIPIG1hcmtldCBwcmljZTogCQCkAwEFC21hcmtldFByaWNlCQCaCggFDnF1b3RlQXNzZXRTb2xkBRdxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyMQUWYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyMQUXdG90YWxQb3NpdGlvblNpemVBZnRlcjEFGGN1bXVsYXRpdmVOb3Rpb25hbEFmdGVyMQkAZQIJARV0b3RhbExvbmdQb3NpdGlvblNpemUAAwUGX2lzQWRkCQEDYWJzAQUQX2Jhc2VBc3NldEFtb3VudAAACQBlAgkBFnRvdGFsU2hvcnRQb3NpdGlvblNpemUAAwkBASEBBQZfaXNBZGQJAQNhYnMBBRBfYmFzZUFzc2V0QW1vdW50AAAFC3ByaWNlSW1wYWN0AQpzd2FwT3V0cHV0AwZfaXNBZGQQX2Jhc2VBc3NldEFtb3VudBRfY2hlY2tNYXhQcmljZUltcGFjdAkBFnN3YXBPdXRwdXRXaXRoUmVzZXJ2ZXMHBQZfaXNBZGQFEF9iYXNlQXNzZXRBbW91bnQFFF9jaGVja01heFByaWNlSW1wYWN0CQEGcXRBc3RSAAkBBnF0QXN0VwAJAQZic0FzdFIACQEGYnNBc3RXAAESZ2V0T3JhY2xlVHdhcFByaWNlAAQGb3JhY2xlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUFa19vcmECAAQIcHJpY2VLZXkJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMFCWtfb3JhX2tleQQIYmxvY2tLZXkJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMFD2tfb3JhX2Jsb2NrX2tleQQJbGFzdFZhbHVlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUGb3JhY2xlBQhwcmljZUtleQkArAICCQCsAgIJAKwCAgIiQ2FuIG5vdCBnZXQgb3JhY2xlIHByaWNlLiBPcmFjbGU6IAkApQgBBQZvcmFjbGUCBiBrZXk6IAUIcHJpY2VLZXkFCWxhc3RWYWx1ZQEZcmVxdWlyZU5vdE92ZXJTcHJlYWRMaW1pdAISX3F1b3RlQXNzZXRSZXNlcnZlEV9iYXNlQXNzZXRSZXNlcnZlBAtvcmFjbGVQcmljZQkBEmdldE9yYWNsZVR3YXBQcmljZQAECnByaWNlQWZ0ZXIJAQRkaXZkAgUSX3F1b3RlQXNzZXRSZXNlcnZlBRFfYmFzZUFzc2V0UmVzZXJ2ZQQMYXZlcmFnZVByaWNlCQEEZGl2ZAIJAGQCBQtvcmFjbGVQcmljZQUKcHJpY2VBZnRlcgkAaAIAAgUMREVDSU1BTF9VTklUBAxhYnNQcmljZURpZmYJAQRkaXZkAgkBA2FicwEJAGUCBQtvcmFjbGVQcmljZQUKcHJpY2VBZnRlcgUMYXZlcmFnZVByaWNlAwkAZgIFDGFic1ByaWNlRGlmZgkBDm1heFByaWNlU3ByZWFkAAkAAgEJAKwCAgkArAICCQCsAgICDVByaWNlIHNwcmVhZCAJAKQDAQUMYWJzUHJpY2VEaWZmAhQgPiBtYXggcHJpY2Ugc3ByZWFkIAkApAMBCQEObWF4UHJpY2VTcHJlYWQABgEMZ2V0U3BvdFByaWNlAAQSX3F1b3RlQXNzZXRSZXNlcnZlCQEGcXRBc3RSAAQRX2Jhc2VBc3NldFJlc2VydmUJAQZic0FzdFIABAdfcXRBc3RXCQEGcXRBc3RXAAQHX2JzQXN0VwkBBmJzQXN0VwAJAQRkaXZkAgkBBG11bGQCBRJfcXVvdGVBc3NldFJlc2VydmUFB19xdEFzdFcJAQRtdWxkAgURX2Jhc2VBc3NldFJlc2VydmUFB19ic0FzdFcBFmlzT3ZlckZsdWN0dWF0aW9uTGltaXQABAtvcmFjbGVQcmljZQkBEmdldE9yYWNsZVR3YXBQcmljZQAEDGN1cnJlbnRQcmljZQkBDGdldFNwb3RQcmljZQAJAGYCCQEEZGl2ZAIJAQNhYnMBCQBlAgULb3JhY2xlUHJpY2UFDGN1cnJlbnRQcmljZQULb3JhY2xlUHJpY2UJAQtzcHJlYWRMaW1pdAABH2dldFBvc2l0aW9uQWRqdXN0ZWRPcGVuTm90aW9uYWwGDV9wb3NpdGlvblNpemUHX29wdGlvbhJfcXVvdGVBc3NldFJlc2VydmURX3F1b3RlQXNzZXRXZWlnaHQRX2Jhc2VBc3NldFJlc2VydmUQX2Jhc2VBc3NldFdlaWdodAQPcG9zaXRpb25TaXplQWJzCQEDYWJzAQUNX3Bvc2l0aW9uU2l6ZQQHaXNTaG9ydAkAZgIAAAUNX3Bvc2l0aW9uU2l6ZQQQcG9zaXRpb25Ob3Rpb25hbAMJAAACBQdfb3B0aW9uBQ9QTkxfT1BUSU9OX1NQT1QEDSR0MDIyODk0MjMxMTQJARZzd2FwT3V0cHV0V2l0aFJlc2VydmVzBwkBASEBBQdpc1Nob3J0BQ9wb3NpdGlvblNpemVBYnMHBRJfcXVvdGVBc3NldFJlc2VydmUFEV9xdW90ZUFzc2V0V2VpZ2h0BRFfYmFzZUFzc2V0UmVzZXJ2ZQUQX2Jhc2VBc3NldFdlaWdodAQTb3V0UG9zaXRpb25Ob3Rpb25hbAgFDSR0MDIyODk0MjMxMTQCXzEEAngxCAUNJHQwMjI4OTQyMzExNAJfMgQCeDIIBQ0kdDAyMjg5NDIzMTE0Al8zBAJ4MwgFDSR0MDIyODk0MjMxMTQCXzQFE291dFBvc2l0aW9uTm90aW9uYWwJAQRtdWxkAgUPcG9zaXRpb25TaXplQWJzCQESZ2V0T3JhY2xlVHdhcFByaWNlAAUQcG9zaXRpb25Ob3Rpb25hbAErZ2V0UG9zaXRpb25Ob3Rpb25hbEFuZFVucmVhbGl6ZWRQbmxCeVZhbHVlcwcNX3Bvc2l0aW9uU2l6ZRVfcG9zaXRpb25PcGVuTm90aW9uYWwSX3F1b3RlQXNzZXRSZXNlcnZlEV9xdW90ZUFzc2V0V2VpZ2h0EV9iYXNlQXNzZXRSZXNlcnZlEF9iYXNlQXNzZXRXZWlnaHQHX29wdGlvbgMJAAACBQ1fcG9zaXRpb25TaXplAAAJAAIBAhVJbnZhbGlkIHBvc2l0aW9uIHNpemUEB2lzU2hvcnQJAGYCAAAFDV9wb3NpdGlvblNpemUEEHBvc2l0aW9uTm90aW9uYWwJAR9nZXRQb3NpdGlvbkFkanVzdGVkT3Blbk5vdGlvbmFsBgUNX3Bvc2l0aW9uU2l6ZQUHX29wdGlvbgUSX3F1b3RlQXNzZXRSZXNlcnZlBRFfcXVvdGVBc3NldFdlaWdodAURX2Jhc2VBc3NldFJlc2VydmUFEF9iYXNlQXNzZXRXZWlnaHQEDXVucmVhbGl6ZWRQbmwDBQdpc1Nob3J0CQBlAgUVX3Bvc2l0aW9uT3Blbk5vdGlvbmFsBRBwb3NpdGlvbk5vdGlvbmFsCQBlAgUQcG9zaXRpb25Ob3Rpb25hbAUVX3Bvc2l0aW9uT3Blbk5vdGlvbmFsCQCUCgIFEHBvc2l0aW9uTm90aW9uYWwFDXVucmVhbGl6ZWRQbmwBI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAgdfdHJhZGVyB19vcHRpb24EDSR0MDI0NTM5MjQ2NjcJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIEDHBvc2l0aW9uU2l6ZQgFDSR0MDI0NTM5MjQ2NjcCXzEEDnBvc2l0aW9uTWFyZ2luCAUNJHQwMjQ1MzkyNDY2NwJfMgQUcG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDAyNDUzOTI0NjY3Al8zBBFwb3NpdGlvbkxzdFVwZENQRggFDSR0MDI0NTM5MjQ2NjcCXzQJAStnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubEJ5VmFsdWVzBwUMcG9zaXRpb25TaXplBRRwb3NpdGlvbk9wZW5Ob3Rpb25hbAkBBnF0QXN0UgAJAQZxdEFzdFcACQEGYnNBc3RSAAkBBmJzQXN0VwAFB19vcHRpb24BD2NhbGNNYXJnaW5SYXRpbwMNX3JlbWFpbk1hcmdpbghfYmFkRGVidBFfcG9zaXRpb25Ob3Rpb25hbAkBBGRpdmQCCQBlAgUNX3JlbWFpbk1hcmdpbgUIX2JhZERlYnQFEV9wb3NpdGlvbk5vdGlvbmFsARZnZXRNYXJnaW5SYXRpb0J5T3B0aW9uAgdfdHJhZGVyB19vcHRpb24EDSR0MDI1MTgwMjUyOTEJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIEDHBvc2l0aW9uU2l6ZQgFDSR0MDI1MTgwMjUyOTECXzEEDnBvc2l0aW9uTWFyZ2luCAUNJHQwMjUxODAyNTI5MQJfMgQDcG9uCAUNJHQwMjUxODAyNTI5MQJfMwQRcG9zaXRpb25Mc3RVcGRDUEYIBQ0kdDAyNTE4MDI1MjkxAl80BA0kdDAyNTI5NzI1MzkwCQEjZ2V0UG9zaXRpb25Ob3Rpb25hbEFuZFVucmVhbGl6ZWRQbmwCBQdfdHJhZGVyBQdfb3B0aW9uBBBwb3NpdGlvbk5vdGlvbmFsCAUNJHQwMjUyOTcyNTM5MAJfMQQNdW5yZWFsaXplZFBubAgFDSR0MDI1Mjk3MjUzOTACXzIEDSR0MDI1Mzk1MjU1NjEJASJjYWxjUmVtYWluTWFyZ2luV2l0aEZ1bmRpbmdQYXltZW50BAUMcG9zaXRpb25TaXplBQ5wb3NpdGlvbk1hcmdpbgURcG9zaXRpb25Mc3RVcGRDUEYFDXVucmVhbGl6ZWRQbmwEDHJlbWFpbk1hcmdpbggFDSR0MDI1Mzk1MjU1NjECXzEEB2JhZERlYnQIBQ0kdDAyNTM5NTI1NTYxAl8yCQEPY2FsY01hcmdpblJhdGlvAwUMcmVtYWluTWFyZ2luBQdiYWREZWJ0BRBwb3NpdGlvbk5vdGlvbmFsAQ5nZXRNYXJnaW5SYXRpbwEHX3RyYWRlcgkBFmdldE1hcmdpblJhdGlvQnlPcHRpb24CBQdfdHJhZGVyBQ9QTkxfT1BUSU9OX1NQT1QBG2dldFBhcnRpYWxMaXF1aWRhdGlvbkFtb3VudAIHX3RyYWRlcg1fcG9zaXRpb25TaXplBAxtYXhpbXVtUmF0aW8JAQR2bWF4AgkBF3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAAkAZQIFDERFQ0lNQUxfVU5JVAkBBGRpdmQCCQEOZ2V0TWFyZ2luUmF0aW8BBQdfdHJhZGVyCQEWbWFpbnRlbmFuY2VNYXJnaW5SYXRpbwAEGG1heEV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQkBBG11bGQCCQEDYWJzAQUNX3Bvc2l0aW9uU2l6ZQUMbWF4aW11bVJhdGlvBApzd2FwUmVzdWx0CQEKc3dhcE91dHB1dAMJAGYCBQ1fcG9zaXRpb25TaXplAAAFGG1heEV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQcEHG1heEV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQIBQpzd2FwUmVzdWx0Al8xBAtwcmljZUltcGFjdAgFCnN3YXBSZXN1bHQCXzgDCQBmAgkBDm1heFByaWNlSW1wYWN0AAULcHJpY2VJbXBhY3QFHG1heEV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQEFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQkBBG11bGQCCQEDYWJzAQUNX3Bvc2l0aW9uU2l6ZQkBF3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAAQZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAgJAQpzd2FwT3V0cHV0AwkAZgIFDV9wb3NpdGlvblNpemUAAAUVZXhjaGFuZ2VkUG9zaXRpb25TaXplBwJfMQUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAEVaW50ZXJuYWxDbG9zZVBvc2l0aW9uAgdfdHJhZGVyFF9jaGVja01heFByaWNlSW1wYWN0BA0kdDAyNjc5NDI2OTIyCQELZ2V0UG9zaXRpb24BBQdfdHJhZGVyBAxwb3NpdGlvblNpemUIBQ0kdDAyNjc5NDI2OTIyAl8xBA5wb3NpdGlvbk1hcmdpbggFDSR0MDI2Nzk0MjY5MjICXzIEFHBvc2l0aW9uT3Blbk5vdGlvbmFsCAUNJHQwMjY3OTQyNjkyMgJfMwQRcG9zaXRpb25Mc3RVcGRDUEYIBQ0kdDAyNjc5NDI2OTIyAl80BA11bnJlYWxpemVkUG5sCAkBI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAgUHX3RyYWRlcgUPUE5MX09QVElPTl9TUE9UAl8yBA0kdDAyNzAxNzI3MTg1CQEiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAQFDHBvc2l0aW9uU2l6ZQUOcG9zaXRpb25NYXJnaW4FEXBvc2l0aW9uTHN0VXBkQ1BGBQ11bnJlYWxpemVkUG5sBAxyZW1haW5NYXJnaW4IBQ0kdDAyNzAxNzI3MTg1Al8xBAdiYWREZWJ0CAUNJHQwMjcwMTcyNzE4NQJfMgQVZXhjaGFuZ2VkUG9zaXRpb25TaXplCQEBLQEFDHBvc2l0aW9uU2l6ZQQLcmVhbGl6ZWRQbmwFDXVucmVhbGl6ZWRQbmwEDW1hcmdpblRvVmF1bHQJAQEtAQUMcmVtYWluTWFyZ2luBA0kdDAyNzMxMjI3NjE3CQEKc3dhcE91dHB1dAMJAGYCBQxwb3NpdGlvblNpemUAAAkBA2FicwEFDHBvc2l0aW9uU2l6ZQUUX2NoZWNrTWF4UHJpY2VJbXBhY3QEGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQIBQ0kdDAyNzMxMjI3NjE3Al8xBBZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwMjczMTIyNzYxNwJfMgQVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwMjczMTIyNzYxNwJfMwQWdG90YWxQb3NpdGlvblNpemVBZnRlcggFDSR0MDI3MzEyMjc2MTcCXzQEF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCAUNJHQwMjczMTIyNzYxNwJfNQQOdG90YWxMb25nQWZ0ZXIIBQ0kdDAyNzMxMjI3NjE3Al82BA90b3RhbFNob3J0QWZ0ZXIIBQ0kdDAyNzMxMjI3NjE3Al83BBlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCQBlAgkBFG9wZW5JbnRlcmVzdE5vdGlvbmFsAAUUcG9zaXRpb25PcGVuTm90aW9uYWwJAJ4KDAUVZXhjaGFuZ2VkUG9zaXRpb25TaXplBQdiYWREZWJ0BQtyZWFsaXplZFBubAUNbWFyZ2luVG9WYXVsdAUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBRZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBRdjdW11bGF0aXZlTm90aW9uYWxBZnRlcgUZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAUOdG90YWxMb25nQWZ0ZXIFD3RvdGFsU2hvcnRBZnRlcgEQZ2V0VHdhcFNwb3RQcmljZQAECG1pbnV0ZUlkCQBpAgkAaQIIBQlsYXN0QmxvY2sJdGltZXN0YW1wAOgHADwEDXN0YXJ0TWludXRlSWQJAGUCBQhtaW51dGVJZAUNVFdBUF9JTlRFUlZBTAQHbGlzdFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQ1rX2xhc3REYXRhU3RyAgAEBGxpc3QJALUJAgUHbGlzdFN0cgIBLAoBCGZpbHRlckZuAgthY2N1bXVsYXRvcgRuZXh0AwkAZwIFDXN0YXJ0TWludXRlSWQJAQ1wYXJzZUludFZhbHVlAQUEbmV4dAkAzQgCBQthY2N1bXVsYXRvcgkBDXBhcnNlSW50VmFsdWUBBQRuZXh0BQthY2N1bXVsYXRvcgQFbGlzdEYKAAIkbAUEbGlzdAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZmlsdGVyRm4CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAQIbWF4SW5kZXgDCQBmAgkAkAMBBQVsaXN0RgAACQCWAwEFBWxpc3RGCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbGlzdAAABAxsYXN0TWludXRlSWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUOa19sYXN0TWludXRlSWQAAAQWZW5kTGFzdEN1bXVsYXRpdmVQcmljZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgUda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UCAV8JAKQDAQUMbGFzdE1pbnV0ZUlkAAAEDGVuZExhc3RQcmljZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgUTa190d2FwRGF0YUxhc3RQcmljZQIBXwkApAMBBQxsYXN0TWludXRlSWQAAAQSbm93Q3VtdWxhdGl2ZVByaWNlCQBkAgUWZW5kTGFzdEN1bXVsYXRpdmVQcmljZQkAaAIJAGUCBQhtaW51dGVJZAUMbGFzdE1pbnV0ZUlkBQxlbmRMYXN0UHJpY2UEGHN0YXJ0TGFzdEN1bXVsYXRpdmVQcmljZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgUda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UCAV8JAKQDAQUIbWF4SW5kZXgAAAQOc3RhcnRMYXN0UHJpY2UJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIFE2tfdHdhcERhdGFMYXN0UHJpY2UCAV8JAKQDAQUIbWF4SW5kZXgAAAQUc3RhcnRDdW11bGF0aXZlUHJpY2UJAGQCBRhzdGFydExhc3RDdW11bGF0aXZlUHJpY2UJAGgCCQBlAgUNc3RhcnRNaW51dGVJZAUIbWF4SW5kZXgFDnN0YXJ0TGFzdFByaWNlCQBpAgkAZQIFEm5vd0N1bXVsYXRpdmVQcmljZQUUc3RhcnRDdW11bGF0aXZlUHJpY2UFDVRXQVBfSU5URVJWQUwBE2dldFRlcm1pbmFsQW1tU3RhdGUABA1fcG9zaXRpb25TaXplCQERdG90YWxQb3NpdGlvblNpemUAAwkAAAIFDV9wb3NpdGlvblNpemUAAAkAlAoCCQEGcXRBc3RSAAkBBmJzQXN0UgAECWRpcmVjdGlvbgkAZgIFDV9wb3NpdGlvblNpemUAAAQNJHQwMjk2MDQyOTc4MwkBCnN3YXBPdXRwdXQDBQlkaXJlY3Rpb24JAQNhYnMBBQ1fcG9zaXRpb25TaXplBwQVY3VycmVudE5ldE1hcmtldFZhbHVlCAUNJHQwMjk2MDQyOTc4MwJfMQQZdGVybWluYWxRdW90ZUFzc2V0UmVzZXJ2ZQgFDSR0MDI5NjA0Mjk3ODMCXzIEGHRlcm1pbmFsQmFzZUFzc2V0UmVzZXJ2ZQgFDSR0MDI5NjA0Mjk3ODMCXzMJAJQKAgUZdGVybWluYWxRdW90ZUFzc2V0UmVzZXJ2ZQUYdGVybWluYWxCYXNlQXNzZXRSZXNlcnZlARNnZXRRdW90ZUFzc2V0V2VpZ2h0BBBiYXNlQXNzZXRSZXNlcnZlEXRvdGFsUG9zaXRpb25TaXplEXF1b3RlQXNzZXRSZXNlcnZlC3RhcmdldFByaWNlBAFiCQC2AgEFEGJhc2VBc3NldFJlc2VydmUEAnN6CQC2AgEFEXRvdGFsUG9zaXRpb25TaXplBAFxCQC2AgEFEXF1b3RlQXNzZXRSZXNlcnZlBAFwCQC2AgEFC3RhcmdldFByaWNlBANiczIJAQVicG93ZAIJALcCAgUBYgUCc3oJALYCAQkAaAIAAgUMREVDSU1BTF9VTklUBARxYnMyCQEFYm11bGQCBQFxBQNiczIEA3BzNAkAuQICCQC2AgEABAkBBWJtdWxkAgUBcAUCc3oEA3NxcgkBBmJzcXJ0ZAEJAQVibXVsZAIFBHFiczIJALgCAgUBcQUDcHM0BAJicQkBBWJtdWxkAgUBYgUBcQQCcXMJAQVibXVsZAIFAXEFAnN6BAN0b3AJALcCAgkAtwICCQC+AgEFA3NxcgUCYnEFAnFzBANib3QJALkCAgkAtgIBAAIJAQVibXVsZAIFAXEFAnN6BAZyZXN1bHQJAQViZGl2ZAIFA3RvcAUDYm90CQCgAwEFBnJlc3VsdAEUZ2V0U3luY1Rlcm1pbmFsUHJpY2UBDl90ZXJtaW5hbFByaWNlBA1fcG9zaXRpb25TaXplCQERdG90YWxQb3NpdGlvblNpemUAAwkAAAIFDV9wb3NpdGlvblNpemUAAAQHX3F0QXN0UgkBBnF0QXN0UgAEB19ic0FzdFIJAQZic0FzdFIABAluZXdRdEFzdFcJAQRkaXZkAgkBBG11bGQCBQ5fdGVybWluYWxQcmljZQUHX2JzQXN0UgUHX3F0QXN0UgkAlQoDBQluZXdRdEFzdFcFDERFQ0lNQUxfVU5JVAAABAlkaXJlY3Rpb24JAGYCBQ1fcG9zaXRpb25TaXplAAAEFWN1cnJlbnROZXRNYXJrZXRWYWx1ZQgJAQpzd2FwT3V0cHV0AwUJZGlyZWN0aW9uCQEDYWJzAQUNX3Bvc2l0aW9uU2l6ZQcCXzEEB19xdEFzdFIJAQZxdEFzdFIABAdfYnNBc3RSCQEGYnNBc3RSAAQJbmV3UXRBc3RXCQETZ2V0UXVvdGVBc3NldFdlaWdodAQFB19ic0FzdFIFDV9wb3NpdGlvblNpemUFB19xdEFzdFIFDl90ZXJtaW5hbFByaWNlBAluZXdCc0FzdFcFDERFQ0lNQUxfVU5JVAQNbWFyZ2luVG9WYXVsdAgJAStnZXRQb3NpdGlvbk5vdGlvbmFsQW5kVW5yZWFsaXplZFBubEJ5VmFsdWVzBwUNX3Bvc2l0aW9uU2l6ZQUVY3VycmVudE5ldE1hcmtldFZhbHVlBQdfcXRBc3RSBQluZXdRdEFzdFcFB19ic0FzdFIFCW5ld0JzQXN0VwUPUE5MX09QVElPTl9TUE9UAl8yCQCVCgMFCW5ld1F0QXN0VwUJbmV3QnNBc3RXBQ1tYXJnaW5Ub1ZhdWx0AQpnZXRGdW5kaW5nAAQPdW5kZXJseWluZ1ByaWNlCQESZ2V0T3JhY2xlVHdhcFByaWNlAAQNc3BvdFR3YXBQcmljZQkBEGdldFR3YXBTcG90UHJpY2UABAdwcmVtaXVtCQBlAgUNc3BvdFR3YXBQcmljZQUPdW5kZXJseWluZ1ByaWNlAwMJAAACCQEWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAAAAYJAAACCQEVdG90YWxMb25nUG9zaXRpb25TaXplAAAACQCUCgIAAAAAAwkAZgIAAAUHcHJlbWl1bQQUc2hvcnRQcmVtaXVtRnJhY3Rpb24JAQRkaXZkAgkBBG11bGQCBQdwcmVtaXVtCQEUZnVuZGluZ1BlcmlvZERlY2ltYWwABQdPTkVfREFZBBNsb25nUHJlbWl1bUZyYWN0aW9uCQEEZGl2ZAIJAQRtdWxkAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24JARZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAkBFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQAJAJQKAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24FE2xvbmdQcmVtaXVtRnJhY3Rpb24EE2xvbmdQcmVtaXVtRnJhY3Rpb24JAQRkaXZkAgkBBG11bGQCBQdwcmVtaXVtCQEUZnVuZGluZ1BlcmlvZERlY2ltYWwABQdPTkVfREFZBBRzaG9ydFByZW1pdW1GcmFjdGlvbgkBBGRpdmQCCQEEbXVsZAIFE2xvbmdQcmVtaXVtRnJhY3Rpb24JARV0b3RhbExvbmdQb3NpdGlvblNpemUACQEWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQAJAJQKAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24FE2xvbmdQcmVtaXVtRnJhY3Rpb24BDmdldEFkanVzdGVkRmVlAgFpEF9iYXNlRmVlRGlzY291bnQECmJhc2VGZWVSYXcJAQNmZWUABAdiYXNlRmVlCQEEbXVsZAIFCmJhc2VGZWVSYXcFEF9iYXNlRmVlRGlzY291bnQEDSR0MDMyODc2MzM0ODQDCQBmAgkAkAMBCAUBaQhwYXltZW50cwABBAphcnRpZmFjdElkCQDYBAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAggJAJEDAggFAWkIcGF5bWVudHMAAQdhc3NldElkAhlJbnZhbGlkIGF0dGFjaGVkIGFydGlmYWN0BAxhcnRpZmFjdEtpbmQJAQRzdHJBAgkBEW5mdE1hbmFnZXJBZGRyZXNzAAkBDnRvQ29tcG9zaXRlS2V5AgUMa190b2tlbl90eXBlBQphcnRpZmFjdElkAwkAAAIFDGFydGlmYWN0S2luZAUYRkVFX1JFRFVDVElPTl9UT0tFTl9UWVBFBAlyZWR1Y3Rpb24JAQRpbnRBAgkBEW5mdE1hbmFnZXJBZGRyZXNzAAkBDnRvQ29tcG9zaXRlS2V5AgUNa190b2tlbl9wYXJhbQUKYXJ0aWZhY3RJZAQLYWRqdXN0ZWRGZWUJAQRtdWxkAgUHYmFzZUZlZQUJcmVkdWN0aW9uCQCUCgIFC2FkanVzdGVkRmVlBgkAAgECGUludmFsaWQgYXR0YWNoZWQgYXJ0aWZhY3QJAJQKAgUHYmFzZUZlZQcEC2FkanVzdGVkRmVlCAUNJHQwMzI4NzYzMzQ4NAJfMQQMYnVybkFydGlmYWN0CAUNJHQwMzI4NzYzMzQ4NAJfMgkAlAoCBQthZGp1c3RlZEZlZQUMYnVybkFydGlmYWN0AQ51cGRhdGVTZXR0aW5ncwkQX2luaXRNYXJnaW5SYXRpbwRfbW1yFF9saXF1aWRhdGlvbkZlZVJhdGlvDl9mdW5kaW5nUGVyaW9kBF9mZWUMX3NwcmVhZExpbWl0D19tYXhQcmljZUltcGFjdBhfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8PX21heFByaWNlU3ByZWFkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFrX2luaXRNYXJnaW5SYXRpbwUQX2luaXRNYXJnaW5SYXRpbwkAzAgCCQEMSW50ZWdlckVudHJ5AgUYa19tYWludGVuYW5jZU1hcmdpblJhdGlvBQRfbW1yCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRVrX2xpcXVpZGF0aW9uRmVlUmF0aW8FFF9saXF1aWRhdGlvbkZlZVJhdGlvCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9rX2Z1bmRpbmdQZXJpb2QFDl9mdW5kaW5nUGVyaW9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQVrX2ZlZQUEX2ZlZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUNa19zcHJlYWRMaW1pdAUMX3NwcmVhZExpbWl0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrX21heFByaWNlSW1wYWN0BQ9fbWF4UHJpY2VJbXBhY3QJAMwIAgkBDEludGVnZXJFbnRyeQIFGWtfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8FGF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwkAzAgCCQEMSW50ZWdlckVudHJ5AgUQa19tYXhQcmljZVNwcmVhZAUPX21heFByaWNlU3ByZWFkBQNuaWwBDXVwZGF0ZUZ1bmRpbmcFEV9uZXh0RnVuZGluZ0Jsb2NrJF9sYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbiVfbGF0ZXN0U2hvcnRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uEF9sb25nRnVuZGluZ1JhdGURX3Nob3J0RnVuZGluZ1JhdGUJAMwIAgkBDEludGVnZXJFbnRyeQIFEmtfbmV4dEZ1bmRpbmdCbG9jawURX25leHRGdW5kaW5nQmxvY2sJAMwIAgkBDEludGVnZXJFbnRyeQIFJWtfbGF0ZXN0TG9uZ0N1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FJF9sYXRlc3RMb25nQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgkAzAgCCQEMSW50ZWdlckVudHJ5AgUma19sYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24FJV9sYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24JAMwIAgkBDEludGVnZXJFbnRyeQIFEWtfbG9uZ0Z1bmRpbmdSYXRlBRBfbG9uZ0Z1bmRpbmdSYXRlCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRJrX3Nob3J0RnVuZGluZ1JhdGUFEV9zaG9ydEZ1bmRpbmdSYXRlBQNuaWwBE3VwZGF0ZVBvc2l0aW9uQXNzZXQCCF9hZGRyZXNzCF9hc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFD2tfcG9zaXRpb25Bc3NldAUIX2FkZHJlc3MFCF9hc3NldElkBQNuaWwBDnVwZGF0ZVBvc2l0aW9uBQhfYWRkcmVzcwVfc2l6ZQdfbWFyZ2luDV9vcGVuTm90aW9uYWwgX2xhdGVzdEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24JAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFDmtfcG9zaXRpb25TaXplBQhfYWRkcmVzcwUFX3NpemUJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFEGtfcG9zaXRpb25NYXJnaW4FCF9hZGRyZXNzBQdfbWFyZ2luCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBRZrX3Bvc2l0aW9uT3Blbk5vdGlvbmFsBQhfYWRkcmVzcwUNX29wZW5Ob3Rpb25hbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUua19wb3NpdGlvbkxhc3RVcGRhdGVkQ3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgUIX2FkZHJlc3MFIF9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uBQNuaWwBCmFwcGVuZFR3YXABBXByaWNlBAhtaW51dGVJZAkAaQIJAGkCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcADoBwA8BBBwcmV2aW91c01pbnV0ZUlkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFDmtfbGFzdE1pbnV0ZUlkAAADCQBmAgUQcHJldmlvdXNNaW51dGVJZAUIbWludXRlSWQJAAIBAhFUV0FQIG91dC1vZi1vcmRlcgQMbGFzdE1pbnV0ZUlkAwkAAAIFEHByZXZpb3VzTWludXRlSWQAAAUIbWludXRlSWQFEHByZXZpb3VzTWludXRlSWQDCQBmAgUIbWludXRlSWQFEHByZXZpb3VzTWludXRlSWQEE3ByZXZDdW11bGF0aXZlUHJpY2UJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIFHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlAgFfCQCkAwEFEHByZXZpb3VzTWludXRlSWQAAAQJcHJldlByaWNlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgkArAICBRNrX3R3YXBEYXRhTGFzdFByaWNlAgFfCQCkAwEFEHByZXZpb3VzTWludXRlSWQFBXByaWNlBBNsYXN0Q3VtdWxhdGl2ZVByaWNlCQBkAgUTcHJldkN1bXVsYXRpdmVQcmljZQkAaAIJAGUCBQhtaW51dGVJZAUMbGFzdE1pbnV0ZUlkBQlwcmV2UHJpY2UEBGxpc3QJAQtwdXNoVG9RdWV1ZQMJAQlzdHJUb0xpc3QBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFDWtfbGFzdERhdGFTdHICAAUNVFdBUF9JTlRFUlZBTAkApAMBBQhtaW51dGVJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBDnRvQ29tcG9zaXRlS2V5AgUda190d2FwRGF0YUxhc3RDdW11bGF0aXZlUHJpY2UJAKQDAQUIbWludXRlSWQFE2xhc3RDdW11bGF0aXZlUHJpY2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFE2tfdHdhcERhdGFMYXN0UHJpY2UJAKQDAQUIbWludXRlSWQFBXByaWNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBRprX3R3YXBEYXRhUHJldmlvdXNNaW51dGVJZAkApAMBBQhtaW51dGVJZAUQcHJldmlvdXNNaW51dGVJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgUOa19sYXN0TWludXRlSWQFCG1pbnV0ZUlkCQDMCAIJAQtTdHJpbmdFbnRyeQIFDWtfbGFzdERhdGFTdHIJAQlsaXN0VG9TdHIBBQRsaXN0BQNuaWwEGHR3YXBEYXRhUHJldmlvdXNNaW51dGVJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEOdG9Db21wb3NpdGVLZXkCBRprX3R3YXBEYXRhUHJldmlvdXNNaW51dGVJZAkApAMBBQhtaW51dGVJZAAABBNwcmV2Q3VtdWxhdGl2ZVByaWNlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQ50b0NvbXBvc2l0ZUtleQIFHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlCQCkAwEFGHR3YXBEYXRhUHJldmlvdXNNaW51dGVJZAAABAlwcmV2UHJpY2UJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBDnRvQ29tcG9zaXRlS2V5AgUTa190d2FwRGF0YUxhc3RQcmljZQkApAMBBRh0d2FwRGF0YVByZXZpb3VzTWludXRlSWQFBXByaWNlBBNsYXN0Q3VtdWxhdGl2ZVByaWNlCQBkAgUTcHJldkN1bXVsYXRpdmVQcmljZQkAaAIJAGUCBQhtaW51dGVJZAUYdHdhcERhdGFQcmV2aW91c01pbnV0ZUlkBQlwcmV2UHJpY2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ50b0NvbXBvc2l0ZUtleQIFHWtfdHdhcERhdGFMYXN0Q3VtdWxhdGl2ZVByaWNlCQCkAwEFCG1pbnV0ZUlkBRNsYXN0Q3VtdWxhdGl2ZVByaWNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBRNrX3R3YXBEYXRhTGFzdFByaWNlCQCkAwEFCG1pbnV0ZUlkBQVwcmljZQUDbmlsARF1cGRhdGVBbW1SZXNlcnZlcwIHX3F0QXN0UgdfYnNBc3RSCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRNrX3F1b3RlQXNzZXRSZXNlcnZlBQdfcXRBc3RSCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRJrX2Jhc2VBc3NldFJlc2VydmUFB19ic0FzdFIFA25pbAEQdXBkYXRlQW1tV2VpZ2h0cwIHX3F0QXN0VwdfYnNBc3RXCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRJrX3F1b3RlQXNzZXRXZWlnaHQFB19xdEFzdFcJAMwIAgkBDEludGVnZXJFbnRyeQIFEWtfYmFzZUFzc2V0V2VpZ2h0BQdfYnNBc3RXBQNuaWwBCXVwZGF0ZUFtbQcHX3F0QXN0UgdfYnNBc3RSF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyGF9jdW11bGF0aXZlTm90aW9uYWxBZnRlchVfb3BlbkludGVyZXN0Tm90aW9uYWwWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZRdfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQQHX3F0QXN0VwkBBnF0QXN0VwAEB19ic0FzdFcJAQZic0FzdFcAAwkBAiE9AgkAZQIFFl90b3RhbExvbmdQb3NpdGlvblNpemUFF190b3RhbFNob3J0UG9zaXRpb25TaXplBRdfdG90YWxQb3NpdGlvblNpemVBZnRlcgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhhJbnZhbGlkIEFNTSBzdGF0ZSBkYXRhOiAJAKQDAQUWX3RvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQIEICsgIAkApAMBBRdfdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQIEICE9IAkApAMBBRdfdG90YWxQb3NpdGlvblNpemVBZnRlcgkAzggCCQDOCAIJARF1cGRhdGVBbW1SZXNlcnZlcwIFB19xdEFzdFIFB19ic0FzdFIJAMwIAgkBDEludGVnZXJFbnRyeQIFE2tfdG90YWxQb3NpdGlvblNpemUFF190b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRRrX2N1bXVsYXRpdmVOb3Rpb25hbAUYX2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRZrX29wZW5JbnRlcmVzdE5vdGlvbmFsBRVfb3BlbkludGVyZXN0Tm90aW9uYWwJAMwIAgkBDEludGVnZXJFbnRyeQIFF2tfdG90YWxMb25nUG9zaXRpb25TaXplBRZfdG90YWxMb25nUG9zaXRpb25TaXplCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRhrX3RvdGFsU2hvcnRQb3NpdGlvblNpemUFF190b3RhbFNob3J0UG9zaXRpb25TaXplBQNuaWwJAQphcHBlbmRUd2FwAQkBBGRpdmQCCQEEbXVsZAIFB19xdEFzdFIFB19xdEFzdFcJAQRtdWxkAgUHX2JzQXN0UgUHX2JzQXN0VwEOZGVsZXRlUG9zaXRpb24BCF9hZGRyZXNzCQDMCAIJAQtEZWxldGVFbnRyeQEJAQ50b0NvbXBvc2l0ZUtleQIFDmtfcG9zaXRpb25TaXplBQhfYWRkcmVzcwkAzAgCCQELRGVsZXRlRW50cnkBCQEOdG9Db21wb3NpdGVLZXkCBRBrX3Bvc2l0aW9uTWFyZ2luBQhfYWRkcmVzcwkAzAgCCQELRGVsZXRlRW50cnkBCQEOdG9Db21wb3NpdGVLZXkCBRZrX3Bvc2l0aW9uT3Blbk5vdGlvbmFsBQhfYWRkcmVzcwkAzAgCCQELRGVsZXRlRW50cnkBCQEOdG9Db21wb3NpdGVLZXkCBS5rX3Bvc2l0aW9uTGFzdFVwZGF0ZWRDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uBQhfYWRkcmVzcwkAzAgCCQELRGVsZXRlRW50cnkBCQEOdG9Db21wb3NpdGVLZXkCBQ9rX3Bvc2l0aW9uQXNzZXQFCF9hZGRyZXNzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOdG9Db21wb3NpdGVLZXkCBRRrX3Bvc2l0aW9uQ2xvc2VkRGF0ZQUIX2FkZHJlc3MIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQNuaWwBCHdpdGhkcmF3AghfYWRkcmVzcwdfYW1vdW50BAdiYWxhbmNlCQDwBwIFBHRoaXMJAQpxdW90ZUFzc2V0AAMJAGYCBQdfYW1vdW50BQdiYWxhbmNlCQACAQkArAICCQCsAgIJAKwCAgITVW5hYmxlIHRvIHdpdGhkcmF3IAkApAMBBQdfYW1vdW50AhcgZnJvbSBjb250cmFjdCBiYWxhbmNlIAkApAMBBQdiYWxhbmNlCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFCF9hZGRyZXNzBQdfYW1vdW50CQEKcXVvdGVBc3NldAAFA25pbAENdXBkYXRlQmFsYW5jZQEBaQMJAGYCAAAFAWkJAAIBAgdCYWxhbmNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQlrX2JhbGFuY2UFAWkFA25pbAELdHJhbnNmZXJGZWUBAWkJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBDnN0YWtpbmdBZGRyZXNzAAUBaQkBCnF1b3RlQXNzZXQABQNuaWwBDmRvQnVybkFydGlmYWN0Ag1fYnVybkFydGlmYWN0AWkDBQ1fYnVybkFydGlmYWN0CQDMCAIJAQRCdXJuAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCAkAkQMCCAUBaQhwYXltZW50cwABB2Fzc2V0SWQCEEludmFsaWQgYXJ0aWZhY3QAAQUDbmlsBQNuaWwBF2lzU2FtZUFzc2V0T3JOb1Bvc2l0aW9uAgdfdHJhZGVyCF9hc3NldElkBA9vbGRQb3NpdGlvblNpemUICQELZ2V0UG9zaXRpb24BBQdfdHJhZGVyAl8xAwkAAAIFD29sZFBvc2l0aW9uU2l6ZQAABgkAAAIJARBnZXRQb3NpdGlvbkFzc2V0AQUHX3RyYWRlcgUIX2Fzc2V0SWQBC2lzU2FtZUFzc2V0AgdfdHJhZGVyCF9hc3NldElkCQAAAgkBEGdldFBvc2l0aW9uQXNzZXQBBQdfdHJhZGVyBQhfYXNzZXRJZAEeZ2V0Qm9ycm93ZWRCeVRyYWRlckluTWFya2V0S2V5AwRfYW1tCF9hc3NldElkB190cmFkZXIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFIGtfdHJhZGVyX21hcmtldF9hc3NldF9jb2xsYXRlcmFsAgFfBQRfYW1tAgFfBQhfYXNzZXRJZAIBXwUHX3RyYWRlcgETZ2V0Qm9ycm93ZWRCeVRyYWRlcgEHX3RyYWRlcgQNcG9zaXRpb25Bc3NldAkBEGdldFBvc2l0aW9uQXNzZXQBBQdfdHJhZGVyAwkAAAIFDXBvc2l0aW9uQXNzZXQJANgEAQkBCnF1b3RlQXNzZXQACQCUCgIAAAUNcG9zaXRpb25Bc3NldAQDa2V5CQEeZ2V0Qm9ycm93ZWRCeVRyYWRlckluTWFya2V0S2V5AwkApQgBBQR0aGlzBQ1wb3NpdGlvbkFzc2V0BQdfdHJhZGVyBAZib3Jyb3cJAQt2YWx1ZU9yRWxzZQIJAJoIAgkBEWNvbGxhdGVyYWxBZGRyZXNzAAUDa2V5AAAJAJQKAgUGYm9ycm93BQ1wb3NpdGlvbkFzc2V0FQFpAQVwYXVzZQADCQECIT0CCAUBaQZjYWxsZXIJAQxhZG1pbkFkZHJlc3MACQACAQIaSW52YWxpZCB0b2dnbGVQYXVzZSBwYXJhbXMJAMwIAgkBDEJvb2xlYW5FbnRyeQIFCGtfcGF1c2VkBgUDbmlsAWkBB3VucGF1c2UAAwkBAiE9AggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAkAAgECGkludmFsaWQgdG9nZ2xlUGF1c2UgcGFyYW1zCQDMCAIJAQxCb29sZWFuRW50cnkCBQhrX3BhdXNlZAcFA25pbAFpAQxhZGRMaXF1aWRpdHkBEV9xdW90ZUFzc2V0QW1vdW50AwMJAQIhPQIIBQFpBmNhbGxlcgkBDGFkbWluQWRkcmVzcwAGCQBnAgAABRFfcXVvdGVBc3NldEFtb3VudAkAAgECG0ludmFsaWQgYWRkTGlxdWlkaXR5IHBhcmFtcwQHX3F0QXN0UgkBBnF0QXN0UgAEB19ic0FzdFIJAQZic0FzdFIABAdfcXRBc3RXCQEGcXRBc3RXAAQHX2JzQXN0VwkBBmJzQXN0VwAEBXByaWNlCQEEZGl2ZAIJAQRtdWxkAgUHX3F0QXN0UgUHX3F0QXN0VwkBBG11bGQCBQdfYnNBc3RSBQdfYnNBc3RXBBRiYXNlQXNzZXRBbW91bnRUb0FkZAkBBGRpdmQCBRFfcXVvdGVBc3NldEFtb3VudAUFcHJpY2UEC3F0QXN0UkFmdGVyCQBkAgUHX3F0QXN0UgURX3F1b3RlQXNzZXRBbW91bnQEC2JzQXN0UkFmdGVyCQBkAgUHX2JzQXN0UgUUYmFzZUFzc2V0QW1vdW50VG9BZGQJARF1cGRhdGVBbW1SZXNlcnZlcwIFC3F0QXN0UkFmdGVyBQtic0FzdFJBZnRlcgFpAQ9yZW1vdmVMaXF1aWRpdHkBEV9xdW90ZUFzc2V0QW1vdW50AwMJAQIhPQIIBQFpBmNhbGxlcgkBDGFkbWluQWRkcmVzcwAGCQBnAgAABRFfcXVvdGVBc3NldEFtb3VudAkAAgECHkludmFsaWQgcmVtb3ZlTGlxdWlkaXR5IHBhcmFtcwQHX3F0QXN0UgkBBnF0QXN0UgAEB19ic0FzdFIJAQZic0FzdFIABAdfcXRBc3RXCQEGcXRBc3RXAAQHX2JzQXN0VwkBBmJzQXN0VwAEBXByaWNlCQEEZGl2ZAIJAQRtdWxkAgUHX3F0QXN0UgUHX3F0QXN0VwkBBG11bGQCBQdfYnNBc3RSBQdfYnNBc3RXBBdiYXNlQXNzZXRBbW91bnRUb1JlbW92ZQkBBGRpdmQCBRFfcXVvdGVBc3NldEFtb3VudAUFcHJpY2UEC3F0QXN0UkFmdGVyCQBlAgUHX3F0QXN0UgURX3F1b3RlQXNzZXRBbW91bnQEC2JzQXN0UkFmdGVyCQBlAgUHX2JzQXN0UgUXYmFzZUFzc2V0QW1vdW50VG9SZW1vdmUJARF1cGRhdGVBbW1SZXNlcnZlcwIFC3F0QXN0UkFmdGVyBQtic0FzdFJBZnRlcgFpAQ5jaGFuZ2VTZXR0aW5ncwkQX2luaXRNYXJnaW5SYXRpbwRfbW1yFF9saXF1aWRhdGlvbkZlZVJhdGlvDl9mdW5kaW5nUGVyaW9kBF9mZWUMX3NwcmVhZExpbWl0D19tYXhQcmljZUltcGFjdBhfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8PX21heFByaWNlU3ByZWFkAwkBAiE9AggFAWkGY2FsbGVyCQEMYWRtaW5BZGRyZXNzAAkAAgECHUludmFsaWQgY2hhbmdlU2V0dGluZ3MgcGFyYW1zCQEOdXBkYXRlU2V0dGluZ3MJBRBfaW5pdE1hcmdpblJhdGlvBQRfbW1yBRRfbGlxdWlkYXRpb25GZWVSYXRpbwUOX2Z1bmRpbmdQZXJpb2QFBF9mZWUFDF9zcHJlYWRMaW1pdAUPX21heFByaWNlSW1wYWN0BRhfcGFydGlhbExpcXVpZGF0aW9uUmF0aW8FD19tYXhQcmljZVNwcmVhZAFpAQppbml0aWFsaXplDgdfcXRBc3RSB19ic0FzdFIOX2Z1bmRpbmdQZXJpb2QQX2luaXRNYXJnaW5SYXRpbwRfbW1yFF9saXF1aWRhdGlvbkZlZVJhdGlvBF9mZWUHX29yYWNsZQpfb3JhY2xlS2V5DF9jb29yZGluYXRvcgxfc3ByZWFkTGltaXQPX21heFByaWNlSW1wYWN0GF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbw9fbWF4UHJpY2VTcHJlYWQDAwMDAwMDAwMDAwMJAGcCAAAFB19xdEFzdFIGCQBnAgAABQdfYnNBc3RSBgkAZwIAAAUOX2Z1bmRpbmdQZXJpb2QGCQBnAgAABRBfaW5pdE1hcmdpblJhdGlvBgkAZwIAAAUEX21tcgYJAGcCAAAFFF9saXF1aWRhdGlvbkZlZVJhdGlvBgkAZwIAAAUEX2ZlZQYJAGcCAAAFDF9zcHJlYWRMaW1pdAYJAGcCAAAFD19tYXhQcmljZUltcGFjdAYJAGcCAAAFGF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwYJAGcCAAAFD19tYXhQcmljZVNwcmVhZAYJAQtpbml0aWFsaXplZAAJAAIBAh1JbnZhbGlkIGluaXRpYWxpemUgcGFyYW1ldGVycwkAzggCCQDOCAIJAM4IAgkAzggCCQEJdXBkYXRlQW1tBwUHX3F0QXN0UgUHX2JzQXN0UgAAAAAAAAAAAAAJAQ51cGRhdGVTZXR0aW5ncwkFEF9pbml0TWFyZ2luUmF0aW8FBF9tbXIFFF9saXF1aWRhdGlvbkZlZVJhdGlvBQ5fZnVuZGluZ1BlcmlvZAUEX2ZlZQUMX3NwcmVhZExpbWl0BQ9fbWF4UHJpY2VJbXBhY3QFGF9wYXJ0aWFsTGlxdWlkYXRpb25SYXRpbwUPX21heFByaWNlU3ByZWFkCQENdXBkYXRlRnVuZGluZwUJAGQCCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUOX2Z1bmRpbmdQZXJpb2QAAAAAAAAAAAkBDXVwZGF0ZUJhbGFuY2UBAAAJAMwIAgkBDEJvb2xlYW5FbnRyeQIFDWtfaW5pdGlhbGl6ZWQGCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWtfb3JhBQdfb3JhY2xlCQDMCAIJAQtTdHJpbmdFbnRyeQIFCWtfb3JhX2tleQUKX29yYWNsZUtleQkAzAgCCQELU3RyaW5nRW50cnkCBRRrX2Nvb3JkaW5hdG9yQWRkcmVzcwUMX2Nvb3JkaW5hdG9yBQNuaWwBaQESc2V0SW5pdE1hcmdpblJhdGlvARBfaW5pdE1hcmdpblJhdGlvAwMJAGcCAAAFEF9pbml0TWFyZ2luUmF0aW8GCQEBIQEJAQtpbml0aWFsaXplZAAJAAIBAiVJbnZhbGlkIHNldEluaXRNYXJnaW5SYXRpbyBwYXJhbWV0ZXJzCQEOdXBkYXRlU2V0dGluZ3MJBRBfaW5pdE1hcmdpblJhdGlvCQEWbWFpbnRlbmFuY2VNYXJnaW5SYXRpbwAJARNsaXF1aWRhdGlvbkZlZVJhdGlvAAkBEGZ1bmRpbmdQZXJpb2RSYXcACQEDZmVlAAkBC3NwcmVhZExpbWl0AAkBDm1heFByaWNlSW1wYWN0AAkBF3BhcnRpYWxMaXF1aWRhdGlvblJhdGlvAAkBDm1heFByaWNlU3ByZWFkAAFpARBkZWNyZWFzZVBvc2l0aW9uAwdfYW1vdW50CV9sZXZlcmFnZRNfbWluQmFzZUFzc2V0QW1vdW50BARzeW5jCQD8BwQFBHRoaXMCGXN5bmNUZXJtaW5hbFByaWNlVG9PcmFjbGUFA25pbAUDbmlsAwkAAAIFBHN5bmMFBHN5bmMDAwMDAwkAZwIAAAUHX2Ftb3VudAYJAQEhAQkBC2luaXRpYWxpemVkAAYJAQEhAQkBFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8DCQEEZGl2ZAIFDERFQ0lNQUxfVU5JVAUJX2xldmVyYWdlCQEPaW5pdE1hcmdpblJhdGlvAAYGCQEBIQEJARNyZXF1aXJlT3BlblBvc2l0aW9uAQkApQgBCAUBaQZjYWxsZXIGCQEGcGF1c2VkAAkAAgECI0ludmFsaWQgZGVjcmVhc2VQb3NpdGlvbiBwYXJhbWV0ZXJzBA0kdDA0NTQ2NDQ1NjE2CQELZ2V0UG9zaXRpb24BCQClCAEIBQFpBmNhbGxlcgQPb2xkUG9zaXRpb25TaXplCAUNJHQwNDU0NjQ0NTYxNgJfMQQRb2xkUG9zaXRpb25NYXJnaW4IBQ0kdDA0NTQ2NDQ1NjE2Al8yBBdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDQ1NDY0NDU2MTYCXzMEFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwNDU0NjQ0NTYxNgJfNAQKX2RpcmVjdGlvbgMJAGYCBQ9vbGRQb3NpdGlvblNpemUAAAUJRElSX1NIT1JUBQhESVJfTE9ORwQFaXNBZGQJAAACBQpfZGlyZWN0aW9uBQhESVJfTE9ORwQMb3Blbk5vdGlvbmFsCQEEbXVsZAIFB19hbW91bnQFCV9sZXZlcmFnZQQNJHQwNDU3ODk0NTkwNQkBI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAgkApQgBCAUBaQZjYWxsZXIFD1BOTF9PUFRJT05fU1BPVAQTb2xkUG9zaXRpb25Ob3Rpb25hbAgFDSR0MDQ1Nzg5NDU5MDUCXzEEDXVucmVhbGl6ZWRQbmwIBQ0kdDA0NTc4OTQ1OTA1Al8yBA0kdDA0NTkxMTQ4NDYwAwkAZgIFE29sZFBvc2l0aW9uTm90aW9uYWwFDG9wZW5Ob3Rpb25hbAQNJHQwNDYyODg0NjUwNwkBCXN3YXBJbnB1dAIFBWlzQWRkBQxvcGVuTm90aW9uYWwEFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQgFDSR0MDQ2Mjg4NDY1MDcCXzEEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA0NjI4ODQ2NTA3Al8yBBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA0NjI4ODQ2NTA3Al8zBBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNDYyODg0NjUwNwJfNAQXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIIBQ0kdDA0NjI4ODQ2NTA3Al81BBhleGNoYW5nZWRQb3NpdGlvblNpemVBYnMJAQNhYnMBBRVleGNoYW5nZWRQb3NpdGlvblNpemUDAwkBAiE9AgUTX21pbkJhc2VBc3NldEFtb3VudAAACQBmAgUTX21pbkJhc2VBc3NldEFtb3VudAUYZXhjaGFuZ2VkUG9zaXRpb25TaXplQWJzBwkAAgEJAKwCAgkArAICCQCsAgICJVRvbyBsaXR0bGUgYmFzZSBhc3NldCBleGNoYW5nZWQsIGdvdCAJAKQDAQUYZXhjaGFuZ2VkUG9zaXRpb25TaXplQWJzAgogZXhwZWN0ZWQgCQCkAwEFE19taW5CYXNlQXNzZXRBbW91bnQEC3JlYWxpemVkUG5sCQEEZGl2ZAIJAQRtdWxkAgUNdW5yZWFsaXplZFBubAUYZXhjaGFuZ2VkUG9zaXRpb25TaXplQWJzCQEDYWJzAQUPb2xkUG9zaXRpb25TaXplBA0kdDA0Njk0NDQ3MTg5CQEiY2FsY1JlbWFpbk1hcmdpbldpdGhGdW5kaW5nUGF5bWVudAQFD29sZFBvc2l0aW9uU2l6ZQURb2xkUG9zaXRpb25NYXJnaW4FFG9sZFBvc2l0aW9uTHN0VXBkQ1BGBQtyZWFsaXplZFBubAQMcmVtYWluTWFyZ2luCAUNJHQwNDY5NDQ0NzE4OQJfMQQHYmFkRGVidAgFDSR0MDQ2OTQ0NDcxODkCXzIEDmZ1bmRpbmdQYXltZW50CAUNJHQwNDY5NDQ0NzE4OQJfMwQZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAUMb3Blbk5vdGlvbmFsBBJ1bnJlYWxpemVkUG5sQWZ0ZXIJAGUCBQ11bnJlYWxpemVkUG5sBQtyZWFsaXplZFBubAQScmVtYWluT3Blbk5vdGlvbmFsAwkAZgIFD29sZFBvc2l0aW9uU2l6ZQAACQBlAgkAZQIFE29sZFBvc2l0aW9uTm90aW9uYWwFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQFEnVucmVhbGl6ZWRQbmxBZnRlcgkAZQIJAGQCBRJ1bnJlYWxpemVkUG5sQWZ0ZXIFE29sZFBvc2l0aW9uTm90aW9uYWwFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQED25ld1Bvc2l0aW9uU2l6ZQkAZAIFD29sZFBvc2l0aW9uU2l6ZQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplCQCdCgsFD25ld1Bvc2l0aW9uU2l6ZQUMcmVtYWluTWFyZ2luCQEDYWJzAQUScmVtYWluT3Blbk5vdGlvbmFsCQEfbGF0ZXN0Q3VtdWxhdGl2ZVByZW1pdW1GcmFjdGlvbgEFD25ld1Bvc2l0aW9uU2l6ZQUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBRdjdW11bGF0aXZlTm90aW9uYWxBZnRlcgkAZQIJARRvcGVuSW50ZXJlc3ROb3Rpb25hbAAFDG9wZW5Ob3Rpb25hbAkAZQIJARV0b3RhbExvbmdQb3NpdGlvblNpemUAAwkAZgIFD25ld1Bvc2l0aW9uU2l6ZQAACQEDYWJzAQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplAAAJAGUCCQEWdG90YWxTaG9ydFBvc2l0aW9uU2l6ZQADCQBmAgAABQ9uZXdQb3NpdGlvblNpemUJAQNhYnMBBRVleGNoYW5nZWRQb3NpdGlvblNpemUAAAkAAgECFENsb3NlIHBvc2l0aW9uIGZpcnN0BA9uZXdQb3NpdGlvblNpemUIBQ0kdDA0NTkxMTQ4NDYwAl8xBBduZXdQb3NpdGlvblJlbWFpbk1hcmdpbggFDSR0MDQ1OTExNDg0NjACXzIEF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsCAUNJHQwNDU5MTE0ODQ2MAJfMwQUbmV3UG9zaXRpb25MYXRlc3RDUEYIBQ0kdDA0NTkxMTQ4NDYwAl80BBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA0NTkxMTQ4NDYwAl81BBZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwNDU5MTE0ODQ2MAJfNgQWdG90YWxQb3NpdGlvblNpemVBZnRlcggFDSR0MDQ1OTExNDg0NjACXzcEF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCAUNJHQwNDU5MTE0ODQ2MAJfOAQZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcggFDSR0MDQ1OTExNDg0NjACXzkEDnRvdGFsTG9uZ0FmdGVyCAUNJHQwNDU5MTE0ODQ2MANfMTAED3RvdGFsU2hvcnRBZnRlcggFDSR0MDQ1OTExNDg0NjADXzExBA5ub3RpZnlOb3Rpb25hbAkA/AcECQEMbWluZXJBZGRyZXNzAAIObm90aWZ5Tm90aW9uYWwJAMwIAgkApQgBCAUBaQZjYWxsZXIJAMwIAgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFA25pbAUDbmlsAwkAAAIFDm5vdGlmeU5vdGlvbmFsBQ5ub3RpZnlOb3Rpb25hbAkAzggCCQEOdXBkYXRlUG9zaXRpb24FCQClCAEIBQFpBmNhbGxlcgUPbmV3UG9zaXRpb25TaXplBRduZXdQb3NpdGlvblJlbWFpbk1hcmdpbgUXbmV3UG9zaXRpb25PcGVuTm90aW9uYWwFFG5ld1Bvc2l0aW9uTGF0ZXN0Q1BGCQEJdXBkYXRlQW1tBwUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBRZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBRdjdW11bGF0aXZlTm90aW9uYWxBZnRlcgUZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgUOdG90YWxMb25nQWZ0ZXIFD3RvdGFsU2hvcnRBZnRlcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARBpbmNyZWFzZVBvc2l0aW9uBApfZGlyZWN0aW9uCV9sZXZlcmFnZRNfbWluQmFzZUFzc2V0QW1vdW50CF9yZWZMaW5rBARzeW5jCQD8BwQFBHRoaXMCGXN5bmNUZXJtaW5hbFByaWNlVG9PcmFjbGUFA25pbAUDbmlsAwkAAAIFBHN5bmMFBHN5bmMEB190cmFkZXIJAKUIAQgFAWkGY2FsbGVyBApfcmF3QW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQIX2Fzc2V0SWQICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQLX2Fzc2V0SWRTdHIJANgEAQkBBXZhbHVlAQUIX2Fzc2V0SWQEDGlzUXVvdGVBc3NldAkAAAIFCF9hc3NldElkCQEKcXVvdGVBc3NldAAEEWlzQ29sbGF0ZXJhbEFzc2V0CQEQaXNXaGl0ZWxpc3RBc3NldAEFC19hc3NldElkU3RyAwMDAwMDAwMJAQIhPQIFCl9kaXJlY3Rpb24FCERJUl9MT05HCQECIT0CBQpfZGlyZWN0aW9uBQlESVJfU0hPUlQHBgkAZwIAAAUKX3Jhd0Ftb3VudAYJAQEhAQkBC2luaXRpYWxpemVkAAYDCQEBIQEFDGlzUXVvdGVBc3NldAkBASEBBRFpc0NvbGxhdGVyYWxBc3NldAcGCQEBIQEJARdpc1NhbWVBc3NldE9yTm9Qb3NpdGlvbgIFB190cmFkZXIFC19hc3NldElkU3RyBgkBASEBCQEWcmVxdWlyZU1vcmVNYXJnaW5SYXRpbwMJAQRkaXZkAgUMREVDSU1BTF9VTklUBQlfbGV2ZXJhZ2UJAQ9pbml0TWFyZ2luUmF0aW8ABgYJAQZwYXVzZWQACQACAQIjSW52YWxpZCBpbmNyZWFzZVBvc2l0aW9uIHBhcmFtZXRlcnMEEGRvR2V0RmVlRGlzY291bnQJAPwHBAkBDG1pbmVyQWRkcmVzcwACEmNvbXB1dGVGZWVEaXNjb3VudAkAzAgCBQdfdHJhZGVyBQNuaWwFA25pbAMJAAACBRBkb0dldEZlZURpc2NvdW50BRBkb0dldEZlZURpc2NvdW50BAtmZWVEaXNjb3VudAQHJG1hdGNoMAUQZG9HZXRGZWVEaXNjb3VudAMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAiFJbnZhbGlkIGNvbXB1dGVGZWVEaXNjb3VudCByZXN1bHQEDSR0MDUwMTIzNTAxODcJAQ5nZXRBZGp1c3RlZEZlZQIFAWkFC2ZlZURpc2NvdW50BAthZGp1c3RlZEZlZQgFDSR0MDUwMTIzNTAxODcCXzEEDGJ1cm5BcnRpZmFjdAgFDSR0MDUwMTIzNTAxODcCXzIEDHJhd0ZlZUFtb3VudAkBBG11bGQCBQpfcmF3QW1vdW50BQthZGp1c3RlZEZlZQQHX2Ftb3VudAkAZQIFCl9yYXdBbW91bnQFDHJhd0ZlZUFtb3VudAQTZGlzdHJpYnV0ZUZlZUFtb3VudAMFEWlzQ29sbGF0ZXJhbEFzc2V0BAhkb0JvcnJvdwkA/AcECQERY29sbGF0ZXJhbEFkZHJlc3MAAgZib3Jyb3cJAMwIAgUHX3RyYWRlcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQhfYXNzZXRJZAUHX2Ftb3VudAUDbmlsAwkAAAIFCGRvQm9ycm93BQhkb0JvcnJvdwQNYmFsYW5jZUJlZm9yZQkA8AcCBQR0aGlzCQEKcXVvdGVBc3NldAADCQAAAgUNYmFsYW5jZUJlZm9yZQUNYmFsYW5jZUJlZm9yZQQGZG9Td2FwCQD8BwQJAQtzd2FwQWRkcmVzcwACBHN3YXAJAMwIAgkA2AQBCQEKcXVvdGVBc3NldAAJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFCF9hc3NldElkBQxyYXdGZWVBbW91bnQFA25pbAMJAAACBQZkb1N3YXAFBmRvU3dhcAQMYmFsYW5jZUFmdGVyCQDwBwIFBHRoaXMJAQpxdW90ZUFzc2V0AAMJAAACBQxiYWxhbmNlQWZ0ZXIFDGJhbGFuY2VBZnRlcgQPZXhjaGFuZ2VkQW1vdW50CQBlAgUMYmFsYW5jZUFmdGVyBQ1iYWxhbmNlQmVmb3JlAwkAAAIFD2V4Y2hhbmdlZEFtb3VudAUPZXhjaGFuZ2VkQW1vdW50BQ9leGNoYW5nZWRBbW91bnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FDHJhd0ZlZUFtb3VudAMJAAACBRNkaXN0cmlidXRlRmVlQW1vdW50BRNkaXN0cmlidXRlRmVlQW1vdW50BA5yZWZlcnJlckZlZUFueQkA/AcECQEPcmVmZXJyYWxBZGRyZXNzAAIVYWNjZXB0UGF5bWVudFdpdGhMaW5rCQDMCAIFB190cmFkZXIJAMwIAgUIX3JlZkxpbmsFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABRNkaXN0cmlidXRlRmVlQW1vdW50BQNuaWwDCQAAAgUOcmVmZXJyZXJGZWVBbnkFDnJlZmVycmVyRmVlQW55BAtyZWZlcnJlckZlZQQHJG1hdGNoMAUOcmVmZXJyZXJGZWVBbnkDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4CQACAQITSW52YWxpZCByZWZlcnJlckZlZQQJZmVlQW1vdW50CQBlAgUTZGlzdHJpYnV0ZUZlZUFtb3VudAULcmVmZXJyZXJGZWUEDSR0MDUxNTAzNTE2NDMJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIED29sZFBvc2l0aW9uU2l6ZQgFDSR0MDUxNTAzNTE2NDMCXzEEEW9sZFBvc2l0aW9uTWFyZ2luCAUNJHQwNTE1MDM1MTY0MwJfMgQXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDA1MTUwMzUxNjQzAl8zBBRvbGRQb3NpdGlvbkxzdFVwZENQRggFDSR0MDUxNTAzNTE2NDMCXzQEDWlzTmV3UG9zaXRpb24JAAACBQ9vbGRQb3NpdGlvblNpemUAAAQPaXNTYW1lRGlyZWN0aW9uAwkAZgIFD29sZFBvc2l0aW9uU2l6ZQAACQAAAgUKX2RpcmVjdGlvbgUIRElSX0xPTkcJAAACBQpfZGlyZWN0aW9uBQlESVJfU0hPUlQEDmV4cGFuZEV4aXN0aW5nAwkBASEBBQ1pc05ld1Bvc2l0aW9uBQ9pc1NhbWVEaXJlY3Rpb24HBAVpc0FkZAkAAAIFCl9kaXJlY3Rpb24FCERJUl9MT05HBA0kdDA1MTkzMjU0NTE3AwMFDWlzTmV3UG9zaXRpb24GBQ5leHBhbmRFeGlzdGluZwQMb3Blbk5vdGlvbmFsCQEEbXVsZAIFB19hbW91bnQFCV9sZXZlcmFnZQQNJHQwNTIzNTY1MjU2MgkBCXN3YXBJbnB1dAIFBWlzQWRkBQxvcGVuTm90aW9uYWwEFWFtb3VudEJhc2VBc3NldEJvdWdodAgFDSR0MDUyMzU2NTI1NjICXzEEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1MjM1NjUyNTYyAl8yBBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1MjM1NjUyNTYyAl8zBBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNTIzNTY1MjU2MgJfNAQXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIIBQ0kdDA1MjM1NjUyNTYyAl81AwMJAQIhPQIFE19taW5CYXNlQXNzZXRBbW91bnQAAAkAZgIFE19taW5CYXNlQXNzZXRBbW91bnQJAQNhYnMBBRVhbW91bnRCYXNlQXNzZXRCb3VnaHQHCQACAQkArAICCQCsAgIJAKwCAgINTGltaXQgZXJyb3I6IAkApAMBCQEDYWJzAQUVYW1vdW50QmFzZUFzc2V0Qm91Z2h0AgMgPCAJAKQDAQUTX21pbkJhc2VBc3NldEFtb3VudAQPbmV3UG9zaXRpb25TaXplCQBkAgUPb2xkUG9zaXRpb25TaXplBRVhbW91bnRCYXNlQXNzZXRCb3VnaHQEGWluY3JlYXNlTWFyZ2luUmVxdWlyZW1lbnQJAQRkaXZkAgUMb3Blbk5vdGlvbmFsBQlfbGV2ZXJhZ2UEDSR0MDUyOTQzNTMxODIJASJjYWxjUmVtYWluTWFyZ2luV2l0aEZ1bmRpbmdQYXltZW50BAUPb2xkUG9zaXRpb25TaXplBRFvbGRQb3NpdGlvbk1hcmdpbgUUb2xkUG9zaXRpb25Mc3RVcGRDUEYFGWluY3JlYXNlTWFyZ2luUmVxdWlyZW1lbnQEDHJlbWFpbk1hcmdpbggFDSR0MDUyOTQzNTMxODICXzEEAngxCAUNJHQwNTI5NDM1MzE4MgJfMgQCeDIIBQ0kdDA1Mjk0MzUzMTgyAl8zAwkBASEBCQEZcmVxdWlyZU5vdE92ZXJTcHJlYWRMaW1pdAIFFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFFWJhc2VBc3NldFJlc2VydmVBZnRlcgkAAgECFU92ZXIgbWF4IHNwcmVhZCBsaW1pdAkAnQoLBQ9uZXdQb3NpdGlvblNpemUFDHJlbWFpbk1hcmdpbgkAZAIFF29sZFBvc2l0aW9uT3Blbk5vdGlvbmFsBQxvcGVuTm90aW9uYWwJAR9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQUPbmV3UG9zaXRpb25TaXplBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCQBkAgkBFG9wZW5JbnRlcmVzdE5vdGlvbmFsAAUMb3Blbk5vdGlvbmFsCQBkAgkBFXRvdGFsTG9uZ1Bvc2l0aW9uU2l6ZQADCQBmAgUPbmV3UG9zaXRpb25TaXplAAAJAQNhYnMBBRVhbW91bnRCYXNlQXNzZXRCb3VnaHQAAAkAZAIJARZ0b3RhbFNob3J0UG9zaXRpb25TaXplAAMJAGYCAAAFD25ld1Bvc2l0aW9uU2l6ZQkBA2FicwEFFWFtb3VudEJhc2VBc3NldEJvdWdodAAABAxvcGVuTm90aW9uYWwJAQRtdWxkAgUHX2Ftb3VudAUJX2xldmVyYWdlBA0kdDA1NDIxMDU0MzI2CQEjZ2V0UG9zaXRpb25Ob3Rpb25hbEFuZFVucmVhbGl6ZWRQbmwCCQClCAEIBQFpBmNhbGxlcgUPUE5MX09QVElPTl9TUE9UBBNvbGRQb3NpdGlvbk5vdGlvbmFsCAUNJHQwNTQyMTA1NDMyNgJfMQQNdW5yZWFsaXplZFBubAgFDSR0MDU0MjEwNTQzMjYCXzIDCQBmAgUTb2xkUG9zaXRpb25Ob3Rpb25hbAUMb3Blbk5vdGlvbmFsCQACAQIuVXNlIGRlY3JlYXNlUG9zaXRpb24gdG8gZGVjcmVhc2UgcG9zaXRpb24gc2l6ZQkAAgECFENsb3NlIHBvc2l0aW9uIGZpcnN0BA9uZXdQb3NpdGlvblNpemUIBQ0kdDA1MTkzMjU0NTE3Al8xBBduZXdQb3NpdGlvblJlbWFpbk1hcmdpbggFDSR0MDUxOTMyNTQ1MTcCXzIEF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsCAUNJHQwNTE5MzI1NDUxNwJfMwQUbmV3UG9zaXRpb25MYXRlc3RDUEYIBQ0kdDA1MTkzMjU0NTE3Al80BBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA1MTkzMjU0NTE3Al81BBZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyCAUNJHQwNTE5MzI1NDUxNwJfNgQWdG90YWxQb3NpdGlvblNpemVBZnRlcggFDSR0MDUxOTMyNTQ1MTcCXzcEF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyCAUNJHQwNTE5MzI1NDUxNwJfOAQZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcggFDSR0MDUxOTMyNTQ1MTcCXzkEDnRvdGFsTG9uZ0FmdGVyCAUNJHQwNTE5MzI1NDUxNwNfMTAED3RvdGFsU2hvcnRBZnRlcggFDSR0MDUxOTMyNTQ1MTcDXzExBAxmZWVUb1N0YWtlcnMJAGkCBQlmZWVBbW91bnQAAgQOZmVlVG9JbnN1cmFuY2UJAGUCBQlmZWVBbW91bnQFDGZlZVRvU3Rha2VycwQFc3Rha2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACCWFkZExvY2tlZAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFB19hbW91bnQFA25pbAMJAAACBQVzdGFrZQUFc3Rha2UEEGRlcG9zaXRJbnN1cmFuY2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACB2FkZEZyZWUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQ5mZWVUb0luc3VyYW5jZQUDbmlsAwkAAAIFEGRlcG9zaXRJbnN1cmFuY2UFEGRlcG9zaXRJbnN1cmFuY2UECW5vdGlmeUZlZQkA/AcECQEMbWluZXJBZGRyZXNzAAIKbm90aWZ5RmVlcwkAzAgCBQdfdHJhZGVyCQDMCAIFCWZlZUFtb3VudAUDbmlsBQNuaWwDCQAAAgUJbm90aWZ5RmVlBQlub3RpZnlGZWUEDm5vdGlmeU5vdGlvbmFsCQD8BwQJAQxtaW5lckFkZHJlc3MAAg5ub3RpZnlOb3Rpb25hbAkAzAgCBQdfdHJhZGVyCQDMCAIFF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsBQNuaWwFA25pbAMJAAACBQ5ub3RpZnlOb3Rpb25hbAUObm90aWZ5Tm90aW9uYWwJAM4IAgkAzggCCQDOCAIJAM4IAgkAzggCCQEOdXBkYXRlUG9zaXRpb24FBQdfdHJhZGVyBQ9uZXdQb3NpdGlvblNpemUFF25ld1Bvc2l0aW9uUmVtYWluTWFyZ2luBRduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAUUbmV3UG9zaXRpb25MYXRlc3RDUEYJARN1cGRhdGVQb3NpdGlvbkFzc2V0AgUHX3RyYWRlcgULX2Fzc2V0SWRTdHIJAQl1cGRhdGVBbW0HBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyBRlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyBQ50b3RhbExvbmdBZnRlcgUPdG90YWxTaG9ydEFmdGVyCQELdHJhbnNmZXJGZWUBBQxmZWVUb1N0YWtlcnMJAQ11cGRhdGVCYWxhbmNlAQkAZAIJAQhjYmFsYW5jZQAFB19hbW91bnQJAQ5kb0J1cm5BcnRpZmFjdAIFDGJ1cm5BcnRpZmFjdAUBaQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQlhZGRNYXJnaW4ABARzeW5jCQD8BwQFBHRoaXMCGXN5bmNUZXJtaW5hbFByaWNlVG9PcmFjbGUFA25pbAUDbmlsAwkAAAIFBHN5bmMFBHN5bmMEB190cmFkZXIJAKUIAQgFAWkGY2FsbGVyBApfcmF3QW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQIX2Fzc2V0SWQICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQLX2Fzc2V0SWRTdHIJANgEAQkBBXZhbHVlAQUIX2Fzc2V0SWQEDGlzUXVvdGVBc3NldAkAAAIFCF9hc3NldElkCQEKcXVvdGVBc3NldAAEEWlzQ29sbGF0ZXJhbEFzc2V0CQEQaXNXaGl0ZWxpc3RBc3NldAEFC19hc3NldElkU3RyAwMDAwMDCQEBIQEFDGlzUXVvdGVBc3NldAkBASEBBRFpc0NvbGxhdGVyYWxBc3NldAcGCQEBIQEJARNyZXF1aXJlT3BlblBvc2l0aW9uAQkApQgBCAUBaQZjYWxsZXIGCQEBIQEJAQtpc1NhbWVBc3NldAIFB190cmFkZXIFC19hc3NldElkU3RyBgkBASEBCQELaW5pdGlhbGl6ZWQABgkBBnBhdXNlZAAJAAIBAhxJbnZhbGlkIGFkZE1hcmdpbiBwYXJhbWV0ZXJzBBBkb0dldEZlZURpc2NvdW50CQD8BwQJAQxtaW5lckFkZHJlc3MAAhJjb21wdXRlRmVlRGlzY291bnQJAMwIAgUHX3RyYWRlcgUDbmlsBQNuaWwDCQAAAgUQZG9HZXRGZWVEaXNjb3VudAUQZG9HZXRGZWVEaXNjb3VudAQLZmVlRGlzY291bnQEByRtYXRjaDAFEGRvR2V0RmVlRGlzY291bnQDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4CQACAQIhSW52YWxpZCBjb21wdXRlRmVlRGlzY291bnQgcmVzdWx0BA0kdDA1NjU5NDU2NjU4CQEOZ2V0QWRqdXN0ZWRGZWUCBQFpBQtmZWVEaXNjb3VudAQLYWRqdXN0ZWRGZWUIBQ0kdDA1NjU5NDU2NjU4Al8xBAxidXJuQXJ0aWZhY3QIBQ0kdDA1NjU5NDU2NjU4Al8yBAxyYXdGZWVBbW91bnQJAQRtdWxkAgUKX3Jhd0Ftb3VudAULYWRqdXN0ZWRGZWUEB19hbW91bnQJAGUCBQpfcmF3QW1vdW50BQxyYXdGZWVBbW91bnQEE2Rpc3RyaWJ1dGVGZWVBbW91bnQDBRFpc0NvbGxhdGVyYWxBc3NldAQIZG9Cb3Jyb3cJAPwHBAkBEWNvbGxhdGVyYWxBZGRyZXNzAAIGYm9ycm93CQDMCAIFB190cmFkZXIFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUIX2Fzc2V0SWQFB19hbW91bnQFA25pbAMJAAACBQhkb0JvcnJvdwUIZG9Cb3Jyb3cEDWJhbGFuY2VCZWZvcmUJAPAHAgUEdGhpcwkBCnF1b3RlQXNzZXQAAwkAAAIFDWJhbGFuY2VCZWZvcmUFDWJhbGFuY2VCZWZvcmUEBmRvU3dhcAkA/AcECQELc3dhcEFkZHJlc3MAAgRzd2FwCQDMCAIJANgEAQkBCnF1b3RlQXNzZXQACQDMCAIAAAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQhfYXNzZXRJZAUMcmF3RmVlQW1vdW50BQNuaWwDCQAAAgUGZG9Td2FwBQZkb1N3YXAEDGJhbGFuY2VBZnRlcgkA8AcCBQR0aGlzCQEKcXVvdGVBc3NldAADCQAAAgUMYmFsYW5jZUFmdGVyBQxiYWxhbmNlQWZ0ZXIED2V4Y2hhbmdlZEFtb3VudAkAZQIFDGJhbGFuY2VBZnRlcgUNYmFsYW5jZUJlZm9yZQMJAAACBQ9leGNoYW5nZWRBbW91bnQFD2V4Y2hhbmdlZEFtb3VudAUPZXhjaGFuZ2VkQW1vdW50CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQxyYXdGZWVBbW91bnQDCQAAAgUTZGlzdHJpYnV0ZUZlZUFtb3VudAUTZGlzdHJpYnV0ZUZlZUFtb3VudAQOcmVmZXJyZXJGZWVBbnkJAPwHBAkBD3JlZmVycmFsQWRkcmVzcwACDWFjY2VwdFBheW1lbnQJAMwIAgUHX3RyYWRlcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFE2Rpc3RyaWJ1dGVGZWVBbW91bnQFA25pbAMJAAACBQ5yZWZlcnJlckZlZUFueQUOcmVmZXJyZXJGZWVBbnkEC3JlZmVycmVyRmVlBAckbWF0Y2gwBQ5yZWZlcnJlckZlZUFueQMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAhNJbnZhbGlkIHJlZmVycmVyRmVlBAlmZWVBbW91bnQJAGUCBRNkaXN0cmlidXRlRmVlQW1vdW50BQtyZWZlcnJlckZlZQQNJHQwNTc5NTc1ODA5NwkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgQPb2xkUG9zaXRpb25TaXplCAUNJHQwNTc5NTc1ODA5NwJfMQQRb2xkUG9zaXRpb25NYXJnaW4IBQ0kdDA1Nzk1NzU4MDk3Al8yBBdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDU3OTU3NTgwOTcCXzMEFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwNTc5NTc1ODA5NwJfNAQMZmVlVG9TdGFrZXJzCQBpAgUJZmVlQW1vdW50AAIEDmZlZVRvSW5zdXJhbmNlCQBlAgUJZmVlQW1vdW50BQxmZWVUb1N0YWtlcnMEBXN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAglhZGRMb2NrZWQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQdfYW1vdW50BQNuaWwDCQAAAgUFc3Rha2UFBXN0YWtlBBBkZXBvc2l0SW5zdXJhbmNlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAgdhZGRGcmVlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQpxdW90ZUFzc2V0AAUOZmVlVG9JbnN1cmFuY2UFA25pbAMJAAACBRBkZXBvc2l0SW5zdXJhbmNlBRBkZXBvc2l0SW5zdXJhbmNlBAlub3RpZnlGZWUJAPwHBAkBDG1pbmVyQWRkcmVzcwACCm5vdGlmeUZlZXMJAMwIAgUHX3RyYWRlcgkAzAgCBQlmZWVBbW91bnQFA25pbAUDbmlsAwkAAAIFCW5vdGlmeUZlZQUJbm90aWZ5RmVlCQDOCAIJAM4IAgkAzggCCQEOdXBkYXRlUG9zaXRpb24FBQdfdHJhZGVyBQ9vbGRQb3NpdGlvblNpemUJAGQCBRFvbGRQb3NpdGlvbk1hcmdpbgUHX2Ftb3VudAUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwFFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCQELdHJhbnNmZXJGZWUBBQxmZWVUb1N0YWtlcnMJAQ11cGRhdGVCYWxhbmNlAQkAZAIJAQhjYmFsYW5jZQAFB19hbW91bnQJAQ5kb0J1cm5BcnRpZmFjdAIFDGJ1cm5BcnRpZmFjdAUBaQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQxyZW1vdmVNYXJnaW4BB19hbW91bnQEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQHX3RyYWRlcgkApQgBCAUBaQZjYWxsZXIDAwMDCQBnAgAABQdfYW1vdW50BgkBASEBCQETcmVxdWlyZU9wZW5Qb3NpdGlvbgEFB190cmFkZXIGCQEBIQEJAQtpbml0aWFsaXplZAAGCQEGcGF1c2VkAAkAAgECH0ludmFsaWQgcmVtb3ZlTWFyZ2luIHBhcmFtZXRlcnMEDSR0MDU5MjAzNTkzNDMJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIED29sZFBvc2l0aW9uU2l6ZQgFDSR0MDU5MjAzNTkzNDMCXzEEEW9sZFBvc2l0aW9uTWFyZ2luCAUNJHQwNTkyMDM1OTM0MwJfMgQXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwIBQ0kdDA1OTIwMzU5MzQzAl8zBBRvbGRQb3NpdGlvbkxzdFVwZENQRggFDSR0MDU5MjAzNTkzNDMCXzQEC21hcmdpbkRlbHRhCQEBLQEFB19hbW91bnQEDSR0MDU5MzgwNTk1NTkJASJjYWxjUmVtYWluTWFyZ2luV2l0aEZ1bmRpbmdQYXltZW50BAUPb2xkUG9zaXRpb25TaXplBRFvbGRQb3NpdGlvbk1hcmdpbgUUb2xkUG9zaXRpb25Mc3RVcGRDUEYFC21hcmdpbkRlbHRhBAxyZW1haW5NYXJnaW4IBQ0kdDA1OTM4MDU5NTU5Al8xBAdiYWREZWJ0CAUNJHQwNTkzODA1OTU1OQJfMgMJAQIhPQIFB2JhZERlYnQAAAkAAgECHUludmFsaWQgcmVtb3ZlZCBtYXJnaW4gYW1vdW50BAttYXJnaW5SYXRpbwkBD2NhbGNNYXJnaW5SYXRpbwMFDHJlbWFpbk1hcmdpbgUHYmFkRGVidAUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwDCQEBIQEJARZyZXF1aXJlTW9yZU1hcmdpblJhdGlvAwULbWFyZ2luUmF0aW8JAQ9pbml0TWFyZ2luUmF0aW8ABgkAAgEJAKwCAgkArAICCQCsAgICGVRvbyBtdWNoIG1hcmdpbiByZW1vdmVkOiAJAKQDAQULbWFyZ2luUmF0aW8CAyA8IAkApAMBCQEPaW5pdE1hcmdpblJhdGlvAAQNcXVvdGVBc3NldFN0cgkA2AQBCQEKcXVvdGVBc3NldAAEDSR0MDYwMDAzNjAwNTcJARNnZXRCb3Jyb3dlZEJ5VHJhZGVyAQUHX3RyYWRlcgQIYm9ycm93ZWQIBQ0kdDA2MDAwMzYwMDU3Al8xBAdhc3NldElkCAUNJHQwNjAwMDM2MDA1NwJfMgQHdG9SZXBheQMJAGYCBQdfYW1vdW50BQhib3Jyb3dlZAUIYm9ycm93ZWQFB19hbW91bnQECnRvV2l0aGRyYXcDCQBmAgUIYm9ycm93ZWQFB19hbW91bnQAAAkAZQIFB19hbW91bnQFCGJvcnJvd2VkBAtmaW5hbEJvcnJvdwkAZQIFCGJvcnJvd2VkBQd0b1JlcGF5BBVzd2l0Y2hQb3NpdGlvblRvUXVvdGUDCQBmAgULZmluYWxCb3Jyb3cAAAUDbmlsCQETdXBkYXRlUG9zaXRpb25Bc3NldAIFB190cmFkZXIFDXF1b3RlQXNzZXRTdHIEDWRvU2FuaXR5Q2hlY2sDCQECIT0CCQBkAgUHdG9SZXBheQUKdG9XaXRoZHJhdwUHX2Ftb3VudAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAgh0b1JlcGF5PQkApAMBBQd0b1JlcGF5Ag4gKyB0b1dpdGhkcmF3PQkApAMBBQp0b1dpdGhkcmF3AgQgIT0gCQCkAwEFB19hbW91bnQFA25pbAMJAAACBQ1kb1Nhbml0eUNoZWNrBQ1kb1Nhbml0eUNoZWNrBAlkb1Vuc3Rha2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACDndpdGhkcmF3TG9ja2VkCQDMCAIFB19hbW91bnQFA25pbAUDbmlsAwkAAAIFCWRvVW5zdGFrZQUJZG9VbnN0YWtlBBZyZXR1cm5Db2xsYXRlcmFsQWN0aW9uAwkAZgIFB3RvUmVwYXkAAAQHZG9SZXBheQkA/AcECQERY29sbGF0ZXJhbEFkZHJlc3MAAgVyZXBheQkAzAgCBQdfdHJhZGVyCQDMCAIFB2Fzc2V0SWQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQd0b1JlcGF5BQNuaWwDCQAAAgUHZG9SZXBheQUHZG9SZXBheQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFB3RvUmVwYXkJANkEAQUHYXNzZXRJZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwDCQAAAgUWcmV0dXJuQ29sbGF0ZXJhbEFjdGlvbgUWcmV0dXJuQ29sbGF0ZXJhbEFjdGlvbgkAzggCCQDOCAIJAM4IAgkAzggCCQEOdXBkYXRlUG9zaXRpb24FBQdfdHJhZGVyBQ9vbGRQb3NpdGlvblNpemUFDHJlbWFpbk1hcmdpbgUXb2xkUG9zaXRpb25PcGVuTm90aW9uYWwJAR9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQUPb2xkUG9zaXRpb25TaXplAwkAZgIFCnRvV2l0aGRyYXcAAAkBCHdpdGhkcmF3AggFAWkGY2FsbGVyBQp0b1dpdGhkcmF3BQNuaWwJAQ11cGRhdGVCYWxhbmNlAQkAZQIJAQhjYmFsYW5jZQAFB19hbW91bnQFFXN3aXRjaFBvc2l0aW9uVG9RdW90ZQUWcmV0dXJuQ29sbGF0ZXJhbEFjdGlvbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ1jbG9zZVBvc2l0aW9uAAQEc3luYwkA/AcEBQR0aGlzAhlzeW5jVGVybWluYWxQcmljZVRvT3JhY2xlBQNuaWwFA25pbAMJAAACBQRzeW5jBQRzeW5jBAdfdHJhZGVyCQEPZ2V0QWN0dWFsQ2FsbGVyAQUBaQQOX3RyYWRlckFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQdfdHJhZGVyAg5JbnZhbGlkIGNhbGxlcgMDAwkBASEBCQETcmVxdWlyZU9wZW5Qb3NpdGlvbgEFB190cmFkZXIGCQEBIQEJAQtpbml0aWFsaXplZAAGCQEGcGF1c2VkAAkAAgECIEludmFsaWQgY2xvc2VQb3NpdGlvbiBwYXJhbWV0ZXJzBA0kdDA2MjMwNzYyNjg1CQEVaW50ZXJuYWxDbG9zZVBvc2l0aW9uAgUHX3RyYWRlcgYEAngxCAUNJHQwNjIzMDc2MjY4NQJfMQQPcG9zaXRpb25CYWREZWJ0CAUNJHQwNjIzMDc2MjY4NQJfMgQLcmVhbGl6ZWRQbmwIBQ0kdDA2MjMwNzYyNjg1Al8zBA1tYXJnaW5Ub1ZhdWx0CAUNJHQwNjIzMDc2MjY4NQJfNAQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDYyMzA3NjI2ODUCXzUEFWJhc2VBc3NldFJlc2VydmVBZnRlcggFDSR0MDYyMzA3NjI2ODUCXzYEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDA2MjMwNzYyNjg1Al83BBdjdW11bGF0aXZlTm90aW9uYWxBZnRlcggFDSR0MDYyMzA3NjI2ODUCXzgEGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIIBQ0kdDA2MjMwNzYyNjg1Al85BAJ4MggFDSR0MDYyMzA3NjI2ODUDXzEwBA50b3RhbExvbmdBZnRlcggFDSR0MDYyMzA3NjI2ODUDXzExBA90b3RhbFNob3J0QWZ0ZXIIBQ0kdDA2MjMwNzYyNjg1A18xMgMJAGYCBQ9wb3NpdGlvbkJhZERlYnQAAAkAAgECJlVuYWJsZSB0byBjbG9zZSBwb3NpdGlvbiB3aXRoIGJhZCBkZWJ0BA53aXRoZHJhd0Ftb3VudAkBA2FicwEFDW1hcmdpblRvVmF1bHQECmFtbUJhbGFuY2UJAGUCCQEIY2JhbGFuY2UABQ53aXRoZHJhd0Ftb3VudAQNJHQwNjMwMDk2MzUyNAMJAGYCAAAFCmFtbUJhbGFuY2UJAJQKAgAACQEDYWJzAQUKYW1tQmFsYW5jZQkAlAoCBQphbW1CYWxhbmNlAAAEDWFtbU5ld0JhbGFuY2UIBQ0kdDA2MzAwOTYzNTI0Al8xBAN4MTEIBQ0kdDA2MzAwOTYzNTI0Al8yBAd1bnN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAg53aXRoZHJhd0xvY2tlZAkAzAgCBQ53aXRoZHJhd0Ftb3VudAUDbmlsBQNuaWwDCQAAAgUHdW5zdGFrZQUHdW5zdGFrZQQNJHQwNjM3MzY2Mzc5MAkBE2dldEJvcnJvd2VkQnlUcmFkZXIBBQdfdHJhZGVyBAhib3Jyb3dlZAgFDSR0MDYzNzM2NjM3OTACXzEEB2Fzc2V0SWQIBQ0kdDA2MzczNjYzNzkwAl8yBA0kdDA2MzgwNTY0NzIyAwkAZgIFCGJvcnJvd2VkAAADCQBnAgUOd2l0aGRyYXdBbW91bnQFCGJvcnJvd2VkBAdkb1JlcGF5CQD8BwQJARFjb2xsYXRlcmFsQWRkcmVzcwACBXJlcGF5CQDMCAIFB190cmFkZXIJAMwIAgUHYXNzZXRJZAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEKcXVvdGVBc3NldAAFCGJvcnJvd2VkBQNuaWwDCQAAAgUHZG9SZXBheQUHZG9SZXBheQkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFDl90cmFkZXJBZGRyZXNzBQhib3Jyb3dlZAkA2QQBBQdhc3NldElkBQNuaWwJAGUCBQ53aXRoZHJhd0Ftb3VudAUIYm9ycm93ZWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4ED3JlYWxpemVBbmRDbG9zZQkA/AcECQERY29sbGF0ZXJhbEFkZHJlc3MAAhhyZWFsaXplUGFydGlhbGx5QW5kQ2xvc2UJAMwIAgUHX3RyYWRlcgkAzAgCBQdhc3NldElkBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQpxdW90ZUFzc2V0AAUOd2l0aGRyYXdBbW91bnQFA25pbAMJAAACBQ9yZWFsaXplQW5kQ2xvc2UFD3JlYWxpemVBbmRDbG9zZQkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFDl90cmFkZXJBZGRyZXNzBQ53aXRoZHJhd0Ftb3VudAkA2QQBBQdhc3NldElkBQNuaWwAAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlAoCBQNuaWwFDndpdGhkcmF3QW1vdW50AwkAAAIFDSR0MDYzODA1NjQ3MjIFDSR0MDYzODA1NjQ3MjIEE3F1b3RlV2l0aGRyYXdBbW91bnQIBQ0kdDA2MzgwNTY0NzIyAl8yBBRzZW5kQ29sbGF0ZXJhbEFjdGlvbggFDSR0MDYzODA1NjQ3MjICXzEEDm5vdGlmeU5vdGlvbmFsCQD8BwQJAQxtaW5lckFkZHJlc3MAAg5ub3RpZnlOb3Rpb25hbAkAzAgCBQdfdHJhZGVyCQDMCAIAAAUDbmlsBQNuaWwDCQAAAgUObm90aWZ5Tm90aW9uYWwFDm5vdGlmeU5vdGlvbmFsCQDOCAIJAM4IAgkAzggCCQDOCAIJAQ5kZWxldGVQb3NpdGlvbgEFB190cmFkZXIJAQl1cGRhdGVBbW0HBRZxdW90ZUFzc2V0UmVzZXJ2ZUFmdGVyBRViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIFFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIFF2N1bXVsYXRpdmVOb3Rpb25hbEFmdGVyBRlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyBQ50b3RhbExvbmdBZnRlcgUPdG90YWxTaG9ydEFmdGVyAwkAZgIFE3F1b3RlV2l0aGRyYXdBbW91bnQAAAkBCHdpdGhkcmF3AgUOX3RyYWRlckFkZHJlc3MFE3F1b3RlV2l0aGRyYXdBbW91bnQFA25pbAkBDXVwZGF0ZUJhbGFuY2UBBQ1hbW1OZXdCYWxhbmNlBRRzZW5kQ29sbGF0ZXJhbEFjdGlvbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQlsaXF1aWRhdGUBB190cmFkZXIEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQPc3BvdE1hcmdpblJhdGlvCQEWZ2V0TWFyZ2luUmF0aW9CeU9wdGlvbgIFB190cmFkZXIFD1BOTF9PUFRJT05fU1BPVAQLbWFyZ2luUmF0aW8DCQEWaXNPdmVyRmx1Y3R1YXRpb25MaW1pdAAEEW9yYWNsZU1hcmdpblJhdGlvCQEWZ2V0TWFyZ2luUmF0aW9CeU9wdGlvbgIFB190cmFkZXIFEVBOTF9PUFRJT05fT1JBQ0xFCQEEdm1heAIFD3Nwb3RNYXJnaW5SYXRpbwURb3JhY2xlTWFyZ2luUmF0aW8FD3Nwb3RNYXJnaW5SYXRpbwMDAwMJAQEhAQkBFnJlcXVpcmVNb3JlTWFyZ2luUmF0aW8DBQttYXJnaW5SYXRpbwkBFm1haW50ZW5hbmNlTWFyZ2luUmF0aW8ABwYJAQEhAQkBE3JlcXVpcmVPcGVuUG9zaXRpb24BBQdfdHJhZGVyBgkBASEBCQELaW5pdGlhbGl6ZWQABgkBBnBhdXNlZAAJAAIBAhNVbmFibGUgdG8gbGlxdWlkYXRlAwMDCQBmAgUPc3BvdE1hcmdpblJhdGlvCQETbGlxdWlkYXRpb25GZWVSYXRpbwAJAGYCCQEXcGFydGlhbExpcXVpZGF0aW9uUmF0aW8AAAAHCQBmAgUMREVDSU1BTF9VTklUCQEXcGFydGlhbExpcXVpZGF0aW9uUmF0aW8ABwQNJHQwNjY0OTA2NjY0MAkBC2dldFBvc2l0aW9uAQUHX3RyYWRlcgQPb2xkUG9zaXRpb25TaXplCAUNJHQwNjY0OTA2NjY0MAJfMQQRb2xkUG9zaXRpb25NYXJnaW4IBQ0kdDA2NjQ5MDY2NjQwAl8yBBdvbGRQb3NpdGlvbk9wZW5Ob3Rpb25hbAgFDSR0MDY2NDkwNjY2NDACXzMEFG9sZFBvc2l0aW9uTHN0VXBkQ1BGCAUNJHQwNjY0OTA2NjY0MAJfNAQKX2RpcmVjdGlvbgMJAGYCBQ9vbGRQb3NpdGlvblNpemUAAAUJRElSX1NIT1JUBQhESVJfTE9ORwQFaXNBZGQJAAACBQpfZGlyZWN0aW9uBQhESVJfTE9ORwQZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAkBG2dldFBhcnRpYWxMaXF1aWRhdGlvbkFtb3VudAIFB190cmFkZXIFD29sZFBvc2l0aW9uU2l6ZQQNJHQwNjY4NjU2Njk2OQkBI2dldFBvc2l0aW9uTm90aW9uYWxBbmRVbnJlYWxpemVkUG5sAgUHX3RyYWRlcgUPUE5MX09QVElPTl9TUE9UBBNvbGRQb3NpdGlvbk5vdGlvbmFsCAUNJHQwNjY4NjU2Njk2OQJfMQQNdW5yZWFsaXplZFBubAgFDSR0MDY2ODY1NjY5NjkCXzIEDSR0MDY2OTc3NjcyMDkJAQlzd2FwSW5wdXQCBQVpc0FkZAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAQVZXhjaGFuZ2VkUG9zaXRpb25TaXplCAUNJHQwNjY5Nzc2NzIwOQJfMQQWcXVvdGVBc3NldFJlc2VydmVBZnRlcggFDSR0MDY2OTc3NjcyMDkCXzIEFWJhc2VBc3NldFJlc2VydmVBZnRlcggFDSR0MDY2OTc3NjcyMDkCXzMEFnRvdGFsUG9zaXRpb25TaXplQWZ0ZXIIBQ0kdDA2Njk3NzY3MjA5Al80BBdjdW11bGF0aXZlTm90aW9uYWxBZnRlcggFDSR0MDY2OTc3NjcyMDkCXzUEEGxpcXVpZGF0aW9uUmF0aW8JAQRkaXZkAgkBA2FicwEFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQkBA2FicwEFD29sZFBvc2l0aW9uU2l6ZQQLcmVhbGl6ZWRQbmwJAQRtdWxkAgUNdW5yZWFsaXplZFBubAUQbGlxdWlkYXRpb25SYXRpbwQNJHQwNjc0OTg2NzczMQkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQ9vbGRQb3NpdGlvblNpemUFEW9sZFBvc2l0aW9uTWFyZ2luBRRvbGRQb3NpdGlvbkxzdFVwZENQRgULcmVhbGl6ZWRQbmwEDHJlbWFpbk1hcmdpbggFDSR0MDY3NDk4Njc3MzECXzEEB2JhZERlYnQIBQ0kdDA2NzQ5ODY3NzMxAl8yBA5mdW5kaW5nUGF5bWVudAgFDSR0MDY3NDk4Njc3MzECXzMEEnVucmVhbGl6ZWRQbmxBZnRlcgkAZQIFDXVucmVhbGl6ZWRQbmwFC3JlYWxpemVkUG5sBBJyZW1haW5PcGVuTm90aW9uYWwDCQBmAgUPb2xkUG9zaXRpb25TaXplAAAJAGUCCQBlAgUTb2xkUG9zaXRpb25Ob3Rpb25hbAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAUSdW5yZWFsaXplZFBubEFmdGVyCQBlAgkAZAIFEnVucmVhbGl6ZWRQbmxBZnRlcgUTb2xkUG9zaXRpb25Ob3Rpb25hbAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAQSbGlxdWlkYXRpb25QZW5hbHR5CQEEbXVsZAIFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQJARNsaXF1aWRhdGlvbkZlZVJhdGlvAAQPZmVlVG9MaXF1aWRhdG9yCQBpAgUSbGlxdWlkYXRpb25QZW5hbHR5AAIEDmZlZVRvSW5zdXJhbmNlCQBlAgUSbGlxdWlkYXRpb25QZW5hbHR5BQ9mZWVUb0xpcXVpZGF0b3IEEW5ld1Bvc2l0aW9uTWFyZ2luCQBlAgUMcmVtYWluTWFyZ2luBRJsaXF1aWRhdGlvblBlbmFsdHkED25ld1Bvc2l0aW9uU2l6ZQkAZAIFD29sZFBvc2l0aW9uU2l6ZQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplBBduZXdQb3NpdGlvbk9wZW5Ob3Rpb25hbAkBA2FicwEFEnJlbWFpbk9wZW5Ob3Rpb25hbAQUbmV3UG9zaXRpb25Mc3RVcGRDUEYJAR9sYXRlc3RDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAQUPbmV3UG9zaXRpb25TaXplBBlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCQBlAgkBFG9wZW5JbnRlcmVzdE5vdGlvbmFsAAUZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAQKYW1tQmFsYW5jZQkAZQIJAQhjYmFsYW5jZQAFEmxpcXVpZGF0aW9uUGVuYWx0eQQNJHQwNjg5MDQ2OTAzMwMJAGYCAAAFCmFtbUJhbGFuY2UJAJQKAgAACQEDYWJzAQUKYW1tQmFsYW5jZQkAlAoCBQphbW1CYWxhbmNlAAAEDW5ld0FtbUJhbGFuY2UIBQ0kdDA2ODkwNDY5MDMzAl8xBAN4MTEIBQ0kdDA2ODkwNDY5MDMzAl8yBA0kdDA2OTA0MTY5MDk1CQETZ2V0Qm9ycm93ZWRCeVRyYWRlcgEFB190cmFkZXIECGJvcnJvd2VkCAUNJHQwNjkwNDE2OTA5NQJfMQQHYXNzZXRJZAgFDSR0MDY5MDQxNjkwOTUCXzIEFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAMJAGYCBQhib3Jyb3dlZAAABBBjb2xsYXRlcmFsVG9TZWxsCQEEbXVsZAIFCGJvcnJvd2VkBRBsaXF1aWRhdGlvblJhdGlvBA9yZWFsaXplQW5kQ2xvc2UJAPwHBAkBEWNvbGxhdGVyYWxBZGRyZXNzAAIQcmVhbGl6ZVBhcnRpYWxseQkAzAgCBQdfdHJhZGVyCQDMCAIFB2Fzc2V0SWQJAMwIAgUQY29sbGF0ZXJhbFRvU2VsbAUDbmlsBQNuaWwDCQAAAgUPcmVhbGl6ZUFuZENsb3NlBQ9yZWFsaXplQW5kQ2xvc2UFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAwkAAAIFFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAUVZG9MaXF1aWRhdGVDb2xsYXRlcmFsBAd1bnN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAg53aXRoZHJhd0xvY2tlZAkAzAgCBRJsaXF1aWRhdGlvblBlbmFsdHkFA25pbAUDbmlsAwkAAAIFB3Vuc3Rha2UFB3Vuc3Rha2UEEGRlcG9zaXRJbnN1cmFuY2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACB2FkZEZyZWUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQ5mZWVUb0luc3VyYW5jZQUDbmlsAwkAAAIFEGRlcG9zaXRJbnN1cmFuY2UFEGRlcG9zaXRJbnN1cmFuY2UEDm5vdGlmeU5vdGlvbmFsCQD8BwQJAQxtaW5lckFkZHJlc3MAAg5ub3RpZnlOb3Rpb25hbAkAzAgCBQdfdHJhZGVyCQDMCAIFF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsBQNuaWwFA25pbAMJAAACBQ5ub3RpZnlOb3Rpb25hbAUObm90aWZ5Tm90aW9uYWwJAM4IAgkAzggCCQDOCAIJAQ51cGRhdGVQb3NpdGlvbgUFB190cmFkZXIFD25ld1Bvc2l0aW9uU2l6ZQURbmV3UG9zaXRpb25NYXJnaW4FF25ld1Bvc2l0aW9uT3Blbk5vdGlvbmFsBRRuZXdQb3NpdGlvbkxzdFVwZENQRgkBCXVwZGF0ZUFtbQcFFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIFFWJhc2VBc3NldFJlc2VydmVBZnRlcgUWdG90YWxQb3NpdGlvblNpemVBZnRlcgUXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIFGW9wZW5JbnRlcmVzdE5vdGlvbmFsQWZ0ZXIJAGUCCQEVdG90YWxMb25nUG9zaXRpb25TaXplAAMJAGYCBQ9uZXdQb3NpdGlvblNpemUAAAkBA2FicwEFFWV4Y2hhbmdlZFBvc2l0aW9uU2l6ZQAACQBlAgkBFnRvdGFsU2hvcnRQb3NpdGlvblNpemUAAwkAZgIAAAUPbmV3UG9zaXRpb25TaXplCQEDYWJzAQUVZXhjaGFuZ2VkUG9zaXRpb25TaXplAAAJAQh3aXRoZHJhdwIIBQFpBmNhbGxlcgUPZmVlVG9MaXF1aWRhdG9yCQENdXBkYXRlQmFsYW5jZQEFDW5ld0FtbUJhbGFuY2UJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EDSR0MDcwOTAwNzEzNTUJARVpbnRlcm5hbENsb3NlUG9zaXRpb24CBQdfdHJhZGVyBwQCeDEIBQ0kdDA3MDkwMDcxMzU1Al8xBAdiYWREZWJ0CAUNJHQwNzA5MDA3MTM1NQJfMgQCeDIIBQ0kdDA3MDkwMDcxMzU1Al8zBAJ4MwgFDSR0MDcwOTAwNzEzNTUCXzQEFnF1b3RlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA3MDkwMDcxMzU1Al81BBViYXNlQXNzZXRSZXNlcnZlQWZ0ZXIIBQ0kdDA3MDkwMDcxMzU1Al82BBZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyCAUNJHQwNzA5MDA3MTM1NQJfNwQXY3VtdWxhdGl2ZU5vdGlvbmFsQWZ0ZXIIBQ0kdDA3MDkwMDcxMzU1Al84BBlvcGVuSW50ZXJlc3ROb3Rpb25hbEFmdGVyCAUNJHQwNzA5MDA3MTM1NQJfOQQZZXhjaGFuZ2VkUXVvdGVBc3NldEFtb3VudAgFDSR0MDcwOTAwNzEzNTUDXzEwBA50b3RhbExvbmdBZnRlcggFDSR0MDcwOTAwNzEzNTUDXzExBA90b3RhbFNob3J0QWZ0ZXIIBQ0kdDA3MDkwMDcxMzU1A18xMgQSbGlxdWlkYXRpb25QZW5hbHR5CQEEbXVsZAIFGWV4Y2hhbmdlZFF1b3RlQXNzZXRBbW91bnQJARNsaXF1aWRhdGlvbkZlZVJhdGlvAAQPZmVlVG9MaXF1aWRhdG9yCQBpAgUSbGlxdWlkYXRpb25QZW5hbHR5AAIEDmZlZVRvSW5zdXJhbmNlCQBlAgUSbGlxdWlkYXRpb25QZW5hbHR5BQ9mZWVUb0xpcXVpZGF0b3IECmFtbUJhbGFuY2UJAGUCCQEIY2JhbGFuY2UABRJsaXF1aWRhdGlvblBlbmFsdHkEDSR0MDcxNzY3NzE4OTYDCQBmAgAABQphbW1CYWxhbmNlCQCUCgIAAAkBA2FicwEFCmFtbUJhbGFuY2UJAJQKAgUKYW1tQmFsYW5jZQAABA1uZXdBbW1CYWxhbmNlCAUNJHQwNzE3Njc3MTg5NgJfMQQDeDExCAUNJHQwNzE3Njc3MTg5NgJfMgQNJHQwNzE5MDQ3MTk1OAkBE2dldEJvcnJvd2VkQnlUcmFkZXIBBQdfdHJhZGVyBAhib3Jyb3dlZAgFDSR0MDcxOTA0NzE5NTgCXzEEB2Fzc2V0SWQIBQ0kdDA3MTkwNDcxOTU4Al8yBBVkb0xpcXVpZGF0ZUNvbGxhdGVyYWwDCQBmAgUIYm9ycm93ZWQAAAQPcmVhbGl6ZUFuZENsb3NlCQD8BwQJARFjb2xsYXRlcmFsQWRkcmVzcwACGHJlYWxpemVQYXJ0aWFsbHlBbmRDbG9zZQkAzAgCBQdfdHJhZGVyCQDMCAIFB2Fzc2V0SWQFA25pbAUDbmlsAwkAAAIFD3JlYWxpemVBbmRDbG9zZQUPcmVhbGl6ZUFuZENsb3NlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBRVkb0xpcXVpZGF0ZUNvbGxhdGVyYWwFFWRvTGlxdWlkYXRlQ29sbGF0ZXJhbAQBeAMJAGYCBQdiYWREZWJ0AAAEC2xvY2tCYWREZWJ0CQD8BwQJAQx2YXVsdEFkZHJlc3MAAhVleGNoYW5nZUZyZWVBbmRMb2NrZWQJAMwIAgUHYmFkRGVidAUDbmlsBQNuaWwDCQAAAgULbG9ja0JhZERlYnQFC2xvY2tCYWREZWJ0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAMJAAACBQF4BQF4BAd1bnN0YWtlCQD8BwQJAQx2YXVsdEFkZHJlc3MAAg53aXRoZHJhd0xvY2tlZAkAzAgCBRJsaXF1aWRhdGlvblBlbmFsdHkFA25pbAUDbmlsAwkAAAIFB3Vuc3Rha2UFB3Vuc3Rha2UEEGRlcG9zaXRJbnN1cmFuY2UJAPwHBAkBDHZhdWx0QWRkcmVzcwACB2FkZEZyZWUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBCnF1b3RlQXNzZXQABQ5mZWVUb0luc3VyYW5jZQUDbmlsAwkAAAIFEGRlcG9zaXRJbnN1cmFuY2UFEGRlcG9zaXRJbnN1cmFuY2UEDm5vdGlmeU5vdGlvbmFsCQD8BwQJAQxtaW5lckFkZHJlc3MAAg5ub3RpZnlOb3Rpb25hbAkAzAgCBQdfdHJhZGVyCQDMCAIAAAUDbmlsBQNuaWwDCQAAAgUObm90aWZ5Tm90aW9uYWwFDm5vdGlmeU5vdGlvbmFsCQDOCAIJAM4IAgkAzggCCQEOZGVsZXRlUG9zaXRpb24BBQdfdHJhZGVyCQEJdXBkYXRlQW1tBwUWcXVvdGVBc3NldFJlc2VydmVBZnRlcgUVYmFzZUFzc2V0UmVzZXJ2ZUFmdGVyBRZ0b3RhbFBvc2l0aW9uU2l6ZUFmdGVyBRdjdW11bGF0aXZlTm90aW9uYWxBZnRlcgUZb3BlbkludGVyZXN0Tm90aW9uYWxBZnRlcgUOdG90YWxMb25nQWZ0ZXIFD3RvdGFsU2hvcnRBZnRlcgkBCHdpdGhkcmF3AggFAWkGY2FsbGVyBQ9mZWVUb0xpcXVpZGF0b3IJAQ11cGRhdGVCYWxhbmNlAQUNbmV3QW1tQmFsYW5jZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQpwYXlGdW5kaW5nAAQVZnVuZGluZ0Jsb2NrVGltZXN0YW1wCQEZbmV4dEZ1bmRpbmdCbG9ja1RpbWVzdGFtcAADAwMJAGYCBRVmdW5kaW5nQmxvY2tUaW1lc3RhbXAIBQlsYXN0QmxvY2sJdGltZXN0YW1wBgkBASEBCQELaW5pdGlhbGl6ZWQABgkBBnBhdXNlZAAJAAIBCQCsAgIJAKwCAgkArAICAiFJbnZhbGlkIGZ1bmRpbmcgYmxvY2sgdGltZXN0YW1wOiAJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXACAyA8IAkApAMBBRVmdW5kaW5nQmxvY2tUaW1lc3RhbXAED3VuZGVybHlpbmdQcmljZQkBEmdldE9yYWNsZVR3YXBQcmljZQAEDSR0MDczOTg1NzQwNDcJAQpnZXRGdW5kaW5nAAQUc2hvcnRQcmVtaXVtRnJhY3Rpb24IBQ0kdDA3Mzk4NTc0MDQ3Al8xBBNsb25nUHJlbWl1bUZyYWN0aW9uCAUNJHQwNzM5ODU3NDA0NwJfMgkBDXVwZGF0ZUZ1bmRpbmcFCQBkAgUVZnVuZGluZ0Jsb2NrVGltZXN0YW1wCQEUZnVuZGluZ1BlcmlvZFNlY29uZHMACQBkAgkBI2xhdGVzdExvbmdDdW11bGF0aXZlUHJlbWl1bUZyYWN0aW9uAAUTbG9uZ1ByZW1pdW1GcmFjdGlvbgkAZAIJASRsYXRlc3RTaG9ydEN1bXVsYXRpdmVQcmVtaXVtRnJhY3Rpb24ABRRzaG9ydFByZW1pdW1GcmFjdGlvbgkBBGRpdmQCBRNsb25nUHJlbWl1bUZyYWN0aW9uBQ91bmRlcmx5aW5nUHJpY2UJAQRkaXZkAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24FD3VuZGVybHlpbmdQcmljZQFpARlzeW5jVGVybWluYWxQcmljZVRvT3JhY2xlAAQNJHQwNzQ0Mjk3NDU1MAkBFGdldFN5bmNUZXJtaW5hbFByaWNlAQkBEmdldE9yYWNsZVR3YXBQcmljZQAEE25ld1F1b3RlQXNzZXRXZWlnaHQIBQ0kdDA3NDQyOTc0NTUwAl8xBBJuZXdCYXNlQXNzZXRXZWlnaHQIBQ0kdDA3NDQyOTc0NTUwAl8yBA1tYXJnaW5Ub1ZhdWx0CAUNJHQwNzQ0Mjk3NDU1MAJfMwkBEHVwZGF0ZUFtbVdlaWdodHMCBRNuZXdRdW90ZUFzc2V0V2VpZ2h0BRJuZXdCYXNlQXNzZXRXZWlnaHQBaQEFdl9nZXQBB190cmFkZXIEBHN5bmMJAPwHBAUEdGhpcwIZc3luY1Rlcm1pbmFsUHJpY2VUb09yYWNsZQUDbmlsBQNuaWwDCQAAAgUEc3luYwUEc3luYwQNJHQwNzQ3Mjg3NDc4OAkBFWludGVybmFsQ2xvc2VQb3NpdGlvbgIFB190cmFkZXIHBAJ4MQgFDSR0MDc0NzI4NzQ3ODgCXzEEAngyCAUNJHQwNzQ3Mjg3NDc4OAJfMgQCeDMIBQ0kdDA3NDcyODc0Nzg4Al8zBAJ4NAgFDSR0MDc0NzI4NzQ3ODgCXzQJAAIBCQCsAgIJAKwCAgkArAICCQEBcwEFAngyCQEBcwEFAngzCQEBcwEFAng0CQEBcwEJAQ5nZXRNYXJnaW5SYXRpbwEFB190cmFkZXIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEndmlld19jYWxjUmVtYWluTWFyZ2luV2l0aEZ1bmRpbmdQYXltZW50AQdfdHJhZGVyBARzeW5jCQD8BwQFBHRoaXMCGXN5bmNUZXJtaW5hbFByaWNlVG9PcmFjbGUFA25pbAUDbmlsAwkAAAIFBHN5bmMFBHN5bmMEDSR0MDc0OTk5NzUxMDAJAQtnZXRQb3NpdGlvbgEFB190cmFkZXIEDHBvc2l0aW9uU2l6ZQgFDSR0MDc0OTk5NzUxMDACXzEEDnBvc2l0aW9uTWFyZ2luCAUNJHQwNzQ5OTk3NTEwMAJfMgQDcG9uCAUNJHQwNzQ5OTk3NTEwMAJfMwQRcG9zaXRpb25Mc3RVcGRDUEYIBQ0kdDA3NDk5OTc1MTAwAl80BA0kdDA3NTEwMzc1MjA0CQEjZ2V0UG9zaXRpb25Ob3Rpb25hbEFuZFVucmVhbGl6ZWRQbmwCBQdfdHJhZGVyBQ9QTkxfT1BUSU9OX1NQT1QEEHBvc2l0aW9uTm90aW9uYWwIBQ0kdDA3NTEwMzc1MjA0Al8xBA11bnJlYWxpemVkUG5sCAUNJHQwNzUxMDM3NTIwNAJfMgQNJHQwNzUyMDc3NTM3OQkBImNhbGNSZW1haW5NYXJnaW5XaXRoRnVuZGluZ1BheW1lbnQEBQxwb3NpdGlvblNpemUFDnBvc2l0aW9uTWFyZ2luBRFwb3NpdGlvbkxzdFVwZENQRgUNdW5yZWFsaXplZFBubAQMcmVtYWluTWFyZ2luCAUNJHQwNzUyMDc3NTM3OQJfMQQHYmFkRGVidAgFDSR0MDc1MjA3NzUzNzkCXzIEDmZ1bmRpbmdQYXltZW50CAUNJHQwNzUyMDc3NTM3OQJfMwkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQEBcwEFDHJlbWFpbk1hcmdpbgkBAXMBBQ5mdW5kaW5nUGF5bWVudAkBAXMBCQEOZ2V0TWFyZ2luUmF0aW8BBQdfdHJhZGVyCQEBcwEFDXVucmVhbGl6ZWRQbmwJAQFzAQUHYmFkRGVidAkBAXMBBRBwb3NpdGlvbk5vdGlvbmFsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBFXZpZXdfZ2V0UGVnQWRqdXN0Q29zdAEGX3ByaWNlBAZyZXN1bHQJARRnZXRTeW5jVGVybWluYWxQcmljZQEFBl9wcmljZQkAAgEJAKQDAQgFBnJlc3VsdAJfMwFpARh2aWV3X2dldFRlcm1pbmFsQW1tUHJpY2UABA0kdDA3NTcyNjc1ODA3CQETZ2V0VGVybWluYWxBbW1TdGF0ZQAEGXRlcm1pbmFsUXVvdGVBc3NldFJlc2VydmUIBQ0kdDA3NTcyNjc1ODA3Al8xBBh0ZXJtaW5hbEJhc2VBc3NldFJlc2VydmUIBQ0kdDA3NTcyNjc1ODA3Al8yBAVwcmljZQkBBGRpdmQCCQEEbXVsZAIFGXRlcm1pbmFsUXVvdGVBc3NldFJlc2VydmUJAQZxdEFzdFcACQEEbXVsZAIFGHRlcm1pbmFsQmFzZUFzc2V0UmVzZXJ2ZQkBBmJzQXN0VwAJAAIBCQCkAwEFBXByaWNlAWkBD3ZpZXdfZ2V0RnVuZGluZwAED3VuZGVybHlpbmdQcmljZQkBEmdldE9yYWNsZVR3YXBQcmljZQAEDSR0MDc2MDI2NzYwODgJAQpnZXRGdW5kaW5nAAQUc2hvcnRQcmVtaXVtRnJhY3Rpb24IBQ0kdDA3NjAyNjc2MDg4Al8xBBNsb25nUHJlbWl1bUZyYWN0aW9uCAUNJHQwNzYwMjY3NjA4OAJfMgQLbG9uZ0Z1bmRpbmcJAQRkaXZkAgUTbG9uZ1ByZW1pdW1GcmFjdGlvbgUPdW5kZXJseWluZ1ByaWNlBAxzaG9ydEZ1bmRpbmcJAQRkaXZkAgUUc2hvcnRQcmVtaXVtRnJhY3Rpb24FD3VuZGVybHlpbmdQcmljZQkAAgEJAKwCAgkArAICCQCsAgIJAQFzAQULbG9uZ0Z1bmRpbmcJAQFzAQUMc2hvcnRGdW5kaW5nCQEBcwEJARBnZXRUd2FwU3BvdFByaWNlAAkBAXMBCQESZ2V0T3JhY2xlVHdhcFByaWNlAAFpARh2aWV3X2dldEJvcnJvd2VkQnlUcmFkZXIBB190cmFkZXIEDSR0MDc2Mzc4NzY0MzIJARNnZXRCb3Jyb3dlZEJ5VHJhZGVyAQUHX3RyYWRlcgQIYm9ycm93ZWQIBQ0kdDA3NjM3ODc2NDMyAl8xBAdhc3NldElkCAUNJHQwNzYzNzg3NjQzMgJfMgkAAgEJAKwCAgkBAXMBBQhib3Jyb3dlZAUHYXNzZXRJZAECdHgBBnZlcmlmeQAJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAJAQ5hZG1pblB1YmxpY0tleQAfwpEX", "height": 2338737, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: A446MLvcKn12ufD9TA9yURkoQiQah9C2wdWVqw62chFU Next: J7uKdaq1NavAeqpr1qshcZMfEx9sZ3mPT65fzBXvvu8G Diff:
OldNewDifferences
328328 func spreadLimit () = int(k_spreadLimit)
329329
330330
331-func maxPriceImpact () = 10000000000
331+func maxPriceImpact () = int(k_maxPriceImpact)
332332
333333
334334 func maxPriceSpread () = int(k_maxPriceSpread)
430430 let quoteAssetReserveAfter = if (_isAdd)
431431 then (_qtAstR + _quoteAssetAmount)
432432 else (_qtAstR - _quoteAssetAmount)
433- let baseAssetReserveAfter = divd(k, muld(muld(quoteAssetReserveAfter, _qtAstW), _bsAstW))
434- let amountBaseAssetBoughtAbs = abs((baseAssetReserveAfter - _bsAstR))
433+ let baseAssetReserveAfter = divd(k, quoteAssetReserveAfter)
434+ let amountBaseAssetBoughtAbs = divd(abs((baseAssetReserveAfter - _bsAstR)), _qtAstW)
435435 let amountBaseAssetBought = if (_isAdd)
436436 then amountBaseAssetBoughtAbs
437437 else -(amountBaseAssetBoughtAbs)
438- let $t01632316516 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
439- let quoteAssetReserveAfter1 = $t01632316516._1
440- let baseAssetReserveAfter1 = $t01632316516._2
441- let totalPositionSizeAfter1 = $t01632316516._3
442- let cumulativeNotionalAfter1 = $t01632316516._4
438+ let $t01631916512 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
439+ let quoteAssetReserveAfter1 = $t01631916512._1
440+ let baseAssetReserveAfter1 = $t01631916512._2
441+ let totalPositionSizeAfter1 = $t01631916512._3
442+ let cumulativeNotionalAfter1 = $t01631916512._4
443443 let priceBefore = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
444444 let marketPrice = divd(_quoteAssetAmount, amountBaseAssetBoughtAbs)
445445 let priceDiff = abs((priceBefore - marketPrice))
459459 }
460460 else 0
461461 let signedMargin = ((_marginDelta - fundingPayment) + _oldPositionMargin)
462- let $t01803518162 = if ((0 > signedMargin))
462+ let $t01803118158 = if ((0 > signedMargin))
463463 then $Tuple2(0, abs(signedMargin))
464464 else $Tuple2(abs(signedMargin), 0)
465- let remainMargin = $t01803518162._1
466- let badDebt = $t01803518162._2
465+ let remainMargin = $t01803118158._1
466+ let badDebt = $t01803118158._2
467467 $Tuple3(remainMargin, badDebt, fundingPayment)
468468 }
469469
480480 let quoteAssetAfter = divd(k, muld(baseAssetPoolAmountAfter, _baseAssetWeight))
481481 let quoteAssetSold = abs((quoteAssetAfter - muld(_quoteAssetReserve, _quoteAssetWeight)))
482482 let maxPriceImpactValue = maxPriceImpact()
483- let $t01933019523 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
484- let quoteAssetReserveAfter1 = $t01933019523._1
485- let baseAssetReserveAfter1 = $t01933019523._2
486- let totalPositionSizeAfter1 = $t01933019523._3
487- let cumulativeNotionalAfter1 = $t01933019523._4
483+ let $t01932619519 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
484+ let quoteAssetReserveAfter1 = $t01932619519._1
485+ let baseAssetReserveAfter1 = $t01932619519._2
486+ let totalPositionSizeAfter1 = $t01932619519._3
487+ let cumulativeNotionalAfter1 = $t01932619519._4
488488 let marketPrice = divd(quoteAssetSold, _baseAssetAmount)
489489 let priceDiff = abs((priceBefore - marketPrice))
490490 let priceImpact = (DECIMAL_UNIT - divd(priceBefore, (priceBefore + priceDiff)))
545545 let isShort = (0 > _positionSize)
546546 let positionNotional = if ((_option == PNL_OPTION_SPOT))
547547 then {
548- let $t02289823118 = swapOutputWithReserves(!(isShort), positionSizeAbs, false, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
549- let outPositionNotional = $t02289823118._1
550- let x1 = $t02289823118._2
551- let x2 = $t02289823118._3
552- let x3 = $t02289823118._4
548+ let $t02289423114 = swapOutputWithReserves(!(isShort), positionSizeAbs, false, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
549+ let outPositionNotional = $t02289423114._1
550+ let x1 = $t02289423114._2
551+ let x2 = $t02289423114._3
552+ let x3 = $t02289423114._4
553553 outPositionNotional
554554 }
555555 else muld(positionSizeAbs, getOracleTwapPrice())
570570
571571
572572 func getPositionNotionalAndUnrealizedPnl (_trader,_option) = {
573- let $t02454324671 = getPosition(_trader)
574- let positionSize = $t02454324671._1
575- let positionMargin = $t02454324671._2
576- let positionOpenNotional = $t02454324671._3
577- let positionLstUpdCPF = $t02454324671._4
573+ let $t02453924667 = getPosition(_trader)
574+ let positionSize = $t02453924667._1
575+ let positionMargin = $t02453924667._2
576+ let positionOpenNotional = $t02453924667._3
577+ let positionLstUpdCPF = $t02453924667._4
578578 getPositionNotionalAndUnrealizedPnlByValues(positionSize, positionOpenNotional, qtAstR(), qtAstW(), bsAstR(), bsAstW(), _option)
579579 }
580580
583583
584584
585585 func getMarginRatioByOption (_trader,_option) = {
586- let $t02518425295 = getPosition(_trader)
587- let positionSize = $t02518425295._1
588- let positionMargin = $t02518425295._2
589- let pon = $t02518425295._3
590- let positionLstUpdCPF = $t02518425295._4
591- let $t02530125394 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
592- let positionNotional = $t02530125394._1
593- let unrealizedPnl = $t02530125394._2
594- let $t02539925565 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
595- let remainMargin = $t02539925565._1
596- let badDebt = $t02539925565._2
586+ let $t02518025291 = getPosition(_trader)
587+ let positionSize = $t02518025291._1
588+ let positionMargin = $t02518025291._2
589+ let pon = $t02518025291._3
590+ let positionLstUpdCPF = $t02518025291._4
591+ let $t02529725390 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
592+ let positionNotional = $t02529725390._1
593+ let unrealizedPnl = $t02529725390._2
594+ let $t02539525561 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
595+ let remainMargin = $t02539525561._1
596+ let badDebt = $t02539525561._2
597597 calcMarginRatio(remainMargin, badDebt, positionNotional)
598598 }
599599
618618
619619
620620 func internalClosePosition (_trader,_checkMaxPriceImpact) = {
621- let $t02679826926 = getPosition(_trader)
622- let positionSize = $t02679826926._1
623- let positionMargin = $t02679826926._2
624- let positionOpenNotional = $t02679826926._3
625- let positionLstUpdCPF = $t02679826926._4
621+ let $t02679426922 = getPosition(_trader)
622+ let positionSize = $t02679426922._1
623+ let positionMargin = $t02679426922._2
624+ let positionOpenNotional = $t02679426922._3
625+ let positionLstUpdCPF = $t02679426922._4
626626 let unrealizedPnl = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)._2
627- let $t02702127189 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
628- let remainMargin = $t02702127189._1
629- let badDebt = $t02702127189._2
627+ let $t02701727185 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
628+ let remainMargin = $t02701727185._1
629+ let badDebt = $t02701727185._2
630630 let exchangedPositionSize = -(positionSize)
631631 let realizedPnl = unrealizedPnl
632632 let marginToVault = -(remainMargin)
633- let $t02731627621 = swapOutput((positionSize > 0), abs(positionSize), _checkMaxPriceImpact)
634- let exchangedQuoteAssetAmount = $t02731627621._1
635- let quoteAssetReserveAfter = $t02731627621._2
636- let baseAssetReserveAfter = $t02731627621._3
637- let totalPositionSizeAfter = $t02731627621._4
638- let cumulativeNotionalAfter = $t02731627621._5
639- let totalLongAfter = $t02731627621._6
640- let totalShortAfter = $t02731627621._7
633+ let $t02731227617 = swapOutput((positionSize > 0), abs(positionSize), _checkMaxPriceImpact)
634+ let exchangedQuoteAssetAmount = $t02731227617._1
635+ let quoteAssetReserveAfter = $t02731227617._2
636+ let baseAssetReserveAfter = $t02731227617._3
637+ let totalPositionSizeAfter = $t02731227617._4
638+ let cumulativeNotionalAfter = $t02731227617._5
639+ let totalLongAfter = $t02731227617._6
640+ let totalShortAfter = $t02731227617._7
641641 let openInterestNotionalAfter = (openInterestNotional() - positionOpenNotional)
642642 $Tuple12(exchangedPositionSize, badDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, exchangedQuoteAssetAmount, totalLongAfter, totalShortAfter)
643643 }
686686 then $Tuple2(qtAstR(), bsAstR())
687687 else {
688688 let direction = (_positionSize > 0)
689- let $t02960829787 = swapOutput(direction, abs(_positionSize), false)
690- let currentNetMarketValue = $t02960829787._1
691- let terminalQuoteAssetReserve = $t02960829787._2
692- let terminalBaseAssetReserve = $t02960829787._3
689+ let $t02960429783 = swapOutput(direction, abs(_positionSize), false)
690+ let currentNetMarketValue = $t02960429783._1
691+ let terminalQuoteAssetReserve = $t02960429783._2
692+ let terminalBaseAssetReserve = $t02960429783._3
693693 $Tuple2(terminalQuoteAssetReserve, terminalBaseAssetReserve)
694694 }
695695 }
760760 func getAdjustedFee (i,_baseFeeDiscount) = {
761761 let baseFeeRaw = fee()
762762 let baseFee = muld(baseFeeRaw, _baseFeeDiscount)
763- let $t03288033488 = if ((size(i.payments) > 1))
763+ let $t03287633484 = if ((size(i.payments) > 1))
764764 then {
765765 let artifactId = toBase58String(valueOrErrorMessage(i.payments[1].assetId, "Invalid attached artifact"))
766766 let artifactKind = strA(nftManagerAddress(), toCompositeKey(k_token_type, artifactId))
773773 else throw("Invalid attached artifact")
774774 }
775775 else $Tuple2(baseFee, false)
776- let adjustedFee = $t03288033488._1
777- let burnArtifact = $t03288033488._2
776+ let adjustedFee = $t03287633484._1
777+ let burnArtifact = $t03287633484._2
778778 $Tuple2(adjustedFee, burnArtifact)
779779 }
780780
996996 else paused())
997997 then throw("Invalid decreasePosition parameters")
998998 else {
999- let $t04546845620 = getPosition(toString(i.caller))
1000- let oldPositionSize = $t04546845620._1
1001- let oldPositionMargin = $t04546845620._2
1002- let oldPositionOpenNotional = $t04546845620._3
1003- let oldPositionLstUpdCPF = $t04546845620._4
999+ let $t04546445616 = getPosition(toString(i.caller))
1000+ let oldPositionSize = $t04546445616._1
1001+ let oldPositionMargin = $t04546445616._2
1002+ let oldPositionOpenNotional = $t04546445616._3
1003+ let oldPositionLstUpdCPF = $t04546445616._4
10041004 let _direction = if ((oldPositionSize > 0))
10051005 then DIR_SHORT
10061006 else DIR_LONG
10071007 let isAdd = (_direction == DIR_LONG)
10081008 let openNotional = muld(_amount, _leverage)
1009- let $t04579345909 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1010- let oldPositionNotional = $t04579345909._1
1011- let unrealizedPnl = $t04579345909._2
1012- let $t04591548464 = if ((oldPositionNotional > openNotional))
1009+ let $t04578945905 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1010+ let oldPositionNotional = $t04578945905._1
1011+ let unrealizedPnl = $t04578945905._2
1012+ let $t04591148460 = if ((oldPositionNotional > openNotional))
10131013 then {
1014- let $t04629246511 = swapInput(isAdd, openNotional)
1015- let exchangedPositionSize = $t04629246511._1
1016- let quoteAssetReserveAfter = $t04629246511._2
1017- let baseAssetReserveAfter = $t04629246511._3
1018- let totalPositionSizeAfter = $t04629246511._4
1019- let cumulativeNotionalAfter = $t04629246511._5
1014+ let $t04628846507 = swapInput(isAdd, openNotional)
1015+ let exchangedPositionSize = $t04628846507._1
1016+ let quoteAssetReserveAfter = $t04628846507._2
1017+ let baseAssetReserveAfter = $t04628846507._3
1018+ let totalPositionSizeAfter = $t04628846507._4
1019+ let cumulativeNotionalAfter = $t04628846507._5
10201020 let exchangedPositionSizeAbs = abs(exchangedPositionSize)
10211021 if (if ((_minBaseAssetAmount != 0))
10221022 then (_minBaseAssetAmount > exchangedPositionSizeAbs)
10241024 then throw(((("Too little base asset exchanged, got " + toString(exchangedPositionSizeAbs)) + " expected ") + toString(_minBaseAssetAmount)))
10251025 else {
10261026 let realizedPnl = divd(muld(unrealizedPnl, exchangedPositionSizeAbs), abs(oldPositionSize))
1027- let $t04694847193 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1028- let remainMargin = $t04694847193._1
1029- let badDebt = $t04694847193._2
1030- let fundingPayment = $t04694847193._3
1027+ let $t04694447189 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1028+ let remainMargin = $t04694447189._1
1029+ let badDebt = $t04694447189._2
1030+ let fundingPayment = $t04694447189._3
10311031 let exchangedQuoteAssetAmount = openNotional
10321032 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
10331033 let remainOpenNotional = if ((oldPositionSize > 0))
10421042 }
10431043 }
10441044 else throw("Close position first")
1045- let newPositionSize = $t04591548464._1
1046- let newPositionRemainMargin = $t04591548464._2
1047- let newPositionOpenNotional = $t04591548464._3
1048- let newPositionLatestCPF = $t04591548464._4
1049- let baseAssetReserveAfter = $t04591548464._5
1050- let quoteAssetReserveAfter = $t04591548464._6
1051- let totalPositionSizeAfter = $t04591548464._7
1052- let cumulativeNotionalAfter = $t04591548464._8
1053- let openInterestNotionalAfter = $t04591548464._9
1054- let totalLongAfter = $t04591548464._10
1055- let totalShortAfter = $t04591548464._11
1045+ let newPositionSize = $t04591148460._1
1046+ let newPositionRemainMargin = $t04591148460._2
1047+ let newPositionOpenNotional = $t04591148460._3
1048+ let newPositionLatestCPF = $t04591148460._4
1049+ let baseAssetReserveAfter = $t04591148460._5
1050+ let quoteAssetReserveAfter = $t04591148460._6
1051+ let totalPositionSizeAfter = $t04591148460._7
1052+ let cumulativeNotionalAfter = $t04591148460._8
1053+ let openInterestNotionalAfter = $t04591148460._9
1054+ let totalLongAfter = $t04591148460._10
1055+ let totalShortAfter = $t04591148460._11
10561056 let notifyNotional = invoke(minerAddress(), "notifyNotional", [toString(i.caller), newPositionOpenNotional], nil)
10571057 if ((notifyNotional == notifyNotional))
10581058 then (updatePosition(toString(i.caller), newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter))
11021102 case _ =>
11031103 throw("Invalid computeFeeDiscount result")
11041104 }
1105- let $t05012750191 = getAdjustedFee(i, feeDiscount)
1106- let adjustedFee = $t05012750191._1
1107- let burnArtifact = $t05012750191._2
1105+ let $t05012350187 = getAdjustedFee(i, feeDiscount)
1106+ let adjustedFee = $t05012350187._1
1107+ let burnArtifact = $t05012350187._2
11081108 let rawFeeAmount = muld(_rawAmount, adjustedFee)
11091109 let _amount = (_rawAmount - rawFeeAmount)
11101110 let distributeFeeAmount = if (isCollateralAsset)
11471147 throw("Invalid referrerFee")
11481148 }
11491149 let feeAmount = (distributeFeeAmount - referrerFee)
1150- let $t05150751647 = getPosition(_trader)
1151- let oldPositionSize = $t05150751647._1
1152- let oldPositionMargin = $t05150751647._2
1153- let oldPositionOpenNotional = $t05150751647._3
1154- let oldPositionLstUpdCPF = $t05150751647._4
1150+ let $t05150351643 = getPosition(_trader)
1151+ let oldPositionSize = $t05150351643._1
1152+ let oldPositionMargin = $t05150351643._2
1153+ let oldPositionOpenNotional = $t05150351643._3
1154+ let oldPositionLstUpdCPF = $t05150351643._4
11551155 let isNewPosition = (oldPositionSize == 0)
11561156 let isSameDirection = if ((oldPositionSize > 0))
11571157 then (_direction == DIR_LONG)
11601160 then isSameDirection
11611161 else false
11621162 let isAdd = (_direction == DIR_LONG)
1163- let $t05193654521 = if (if (isNewPosition)
1163+ let $t05193254517 = if (if (isNewPosition)
11641164 then true
11651165 else expandExisting)
11661166 then {
11671167 let openNotional = muld(_amount, _leverage)
1168- let $t05236052566 = swapInput(isAdd, openNotional)
1169- let amountBaseAssetBought = $t05236052566._1
1170- let quoteAssetReserveAfter = $t05236052566._2
1171- let baseAssetReserveAfter = $t05236052566._3
1172- let totalPositionSizeAfter = $t05236052566._4
1173- let cumulativeNotionalAfter = $t05236052566._5
1168+ let $t05235652562 = swapInput(isAdd, openNotional)
1169+ let amountBaseAssetBought = $t05235652562._1
1170+ let quoteAssetReserveAfter = $t05235652562._2
1171+ let baseAssetReserveAfter = $t05235652562._3
1172+ let totalPositionSizeAfter = $t05235652562._4
1173+ let cumulativeNotionalAfter = $t05235652562._5
11741174 if (if ((_minBaseAssetAmount != 0))
11751175 then (_minBaseAssetAmount > abs(amountBaseAssetBought))
11761176 else false)
11781178 else {
11791179 let newPositionSize = (oldPositionSize + amountBaseAssetBought)
11801180 let increaseMarginRequirement = divd(openNotional, _leverage)
1181- let $t05294753186 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
1182- let remainMargin = $t05294753186._1
1183- let x1 = $t05294753186._2
1184- let x2 = $t05294753186._3
1181+ let $t05294353182 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
1182+ let remainMargin = $t05294353182._1
1183+ let x1 = $t05294353182._2
1184+ let x2 = $t05294353182._3
11851185 if (!(requireNotOverSpreadLimit(quoteAssetReserveAfter, baseAssetReserveAfter)))
11861186 then throw("Over max spread limit")
11871187 else $Tuple11(newPositionSize, remainMargin, (oldPositionOpenNotional + openNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, (openInterestNotional() + openNotional), (totalLongPositionSize() + (if ((newPositionSize > 0))
11931193 }
11941194 else {
11951195 let openNotional = muld(_amount, _leverage)
1196- let $t05421454330 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1197- let oldPositionNotional = $t05421454330._1
1198- let unrealizedPnl = $t05421454330._2
1196+ let $t05421054326 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1197+ let oldPositionNotional = $t05421054326._1
1198+ let unrealizedPnl = $t05421054326._2
11991199 if ((oldPositionNotional > openNotional))
12001200 then throw("Use decreasePosition to decrease position size")
12011201 else throw("Close position first")
12021202 }
1203- let newPositionSize = $t05193654521._1
1204- let newPositionRemainMargin = $t05193654521._2
1205- let newPositionOpenNotional = $t05193654521._3
1206- let newPositionLatestCPF = $t05193654521._4
1207- let baseAssetReserveAfter = $t05193654521._5
1208- let quoteAssetReserveAfter = $t05193654521._6
1209- let totalPositionSizeAfter = $t05193654521._7
1210- let cumulativeNotionalAfter = $t05193654521._8
1211- let openInterestNotionalAfter = $t05193654521._9
1212- let totalLongAfter = $t05193654521._10
1213- let totalShortAfter = $t05193654521._11
1203+ let newPositionSize = $t05193254517._1
1204+ let newPositionRemainMargin = $t05193254517._2
1205+ let newPositionOpenNotional = $t05193254517._3
1206+ let newPositionLatestCPF = $t05193254517._4
1207+ let baseAssetReserveAfter = $t05193254517._5
1208+ let quoteAssetReserveAfter = $t05193254517._6
1209+ let totalPositionSizeAfter = $t05193254517._7
1210+ let cumulativeNotionalAfter = $t05193254517._8
1211+ let openInterestNotionalAfter = $t05193254517._9
1212+ let totalLongAfter = $t05193254517._10
1213+ let totalShortAfter = $t05193254517._11
12141214 let feeToStakers = (feeAmount / 2)
12151215 let feeToInsurance = (feeAmount - feeToStakers)
12161216 let stake = invoke(vaultAddress(), "addLocked", nil, [AttachedPayment(quoteAsset(), _amount)])
12781278 case _ =>
12791279 throw("Invalid computeFeeDiscount result")
12801280 }
1281- let $t05659856662 = getAdjustedFee(i, feeDiscount)
1282- let adjustedFee = $t05659856662._1
1283- let burnArtifact = $t05659856662._2
1281+ let $t05659456658 = getAdjustedFee(i, feeDiscount)
1282+ let adjustedFee = $t05659456658._1
1283+ let burnArtifact = $t05659456658._2
12841284 let rawFeeAmount = muld(_rawAmount, adjustedFee)
12851285 let _amount = (_rawAmount - rawFeeAmount)
12861286 let distributeFeeAmount = if (isCollateralAsset)
13231323 throw("Invalid referrerFee")
13241324 }
13251325 let feeAmount = (distributeFeeAmount - referrerFee)
1326- let $t05796158101 = getPosition(_trader)
1327- let oldPositionSize = $t05796158101._1
1328- let oldPositionMargin = $t05796158101._2
1329- let oldPositionOpenNotional = $t05796158101._3
1330- let oldPositionLstUpdCPF = $t05796158101._4
1326+ let $t05795758097 = getPosition(_trader)
1327+ let oldPositionSize = $t05795758097._1
1328+ let oldPositionMargin = $t05795758097._2
1329+ let oldPositionOpenNotional = $t05795758097._3
1330+ let oldPositionLstUpdCPF = $t05795758097._4
13311331 let feeToStakers = (feeAmount / 2)
13321332 let feeToInsurance = (feeAmount - feeToStakers)
13331333 let stake = invoke(vaultAddress(), "addLocked", nil, [AttachedPayment(quoteAsset(), _amount)])
13721372 else paused())
13731373 then throw("Invalid removeMargin parameters")
13741374 else {
1375- let $t05920759347 = getPosition(_trader)
1376- let oldPositionSize = $t05920759347._1
1377- let oldPositionMargin = $t05920759347._2
1378- let oldPositionOpenNotional = $t05920759347._3
1379- let oldPositionLstUpdCPF = $t05920759347._4
1375+ let $t05920359343 = getPosition(_trader)
1376+ let oldPositionSize = $t05920359343._1
1377+ let oldPositionMargin = $t05920359343._2
1378+ let oldPositionOpenNotional = $t05920359343._3
1379+ let oldPositionLstUpdCPF = $t05920359343._4
13801380 let marginDelta = -(_amount)
1381- let $t05938459563 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1382- let remainMargin = $t05938459563._1
1383- let badDebt = $t05938459563._2
1381+ let $t05938059559 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1382+ let remainMargin = $t05938059559._1
1383+ let badDebt = $t05938059559._2
13841384 if ((badDebt != 0))
13851385 then throw("Invalid removed margin amount")
13861386 else {
13891389 then throw(((("Too much margin removed: " + toString(marginRatio)) + " < ") + toString(initMarginRatio())))
13901390 else {
13911391 let quoteAssetStr = toBase58String(quoteAsset())
1392- let $t06000760061 = getBorrowedByTrader(_trader)
1393- let borrowed = $t06000760061._1
1394- let assetId = $t06000760061._2
1392+ let $t06000360057 = getBorrowedByTrader(_trader)
1393+ let borrowed = $t06000360057._1
1394+ let assetId = $t06000360057._2
13951395 let toRepay = if ((_amount > borrowed))
13961396 then borrowed
13971397 else _amount
14501450 else paused())
14511451 then throw("Invalid closePosition parameters")
14521452 else {
1453- let $t06231162689 = internalClosePosition(_trader, true)
1454- let x1 = $t06231162689._1
1455- let positionBadDebt = $t06231162689._2
1456- let realizedPnl = $t06231162689._3
1457- let marginToVault = $t06231162689._4
1458- let quoteAssetReserveAfter = $t06231162689._5
1459- let baseAssetReserveAfter = $t06231162689._6
1460- let totalPositionSizeAfter = $t06231162689._7
1461- let cumulativeNotionalAfter = $t06231162689._8
1462- let openInterestNotionalAfter = $t06231162689._9
1463- let x2 = $t06231162689._10
1464- let totalLongAfter = $t06231162689._11
1465- let totalShortAfter = $t06231162689._12
1453+ let $t06230762685 = internalClosePosition(_trader, true)
1454+ let x1 = $t06230762685._1
1455+ let positionBadDebt = $t06230762685._2
1456+ let realizedPnl = $t06230762685._3
1457+ let marginToVault = $t06230762685._4
1458+ let quoteAssetReserveAfter = $t06230762685._5
1459+ let baseAssetReserveAfter = $t06230762685._6
1460+ let totalPositionSizeAfter = $t06230762685._7
1461+ let cumulativeNotionalAfter = $t06230762685._8
1462+ let openInterestNotionalAfter = $t06230762685._9
1463+ let x2 = $t06230762685._10
1464+ let totalLongAfter = $t06230762685._11
1465+ let totalShortAfter = $t06230762685._12
14661466 if ((positionBadDebt > 0))
14671467 then throw("Unable to close position with bad debt")
14681468 else {
14691469 let withdrawAmount = abs(marginToVault)
14701470 let ammBalance = (cbalance() - withdrawAmount)
1471- let $t06301363528 = if ((0 > ammBalance))
1471+ let $t06300963524 = if ((0 > ammBalance))
14721472 then $Tuple2(0, abs(ammBalance))
14731473 else $Tuple2(ammBalance, 0)
1474- let ammNewBalance = $t06301363528._1
1475- let x11 = $t06301363528._2
1474+ let ammNewBalance = $t06300963524._1
1475+ let x11 = $t06300963524._2
14761476 let unstake = invoke(vaultAddress(), "withdrawLocked", [withdrawAmount], nil)
14771477 if ((unstake == unstake))
14781478 then {
1479- let $t06374063794 = getBorrowedByTrader(_trader)
1480- let borrowed = $t06374063794._1
1481- let assetId = $t06374063794._2
1482- let $t06380964726 = if ((borrowed > 0))
1479+ let $t06373663790 = getBorrowedByTrader(_trader)
1480+ let borrowed = $t06373663790._1
1481+ let assetId = $t06373663790._2
1482+ let $t06380564722 = if ((borrowed > 0))
14831483 then if ((withdrawAmount >= borrowed))
14841484 then {
14851485 let doRepay = invoke(collateralAddress(), "repay", [_trader, assetId], [AttachedPayment(quoteAsset(), borrowed)])
14941494 else throw("Strict value is not equal to itself.")
14951495 }
14961496 else $Tuple2(nil, withdrawAmount)
1497- if (($t06380964726 == $t06380964726))
1497+ if (($t06380564722 == $t06380564722))
14981498 then {
1499- let quoteWithdrawAmount = $t06380964726._2
1500- let sendCollateralAction = $t06380964726._1
1499+ let quoteWithdrawAmount = $t06380564722._2
1500+ let sendCollateralAction = $t06380564722._1
15011501 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, 0], nil)
15021502 if ((notifyNotional == notifyNotional))
15031503 then ((((deletePosition(_trader) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter)) ++ (if ((quoteWithdrawAmount > 0))
15421542 then (DECIMAL_UNIT > partialLiquidationRatio())
15431543 else false)
15441544 then {
1545- let $t06649466644 = getPosition(_trader)
1546- let oldPositionSize = $t06649466644._1
1547- let oldPositionMargin = $t06649466644._2
1548- let oldPositionOpenNotional = $t06649466644._3
1549- let oldPositionLstUpdCPF = $t06649466644._4
1545+ let $t06649066640 = getPosition(_trader)
1546+ let oldPositionSize = $t06649066640._1
1547+ let oldPositionMargin = $t06649066640._2
1548+ let oldPositionOpenNotional = $t06649066640._3
1549+ let oldPositionLstUpdCPF = $t06649066640._4
15501550 let _direction = if ((oldPositionSize > 0))
15511551 then DIR_SHORT
15521552 else DIR_LONG
15531553 let isAdd = (_direction == DIR_LONG)
15541554 let exchangedQuoteAssetAmount = getPartialLiquidationAmount(_trader, oldPositionSize)
1555- let $t06686966973 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1556- let oldPositionNotional = $t06686966973._1
1557- let unrealizedPnl = $t06686966973._2
1558- let $t06698167213 = swapInput(isAdd, exchangedQuoteAssetAmount)
1559- let exchangedPositionSize = $t06698167213._1
1560- let quoteAssetReserveAfter = $t06698167213._2
1561- let baseAssetReserveAfter = $t06698167213._3
1562- let totalPositionSizeAfter = $t06698167213._4
1563- let cumulativeNotionalAfter = $t06698167213._5
1555+ let $t06686566969 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1556+ let oldPositionNotional = $t06686566969._1
1557+ let unrealizedPnl = $t06686566969._2
1558+ let $t06697767209 = swapInput(isAdd, exchangedQuoteAssetAmount)
1559+ let exchangedPositionSize = $t06697767209._1
1560+ let quoteAssetReserveAfter = $t06697767209._2
1561+ let baseAssetReserveAfter = $t06697767209._3
1562+ let totalPositionSizeAfter = $t06697767209._4
1563+ let cumulativeNotionalAfter = $t06697767209._5
15641564 let liquidationRatio = divd(abs(exchangedPositionSize), abs(oldPositionSize))
15651565 let realizedPnl = muld(unrealizedPnl, liquidationRatio)
1566- let $t06750267735 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1567- let remainMargin = $t06750267735._1
1568- let badDebt = $t06750267735._2
1569- let fundingPayment = $t06750267735._3
1566+ let $t06749867731 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1567+ let remainMargin = $t06749867731._1
1568+ let badDebt = $t06749867731._2
1569+ let fundingPayment = $t06749867731._3
15701570 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
15711571 let remainOpenNotional = if ((oldPositionSize > 0))
15721572 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
15801580 let newPositionLstUpdCPF = latestCumulativePremiumFraction(newPositionSize)
15811581 let openInterestNotionalAfter = (openInterestNotional() - exchangedQuoteAssetAmount)
15821582 let ammBalance = (cbalance() - liquidationPenalty)
1583- let $t06890869037 = if ((0 > ammBalance))
1583+ let $t06890469033 = if ((0 > ammBalance))
15841584 then $Tuple2(0, abs(ammBalance))
15851585 else $Tuple2(ammBalance, 0)
1586- let newAmmBalance = $t06890869037._1
1587- let x11 = $t06890869037._2
1588- let $t06904569099 = getBorrowedByTrader(_trader)
1589- let borrowed = $t06904569099._1
1590- let assetId = $t06904569099._2
1586+ let newAmmBalance = $t06890469033._1
1587+ let x11 = $t06890469033._2
1588+ let $t06904169095 = getBorrowedByTrader(_trader)
1589+ let borrowed = $t06904169095._1
1590+ let assetId = $t06904169095._2
15911591 let doLiquidateCollateral = if ((borrowed > 0))
15921592 then {
15931593 let collateralToSell = muld(borrowed, liquidationRatio)
16211621 else throw("Strict value is not equal to itself.")
16221622 }
16231623 else {
1624- let $t07090471359 = internalClosePosition(_trader, false)
1625- let x1 = $t07090471359._1
1626- let badDebt = $t07090471359._2
1627- let x2 = $t07090471359._3
1628- let x3 = $t07090471359._4
1629- let quoteAssetReserveAfter = $t07090471359._5
1630- let baseAssetReserveAfter = $t07090471359._6
1631- let totalPositionSizeAfter = $t07090471359._7
1632- let cumulativeNotionalAfter = $t07090471359._8
1633- let openInterestNotionalAfter = $t07090471359._9
1634- let exchangedQuoteAssetAmount = $t07090471359._10
1635- let totalLongAfter = $t07090471359._11
1636- let totalShortAfter = $t07090471359._12
1624+ let $t07090071355 = internalClosePosition(_trader, false)
1625+ let x1 = $t07090071355._1
1626+ let badDebt = $t07090071355._2
1627+ let x2 = $t07090071355._3
1628+ let x3 = $t07090071355._4
1629+ let quoteAssetReserveAfter = $t07090071355._5
1630+ let baseAssetReserveAfter = $t07090071355._6
1631+ let totalPositionSizeAfter = $t07090071355._7
1632+ let cumulativeNotionalAfter = $t07090071355._8
1633+ let openInterestNotionalAfter = $t07090071355._9
1634+ let exchangedQuoteAssetAmount = $t07090071355._10
1635+ let totalLongAfter = $t07090071355._11
1636+ let totalShortAfter = $t07090071355._12
16371637 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
16381638 let feeToLiquidator = (liquidationPenalty / 2)
16391639 let feeToInsurance = (liquidationPenalty - feeToLiquidator)
16401640 let ammBalance = (cbalance() - liquidationPenalty)
1641- let $t07177171900 = if ((0 > ammBalance))
1641+ let $t07176771896 = if ((0 > ammBalance))
16421642 then $Tuple2(0, abs(ammBalance))
16431643 else $Tuple2(ammBalance, 0)
1644- let newAmmBalance = $t07177171900._1
1645- let x11 = $t07177171900._2
1646- let $t07190871962 = getBorrowedByTrader(_trader)
1647- let borrowed = $t07190871962._1
1648- let assetId = $t07190871962._2
1644+ let newAmmBalance = $t07176771896._1
1645+ let x11 = $t07176771896._2
1646+ let $t07190471958 = getBorrowedByTrader(_trader)
1647+ let borrowed = $t07190471958._1
1648+ let assetId = $t07190471958._2
16491649 let doLiquidateCollateral = if ((borrowed > 0))
16501650 then {
16511651 let realizeAndClose = invoke(collateralAddress(), "realizePartiallyAndClose", [_trader, assetId], nil)
17021702 then throw(((("Invalid funding block timestamp: " + toString(lastBlock.timestamp)) + " < ") + toString(fundingBlockTimestamp)))
17031703 else {
17041704 let underlyingPrice = getOracleTwapPrice()
1705- let $t07398974051 = getFunding()
1706- let shortPremiumFraction = $t07398974051._1
1707- let longPremiumFraction = $t07398974051._2
1705+ let $t07398574047 = getFunding()
1706+ let shortPremiumFraction = $t07398574047._1
1707+ let longPremiumFraction = $t07398574047._2
17081708 updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), divd(longPremiumFraction, underlyingPrice), divd(shortPremiumFraction, underlyingPrice))
17091709 }
17101710 }
17131713
17141714 @Callable(i)
17151715 func syncTerminalPriceToOracle () = {
1716- let $t07443374554 = getSyncTerminalPrice(getOracleTwapPrice())
1717- let newQuoteAssetWeight = $t07443374554._1
1718- let newBaseAssetWeight = $t07443374554._2
1719- let marginToVault = $t07443374554._3
1716+ let $t07442974550 = getSyncTerminalPrice(getOracleTwapPrice())
1717+ let newQuoteAssetWeight = $t07442974550._1
1718+ let newBaseAssetWeight = $t07442974550._2
1719+ let marginToVault = $t07442974550._3
17201720 updateAmmWeights(newQuoteAssetWeight, newBaseAssetWeight)
17211721 }
17221722
17271727 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
17281728 if ((sync == sync))
17291729 then {
1730- let $t07473274792 = internalClosePosition(_trader, false)
1731- let x1 = $t07473274792._1
1732- let x2 = $t07473274792._2
1733- let x3 = $t07473274792._3
1734- let x4 = $t07473274792._4
1730+ let $t07472874788 = internalClosePosition(_trader, false)
1731+ let x1 = $t07472874788._1
1732+ let x2 = $t07472874788._2
1733+ let x3 = $t07472874788._3
1734+ let x4 = $t07472874788._4
17351735 throw((((s(x2) + s(x3)) + s(x4)) + s(getMarginRatio(_trader))))
17361736 }
17371737 else throw("Strict value is not equal to itself.")
17441744 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
17451745 if ((sync == sync))
17461746 then {
1747- let $t07500375104 = getPosition(_trader)
1748- let positionSize = $t07500375104._1
1749- let positionMargin = $t07500375104._2
1750- let pon = $t07500375104._3
1751- let positionLstUpdCPF = $t07500375104._4
1752- let $t07510775208 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1753- let positionNotional = $t07510775208._1
1754- let unrealizedPnl = $t07510775208._2
1755- let $t07521175383 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1756- let remainMargin = $t07521175383._1
1757- let badDebt = $t07521175383._2
1758- let fundingPayment = $t07521175383._3
1747+ let $t07499975100 = getPosition(_trader)
1748+ let positionSize = $t07499975100._1
1749+ let positionMargin = $t07499975100._2
1750+ let pon = $t07499975100._3
1751+ let positionLstUpdCPF = $t07499975100._4
1752+ let $t07510375204 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1753+ let positionNotional = $t07510375204._1
1754+ let unrealizedPnl = $t07510375204._2
1755+ let $t07520775379 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1756+ let remainMargin = $t07520775379._1
1757+ let badDebt = $t07520775379._2
1758+ let fundingPayment = $t07520775379._3
17591759 throw((((((s(remainMargin) + s(fundingPayment)) + s(getMarginRatio(_trader))) + s(unrealizedPnl)) + s(badDebt)) + s(positionNotional)))
17601760 }
17611761 else throw("Strict value is not equal to itself.")
17731773
17741774 @Callable(i)
17751775 func view_getTerminalAmmPrice () = {
1776- let $t07573075811 = getTerminalAmmState()
1777- let terminalQuoteAssetReserve = $t07573075811._1
1778- let terminalBaseAssetReserve = $t07573075811._2
1776+ let $t07572675807 = getTerminalAmmState()
1777+ let terminalQuoteAssetReserve = $t07572675807._1
1778+ let terminalBaseAssetReserve = $t07572675807._2
17791779 let price = divd(muld(terminalQuoteAssetReserve, qtAstW()), muld(terminalBaseAssetReserve, bsAstW()))
17801780 throw(toString(price))
17811781 }
17851785 @Callable(i)
17861786 func view_getFunding () = {
17871787 let underlyingPrice = getOracleTwapPrice()
1788- let $t07603076092 = getFunding()
1789- let shortPremiumFraction = $t07603076092._1
1790- let longPremiumFraction = $t07603076092._2
1788+ let $t07602676088 = getFunding()
1789+ let shortPremiumFraction = $t07602676088._1
1790+ let longPremiumFraction = $t07602676088._2
17911791 let longFunding = divd(longPremiumFraction, underlyingPrice)
17921792 let shortFunding = divd(shortPremiumFraction, underlyingPrice)
17931793 throw((((s(longFunding) + s(shortFunding)) + s(getTwapSpotPrice())) + s(getOracleTwapPrice())))
17971797
17981798 @Callable(i)
17991799 func view_getBorrowedByTrader (_trader) = {
1800- let $t07638276436 = getBorrowedByTrader(_trader)
1801- let borrowed = $t07638276436._1
1802- let assetId = $t07638276436._2
1800+ let $t07637876432 = getBorrowedByTrader(_trader)
1801+ let borrowed = $t07637876432._1
1802+ let assetId = $t07637876432._2
18031803 throw((s(borrowed) + assetId))
18041804 }
18051805
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 = "k_ora"
99
1010 let k_balance = "k_balance"
1111
1212 let k_positionSize = "k_positionSize"
1313
1414 let k_positionMargin = "k_positionMargin"
1515
1616 let k_positionOpenNotional = "k_positionOpenNotional"
1717
1818 let k_positionLastUpdatedCumulativePremiumFraction = "k_positionFraction"
1919
2020 let k_positionClosedDate = "k_positionClosedDate"
2121
2222 let k_positionAsset = "k_positionAsset"
2323
2424 let k_initialized = "k_initialized"
2525
2626 let k_paused = "k_paused"
2727
2828 let k_fee = "k_fee"
2929
3030 let k_fundingPeriod = "k_fundingPeriod"
3131
3232 let k_initMarginRatio = "k_initMarginRatio"
3333
3434 let k_maintenanceMarginRatio = "k_mmr"
3535
3636 let k_liquidationFeeRatio = "k_liquidationFeeRatio"
3737
3838 let k_partialLiquidationRatio = "k_partLiquidationRatio"
3939
4040 let k_spreadLimit = "k_spreadLimit"
4141
4242 let k_maxPriceImpact = "k_maxPriceImpact"
4343
4444 let k_maxPriceSpread = "k_maxPriceSpread"
4545
4646 let k_lastDataStr = "k_lastDataStr"
4747
4848 let k_lastMinuteId = "k_lastMinuteId"
4949
5050 let k_twapDataLastCumulativePrice = "k_twapDataLastCumulativePrice"
5151
5252 let k_twapDataLastPrice = "k_twapDataLastPrice"
5353
5454 let k_twapDataPreviousMinuteId = "k_twapDataPreviousMinuteId"
5555
5656 let k_latestLongCumulativePremiumFraction = "k_latestLongPremiumFraction"
5757
5858 let k_latestShortCumulativePremiumFraction = "k_latestShortPremiumFraction"
5959
6060 let k_nextFundingBlock = "k_nextFundingBlockMinTimestamp"
6161
6262 let k_longFundingRate = "k_longFundingRate"
6363
6464 let k_shortFundingRate = "k_shortFundingRate"
6565
6666 let k_quoteAssetReserve = "k_qtAstR"
6767
6868 let k_baseAssetReserve = "k_bsAstR"
6969
7070 let k_quoteAssetWeight = "k_qtAstW"
7171
7272 let k_baseAssetWeight = "k_bsAstW"
7373
7474 let k_totalPositionSize = "k_totalPositionSize"
7575
7676 let k_totalLongPositionSize = "k_totalLongPositionSize"
7777
7878 let k_totalShortPositionSize = "k_totalShortPositionSize"
7979
8080 let k_cumulativeNotional = "k_cumulativeNotional"
8181
8282 let k_openInterestNotional = "k_openInterestNotional"
8383
8484 let k_coordinatorAddress = "k_coordinatorAddress"
8585
8686 let k_vault_address = "k_vault_address"
8787
8888 let k_admin_address = "k_admin_address"
8989
9090 let k_admin_public_key = "k_admin_public_key"
9191
9292 let k_quote_asset = "k_quote_asset"
9393
9494 let k_quote_staking = "k_quote_staking"
9595
9696 let k_staking_address = "k_staking_address"
9797
9898 let k_miner_address = "k_miner_address"
9999
100100 let k_orders_address = "k_orders_address"
101101
102102 let k_referral_address = "k_referral_address"
103103
104104 let k_manager_address = "k_manager_address"
105105
106106 let k_collateral_address = "k_collateral_address"
107107
108108 let k_exchange_address = "k_exchange_address"
109109
110110 let k_nft_manager_address = "k_nft_manager_address"
111111
112112 let k_trader_market_asset_collateral = "k_trader_market_asset_collateral"
113113
114114 func toCompositeKey (_key,_address) = ((_key + "_") + _address)
115115
116116
117117 func coordinator () = valueOrErrorMessage(addressFromString(getStringValue(this, k_coordinatorAddress)), "Coordinator not set")
118118
119119
120120 func adminAddress () = addressFromString(getStringValue(coordinator(), k_admin_address))
121121
122122
123123 func adminPublicKey () = fromBase58String(getStringValue(coordinator(), k_admin_public_key))
124124
125125
126126 func quoteAsset () = fromBase58String(getStringValue(coordinator(), k_quote_asset))
127127
128128
129129 func quoteAssetStaking () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_quote_staking)), "Quote asset staking not set")
130130
131131
132132 func stakingAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_staking_address)), "Staking not set")
133133
134134
135135 func vaultAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_vault_address)), "Vault not set")
136136
137137
138138 func minerAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_miner_address)), "Miner not set")
139139
140140
141141 func ordersAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_orders_address)), "Orders not set")
142142
143143
144144 func referralAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_referral_address)), "Referral not set")
145145
146146
147147 func nftManagerAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_nft_manager_address)), "NFT Manager not set")
148148
149149
150150 func collateralAddress () = valueOrErrorMessage(addressFromString(getStringValue(coordinator(), k_collateral_address)), "Collateral Manager not set")
151151
152152
153153 func swapAddress () = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(coordinator(), k_exchange_address), "No swap address")), "Invalid swap address")
154154
155155
156156 let k_whitelist_asset = "k_whitelist_asset"
157157
158158 func isWhitelistAsset (_assetId) = valueOrElse(getBoolean(collateralAddress(), toCompositeKey(k_whitelist_asset, _assetId)), false)
159159
160160
161161 let k_token_param = "k_token_param"
162162
163163 let k_token_type = "k_token_type"
164164
165165 let FEE_REDUCTION_TOKEN_TYPE = "fee_reduction"
166166
167167 let DIR_LONG = 1
168168
169169 let DIR_SHORT = 2
170170
171171 let TWAP_INTERVAL = 15
172172
173173 let ORACLE_INTERVAL = 15
174174
175175 let SECONDS = 1000
176176
177177 let DECIMAL_NUMBERS = 6
178178
179179 let DECIMAL_UNIT = (1 * (((((10 * 10) * 10) * 10) * 10) * 10))
180180
181181 let ONE_DAY = (86400 * DECIMAL_UNIT)
182182
183183 let ALL_FEES = 100
184184
185185 let PNL_OPTION_SPOT = 1
186186
187187 let PNL_OPTION_ORACLE = 2
188188
189189 func s (_x) = (toString(_x) + ",")
190190
191191
192192 func divd (_x,_y) = fraction(_x, DECIMAL_UNIT, _y, HALFEVEN)
193193
194194
195195 func muld (_x,_y) = fraction(_x, _y, DECIMAL_UNIT, HALFEVEN)
196196
197197
198198 func sqrtd (_x) = sqrt(_x, DECIMAL_NUMBERS, DECIMAL_NUMBERS, HALFEVEN)
199199
200200
201201 func powd (_x,_y) = pow(_x, DECIMAL_NUMBERS, _y, DECIMAL_NUMBERS, DECIMAL_NUMBERS, HALFEVEN)
202202
203203
204204 func bdivd (_x,_y) = fraction(_x, toBigInt(DECIMAL_UNIT), _y, HALFEVEN)
205205
206206
207207 func bmuld (_x,_y) = fraction(_x, _y, toBigInt(DECIMAL_UNIT), HALFEVEN)
208208
209209
210210 func bsqrtd (_x) = sqrtBigInt(_x, DECIMAL_NUMBERS, DECIMAL_NUMBERS, HALFEVEN)
211211
212212
213213 func bpowd (_x,_y) = pow(_x, DECIMAL_NUMBERS, _y, DECIMAL_NUMBERS, DECIMAL_NUMBERS, HALFEVEN)
214214
215215
216216 func abs (_x) = if ((_x > 0))
217217 then _x
218218 else -(_x)
219219
220220
221221 func vmax (_x,_y) = if ((_x >= _y))
222222 then _x
223223 else _y
224224
225225
226226 func listToStr (_list) = {
227227 func _join (accumulator,val) = ((accumulator + val) + ",")
228228
229229 let newListStr = {
230230 let $l = _list
231231 let $s = size($l)
232232 let $acc0 = ""
233233 func $f0_1 ($a,$i) = if (($i >= $s))
234234 then $a
235235 else _join($a, $l[$i])
236236
237237 func $f0_2 ($a,$i) = if (($i >= $s))
238238 then $a
239239 else throw("List size exceeds 20")
240240
241241 $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)
242242 }
243243 let newListStrU = dropRight(newListStr, 1)
244244 let newListStrR = if ((take(newListStrU, 1) == ","))
245245 then drop(newListStrU, 1)
246246 else newListStrU
247247 newListStrR
248248 }
249249
250250
251251 func strToList (_str) = split(_str, ",")
252252
253253
254254 func pushToQueue (_list,_maxSize,_value) = if ((size(_list) > _maxSize))
255255 then (removeByIndex(_list, 0) :+ _value)
256256 else (_list :+ _value)
257257
258258
259259 func int (k) = valueOrErrorMessage(getInteger(this, k), ("no value for " + k))
260260
261261
262262 func intOr (k,def) = valueOrElse(getInteger(this, k), def)
263263
264264
265265 func strA (_address,_key) = {
266266 let val = valueOrErrorMessage(getString(_address, _key), ("No value for key " + _key))
267267 val
268268 }
269269
270270
271271 func intA (_address,_key) = {
272272 let val = valueOrErrorMessage(getInteger(_address, _key), ("No value for key " + _key))
273273 val
274274 }
275275
276276
277277 func cbalance () = int(k_balance)
278278
279279
280280 func fee () = int(k_fee)
281281
282282
283283 func initMarginRatio () = int(k_initMarginRatio)
284284
285285
286286 func qtAstR () = int(k_quoteAssetReserve)
287287
288288
289289 func bsAstR () = int(k_baseAssetReserve)
290290
291291
292292 func qtAstW () = intOr(k_quoteAssetWeight, DECIMAL_UNIT)
293293
294294
295295 func bsAstW () = intOr(k_baseAssetWeight, DECIMAL_UNIT)
296296
297297
298298 func totalPositionSize () = int(k_totalPositionSize)
299299
300300
301301 func cumulativeNotional () = int(k_cumulativeNotional)
302302
303303
304304 func openInterestNotional () = int(k_openInterestNotional)
305305
306306
307307 func nextFundingBlockTimestamp () = int(k_nextFundingBlock)
308308
309309
310310 func fundingPeriodRaw () = int(k_fundingPeriod)
311311
312312
313313 func fundingPeriodDecimal () = (fundingPeriodRaw() * DECIMAL_UNIT)
314314
315315
316316 func fundingPeriodSeconds () = (fundingPeriodRaw() * SECONDS)
317317
318318
319319 func maintenanceMarginRatio () = int(k_maintenanceMarginRatio)
320320
321321
322322 func liquidationFeeRatio () = int(k_liquidationFeeRatio)
323323
324324
325325 func partialLiquidationRatio () = int(k_partialLiquidationRatio)
326326
327327
328328 func spreadLimit () = int(k_spreadLimit)
329329
330330
331-func maxPriceImpact () = 10000000000
331+func maxPriceImpact () = int(k_maxPriceImpact)
332332
333333
334334 func maxPriceSpread () = int(k_maxPriceSpread)
335335
336336
337337 func latestLongCumulativePremiumFraction () = int(k_latestLongCumulativePremiumFraction)
338338
339339
340340 func latestShortCumulativePremiumFraction () = int(k_latestShortCumulativePremiumFraction)
341341
342342
343343 func totalShortPositionSize () = int(k_totalShortPositionSize)
344344
345345
346346 func totalLongPositionSize () = int(k_totalLongPositionSize)
347347
348348
349349 func getActualCaller (i) = valueOrElse(getString(ordersAddress(), "k_sender"), toString(i.caller))
350350
351351
352352 func requireMoreMarginRatio (_marginRatio,_baseMarginRatio,_largerThanOrEqualTo) = {
353353 let remainingMarginRatio = (_marginRatio - _baseMarginRatio)
354354 if (if (_largerThanOrEqualTo)
355355 then (0 > remainingMarginRatio)
356356 else false)
357357 then throw("Invalid margin")
358358 else if (if (!(_largerThanOrEqualTo))
359359 then (remainingMarginRatio >= 0)
360360 else false)
361361 then throw("Invalid margin")
362362 else true
363363 }
364364
365365
366366 func latestCumulativePremiumFraction (_positionSize) = if ((_positionSize == 0))
367367 then throw("Should not be called with _positionSize == 0")
368368 else if ((_positionSize > 0))
369369 then latestLongCumulativePremiumFraction()
370370 else latestShortCumulativePremiumFraction()
371371
372372
373373 func getPosition (_trader) = {
374374 let positionSizeOpt = getInteger(this, toCompositeKey(k_positionSize, _trader))
375375 match positionSizeOpt {
376376 case positionSize: Int =>
377377 $Tuple4(positionSize, getIntegerValue(this, toCompositeKey(k_positionMargin, _trader)), getIntegerValue(this, toCompositeKey(k_positionOpenNotional, _trader)), getIntegerValue(this, toCompositeKey(k_positionLastUpdatedCumulativePremiumFraction, _trader)))
378378 case _ =>
379379 $Tuple4(0, 0, 0, 0)
380380 }
381381 }
382382
383383
384384 func getPositionAsset (_trader) = {
385385 let positionAssetOpt = getString(this, toCompositeKey(k_positionAsset, _trader))
386386 match positionAssetOpt {
387387 case positionAsset: String =>
388388 positionAsset
389389 case _ =>
390390 toBase58String(quoteAsset())
391391 }
392392 }
393393
394394
395395 func requireOpenPosition (_trader) = if ((getPosition(_trader)._1 == 0))
396396 then throw("No open position")
397397 else true
398398
399399
400400 func initialized () = valueOrElse(getBoolean(this, k_initialized), false)
401401
402402
403403 func paused () = valueOrElse(getBoolean(this, k_paused), false)
404404
405405
406406 func updateReserve (_isAdd,_quoteAssetAmount,_baseAssetAmount) = if (_isAdd)
407407 then {
408408 let newBase = (bsAstR() - _baseAssetAmount)
409409 if ((0 >= newBase))
410410 then throw("Tx lead to base asset reserve <= 0, revert")
411411 else $Tuple4((qtAstR() + _quoteAssetAmount), newBase, (totalPositionSize() + _baseAssetAmount), (cumulativeNotional() + _quoteAssetAmount))
412412 }
413413 else {
414414 let newQuote = (qtAstR() - _quoteAssetAmount)
415415 if ((0 >= newQuote))
416416 then throw("Tx lead to base quote reserve <= 0, revert")
417417 else $Tuple4(newQuote, (bsAstR() + _baseAssetAmount), (totalPositionSize() - _baseAssetAmount), (cumulativeNotional() - _quoteAssetAmount))
418418 }
419419
420420
421421 func calcInvariant (_qtAstR,_qtAstW,_bsAstR,_bsAstW) = muld(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
422422
423423
424424 func swapInput (_isAdd,_quoteAssetAmount) = {
425425 let _qtAstR = qtAstR()
426426 let _bsAstR = bsAstR()
427427 let _qtAstW = qtAstW()
428428 let _bsAstW = bsAstW()
429429 let k = calcInvariant(_qtAstR, _qtAstW, _bsAstR, _bsAstW)
430430 let quoteAssetReserveAfter = if (_isAdd)
431431 then (_qtAstR + _quoteAssetAmount)
432432 else (_qtAstR - _quoteAssetAmount)
433- let baseAssetReserveAfter = divd(k, muld(muld(quoteAssetReserveAfter, _qtAstW), _bsAstW))
434- let amountBaseAssetBoughtAbs = abs((baseAssetReserveAfter - _bsAstR))
433+ let baseAssetReserveAfter = divd(k, quoteAssetReserveAfter)
434+ let amountBaseAssetBoughtAbs = divd(abs((baseAssetReserveAfter - _bsAstR)), _qtAstW)
435435 let amountBaseAssetBought = if (_isAdd)
436436 then amountBaseAssetBoughtAbs
437437 else -(amountBaseAssetBoughtAbs)
438- let $t01632316516 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
439- let quoteAssetReserveAfter1 = $t01632316516._1
440- let baseAssetReserveAfter1 = $t01632316516._2
441- let totalPositionSizeAfter1 = $t01632316516._3
442- let cumulativeNotionalAfter1 = $t01632316516._4
438+ let $t01631916512 = updateReserve(_isAdd, _quoteAssetAmount, amountBaseAssetBoughtAbs)
439+ let quoteAssetReserveAfter1 = $t01631916512._1
440+ let baseAssetReserveAfter1 = $t01631916512._2
441+ let totalPositionSizeAfter1 = $t01631916512._3
442+ let cumulativeNotionalAfter1 = $t01631916512._4
443443 let priceBefore = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
444444 let marketPrice = divd(_quoteAssetAmount, amountBaseAssetBoughtAbs)
445445 let priceDiff = abs((priceBefore - marketPrice))
446446 let priceImpact = (DECIMAL_UNIT - divd(priceBefore, (priceBefore + priceDiff)))
447447 let maxPriceImpactValue = maxPriceImpact()
448448 if ((priceImpact > maxPriceImpactValue))
449449 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)))
450450 else $Tuple5(amountBaseAssetBought, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1, cumulativeNotionalAfter1)
451451 }
452452
453453
454454 func calcRemainMarginWithFundingPayment (_oldPositionSize,_oldPositionMargin,_oldPositionCumulativePremiumFraction,_marginDelta) = {
455455 let fundingPayment = if ((_oldPositionSize != 0))
456456 then {
457457 let _latestCumulativePremiumFraction = latestCumulativePremiumFraction(_oldPositionSize)
458458 muld((_latestCumulativePremiumFraction - _oldPositionCumulativePremiumFraction), _oldPositionSize)
459459 }
460460 else 0
461461 let signedMargin = ((_marginDelta - fundingPayment) + _oldPositionMargin)
462- let $t01803518162 = if ((0 > signedMargin))
462+ let $t01803118158 = if ((0 > signedMargin))
463463 then $Tuple2(0, abs(signedMargin))
464464 else $Tuple2(abs(signedMargin), 0)
465- let remainMargin = $t01803518162._1
466- let badDebt = $t01803518162._2
465+ let remainMargin = $t01803118158._1
466+ let badDebt = $t01803118158._2
467467 $Tuple3(remainMargin, badDebt, fundingPayment)
468468 }
469469
470470
471471 func swapOutputWithReserves (_isAdd,_baseAssetAmount,_checkMaxPriceImpact,_quoteAssetReserve,_quoteAssetWeight,_baseAssetReserve,_baseAssetWeight) = {
472472 let priceBefore = divd(muld(_quoteAssetReserve, _quoteAssetWeight), muld(_baseAssetReserve, _baseAssetWeight))
473473 if ((_baseAssetAmount == 0))
474474 then throw("Invalid base asset amount")
475475 else {
476476 let k = calcInvariant(_quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
477477 let baseAssetPoolAmountAfter = if (_isAdd)
478478 then (_baseAssetReserve + _baseAssetAmount)
479479 else (_baseAssetReserve - _baseAssetAmount)
480480 let quoteAssetAfter = divd(k, muld(baseAssetPoolAmountAfter, _baseAssetWeight))
481481 let quoteAssetSold = abs((quoteAssetAfter - muld(_quoteAssetReserve, _quoteAssetWeight)))
482482 let maxPriceImpactValue = maxPriceImpact()
483- let $t01933019523 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
484- let quoteAssetReserveAfter1 = $t01933019523._1
485- let baseAssetReserveAfter1 = $t01933019523._2
486- let totalPositionSizeAfter1 = $t01933019523._3
487- let cumulativeNotionalAfter1 = $t01933019523._4
483+ let $t01932619519 = updateReserve(!(_isAdd), quoteAssetSold, _baseAssetAmount)
484+ let quoteAssetReserveAfter1 = $t01932619519._1
485+ let baseAssetReserveAfter1 = $t01932619519._2
486+ let totalPositionSizeAfter1 = $t01932619519._3
487+ let cumulativeNotionalAfter1 = $t01932619519._4
488488 let marketPrice = divd(quoteAssetSold, _baseAssetAmount)
489489 let priceDiff = abs((priceBefore - marketPrice))
490490 let priceImpact = (DECIMAL_UNIT - divd(priceBefore, (priceBefore + priceDiff)))
491491 if (if ((priceImpact > maxPriceImpactValue))
492492 then _checkMaxPriceImpact
493493 else false)
494494 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)))
495495 else $Tuple8(quoteAssetSold, quoteAssetReserveAfter1, baseAssetReserveAfter1, totalPositionSizeAfter1, cumulativeNotionalAfter1, (totalLongPositionSize() - (if (_isAdd)
496496 then abs(_baseAssetAmount)
497497 else 0)), (totalShortPositionSize() - (if (!(_isAdd))
498498 then abs(_baseAssetAmount)
499499 else 0)), priceImpact)
500500 }
501501 }
502502
503503
504504 func swapOutput (_isAdd,_baseAssetAmount,_checkMaxPriceImpact) = swapOutputWithReserves(_isAdd, _baseAssetAmount, _checkMaxPriceImpact, qtAstR(), qtAstW(), bsAstR(), bsAstW())
505505
506506
507507 func getOracleTwapPrice () = {
508508 let oracle = valueOrErrorMessage(addressFromString(getStringValue(this, k_ora)), "")
509509 let priceKey = getStringValue(this, k_ora_key)
510510 let blockKey = getStringValue(this, k_ora_block_key)
511511 let lastValue = valueOrErrorMessage(getInteger(oracle, priceKey), ((("Can not get oracle price. Oracle: " + toString(oracle)) + " key: ") + priceKey))
512512 lastValue
513513 }
514514
515515
516516 func requireNotOverSpreadLimit (_quoteAssetReserve,_baseAssetReserve) = {
517517 let oraclePrice = getOracleTwapPrice()
518518 let priceAfter = divd(_quoteAssetReserve, _baseAssetReserve)
519519 let averagePrice = divd((oraclePrice + priceAfter), (2 * DECIMAL_UNIT))
520520 let absPriceDiff = divd(abs((oraclePrice - priceAfter)), averagePrice)
521521 if ((absPriceDiff > maxPriceSpread()))
522522 then throw(((("Price spread " + toString(absPriceDiff)) + " > max price spread ") + toString(maxPriceSpread())))
523523 else true
524524 }
525525
526526
527527 func getSpotPrice () = {
528528 let _quoteAssetReserve = qtAstR()
529529 let _baseAssetReserve = bsAstR()
530530 let _qtAstW = qtAstW()
531531 let _bsAstW = bsAstW()
532532 divd(muld(_quoteAssetReserve, _qtAstW), muld(_baseAssetReserve, _bsAstW))
533533 }
534534
535535
536536 func isOverFluctuationLimit () = {
537537 let oraclePrice = getOracleTwapPrice()
538538 let currentPrice = getSpotPrice()
539539 (divd(abs((oraclePrice - currentPrice)), oraclePrice) > spreadLimit())
540540 }
541541
542542
543543 func getPositionAdjustedOpenNotional (_positionSize,_option,_quoteAssetReserve,_quoteAssetWeight,_baseAssetReserve,_baseAssetWeight) = {
544544 let positionSizeAbs = abs(_positionSize)
545545 let isShort = (0 > _positionSize)
546546 let positionNotional = if ((_option == PNL_OPTION_SPOT))
547547 then {
548- let $t02289823118 = swapOutputWithReserves(!(isShort), positionSizeAbs, false, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
549- let outPositionNotional = $t02289823118._1
550- let x1 = $t02289823118._2
551- let x2 = $t02289823118._3
552- let x3 = $t02289823118._4
548+ let $t02289423114 = swapOutputWithReserves(!(isShort), positionSizeAbs, false, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
549+ let outPositionNotional = $t02289423114._1
550+ let x1 = $t02289423114._2
551+ let x2 = $t02289423114._3
552+ let x3 = $t02289423114._4
553553 outPositionNotional
554554 }
555555 else muld(positionSizeAbs, getOracleTwapPrice())
556556 positionNotional
557557 }
558558
559559
560560 func getPositionNotionalAndUnrealizedPnlByValues (_positionSize,_positionOpenNotional,_quoteAssetReserve,_quoteAssetWeight,_baseAssetReserve,_baseAssetWeight,_option) = if ((_positionSize == 0))
561561 then throw("Invalid position size")
562562 else {
563563 let isShort = (0 > _positionSize)
564564 let positionNotional = getPositionAdjustedOpenNotional(_positionSize, _option, _quoteAssetReserve, _quoteAssetWeight, _baseAssetReserve, _baseAssetWeight)
565565 let unrealizedPnl = if (isShort)
566566 then (_positionOpenNotional - positionNotional)
567567 else (positionNotional - _positionOpenNotional)
568568 $Tuple2(positionNotional, unrealizedPnl)
569569 }
570570
571571
572572 func getPositionNotionalAndUnrealizedPnl (_trader,_option) = {
573- let $t02454324671 = getPosition(_trader)
574- let positionSize = $t02454324671._1
575- let positionMargin = $t02454324671._2
576- let positionOpenNotional = $t02454324671._3
577- let positionLstUpdCPF = $t02454324671._4
573+ let $t02453924667 = getPosition(_trader)
574+ let positionSize = $t02453924667._1
575+ let positionMargin = $t02453924667._2
576+ let positionOpenNotional = $t02453924667._3
577+ let positionLstUpdCPF = $t02453924667._4
578578 getPositionNotionalAndUnrealizedPnlByValues(positionSize, positionOpenNotional, qtAstR(), qtAstW(), bsAstR(), bsAstW(), _option)
579579 }
580580
581581
582582 func calcMarginRatio (_remainMargin,_badDebt,_positionNotional) = divd((_remainMargin - _badDebt), _positionNotional)
583583
584584
585585 func getMarginRatioByOption (_trader,_option) = {
586- let $t02518425295 = getPosition(_trader)
587- let positionSize = $t02518425295._1
588- let positionMargin = $t02518425295._2
589- let pon = $t02518425295._3
590- let positionLstUpdCPF = $t02518425295._4
591- let $t02530125394 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
592- let positionNotional = $t02530125394._1
593- let unrealizedPnl = $t02530125394._2
594- let $t02539925565 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
595- let remainMargin = $t02539925565._1
596- let badDebt = $t02539925565._2
586+ let $t02518025291 = getPosition(_trader)
587+ let positionSize = $t02518025291._1
588+ let positionMargin = $t02518025291._2
589+ let pon = $t02518025291._3
590+ let positionLstUpdCPF = $t02518025291._4
591+ let $t02529725390 = getPositionNotionalAndUnrealizedPnl(_trader, _option)
592+ let positionNotional = $t02529725390._1
593+ let unrealizedPnl = $t02529725390._2
594+ let $t02539525561 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
595+ let remainMargin = $t02539525561._1
596+ let badDebt = $t02539525561._2
597597 calcMarginRatio(remainMargin, badDebt, positionNotional)
598598 }
599599
600600
601601 func getMarginRatio (_trader) = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
602602
603603
604604 func getPartialLiquidationAmount (_trader,_positionSize) = {
605605 let maximumRatio = vmax(partialLiquidationRatio(), (DECIMAL_UNIT - divd(getMarginRatio(_trader), maintenanceMarginRatio())))
606606 let maxExchangedPositionSize = muld(abs(_positionSize), maximumRatio)
607607 let swapResult = swapOutput((_positionSize > 0), maxExchangedPositionSize, false)
608608 let maxExchangedQuoteAssetAmount = swapResult._1
609609 let priceImpact = swapResult._8
610610 if ((maxPriceImpact() > priceImpact))
611611 then maxExchangedQuoteAssetAmount
612612 else {
613613 let exchangedPositionSize = muld(abs(_positionSize), partialLiquidationRatio())
614614 let exchangedQuoteAssetAmount = swapOutput((_positionSize > 0), exchangedPositionSize, false)._1
615615 exchangedQuoteAssetAmount
616616 }
617617 }
618618
619619
620620 func internalClosePosition (_trader,_checkMaxPriceImpact) = {
621- let $t02679826926 = getPosition(_trader)
622- let positionSize = $t02679826926._1
623- let positionMargin = $t02679826926._2
624- let positionOpenNotional = $t02679826926._3
625- let positionLstUpdCPF = $t02679826926._4
621+ let $t02679426922 = getPosition(_trader)
622+ let positionSize = $t02679426922._1
623+ let positionMargin = $t02679426922._2
624+ let positionOpenNotional = $t02679426922._3
625+ let positionLstUpdCPF = $t02679426922._4
626626 let unrealizedPnl = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)._2
627- let $t02702127189 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
628- let remainMargin = $t02702127189._1
629- let badDebt = $t02702127189._2
627+ let $t02701727185 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
628+ let remainMargin = $t02701727185._1
629+ let badDebt = $t02701727185._2
630630 let exchangedPositionSize = -(positionSize)
631631 let realizedPnl = unrealizedPnl
632632 let marginToVault = -(remainMargin)
633- let $t02731627621 = swapOutput((positionSize > 0), abs(positionSize), _checkMaxPriceImpact)
634- let exchangedQuoteAssetAmount = $t02731627621._1
635- let quoteAssetReserveAfter = $t02731627621._2
636- let baseAssetReserveAfter = $t02731627621._3
637- let totalPositionSizeAfter = $t02731627621._4
638- let cumulativeNotionalAfter = $t02731627621._5
639- let totalLongAfter = $t02731627621._6
640- let totalShortAfter = $t02731627621._7
633+ let $t02731227617 = swapOutput((positionSize > 0), abs(positionSize), _checkMaxPriceImpact)
634+ let exchangedQuoteAssetAmount = $t02731227617._1
635+ let quoteAssetReserveAfter = $t02731227617._2
636+ let baseAssetReserveAfter = $t02731227617._3
637+ let totalPositionSizeAfter = $t02731227617._4
638+ let cumulativeNotionalAfter = $t02731227617._5
639+ let totalLongAfter = $t02731227617._6
640+ let totalShortAfter = $t02731227617._7
641641 let openInterestNotionalAfter = (openInterestNotional() - positionOpenNotional)
642642 $Tuple12(exchangedPositionSize, badDebt, realizedPnl, marginToVault, quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, exchangedQuoteAssetAmount, totalLongAfter, totalShortAfter)
643643 }
644644
645645
646646 func getTwapSpotPrice () = {
647647 let minuteId = ((lastBlock.timestamp / 1000) / 60)
648648 let startMinuteId = (minuteId - TWAP_INTERVAL)
649649 let listStr = valueOrElse(getString(this, k_lastDataStr), "")
650650 let list = split(listStr, ",")
651651 func filterFn (accumulator,next) = if ((startMinuteId >= parseIntValue(next)))
652652 then (accumulator :+ parseIntValue(next))
653653 else accumulator
654654
655655 let listF = {
656656 let $l = list
657657 let $s = size($l)
658658 let $acc0 = nil
659659 func $f0_1 ($a,$i) = if (($i >= $s))
660660 then $a
661661 else filterFn($a, $l[$i])
662662
663663 func $f0_2 ($a,$i) = if (($i >= $s))
664664 then $a
665665 else throw("List size exceeds 20")
666666
667667 $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)
668668 }
669669 let maxIndex = if ((size(listF) > 0))
670670 then max(listF)
671671 else parseIntValue(list[0])
672672 let lastMinuteId = valueOrElse(getInteger(this, k_lastMinuteId), 0)
673673 let endLastCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(lastMinuteId))), 0)
674674 let endLastPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(lastMinuteId))), 0)
675675 let nowCumulativePrice = (endLastCumulativePrice + ((minuteId - lastMinuteId) * endLastPrice))
676676 let startLastCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(maxIndex))), 0)
677677 let startLastPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(maxIndex))), 0)
678678 let startCumulativePrice = (startLastCumulativePrice + ((startMinuteId - maxIndex) * startLastPrice))
679679 ((nowCumulativePrice - startCumulativePrice) / TWAP_INTERVAL)
680680 }
681681
682682
683683 func getTerminalAmmState () = {
684684 let _positionSize = totalPositionSize()
685685 if ((_positionSize == 0))
686686 then $Tuple2(qtAstR(), bsAstR())
687687 else {
688688 let direction = (_positionSize > 0)
689- let $t02960829787 = swapOutput(direction, abs(_positionSize), false)
690- let currentNetMarketValue = $t02960829787._1
691- let terminalQuoteAssetReserve = $t02960829787._2
692- let terminalBaseAssetReserve = $t02960829787._3
689+ let $t02960429783 = swapOutput(direction, abs(_positionSize), false)
690+ let currentNetMarketValue = $t02960429783._1
691+ let terminalQuoteAssetReserve = $t02960429783._2
692+ let terminalBaseAssetReserve = $t02960429783._3
693693 $Tuple2(terminalQuoteAssetReserve, terminalBaseAssetReserve)
694694 }
695695 }
696696
697697
698698 func getQuoteAssetWeight (baseAssetReserve,totalPositionSize,quoteAssetReserve,targetPrice) = {
699699 let b = toBigInt(baseAssetReserve)
700700 let sz = toBigInt(totalPositionSize)
701701 let q = toBigInt(quoteAssetReserve)
702702 let p = toBigInt(targetPrice)
703703 let bs2 = bpowd((b + sz), toBigInt((2 * DECIMAL_UNIT)))
704704 let qbs2 = bmuld(q, bs2)
705705 let ps4 = (toBigInt(4) * bmuld(p, sz))
706706 let sqr = bsqrtd(bmuld(qbs2, (q - ps4)))
707707 let bq = bmuld(b, q)
708708 let qs = bmuld(q, sz)
709709 let top = ((-(sqr) + bq) + qs)
710710 let bot = (toBigInt(2) * bmuld(q, sz))
711711 let result = bdivd(top, bot)
712712 toInt(result)
713713 }
714714
715715
716716 func getSyncTerminalPrice (_terminalPrice) = {
717717 let _positionSize = totalPositionSize()
718718 if ((_positionSize == 0))
719719 then {
720720 let _qtAstR = qtAstR()
721721 let _bsAstR = bsAstR()
722722 let newQtAstW = divd(muld(_terminalPrice, _bsAstR), _qtAstR)
723723 $Tuple3(newQtAstW, DECIMAL_UNIT, 0)
724724 }
725725 else {
726726 let direction = (_positionSize > 0)
727727 let currentNetMarketValue = swapOutput(direction, abs(_positionSize), false)._1
728728 let _qtAstR = qtAstR()
729729 let _bsAstR = bsAstR()
730730 let newQtAstW = getQuoteAssetWeight(_bsAstR, _positionSize, _qtAstR, _terminalPrice)
731731 let newBsAstW = DECIMAL_UNIT
732732 let marginToVault = getPositionNotionalAndUnrealizedPnlByValues(_positionSize, currentNetMarketValue, _qtAstR, newQtAstW, _bsAstR, newBsAstW, PNL_OPTION_SPOT)._2
733733 $Tuple3(newQtAstW, newBsAstW, marginToVault)
734734 }
735735 }
736736
737737
738738 func getFunding () = {
739739 let underlyingPrice = getOracleTwapPrice()
740740 let spotTwapPrice = getTwapSpotPrice()
741741 let premium = (spotTwapPrice - underlyingPrice)
742742 if (if ((totalShortPositionSize() == 0))
743743 then true
744744 else (totalLongPositionSize() == 0))
745745 then $Tuple2(0, 0)
746746 else if ((0 > premium))
747747 then {
748748 let shortPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
749749 let longPremiumFraction = divd(muld(shortPremiumFraction, totalShortPositionSize()), totalLongPositionSize())
750750 $Tuple2(shortPremiumFraction, longPremiumFraction)
751751 }
752752 else {
753753 let longPremiumFraction = divd(muld(premium, fundingPeriodDecimal()), ONE_DAY)
754754 let shortPremiumFraction = divd(muld(longPremiumFraction, totalLongPositionSize()), totalShortPositionSize())
755755 $Tuple2(shortPremiumFraction, longPremiumFraction)
756756 }
757757 }
758758
759759
760760 func getAdjustedFee (i,_baseFeeDiscount) = {
761761 let baseFeeRaw = fee()
762762 let baseFee = muld(baseFeeRaw, _baseFeeDiscount)
763- let $t03288033488 = if ((size(i.payments) > 1))
763+ let $t03287633484 = if ((size(i.payments) > 1))
764764 then {
765765 let artifactId = toBase58String(valueOrErrorMessage(i.payments[1].assetId, "Invalid attached artifact"))
766766 let artifactKind = strA(nftManagerAddress(), toCompositeKey(k_token_type, artifactId))
767767 if ((artifactKind == FEE_REDUCTION_TOKEN_TYPE))
768768 then {
769769 let reduction = intA(nftManagerAddress(), toCompositeKey(k_token_param, artifactId))
770770 let adjustedFee = muld(baseFee, reduction)
771771 $Tuple2(adjustedFee, true)
772772 }
773773 else throw("Invalid attached artifact")
774774 }
775775 else $Tuple2(baseFee, false)
776- let adjustedFee = $t03288033488._1
777- let burnArtifact = $t03288033488._2
776+ let adjustedFee = $t03287633484._1
777+ let burnArtifact = $t03287633484._2
778778 $Tuple2(adjustedFee, burnArtifact)
779779 }
780780
781781
782782 func updateSettings (_initMarginRatio,_mmr,_liquidationFeeRatio,_fundingPeriod,_fee,_spreadLimit,_maxPriceImpact,_partialLiquidationRatio,_maxPriceSpread) = [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)]
783783
784784
785785 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)]
786786
787787
788788 func updatePositionAsset (_address,_assetId) = [StringEntry(toCompositeKey(k_positionAsset, _address), _assetId)]
789789
790790
791791 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)]
792792
793793
794794 func appendTwap (price) = {
795795 let minuteId = ((lastBlock.timestamp / 1000) / 60)
796796 let previousMinuteId = valueOrElse(getInteger(this, k_lastMinuteId), 0)
797797 if ((previousMinuteId > minuteId))
798798 then throw("TWAP out-of-order")
799799 else {
800800 let lastMinuteId = if ((previousMinuteId == 0))
801801 then minuteId
802802 else previousMinuteId
803803 if ((minuteId > previousMinuteId))
804804 then {
805805 let prevCumulativePrice = valueOrElse(getInteger(this, ((k_twapDataLastCumulativePrice + "_") + toString(previousMinuteId))), 0)
806806 let prevPrice = valueOrElse(getInteger(this, ((k_twapDataLastPrice + "_") + toString(previousMinuteId))), price)
807807 let lastCumulativePrice = (prevCumulativePrice + ((minuteId - lastMinuteId) * prevPrice))
808808 let list = pushToQueue(strToList(valueOrElse(getString(this, k_lastDataStr), "")), TWAP_INTERVAL, toString(minuteId))
809809 [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))]
810810 }
811811 else {
812812 let twapDataPreviousMinuteId = valueOrElse(getInteger(this, toCompositeKey(k_twapDataPreviousMinuteId, toString(minuteId))), 0)
813813 let prevCumulativePrice = valueOrElse(getInteger(this, toCompositeKey(k_twapDataLastCumulativePrice, toString(twapDataPreviousMinuteId))), 0)
814814 let prevPrice = valueOrElse(getInteger(this, toCompositeKey(k_twapDataLastPrice, toString(twapDataPreviousMinuteId))), price)
815815 let lastCumulativePrice = (prevCumulativePrice + ((minuteId - twapDataPreviousMinuteId) * prevPrice))
816816 [IntegerEntry(toCompositeKey(k_twapDataLastCumulativePrice, toString(minuteId)), lastCumulativePrice), IntegerEntry(toCompositeKey(k_twapDataLastPrice, toString(minuteId)), price)]
817817 }
818818 }
819819 }
820820
821821
822822 func updateAmmReserves (_qtAstR,_bsAstR) = [IntegerEntry(k_quoteAssetReserve, _qtAstR), IntegerEntry(k_baseAssetReserve, _bsAstR)]
823823
824824
825825 func updateAmmWeights (_qtAstW,_bsAstW) = [IntegerEntry(k_quoteAssetWeight, _qtAstW), IntegerEntry(k_baseAssetWeight, _bsAstW)]
826826
827827
828828 func updateAmm (_qtAstR,_bsAstR,_totalPositionSizeAfter,_cumulativeNotionalAfter,_openInterestNotional,_totalLongPositionSize,_totalShortPositionSize) = {
829829 let _qtAstW = qtAstW()
830830 let _bsAstW = bsAstW()
831831 if (((_totalLongPositionSize - _totalShortPositionSize) != _totalPositionSizeAfter))
832832 then throw(((((("Invalid AMM state data: " + toString(_totalLongPositionSize)) + " + ") + toString(_totalShortPositionSize)) + " != ") + toString(_totalPositionSizeAfter)))
833833 else ((updateAmmReserves(_qtAstR, _bsAstR) ++ [IntegerEntry(k_totalPositionSize, _totalPositionSizeAfter), IntegerEntry(k_cumulativeNotional, _cumulativeNotionalAfter), IntegerEntry(k_openInterestNotional, _openInterestNotional), IntegerEntry(k_totalLongPositionSize, _totalLongPositionSize), IntegerEntry(k_totalShortPositionSize, _totalShortPositionSize)]) ++ appendTwap(divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))))
834834 }
835835
836836
837837 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)), IntegerEntry(toCompositeKey(k_positionClosedDate, _address), lastBlock.timestamp)]
838838
839839
840840 func withdraw (_address,_amount) = {
841841 let balance = assetBalance(this, quoteAsset())
842842 if ((_amount > balance))
843843 then throw(((("Unable to withdraw " + toString(_amount)) + " from contract balance ") + toString(balance)))
844844 else [ScriptTransfer(_address, _amount, quoteAsset())]
845845 }
846846
847847
848848 func updateBalance (i) = if ((0 > i))
849849 then throw("Balance")
850850 else [IntegerEntry(k_balance, i)]
851851
852852
853853 func transferFee (i) = [ScriptTransfer(stakingAddress(), i, quoteAsset())]
854854
855855
856856 func doBurnArtifact (_burnArtifact,i) = if (_burnArtifact)
857857 then [Burn(valueOrErrorMessage(i.payments[1].assetId, "Invalid artifact"), 1)]
858858 else nil
859859
860860
861861 func isSameAssetOrNoPosition (_trader,_assetId) = {
862862 let oldPositionSize = getPosition(_trader)._1
863863 if ((oldPositionSize == 0))
864864 then true
865865 else (getPositionAsset(_trader) == _assetId)
866866 }
867867
868868
869869 func isSameAsset (_trader,_assetId) = (getPositionAsset(_trader) == _assetId)
870870
871871
872872 func getBorrowedByTraderInMarketKey (_amm,_assetId,_trader) = ((((((k_trader_market_asset_collateral + "_") + _amm) + "_") + _assetId) + "_") + _trader)
873873
874874
875875 func getBorrowedByTrader (_trader) = {
876876 let positionAsset = getPositionAsset(_trader)
877877 if ((positionAsset == toBase58String(quoteAsset())))
878878 then $Tuple2(0, positionAsset)
879879 else {
880880 let key = getBorrowedByTraderInMarketKey(toString(this), positionAsset, _trader)
881881 let borrow = valueOrElse(getInteger(collateralAddress(), key), 0)
882882 $Tuple2(borrow, positionAsset)
883883 }
884884 }
885885
886886
887887 @Callable(i)
888888 func pause () = if ((i.caller != adminAddress()))
889889 then throw("Invalid togglePause params")
890890 else [BooleanEntry(k_paused, true)]
891891
892892
893893
894894 @Callable(i)
895895 func unpause () = if ((i.caller != adminAddress()))
896896 then throw("Invalid togglePause params")
897897 else [BooleanEntry(k_paused, false)]
898898
899899
900900
901901 @Callable(i)
902902 func addLiquidity (_quoteAssetAmount) = if (if ((i.caller != adminAddress()))
903903 then true
904904 else (0 >= _quoteAssetAmount))
905905 then throw("Invalid addLiquidity params")
906906 else {
907907 let _qtAstR = qtAstR()
908908 let _bsAstR = bsAstR()
909909 let _qtAstW = qtAstW()
910910 let _bsAstW = bsAstW()
911911 let price = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
912912 let baseAssetAmountToAdd = divd(_quoteAssetAmount, price)
913913 let qtAstRAfter = (_qtAstR + _quoteAssetAmount)
914914 let bsAstRAfter = (_bsAstR + baseAssetAmountToAdd)
915915 updateAmmReserves(qtAstRAfter, bsAstRAfter)
916916 }
917917
918918
919919
920920 @Callable(i)
921921 func removeLiquidity (_quoteAssetAmount) = if (if ((i.caller != adminAddress()))
922922 then true
923923 else (0 >= _quoteAssetAmount))
924924 then throw("Invalid removeLiquidity params")
925925 else {
926926 let _qtAstR = qtAstR()
927927 let _bsAstR = bsAstR()
928928 let _qtAstW = qtAstW()
929929 let _bsAstW = bsAstW()
930930 let price = divd(muld(_qtAstR, _qtAstW), muld(_bsAstR, _bsAstW))
931931 let baseAssetAmountToRemove = divd(_quoteAssetAmount, price)
932932 let qtAstRAfter = (_qtAstR - _quoteAssetAmount)
933933 let bsAstRAfter = (_bsAstR - baseAssetAmountToRemove)
934934 updateAmmReserves(qtAstRAfter, bsAstRAfter)
935935 }
936936
937937
938938
939939 @Callable(i)
940940 func changeSettings (_initMarginRatio,_mmr,_liquidationFeeRatio,_fundingPeriod,_fee,_spreadLimit,_maxPriceImpact,_partialLiquidationRatio,_maxPriceSpread) = if ((i.caller != adminAddress()))
941941 then throw("Invalid changeSettings params")
942942 else updateSettings(_initMarginRatio, _mmr, _liquidationFeeRatio, _fundingPeriod, _fee, _spreadLimit, _maxPriceImpact, _partialLiquidationRatio, _maxPriceSpread)
943943
944944
945945
946946 @Callable(i)
947947 func initialize (_qtAstR,_bsAstR,_fundingPeriod,_initMarginRatio,_mmr,_liquidationFeeRatio,_fee,_oracle,_oracleKey,_coordinator,_spreadLimit,_maxPriceImpact,_partialLiquidationRatio,_maxPriceSpread) = if (if (if (if (if (if (if (if (if (if (if (if ((0 >= _qtAstR))
948948 then true
949949 else (0 >= _bsAstR))
950950 then true
951951 else (0 >= _fundingPeriod))
952952 then true
953953 else (0 >= _initMarginRatio))
954954 then true
955955 else (0 >= _mmr))
956956 then true
957957 else (0 >= _liquidationFeeRatio))
958958 then true
959959 else (0 >= _fee))
960960 then true
961961 else (0 >= _spreadLimit))
962962 then true
963963 else (0 >= _maxPriceImpact))
964964 then true
965965 else (0 >= _partialLiquidationRatio))
966966 then true
967967 else (0 >= _maxPriceSpread))
968968 then true
969969 else initialized())
970970 then throw("Invalid initialize parameters")
971971 else ((((updateAmm(_qtAstR, _bsAstR, 0, 0, 0, 0, 0) ++ updateSettings(_initMarginRatio, _mmr, _liquidationFeeRatio, _fundingPeriod, _fee, _spreadLimit, _maxPriceImpact, _partialLiquidationRatio, _maxPriceSpread)) ++ updateFunding((lastBlock.timestamp + _fundingPeriod), 0, 0, 0, 0)) ++ updateBalance(0)) ++ [BooleanEntry(k_initialized, true), StringEntry(k_ora, _oracle), StringEntry(k_ora_key, _oracleKey), StringEntry(k_coordinatorAddress, _coordinator)])
972972
973973
974974
975975 @Callable(i)
976976 func setInitMarginRatio (_initMarginRatio) = if (if ((0 >= _initMarginRatio))
977977 then true
978978 else !(initialized()))
979979 then throw("Invalid setInitMarginRatio parameters")
980980 else updateSettings(_initMarginRatio, maintenanceMarginRatio(), liquidationFeeRatio(), fundingPeriodRaw(), fee(), spreadLimit(), maxPriceImpact(), partialLiquidationRatio(), maxPriceSpread())
981981
982982
983983
984984 @Callable(i)
985985 func decreasePosition (_amount,_leverage,_minBaseAssetAmount) = {
986986 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
987987 if ((sync == sync))
988988 then if (if (if (if (if ((0 >= _amount))
989989 then true
990990 else !(initialized()))
991991 then true
992992 else !(requireMoreMarginRatio(divd(DECIMAL_UNIT, _leverage), initMarginRatio(), true)))
993993 then true
994994 else !(requireOpenPosition(toString(i.caller))))
995995 then true
996996 else paused())
997997 then throw("Invalid decreasePosition parameters")
998998 else {
999- let $t04546845620 = getPosition(toString(i.caller))
1000- let oldPositionSize = $t04546845620._1
1001- let oldPositionMargin = $t04546845620._2
1002- let oldPositionOpenNotional = $t04546845620._3
1003- let oldPositionLstUpdCPF = $t04546845620._4
999+ let $t04546445616 = getPosition(toString(i.caller))
1000+ let oldPositionSize = $t04546445616._1
1001+ let oldPositionMargin = $t04546445616._2
1002+ let oldPositionOpenNotional = $t04546445616._3
1003+ let oldPositionLstUpdCPF = $t04546445616._4
10041004 let _direction = if ((oldPositionSize > 0))
10051005 then DIR_SHORT
10061006 else DIR_LONG
10071007 let isAdd = (_direction == DIR_LONG)
10081008 let openNotional = muld(_amount, _leverage)
1009- let $t04579345909 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1010- let oldPositionNotional = $t04579345909._1
1011- let unrealizedPnl = $t04579345909._2
1012- let $t04591548464 = if ((oldPositionNotional > openNotional))
1009+ let $t04578945905 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1010+ let oldPositionNotional = $t04578945905._1
1011+ let unrealizedPnl = $t04578945905._2
1012+ let $t04591148460 = if ((oldPositionNotional > openNotional))
10131013 then {
1014- let $t04629246511 = swapInput(isAdd, openNotional)
1015- let exchangedPositionSize = $t04629246511._1
1016- let quoteAssetReserveAfter = $t04629246511._2
1017- let baseAssetReserveAfter = $t04629246511._3
1018- let totalPositionSizeAfter = $t04629246511._4
1019- let cumulativeNotionalAfter = $t04629246511._5
1014+ let $t04628846507 = swapInput(isAdd, openNotional)
1015+ let exchangedPositionSize = $t04628846507._1
1016+ let quoteAssetReserveAfter = $t04628846507._2
1017+ let baseAssetReserveAfter = $t04628846507._3
1018+ let totalPositionSizeAfter = $t04628846507._4
1019+ let cumulativeNotionalAfter = $t04628846507._5
10201020 let exchangedPositionSizeAbs = abs(exchangedPositionSize)
10211021 if (if ((_minBaseAssetAmount != 0))
10221022 then (_minBaseAssetAmount > exchangedPositionSizeAbs)
10231023 else false)
10241024 then throw(((("Too little base asset exchanged, got " + toString(exchangedPositionSizeAbs)) + " expected ") + toString(_minBaseAssetAmount)))
10251025 else {
10261026 let realizedPnl = divd(muld(unrealizedPnl, exchangedPositionSizeAbs), abs(oldPositionSize))
1027- let $t04694847193 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1028- let remainMargin = $t04694847193._1
1029- let badDebt = $t04694847193._2
1030- let fundingPayment = $t04694847193._3
1027+ let $t04694447189 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1028+ let remainMargin = $t04694447189._1
1029+ let badDebt = $t04694447189._2
1030+ let fundingPayment = $t04694447189._3
10311031 let exchangedQuoteAssetAmount = openNotional
10321032 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
10331033 let remainOpenNotional = if ((oldPositionSize > 0))
10341034 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
10351035 else ((unrealizedPnlAfter + oldPositionNotional) - exchangedQuoteAssetAmount)
10361036 let newPositionSize = (oldPositionSize + exchangedPositionSize)
10371037 $Tuple11(newPositionSize, remainMargin, abs(remainOpenNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, (openInterestNotional() - openNotional), (totalLongPositionSize() - (if ((newPositionSize > 0))
10381038 then abs(exchangedPositionSize)
10391039 else 0)), (totalShortPositionSize() - (if ((0 > newPositionSize))
10401040 then abs(exchangedPositionSize)
10411041 else 0)))
10421042 }
10431043 }
10441044 else throw("Close position first")
1045- let newPositionSize = $t04591548464._1
1046- let newPositionRemainMargin = $t04591548464._2
1047- let newPositionOpenNotional = $t04591548464._3
1048- let newPositionLatestCPF = $t04591548464._4
1049- let baseAssetReserveAfter = $t04591548464._5
1050- let quoteAssetReserveAfter = $t04591548464._6
1051- let totalPositionSizeAfter = $t04591548464._7
1052- let cumulativeNotionalAfter = $t04591548464._8
1053- let openInterestNotionalAfter = $t04591548464._9
1054- let totalLongAfter = $t04591548464._10
1055- let totalShortAfter = $t04591548464._11
1045+ let newPositionSize = $t04591148460._1
1046+ let newPositionRemainMargin = $t04591148460._2
1047+ let newPositionOpenNotional = $t04591148460._3
1048+ let newPositionLatestCPF = $t04591148460._4
1049+ let baseAssetReserveAfter = $t04591148460._5
1050+ let quoteAssetReserveAfter = $t04591148460._6
1051+ let totalPositionSizeAfter = $t04591148460._7
1052+ let cumulativeNotionalAfter = $t04591148460._8
1053+ let openInterestNotionalAfter = $t04591148460._9
1054+ let totalLongAfter = $t04591148460._10
1055+ let totalShortAfter = $t04591148460._11
10561056 let notifyNotional = invoke(minerAddress(), "notifyNotional", [toString(i.caller), newPositionOpenNotional], nil)
10571057 if ((notifyNotional == notifyNotional))
10581058 then (updatePosition(toString(i.caller), newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter))
10591059 else throw("Strict value is not equal to itself.")
10601060 }
10611061 else throw("Strict value is not equal to itself.")
10621062 }
10631063
10641064
10651065
10661066 @Callable(i)
10671067 func increasePosition (_direction,_leverage,_minBaseAssetAmount,_refLink) = {
10681068 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
10691069 if ((sync == sync))
10701070 then {
10711071 let _trader = toString(i.caller)
10721072 let _rawAmount = i.payments[0].amount
10731073 let _assetId = i.payments[0].assetId
10741074 let _assetIdStr = toBase58String(value(_assetId))
10751075 let isQuoteAsset = (_assetId == quoteAsset())
10761076 let isCollateralAsset = isWhitelistAsset(_assetIdStr)
10771077 if (if (if (if (if (if (if (if ((_direction != DIR_LONG))
10781078 then (_direction != DIR_SHORT)
10791079 else false)
10801080 then true
10811081 else (0 >= _rawAmount))
10821082 then true
10831083 else !(initialized()))
10841084 then true
10851085 else if (!(isQuoteAsset))
10861086 then !(isCollateralAsset)
10871087 else false)
10881088 then true
10891089 else !(isSameAssetOrNoPosition(_trader, _assetIdStr)))
10901090 then true
10911091 else !(requireMoreMarginRatio(divd(DECIMAL_UNIT, _leverage), initMarginRatio(), true)))
10921092 then true
10931093 else paused())
10941094 then throw("Invalid increasePosition parameters")
10951095 else {
10961096 let doGetFeeDiscount = invoke(minerAddress(), "computeFeeDiscount", [_trader], nil)
10971097 if ((doGetFeeDiscount == doGetFeeDiscount))
10981098 then {
10991099 let feeDiscount = match doGetFeeDiscount {
11001100 case x: Int =>
11011101 x
11021102 case _ =>
11031103 throw("Invalid computeFeeDiscount result")
11041104 }
1105- let $t05012750191 = getAdjustedFee(i, feeDiscount)
1106- let adjustedFee = $t05012750191._1
1107- let burnArtifact = $t05012750191._2
1105+ let $t05012350187 = getAdjustedFee(i, feeDiscount)
1106+ let adjustedFee = $t05012350187._1
1107+ let burnArtifact = $t05012350187._2
11081108 let rawFeeAmount = muld(_rawAmount, adjustedFee)
11091109 let _amount = (_rawAmount - rawFeeAmount)
11101110 let distributeFeeAmount = if (isCollateralAsset)
11111111 then {
11121112 let doBorrow = invoke(collateralAddress(), "borrow", [_trader], [AttachedPayment(_assetId, _amount)])
11131113 if ((doBorrow == doBorrow))
11141114 then {
11151115 let balanceBefore = assetBalance(this, quoteAsset())
11161116 if ((balanceBefore == balanceBefore))
11171117 then {
11181118 let doSwap = invoke(swapAddress(), "swap", [toBase58String(quoteAsset()), 0], [AttachedPayment(_assetId, rawFeeAmount)])
11191119 if ((doSwap == doSwap))
11201120 then {
11211121 let balanceAfter = assetBalance(this, quoteAsset())
11221122 if ((balanceAfter == balanceAfter))
11231123 then {
11241124 let exchangedAmount = (balanceAfter - balanceBefore)
11251125 if ((exchangedAmount == exchangedAmount))
11261126 then exchangedAmount
11271127 else throw("Strict value is not equal to itself.")
11281128 }
11291129 else throw("Strict value is not equal to itself.")
11301130 }
11311131 else throw("Strict value is not equal to itself.")
11321132 }
11331133 else throw("Strict value is not equal to itself.")
11341134 }
11351135 else throw("Strict value is not equal to itself.")
11361136 }
11371137 else rawFeeAmount
11381138 if ((distributeFeeAmount == distributeFeeAmount))
11391139 then {
11401140 let referrerFeeAny = invoke(referralAddress(), "acceptPaymentWithLink", [_trader, _refLink], [AttachedPayment(quoteAsset(), distributeFeeAmount)])
11411141 if ((referrerFeeAny == referrerFeeAny))
11421142 then {
11431143 let referrerFee = match referrerFeeAny {
11441144 case x: Int =>
11451145 x
11461146 case _ =>
11471147 throw("Invalid referrerFee")
11481148 }
11491149 let feeAmount = (distributeFeeAmount - referrerFee)
1150- let $t05150751647 = getPosition(_trader)
1151- let oldPositionSize = $t05150751647._1
1152- let oldPositionMargin = $t05150751647._2
1153- let oldPositionOpenNotional = $t05150751647._3
1154- let oldPositionLstUpdCPF = $t05150751647._4
1150+ let $t05150351643 = getPosition(_trader)
1151+ let oldPositionSize = $t05150351643._1
1152+ let oldPositionMargin = $t05150351643._2
1153+ let oldPositionOpenNotional = $t05150351643._3
1154+ let oldPositionLstUpdCPF = $t05150351643._4
11551155 let isNewPosition = (oldPositionSize == 0)
11561156 let isSameDirection = if ((oldPositionSize > 0))
11571157 then (_direction == DIR_LONG)
11581158 else (_direction == DIR_SHORT)
11591159 let expandExisting = if (!(isNewPosition))
11601160 then isSameDirection
11611161 else false
11621162 let isAdd = (_direction == DIR_LONG)
1163- let $t05193654521 = if (if (isNewPosition)
1163+ let $t05193254517 = if (if (isNewPosition)
11641164 then true
11651165 else expandExisting)
11661166 then {
11671167 let openNotional = muld(_amount, _leverage)
1168- let $t05236052566 = swapInput(isAdd, openNotional)
1169- let amountBaseAssetBought = $t05236052566._1
1170- let quoteAssetReserveAfter = $t05236052566._2
1171- let baseAssetReserveAfter = $t05236052566._3
1172- let totalPositionSizeAfter = $t05236052566._4
1173- let cumulativeNotionalAfter = $t05236052566._5
1168+ let $t05235652562 = swapInput(isAdd, openNotional)
1169+ let amountBaseAssetBought = $t05235652562._1
1170+ let quoteAssetReserveAfter = $t05235652562._2
1171+ let baseAssetReserveAfter = $t05235652562._3
1172+ let totalPositionSizeAfter = $t05235652562._4
1173+ let cumulativeNotionalAfter = $t05235652562._5
11741174 if (if ((_minBaseAssetAmount != 0))
11751175 then (_minBaseAssetAmount > abs(amountBaseAssetBought))
11761176 else false)
11771177 then throw(((("Limit error: " + toString(abs(amountBaseAssetBought))) + " < ") + toString(_minBaseAssetAmount)))
11781178 else {
11791179 let newPositionSize = (oldPositionSize + amountBaseAssetBought)
11801180 let increaseMarginRequirement = divd(openNotional, _leverage)
1181- let $t05294753186 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
1182- let remainMargin = $t05294753186._1
1183- let x1 = $t05294753186._2
1184- let x2 = $t05294753186._3
1181+ let $t05294353182 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, increaseMarginRequirement)
1182+ let remainMargin = $t05294353182._1
1183+ let x1 = $t05294353182._2
1184+ let x2 = $t05294353182._3
11851185 if (!(requireNotOverSpreadLimit(quoteAssetReserveAfter, baseAssetReserveAfter)))
11861186 then throw("Over max spread limit")
11871187 else $Tuple11(newPositionSize, remainMargin, (oldPositionOpenNotional + openNotional), latestCumulativePremiumFraction(newPositionSize), baseAssetReserveAfter, quoteAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, (openInterestNotional() + openNotional), (totalLongPositionSize() + (if ((newPositionSize > 0))
11881188 then abs(amountBaseAssetBought)
11891189 else 0)), (totalShortPositionSize() + (if ((0 > newPositionSize))
11901190 then abs(amountBaseAssetBought)
11911191 else 0)))
11921192 }
11931193 }
11941194 else {
11951195 let openNotional = muld(_amount, _leverage)
1196- let $t05421454330 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1197- let oldPositionNotional = $t05421454330._1
1198- let unrealizedPnl = $t05421454330._2
1196+ let $t05421054326 = getPositionNotionalAndUnrealizedPnl(toString(i.caller), PNL_OPTION_SPOT)
1197+ let oldPositionNotional = $t05421054326._1
1198+ let unrealizedPnl = $t05421054326._2
11991199 if ((oldPositionNotional > openNotional))
12001200 then throw("Use decreasePosition to decrease position size")
12011201 else throw("Close position first")
12021202 }
1203- let newPositionSize = $t05193654521._1
1204- let newPositionRemainMargin = $t05193654521._2
1205- let newPositionOpenNotional = $t05193654521._3
1206- let newPositionLatestCPF = $t05193654521._4
1207- let baseAssetReserveAfter = $t05193654521._5
1208- let quoteAssetReserveAfter = $t05193654521._6
1209- let totalPositionSizeAfter = $t05193654521._7
1210- let cumulativeNotionalAfter = $t05193654521._8
1211- let openInterestNotionalAfter = $t05193654521._9
1212- let totalLongAfter = $t05193654521._10
1213- let totalShortAfter = $t05193654521._11
1203+ let newPositionSize = $t05193254517._1
1204+ let newPositionRemainMargin = $t05193254517._2
1205+ let newPositionOpenNotional = $t05193254517._3
1206+ let newPositionLatestCPF = $t05193254517._4
1207+ let baseAssetReserveAfter = $t05193254517._5
1208+ let quoteAssetReserveAfter = $t05193254517._6
1209+ let totalPositionSizeAfter = $t05193254517._7
1210+ let cumulativeNotionalAfter = $t05193254517._8
1211+ let openInterestNotionalAfter = $t05193254517._9
1212+ let totalLongAfter = $t05193254517._10
1213+ let totalShortAfter = $t05193254517._11
12141214 let feeToStakers = (feeAmount / 2)
12151215 let feeToInsurance = (feeAmount - feeToStakers)
12161216 let stake = invoke(vaultAddress(), "addLocked", nil, [AttachedPayment(quoteAsset(), _amount)])
12171217 if ((stake == stake))
12181218 then {
12191219 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToInsurance)])
12201220 if ((depositInsurance == depositInsurance))
12211221 then {
12221222 let notifyFee = invoke(minerAddress(), "notifyFees", [_trader, feeAmount], nil)
12231223 if ((notifyFee == notifyFee))
12241224 then {
12251225 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, newPositionOpenNotional], nil)
12261226 if ((notifyNotional == notifyNotional))
12271227 then (((((updatePosition(_trader, newPositionSize, newPositionRemainMargin, newPositionOpenNotional, newPositionLatestCPF) ++ updatePositionAsset(_trader, _assetIdStr)) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter)) ++ transferFee(feeToStakers)) ++ updateBalance((cbalance() + _amount))) ++ doBurnArtifact(burnArtifact, i))
12281228 else throw("Strict value is not equal to itself.")
12291229 }
12301230 else throw("Strict value is not equal to itself.")
12311231 }
12321232 else throw("Strict value is not equal to itself.")
12331233 }
12341234 else throw("Strict value is not equal to itself.")
12351235 }
12361236 else throw("Strict value is not equal to itself.")
12371237 }
12381238 else throw("Strict value is not equal to itself.")
12391239 }
12401240 else throw("Strict value is not equal to itself.")
12411241 }
12421242 }
12431243 else throw("Strict value is not equal to itself.")
12441244 }
12451245
12461246
12471247
12481248 @Callable(i)
12491249 func addMargin () = {
12501250 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
12511251 if ((sync == sync))
12521252 then {
12531253 let _trader = toString(i.caller)
12541254 let _rawAmount = i.payments[0].amount
12551255 let _assetId = i.payments[0].assetId
12561256 let _assetIdStr = toBase58String(value(_assetId))
12571257 let isQuoteAsset = (_assetId == quoteAsset())
12581258 let isCollateralAsset = isWhitelistAsset(_assetIdStr)
12591259 if (if (if (if (if (if (!(isQuoteAsset))
12601260 then !(isCollateralAsset)
12611261 else false)
12621262 then true
12631263 else !(requireOpenPosition(toString(i.caller))))
12641264 then true
12651265 else !(isSameAsset(_trader, _assetIdStr)))
12661266 then true
12671267 else !(initialized()))
12681268 then true
12691269 else paused())
12701270 then throw("Invalid addMargin parameters")
12711271 else {
12721272 let doGetFeeDiscount = invoke(minerAddress(), "computeFeeDiscount", [_trader], nil)
12731273 if ((doGetFeeDiscount == doGetFeeDiscount))
12741274 then {
12751275 let feeDiscount = match doGetFeeDiscount {
12761276 case x: Int =>
12771277 x
12781278 case _ =>
12791279 throw("Invalid computeFeeDiscount result")
12801280 }
1281- let $t05659856662 = getAdjustedFee(i, feeDiscount)
1282- let adjustedFee = $t05659856662._1
1283- let burnArtifact = $t05659856662._2
1281+ let $t05659456658 = getAdjustedFee(i, feeDiscount)
1282+ let adjustedFee = $t05659456658._1
1283+ let burnArtifact = $t05659456658._2
12841284 let rawFeeAmount = muld(_rawAmount, adjustedFee)
12851285 let _amount = (_rawAmount - rawFeeAmount)
12861286 let distributeFeeAmount = if (isCollateralAsset)
12871287 then {
12881288 let doBorrow = invoke(collateralAddress(), "borrow", [_trader], [AttachedPayment(_assetId, _amount)])
12891289 if ((doBorrow == doBorrow))
12901290 then {
12911291 let balanceBefore = assetBalance(this, quoteAsset())
12921292 if ((balanceBefore == balanceBefore))
12931293 then {
12941294 let doSwap = invoke(swapAddress(), "swap", [toBase58String(quoteAsset()), 0], [AttachedPayment(_assetId, rawFeeAmount)])
12951295 if ((doSwap == doSwap))
12961296 then {
12971297 let balanceAfter = assetBalance(this, quoteAsset())
12981298 if ((balanceAfter == balanceAfter))
12991299 then {
13001300 let exchangedAmount = (balanceAfter - balanceBefore)
13011301 if ((exchangedAmount == exchangedAmount))
13021302 then exchangedAmount
13031303 else throw("Strict value is not equal to itself.")
13041304 }
13051305 else throw("Strict value is not equal to itself.")
13061306 }
13071307 else throw("Strict value is not equal to itself.")
13081308 }
13091309 else throw("Strict value is not equal to itself.")
13101310 }
13111311 else throw("Strict value is not equal to itself.")
13121312 }
13131313 else rawFeeAmount
13141314 if ((distributeFeeAmount == distributeFeeAmount))
13151315 then {
13161316 let referrerFeeAny = invoke(referralAddress(), "acceptPayment", [_trader], [AttachedPayment(quoteAsset(), distributeFeeAmount)])
13171317 if ((referrerFeeAny == referrerFeeAny))
13181318 then {
13191319 let referrerFee = match referrerFeeAny {
13201320 case x: Int =>
13211321 x
13221322 case _ =>
13231323 throw("Invalid referrerFee")
13241324 }
13251325 let feeAmount = (distributeFeeAmount - referrerFee)
1326- let $t05796158101 = getPosition(_trader)
1327- let oldPositionSize = $t05796158101._1
1328- let oldPositionMargin = $t05796158101._2
1329- let oldPositionOpenNotional = $t05796158101._3
1330- let oldPositionLstUpdCPF = $t05796158101._4
1326+ let $t05795758097 = getPosition(_trader)
1327+ let oldPositionSize = $t05795758097._1
1328+ let oldPositionMargin = $t05795758097._2
1329+ let oldPositionOpenNotional = $t05795758097._3
1330+ let oldPositionLstUpdCPF = $t05795758097._4
13311331 let feeToStakers = (feeAmount / 2)
13321332 let feeToInsurance = (feeAmount - feeToStakers)
13331333 let stake = invoke(vaultAddress(), "addLocked", nil, [AttachedPayment(quoteAsset(), _amount)])
13341334 if ((stake == stake))
13351335 then {
13361336 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToInsurance)])
13371337 if ((depositInsurance == depositInsurance))
13381338 then {
13391339 let notifyFee = invoke(minerAddress(), "notifyFees", [_trader, feeAmount], nil)
13401340 if ((notifyFee == notifyFee))
13411341 then (((updatePosition(_trader, oldPositionSize, (oldPositionMargin + _amount), oldPositionOpenNotional, oldPositionLstUpdCPF) ++ transferFee(feeToStakers)) ++ updateBalance((cbalance() + _amount))) ++ doBurnArtifact(burnArtifact, i))
13421342 else throw("Strict value is not equal to itself.")
13431343 }
13441344 else throw("Strict value is not equal to itself.")
13451345 }
13461346 else throw("Strict value is not equal to itself.")
13471347 }
13481348 else throw("Strict value is not equal to itself.")
13491349 }
13501350 else throw("Strict value is not equal to itself.")
13511351 }
13521352 else throw("Strict value is not equal to itself.")
13531353 }
13541354 }
13551355 else throw("Strict value is not equal to itself.")
13561356 }
13571357
13581358
13591359
13601360 @Callable(i)
13611361 func removeMargin (_amount) = {
13621362 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
13631363 if ((sync == sync))
13641364 then {
13651365 let _trader = toString(i.caller)
13661366 if (if (if (if ((0 >= _amount))
13671367 then true
13681368 else !(requireOpenPosition(_trader)))
13691369 then true
13701370 else !(initialized()))
13711371 then true
13721372 else paused())
13731373 then throw("Invalid removeMargin parameters")
13741374 else {
1375- let $t05920759347 = getPosition(_trader)
1376- let oldPositionSize = $t05920759347._1
1377- let oldPositionMargin = $t05920759347._2
1378- let oldPositionOpenNotional = $t05920759347._3
1379- let oldPositionLstUpdCPF = $t05920759347._4
1375+ let $t05920359343 = getPosition(_trader)
1376+ let oldPositionSize = $t05920359343._1
1377+ let oldPositionMargin = $t05920359343._2
1378+ let oldPositionOpenNotional = $t05920359343._3
1379+ let oldPositionLstUpdCPF = $t05920359343._4
13801380 let marginDelta = -(_amount)
1381- let $t05938459563 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1382- let remainMargin = $t05938459563._1
1383- let badDebt = $t05938459563._2
1381+ let $t05938059559 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, marginDelta)
1382+ let remainMargin = $t05938059559._1
1383+ let badDebt = $t05938059559._2
13841384 if ((badDebt != 0))
13851385 then throw("Invalid removed margin amount")
13861386 else {
13871387 let marginRatio = calcMarginRatio(remainMargin, badDebt, oldPositionOpenNotional)
13881388 if (!(requireMoreMarginRatio(marginRatio, initMarginRatio(), true)))
13891389 then throw(((("Too much margin removed: " + toString(marginRatio)) + " < ") + toString(initMarginRatio())))
13901390 else {
13911391 let quoteAssetStr = toBase58String(quoteAsset())
1392- let $t06000760061 = getBorrowedByTrader(_trader)
1393- let borrowed = $t06000760061._1
1394- let assetId = $t06000760061._2
1392+ let $t06000360057 = getBorrowedByTrader(_trader)
1393+ let borrowed = $t06000360057._1
1394+ let assetId = $t06000360057._2
13951395 let toRepay = if ((_amount > borrowed))
13961396 then borrowed
13971397 else _amount
13981398 let toWithdraw = if ((borrowed > _amount))
13991399 then 0
14001400 else (_amount - borrowed)
14011401 let finalBorrow = (borrowed - toRepay)
14021402 let switchPositionToQuote = if ((finalBorrow > 0))
14031403 then nil
14041404 else updatePositionAsset(_trader, quoteAssetStr)
14051405 let doSanityCheck = if (((toRepay + toWithdraw) != _amount))
14061406 then throw(((((("toRepay=" + toString(toRepay)) + " + toWithdraw=") + toString(toWithdraw)) + " != ") + toString(_amount)))
14071407 else nil
14081408 if ((doSanityCheck == doSanityCheck))
14091409 then {
14101410 let doUnstake = invoke(vaultAddress(), "withdrawLocked", [_amount], nil)
14111411 if ((doUnstake == doUnstake))
14121412 then {
14131413 let returnCollateralAction = if ((toRepay > 0))
14141414 then {
14151415 let doRepay = invoke(collateralAddress(), "repay", [_trader, assetId], [AttachedPayment(quoteAsset(), toRepay)])
14161416 if ((doRepay == doRepay))
14171417 then [ScriptTransfer(i.caller, toRepay, fromBase58String(assetId))]
14181418 else throw("Strict value is not equal to itself.")
14191419 }
14201420 else nil
14211421 if ((returnCollateralAction == returnCollateralAction))
14221422 then ((((updatePosition(_trader, oldPositionSize, remainMargin, oldPositionOpenNotional, latestCumulativePremiumFraction(oldPositionSize)) ++ (if ((toWithdraw > 0))
14231423 then withdraw(i.caller, toWithdraw)
14241424 else nil)) ++ updateBalance((cbalance() - _amount))) ++ switchPositionToQuote) ++ returnCollateralAction)
14251425 else throw("Strict value is not equal to itself.")
14261426 }
14271427 else throw("Strict value is not equal to itself.")
14281428 }
14291429 else throw("Strict value is not equal to itself.")
14301430 }
14311431 }
14321432 }
14331433 }
14341434 else throw("Strict value is not equal to itself.")
14351435 }
14361436
14371437
14381438
14391439 @Callable(i)
14401440 func closePosition () = {
14411441 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
14421442 if ((sync == sync))
14431443 then {
14441444 let _trader = getActualCaller(i)
14451445 let _traderAddress = valueOrErrorMessage(addressFromString(_trader), "Invalid caller")
14461446 if (if (if (!(requireOpenPosition(_trader)))
14471447 then true
14481448 else !(initialized()))
14491449 then true
14501450 else paused())
14511451 then throw("Invalid closePosition parameters")
14521452 else {
1453- let $t06231162689 = internalClosePosition(_trader, true)
1454- let x1 = $t06231162689._1
1455- let positionBadDebt = $t06231162689._2
1456- let realizedPnl = $t06231162689._3
1457- let marginToVault = $t06231162689._4
1458- let quoteAssetReserveAfter = $t06231162689._5
1459- let baseAssetReserveAfter = $t06231162689._6
1460- let totalPositionSizeAfter = $t06231162689._7
1461- let cumulativeNotionalAfter = $t06231162689._8
1462- let openInterestNotionalAfter = $t06231162689._9
1463- let x2 = $t06231162689._10
1464- let totalLongAfter = $t06231162689._11
1465- let totalShortAfter = $t06231162689._12
1453+ let $t06230762685 = internalClosePosition(_trader, true)
1454+ let x1 = $t06230762685._1
1455+ let positionBadDebt = $t06230762685._2
1456+ let realizedPnl = $t06230762685._3
1457+ let marginToVault = $t06230762685._4
1458+ let quoteAssetReserveAfter = $t06230762685._5
1459+ let baseAssetReserveAfter = $t06230762685._6
1460+ let totalPositionSizeAfter = $t06230762685._7
1461+ let cumulativeNotionalAfter = $t06230762685._8
1462+ let openInterestNotionalAfter = $t06230762685._9
1463+ let x2 = $t06230762685._10
1464+ let totalLongAfter = $t06230762685._11
1465+ let totalShortAfter = $t06230762685._12
14661466 if ((positionBadDebt > 0))
14671467 then throw("Unable to close position with bad debt")
14681468 else {
14691469 let withdrawAmount = abs(marginToVault)
14701470 let ammBalance = (cbalance() - withdrawAmount)
1471- let $t06301363528 = if ((0 > ammBalance))
1471+ let $t06300963524 = if ((0 > ammBalance))
14721472 then $Tuple2(0, abs(ammBalance))
14731473 else $Tuple2(ammBalance, 0)
1474- let ammNewBalance = $t06301363528._1
1475- let x11 = $t06301363528._2
1474+ let ammNewBalance = $t06300963524._1
1475+ let x11 = $t06300963524._2
14761476 let unstake = invoke(vaultAddress(), "withdrawLocked", [withdrawAmount], nil)
14771477 if ((unstake == unstake))
14781478 then {
1479- let $t06374063794 = getBorrowedByTrader(_trader)
1480- let borrowed = $t06374063794._1
1481- let assetId = $t06374063794._2
1482- let $t06380964726 = if ((borrowed > 0))
1479+ let $t06373663790 = getBorrowedByTrader(_trader)
1480+ let borrowed = $t06373663790._1
1481+ let assetId = $t06373663790._2
1482+ let $t06380564722 = if ((borrowed > 0))
14831483 then if ((withdrawAmount >= borrowed))
14841484 then {
14851485 let doRepay = invoke(collateralAddress(), "repay", [_trader, assetId], [AttachedPayment(quoteAsset(), borrowed)])
14861486 if ((doRepay == doRepay))
14871487 then $Tuple2([ScriptTransfer(_traderAddress, borrowed, fromBase58String(assetId))], (withdrawAmount - borrowed))
14881488 else throw("Strict value is not equal to itself.")
14891489 }
14901490 else {
14911491 let realizeAndClose = invoke(collateralAddress(), "realizePartiallyAndClose", [_trader, assetId], [AttachedPayment(quoteAsset(), withdrawAmount)])
14921492 if ((realizeAndClose == realizeAndClose))
14931493 then $Tuple2([ScriptTransfer(_traderAddress, withdrawAmount, fromBase58String(assetId))], 0)
14941494 else throw("Strict value is not equal to itself.")
14951495 }
14961496 else $Tuple2(nil, withdrawAmount)
1497- if (($t06380964726 == $t06380964726))
1497+ if (($t06380564722 == $t06380564722))
14981498 then {
1499- let quoteWithdrawAmount = $t06380964726._2
1500- let sendCollateralAction = $t06380964726._1
1499+ let quoteWithdrawAmount = $t06380564722._2
1500+ let sendCollateralAction = $t06380564722._1
15011501 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, 0], nil)
15021502 if ((notifyNotional == notifyNotional))
15031503 then ((((deletePosition(_trader) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter)) ++ (if ((quoteWithdrawAmount > 0))
15041504 then withdraw(_traderAddress, quoteWithdrawAmount)
15051505 else nil)) ++ updateBalance(ammNewBalance)) ++ sendCollateralAction)
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 }
15131513 }
15141514 else throw("Strict value is not equal to itself.")
15151515 }
15161516
15171517
15181518
15191519 @Callable(i)
15201520 func liquidate (_trader) = {
15211521 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
15221522 if ((sync == sync))
15231523 then {
15241524 let spotMarginRatio = getMarginRatioByOption(_trader, PNL_OPTION_SPOT)
15251525 let marginRatio = if (isOverFluctuationLimit())
15261526 then {
15271527 let oracleMarginRatio = getMarginRatioByOption(_trader, PNL_OPTION_ORACLE)
15281528 vmax(spotMarginRatio, oracleMarginRatio)
15291529 }
15301530 else spotMarginRatio
15311531 if (if (if (if (!(requireMoreMarginRatio(marginRatio, maintenanceMarginRatio(), false)))
15321532 then true
15331533 else !(requireOpenPosition(_trader)))
15341534 then true
15351535 else !(initialized()))
15361536 then true
15371537 else paused())
15381538 then throw("Unable to liquidate")
15391539 else if (if (if ((spotMarginRatio > liquidationFeeRatio()))
15401540 then (partialLiquidationRatio() > 0)
15411541 else false)
15421542 then (DECIMAL_UNIT > partialLiquidationRatio())
15431543 else false)
15441544 then {
1545- let $t06649466644 = getPosition(_trader)
1546- let oldPositionSize = $t06649466644._1
1547- let oldPositionMargin = $t06649466644._2
1548- let oldPositionOpenNotional = $t06649466644._3
1549- let oldPositionLstUpdCPF = $t06649466644._4
1545+ let $t06649066640 = getPosition(_trader)
1546+ let oldPositionSize = $t06649066640._1
1547+ let oldPositionMargin = $t06649066640._2
1548+ let oldPositionOpenNotional = $t06649066640._3
1549+ let oldPositionLstUpdCPF = $t06649066640._4
15501550 let _direction = if ((oldPositionSize > 0))
15511551 then DIR_SHORT
15521552 else DIR_LONG
15531553 let isAdd = (_direction == DIR_LONG)
15541554 let exchangedQuoteAssetAmount = getPartialLiquidationAmount(_trader, oldPositionSize)
1555- let $t06686966973 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1556- let oldPositionNotional = $t06686966973._1
1557- let unrealizedPnl = $t06686966973._2
1558- let $t06698167213 = swapInput(isAdd, exchangedQuoteAssetAmount)
1559- let exchangedPositionSize = $t06698167213._1
1560- let quoteAssetReserveAfter = $t06698167213._2
1561- let baseAssetReserveAfter = $t06698167213._3
1562- let totalPositionSizeAfter = $t06698167213._4
1563- let cumulativeNotionalAfter = $t06698167213._5
1555+ let $t06686566969 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1556+ let oldPositionNotional = $t06686566969._1
1557+ let unrealizedPnl = $t06686566969._2
1558+ let $t06697767209 = swapInput(isAdd, exchangedQuoteAssetAmount)
1559+ let exchangedPositionSize = $t06697767209._1
1560+ let quoteAssetReserveAfter = $t06697767209._2
1561+ let baseAssetReserveAfter = $t06697767209._3
1562+ let totalPositionSizeAfter = $t06697767209._4
1563+ let cumulativeNotionalAfter = $t06697767209._5
15641564 let liquidationRatio = divd(abs(exchangedPositionSize), abs(oldPositionSize))
15651565 let realizedPnl = muld(unrealizedPnl, liquidationRatio)
1566- let $t06750267735 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1567- let remainMargin = $t06750267735._1
1568- let badDebt = $t06750267735._2
1569- let fundingPayment = $t06750267735._3
1566+ let $t06749867731 = calcRemainMarginWithFundingPayment(oldPositionSize, oldPositionMargin, oldPositionLstUpdCPF, realizedPnl)
1567+ let remainMargin = $t06749867731._1
1568+ let badDebt = $t06749867731._2
1569+ let fundingPayment = $t06749867731._3
15701570 let unrealizedPnlAfter = (unrealizedPnl - realizedPnl)
15711571 let remainOpenNotional = if ((oldPositionSize > 0))
15721572 then ((oldPositionNotional - exchangedQuoteAssetAmount) - unrealizedPnlAfter)
15731573 else ((unrealizedPnlAfter + oldPositionNotional) - exchangedQuoteAssetAmount)
15741574 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
15751575 let feeToLiquidator = (liquidationPenalty / 2)
15761576 let feeToInsurance = (liquidationPenalty - feeToLiquidator)
15771577 let newPositionMargin = (remainMargin - liquidationPenalty)
15781578 let newPositionSize = (oldPositionSize + exchangedPositionSize)
15791579 let newPositionOpenNotional = abs(remainOpenNotional)
15801580 let newPositionLstUpdCPF = latestCumulativePremiumFraction(newPositionSize)
15811581 let openInterestNotionalAfter = (openInterestNotional() - exchangedQuoteAssetAmount)
15821582 let ammBalance = (cbalance() - liquidationPenalty)
1583- let $t06890869037 = if ((0 > ammBalance))
1583+ let $t06890469033 = if ((0 > ammBalance))
15841584 then $Tuple2(0, abs(ammBalance))
15851585 else $Tuple2(ammBalance, 0)
1586- let newAmmBalance = $t06890869037._1
1587- let x11 = $t06890869037._2
1588- let $t06904569099 = getBorrowedByTrader(_trader)
1589- let borrowed = $t06904569099._1
1590- let assetId = $t06904569099._2
1586+ let newAmmBalance = $t06890469033._1
1587+ let x11 = $t06890469033._2
1588+ let $t06904169095 = getBorrowedByTrader(_trader)
1589+ let borrowed = $t06904169095._1
1590+ let assetId = $t06904169095._2
15911591 let doLiquidateCollateral = if ((borrowed > 0))
15921592 then {
15931593 let collateralToSell = muld(borrowed, liquidationRatio)
15941594 let realizeAndClose = invoke(collateralAddress(), "realizePartially", [_trader, assetId, collateralToSell], nil)
15951595 if ((realizeAndClose == realizeAndClose))
15961596 then nil
15971597 else throw("Strict value is not equal to itself.")
15981598 }
15991599 else nil
16001600 if ((doLiquidateCollateral == doLiquidateCollateral))
16011601 then {
16021602 let unstake = invoke(vaultAddress(), "withdrawLocked", [liquidationPenalty], nil)
16031603 if ((unstake == unstake))
16041604 then {
16051605 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToInsurance)])
16061606 if ((depositInsurance == depositInsurance))
16071607 then {
16081608 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, newPositionOpenNotional], nil)
16091609 if ((notifyNotional == notifyNotional))
16101610 then (((updatePosition(_trader, newPositionSize, newPositionMargin, newPositionOpenNotional, newPositionLstUpdCPF) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, (totalLongPositionSize() - (if ((newPositionSize > 0))
16111611 then abs(exchangedPositionSize)
16121612 else 0)), (totalShortPositionSize() - (if ((0 > newPositionSize))
16131613 then abs(exchangedPositionSize)
16141614 else 0)))) ++ withdraw(i.caller, feeToLiquidator)) ++ updateBalance(newAmmBalance))
16151615 else throw("Strict value is not equal to itself.")
16161616 }
16171617 else throw("Strict value is not equal to itself.")
16181618 }
16191619 else throw("Strict value is not equal to itself.")
16201620 }
16211621 else throw("Strict value is not equal to itself.")
16221622 }
16231623 else {
1624- let $t07090471359 = internalClosePosition(_trader, false)
1625- let x1 = $t07090471359._1
1626- let badDebt = $t07090471359._2
1627- let x2 = $t07090471359._3
1628- let x3 = $t07090471359._4
1629- let quoteAssetReserveAfter = $t07090471359._5
1630- let baseAssetReserveAfter = $t07090471359._6
1631- let totalPositionSizeAfter = $t07090471359._7
1632- let cumulativeNotionalAfter = $t07090471359._8
1633- let openInterestNotionalAfter = $t07090471359._9
1634- let exchangedQuoteAssetAmount = $t07090471359._10
1635- let totalLongAfter = $t07090471359._11
1636- let totalShortAfter = $t07090471359._12
1624+ let $t07090071355 = internalClosePosition(_trader, false)
1625+ let x1 = $t07090071355._1
1626+ let badDebt = $t07090071355._2
1627+ let x2 = $t07090071355._3
1628+ let x3 = $t07090071355._4
1629+ let quoteAssetReserveAfter = $t07090071355._5
1630+ let baseAssetReserveAfter = $t07090071355._6
1631+ let totalPositionSizeAfter = $t07090071355._7
1632+ let cumulativeNotionalAfter = $t07090071355._8
1633+ let openInterestNotionalAfter = $t07090071355._9
1634+ let exchangedQuoteAssetAmount = $t07090071355._10
1635+ let totalLongAfter = $t07090071355._11
1636+ let totalShortAfter = $t07090071355._12
16371637 let liquidationPenalty = muld(exchangedQuoteAssetAmount, liquidationFeeRatio())
16381638 let feeToLiquidator = (liquidationPenalty / 2)
16391639 let feeToInsurance = (liquidationPenalty - feeToLiquidator)
16401640 let ammBalance = (cbalance() - liquidationPenalty)
1641- let $t07177171900 = if ((0 > ammBalance))
1641+ let $t07176771896 = if ((0 > ammBalance))
16421642 then $Tuple2(0, abs(ammBalance))
16431643 else $Tuple2(ammBalance, 0)
1644- let newAmmBalance = $t07177171900._1
1645- let x11 = $t07177171900._2
1646- let $t07190871962 = getBorrowedByTrader(_trader)
1647- let borrowed = $t07190871962._1
1648- let assetId = $t07190871962._2
1644+ let newAmmBalance = $t07176771896._1
1645+ let x11 = $t07176771896._2
1646+ let $t07190471958 = getBorrowedByTrader(_trader)
1647+ let borrowed = $t07190471958._1
1648+ let assetId = $t07190471958._2
16491649 let doLiquidateCollateral = if ((borrowed > 0))
16501650 then {
16511651 let realizeAndClose = invoke(collateralAddress(), "realizePartiallyAndClose", [_trader, assetId], nil)
16521652 if ((realizeAndClose == realizeAndClose))
16531653 then nil
16541654 else throw("Strict value is not equal to itself.")
16551655 }
16561656 else nil
16571657 if ((doLiquidateCollateral == doLiquidateCollateral))
16581658 then {
16591659 let x = if ((badDebt > 0))
16601660 then {
16611661 let lockBadDebt = invoke(vaultAddress(), "exchangeFreeAndLocked", [badDebt], nil)
16621662 if ((lockBadDebt == lockBadDebt))
16631663 then nil
16641664 else throw("Strict value is not equal to itself.")
16651665 }
16661666 else nil
16671667 if ((x == x))
16681668 then {
16691669 let unstake = invoke(vaultAddress(), "withdrawLocked", [liquidationPenalty], nil)
16701670 if ((unstake == unstake))
16711671 then {
16721672 let depositInsurance = invoke(vaultAddress(), "addFree", nil, [AttachedPayment(quoteAsset(), feeToInsurance)])
16731673 if ((depositInsurance == depositInsurance))
16741674 then {
16751675 let notifyNotional = invoke(minerAddress(), "notifyNotional", [_trader, 0], nil)
16761676 if ((notifyNotional == notifyNotional))
16771677 then (((deletePosition(_trader) ++ updateAmm(quoteAssetReserveAfter, baseAssetReserveAfter, totalPositionSizeAfter, cumulativeNotionalAfter, openInterestNotionalAfter, totalLongAfter, totalShortAfter)) ++ withdraw(i.caller, feeToLiquidator)) ++ updateBalance(newAmmBalance))
16781678 else throw("Strict value is not equal to itself.")
16791679 }
16801680 else throw("Strict value is not equal to itself.")
16811681 }
16821682 else throw("Strict value is not equal to itself.")
16831683 }
16841684 else throw("Strict value is not equal to itself.")
16851685 }
16861686 else throw("Strict value is not equal to itself.")
16871687 }
16881688 }
16891689 else throw("Strict value is not equal to itself.")
16901690 }
16911691
16921692
16931693
16941694 @Callable(i)
16951695 func payFunding () = {
16961696 let fundingBlockTimestamp = nextFundingBlockTimestamp()
16971697 if (if (if ((fundingBlockTimestamp > lastBlock.timestamp))
16981698 then true
16991699 else !(initialized()))
17001700 then true
17011701 else paused())
17021702 then throw(((("Invalid funding block timestamp: " + toString(lastBlock.timestamp)) + " < ") + toString(fundingBlockTimestamp)))
17031703 else {
17041704 let underlyingPrice = getOracleTwapPrice()
1705- let $t07398974051 = getFunding()
1706- let shortPremiumFraction = $t07398974051._1
1707- let longPremiumFraction = $t07398974051._2
1705+ let $t07398574047 = getFunding()
1706+ let shortPremiumFraction = $t07398574047._1
1707+ let longPremiumFraction = $t07398574047._2
17081708 updateFunding((fundingBlockTimestamp + fundingPeriodSeconds()), (latestLongCumulativePremiumFraction() + longPremiumFraction), (latestShortCumulativePremiumFraction() + shortPremiumFraction), divd(longPremiumFraction, underlyingPrice), divd(shortPremiumFraction, underlyingPrice))
17091709 }
17101710 }
17111711
17121712
17131713
17141714 @Callable(i)
17151715 func syncTerminalPriceToOracle () = {
1716- let $t07443374554 = getSyncTerminalPrice(getOracleTwapPrice())
1717- let newQuoteAssetWeight = $t07443374554._1
1718- let newBaseAssetWeight = $t07443374554._2
1719- let marginToVault = $t07443374554._3
1716+ let $t07442974550 = getSyncTerminalPrice(getOracleTwapPrice())
1717+ let newQuoteAssetWeight = $t07442974550._1
1718+ let newBaseAssetWeight = $t07442974550._2
1719+ let marginToVault = $t07442974550._3
17201720 updateAmmWeights(newQuoteAssetWeight, newBaseAssetWeight)
17211721 }
17221722
17231723
17241724
17251725 @Callable(i)
17261726 func v_get (_trader) = {
17271727 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
17281728 if ((sync == sync))
17291729 then {
1730- let $t07473274792 = internalClosePosition(_trader, false)
1731- let x1 = $t07473274792._1
1732- let x2 = $t07473274792._2
1733- let x3 = $t07473274792._3
1734- let x4 = $t07473274792._4
1730+ let $t07472874788 = internalClosePosition(_trader, false)
1731+ let x1 = $t07472874788._1
1732+ let x2 = $t07472874788._2
1733+ let x3 = $t07472874788._3
1734+ let x4 = $t07472874788._4
17351735 throw((((s(x2) + s(x3)) + s(x4)) + s(getMarginRatio(_trader))))
17361736 }
17371737 else throw("Strict value is not equal to itself.")
17381738 }
17391739
17401740
17411741
17421742 @Callable(i)
17431743 func view_calcRemainMarginWithFundingPayment (_trader) = {
17441744 let sync = invoke(this, "syncTerminalPriceToOracle", nil, nil)
17451745 if ((sync == sync))
17461746 then {
1747- let $t07500375104 = getPosition(_trader)
1748- let positionSize = $t07500375104._1
1749- let positionMargin = $t07500375104._2
1750- let pon = $t07500375104._3
1751- let positionLstUpdCPF = $t07500375104._4
1752- let $t07510775208 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1753- let positionNotional = $t07510775208._1
1754- let unrealizedPnl = $t07510775208._2
1755- let $t07521175383 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1756- let remainMargin = $t07521175383._1
1757- let badDebt = $t07521175383._2
1758- let fundingPayment = $t07521175383._3
1747+ let $t07499975100 = getPosition(_trader)
1748+ let positionSize = $t07499975100._1
1749+ let positionMargin = $t07499975100._2
1750+ let pon = $t07499975100._3
1751+ let positionLstUpdCPF = $t07499975100._4
1752+ let $t07510375204 = getPositionNotionalAndUnrealizedPnl(_trader, PNL_OPTION_SPOT)
1753+ let positionNotional = $t07510375204._1
1754+ let unrealizedPnl = $t07510375204._2
1755+ let $t07520775379 = calcRemainMarginWithFundingPayment(positionSize, positionMargin, positionLstUpdCPF, unrealizedPnl)
1756+ let remainMargin = $t07520775379._1
1757+ let badDebt = $t07520775379._2
1758+ let fundingPayment = $t07520775379._3
17591759 throw((((((s(remainMargin) + s(fundingPayment)) + s(getMarginRatio(_trader))) + s(unrealizedPnl)) + s(badDebt)) + s(positionNotional)))
17601760 }
17611761 else throw("Strict value is not equal to itself.")
17621762 }
17631763
17641764
17651765
17661766 @Callable(i)
17671767 func view_getPegAdjustCost (_price) = {
17681768 let result = getSyncTerminalPrice(_price)
17691769 throw(toString(result._3))
17701770 }
17711771
17721772
17731773
17741774 @Callable(i)
17751775 func view_getTerminalAmmPrice () = {
1776- let $t07573075811 = getTerminalAmmState()
1777- let terminalQuoteAssetReserve = $t07573075811._1
1778- let terminalBaseAssetReserve = $t07573075811._2
1776+ let $t07572675807 = getTerminalAmmState()
1777+ let terminalQuoteAssetReserve = $t07572675807._1
1778+ let terminalBaseAssetReserve = $t07572675807._2
17791779 let price = divd(muld(terminalQuoteAssetReserve, qtAstW()), muld(terminalBaseAssetReserve, bsAstW()))
17801780 throw(toString(price))
17811781 }
17821782
17831783
17841784
17851785 @Callable(i)
17861786 func view_getFunding () = {
17871787 let underlyingPrice = getOracleTwapPrice()
1788- let $t07603076092 = getFunding()
1789- let shortPremiumFraction = $t07603076092._1
1790- let longPremiumFraction = $t07603076092._2
1788+ let $t07602676088 = getFunding()
1789+ let shortPremiumFraction = $t07602676088._1
1790+ let longPremiumFraction = $t07602676088._2
17911791 let longFunding = divd(longPremiumFraction, underlyingPrice)
17921792 let shortFunding = divd(shortPremiumFraction, underlyingPrice)
17931793 throw((((s(longFunding) + s(shortFunding)) + s(getTwapSpotPrice())) + s(getOracleTwapPrice())))
17941794 }
17951795
17961796
17971797
17981798 @Callable(i)
17991799 func view_getBorrowedByTrader (_trader) = {
1800- let $t07638276436 = getBorrowedByTrader(_trader)
1801- let borrowed = $t07638276436._1
1802- let assetId = $t07638276436._2
1800+ let $t07637876432 = getBorrowedByTrader(_trader)
1801+ let borrowed = $t07637876432._1
1802+ let assetId = $t07637876432._2
18031803 throw((s(borrowed) + assetId))
18041804 }
18051805
18061806
18071807 @Verifier(tx)
18081808 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], adminPublicKey())
18091809

github/deemru/w8io/026f985 
317.25 ms