tx · 4JnZHetswEK2vsWqraSxe7r7vnkPPqWEAfEXWdgZV7kj

3N3c8hF3E1qiSZ27uH3XZvtWSso9QFckZUb:  -0.03100000 Waves

2024.08.26 13:28 [3255739] smart account 3N3c8hF3E1qiSZ27uH3XZvtWSso9QFckZUb > SELF 0.00000000 Waves

{ "type": 13, "id": "4JnZHetswEK2vsWqraSxe7r7vnkPPqWEAfEXWdgZV7kj", "fee": 3100000, "feeAssetId": null, "timestamp": 1724668121964, "version": 1, "sender": "3N3c8hF3E1qiSZ27uH3XZvtWSso9QFckZUb", "senderPublicKey": "9Dkh2UiuYRqFTQrAXgJJbJuG3Q6VDPhiYHrsdfQx42Zx", "proofs": [ "HTuh3KiVqcah62dj2PSvur9d2GEjyg8vNogZfF8ABsh2uu35Qw1T3jVK99pWYtEtjfJZ34WTNWPfXBKc49BEdTg" ], "script": "base64:BwJhCAISAwoBCBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGBIECgICGGAACXNlcGFyYXRvcgICX18AB2NoYWluSWQJAMkBAgkAygECCAUEdGhpcwVieXRlcwABAAEACGNoYWluSWRXAQFXABBjb250cmFjdEZpbGVuYW1lAhdmdXR1cmVzX2NhbGN1bGF0b3IucmlkZQAFbXVsdDgAgMLXLwAMbXVsdDE4QmlnSW50CQC2AgEAgICQu7rWrfANAA13YXZlc0RlY2ltYWxzAAgADHVzZHREZWNpbWFscwAGAAt3YXZlc1N0cmluZwIFV0FWRVMADXF1ZXVlSXRlbVNpemUAIAAEYmlnMAkAtgIBAAAACklOREVYX0xJU1QJAMwIAgAACQDMCAIAAQkAzAgCAAIJAMwIAgADCQDMCAIABAkAzAgCAAUJAMwIAgAGCQDMCAIABwkAzAgCAAgJAMwIAgAJCQDMCAIACgkAzAgCAAsJAMwIAgAMCQDMCAIADQkAzAgCAA4JAMwIAgAPCQDMCAIAEAkAzAgCABEJAMwIAgASCQDMCAIAEwUDbmlsAAlrTXVsdGlzaWcCDCVzX19tdWx0aXNpZwEHa1N0YXR1cwIEZGFwcAR0eElkCQC5CQIJAMwIAgIKJXNfX3N0YXR1cwkAzAgCBQRkYXBwCQDMCAIFBHR4SWQFA25pbAUJc2VwYXJhdG9yAAlrU2h1dGRvd24CDCVzX19zaHV0ZG93bgALa1B1YmxpY0tleXMCDiVzX19wdWJsaWNLZXlzABFrTWF0Y2hlclB1YmxpY0tleQIUJXNfX21hdGNoZXJQdWJsaWNLZXkBBXRvWDE4AgdvcmlnVmFsDW9yaWdTY2FsZU11bHQJALwCAwkAtgIBBQdvcmlnVmFsBQxtdWx0MThCaWdJbnQJALYCAQUNb3JpZ1NjYWxlTXVsdAEHZnJvbVgxOAIDdmFsD3Jlc3VsdFNjYWxlTXVsdAkAoAMBCQC8AgMFA3ZhbAkAtgIBBQ9yZXN1bHRTY2FsZU11bHQFDG11bHQxOEJpZ0ludAEPdmFsaWRhdGVBZGRyZXNzAQdhZGRyZXNzCQEJaXNEZWZpbmVkAQkApggBBQdhZGRyZXNzAQd3cmFwRXJyAQFzCQCsAgIJAKwCAgUQY29udHJhY3RGaWxlbmFtZQICOiAFAXMBCHRocm93RXJyAQFzCQACAQkBB3dyYXBFcnIBBQFzAQ5lbnN1cmVQb3NpdGl2ZQIBdgFzAwkAZwIFAXYAAAUBdgkBCHRocm93RXJyAQkArAICBQFzAhkgdmFsdWUgc2hvdWxkIGJlIHBvc2l0aXZlAQxwYXJzZUFzc2V0SWQBBWlucHV0AwkAAAIFBWlucHV0BQt3YXZlc1N0cmluZwUEdW5pdAkA2QQBBQVpbnB1dAEPYXNzZXRJZFRvU3RyaW5nAQVpbnB1dAMJAAACBQVpbnB1dAUEdW5pdAULd2F2ZXNTdHJpbmcJANgEAQkBBXZhbHVlAQUFaW5wdXQBEmdldEFzc2V0SW5mb09yRmFpbAEHYXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFB2Fzc2V0SWQJAQd3cmFwRXJyAQISaW52YWxpZCBhc3NldCBpbmZvARZnZXRBc3NldERlY2ltYWxzT3JGYWlsAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACBFVuaXQFDXdhdmVzRGVjaW1hbHMDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQHYXNzZXRJZAUHJG1hdGNoMAgJARJnZXRBc3NldEluZm9PckZhaWwBBQdhc3NldElkCGRlY2ltYWxzCQACAQILTWF0Y2ggZXJyb3IBD2dldEFzc2V0QmFsYW5jZQIHYXNzZXRJZAdhZGRyZXNzBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACBFVuaXQICQDvBwEFB2FkZHJlc3MJYXZhaWxhYmxlAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEB2Fzc2V0SWQFByRtYXRjaDAJAPAHAgUHYWRkcmVzcwUHYXNzZXRJZAkAAgECC01hdGNoIGVycm9yAQVwb3cxMAEBbgkAbAYACgAABQFuAAAAAAUERE9XTgENcG93MTBEZWNpbWFscwEHYXNzZXRJZAkBBXBvdzEwAQkBFmdldEFzc2V0RGVjaW1hbHNPckZhaWwBBQdhc3NldElkAA9rRmFjdG9yeUFkZHJlc3MCEiVzX19mYWN0b3J5QWRkcmVzcwAUZmFjdG9yeUFkZHJlc3NPcHRpb24EByRtYXRjaDAJAJ0IAgUEdGhpcwUPa0ZhY3RvcnlBZGRyZXNzAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkApggBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgAOZmFjdG9yeUFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgUUZmFjdG9yeUFkZHJlc3NPcHRpb24JAQd3cmFwRXJyAQIXaW52YWxpZCBmYWN0b3J5IGFkZHJlc3MADGtVc2R0QXNzZXRJZAIPJXNfX3VzZHRBc3NldElkABF1c2R0QXNzZXRJZE9wdGlvbgQHJG1hdGNoMAkAnQgCBQ5mYWN0b3J5QWRkcmVzcwUMa1VzZHRBc3NldElkAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkBDHBhcnNlQXNzZXRJZAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAAt1c2R0QXNzZXRJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBRF1c2R0QXNzZXRJZE9wdGlvbgkBB3dyYXBFcnIBAhVpbnZhbGlkIHVzZHQgYXNzZXQgaWQADmtQcmljZXNBZGRyZXNzAhUlc19fY2FsY3VsYXRvckFkZHJlc3MACHNodXRkb3duCQELdmFsdWVPckVsc2UCCQCbCAIFDmZhY3RvcnlBZGRyZXNzBQlrU2h1dGRvd24HAQttdXN0QWRkcmVzcwIGY2FsbGVyB2FkZHJlc3MDCQAAAgUGY2FsbGVyBQdhZGRyZXNzBgkBCHRocm93RXJyAQIRcGVybWlzc2lvbiBkZW5pZWQBCG11c3RUaGlzAQZjYWxsZXIJAQttdXN0QWRkcmVzcwIFBmNhbGxlcgUEdGhpcwELbXVzdEZhY3RvcnkBBmNhbGxlcgkBC211c3RBZGRyZXNzAgUGY2FsbGVyBQ5mYWN0b3J5QWRkcmVzcwEJbXVzdEFkbWluAQ9jYWxsZXJQdWJsaWNLZXkEFW11bHRpc2lnQWRkcmVzc1N0cmluZwkAnQgCBQ5mYWN0b3J5QWRkcmVzcwUJa011bHRpc2lnBAdpc0FkbWluBAckbWF0Y2gwBRVtdWx0aXNpZ0FkZHJlc3NTdHJpbmcDCQABAgUHJG1hdGNoMAIGU3RyaW5nBA1hZGRyZXNzU3RyaW5nBQckbWF0Y2gwBAhtdWx0aXNpZwkBEUBleHRyTmF0aXZlKDEwNjIpAQUNYWRkcmVzc1N0cmluZwQOcHVibGljS2V5c0xpc3QJALUJAgkBEUBleHRyTmF0aXZlKDEwNTMpAgUIbXVsdGlzaWcFC2tQdWJsaWNLZXlzBQlzZXBhcmF0b3IJAQ9jb250YWluc0VsZW1lbnQCBQ5wdWJsaWNLZXlzTGlzdAkA2AQBBQ9jYWxsZXJQdWJsaWNLZXkJAAACCQCnCAEFD2NhbGxlclB1YmxpY0tleQUOZmFjdG9yeUFkZHJlc3MDBQdpc0FkbWluBgkBCHRocm93RXJyAQILbm90IGFsbG93ZWQADmtBY2NvdW50U2NyaXB0AhElc19fYWNjb3VudFNjcmlwdAENYWNjb3VudFNjcmlwdAAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQ5mYWN0b3J5QWRkcmVzcwUOa0FjY291bnRTY3JpcHQJAQd3cmFwRXJyAQIZYWNjb3VudCBzY3JpcHQgaXMgbm90IHNldAANa1Jld2FyZEFtb3VudAIQJXNfX3Jld2FyZEFtb3VudAEMcmV3YXJkQW1vdW50AAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDmZhY3RvcnlBZGRyZXNzBQ1rUmV3YXJkQW1vdW50CQEHd3JhcEVycgECGHJld2FyZCBhbW91bnQgaXMgbm90IHNldAAOa0FjY291bnRzTGltaXQCESVzX19hY2NvdW50c0xpbWl0ABRhY2NvdW50c0xpbWl0RGVmYXVsdAAUAQ1hY2NvdW50c0xpbWl0AAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5mYWN0b3J5QWRkcmVzcwUOa0FjY291bnRzTGltaXQFFGFjY291bnRzTGltaXREZWZhdWx0AQprRGVwb3NpdGVkAQ5hY2NvdW50QWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIJZGVwb3NpdGVkCQDMCAIJAKUIAQUOYWNjb3VudEFkZHJlc3MFA25pbAUJc2VwYXJhdG9yAQ9kZXBvc2l0ZWRPcHRpb24BDmFjY291bnRBZGRyZXNzCQCaCAIFDmZhY3RvcnlBZGRyZXNzCQEKa0RlcG9zaXRlZAEFDmFjY291bnRBZGRyZXNzAQdrQ3JlZGl0Ag5hY2NvdW50QWRkcmVzcwdhc3NldElkCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICBmNyZWRpdAkAzAgCCQClCAEFDmFjY291bnRBZGRyZXNzCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQdhc3NldElkBQNuaWwFCXNlcGFyYXRvcgEMY3JlZGl0T3B0aW9uAg5hY2NvdW50QWRkcmVzcwdhc3NldElkCQCaCAIFDmZhY3RvcnlBZGRyZXNzCQEHa0NyZWRpdAIFDmFjY291bnRBZGRyZXNzBQdhc3NldElkAQlrTGV2ZXJhZ2UBDmFjY291bnRBZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCAghsZXZlcmFnZQkAzAgCCQClCAEFDmFjY291bnRBZGRyZXNzBQNuaWwFCXNlcGFyYXRvcgEQa1JlcXVlc3RMZXZlcmFnZQEJcmVxdWVzdElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCAg9yZXF1ZXN0TGV2ZXJhZ2UJAMwIAgkA2AQBBQlyZXF1ZXN0SWQFA25pbAUJc2VwYXJhdG9yARFrU3ludGhldGljQXNzZXRJZAELYmFzZUFzc2V0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAICEHN5bnRoZXRpY0Fzc2V0SWQJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFC2Jhc2VBc3NldElkBQNuaWwFCXNlcGFyYXRvcgEMa0Jhc2VBc3NldElkARBzeW50aGV0aWNBc3NldElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgtiYXNlQXNzZXRJZAkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQUQc3ludGhldGljQXNzZXRJZAUDbmlsBQlzZXBhcmF0b3IAFFJFUVVFU1RfU1RBVFVTX0VNUFRZAAAAFFJFUVVFU1RfU1RBVFVTX1JFQURZAAEBDmtSZXF1ZXN0U3RhdHVzAQlyZXF1ZXN0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAIJANgEAQUJcmVxdWVzdElkCQDMCAICBnN0YXR1cwUDbmlsBQlzZXBhcmF0b3IBGGtBY2NvdW50Q3JlYXRvclB1YmxpY0tleQEOYWNjb3VudEFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAIJAKUIAQUOYWNjb3VudEFkZHJlc3MJAMwIAgIQY3JlYXRvclB1YmxpY0tleQUDbmlsBQlzZXBhcmF0b3IBFmtSZXF1ZXN0T3duZXJQdWJsaWNLZXkBCXJlcXVlc3RJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgkA2AQBBQlyZXF1ZXN0SWQJAMwIAgIOb3duZXJQdWJsaWNLZXkFA25pbAUJc2VwYXJhdG9yARVrUmVxdWVzdEFtb3VudEFzc2V0SWQBCXJlcXVlc3RJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgkA2AQBBQlyZXF1ZXN0SWQJAMwIAgINYW1vdW50QXNzZXRJZAUDbmlsBQlzZXBhcmF0b3IBFGtSZXF1ZXN0UHJpY2VBc3NldElkAQlyZXF1ZXN0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAIJANgEAQUJcmVxdWVzdElkCQDMCAICDHByaWNlQXNzZXRJZAUDbmlsBQlzZXBhcmF0b3IBHGtSZXF1ZXN0SWRUb0FjY291bnRQdWJsaWNLZXkBCXJlcXVlc3RJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgkA2AQBBQlyZXF1ZXN0SWQJAMwIAgIbcmVxdWVzdElkVG9BY2NvdW50UHVibGljS2V5BQNuaWwFCXNlcGFyYXRvcgEaa0FjY291bnRBZGRyZXNzVG9SZXF1ZXN0SWQBDmFjY291bnRBZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCCQClCAEFDmFjY291bnRBZGRyZXNzCQDMCAICGWFjY291bnRBZGRyZXNzVG9SZXF1ZXN0SWQFA25pbAUJc2VwYXJhdG9yAQ5rUmVxdWVzdHNRdWV1ZQAJALkJAgkAzAgCAgIlcwkAzAgCAg1yZXF1ZXN0c1F1ZXVlBQNuaWwFCXNlcGFyYXRvcgENcmVxdWVzdHNRdWV1ZQAJAQt2YWx1ZU9yRWxzZQIJAJwIAgUOZmFjdG9yeUFkZHJlc3MJAQ5rUmVxdWVzdHNRdWV1ZQABAAEOa0FjY291bnRzUXVldWUACQC5CQIJAMwIAgICJXMJAMwIAgINYWNjb3VudHNRdWV1ZQUDbmlsBQlzZXBhcmF0b3IBDWFjY291bnRzUXVldWUACQELdmFsdWVPckVsc2UCCQCcCAIFDmZhY3RvcnlBZGRyZXNzCQEOa0FjY291bnRzUXVldWUAAQABEGtSZXF1ZXN0c0J5T3duZXIBDG93bmVyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIIcmVxdWVzdHMJAMwIAgkApQgBBQxvd25lckFkZHJlc3MFA25pbAUJc2VwYXJhdG9yAQ9yZXF1ZXN0c0J5T3duZXIBDG93bmVyQWRkcmVzcwkBC3ZhbHVlT3JFbHNlAgkAnAgCBQ5mYWN0b3J5QWRkcmVzcwkBEGtSZXF1ZXN0c0J5T3duZXIBBQxvd25lckFkZHJlc3MBAAEMa1BhaXJBbGxvd2VkAg1hbW91bnRBc3NldElkDHByaWNlQXNzZXRJZAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQUNYW1vdW50QXNzZXRJZAkAzAgCCQEPYXNzZXRJZFRvU3RyaW5nAQUMcHJpY2VBc3NldElkCQDMCAICC3BhaXJBbGxvd2VkBQNuaWwFCXNlcGFyYXRvcgELcGFpckFsbG93ZWQCDWFtb3VudEFzc2V0SWQMcHJpY2VBc3NldElkCQELdmFsdWVPckVsc2UCCQCbCAIFDmZhY3RvcnlBZGRyZXNzCQEMa1BhaXJBbGxvd2VkAgUNYW1vdW50QXNzZXRJZAUMcHJpY2VBc3NldElkBwEGa1ByaWNlAQdhc3NldElkCQC5CQIJAMwIAgICJXMJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFB2Fzc2V0SWQFA25pbAUJc2VwYXJhdG9yARJrUGFpclByaWNlc0xpc3RLZXkCDWFtb3VudEFzc2V0SWQMcHJpY2VBc3NldElkCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQ1hbW91bnRBc3NldElkCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQxwcmljZUFzc2V0SWQJAMwIAgIRcGFpclNldHRpbmdQcmljZXMFA25pbAUJc2VwYXJhdG9yARFnZXRQYWlyUHJpY2VzTGlzdAINYW1vdW50QXNzZXRJZAxwcmljZUFzc2V0SWQEByRtYXRjaDAJAJ0IAgUOZmFjdG9yeUFkZHJlc3MJARJrUGFpclByaWNlc0xpc3RLZXkCBQ1hbW91bnRBc3NldElkBQxwcmljZUFzc2V0SWQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQC1CQIFAXMFCXNlcGFyYXRvcgUDbmlsARBrUGFpclNldHRpbmdzS2V5Aw1hbW91bnRBc3NldElkDHByaWNlQXNzZXRJZAtwcmljZVN0cmluZwkAuQkCCQDMCAICCCVzJXMlZCVzCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQ1hbW91bnRBc3NldElkCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQxwcmljZUFzc2V0SWQJAMwIAgULcHJpY2VTdHJpbmcJAMwIAgIIc2V0dGluZ3MFA25pbAUJc2VwYXJhdG9yAQ9nZXRDdXJyZW50UHJpY2UBB2Fzc2V0SWQEEG1hdGNoZXJQdWJsaWNLZXkJANkEAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFDmZhY3RvcnlBZGRyZXNzBRFrTWF0Y2hlclB1YmxpY0tleQkBB3dyYXBFcnIBAhppbnZhbGlkIG1hdGNoZXIgcHVibGljIGtleQQObWF0Y2hlckFkZHJlc3MJAKcIAQUQbWF0Y2hlclB1YmxpY0tleQQFcHJpY2UJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQ5tYXRjaGVyQWRkcmVzcwkBBmtQcmljZQEFB2Fzc2V0SWQJAQd3cmFwRXJyAQkArAICAhlpbnZhbGlkIHByaWNlLCBhc3NldElkID0gCQEPYXNzZXRJZFRvU3RyaW5nAQUHYXNzZXRJZAUFcHJpY2UBD2NhbGNUb3RhbENyZWRpdAMHY3JlZGl0QQdjcmVkaXRCDGN1cnJlbnRQcmljZQkAtwICCQC8AgMFB2NyZWRpdEEFDGN1cnJlbnRQcmljZQUMbXVsdDE4QmlnSW50BQdjcmVkaXRCARBjYWxjVG90YWxCYWxhbmNlAwhiYWxhbmNlQQhiYWxhbmNlQgxjdXJyZW50UHJpY2UJALcCAgkAvAIDBQhiYWxhbmNlQQUMY3VycmVudFByaWNlBQxtdWx0MThCaWdJbnQFCGJhbGFuY2VCAQdjYWxjUG5sAgx0b3RhbEJhbGFuY2ULdG90YWxDcmVkaXQJALgCAgUMdG90YWxCYWxhbmNlBQt0b3RhbENyZWRpdAETY2FsY0NyZWRpdEF2YWlsYWJsZQMHZGVwb3NpdAhsZXZlcmFnZQt0b3RhbENyZWRpdAkAuAICCQC8AgMFB2RlcG9zaXQFCGxldmVyYWdlBQxtdWx0MThCaWdJbnQFC3RvdGFsQ3JlZGl0ARBjYWxjUmVhbEluQ3JlZGl0AgZjcmVkaXQHYmFsYW5jZQMJAL8CAgUGY3JlZGl0BQRiaWcwCQC4AgIFBmNyZWRpdAUHYmFsYW5jZQUEYmlnMAEIY2FsY0ZyZWUCBmNyZWRpdAdiYWxhbmNlAwkAvwICBQZjcmVkaXQFBGJpZzAJALgCAgUHYmFsYW5jZQUGY3JlZGl0BQRiaWcwAQ5jYWxjU2hvcnRQcmljZQIEZnJlZQxyZWFsSW5DcmVkaXQDCQC/AgIFDHJlYWxJbkNyZWRpdAUEYmlnMAkAmAMBCQDMCAIFBGJpZzAJAMwIAgkAvAIDBQRmcmVlBQxtdWx0MThCaWdJbnQFDHJlYWxJbkNyZWRpdAUDbmlsBQRiaWcwAQ1jYWxjTG9uZ1ByaWNlAgRmcmVlDHJlYWxJbkNyZWRpdAMJAL8CAgUMcmVhbEluQ3JlZGl0BQRiaWcwCQCYAwEJAMwIAgUEYmlnMAkAzAgCCQC8AgMFDHJlYWxJbkNyZWRpdAUMbXVsdDE4QmlnSW50BQRmcmVlBQNuaWwFBGJpZzABD2NhbGNTdGFydE1hcmdpbgQNcmVhbEluQ3JlZGl0QQ1yZWFsSW5DcmVkaXRCDGN1cnJlbnRQcmljZQ5zZXR0aW5nc01hcmdpbgkAvAIDCQC3AgIJALwCAwUNcmVhbEluQ3JlZGl0QQUMY3VycmVudFByaWNlBQxtdWx0MThCaWdJbnQFDXJlYWxJbkNyZWRpdEIFDnNldHRpbmdzTWFyZ2luBQxtdWx0MThCaWdJbnQBEGNhbGNNYXJnaW5TdXBwbHkDFHNldHRpbmdzTWFyZ2luU3VwcGx5DnNldHRpbmdzTWFyZ2luC3N0YXJ0TWFyZ2luCQC8AgMFFHNldHRpbmdzTWFyZ2luU3VwcGx5BQtzdGFydE1hcmdpbgUOc2V0dGluZ3NNYXJnaW4BFGNhbGNMaXF1aWRhdGlvblByaWNlBgdkZXBvc2l0DG1hcmdpblN1cHBseQ1yZWFsSW5DcmVkaXRBDXJlYWxJbkNyZWRpdEIKc2hvcnRQcmljZQlsb25nUHJpY2UEEWxpcXVpZGF0aW9uUHJpY2VBAwkAvwICBQ1yZWFsSW5DcmVkaXRBBQRiaWcwCQC3AgIJALoCAgkAuAICBQdkZXBvc2l0BQxtYXJnaW5TdXBwbHkFDXJlYWxJbkNyZWRpdEEFCnNob3J0UHJpY2UFBGJpZzAEEWxpcXVpZGF0aW9uUHJpY2VCAwkAvwICBQ1yZWFsSW5DcmVkaXRCBQRiaWcwCQC4AgIFCWxvbmdQcmljZQkAugICCQC4AgIFB2RlcG9zaXQFDG1hcmdpblN1cHBseQkAugICBQ1yZWFsSW5DcmVkaXRBBQlsb25nUHJpY2UFBGJpZzAJALcCAgURbGlxdWlkYXRpb25QcmljZUEFEWxpcXVpZGF0aW9uUHJpY2VCAQxnZXRSZXF1ZXN0SWQBDmFjY291bnRBZGRyZXNzBAlyZXF1ZXN0SWQJANkEAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQEaa0FjY291bnRBZGRyZXNzVG9SZXF1ZXN0SWQBBQ5hY2NvdW50QWRkcmVzcwkBB3dyYXBFcnIBAjBpbnZhbGlkIGFjY291bnQgYWRkcmVzczogcmVxdWVzdCBpZCBpcyB1bmRlZmluZWQFCXJlcXVlc3RJZAEQZ2V0QWNjb3VudEFzc2V0cwEOYWNjb3VudEFkZHJlc3MECXJlcXVlc3RJZAkBDGdldFJlcXVlc3RJZAEFDmFjY291bnRBZGRyZXNzBA1hbW91bnRBc3NldElkCQEMcGFyc2VBc3NldElkAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQEVa1JlcXVlc3RBbW91bnRBc3NldElkAQUJcmVxdWVzdElkCQEHd3JhcEVycgECF2ludmFsaWQgYW1vdW50IGFzc2V0IGlkBAxwcmljZUFzc2V0SWQJAQxwYXJzZUFzc2V0SWQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUOZmFjdG9yeUFkZHJlc3MJARRrUmVxdWVzdFByaWNlQXNzZXRJZAEFCXJlcXVlc3RJZAkBB3dyYXBFcnIBAhdpbnZhbGlkIGFtb3VudCBwcmljZSBpZAkAlAoCBQ1hbW91bnRBc3NldElkBQxwcmljZUFzc2V0SWQBGGdldEFjY291bnRPd25lclB1YmxpY0tleQEOYWNjb3VudEFkZHJlc3MECXJlcXVlc3RJZAkBDGdldFJlcXVlc3RJZAEFDmFjY291bnRBZGRyZXNzBBVyZXF1ZXN0T3duZXJQdWJsaWNLZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnAgCBQ5mYWN0b3J5QWRkcmVzcwkBFmtSZXF1ZXN0T3duZXJQdWJsaWNLZXkBBQlyZXF1ZXN0SWQJAQd3cmFwRXJyAQIXaW52YWxpZCBhbW91bnQgYXNzZXQgaWQFFXJlcXVlc3RPd25lclB1YmxpY0tleQEWZ2V0QWNjb3VudEluZm9JbnRlcm5hbAEOYWNjb3VudEFkZHJlc3MEDSR0MDExNDIwMTE0ODgJARBnZXRBY2NvdW50QXNzZXRzAQUOYWNjb3VudEFkZHJlc3MEDWFtb3VudEFzc2V0SWQIBQ0kdDAxMTQyMDExNDg4Al8xBAxwcmljZUFzc2V0SWQIBQ0kdDAxMTQyMDExNDg4Al8yBAhsZXZlcmFnZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDmZhY3RvcnlBZGRyZXNzCQEJa0xldmVyYWdlAQUOYWNjb3VudEFkZHJlc3MJAQd3cmFwRXJyAQIabGV2ZXJhZ2Ugc2hvdWxkIGJlIGRlZmluZWQECXJlcXVlc3RJZAkBDGdldFJlcXVlc3RJZAEFDmFjY291bnRBZGRyZXNzBBBhY2NvdW50UHVibGljS2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJwIAgUOZmFjdG9yeUFkZHJlc3MJARxrUmVxdWVzdElkVG9BY2NvdW50UHVibGljS2V5AQUJcmVxdWVzdElkAiZrUmVxdWVzdElkVG9BY2NvdW50UHVibGljS2V5IG5vdCBmb3VuZAQJZGVwb3NpdGVkCQELdmFsdWVPckVsc2UCCQEPZGVwb3NpdGVkT3B0aW9uAQUOYWNjb3VudEFkZHJlc3MAAAQMY3VycmVudFByaWNlCQEFdG9YMTgCCQEPZ2V0Q3VycmVudFByaWNlAQUNYW1vdW50QXNzZXRJZAkBDXBvdzEwRGVjaW1hbHMBBQxwcmljZUFzc2V0SWQEB2NyZWRpdEEJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQdrQ3JlZGl0AgUOYWNjb3VudEFkZHJlc3MFDWFtb3VudEFzc2V0SWQAAAQHY3JlZGl0QgkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5mYWN0b3J5QWRkcmVzcwkBB2tDcmVkaXQCBQ5hY2NvdW50QWRkcmVzcwUMcHJpY2VBc3NldElkAAAEBnN0YXR1cwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDmZhY3RvcnlBZGRyZXNzCQEOa1JlcXVlc3RTdGF0dXMBBQlyZXF1ZXN0SWQJAKwCAgIec3RhdHVzIG5vdCBmb3VuZC4gUmVxdWVzdElkID0gCQDYBAEFCXJlcXVlc3RJZAQSc3ludGhBbW91bnRBc3NldElkCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQERa1N5bnRoZXRpY0Fzc2V0SWQBBQ1hbW91bnRBc3NldElkBBdzeW50aEFtb3VudEFzc2V0QmFsYW5jZQQHJG1hdGNoMAUSc3ludGhBbW91bnRBc3NldElkAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkBD2dldEFzc2V0QmFsYW5jZQIJAQxwYXJzZUFzc2V0SWQBBQFzBQ5hY2NvdW50QWRkcmVzcwAABBFzeW50aFByaWNlQXNzZXRJZAkAnQgCBQ5mYWN0b3J5QWRkcmVzcwkBEWtTeW50aGV0aWNBc3NldElkAQUMcHJpY2VBc3NldElkBBZzeW50aFByaWNlQXNzZXRCYWxhbmNlBAckbWF0Y2gwBRFzeW50aFByaWNlQXNzZXRJZAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJAQ9nZXRBc3NldEJhbGFuY2UCCQEMcGFyc2VBc3NldElkAQUBcwUOYWNjb3VudEFkZHJlc3MAAAkAngoMCQEPYXNzZXRJZFRvU3RyaW5nAQUNYW1vdW50QXNzZXRJZAkBD2Fzc2V0SWRUb1N0cmluZwEFDHByaWNlQXNzZXRJZAkApQgBBQ5hY2NvdW50QWRkcmVzcwkA2AQBBRBhY2NvdW50UHVibGljS2V5BQhsZXZlcmFnZQkA2AQBBQlyZXF1ZXN0SWQFCWRlcG9zaXRlZAUHY3JlZGl0QQUHY3JlZGl0QgUXc3ludGhBbW91bnRBc3NldEJhbGFuY2UFFnN5bnRoUHJpY2VBc3NldEJhbGFuY2UFBnN0YXR1cwEPZGVwb3NpdElOVEVSTkFMAw9jYWxsZXJQdWJsaWNLZXkEYXJncwFpBAdwYXltZW50CQCRAwIIBQFpCHBheW1lbnRzAAAEDmFjY291bnRBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQRhcmdzAAAJAQd3cmFwRXJyAQIXaW52YWxpZCBhY2NvdW50IGFkZHJlc3MEBmNrZWNrcwkAzAgCAwkBASEBBQhzaHV0ZG93bgYJAQh0aHJvd0VycgECC25vdCBhbGxvd2VkCQDMCAIJAQttdXN0RmFjdG9yeQEIBQFpBmNhbGxlcgkAzAgCAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQYJAQh0aHJvd0VycgECFTEgcGF5bWVudCBpcyByZXF1aXJlZAkAzAgCAwkAAAIIBQdwYXltZW50B2Fzc2V0SWQFC3VzZHRBc3NldElkBgkBCHRocm93RXJyAQINaW52YWxpZCBhc3NldAkAzAgCAwkAAAIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQ5rUmVxdWVzdFN0YXR1cwEJAQxnZXRSZXF1ZXN0SWQBBQ5hY2NvdW50QWRkcmVzcwUUUkVRVUVTVF9TVEFUVVNfUkVBRFkGCQEIdGhyb3dFcnIBAhRhY2NvdW50IGlzIG5vdCByZWFkeQUDbmlsAwkAAAIFBmNrZWNrcwUGY2tlY2tzBAdhY3Rpb25zCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFDmFjY291bnRBZGRyZXNzCAUHcGF5bWVudAZhbW91bnQIBQdwYXltZW50B2Fzc2V0SWQFA25pbAQOZmFjdG9yeUFjdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMaW50ZWdlckVudHJ5CQDMCAIJAQprRGVwb3NpdGVkAQUOYWNjb3VudEFkZHJlc3MJAMwIAgkAZAIJAQt2YWx1ZU9yRWxzZQIJAQ9kZXBvc2l0ZWRPcHRpb24BBQ5hY2NvdW50QWRkcmVzcwAACAUHcGF5bWVudAZhbW91bnQFA25pbAUDbmlsBQNuaWwJAJQKAgUHYWN0aW9ucwUOZmFjdG9yeUFjdGlvbnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BDmJvcnJvd0lOVEVSTkFMAw9jYWxsZXJQdWJsaWNLZXkEYXJncwFpBA5hY2NvdW50QWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUEYXJncwAACQEHd3JhcEVycgECF2ludmFsaWQgYWNjb3VudCBhZGRyZXNzBBBhc3NldElkUmVxdWVzdGVkCQEMcGFyc2VBc3NldElkAQkAkQMCBQRhcmdzAAEED2Ftb3VudFJlcXVlc3RlZAkBDmVuc3VyZVBvc2l0aXZlAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEJAJEDAgUEYXJncwACCQEHd3JhcEVycgECGGludmFsaWQgcmVxdWVzdGVkIGFtb3VudAIQcmVxdWVzdGVkIGFtb3VudAQVYWNjb3VudE93bmVyUHVibGljS2V5CQEYZ2V0QWNjb3VudE93bmVyUHVibGljS2V5AQUOYWNjb3VudEFkZHJlc3MEC3VzZXJBZGRyZXNzCQCnCAEFD2NhbGxlclB1YmxpY0tleQQGY2tlY2tzCQDMCAIDCQEBIQEFCHNodXRkb3duBgkBCHRocm93RXJyAQILbm90IGFsbG93ZWQJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyCQDMCAIDCQAAAgUPY2FsbGVyUHVibGljS2V5BRVhY2NvdW50T3duZXJQdWJsaWNLZXkGCQEIdGhyb3dFcnIBAiNjYW4gYmUgY2FsbGVkIGJ5IGFjY291bnQgb3duZXIgb25seQUDbmlsAwkAAAIFBmNrZWNrcwUGY2tlY2tzBA1hbW91bnRBc3NldElkCAkBEGdldEFjY291bnRBc3NldHMBBQ5hY2NvdW50QWRkcmVzcwJfMQQJZGVwb3NpdGVkCQEFdG9YMTgCCQELdmFsdWVPckVsc2UCCQEPZGVwb3NpdGVkT3B0aW9uAQUOYWNjb3VudEFkZHJlc3MAAAkBDXBvdzEwRGVjaW1hbHMBBQt1c2R0QXNzZXRJZAQMY3VycmVudFByaWNlCQEFdG9YMTgCCQEPZ2V0Q3VycmVudFByaWNlAQUNYW1vdW50QXNzZXRJZAkBDXBvdzEwRGVjaW1hbHMBBQt1c2R0QXNzZXRJZAQHY3JlZGl0QQkBBXRvWDE4AgkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5mYWN0b3J5QWRkcmVzcwkBB2tDcmVkaXQCBQ5hY2NvdW50QWRkcmVzcwUNYW1vdW50QXNzZXRJZAAACQENcG93MTBEZWNpbWFscwEFDWFtb3VudEFzc2V0SWQEB2NyZWRpdEIJAQV0b1gxOAIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQdrQ3JlZGl0AgUOYWNjb3VudEFkZHJlc3MFC3VzZHRBc3NldElkAAAJAQ1wb3cxMERlY2ltYWxzAQULdXNkdEFzc2V0SWQEC3RvdGFsQ3JlZGl0CQEPY2FsY1RvdGFsQ3JlZGl0AwUHY3JlZGl0QQUHY3JlZGl0QgUMY3VycmVudFByaWNlBAhsZXZlcmFnZQkBBXRvWDE4AgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFDmZhY3RvcnlBZGRyZXNzCQEJa0xldmVyYWdlAQUOYWNjb3VudEFkZHJlc3MJAQd3cmFwRXJyAQIabGV2ZXJhZ2Ugc2hvdWxkIGJlIGRlZmluZWQAAQQTY3JlZGl0QXZhaWxhYmxlVXNkdAkBE2NhbGNDcmVkaXRBdmFpbGFibGUDBQlkZXBvc2l0ZWQFCGxldmVyYWdlBQt0b3RhbENyZWRpdAQPY3JlZGl0QXZhaWxhYmxlAwkAAAIFEGFzc2V0SWRSZXF1ZXN0ZWQFDWFtb3VudEFzc2V0SWQJAQdmcm9tWDE4AgkAvAIDBRNjcmVkaXRBdmFpbGFibGVVc2R0BQxtdWx0MThCaWdJbnQFDGN1cnJlbnRQcmljZQkBDXBvdzEwRGVjaW1hbHMBBQ1hbW91bnRBc3NldElkAwkAAAIFEGFzc2V0SWRSZXF1ZXN0ZWQFC3VzZHRBc3NldElkCQEHZnJvbVgxOAIFE2NyZWRpdEF2YWlsYWJsZVVzZHQJAQ1wb3cxMERlY2ltYWxzAQULdXNkdEFzc2V0SWQJAQh0aHJvd0VycgECGmludmFsaWQgcmVxdWVzdGVkIGFzc2V0IGlkBBBzeW50aGV0aWNBc3NldElkCQEMcGFyc2VBc3NldElkAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQERa1N5bnRoZXRpY0Fzc2V0SWQBBRBhc3NldElkUmVxdWVzdGVkCQEHd3JhcEVycgECMHN5bnRoZXRpYyBhc3NldCBmb3IgcmVxdWVzdGVkIGFzc2V0IGlzIHVuZGVmaW5lZAQMYW1vdW50VG9TZW5kAwkAZwIFD2NyZWRpdEF2YWlsYWJsZQUPYW1vdW50UmVxdWVzdGVkBQ9hbW91bnRSZXF1ZXN0ZWQJAQh0aHJvd0VycgEJAKwCAgITY3JlZGl0IGF2YWlsYWJsZSA9IAkApAMBBQ9jcmVkaXRBdmFpbGFibGUEDmZhY3RvcnlBY3Rpb25zCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCDGludGVnZXJFbnRyeQkAzAgCCQEHa0NyZWRpdAIFDmFjY291bnRBZGRyZXNzBRBhc3NldElkUmVxdWVzdGVkCQDMCAIJAGQCCQELdmFsdWVPckVsc2UCCQEMY3JlZGl0T3B0aW9uAgUOYWNjb3VudEFkZHJlc3MFEGFzc2V0SWRSZXF1ZXN0ZWQAAAUMYW1vdW50VG9TZW5kBQNuaWwFA25pbAkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAg10cmFuc2ZlckFzc2V0CQDMCAIIBQ5hY2NvdW50QWRkcmVzcwVieXRlcwkAzAgCBQxhbW91bnRUb1NlbmQJAMwIAgUQc3ludGhldGljQXNzZXRJZAUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwJAMwIAgUOZmFjdG9yeUFjdGlvbnMJAMwIAgUPY3JlZGl0QXZhaWxhYmxlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4QAWkBBGluaXQBEWZhY3RvcnlBZGRyZXNzU3RyBAtjaGVja0NhbGxlcgkBCG11c3RUaGlzAQgFAWkGY2FsbGVyAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFD2tGYWN0b3J5QWRkcmVzcwURZmFjdG9yeUFkZHJlc3NTdHIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ5yZXF1ZXN0QWNjb3VudAIPY2FsbGVyUHVibGljS2V5BGFyZ3MEBmNrZWNrcwkAzAgCAwkBASEBBQhzaHV0ZG93bgYJAQh0aHJvd0VycgECC25vdCBhbGxvd2VkCQDMCAIJAQttdXN0RmFjdG9yeQEIBQFpBmNhbGxlcgUDbmlsAwkAAAIFBmNrZWNrcwUGY2tlY2tzBBBhbW91bnRBc3NldElkU3RyCQCRAwIFBGFyZ3MAAAQPcHJpY2VBc3NldElkU3RyCQCRAwIFBGFyZ3MAAQQIbGV2ZXJhZ2UJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBCQCRAwIFBGFyZ3MAAgkBB3dyYXBFcnIBAhBpbnZhbGlkIGxldmVyYWdlBAt1c2VyQWRkcmVzcwkApwgBBQ9jYWxsZXJQdWJsaWNLZXkECXJlcXVlc3RJZAkA9wMBCQDLAQIJAMsBAggFC3VzZXJBZGRyZXNzBWJ5dGVzCQDZBAEFEGFtb3VudEFzc2V0SWRTdHIJANkEAQUPcHJpY2VBc3NldElkU3RyBA1hbW91bnRBc3NldElkCQEMcGFyc2VBc3NldElkAQUQYW1vdW50QXNzZXRJZFN0cgQMcHJpY2VBc3NldElkCQEMcGFyc2VBc3NldElkAQUPcHJpY2VBc3NldElkU3RyBBJ1c2VyUmVxdWVzdHNOdW1iZXIJAGkCCQCxAgEJARBrUmVxdWVzdHNCeU93bmVyAQULdXNlckFkZHJlc3MFDXF1ZXVlSXRlbVNpemUEBmNoZWNrcwkAzAgCAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQYJAQh0aHJvd0VycgECFTEgcGF5bWVudCBpcyByZXF1aXJlZAkAzAgCAwkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUEdW5pdAYJAQh0aHJvd0VycgECDWludmFsaWQgYXNzZXQJAMwIAgMJAAACCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAkBDHJld2FyZEFtb3VudAAGCQEIdGhyb3dFcnIBAg5pbnZhbGlkIGFtb3VudAkAzAgCAwkBC3BhaXJBbGxvd2VkAgUNYW1vdW50QXNzZXRJZAUMcHJpY2VBc3NldElkBgkBCHRocm93RXJyAQITcGFpciBpcyBub3QgYWxsb3dlZAkAzAgCAwkAAAIJAJoIAgUOZmFjdG9yeUFkZHJlc3MJAQ5rUmVxdWVzdFN0YXR1cwEFCXJlcXVlc3RJZAUEdW5pdAYJAQh0aHJvd0VycgECGWFjY291bnQgaXMgYWxyZWFkeSBleGlzdHMJAMwIAgMJAGYCCQENYWNjb3VudHNMaW1pdAAFEnVzZXJSZXF1ZXN0c051bWJlcgYJAQh0aHJvd0VycgEJAKwCAgISYWNjb3VudHMgbGltaXQgaXMgCQCkAwEJAQ1hY2NvdW50c0xpbWl0AAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA0kdDAxODYyODIwMDgzCQCUCgIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUOZmFjdG9yeUFkZHJlc3MJAQxyZXdhcmRBbW91bnQABQR1bml0BQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMaW50ZWdlckVudHJ5CQDMCAIJAQ5rUmVxdWVzdFN0YXR1cwEFCXJlcXVlc3RJZAkAzAgCBRRSRVFVRVNUX1NUQVRVU19FTVBUWQUDbmlsBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILYmluYXJ5RW50cnkJAMwIAgkBDmtSZXF1ZXN0c1F1ZXVlAAkAzAgCCQDLAQIJAQ1yZXF1ZXN0c1F1ZXVlAAUJcmVxdWVzdElkBQNuaWwFA25pbAkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAgxpbnRlZ2VyRW50cnkJAMwIAgkBEGtSZXF1ZXN0TGV2ZXJhZ2UBBQlyZXF1ZXN0SWQJAMwIAgUIbGV2ZXJhZ2UFA25pbAUDbmlsBQNuaWwEB2FjdGlvbnMIBQ0kdDAxODYyODIwMDgzAl8xBA5mYWN0b3J5QWN0aW9ucwgFDSR0MDE4NjI4MjAwODMCXzIJAJQKAgUHYWN0aW9ucwkAzggCBQ5mYWN0b3J5QWN0aW9ucwkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAgtiaW5hcnlFbnRyeQkAzAgCCQEWa1JlcXVlc3RPd25lclB1YmxpY0tleQEFCXJlcXVlc3RJZAkAzAgCBQ9jYWxsZXJQdWJsaWNLZXkFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC2JpbmFyeUVudHJ5CQDMCAIJARBrUmVxdWVzdHNCeU93bmVyAQULdXNlckFkZHJlc3MJAMwIAgkAywECCQEPcmVxdWVzdHNCeU93bmVyAQULdXNlckFkZHJlc3MFCXJlcXVlc3RJZAUDbmlsBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILc3RyaW5nRW50cnkJAMwIAgkBFWtSZXF1ZXN0QW1vdW50QXNzZXRJZAEFCXJlcXVlc3RJZAkAzAgCBRBhbW91bnRBc3NldElkU3RyBQNuaWwFA25pbAkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAgtzdHJpbmdFbnRyeQkAzAgCCQEUa1JlcXVlc3RQcmljZUFzc2V0SWQBBQlyZXF1ZXN0SWQJAMwIAgUPcHJpY2VBc3NldElkU3RyBQNuaWwFA25pbAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCmFkZEFjY291bnQCD2NhbGxlclB1YmxpY0tleQRhcmdzBAZja2Vja3MJAMwIAgMJAQEhAQUIc2h1dGRvd24GCQEIdGhyb3dFcnIBAgtub3QgYWxsb3dlZAkAzAgCCQELbXVzdEZhY3RvcnkBCAUBaQZjYWxsZXIFA25pbAMJAAACBQZja2Vja3MFBmNrZWNrcwQQY3JlYXRvclB1YmxpY0tleQkA2QQBCQCRAwIFBGFyZ3MAAAQQYWNjb3VudFB1YmxpY0tleQUPY2FsbGVyUHVibGljS2V5BA5hY2NvdW50QWRkcmVzcwkApwgBBQ9jYWxsZXJQdWJsaWNLZXkEDmNyZWF0b3JBZGRyZXNzCQCnCAEFEGNyZWF0b3JQdWJsaWNLZXkEBmNoZWNrcwkAzAgCAwkAAAIJAJwIAgUOZmFjdG9yeUFkZHJlc3MJARhrQWNjb3VudENyZWF0b3JQdWJsaWNLZXkBBQ5hY2NvdW50QWRkcmVzcwUEdW5pdAYJAQh0aHJvd0VycgECGWFjY291bnQgaXMgYWxyZWFkeSBleGlzdHMJAMwIAgMEByRtYXRjaDAJAPEHAQUOYWNjb3VudEFkZHJlc3MDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAkAAAIFAWIJAPEVAQkBDWFjY291bnRTY3JpcHQABwYJAQh0aHJvd0VycgECDmludmFsaWQgc2NyaXB0BQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDSR0MDIxMzM4MjI2NDkDCQAAAgkAyAEBCQENcmVxdWVzdHNRdWV1ZQAAAAkAlAoCBQNuaWwFA25pbAQJcmVxdWVzdElkCQDJAQIJAQ1yZXF1ZXN0c1F1ZXVlAAUNcXVldWVJdGVtU2l6ZQQIbGV2ZXJhZ2UJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQ5mYWN0b3J5QWRkcmVzcwkBEGtSZXF1ZXN0TGV2ZXJhZ2UBBQlyZXF1ZXN0SWQJAQd3cmFwRXJyAQIfcmVxdWVzdCdzIGxldmVyYWdlIGlzIHVuZGVmaW5lZAkAlAoCBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMaW50ZWdlckVudHJ5CQDMCAIJAQ5rUmVxdWVzdFN0YXR1cwEFCXJlcXVlc3RJZAkAzAgCBRRSRVFVRVNUX1NUQVRVU19SRUFEWQUDbmlsBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILYmluYXJ5RW50cnkJAMwIAgkBHGtSZXF1ZXN0SWRUb0FjY291bnRQdWJsaWNLZXkBBQlyZXF1ZXN0SWQJAMwIAgUQYWNjb3VudFB1YmxpY0tleQUDbmlsBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILYmluYXJ5RW50cnkJAMwIAgkBDmtSZXF1ZXN0c1F1ZXVlAAkAzAgCCQDKAQIJAQ1yZXF1ZXN0c1F1ZXVlAAUNcXVldWVJdGVtU2l6ZQUDbmlsBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILc3RyaW5nRW50cnkJAMwIAgkBGmtBY2NvdW50QWRkcmVzc1RvUmVxdWVzdElkAQUOYWNjb3VudEFkZHJlc3MJAMwIAgkA2AQBBQlyZXF1ZXN0SWQFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCDXRyYW5zZmVyV2F2ZXMJAMwIAggFDmNyZWF0b3JBZGRyZXNzBWJ5dGVzCQDMCAIJAQxyZXdhcmRBbW91bnQABQNuaWwFA25pbAkAzAgCCQD8BwQFDmZhY3RvcnlBZGRyZXNzAgxpbnRlZ2VyRW50cnkJAMwIAgkBCWtMZXZlcmFnZQEFDmFjY291bnRBZGRyZXNzCQDMCAIFCGxldmVyYWdlBQNuaWwFA25pbAUDbmlsBAdhY3Rpb25zCAUNJHQwMjEzMzgyMjY0OQJfMQQOZmFjdG9yeUFjdGlvbnMIBQ0kdDAyMTMzODIyNjQ5Al8yCQCUCgIFB2FjdGlvbnMJAM4IAgUOZmFjdG9yeUFjdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILYmluYXJ5RW50cnkJAMwIAgkBGGtBY2NvdW50Q3JlYXRvclB1YmxpY0tleQEFDmFjY291bnRBZGRyZXNzCQDMCAIFEGNyZWF0b3JQdWJsaWNLZXkFA25pbAUDbmlsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEId2l0aGRyYXcCD2NhbGxlclB1YmxpY0tleQRhcmdzBAZjaGVja3MJAMwIAgMJAQEhAQUIc2h1dGRvd24GCQEIdGhyb3dFcnIBAgtub3QgYWxsb3dlZAkAzAgCCQELbXVzdEZhY3RvcnkBCAUBaQZjYWxsZXIFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQLdXNlckFkZHJlc3MJAKcIAQUPY2FsbGVyUHVibGljS2V5BA5hY2NvdW50QWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUEYXJncwAACQEHd3JhcEVycgECF2ludmFsaWQgYWNjb3VudCBhZGRyZXNzBAZhbW91bnQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBCQCRAwIFBGFyZ3MAAQkBB3dyYXBFcnIBAg5pbnZhbGlkIGFtb3VudAQHYXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEJAJEDAgUEYXJncwACBAtpbnZvY2F0aW9ucwkAzAgCCQD8BwQFDmFjY291bnRBZGRyZXNzAg10cmFuc2ZlckFzc2V0CQDMCAIIBQt1c2VyQWRkcmVzcwVieXRlcwkAzAgCBQZhbW91bnQJAMwIAgUHYXNzZXRJZAUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFC2ludm9jYXRpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBB2RlcG9zaXQCD2NhbGxlclB1YmxpY0tleQRhcmdzBA0kdDAyMzY3MDIzNzQzCQEPZGVwb3NpdElOVEVSTkFMAwUPY2FsbGVyUHVibGljS2V5BQRhcmdzBQFpBAdhY3Rpb25zCAUNJHQwMjM2NzAyMzc0MwJfMQQOZmFjdG9yeUFjdGlvbnMIBQ0kdDAyMzY3MDIzNzQzAl8yCQCUCgIFB2FjdGlvbnMFDmZhY3RvcnlBY3Rpb25zAWkBBmJvcnJvdwIPY2FsbGVyUHVibGljS2V5BGFyZ3MEDSR0MDIzODk4MjM5NzAJAQ5ib3Jyb3dJTlRFUk5BTAMFD2NhbGxlclB1YmxpY0tleQUEYXJncwUBaQQHYWN0aW9ucwgFDSR0MDIzODk4MjM5NzACXzEEDmZhY3RvcnlBY3Rpb25zCAUNJHQwMjM4OTgyMzk3MAJfMgkAlAoCBQdhY3Rpb25zBQ5mYWN0b3J5QWN0aW9ucwFpARBkZXBvc2l0QW5kQm9ycm93Ag9jYWxsZXJQdWJsaWNLZXkEYXJncwQOYWNjb3VudEFkZHJlc3MJAJEDAgUEYXJncwAABA0kdDAyNDE2NjI0MjY1CQEPZGVwb3NpdElOVEVSTkFMAwUPY2FsbGVyUHVibGljS2V5CQDMCAIFDmFjY291bnRBZGRyZXNzBQNuaWwFAWkEDmRlcG9zaXRBY3Rpb25zCAUNJHQwMjQxNjYyNDI2NQJfMQQVZGVwb3NpdEZhY3RvcnlBY3Rpb25zCAUNJHQwMjQxNjYyNDI2NQJfMgQNJHQwMjQyNjgyNDM1MgkBDmJvcnJvd0lOVEVSTkFMAwUPY2FsbGVyUHVibGljS2V5BQRhcmdzBQFpBA1ib3Jyb3dBY3Rpb25zCAUNJHQwMjQyNjgyNDM1MgJfMQQUYm9ycm93RmFjdG9yeUFjdGlvbnMIBQ0kdDAyNDI2ODI0MzUyAl8yCQCUCgIJAM4IAgUOZGVwb3NpdEFjdGlvbnMFDWJvcnJvd0FjdGlvbnMJAM4IAgUVZGVwb3NpdEZhY3RvcnlBY3Rpb25zBRRib3Jyb3dGYWN0b3J5QWN0aW9ucwFpAQVyZXBheQIPY2FsbGVyUHVibGljS2V5BGFyZ3MEBmNrZWNrcwkAzAgCAwkBASEBBQhzaHV0ZG93bgYJAQh0aHJvd0VycgECC25vdCBhbGxvd2VkCQDMCAIJAQttdXN0RmFjdG9yeQEIBQFpBmNhbGxlcgUDbmlsAwkAAAIFBmNrZWNrcwUGY2tlY2tzCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARBzZXRQYWlyQWxsb3dhbmNlAg9jYWxsZXJQdWJsaWNLZXkEYXJncwQGY2tlY2tzCQDMCAIDCQEBIQEFCHNodXRkb3duBgkBCHRocm93RXJyAQILbm90IGFsbG93ZWQJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyCQDMCAIJAQltdXN0QWRtaW4BBQ9jYWxsZXJQdWJsaWNLZXkFA25pbAMJAAACBQZja2Vja3MFBmNrZWNrcwQQYW1vdW50QXNzZXRJZFN0cgkAkQMCBQRhcmdzAAAED3ByaWNlQXNzZXRJZFN0cgkAkQMCBQRhcmdzAAEECGFsbG93U3RyCQCRAwIFBGFyZ3MAAgQNYW1vdW50QXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEFEGFtb3VudEFzc2V0SWRTdHIEDHByaWNlQXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEFD3ByaWNlQXNzZXRJZFN0cgQFYWxsb3cJAAACBQhhbGxvd1N0cgIEdHJ1ZQQLaW52b2NhdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMYm9vbGVhbkVudHJ5CQDMCAIJAQxrUGFpckFsbG93ZWQCBQ1hbW91bnRBc3NldElkBQxwcmljZUFzc2V0SWQJAMwIAgUFYWxsb3cFA25pbAUDbmlsBQNuaWwJAJQKAgUDbmlsBQtpbnZvY2F0aW9ucwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARFhZGRTeW50aGV0aWNBc3NldAIPY2FsbGVyUHVibGljS2V5BGFyZ3MEC2Jhc2VBc3NldElkCQEMcGFyc2VBc3NldElkAQkAkQMCBQRhcmdzAAAEEHN5bnRoZXRpY0Fzc2V0SWQJAQxwYXJzZUFzc2V0SWQBCQCRAwIFBGFyZ3MAAQQGY2tlY2tzCQDMCAIDCQEBIQEFCHNodXRkb3duBgkBCHRocm93RXJyAQILbm90IGFsbG93ZWQJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyCQDMCAIJAQltdXN0QWRtaW4BBQ9jYWxsZXJQdWJsaWNLZXkJAMwIAgMJAAACCQCdCAIFDmZhY3RvcnlBZGRyZXNzCQERa1N5bnRoZXRpY0Fzc2V0SWQBBQtiYXNlQXNzZXRJZAUEdW5pdAYJAQh0aHJvd0VycgECEmludmFsaWQgYmFzZSBhc3NldAkAzAgCAwkAAAIJAJ0IAgUOZmFjdG9yeUFkZHJlc3MJAQxrQmFzZUFzc2V0SWQBBRBzeW50aGV0aWNBc3NldElkBQR1bml0BgkBCHRocm93RXJyAQIXaW52YWxpZCBzeW50aGV0aWMgYXNzZXQFA25pbAMJAAACBQZja2Vja3MFBmNrZWNrcwQLaW52b2NhdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILc3RyaW5nRW50cnkJAMwIAgkBEWtTeW50aGV0aWNBc3NldElkAQULYmFzZUFzc2V0SWQJAMwIAgkBD2Fzc2V0SWRUb1N0cmluZwEFEHN5bnRoZXRpY0Fzc2V0SWQFA25pbAUDbmlsCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC3N0cmluZ0VudHJ5CQDMCAIJAQxrQmFzZUFzc2V0SWQBBRBzeW50aGV0aWNBc3NldElkCQDMCAIJAQ9hc3NldElkVG9TdHJpbmcBBQtiYXNlQXNzZXRJZAUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFC2ludm9jYXRpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCmRvU2h1dGRvd24CD2NhbGxlclB1YmxpY0tleQRhcmdzBAZjaGVja3MJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyCQDMCAIJAQltdXN0QWRtaW4BBQ9jYWxsZXJQdWJsaWNLZXkFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQLaW52b2NhdGlvbnMJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwIMYm9vbGVhbkVudHJ5CQDMCAIFCWtTaHV0ZG93bgkAzAgCBgUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFC2ludm9jYXRpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBFmdldEFjY291bnRJbmZvUkVBRE9OTFkCD2NhbGxlclB1YmxpY0tleQRhcmdzBAZjaGVja3MJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDmFjY291bnRBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQRhcmdzAAAJAQd3cmFwRXJyAQIXaW52YWxpZCBhY2NvdW50IGFkZHJlc3MEBGRhdGEJARZnZXRBY2NvdW50SW5mb0ludGVybmFsAQUOYWNjb3VudEFkZHJlc3MJAJQKAgUDbmlsBQRkYXRhCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBE2dldFVzZXJJbmZvUkVBRE9OTFkCD2NhbGxlclB1YmxpY0tleQRhcmdzBAZjaGVja3MJAMwIAgkBC211c3RGYWN0b3J5AQgFAWkGY2FsbGVyBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEC3VzZXJBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQRhcmdzAAAJAQd3cmFwRXJyAQIUaW52YWxpZCB1c2VyIGFkZHJlc3MEDHVzZXJSZXF1ZXN0cwkBC3ZhbHVlT3JFbHNlAgkAnAgCBQ5mYWN0b3J5QWRkcmVzcwkBEGtSZXF1ZXN0c0J5T3duZXIBBQt1c2VyQWRkcmVzcwEABBJ1c2VyUmVxdWVzdHNOdW1iZXIJAGkCCQDIAQEFDHVzZXJSZXF1ZXN0cwUNcXVldWVJdGVtU2l6ZQoBD2dldEFjY291bnRzRGF0YQIDYWNjBWNvdW50BA0kdDAyNzI4NTI3MzI3BQNhY2MEC2FjY0RhdGFMaXN0CAUNJHQwMjcyODUyNzMyNwJfMQQIcmF3Qnl0ZXMIBQ0kdDAyNzI4NTI3MzI3Al8yBAdtYXhTaXplCAUNJHQwMjcyODUyNzMyNwJfMwMJAGYCBQdtYXhTaXplBQVjb3VudAQJcmVxdWVzdElkCQDJAQIFCHJhd0J5dGVzBQ1xdWV1ZUl0ZW1TaXplBAtuZXdSYXdCeXRlcwkAygECBQhyYXdCeXRlcwUNcXVldWVJdGVtU2l6ZQQQYWNjb3VudFB1YmxpY0tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCcCAIFDmZhY3RvcnlBZGRyZXNzCQEca1JlcXVlc3RJZFRvQWNjb3VudFB1YmxpY0tleQEFCXJlcXVlc3RJZAIma1JlcXVlc3RJZFRvQWNjb3VudFB1YmxpY0tleSBub3QgZm91bmQEDmFjY291bnRBZGRyZXNzCQCnCAEFEGFjY291bnRQdWJsaWNLZXkEBGRhdGEJARZnZXRBY2NvdW50SW5mb0ludGVybmFsAQUOYWNjb3VudEFkZHJlc3MJAJUKAwkAzQgCBQthY2NEYXRhTGlzdAUEZGF0YQULbmV3UmF3Qnl0ZXMFB21heFNpemUFA2FjYwQNJHQwMjc4MzEyNzkzNgoAAiRsBQpJTkRFWF9MSVNUCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlQoDBQNuaWwFDHVzZXJSZXF1ZXN0cwUSdXNlclJlcXVlc3RzTnVtYmVyCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQ9nZXRBY2NvdW50c0RhdGECBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAQLYWNjRGF0YUxpc3QIBQ0kdDAyNzgzMTI3OTM2Al8xBAJfYQgFDSR0MDI3ODMxMjc5MzYCXzIEAl9iCAUNJHQwMjc4MzEyNzkzNgJfMwkAlAoCBQNuaWwFC2FjY0RhdGFMaXN0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBG2dldFBhaXJTZXR0aW5nc0luZm9SRUFET05MWQIPY2FsbGVyUHVibGljS2V5BGFyZ3MEC2Ftb3VudEFzc2V0CQEMcGFyc2VBc3NldElkAQkAkQMCBQRhcmdzAAAECnByaWNlQXNzZXQJAQxwYXJzZUFzc2V0SWQBCQCRAwIFBGFyZ3MAAQQKcHJpY2VzTGlzdAkBEWdldFBhaXJQcmljZXNMaXN0AgULYW1vdW50QXNzZXQFCnByaWNlQXNzZXQKAQ9nZXRQYWlyU2V0dGluZ3MCA2FjYwxwcmljZXNTdHJpbmcEC3NldHRpbmdzS2V5CQEQa1BhaXJTZXR0aW5nc0tleQMFC2Ftb3VudEFzc2V0BQpwcmljZUFzc2V0BQxwcmljZXNTdHJpbmcEE3NldHRpbmdzU3RyaW5nVmFsdWUJARFAZXh0ck5hdGl2ZSgxMDUzKQIFDmZhY3RvcnlBZGRyZXNzBQtzZXR0aW5nc0tleQQFc0xpc3QJALUJAgUTc2V0dGluZ3NTdHJpbmdWYWx1ZQUJc2VwYXJhdG9yBAVwcmljZQkAtgkBBQxwcmljZXNTdHJpbmcEC21heExldmVyYWdlCQC2CQEJAJEDAgUFc0xpc3QAAQQNaW5pdGlhbE1hcmdpbgkAtgkBCQCRAwIFBXNMaXN0AAIEEW1haW50ZW5hbmNlTWFyZ2luCQC2CQEJAJEDAgUFc0xpc3QAAwkAzQgCBQNhY2MJAJYKBAUFcHJpY2UFC21heExldmVyYWdlBQ1pbml0aWFsTWFyZ2luBRFtYWludGVuYW5jZU1hcmdpbgQEZGF0YQoAAiRsBQpwcmljZXNMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQ9nZXRQYWlyU2V0dGluZ3MCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAkAlAoCBQNuaWwFBGRhdGEBaQEQZWRpdFBhaXJTZXR0aW5ncwIPY2FsbGVyUHVibGljS2V5BGFyZ3MEBmNoZWNrcwkAzAgCCQELbXVzdEZhY3RvcnkBCAUBaQZjYWxsZXIJAMwIAgkBCW11c3RBZG1pbgEFD2NhbGxlclB1YmxpY0tleQUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBAthbW91bnRBc3NldAkBDHBhcnNlQXNzZXRJZAEJAJEDAgUEYXJncwAABApwcmljZUFzc2V0CQEMcGFyc2VBc3NldElkAQkAkQMCBQRhcmdzAAEEBXByaWNlCQCRAwIFBGFyZ3MAAgQLbWF4TGV2ZXJhZ2UJAJEDAgUEYXJncwADBA1pbml0aWFsTWFyZ2luCQCRAwIFBGFyZ3MABAQRbWFpbnRlbmFuY2VNYXJnaW4JAJEDAgUEYXJncwAFBBFwYWlyUHJpY2VzTGlzdEtleQkBEmtQYWlyUHJpY2VzTGlzdEtleQIFC2Ftb3VudEFzc2V0BQpwcmljZUFzc2V0BAtzZXR0aW5nc0tleQkBEGtQYWlyU2V0dGluZ3NLZXkDBQthbW91bnRBc3NldAUKcHJpY2VBc3NldAUFcHJpY2UECnByaWNlc0xpc3QJARFnZXRQYWlyUHJpY2VzTGlzdAIFC2Ftb3VudEFzc2V0BQpwcmljZUFzc2V0BAduZXdMaXN0BAckbWF0Y2gwCQDPCAIFCnByaWNlc0xpc3QFBXByaWNlAwkAAQIFByRtYXRjaDACA0ludAQDaW5kBQckbWF0Y2gwBQpwcmljZXNMaXN0CQDNCAIFCnByaWNlc0xpc3QFBXByaWNlBAZjaGVjazIJAMwIAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEFBXByaWNlCQEHd3JhcEVycgECGXByaWNlIHZhbHVlIGlzIG5vdCBhbiBJbnQJAMwIAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBQttYXhMZXZlcmFnZQkBB3dyYXBFcnIBAh9tYXhMZXZlcmFnZSB2YWx1ZSBpcyBub3QgYW4gSW50CQDMCAIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgUNaW5pdGlhbE1hcmdpbgkBB3dyYXBFcnIBAiFpbml0aWFsTWFyZ2luIHZhbHVlIGlzIG5vdCBhbiBJbnQJAMwIAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBRFtYWludGVuYW5jZU1hcmdpbgkBB3dyYXBFcnIBAiVtYWludGVuYW5jZU1hcmdpbiB2YWx1ZSBpcyBub3QgYW4gSW50CQDMCAIDCQBnAgAUCQCQAwEFB25ld0xpc3QGCQEIdGhyb3dFcnIBAiJleGNlZWRlZCBtYXggcHJpY2VzIGxpc3Qgc2l6ZSAoMjApBQNuaWwDCQAAAgUGY2hlY2syBQZjaGVjazIEEHBhaXJTZXR0aW5nVmFsdWUJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgULbWF4TGV2ZXJhZ2UJAMwIAgUNaW5pdGlhbE1hcmdpbgkAzAgCBRFtYWludGVuYW5jZU1hcmdpbgUDbmlsBQlzZXBhcmF0b3IEC2ludm9jYXRpb25zCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC3N0cmluZ0VudHJ5CQDMCAIJARJrUGFpclByaWNlc0xpc3RLZXkCBQthbW91bnRBc3NldAUKcHJpY2VBc3NldAkAzAgCCQC5CQIFB25ld0xpc3QFCXNlcGFyYXRvcgUDbmlsBQNuaWwJAMwIAgkA/AcEBQ5mYWN0b3J5QWRkcmVzcwILc3RyaW5nRW50cnkJAMwIAgkBEGtQYWlyU2V0dGluZ3NLZXkDBQthbW91bnRBc3NldAUKcHJpY2VBc3NldAUFcHJpY2UJAMwIAgUQcGFpclNldHRpbmdWYWx1ZQUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFC2ludm9jYXRpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEmRlbGV0ZVBhaXJTZXR0aW5ncwIPY2FsbGVyUHVibGljS2V5BGFyZ3MEBmNoZWNrcwkAzAgCCQELbXVzdEZhY3RvcnkBCAUBaQZjYWxsZXIJAMwIAgkBCW11c3RBZG1pbgEFD2NhbGxlclB1YmxpY0tleQUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBAthbW91bnRBc3NldAkBDHBhcnNlQXNzZXRJZAEJAJEDAgUEYXJncwAABApwcmljZUFzc2V0CQEMcGFyc2VBc3NldElkAQkAkQMCBQRhcmdzAAEEBXByaWNlCQCRAwIFBGFyZ3MAAgQLc2V0dGluZ3NLZXkJARBrUGFpclNldHRpbmdzS2V5AwULYW1vdW50QXNzZXQFCnByaWNlQXNzZXQFBXByaWNlBBFwYWlyUHJpY2VzTGlzdEtleQkBEmtQYWlyUHJpY2VzTGlzdEtleQIFC2Ftb3VudEFzc2V0BQpwcmljZUFzc2V0BApwcmljZXNMaXN0CQERZ2V0UGFpclByaWNlc0xpc3QCBQthbW91bnRBc3NldAUKcHJpY2VBc3NldAQHbmV3TGlzdAQHJG1hdGNoMAkAzwgCBQpwcmljZXNMaXN0BQVwcmljZQMJAAECBQckbWF0Y2gwAgNJbnQEA2luZAUHJG1hdGNoMAkA0QgCBQpwcmljZXNMaXN0BQNpbmQFCnByaWNlc0xpc3QEC2ludm9jYXRpb25zCQDMCAIJAPwHBAUOZmFjdG9yeUFkZHJlc3MCC2RlbGV0ZUVudHJ5CQDMCAIFC3NldHRpbmdzS2V5BQNuaWwFA25pbAkAzAgCAwkAAAIJAJADAQUHbmV3TGlzdAAACQD8BwQFDmZhY3RvcnlBZGRyZXNzAgtkZWxldGVFbnRyeQkAzAgCCQESa1BhaXJQcmljZXNMaXN0S2V5AgULYW1vdW50QXNzZXQFCnByaWNlQXNzZXQFA25pbAUDbmlsCQD8BwQFDmZhY3RvcnlBZGRyZXNzAgtzdHJpbmdFbnRyeQkAzAgCCQESa1BhaXJQcmljZXNMaXN0S2V5AgULYW1vdW50QXNzZXQFCnByaWNlQXNzZXQJAMwIAgkAuQkCBQduZXdMaXN0BQlzZXBhcmF0b3IFA25pbAUDbmlsBQNuaWwJAJQKAgUDbmlsBQtpbnZvY2F0aW9ucwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECdHgBBnZlcmlmeQADAwkBCWlzRGVmaW5lZAEFFGZhY3RvcnlBZGRyZXNzT3B0aW9uCQEJaXNEZWZpbmVkAQkAnQgCBQ5mYWN0b3J5QWRkcmVzcwUJa011bHRpc2lnBwQHJG1hdGNoMAkAnQgCBQ5mYWN0b3J5QWRkcmVzcwUJa011bHRpc2lnAwkAAQIFByRtYXRjaDACBlN0cmluZwQIbXVsdGlzaWcFByRtYXRjaDAECXN0YXR1c0tleQkBB2tTdGF0dXMCCQClCAEFBHRoaXMJANgEAQgFAnR4AmlkBAZzdGF0dXMJAQt2YWx1ZU9yRWxzZQIJAJsIAgkBEUBleHRyTmF0aXZlKDEwNjIpAQUIbXVsdGlzaWcFCXN0YXR1c0tleQcFBnN0YXR1cwcJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXmrzGUl", "chainId": 84, "height": 3255739, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HXTKVZ667TfaWfnxf93X96BJni83XQPZ4Qtke3mU5m2F Next: A7YETDhSCzJGMoQUktAxZAMXJLmVrnG4dmGnquGdajnc Diff:
OldNewDifferences
501501 else throwErr("invalid script")]
502502 if ((checks == checks))
503503 then {
504- let $t02133822632 = if ((size(requestsQueue()) == 0))
505- then $Tuple2(throwErr("requests is empty"), nil)
504+ let $t02133822649 = if ((size(requestsQueue()) == 0))
505+ then $Tuple2(nil, nil)
506506 else {
507507 let requestId = take(requestsQueue(), queueItemSize)
508508 let leverage = valueOrErrorMessage(getInteger(factoryAddress, kRequestLeverage(requestId)), wrapErr("request's leverage is undefined"))
509509 $Tuple2(nil, [invoke(factoryAddress, "integerEntry", [kRequestStatus(requestId), REQUEST_STATUS_READY], nil), invoke(factoryAddress, "binaryEntry", [kRequestIdToAccountPublicKey(requestId), accountPublicKey], nil), invoke(factoryAddress, "binaryEntry", [kRequestsQueue(), drop(requestsQueue(), queueItemSize)], nil), invoke(factoryAddress, "stringEntry", [kAccountAddressToRequestId(accountAddress), toBase58String(requestId)], nil), invoke(factoryAddress, "transferWaves", [creatorAddress.bytes, rewardAmount()], nil), invoke(factoryAddress, "integerEntry", [kLeverage(accountAddress), leverage], nil)])
510510 }
511- let actions = $t02133822632._1
512- let factoryActions = $t02133822632._2
511+ let actions = $t02133822649._1
512+ let factoryActions = $t02133822649._2
513513 $Tuple2(actions, (factoryActions ++ [invoke(factoryAddress, "binaryEntry", [kAccountCreatorPublicKey(accountAddress), creatorPublicKey], nil)]))
514514 }
515515 else throw("Strict value is not equal to itself.")
540540
541541 @Callable(i)
542542 func deposit (callerPublicKey,args) = {
543- let $t02365323726 = depositINTERNAL(callerPublicKey, args, i)
544- let actions = $t02365323726._1
545- let factoryActions = $t02365323726._2
543+ let $t02367023743 = depositINTERNAL(callerPublicKey, args, i)
544+ let actions = $t02367023743._1
545+ let factoryActions = $t02367023743._2
546546 $Tuple2(actions, factoryActions)
547547 }
548548
550550
551551 @Callable(i)
552552 func borrow (callerPublicKey,args) = {
553- let $t02388123953 = borrowINTERNAL(callerPublicKey, args, i)
554- let actions = $t02388123953._1
555- let factoryActions = $t02388123953._2
553+ let $t02389823970 = borrowINTERNAL(callerPublicKey, args, i)
554+ let actions = $t02389823970._1
555+ let factoryActions = $t02389823970._2
556556 $Tuple2(actions, factoryActions)
557557 }
558558
561561 @Callable(i)
562562 func depositAndBorrow (callerPublicKey,args) = {
563563 let accountAddress = args[0]
564- let $t02414924248 = depositINTERNAL(callerPublicKey, [accountAddress], i)
565- let depositActions = $t02414924248._1
566- let depositFactoryActions = $t02414924248._2
567- let $t02425124335 = borrowINTERNAL(callerPublicKey, args, i)
568- let borrowActions = $t02425124335._1
569- let borrowFactoryActions = $t02425124335._2
564+ let $t02416624265 = depositINTERNAL(callerPublicKey, [accountAddress], i)
565+ let depositActions = $t02416624265._1
566+ let depositFactoryActions = $t02416624265._2
567+ let $t02426824352 = borrowINTERNAL(callerPublicKey, args, i)
568+ let borrowActions = $t02426824352._1
569+ let borrowFactoryActions = $t02426824352._2
570570 $Tuple2((depositActions ++ borrowActions), (depositFactoryActions ++ borrowFactoryActions))
571571 }
572572
662662 let userRequests = valueOrElse(getBinary(factoryAddress, kRequestsByOwner(userAddress)), base58'')
663663 let userRequestsNumber = (size(userRequests) / queueItemSize)
664664 func getAccountsData (acc,count) = {
665- let $t02726827310 = acc
666- let accDataList = $t02726827310._1
667- let rawBytes = $t02726827310._2
668- let maxSize = $t02726827310._3
665+ let $t02728527327 = acc
666+ let accDataList = $t02728527327._1
667+ let rawBytes = $t02728527327._2
668+ let maxSize = $t02728527327._3
669669 if ((maxSize > count))
670670 then {
671671 let requestId = take(rawBytes, queueItemSize)
678678 else acc
679679 }
680680
681- let $t02781427919 = {
681+ let $t02783127936 = {
682682 let $l = INDEX_LIST
683683 let $s = size($l)
684684 let $acc0 = $Tuple3(nil, userRequests, userRequestsNumber)
692692
693693 $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)
694694 }
695- let accDataList = $t02781427919._1
696- let _a = $t02781427919._2
697- let _b = $t02781427919._3
695+ let accDataList = $t02783127936._1
696+ let _a = $t02783127936._2
697+ let _b = $t02783127936._3
698698 $Tuple2(nil, accDataList)
699699 }
700700 else throw("Strict value is not equal to itself.")
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 7 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let chainId = take(drop(this.bytes, 1), 1)
77
88 let chainIdW = base58'2W'
99
1010 let contractFilename = "futures_calculator.ride"
1111
1212 let mult8 = 100000000
1313
1414 let mult18BigInt = toBigInt(1000000000000000000)
1515
1616 let wavesDecimals = 8
1717
1818 let usdtDecimals = 6
1919
2020 let wavesString = "WAVES"
2121
2222 let queueItemSize = 32
2323
2424 let big0 = toBigInt(0)
2525
2626 let INDEX_LIST = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
2727
2828 let kMultisig = "%s__multisig"
2929
3030 func kStatus (dapp,txId) = makeString(["%s__status", dapp, txId], separator)
3131
3232
3333 let kShutdown = "%s__shutdown"
3434
3535 let kPublicKeys = "%s__publicKeys"
3636
3737 let kMatcherPublicKey = "%s__matcherPublicKey"
3838
3939 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), mult18BigInt, toBigInt(origScaleMult))
4040
4141
4242 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), mult18BigInt))
4343
4444
4545 func validateAddress (address) = isDefined(addressFromString(address))
4646
4747
4848 func wrapErr (s) = ((contractFilename + ": ") + s)
4949
5050
5151 func throwErr (s) = throw(wrapErr(s))
5252
5353
5454 func ensurePositive (v,s) = if ((v >= 0))
5555 then v
5656 else throwErr((s + " value should be positive"))
5757
5858
5959 func parseAssetId (input) = if ((input == wavesString))
6060 then unit
6161 else fromBase58String(input)
6262
6363
6464 func assetIdToString (input) = if ((input == unit))
6565 then wavesString
6666 else toBase58String(value(input))
6767
6868
6969 func getAssetInfoOrFail (assetId) = valueOrErrorMessage(assetInfo(assetId), wrapErr("invalid asset info"))
7070
7171
7272 func getAssetDecimalsOrFail (assetId) = match assetId {
7373 case _: Unit =>
7474 wavesDecimals
7575 case assetId: ByteVector =>
7676 getAssetInfoOrFail(assetId).decimals
7777 case _ =>
7878 throw("Match error")
7979 }
8080
8181
8282 func getAssetBalance (assetId,address) = match assetId {
8383 case _: Unit =>
8484 wavesBalance(address).available
8585 case assetId: ByteVector =>
8686 assetBalance(address, assetId)
8787 case _ =>
8888 throw("Match error")
8989 }
9090
9191
9292 func pow10 (n) = pow(10, 0, n, 0, 0, DOWN)
9393
9494
9595 func pow10Decimals (assetId) = pow10(getAssetDecimalsOrFail(assetId))
9696
9797
9898 let kFactoryAddress = "%s__factoryAddress"
9999
100100 let factoryAddressOption = match getString(this, kFactoryAddress) {
101101 case s: String =>
102102 addressFromString(s)
103103 case _: Unit =>
104104 unit
105105 case _ =>
106106 throw("Match error")
107107 }
108108
109109 let factoryAddress = valueOrErrorMessage(factoryAddressOption, wrapErr("invalid factory address"))
110110
111111 let kUsdtAssetId = "%s__usdtAssetId"
112112
113113 let usdtAssetIdOption = match getString(factoryAddress, kUsdtAssetId) {
114114 case s: String =>
115115 parseAssetId(s)
116116 case _: Unit =>
117117 unit
118118 case _ =>
119119 throw("Match error")
120120 }
121121
122122 let usdtAssetId = valueOrErrorMessage(usdtAssetIdOption, wrapErr("invalid usdt asset id"))
123123
124124 let kPricesAddress = "%s__calculatorAddress"
125125
126126 let shutdown = valueOrElse(getBoolean(factoryAddress, kShutdown), false)
127127
128128 func mustAddress (caller,address) = if ((caller == address))
129129 then true
130130 else throwErr("permission denied")
131131
132132
133133 func mustThis (caller) = mustAddress(caller, this)
134134
135135
136136 func mustFactory (caller) = mustAddress(caller, factoryAddress)
137137
138138
139139 func mustAdmin (callerPublicKey) = {
140140 let multisigAddressString = getString(factoryAddress, kMultisig)
141141 let isAdmin = match multisigAddressString {
142142 case addressString: String =>
143143 let multisig = addressFromStringValue(addressString)
144144 let publicKeysList = split(getStringValue(multisig, kPublicKeys), separator)
145145 containsElement(publicKeysList, toBase58String(callerPublicKey))
146146 case _ =>
147147 (addressFromPublicKey(callerPublicKey) == factoryAddress)
148148 }
149149 if (isAdmin)
150150 then true
151151 else throwErr("not allowed")
152152 }
153153
154154
155155 let kAccountScript = "%s__accountScript"
156156
157157 func accountScript () = valueOrErrorMessage(getBinary(factoryAddress, kAccountScript), wrapErr("account script is not set"))
158158
159159
160160 let kRewardAmount = "%s__rewardAmount"
161161
162162 func rewardAmount () = valueOrErrorMessage(getInteger(factoryAddress, kRewardAmount), wrapErr("reward amount is not set"))
163163
164164
165165 let kAccountsLimit = "%s__accountsLimit"
166166
167167 let accountsLimitDefault = 20
168168
169169 func accountsLimit () = valueOrElse(getInteger(factoryAddress, kAccountsLimit), accountsLimitDefault)
170170
171171
172172 func kDeposited (accountAddress) = makeString(["%s%s", "deposited", toString(accountAddress)], separator)
173173
174174
175175 func depositedOption (accountAddress) = getInteger(factoryAddress, kDeposited(accountAddress))
176176
177177
178178 func kCredit (accountAddress,assetId) = makeString(["%s%s%s", "credit", toString(accountAddress), assetIdToString(assetId)], separator)
179179
180180
181181 func creditOption (accountAddress,assetId) = getInteger(factoryAddress, kCredit(accountAddress, assetId))
182182
183183
184184 func kLeverage (accountAddress) = makeString(["%s%s", "leverage", toString(accountAddress)], separator)
185185
186186
187187 func kRequestLeverage (requestId) = makeString(["%s%s", "requestLeverage", toBase58String(requestId)], separator)
188188
189189
190190 func kSyntheticAssetId (baseAssetId) = makeString(["%s%s", "syntheticAssetId", assetIdToString(baseAssetId)], separator)
191191
192192
193193 func kBaseAssetId (syntheticAssetId) = makeString(["%s%s", "baseAssetId", assetIdToString(syntheticAssetId)], separator)
194194
195195
196196 let REQUEST_STATUS_EMPTY = 0
197197
198198 let REQUEST_STATUS_READY = 1
199199
200200 func kRequestStatus (requestId) = makeString(["%s%s", toBase58String(requestId), "status"], separator)
201201
202202
203203 func kAccountCreatorPublicKey (accountAddress) = makeString(["%s%s", toString(accountAddress), "creatorPublicKey"], separator)
204204
205205
206206 func kRequestOwnerPublicKey (requestId) = makeString(["%s%s", toBase58String(requestId), "ownerPublicKey"], separator)
207207
208208
209209 func kRequestAmountAssetId (requestId) = makeString(["%s%s", toBase58String(requestId), "amountAssetId"], separator)
210210
211211
212212 func kRequestPriceAssetId (requestId) = makeString(["%s%s", toBase58String(requestId), "priceAssetId"], separator)
213213
214214
215215 func kRequestIdToAccountPublicKey (requestId) = makeString(["%s%s", toBase58String(requestId), "requestIdToAccountPublicKey"], separator)
216216
217217
218218 func kAccountAddressToRequestId (accountAddress) = makeString(["%s%s", toString(accountAddress), "accountAddressToRequestId"], separator)
219219
220220
221221 func kRequestsQueue () = makeString(["%s", "requestsQueue"], separator)
222222
223223
224224 func requestsQueue () = valueOrElse(getBinary(factoryAddress, kRequestsQueue()), base58'')
225225
226226
227227 func kAccountsQueue () = makeString(["%s", "accountsQueue"], separator)
228228
229229
230230 func accountsQueue () = valueOrElse(getBinary(factoryAddress, kAccountsQueue()), base58'')
231231
232232
233233 func kRequestsByOwner (ownerAddress) = makeString(["%s%s", "requests", toString(ownerAddress)], separator)
234234
235235
236236 func requestsByOwner (ownerAddress) = valueOrElse(getBinary(factoryAddress, kRequestsByOwner(ownerAddress)), base58'')
237237
238238
239239 func kPairAllowed (amountAssetId,priceAssetId) = makeString(["%s%s%s", assetIdToString(amountAssetId), assetIdToString(priceAssetId), "pairAllowed"], separator)
240240
241241
242242 func pairAllowed (amountAssetId,priceAssetId) = valueOrElse(getBoolean(factoryAddress, kPairAllowed(amountAssetId, priceAssetId)), false)
243243
244244
245245 func kPrice (assetId) = makeString(["%s", assetIdToString(assetId)], separator)
246246
247247
248248 func kPairPricesListKey (amountAssetId,priceAssetId) = makeString(["%s%s%s", assetIdToString(amountAssetId), assetIdToString(priceAssetId), "pairSettingPrices"], separator)
249249
250250
251251 func getPairPricesList (amountAssetId,priceAssetId) = match getString(factoryAddress, kPairPricesListKey(amountAssetId, priceAssetId)) {
252252 case s: String =>
253253 split(s, separator)
254254 case _ =>
255255 nil
256256 }
257257
258258
259259 func kPairSettingsKey (amountAssetId,priceAssetId,priceString) = makeString(["%s%s%d%s", assetIdToString(amountAssetId), assetIdToString(priceAssetId), priceString, "settings"], separator)
260260
261261
262262 func getCurrentPrice (assetId) = {
263263 let matcherPublicKey = fromBase58String(valueOrErrorMessage(getString(factoryAddress, kMatcherPublicKey), wrapErr("invalid matcher public key")))
264264 let matcherAddress = addressFromPublicKey(matcherPublicKey)
265265 let price = valueOrErrorMessage(getInteger(matcherAddress, kPrice(assetId)), wrapErr(("invalid price, assetId = " + assetIdToString(assetId))))
266266 price
267267 }
268268
269269
270270 func calcTotalCredit (creditA,creditB,currentPrice) = (fraction(creditA, currentPrice, mult18BigInt) + creditB)
271271
272272
273273 func calcTotalBalance (balanceA,balanceB,currentPrice) = (fraction(balanceA, currentPrice, mult18BigInt) + balanceB)
274274
275275
276276 func calcPnl (totalBalance,totalCredit) = (totalBalance - totalCredit)
277277
278278
279279 func calcCreditAvailable (deposit,leverage,totalCredit) = (fraction(deposit, leverage, mult18BigInt) - totalCredit)
280280
281281
282282 func calcRealInCredit (credit,balance) = if ((credit > big0))
283283 then (credit - balance)
284284 else big0
285285
286286
287287 func calcFree (credit,balance) = if ((credit > big0))
288288 then (balance - credit)
289289 else big0
290290
291291
292292 func calcShortPrice (free,realInCredit) = if ((realInCredit > big0))
293293 then max([big0, fraction(free, mult18BigInt, realInCredit)])
294294 else big0
295295
296296
297297 func calcLongPrice (free,realInCredit) = if ((realInCredit > big0))
298298 then max([big0, fraction(realInCredit, mult18BigInt, free)])
299299 else big0
300300
301301
302302 func calcStartMargin (realInCreditA,realInCreditB,currentPrice,settingsMargin) = fraction((fraction(realInCreditA, currentPrice, mult18BigInt) + realInCreditB), settingsMargin, mult18BigInt)
303303
304304
305305 func calcMarginSupply (settingsMarginSupply,settingsMargin,startMargin) = fraction(settingsMarginSupply, startMargin, settingsMargin)
306306
307307
308308 func calcLiquidationPrice (deposit,marginSupply,realInCreditA,realInCreditB,shortPrice,longPrice) = {
309309 let liquidationPriceA = if ((realInCreditA > big0))
310310 then (((deposit - marginSupply) / realInCreditA) + shortPrice)
311311 else big0
312312 let liquidationPriceB = if ((realInCreditB > big0))
313313 then (longPrice - ((deposit - marginSupply) / (realInCreditA / longPrice)))
314314 else big0
315315 (liquidationPriceA + liquidationPriceB)
316316 }
317317
318318
319319 func getRequestId (accountAddress) = {
320320 let requestId = fromBase58String(valueOrErrorMessage(getString(factoryAddress, kAccountAddressToRequestId(accountAddress)), wrapErr("invalid account address: request id is undefined")))
321321 requestId
322322 }
323323
324324
325325 func getAccountAssets (accountAddress) = {
326326 let requestId = getRequestId(accountAddress)
327327 let amountAssetId = parseAssetId(valueOrErrorMessage(getString(factoryAddress, kRequestAmountAssetId(requestId)), wrapErr("invalid amount asset id")))
328328 let priceAssetId = parseAssetId(valueOrErrorMessage(getString(factoryAddress, kRequestPriceAssetId(requestId)), wrapErr("invalid amount price id")))
329329 $Tuple2(amountAssetId, priceAssetId)
330330 }
331331
332332
333333 func getAccountOwnerPublicKey (accountAddress) = {
334334 let requestId = getRequestId(accountAddress)
335335 let requestOwnerPublicKey = valueOrErrorMessage(getBinary(factoryAddress, kRequestOwnerPublicKey(requestId)), wrapErr("invalid amount asset id"))
336336 requestOwnerPublicKey
337337 }
338338
339339
340340 func getAccountInfoInternal (accountAddress) = {
341341 let $t01142011488 = getAccountAssets(accountAddress)
342342 let amountAssetId = $t01142011488._1
343343 let priceAssetId = $t01142011488._2
344344 let leverage = valueOrErrorMessage(getInteger(factoryAddress, kLeverage(accountAddress)), wrapErr("leverage should be defined"))
345345 let requestId = getRequestId(accountAddress)
346346 let accountPublicKey = valueOrErrorMessage(getBinary(factoryAddress, kRequestIdToAccountPublicKey(requestId)), "kRequestIdToAccountPublicKey not found")
347347 let deposited = valueOrElse(depositedOption(accountAddress), 0)
348348 let currentPrice = toX18(getCurrentPrice(amountAssetId), pow10Decimals(priceAssetId))
349349 let creditA = valueOrElse(getInteger(factoryAddress, kCredit(accountAddress, amountAssetId)), 0)
350350 let creditB = valueOrElse(getInteger(factoryAddress, kCredit(accountAddress, priceAssetId)), 0)
351351 let status = valueOrErrorMessage(getInteger(factoryAddress, kRequestStatus(requestId)), ("status not found. RequestId = " + toBase58String(requestId)))
352352 let synthAmountAssetId = getString(factoryAddress, kSyntheticAssetId(amountAssetId))
353353 let synthAmountAssetBalance = match synthAmountAssetId {
354354 case s: String =>
355355 getAssetBalance(parseAssetId(s), accountAddress)
356356 case _ =>
357357 0
358358 }
359359 let synthPriceAssetId = getString(factoryAddress, kSyntheticAssetId(priceAssetId))
360360 let synthPriceAssetBalance = match synthPriceAssetId {
361361 case s: String =>
362362 getAssetBalance(parseAssetId(s), accountAddress)
363363 case _ =>
364364 0
365365 }
366366 $Tuple12(assetIdToString(amountAssetId), assetIdToString(priceAssetId), toString(accountAddress), toBase58String(accountPublicKey), leverage, toBase58String(requestId), deposited, creditA, creditB, synthAmountAssetBalance, synthPriceAssetBalance, status)
367367 }
368368
369369
370370 func depositINTERNAL (callerPublicKey,args,i) = {
371371 let payment = i.payments[0]
372372 let accountAddress = valueOrErrorMessage(addressFromString(args[0]), wrapErr("invalid account address"))
373373 let ckecks = [if (!(shutdown))
374374 then true
375375 else throwErr("not allowed"), mustFactory(i.caller), if ((size(i.payments) == 1))
376376 then true
377377 else throwErr("1 payment is required"), if ((payment.assetId == usdtAssetId))
378378 then true
379379 else throwErr("invalid asset"), if ((getInteger(factoryAddress, kRequestStatus(getRequestId(accountAddress))) == REQUEST_STATUS_READY))
380380 then true
381381 else throwErr("account is not ready")]
382382 if ((ckecks == ckecks))
383383 then {
384384 let actions = [ScriptTransfer(accountAddress, payment.amount, payment.assetId)]
385385 let factoryActions = [invoke(factoryAddress, "integerEntry", [kDeposited(accountAddress), (valueOrElse(depositedOption(accountAddress), 0) + payment.amount)], nil)]
386386 $Tuple2(actions, factoryActions)
387387 }
388388 else throw("Strict value is not equal to itself.")
389389 }
390390
391391
392392 func borrowINTERNAL (callerPublicKey,args,i) = {
393393 let accountAddress = valueOrErrorMessage(addressFromString(args[0]), wrapErr("invalid account address"))
394394 let assetIdRequested = parseAssetId(args[1])
395395 let amountRequested = ensurePositive(valueOrErrorMessage(parseInt(args[2]), wrapErr("invalid requested amount")), "requested amount")
396396 let accountOwnerPublicKey = getAccountOwnerPublicKey(accountAddress)
397397 let userAddress = addressFromPublicKey(callerPublicKey)
398398 let ckecks = [if (!(shutdown))
399399 then true
400400 else throwErr("not allowed"), mustFactory(i.caller), if ((callerPublicKey == accountOwnerPublicKey))
401401 then true
402402 else throwErr("can be called by account owner only")]
403403 if ((ckecks == ckecks))
404404 then {
405405 let amountAssetId = getAccountAssets(accountAddress)._1
406406 let deposited = toX18(valueOrElse(depositedOption(accountAddress), 0), pow10Decimals(usdtAssetId))
407407 let currentPrice = toX18(getCurrentPrice(amountAssetId), pow10Decimals(usdtAssetId))
408408 let creditA = toX18(valueOrElse(getInteger(factoryAddress, kCredit(accountAddress, amountAssetId)), 0), pow10Decimals(amountAssetId))
409409 let creditB = toX18(valueOrElse(getInteger(factoryAddress, kCredit(accountAddress, usdtAssetId)), 0), pow10Decimals(usdtAssetId))
410410 let totalCredit = calcTotalCredit(creditA, creditB, currentPrice)
411411 let leverage = toX18(valueOrErrorMessage(getInteger(factoryAddress, kLeverage(accountAddress)), wrapErr("leverage should be defined")), 1)
412412 let creditAvailableUsdt = calcCreditAvailable(deposited, leverage, totalCredit)
413413 let creditAvailable = if ((assetIdRequested == amountAssetId))
414414 then fromX18(fraction(creditAvailableUsdt, mult18BigInt, currentPrice), pow10Decimals(amountAssetId))
415415 else if ((assetIdRequested == usdtAssetId))
416416 then fromX18(creditAvailableUsdt, pow10Decimals(usdtAssetId))
417417 else throwErr("invalid requested asset id")
418418 let syntheticAssetId = parseAssetId(valueOrErrorMessage(getString(factoryAddress, kSyntheticAssetId(assetIdRequested)), wrapErr("synthetic asset for requested asset is undefined")))
419419 let amountToSend = if ((creditAvailable >= amountRequested))
420420 then amountRequested
421421 else throwErr(("credit available = " + toString(creditAvailable)))
422422 let factoryActions = [invoke(factoryAddress, "integerEntry", [kCredit(accountAddress, assetIdRequested), (valueOrElse(creditOption(accountAddress, assetIdRequested), 0) + amountToSend)], nil), invoke(factoryAddress, "transferAsset", [accountAddress.bytes, amountToSend, syntheticAssetId], nil)]
423423 $Tuple2(nil, [factoryActions, creditAvailable])
424424 }
425425 else throw("Strict value is not equal to itself.")
426426 }
427427
428428
429429 @Callable(i)
430430 func init (factoryAddressStr) = {
431431 let checkCaller = mustThis(i.caller)
432432 if ((checkCaller == checkCaller))
433433 then $Tuple2([StringEntry(kFactoryAddress, factoryAddressStr)], unit)
434434 else throw("Strict value is not equal to itself.")
435435 }
436436
437437
438438
439439 @Callable(i)
440440 func requestAccount (callerPublicKey,args) = {
441441 let ckecks = [if (!(shutdown))
442442 then true
443443 else throwErr("not allowed"), mustFactory(i.caller)]
444444 if ((ckecks == ckecks))
445445 then {
446446 let amountAssetIdStr = args[0]
447447 let priceAssetIdStr = args[1]
448448 let leverage = valueOrErrorMessage(parseInt(args[2]), wrapErr("invalid leverage"))
449449 let userAddress = addressFromPublicKey(callerPublicKey)
450450 let requestId = sha256(((userAddress.bytes + fromBase58String(amountAssetIdStr)) + fromBase58String(priceAssetIdStr)))
451451 let amountAssetId = parseAssetId(amountAssetIdStr)
452452 let priceAssetId = parseAssetId(priceAssetIdStr)
453453 let userRequestsNumber = (size(kRequestsByOwner(userAddress)) / queueItemSize)
454454 let checks = [if ((size(i.payments) == 1))
455455 then true
456456 else throwErr("1 payment is required"), if ((i.payments[0].assetId == unit))
457457 then true
458458 else throwErr("invalid asset"), if ((i.payments[0].amount == rewardAmount()))
459459 then true
460460 else throwErr("invalid amount"), if (pairAllowed(amountAssetId, priceAssetId))
461461 then true
462462 else throwErr("pair is not allowed"), if ((getInteger(factoryAddress, kRequestStatus(requestId)) == unit))
463463 then true
464464 else throwErr("account is already exists"), if ((accountsLimit() > userRequestsNumber))
465465 then true
466466 else throwErr(("accounts limit is " + toString(accountsLimit())))]
467467 if ((checks == checks))
468468 then {
469469 let $t01862820083 = $Tuple2([ScriptTransfer(factoryAddress, rewardAmount(), unit)], [invoke(factoryAddress, "integerEntry", [kRequestStatus(requestId), REQUEST_STATUS_EMPTY], nil), invoke(factoryAddress, "binaryEntry", [kRequestsQueue(), (requestsQueue() + requestId)], nil), invoke(factoryAddress, "integerEntry", [kRequestLeverage(requestId), leverage], nil)])
470470 let actions = $t01862820083._1
471471 let factoryActions = $t01862820083._2
472472 $Tuple2(actions, (factoryActions ++ [invoke(factoryAddress, "binaryEntry", [kRequestOwnerPublicKey(requestId), callerPublicKey], nil), invoke(factoryAddress, "binaryEntry", [kRequestsByOwner(userAddress), (requestsByOwner(userAddress) + requestId)], nil), invoke(factoryAddress, "stringEntry", [kRequestAmountAssetId(requestId), amountAssetIdStr], nil), invoke(factoryAddress, "stringEntry", [kRequestPriceAssetId(requestId), priceAssetIdStr], nil)]))
473473 }
474474 else throw("Strict value is not equal to itself.")
475475 }
476476 else throw("Strict value is not equal to itself.")
477477 }
478478
479479
480480
481481 @Callable(i)
482482 func addAccount (callerPublicKey,args) = {
483483 let ckecks = [if (!(shutdown))
484484 then true
485485 else throwErr("not allowed"), mustFactory(i.caller)]
486486 if ((ckecks == ckecks))
487487 then {
488488 let creatorPublicKey = fromBase58String(args[0])
489489 let accountPublicKey = callerPublicKey
490490 let accountAddress = addressFromPublicKey(callerPublicKey)
491491 let creatorAddress = addressFromPublicKey(creatorPublicKey)
492492 let checks = [if ((getBinary(factoryAddress, kAccountCreatorPublicKey(accountAddress)) == unit))
493493 then true
494494 else throwErr("account is already exists"), if ( match scriptHash(accountAddress) {
495495 case b: ByteVector =>
496496 (b == blake2b256_32Kb(accountScript()))
497497 case _ =>
498498 false
499499 })
500500 then true
501501 else throwErr("invalid script")]
502502 if ((checks == checks))
503503 then {
504- let $t02133822632 = if ((size(requestsQueue()) == 0))
505- then $Tuple2(throwErr("requests is empty"), nil)
504+ let $t02133822649 = if ((size(requestsQueue()) == 0))
505+ then $Tuple2(nil, nil)
506506 else {
507507 let requestId = take(requestsQueue(), queueItemSize)
508508 let leverage = valueOrErrorMessage(getInteger(factoryAddress, kRequestLeverage(requestId)), wrapErr("request's leverage is undefined"))
509509 $Tuple2(nil, [invoke(factoryAddress, "integerEntry", [kRequestStatus(requestId), REQUEST_STATUS_READY], nil), invoke(factoryAddress, "binaryEntry", [kRequestIdToAccountPublicKey(requestId), accountPublicKey], nil), invoke(factoryAddress, "binaryEntry", [kRequestsQueue(), drop(requestsQueue(), queueItemSize)], nil), invoke(factoryAddress, "stringEntry", [kAccountAddressToRequestId(accountAddress), toBase58String(requestId)], nil), invoke(factoryAddress, "transferWaves", [creatorAddress.bytes, rewardAmount()], nil), invoke(factoryAddress, "integerEntry", [kLeverage(accountAddress), leverage], nil)])
510510 }
511- let actions = $t02133822632._1
512- let factoryActions = $t02133822632._2
511+ let actions = $t02133822649._1
512+ let factoryActions = $t02133822649._2
513513 $Tuple2(actions, (factoryActions ++ [invoke(factoryAddress, "binaryEntry", [kAccountCreatorPublicKey(accountAddress), creatorPublicKey], nil)]))
514514 }
515515 else throw("Strict value is not equal to itself.")
516516 }
517517 else throw("Strict value is not equal to itself.")
518518 }
519519
520520
521521
522522 @Callable(i)
523523 func withdraw (callerPublicKey,args) = {
524524 let checks = [if (!(shutdown))
525525 then true
526526 else throwErr("not allowed"), mustFactory(i.caller)]
527527 if ((checks == checks))
528528 then {
529529 let userAddress = addressFromPublicKey(callerPublicKey)
530530 let accountAddress = valueOrErrorMessage(addressFromString(args[0]), wrapErr("invalid account address"))
531531 let amount = valueOrErrorMessage(parseInt(args[1]), wrapErr("invalid amount"))
532532 let assetId = parseAssetId(args[2])
533533 let invocations = [invoke(accountAddress, "transferAsset", [userAddress.bytes, amount, assetId], nil)]
534534 $Tuple2(nil, invocations)
535535 }
536536 else throw("Strict value is not equal to itself.")
537537 }
538538
539539
540540
541541 @Callable(i)
542542 func deposit (callerPublicKey,args) = {
543- let $t02365323726 = depositINTERNAL(callerPublicKey, args, i)
544- let actions = $t02365323726._1
545- let factoryActions = $t02365323726._2
543+ let $t02367023743 = depositINTERNAL(callerPublicKey, args, i)
544+ let actions = $t02367023743._1
545+ let factoryActions = $t02367023743._2
546546 $Tuple2(actions, factoryActions)
547547 }
548548
549549
550550
551551 @Callable(i)
552552 func borrow (callerPublicKey,args) = {
553- let $t02388123953 = borrowINTERNAL(callerPublicKey, args, i)
554- let actions = $t02388123953._1
555- let factoryActions = $t02388123953._2
553+ let $t02389823970 = borrowINTERNAL(callerPublicKey, args, i)
554+ let actions = $t02389823970._1
555+ let factoryActions = $t02389823970._2
556556 $Tuple2(actions, factoryActions)
557557 }
558558
559559
560560
561561 @Callable(i)
562562 func depositAndBorrow (callerPublicKey,args) = {
563563 let accountAddress = args[0]
564- let $t02414924248 = depositINTERNAL(callerPublicKey, [accountAddress], i)
565- let depositActions = $t02414924248._1
566- let depositFactoryActions = $t02414924248._2
567- let $t02425124335 = borrowINTERNAL(callerPublicKey, args, i)
568- let borrowActions = $t02425124335._1
569- let borrowFactoryActions = $t02425124335._2
564+ let $t02416624265 = depositINTERNAL(callerPublicKey, [accountAddress], i)
565+ let depositActions = $t02416624265._1
566+ let depositFactoryActions = $t02416624265._2
567+ let $t02426824352 = borrowINTERNAL(callerPublicKey, args, i)
568+ let borrowActions = $t02426824352._1
569+ let borrowFactoryActions = $t02426824352._2
570570 $Tuple2((depositActions ++ borrowActions), (depositFactoryActions ++ borrowFactoryActions))
571571 }
572572
573573
574574
575575 @Callable(i)
576576 func repay (callerPublicKey,args) = {
577577 let ckecks = [if (!(shutdown))
578578 then true
579579 else throwErr("not allowed"), mustFactory(i.caller)]
580580 if ((ckecks == ckecks))
581581 then $Tuple2(nil, unit)
582582 else throw("Strict value is not equal to itself.")
583583 }
584584
585585
586586
587587 @Callable(i)
588588 func setPairAllowance (callerPublicKey,args) = {
589589 let ckecks = [if (!(shutdown))
590590 then true
591591 else throwErr("not allowed"), mustFactory(i.caller), mustAdmin(callerPublicKey)]
592592 if ((ckecks == ckecks))
593593 then {
594594 let amountAssetIdStr = args[0]
595595 let priceAssetIdStr = args[1]
596596 let allowStr = args[2]
597597 let amountAssetId = parseAssetId(amountAssetIdStr)
598598 let priceAssetId = parseAssetId(priceAssetIdStr)
599599 let allow = (allowStr == "true")
600600 let invocations = [invoke(factoryAddress, "booleanEntry", [kPairAllowed(amountAssetId, priceAssetId), allow], nil)]
601601 $Tuple2(nil, invocations)
602602 }
603603 else throw("Strict value is not equal to itself.")
604604 }
605605
606606
607607
608608 @Callable(i)
609609 func addSyntheticAsset (callerPublicKey,args) = {
610610 let baseAssetId = parseAssetId(args[0])
611611 let syntheticAssetId = parseAssetId(args[1])
612612 let ckecks = [if (!(shutdown))
613613 then true
614614 else throwErr("not allowed"), mustFactory(i.caller), mustAdmin(callerPublicKey), if ((getString(factoryAddress, kSyntheticAssetId(baseAssetId)) == unit))
615615 then true
616616 else throwErr("invalid base asset"), if ((getString(factoryAddress, kBaseAssetId(syntheticAssetId)) == unit))
617617 then true
618618 else throwErr("invalid synthetic asset")]
619619 if ((ckecks == ckecks))
620620 then {
621621 let invocations = [invoke(factoryAddress, "stringEntry", [kSyntheticAssetId(baseAssetId), assetIdToString(syntheticAssetId)], nil), invoke(factoryAddress, "stringEntry", [kBaseAssetId(syntheticAssetId), assetIdToString(baseAssetId)], nil)]
622622 $Tuple2(nil, invocations)
623623 }
624624 else throw("Strict value is not equal to itself.")
625625 }
626626
627627
628628
629629 @Callable(i)
630630 func doShutdown (callerPublicKey,args) = {
631631 let checks = [mustFactory(i.caller), mustAdmin(callerPublicKey)]
632632 if ((checks == checks))
633633 then {
634634 let invocations = [invoke(factoryAddress, "booleanEntry", [kShutdown, true], nil)]
635635 $Tuple2(nil, invocations)
636636 }
637637 else throw("Strict value is not equal to itself.")
638638 }
639639
640640
641641
642642 @Callable(i)
643643 func getAccountInfoREADONLY (callerPublicKey,args) = {
644644 let checks = [mustFactory(i.caller)]
645645 if ((checks == checks))
646646 then {
647647 let accountAddress = valueOrErrorMessage(addressFromString(args[0]), wrapErr("invalid account address"))
648648 let data = getAccountInfoInternal(accountAddress)
649649 $Tuple2(nil, data)
650650 }
651651 else throw("Strict value is not equal to itself.")
652652 }
653653
654654
655655
656656 @Callable(i)
657657 func getUserInfoREADONLY (callerPublicKey,args) = {
658658 let checks = [mustFactory(i.caller)]
659659 if ((checks == checks))
660660 then {
661661 let userAddress = valueOrErrorMessage(addressFromString(args[0]), wrapErr("invalid user address"))
662662 let userRequests = valueOrElse(getBinary(factoryAddress, kRequestsByOwner(userAddress)), base58'')
663663 let userRequestsNumber = (size(userRequests) / queueItemSize)
664664 func getAccountsData (acc,count) = {
665- let $t02726827310 = acc
666- let accDataList = $t02726827310._1
667- let rawBytes = $t02726827310._2
668- let maxSize = $t02726827310._3
665+ let $t02728527327 = acc
666+ let accDataList = $t02728527327._1
667+ let rawBytes = $t02728527327._2
668+ let maxSize = $t02728527327._3
669669 if ((maxSize > count))
670670 then {
671671 let requestId = take(rawBytes, queueItemSize)
672672 let newRawBytes = drop(rawBytes, queueItemSize)
673673 let accountPublicKey = valueOrErrorMessage(getBinary(factoryAddress, kRequestIdToAccountPublicKey(requestId)), "kRequestIdToAccountPublicKey not found")
674674 let accountAddress = addressFromPublicKey(accountPublicKey)
675675 let data = getAccountInfoInternal(accountAddress)
676676 $Tuple3((accDataList :+ data), newRawBytes, maxSize)
677677 }
678678 else acc
679679 }
680680
681- let $t02781427919 = {
681+ let $t02783127936 = {
682682 let $l = INDEX_LIST
683683 let $s = size($l)
684684 let $acc0 = $Tuple3(nil, userRequests, userRequestsNumber)
685685 func $f0_1 ($a,$i) = if (($i >= $s))
686686 then $a
687687 else getAccountsData($a, $l[$i])
688688
689689 func $f0_2 ($a,$i) = if (($i >= $s))
690690 then $a
691691 else throw("List size exceeds 20")
692692
693693 $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)
694694 }
695- let accDataList = $t02781427919._1
696- let _a = $t02781427919._2
697- let _b = $t02781427919._3
695+ let accDataList = $t02783127936._1
696+ let _a = $t02783127936._2
697+ let _b = $t02783127936._3
698698 $Tuple2(nil, accDataList)
699699 }
700700 else throw("Strict value is not equal to itself.")
701701 }
702702
703703
704704
705705 @Callable(i)
706706 func getPairSettingsInfoREADONLY (callerPublicKey,args) = {
707707 let amountAsset = parseAssetId(args[0])
708708 let priceAsset = parseAssetId(args[1])
709709 let pricesList = getPairPricesList(amountAsset, priceAsset)
710710 func getPairSettings (acc,pricesString) = {
711711 let settingsKey = kPairSettingsKey(amountAsset, priceAsset, pricesString)
712712 let settingsStringValue = getStringValue(factoryAddress, settingsKey)
713713 let sList = split(settingsStringValue, separator)
714714 let price = parseInt(pricesString)
715715 let maxLeverage = parseInt(sList[1])
716716 let initialMargin = parseInt(sList[2])
717717 let maintenanceMargin = parseInt(sList[3])
718718 (acc :+ $Tuple4(price, maxLeverage, initialMargin, maintenanceMargin))
719719 }
720720
721721 let data = {
722722 let $l = pricesList
723723 let $s = size($l)
724724 let $acc0 = nil
725725 func $f0_1 ($a,$i) = if (($i >= $s))
726726 then $a
727727 else getPairSettings($a, $l[$i])
728728
729729 func $f0_2 ($a,$i) = if (($i >= $s))
730730 then $a
731731 else throw("List size exceeds 20")
732732
733733 $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)
734734 }
735735 $Tuple2(nil, data)
736736 }
737737
738738
739739
740740 @Callable(i)
741741 func editPairSettings (callerPublicKey,args) = {
742742 let checks = [mustFactory(i.caller), mustAdmin(callerPublicKey)]
743743 if ((checks == checks))
744744 then {
745745 let amountAsset = parseAssetId(args[0])
746746 let priceAsset = parseAssetId(args[1])
747747 let price = args[2]
748748 let maxLeverage = args[3]
749749 let initialMargin = args[4]
750750 let maintenanceMargin = args[5]
751751 let pairPricesListKey = kPairPricesListKey(amountAsset, priceAsset)
752752 let settingsKey = kPairSettingsKey(amountAsset, priceAsset, price)
753753 let pricesList = getPairPricesList(amountAsset, priceAsset)
754754 let newList = match indexOf(pricesList, price) {
755755 case ind: Int =>
756756 pricesList
757757 case _ =>
758758 (pricesList :+ price)
759759 }
760760 let check2 = [valueOrErrorMessage(parseInt(price), wrapErr("price value is not an Int")), valueOrErrorMessage(maxLeverage, wrapErr("maxLeverage value is not an Int")), valueOrErrorMessage(initialMargin, wrapErr("initialMargin value is not an Int")), valueOrErrorMessage(maintenanceMargin, wrapErr("maintenanceMargin value is not an Int")), if ((20 >= size(newList)))
761761 then true
762762 else throwErr("exceeded max prices list size (20)")]
763763 if ((check2 == check2))
764764 then {
765765 let pairSettingValue = makeString(["%s%s%s", maxLeverage, initialMargin, maintenanceMargin], separator)
766766 let invocations = [invoke(factoryAddress, "stringEntry", [kPairPricesListKey(amountAsset, priceAsset), makeString(newList, separator)], nil), invoke(factoryAddress, "stringEntry", [kPairSettingsKey(amountAsset, priceAsset, price), pairSettingValue], nil)]
767767 $Tuple2(nil, invocations)
768768 }
769769 else throw("Strict value is not equal to itself.")
770770 }
771771 else throw("Strict value is not equal to itself.")
772772 }
773773
774774
775775
776776 @Callable(i)
777777 func deletePairSettings (callerPublicKey,args) = {
778778 let checks = [mustFactory(i.caller), mustAdmin(callerPublicKey)]
779779 if ((checks == checks))
780780 then {
781781 let amountAsset = parseAssetId(args[0])
782782 let priceAsset = parseAssetId(args[1])
783783 let price = args[2]
784784 let settingsKey = kPairSettingsKey(amountAsset, priceAsset, price)
785785 let pairPricesListKey = kPairPricesListKey(amountAsset, priceAsset)
786786 let pricesList = getPairPricesList(amountAsset, priceAsset)
787787 let newList = match indexOf(pricesList, price) {
788788 case ind: Int =>
789789 removeByIndex(pricesList, ind)
790790 case _ =>
791791 pricesList
792792 }
793793 let invocations = [invoke(factoryAddress, "deleteEntry", [settingsKey], nil), if ((size(newList) == 0))
794794 then invoke(factoryAddress, "deleteEntry", [kPairPricesListKey(amountAsset, priceAsset)], nil)
795795 else invoke(factoryAddress, "stringEntry", [kPairPricesListKey(amountAsset, priceAsset), makeString(newList, separator)], nil)]
796796 $Tuple2(nil, invocations)
797797 }
798798 else throw("Strict value is not equal to itself.")
799799 }
800800
801801
802802 @Verifier(tx)
803803 func verify () = if (if (isDefined(factoryAddressOption))
804804 then isDefined(getString(factoryAddress, kMultisig))
805805 else false)
806806 then match getString(factoryAddress, kMultisig) {
807807 case multisig: String =>
808808 let statusKey = kStatus(toString(this), toBase58String(tx.id))
809809 let status = valueOrElse(getBoolean(addressFromStringValue(multisig), statusKey), false)
810810 status
811811 case _ =>
812812 false
813813 }
814814 else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
815815

github/deemru/w8io/026f985 
84.46 ms