tx · 57espbn1fBLoVfnxr6iD4i4VTpEQuFggjHjDMwh2baux 3Mw8ZcMK47vENHqhYYhCZTCPDXhff6ZQVwt: -0.04700000 Waves 2023.07.05 14:04 [2652535] smart account 3Mw8ZcMK47vENHqhYYhCZTCPDXhff6ZQVwt > SELF 0.00000000 Waves
{ "type": 13, "id": "57espbn1fBLoVfnxr6iD4i4VTpEQuFggjHjDMwh2baux", "fee": 4700000, "feeAssetId": null, "timestamp": 1688555107571, "version": 2, "chainId": 84, "sender": "3Mw8ZcMK47vENHqhYYhCZTCPDXhff6ZQVwt", "senderPublicKey": "3fNYAZ872D7hsaic3sPDZd5uAk59U5CiWiA153FUZ6Qv", "proofs": [ "J88nXAYQpJ6BEpeoUjdvGvhiAkekhyFY5SUG5CzqNm3okYwm9Biu62DRo9G8f3mnzvQSbH4QJZyqo5Re8ftKzTe" ], "script": "base64:BgI2CAISDQoLGBgBAQgIAQEBAQESAwoBARIDCgEBEgASBAoCCAESBAoCCAESABIDCgEBEgQKAggBaQADU0VQAgJfXwAFV0FWRVMCBXdhdmVzAAdNQVhfSU5UAP//////////fwAHTUFYX0ZFRQDAhD0ADU1BWF9BTVBMSUZJRVIAwIQ9ABRNQVhfV0VJR0hUX0FNUExJRklFUgDAhD0ACk1BWF9XRUlHSFQAgKCUpY0dABRTTElQUEFHRV9SQVRFX0ZBQ1RPUgDAhD0AD0ZFRV9SQVRFX0ZBQ1RPUgDAhD0AC1JBVEVfRkFDVE9SAMCEPQAOUEVSQ0VOVF9GQUNUT1IJALYCAQCAoJSljR0AD1pFUk9fSU5UX0xJU1QxMAkAzAgCAAAJAMwIAgAACQDMCAIAAAkAzAgCAAAJAMwIAgAACQDMCAIAAAkAzAgCAAAJAMwIAgAACQDMCAIAAAkAzAgCAAAFA25pbAALWkVST19CSUdJTlQJALYCAQAAABJaRVJPX0JJR0lOVF9MSVNUMTEJAMwIAgULWkVST19CSUdJTlQJAMwIAgULWkVST19CSUdJTlQJAMwIAgULWkVST19CSUdJTlQJAMwIAgULWkVST19CSUdJTlQJAMwIAgULWkVST19CSUdJTlQJAMwIAgULWkVST19CSUdJTlQJAMwIAgULWkVST19CSUdJTlQJAMwIAgULWkVST19CSUdJTlQJAMwIAgULWkVST19CSUdJTlQJAMwIAgULWkVST19CSUdJTlQJAMwIAgULWkVST19CSUdJTlQFA25pbAAMSU5UX0RFQ0lNQUxTAAgAD0JJR0lOVF9ERUNJTUFMUwASAAlQUkVDSVNJT04AwIQ9AAdMSVNUXzI1CQC9CQICMTBfMF8wXzBfMF8wXzBfMF8wXzBfMF8wXzBfMF8wXzBfMF8wXzBfMF8wXzBfMF8wXzACAV8AC0tFWV9TVE9SQUdFAgdTVE9SQUdFAApLRVlfQVNTRVRTAgZBU1NFVFMAEktFWV9BU1NFVF9CQUxBTkNFUwIOQVNTRVRfQkFMQU5DRVMAEUtFWV9BU1NFVF9XRUlHSFRTAg1BU1NFVF9XRUlHSFRTAApLRVlfTFBfRkVFAgZMUF9GRUUAEEtFWV9QUk9UT0NPTF9GRUUCDFBST1RPQ09MX0ZFRQAOS0VZX0ZFRV9JTkNPTUUCCkZFRV9JTkNPTUUAC0tFWV9VU0VSX0xQAgdVU0VSX0xQAAxLRVlfVE9UQUxfTFACCFRPVEFMX0xQABVLRVlfVE9UQUxfTFBfSU5URUdSQUwCEVRPVEFMX0xQX0lOVEVHUkFMABhLRVlfVE9UQUxfTFBfSU5URUdSQUxfQVQCFFRPVEFMX0xQX0lOVEVHUkFMX0FUABRLRVlfSU5DT01FX0lOVEVHUkFMUwIQSU5DT01FX0lOVEVHUkFMUwAXS0VZX0lOQ09NRV9JTlRFR1JBTFNfQVQCE0lOQ09NRV9JTlRFR1JBTFNfQVQAGUtFWV9VU0VSX0lOQ09NRV9JTlRFR1JBTFMCFVVTRVJfSU5DT01FX0lOVEVHUkFMUwAbS0VZX1VTRVJfVE9UQUxfTFBfSU5URUdSQUxTAhdVU0VSX1RPVEFMX0xQX0lOVEVHUkFMUwAQS0VZX1VTRVJfUFJPRklUUwIMVVNFUl9QUk9GSVRTARBfdmFsaWRhdGVBZGRyZXNzAghhZGRyZXNzXwRlcnJfBAckbWF0Y2gwCQCmCAEFCGFkZHJlc3NfAwkAAQIFByRtYXRjaDACB0FkZHJlc3MEAWEFByRtYXRjaDAGCQACAQUEZXJyXwEOX3ZhbGlkYXRlQXNzZXQCCGFzc2V0SWRfBGVycl8DCQAAAgUIYXNzZXRJZF8FBVdBVkVTBgQHJG1hdGNoMAkA7AcBCQDZBAEFCGFzc2V0SWRfAwkAAQIFByRtYXRjaDACBUFzc2V0BAFhBQckbWF0Y2gwBgkAAgEFBGVycl8BDF92YWxpZGF0ZUludAQEdmFsXw5sb3dlckJvdW5kYXJ5Xw51cHBlckJvdW5kYXJ5XwRlcnJfAwMJAGYCBQ5sb3dlckJvdW5kYXJ5XwUEdmFsXwYJAGYCBQR2YWxfBQ51cHBlckJvdW5kYXJ5XwkAAgEFBGVycl8GAQ1fdmFsaWRhdGVCb29sAwR2YWxfB3RhcmdldF8EZXJyXwMJAQIhPQIFBHZhbF8FB3RhcmdldF8JAAIBBQRlcnJfBgEUX3ZhbGlkYXRlU3RyaW5nRXF1YWwDBXZhbDFfBXZhbDJfBGVycl8DCQECIT0CBQV2YWwxXwUFdmFsMl8JAAIBBQRlcnJfBgEUX3ZhbGlkYXRlU3RyaW5nTm90RXEDBXZhbDFfBXZhbDJfBGVycl8DCQAAAgUFdmFsMV8FBXZhbDJfCQACAQUEZXJyXwYBEF92YWxpZGF0ZUludExpc3QEBHZhbF8ObG93ZXJCb3VuZGFyeV8OdXBwZXJCb3VuZGFyeV8EZXJyXwoBCGZvbGRGdW5jAgNhY2MEZWxlbQQHJG1hdGNoMAkAtgkBBQRlbGVtAwkAAQIFByRtYXRjaDACA0ludAQBYQUHJG1hdGNoMAMFA2FjYwkBDF92YWxpZGF0ZUludAQFAWEFDmxvd2VyQm91bmRhcnlfBQ51cHBlckJvdW5kYXJ5XwUEZXJyXwcJAAIBBQRlcnJfCgACJGwFBHZhbF8KAAIkcwkAkAMBBQIkbAoABSRhY2MwBgoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZm9sZEZ1bmMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBD192YWxpZGF0ZUFzc2V0cwIHYXNzZXRzXwRlcnJfCgEIZm9sZEZ1bmMCA2FjYwRlbGVtAwUDYWNjCQEOX3ZhbGlkYXRlQXNzZXQCBQRlbGVtBQRlcnJfBwoAAiRsBQdhc3NldHNfCgACJHMJAJADAQUCJGwKAAUkYWNjMAYKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGZvbGRGdW5jAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARJfdmFsaWRhdGVJbnRFcXVhbHMDBXZhbDFfBXZhbDJfBGVycl8DCQECIT0CBQV2YWwxXwUFdmFsMl8JAAIBBQRlcnJfBgESX3ZhbGlkYXRlVG9rZW5OYW1lAgR2YWxfBGVycl8DAwkAZgIABAkAsQIBBQR2YWxfBgkAZgIJALECAQUEdmFsXwAQCQACAQUEZXJyXwYBE192YWxpZGF0ZVRva2VuRGVzY3ICBHZhbF8EZXJyXwMJAGYCCQCxAgEFBHZhbF8A6AcJAAIBBQRlcnJfBgERX3ZhbGlkYXRlRGVjaW1hbHMCBHZhbF8EZXJyXwMDCQBmAgAABQR2YWxfBgkAZgIFBHZhbF8ACAkAAgEFBGVycl8GARBfdmFsaWRhdGVQYXltZW50BAhwYXltZW50Xwhhc3NldElkXw9yZXF1aXJlZEFtb3VudF8EZXJyXwQHJG1hdGNoMAgFCHBheW1lbnRfB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYQUHJG1hdGNoMAMJAQIhPQIFCGFzc2V0SWRfCQDYBAEFAWEJAAIBCQCsAgIFBGVycl8CBzogYXNzZXQDCQBmAgUPcmVxdWlyZWRBbW91bnRfCAUIcGF5bWVudF8GYW1vdW50CQACAQkArAICBQRlcnJfAgg6IGFtb3VudAYJAAIBCQCsAgIFBGVycl8CBzogYXNzZXQBFV92YWxpZGF0ZUxpc3RDb250YWlucwMFbGlzdF8EdmFsXwRlcnJfAwkBASEBCQEPY29udGFpbnNFbGVtZW50AgUFbGlzdF8FBHZhbF8JAAIBBQRlcnJfBgELX2Fzc2V0VG9TdHIBBmFzc2V0XwQHJG1hdGNoMAUGYXNzZXRfAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWEFByRtYXRjaDAJANgEAQUBYQUFV0FWRVMBC19zdHJUb0Fzc2V0AQZhc3NldF8DAwkAAAIFBmFzc2V0XwUFV0FWRVMGCQAAAgUGYXNzZXRfAgAFBHVuaXQJANkEAQUGYXNzZXRfAQxfbG9hZFN0b3JhZ2UABAckbWF0Y2gwCQCiCAEFC0tFWV9TVE9SQUdFAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAQGc3RydWN0CQC1CQIFAWEFA1NFUAkAmwoJCQDZBAEJAJEDAgUGc3RydWN0AAAJAAACCQCRAwIFBnN0cnVjdAABAgExCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RydWN0AAIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdHJ1Y3QAAwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0cnVjdAAECQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RydWN0AAUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZzdHJ1Y3QABgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnN0cnVjdAAHCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGc3RydWN0AAgJAJsKCQEABwAAAAAAAAAAAAAAAAAAAQxfc2F2ZVN0b3JhZ2UBCHN0b3JhZ2VfCQDMCAIJAQtTdHJpbmdFbnRyeQIFC0tFWV9TVE9SQUdFCQC5CQIJAMwIAgkA2AQBCAUIc3RvcmFnZV8CXzEJAMwIAgMIBQhzdG9yYWdlXwJfMgIBMQIBMAkAzAgCCQCkAwEIBQhzdG9yYWdlXwJfMwkAzAgCCQCkAwEIBQhzdG9yYWdlXwJfNAkAzAgCCQCkAwEIBQhzdG9yYWdlXwJfNQkAzAgCCQCkAwEIBQhzdG9yYWdlXwJfNgkAzAgCCQCkAwEIBQhzdG9yYWdlXwJfNwkAzAgCCQCkAwEIBQhzdG9yYWdlXwJfOAkAzAgCCQCkAwEIBQhzdG9yYWdlXwJfOQUDbmlsBQNTRVAFA25pbAELX2xvYWRBc3NldHMABAckbWF0Y2gwCQCiCAEFCktFWV9BU1NFVFMDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwAwkAZgIJALECAQUBYQAACQC9CQIFAWEFA1NFUAUDbmlsBQNuaWwBC19zYXZlQXNzZXRzAQdhc3NldHNfCQDMCAIJAQtTdHJpbmdFbnRyeQIFCktFWV9BU1NFVFMJALsJAgUHYXNzZXRzXwUDU0VQBQNuaWwBEl9sb2FkQXNzZXRCYWxhbmNlcwAKAQhmb2xkRnVuYwIDYWNjBGVsZW0EB2JhbGFuY2UJAQ1wYXJzZUludFZhbHVlAQUEZWxlbQkAlAoCCQDNCAIIBQNhY2MCXzEFB2JhbGFuY2UJAGQCCAUDYWNjAl8yBQdiYWxhbmNlBAckbWF0Y2gwCQCi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Cl9sb2FkTHBGZWUBCGFzc2V0SWRfBAckbWF0Y2gwCQCfCAEJALkJAgkAzAgCBQpLRVlfTFBfRkVFCQDMCAIFCGFzc2V0SWRfBQNuaWwFA1NFUAMJAAECBQckbWF0Y2gwAgNJbnQEAWEFByRtYXRjaDAFAWEAAAEKX3NhdmVMcEZlZQIIYXNzZXRJZF8EdmFsXwkAzAgCCQEMSW50ZWdlckVudHJ5AgkAuQkCCQDMCAIFCktFWV9MUF9GRUUJAMwIAgUIYXNzZXRJZF8FA25pbAUDU0VQBQR2YWxfBQNuaWwBEF9sb2FkUHJvdG9jb2xGZWUBCGFzc2V0SWRfBAckbWF0Y2gwCQCfCAEJALkJAgkAzAgCBRBLRVlfUFJPVE9DT0xfRkVFCQDMCAIFCGFzc2V0SWRfBQNuaWwFA1NFUAMJAAECBQckbWF0Y2gwAgNJbnQEAWEFByRtYXRjaDAFAWEAAAEQX3NhdmVQcm90b2NvbEZlZQIIYXNzZXRJZF8EdmFsXwkAzAgCCQEMSW50ZWdlckVudHJ5AgkAuQkCCQDMCAIFEEtFWV9QUk9UT0NPTF9GRUUJAMwIAgUIYXNzZXRJZF8FA25pbAUDU0VQBQR2YWxfBQNuaWwBC19sb2FkVXNlckxwAQhhZGRyZXNzXwQHJG1hdGNoMAkAnwgBCQC5CQIJAMwIAgULS0VZX1VTRVJfTFAJAMwIAgkApQgBBQhhZGRyZXNzXwUDbmlsBQNTRVADCQABAgUHJG1hdGNoMAIDSW50BAFhBQckbWF0Y2gwBQFhAAABC19zYXZlVXNlckxwAghhZGRyZXNzXwR2YWxfCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQC5CQIJAMwIAgULS0VZX1VTRVJfTFAJAMwIAgkApQgBBQhhZGRyZXNzXwUDbmlsBQNTRVAFBHZhbF8FA25pbAEMX2xvYWRUb3RhbExwAAQHJG1hdGNoMAkAnwgBBQxLRVlfVE9UQUxfTFADCQABAgUHJG1hdGNoMAIDSW50BAFhBQckbWF0Y2gwBQFhAAABDF9zYXZlVG90YWxMcAEEdmFsXwkAzAgCCQEMSW50ZWdlckVudHJ5AgUMS0VZX1RPVEFMX0xQBQR2YWxfBQNuaWwBDl9sb2FkRmVlSW5jb21lAQhhc3NldElkXwQHJG1hdGNoMAkAnwgBCQC5CQIJAMwIAgUOS0VZX0ZFRV9JTkNPTUUJAMwIAgUIYXNzZXRJZF8FA25pbAUDU0VQAwkAAQIFByRtYXRjaDACA0ludAQBYQUHJG1hdGNoMAUBYQAAAQ5fc2F2ZUZlZUluY29tZQIIYXNzZXRJZF8EdmFsXwkAzAgCCQEMSW50ZWdlckVudHJ5AgkAuQkCCQDMCAIFDktFWV9GRUVfSU5DT01FCQDMCAIFCGFzc2V0SWRfBQNuaWwFA1NFUAUEdmFsXwUDbmlsARRfbG9hZEluY29tZUludGVncmFscwAKAQhmb2xkRnVuYwIDYWNjBGVsZW0JAM0IAgUDYWNjCQCnAwEFBGVsZW0EByRtYXRjaDAJAKIIAQUUS0VZX0lOQ09NRV9JTlRFR1JBTFMDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwAwkAZgIJALECAQUBYQAACgACJGwJAL0JAgUBYQUDU0VQCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmb2xkRnVuYwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTEJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALBRJaRVJPX0JJR0lOVF9MSVNUMTEFElpFUk9fQklHSU5UX0xJU1QxMQEUX3NhdmVJbmNvbWVJbnRlZ3JhbHMBBHZhbF8KAQhmb2xkRnVuYwIDYWNjBGVsZW0JAM0IAgUDYWNjCQCmAwEFBGVsZW0JAMwIAgkBC1N0cmluZ0VudHJ5AgUUS0VZX0lOQ09NRV9JTlRFR1JBTFMJALsJAgoAAiRsBQR2YWxfCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmb2xkRnVuYwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTEJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALBQNTRVAFA25pbAEWX2xvYWRJbmNvbWVJbnRlZ3JhbHNBdAAKAQhmb2xkRnVuYwIDYWNjBGVsZW0JAM0IAgUDYWNjCQENcGFyc2VJbnRWYWx1ZQEFBGVsZW0EByRtYXRjaDAJAKIIAQUXS0VZX0lOQ09NRV9JTlRFR1JBTFNfQVQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwAwkAZgIJALECAQUBYQAACgACJGwJAL0JAgUBYQUDU0VQCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmb2xkRnVuYwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTEJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALCQDNCAIFD1pFUk9fSU5UX0xJU1QxMAAACQDNCAIFD1pFUk9fSU5UX0xJU1QxMAAAARZfc2F2ZUluY29tZUludGVncmFsc0F0AQR2YWxfCgEIZm9sZEZ1bmMCA2FjYwRlbGVtCQDNCAIFA2FjYwkApAMBBQRlbGVtCQDMCAIJAQtTdHJpbmdFbnRyeQIFF0tFWV9JTkNPTUVfSU5URUdSQUxTX0FUCQC7CQIKAAIkbAUEdmFsXwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZm9sZEZ1bmMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDExCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwUDU0VQBQNuaWwBFF9sb2FkVG90YWxMcEludGVncmFsAAQHJG1hdGNoMAkAoggBBRVLRVlfVE9UQUxfTFBfSU5URUdSQUwDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwCQCnAwEFAWEJALYCAQAAARRfc2F2ZVRvdGFsTHBJbnRlZ3JhbAEEdmFsXwkAzAgCCQELU3RyaW5nRW50cnkCBRVLRVlfVE9UQUxfTFBfSU5URUdSQUwJAKYDAQUEdmFsXwUDbmlsARZfbG9hZFRvdGFsTHBJbnRlZ3JhbEF0AAQHJG1hdGNoMAkAnwgBBRhLRVlfVE9UQUxfTFBfSU5URUdSQUxfQVQDCQABAgUHJG1hdGNoMAIDSW50BAFhBQckbWF0Y2gwBQFhAAABFl9zYXZlVG90YWxMcEludGVncmFsQXQBBHZhbF8JAMwIAgkBDEludGVnZXJFbnRyeQIFGEtFWV9UT1RBTF9MUF9JTlRFR1JBTF9BVAUEdmFsXwUDbmlsARhfbG9hZFVzZXJJbmNvbWVJbnRlZ3JhbHMBBXVzZXJfCgEIZm9sZEZ1bmMCA2FjYwRlbGVtCQDNCAIFA2FjYwkApwMBBQRlbGVtBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBRlLRVlfVVNFUl9JTkNPTUVfSU5URUdSQUxTCQDMCAIJAKUIAQUFdXNlcl8FA25pbAUDU0VQAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAMJAGYCCQCxAgEFAWEAAAoAAiRsCQC9CQIFAWEFA1NFUAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZm9sZEZ1bmMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDExCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwUSWkVST19CSUdJTlRfTElTVDExBRJaRVJPX0JJR0lOVF9MSVNUMTEBGF9zYXZlVXNlckluY29tZUludGVncmFscwIFdXNlcl8EdmFsXwoBCGZvbGRGdW5jAgNhY2MEZWxlbQkAzQgCBQNhY2MJAKYDAQUEZWxlbQkAzAgCCQELU3RyaW5nRW50cnkCCQC5CQIJAMwIAgUZS0VZX1VTRVJfSU5DT01FX0lOVEVHUkFMUwkAzAgCCQClCAEFBXVzZXJfBQNuaWwFA1NFUAkAuwkCCgACJGwFBHZhbF8KAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGZvbGRGdW5jAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsFA1NFUAUDbmlsARhfbG9hZFVzZXJUb3RhbExwSW50ZWdyYWwBBXVzZXJfBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBRtLRVlfVVNFUl9UT1RBTF9MUF9JTlRFR1JBTFMJAMwIAgkApQgBBQV1c2VyXwUDbmlsBQNTRVADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFhBQckbWF0Y2gwCQCnAwEFAWEJALYCAQAAARhfc2F2ZVVzZXJUb3RhbExwSW50ZWdyYWwCBXVzZXJfBHZhbF8JAMwIAgkBC1N0cmluZ0VudHJ5AgkAuQkCCQDMCAIFG0tFWV9VU0VSX1RPVEFMX0xQX0lOVEVHUkFMUwkAzAgCCQClCAEFBXVzZXJfBQNuaWwFA1NFUAkApgMBBQR2YWxfBQNuaWwBEF9sb2FkVXNlclByb2ZpdHMBBXVzZXJfCgEIZm9sZEZ1bmMCA2FjYwRlbGVtCQDNCAIFA2FjYwkBDXBhcnNlSW50VmFsdWUBBQRlbGVtBAckbWF0Y2gwCQCiCAEJALkJAgkAzAgCBRBLRVlfVVNFUl9QUk9GSVRTCQDMCAIJAKUIAQUFdXNlcl8FA25pbAUDU0VQAwkAAQIFByRtYXRjaDACBlN0cmluZwQBYQUHJG1hdGNoMAMJAGYCCQCxAgEFAWEAAAoAAiRsCQC9CQIFAWEFA1NFUAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZm9sZEZ1bmMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDExCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwkAzQgCBQ9aRVJPX0lOVF9MSVNUMTAAAAkAzQgCBQ9aRVJPX0lOVF9MSVNUMTAAAAEQX3NhdmVVc2VyUHJvZml0cwIFdXNlcl8EdmFsXwoBCGZvbGRGdW5jAgNhY2MEZWxlbQkAzQgCBQNhY2MJAKQDAQUEZWxlbQkAzAgCCQELU3RyaW5nRW50cnkCCQC5CQIJAMwIAgUQS0VZX1VTRVJfUFJPRklUUwkAzAgCCQClCAEFBXVzZXJfBQNuaWwFA1NFUAkAuwkCCgACJGwFBHZhbF8KAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGZvbGRGdW5jAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsFA1NFUAUDbmlsARNfd2hlbk5vdEluaXRpYWxpemVkAAQHc3RvcmFnZQkBDF9sb2FkU3RvcmFnZQADCQECIT0CCAUHc3RvcmFnZQJfMQEACQACAQIbX3doZW5Ob3RJbml0aWFsaXplZDogcmV2ZXJ0BgEQX3doZW5Jbml0aWFsaXplZAAEB3N0b3JhZ2UJAQxfbG9hZFN0b3JhZ2UAAwkAAAIIBQdzdG9yYWdlAl8xAQAJAAIBAhhfd2hlbkluaXRpYWxpemVkOiByZXZlcnQGAQxfZ2V0RGVjaW1hbHMBCGFzc2V0SWRfBAckbWF0Y2gwCQDsBwEJANkEAQUIYXNzZXRJZF8DCQABAgUHJG1hdGNoMAIFQXNzZXQEAWEFByRtYXRjaDAIBQFhCGRlY2ltYWxzCQACAQkArAICAhdfZ2V0RGVjaW1hbHM6IG5vIGFzc2V0PQUIYXNzZXRJZF8BEl9ub3JtYWxpemVEZWNpbWFscwQHYW1vdW50Xw9zb3VyY2VEZWNpbWFsc18PdGFyZ2V0RGVjaW1hbHNfBnJvdW5kXwMJAGcCBQ9zb3VyY2VEZWNpbWFsc18FD3RhcmdldERlY2ltYWxzXwkAbgQFB2Ftb3VudF8AAQkAbAYACgAACQBlAgUPc291cmNlRGVjaW1hbHNfBQ90YXJnZXREZWNpbWFsc18AAAAABQRET1dOBQZyb3VuZF8JAGgCBQdhbW91bnRfCQBsBgAKAAAJAGUCBQ90YXJnZXREZWNpbWFsc18FD3NvdXJjZURlY2ltYWxzXwAAAAAFBERPV04BFV9wcmVwYXJlQXNzZXRCYWxhbmNlcwEHYXNzZXRz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YWNjBGVsZW0EBWluZGV4CAUDYWNjAl8xBAdwYXltZW50CQCRAwIFCXBheW1lbnRzXwUFaW5kZXgED3BheW1lbnRBc3NldFN0cgkBC19hc3NldFRvU3RyAQgFB3BheW1lbnQHYXNzZXRJZAQDZXJyAwkBAiE9AgUPcGF5bWVudEFzc2V0U3RyCQCRAwIFB2Fzc2V0c18FBWluZGV4CQACAQkArAICCQCsAgIFBGVycl8CCDogaW5kZXg9CQCkAwEFBWluZGV4BQR1bml0AwkAAAIFA2VycgUDZXJyBA1hc3NldERlY2ltYWxzCQEMX2dldERlY2ltYWxzAQUPcGF5bWVudEFzc2V0U3RyBApuZXdCYWxhbmNlCQBkAgUEZWxlbQkBEl9ub3JtYWxpemVEZWNpbWFscwQICQCRAwIFCXBheW1lbnRzXwUFaW5kZXgGYW1vdW50BQ1hc3NldERlY2ltYWxzBQlkZWNpbWFsc18FBERPV04JAJUKAwkAZAIFBWluZGV4AAEJAM0IAggFA2FjYwJfMgUKbmV3QmFsYW5jZQkAZAIIBQNhY2MCXzMFCm5ld0JhbGFuY2UJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EBnJlc3VsdAoAAiRsBQliYWxhbmNlc18KAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCVCgMAAAUDbmlsAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGZvbGRGdW5jAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCQCUCgIIBQZyZXN1bHQCXzIIBQZyZXN1bHQCXzMBGF9pbmNyZW1lbnRCYWxhbmNlQnlJbmRleAMJYmFsYW5jZXNfBmluZGV4XwdhbW91bnRfCgEIZm9sZEZ1bmMCA2FjYwRlbGVtBAVpbmRleAgFA2FjYwJfMQMJAAACBQVpbmRleAUGaW5kZXhfCQCUCgIJAGQCBQVpbmRleAABCQDNCAIIBQNhY2MCXzIJAGQCBQRlbGVtBQdhbW91bnRfCQCUCgIJAGQCBQVpbmRleAABCQDNCAIIBQNhY2MCXzIFBGVsZW0EBnJlc3VsdAoAAiRsBQliYWxhbmNlc18KAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmb2xkRnVuYwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACggFBnJlc3VsdAJfMgEYX2RlY3JlbWVudEJhbGFuY2VCeUluZGV4AwliYWxhbmNlc18GaW5kZXhfB2Ftb3VudF8KAQhmb2xkRnVuYwIDYWNjBGVsZW0EBWluZGV4CAUDYWNjAl8xAwkAAAIFBWluZGV4BQZpbmRleF8JAJQKAgkAZAIFBWluZGV4AAEJAM0IAggFA2FjYwJfMgkAZQIFBGVsZW0FB2Ftb3VudF8JAJQKAgkAZAIFBWluZGV4AAEJAM0IAggFA2FjYwJfMgUEZWxlbQQGcmVzdWx0CgACJGwFCWJhbGFuY2VzXwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgAABQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGZvbGRGdW5jAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCAUGcmVzdWx0Al8yARxfZGVjcmVtZW50QmFsYW5jZXNCeUxwQW1vdW50AwliYWxhbmNlc18HYW1vdW50Xw5scFRvdGFsU3VwcGx5XwQEcmF0ZQkAbgQJAGUCBQ5scFRvdGFsU3VwcGx5XwUHYW1vdW50XwULUkFURV9GQUNUT1IFDmxwVG90YWxTdXBwbHlfBQdDRUlMSU5HCgEIZm9sZEZ1bmMCA2FjYwRlbGVtBApuZXdCYWxhbmNlCQBuBAUEZWxlbQUEcmF0ZQULUkFURV9GQUNUT1IFB0NFSUxJTkcEDGRlbHRhQmFsYW5jZQkAZQIFBGVsZW0FCm5ld0JhbGFuY2UJAJUKAwkAzQgCCAUDYWNjAl8xBQpuZXdCYWxhbmNlCQBkAggFA2FjYwJfMgUKbmV3QmFsYW5jZQkAzQgCCAUDYWNjAl8zBQxkZWx0YUJhbGFuY2UKAAIkbAUJYmFsYW5jZXNfCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlQoDBQNuaWwAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmb2xkRnVuYwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgEYX2dldFBheW1lbnRzRnJvbUJhbGFuY2VzBAdhc3NldHNfCWJhbGFuY2VzXwpyZWNpcGllbnRfD3NvdXJjZURlY2ltYWxzXwoBCGZvbGRGdW5jAgNhY2MEZWxlbQQFaW5kZXgIBQNhY2MCXzEJAJQKAgkAZAIFBWluZGV4AAEJAM0IAggFA2FjYwJfMgkBDlNjcmlwdFRyYW5zZmVyAwUKcmVjaXBpZW50XwkBEl9ub3JtYWxpemVEZWNpbWFscwQJAJEDAgUJYmFsYW5jZXNfBQVpbmRleAUPc291cmNlRGVjaW1hbHNfCQEMX2dldERlY2ltYWxzAQUEZWxlbQUERE9XTgkBC19zdHJUb0Fzc2V0AQUEZWxlbQQGcmVzdWx0CgACJGwFB2Fzc2V0c18KAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmb2xkRnVuYwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACggFBnJlc3VsdAJfMgESX2NhbGN1bGF0ZU1pY3JvRmVlBQhiYWxhbmNlXwxlcXVpbGlicml1bV8Qd2VpZ2h0QW1wbGlmaWVyXw1zbGlwcGFnZVJhdGVfC2ZlZU1heFJhdGVfAwkAZgIFDGVxdWlsaWJyaXVtXwUIYmFsYW5jZV8ECXRocmVzaG9sZAkAawMFDGVxdWlsaWJyaXVtXwkAZQIFFE1BWF9XRUlHSFRfQU1QTElGSUVSBRB3ZWlnaHRBbXBsaWZpZXJfBRRNQVhfV0VJR0hUX0FNUExJRklFUgMJAGYCBQl0aHJlc2hvbGQFCGJhbGFuY2VfBAxtYXhEZXZpYXRpb24JAGUCBQl0aHJlc2hvbGQFCGJhbGFuY2VfBAdmZWVSYXRlCQBrAwkAawMFDG1heERldmlhdGlvbgUNc2xpcHBhZ2VSYXRlXwUUU0xJUFBBR0VfUkFURV9GQUNUT1IFD0ZFRV9SQVRFX0ZBQ1RPUgUMZXF1aWxpYnJpdW1fAwkAZgIFB2ZlZVJhdGUFC2ZlZU1heFJhdGVfCQBrAwUMbWF4RGV2aWF0aW9uBQtmZWVNYXhSYXRlXwUPRkVFX1JBVEVfRkFDVE9SCQBrAwUMbWF4RGV2aWF0aW9uBQdmZWVSYXRlBQ9GRUVfUkFURV9GQUNUT1IAAAQJdGhyZXNob2xkCQBrAwUMZXF1aWxpYnJpdW1fCQBkAgUUTUFYX1dFSUdIVF9BTVBMSUZJRVIFEHdlaWdodEFtcGxpZmllcl8FFE1BWF9XRUlHSFRfQU1QTElGSUVSAwkAZgIFCGJhbGFuY2VfBQl0aHJlc2hvbGQEDG1heERldmlhdGlvbgkAZQIFCGJhbGFuY2VfBQl0aHJlc2hvbGQEB2ZlZVJhdGUJAGsDCQBrAwUMbWF4RGV2aWF0aW9uBQ1zbGlwcGFnZVJhdGVfBRRTTElQUEFHRV9SQVRFX0ZBQ1RPUgUPRkVFX1JBVEVfRkFDVE9SBQxlcXVpbGlicml1bV8DCQBmAgUHZmVlUmF0ZQULZmVlTWF4UmF0ZV8JAGsDBQxtYXhEZXZpYXRpb24FC2ZlZU1heFJhdGVfBQ9GRUVfUkFURV9GQUNUT1IJAGsDBQxtYXhEZXZpYXRpb24FB2ZlZVJhdGUFD0ZFRV9SQVRFX0ZBQ1RPUgAAAQ1fY2FsY3VsYXRlRmVlBwliYWxhbmNlc18SYXNzZXRzVG90YWxTdXBwbHlfCHdlaWdodHNfDHNpZ21hV2VpZ2h0XxB3ZWlnaHRBbXBsaWZpZXJfDXNsaXBwYWdlUmF0ZV8LZmVlTWF4UmF0ZV8KAQhmb2xkRnVuYwIDYWNjB2JhbGFuY2UEBWluZGV4CAUDYWNjAl8xBAtlcXVpbGlicml1bQkAawMFEmFzc2V0c1RvdGFsU3VwcGx5XwkAkQMCBQh3ZWlnaHRzXwUFaW5kZXgFDHNpZ21hV2VpZ2h0XwkAlAoCCQBkAgUFaW5kZXgAAQkAZAIIBQNhY2MCXzIJARJfY2FsY3VsYXRlTWljcm9GZWUFBQdiYWxhbmNlBQtlcXVpbGlicml1bQUQd2VpZ2h0QW1wbGlmaWVyXwUNc2xpcHBhZ2VSYXRlXwULZmVlTWF4UmF0ZV8EBnJlc3VsdAoAAiRsBQliYWxhbmNlc18KAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmb2xkRnVuYwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACggFBnJlc3VsdAJfMgEbX3ZhbGlkYXRlTGlxdWlkaXR5SW52YXJpYW50CxJwcmV2QXNzZXRCYWxhbmNlc18VcHJldkFzc2V0VG90YWxTdXBwbHlfDmFzc2V0QmFsYW5jZXNfEWFzc2V0VG90YWxTdXBwbHlfEnByZXZMcFRvdGFsU3VwcGx5Xw5scFRvdGFsU3VwcGx5Xw1hc3NldFdlaWdodHNfDHNpZ21hV2VpZ2h0XxB3ZWlnaHRBbXBsaWZpZXJfDXNsaXBwYWdlUmF0ZV8LZmVlTWF4UmF0ZV8DAwkAAAIFEnByZXZMcFRvdGFsU3VwcGx5XwAABgkAAAIFDmxwVG90YWxTdXBwbHlfAAAGBA5wcmV2QXNzZXRzUmF0ZQkAawMJAGUCBRVwcmV2QXNzZXRUb3RhbFN1cHBseV8JAQ1fY2FsY3VsYXRlRmVlBwUScHJldkFzc2V0QmFsYW5jZXNfBRVwcmV2QXNzZXRUb3RhbFN1cHBseV8FDWFzc2V0V2VpZ2h0c18FDHNpZ21hV2VpZ2h0XwUQd2VpZ2h0QW1wbGlmaWVyXwUNc2xpcHBhZ2VSYXRlXwULZmVlTWF4UmF0ZV8FC1JBVEVfRkFDVE9SBRJwcmV2THBUb3RhbFN1cHBseV8EDW5ld0Fzc2V0c1JhdGUJAGsDCQBlAgURYXNzZXRUb3RhbFN1cHBseV8JAQ1fY2FsY3VsYXRlRmVlBwUOYXNzZXRCYWxhbmNlc18FEWFzc2V0VG90YWxTdXBwbHlfBQ1hc3NldFdlaWdodHNfBQxzaWdtYVdlaWdodF8FEHdlaWdodEFtcGxpZmllcl8FDXNsaXBwYWdlUmF0ZV8FC2ZlZU1heFJhdGVfBQtSQVRFX0ZBQ1RPUgUObHBUb3RhbFN1cHBseV8EBGRpZmYJAGUCBQ1uZXdBc3NldHNSYXRlBQ5wcmV2QXNzZXRzUmF0ZQMDCQBnAgAABQRkaWZmCQBmAgkAaAIA////////////AQULUkFURV9GQUNUT1IFBGRpZmYHCQACAQkArAICAipfdmFsaWRhdGVMaXF1aWRpdHlJbnZhcmlhbnQ6IHJldmVydDogZGlmZj0JAKQDAQUEZGlmZgYBFl92YWxpZGF0ZVN3YXBJbnZhcmlhbnQJEnByZXZBc3NldEJhbGFuY2VzXxVwcmV2QXNzZXRUb3RhbFN1cHBseV8OYXNzZXRCYWxhbmNlc18RYXNzZXRUb3RhbFN1cHBseV8NYXNzZXRXZWlnaHRzXwxzaWdtYVdlaWdodF8Qd2VpZ2h0QW1wbGlmaWVyXw1zbGlwcGFnZVJhdGVfC2ZlZU1heFJhdGVfBAhwcmV2VXRpbAkAZQIFFXByZXZBc3NldFRvdGFsU3VwcGx5XwkBDV9jYWxjdWxhdGVGZWUHBRJwcmV2QXNzZXRCYWxhbmNlc18FFXByZXZBc3NldFRvdGFsU3VwcGx5XwUNYXNzZXRXZWlnaHRzXwUMc2lnbWFXZWlnaHRfBRB3ZWlnaHRBbXBsaWZpZXJfBQ1zbGlwcGFnZVJhdGVfBQtmZWVNYXhSYXRlXwQHbmV3VXRpbAkAZQIFEWFzc2V0VG90YWxTdXBwbHlfCQENX2NhbGN1bGF0ZUZlZQcFDmFzc2V0QmFsYW5jZXNfBRFhc3NldFRvdGFsU3VwcGx5XwUNYXNzZXRXZWlnaHRzXwUMc2lnbWFXZWlnaHRfBRB3ZWlnaHRBbXBsaWZpZXJfBQ1zbGlwcGFnZVJhdGVfBQtmZWVNYXhSYXRlXwQEZGlmZgkAZQIFB25ld1V0aWwFCHByZXZVdGlsAwMJAGcCAAAFBGRpZmYJAGYCCQBoAgD///////////8BBQtSQVRFX0ZBQ1RPUgUEZGlmZgcJAAIBCQCsAgICJV92YWxpZGF0ZVN3YXBJbnZhcmlhbnQ6IHJldmVydDogZGlmZj0JAKQDAQUEZGlmZgYBGF92YWxpZGF0ZUFzc2V0QWxsb2NhdGlvbgcIYmFsYW5jZV8RYXNzZXRUb3RhbFN1cHBseV8McHJldkJhbGFuY2VfFXByZXZBc3NldFRvdGFsU3VwcGx5Xwd3ZWlnaHRfDHNpZ21hV2VpZ2h0XwxtYXhBbGxvY0FtcF8EC2VxdWlsaWJyaXVtCQBrAwURYXNzZXRUb3RhbFN1cHBseV8FB3dlaWdodF8FDHNpZ21hV2VpZ2h0XwQQbWF4QWxsb2NhdGlvbkFtcAMJAGYCBQhiYWxhbmNlXwULZXF1aWxpYnJpdW0JAGQCBQ1NQVhfQU1QTElGSUVSBQxtYXhBbGxvY0FtcF8JAGUCBQ1NQVhfQU1QTElGSUVSBQxtYXhBbGxvY0FtcF8EDW1heEFsbG9jYXRpb24JAGsDBQtlcXVpbGlicml1bQUQbWF4QWxsb2NhdGlvbkFtcAUNTUFYX0FNUExJRklFUgQRcHJldk1heEFsbG9jYXRpb24JAGsDCQBrAwUVcHJldkFzc2V0VG90YWxTdXBwbHlfBQd3ZWlnaHRfBQxzaWdtYVdlaWdodF8FEG1heEFsbG9jYXRpb25BbXAFDU1BWF9BTVBMSUZJRVIDCQBmAgUIYmFsYW5jZV8FC2VxdWlsaWJyaXVtAwkAZgIFCGJhbGFuY2VfBQ1tYXhBbGxvY2F0aW9uAwkAZgIFEXByZXZNYXhBbGxvY2F0aW9uBQxwcmV2QmFsYW5jZV8JAAIBAiBfdmFsaWRhdGVBc3NldEFsbG9jYXRpb246IG5ldyB1cAMJAGYCCQBlAgUIYmFsYW5jZV8FDW1heEFsbG9jYXRpb24JAGUCBQxwcmV2QmFsYW5jZV8FEXByZXZNYXhBbGxvY2F0aW9uCQACAQIiX3ZhbGlkYXRlQXNzZXRBbGxvY2F0aW9uOiBzdGlsbCB1cAYGAwkAZgIFDW1heEFsbG9jYXRpb24FCGJhbGFuY2VfAwkAZgIFDHByZXZCYWxhbmNlXwURcHJldk1heEFsbG9jYXRpb24JAAIBAiJfdmFsaWRhdGVBc3NldEFsbG9jYXRpb246IG5ldyBkb3duAwkAZgIJAGUCBRFwcmV2TWF4QWxsb2NhdGlvbgUMcHJldkJhbGFuY2VfCQBlAgUNbWF4QWxsb2NhdGlvbgUIYmFsYW5jZV8JAAIBAiRfdmFsaWRhdGVBc3NldEFsbG9jYXRpb246IHN0aWxsIGRvd24GBgETX3ZhbGlkYXRlQWxsb2NhdGlvbgcOYXNzZXRCYWxhbmNlc18RYXNzZXRUb3RhbFN1cHBseV8ScHJldkFzc2V0QmFsYW5jZXNfFXByZXZBc3NldFRvdGFsU3VwcGx5Xw1hc3NldFdlaWdodHNfDHNpZ21hV2VpZ2h0XwxtYXhBbGxvY0FtcF8KAQhmb2xkRnVuYwIDYWNjBGVsZW0EBWluZGV4CAUDYWNjAl8xCQCUCgIJAGQCBQVpbmRleAABAwgFA2FjYwJfMgkBGF92YWxpZGF0ZUFzc2V0QWxsb2NhdGlvbgcFBGVsZW0FEWFzc2V0VG90YWxTdXBwbHlfCQCRAwIFEnByZXZBc3NldEJhbGFuY2VzXwUFaW5kZXgFFXByZXZBc3NldFRvdGFsU3VwcGx5XwkAkQMCBQ1hc3NldFdlaWdodHNfBQVpbmRleAUMc2lnbWFXZWlnaHRfBQxtYXhBbGxvY0FtcF8HBAZyZXN1bHQKAAIkbAUOYXNzZXRCYWxhbmNlc18KAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAYKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGZvbGRGdW5jAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCAUGcmVzdWx0Al8yAQ9fdXNlckNoZWNrcG9pbnQEBXVzZXJfB3VzZXJMcF8VdG90YWxJbmNvbWVJbnRlZ3JhbHNfEHRvdGFsTHBJbnRlZ3JhbF8EC3VzZXJQcm9maXRzCQEQX2xvYWRVc2VyUHJvZml0cwEFBXVzZXJfBBN1c2VySW5jb21lSW50ZWdyYWxzCQEYX2xvYWRVc2VySW5jb21lSW50ZWdyYWxzAQUFdXNlcl8EE3VzZXJUb3RhbExwSW50ZWdyYWwJARhfbG9hZFVzZXJUb3RhbExwSW50ZWdyYWwBBQV1c2VyXwoBCGZvbGRGdW5jAgNhY2MEZWxlbQQFaW5kZXgIBQNhY2MCXzEEDXByb2ZpdFVwZGF0ZWQJAGQCBQRlbGVtCQCgAwEJALwCAwkAtgIBBQd1c2VyTHBfCQC4AgIJAJEDAgUVdG90YWxJbmNvbWVJbnRlZ3JhbHNfBQVpbmRleAkAkQMCBRN1c2VySW5jb21lSW50ZWdyYWxzBQVpbmRleAkAuAICBRB0b3RhbExwSW50ZWdyYWxfBRN1c2VyVG90YWxMcEludGVncmFsCQCVCgMJAGQCBQVpbmRleAABCQDNCAIIBQNhY2MCXzIFDXByb2ZpdFVwZGF0ZWQIBQNhY2MCXzMEDSR0MDI0ODkyMjQ5NjQKAAIkbAULdXNlclByb2ZpdHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCVCgMAAAUDbmlsBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGZvbGRGdW5jAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsEA2lkeAgFDSR0MDI0ODkyMjQ5NjQCXzEEDnByb2ZpdHNVcGRhdGVkCAUNJHQwMjQ4OTIyNDk2NAJfMgkAlAoCBQ5wcm9maXRzVXBkYXRlZAkAzggCCQDOCAIJARhfc2F2ZVVzZXJJbmNvbWVJbnRlZ3JhbHMCBQV1c2VyXwUVdG90YWxJbmNvbWVJbnRlZ3JhbHNfCQEYX3NhdmVVc2VyVG90YWxMcEludGVncmFsAgUFdXNlcl8FEHRvdGFsTHBJbnRlZ3JhbF8JARBfc2F2ZVVzZXJQcm9maXRzAgUFdXNlcl8FDnByb2ZpdHNVcGRhdGVkAQtfY2hlY2twb2ludAEHYXNzZXRzXwQPaW5jb21lSW50ZWdyYWxzCQEUX2xvYWRJbmNvbWVJbnRlZ3JhbHMABBBpbmNvbWVJbnRlZ2Fsc0F0CQEWX2xvYWRJbmNvbWVJbnRlZ3JhbHNBdAAKAQhmb2xkRnVuYwIDYWNjBGVsZW0EBWluZGV4CAUDYWNjAl8xBA5pbmNvbWVJbnRlZ3JhbAkAtwICCQCRAwIFD2luY29tZUludGVncmFscwUFaW5kZXgJALkCAgkAtgIBCQEOX2xvYWRGZWVJbmNvbWUBBQRlbGVtCQC2AgEJAGUCBQZoZWlnaHQJAJEDAgUQaW5jb21lSW50ZWdhbHNBdAUFaW5kZXgJAJUKAwkAZAIFBWluZGV4AAEJAM0IAggFA2FjYwJfMgUOaW5jb21lSW50ZWdyYWwJAM0IAggFA2FjYwJfMwUGaGVpZ2h0BBZ0b3RhbExwSW50ZWdyYWxVcGRhdGVkCQC3AgIJARRfbG9hZFRvdGFsTHBJbnRlZ3JhbAAJALkCAgkAtgIBCQEMX2xvYWRUb3RhbExwAAkAtgIBCQBlAgUGaGVpZ2h0CQEWX2xvYWRUb3RhbExwSW50ZWdyYWxBdAAEDSR0MDI1ODM3MjU5MzgKAAIkbAUHYXNzZXRzXwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJUKAwAABQNuaWwFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZm9sZEZ1bmMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDExCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwQDaWR4CAUNJHQwMjU4MzcyNTkzOAJfMQQWaW5jb21lSW50ZWdyYWxzVXBkYXRlZAgFDSR0MDI1ODM3MjU5MzgCXzIEF2luY29tZUludGVnYWxzQXRVcGRhdGVkCAUNJHQwMjU4MzcyNTkzOAJfMwkAlQoDBRZpbmNvbWVJbnRlZ3JhbHNVcGRhdGVkBRZ0b3RhbExwSW50ZWdyYWxVcGRhdGVkCQDOCAIJAM4IAgkAzggCCQEUX3NhdmVJbmNvbWVJbnRlZ3JhbHMBBRZpbmNvbWVJbnRlZ3JhbHNVcGRhdGVkCQEWX3NhdmVJbmNvbWVJbnRlZ3JhbHNBdAEFF2luY29tZUludGVnYWxzQXRVcGRhdGVkCQEUX3NhdmVUb3RhbExwSW50ZWdyYWwBBRZ0b3RhbExwSW50ZWdyYWxVcGRhdGVkCQEWX3NhdmVUb3RhbExwSW50ZWdyYWxBdAEFBmhlaWdodAkBaQEEaW5pdAsHYXNzZXRzXw1hc3NldFdlaWdodHNfCmxwRmVlUmF0ZV8QcHJvdG9jb2xGZWVSYXRlXwxscFRva2VuTmFtZV8NbHBUb2tlbkRlc2NyXxBscFRva2VuRGVjaW1hbHNfF21heEFsbG9jYXRpb25BbXBsaWZpZXJfEHdlaWdodEFtcGxpZmllcl8Nc2xpcHBhZ2VSYXRlXwtmZWVNYXhSYXRlXwQDZXJyAwMDAwMDAwMDAwMDCQETX3doZW5Ob3RJbml0aWFsaXplZAAJAQ9fdmFsaWRhdGVBc3NldHMCBQdhc3NldHNfAhRpbml0OiBpbnZhbGlkIGFzc2V0cwcJARBfdmFsaWRhdGVJbnRMaXN0BAUNYXNzZXRXZWlnaHRzXwAABQpNQVhfV0VJR0hUAhppbml0OiBpbnZhbGlkIGFzc2V0V2VpZ2h0cwcJARJfdmFsaWRhdGVJbnRFcXVhbHMDCQCQAwEFB2Fzc2V0c18JAJADAQUNYXNzZXRXZWlnaHRzXwIfaW5pdDogaW52YWxpZCBhc3NldFdlaWdodHMgc2l6ZQcJAQxfdmFsaWRhdGVJbnQEBQpscEZlZVJhdGVfAAAFB01BWF9GRUUCFGluaXQ6IGludmFsaWQgbHAgZmVlBwkBDF92YWxpZGF0ZUludAQFEHByb3RvY29sRmVlUmF0ZV8AAAUHTUFYX0ZFRQIaaW5pdDogaW52YWxpZCBwcm90b2NvbCBmZWUHCQESX3ZhbGlkYXRlVG9rZW5OYW1lAgUMbHBUb2tlbk5hbWVfAhJpbml0OiBpbnZhbGlkIG5hbWUHCQETX3ZhbGlkYXRlVG9rZW5EZXNjcgIFDWxwVG9rZW5EZXNjcl8CE2luaXQ6IGludmFsaWQgZGVzY3IHCQERX3ZhbGlkYXRlRGVjaW1hbHMCBRBscFRva2VuRGVjaW1hbHNfAhZpbml0OiBpbnZhbGlkIGRlY2ltYWxzBwkBDF92YWxpZGF0ZUludAQFF21heEFsbG9jYXRpb25BbXBsaWZpZXJfAAAFDU1BWF9BTVBMSUZJRVICJGluaXQ6IGludmFsaWQgbWF4QWxsb2NhdGlvbkFtcGxpZmllcgcJAQxfdmFsaWRhdGVJbnQEBRB3ZWlnaHRBbXBsaWZpZXJfAAAFF21heEFsbG9jYXRpb25BbXBsaWZpZXJfAh1pbml0OiBpbnZhbGlkIHdlaWdodEFtcGxpZmllcgcJAQxfdmFsaWRhdGVJbnQEBQ1zbGlwcGFnZVJhdGVfAAAFB01BWF9JTlQCGmluaXQ6IGludmFsaWQgc2xpcHBhZ2VSYXRlBwkBDF92YWxpZGF0ZUludAQFC2ZlZU1heFJhdGVfAAAFB01BWF9JTlQCGGluaXQ6IGludmFsaWQgZmVlTWF4UmF0ZQcDCQAAAgUDZXJyBQNlcnIEDSR0MDI3NjM5Mjc3MDgJARRfcHJlcGFyZUFzc2V0V2VpZ2h0cwEFDWFzc2V0V2VpZ2h0c18EDGFzc2V0V2VpZ2h0cwgFDSR0MDI3NjM5Mjc3MDgCXzEEC3NpZ21hV2VpZ2h0CAUNJHQwMjc2MzkyNzcwOAJfMgQNYXNzZXRCYWxhbmNlcwkBFV9wcmVwYXJlQXNzZXRCYWxhbmNlcwEFB2Fzc2V0c18EBWlzc3VlCQDCCAUFDGxwVG9rZW5OYW1lXwUNbHBUb2tlbkRlc2NyXwAABRBscFRva2VuRGVjaW1hbHNfBgQJbHBBc3NldElkCQC4CAEFBWlzc3VlBA5zdG9yYWdlVXBkYXRlZAkAmwoJBQlscEFzc2V0SWQGAAAFCmxwRmVlUmF0ZV8FEHByb3RvY29sRmVlUmF0ZV8FF21heEFsbG9jYXRpb25BbXBsaWZpZXJfBRB3ZWlnaHRBbXBsaWZpZXJfBQ1zbGlwcGFnZVJhdGVfBQtmZWVNYXhSYXRlXwkAlAoCCQDOCAIJAM4IAgkAzggCCQDOCAIJAMwIAgUFaXNzdWUFA25pbAkBDF9zYXZlU3RvcmFnZQEFDnN0b3JhZ2VVcGRhdGVkCQELX3NhdmVBc3NldHMBBQdhc3NldHNfCQESX3NhdmVBc3NldEJhbGFuY2VzAQUNYXNzZXRCYWxhbmNlcwkBEV9zYXZlQXNzZXRXZWlnaHRzAQUMYXNzZXRXZWlnaHRzBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCmRlcG9zaXRBbGwBB2Ftb3VudF8EA2VycgkBDF92YWxpZGF0ZUludAQFB2Ftb3VudF8AAAUHTUFYX0lOVAIaZGVwb3NpdEFsbDogaW52YWxpZCBhbW91bnQDCQAAAgUDZXJyBQNlcnIEB3N0b3JhZ2UJAQxfbG9hZFN0b3JhZ2UABAlscEFzc2V0SWQIBQdzdG9yYWdlAl8xBApscERlY2ltYWxzCQEMX2dldERlY2ltYWxzAQkA2AQBBQlscEFzc2V0SWQEDWxwVG90YWxTdXBwbHkIBQdzdG9yYWdlAl8zBA93ZWlnaHRBbXBsaWZpZXIIBQdzdG9yYWdlAl83BAxzbGlwcGFnZVJhdGUIBQdzdG9yYWdlAl84BApmZWVNYXhSYXRlCAUHc3RvcmFnZQJfOQQGYXNzZXRzCQELX2xvYWRBc3NldHMABA0kdDAyOTAyODI5MDgxCQERX2xvYWRBc3NldFdlaWdodHMABAxhc3NldFdlaWdodHMIBQ0kdDAyOTAyODI5MDgxAl8xBAtzaWdtYVdlaWdodAgFDSR0MDI5MDI4MjkwODECXzIEDSR0MDI5MDg2MjkxNTQJARJfbG9hZEFzc2V0QmFsYW5jZXMABBFwcmV2QXNzZXRCYWxhbmNlcwgFDSR0MDI5MDg2MjkxNTQCXzEEFHByZXZBc3NldFRvdGFsU3VwcGx5CAUNJHQwMjkwODYyOTE1NAJfMgQNJHQwMjkxNjAzMjQ2NQMJAAACBRRwcmV2QXNzZXRUb3RhbFN1cHBseQAACgEIZm9sZEZ1bmMCA2FjYwRlbGVtBAVpbmRleAgFA2FjYwJfMQQPcGF5bWVudEFzc2V0U3RyCQELX2Fzc2V0VG9TdHIBCAkAkQMCCAUBaQhwYXltZW50cwUFaW5kZXgHYXNzZXRJZAQUcGF5bWVudEFzc2V0RGVjaW1hbHMJAQxfZ2V0RGVjaW1hbHMBBQ9wYXltZW50QXNzZXRTdHIEGHJlcXVpcmVkQW1vdW50Tm9ybWFsaXplZAkAawMJAJEDAgUMYXNzZXRXZWlnaHRzBQVpbmRleAUHYW1vdW50XwULc2lnbWFXZWlnaHQEDnJlcXVpcmVkQW1vdW50CQESX25vcm1hbGl6ZURlY2ltYWxzBAUYcmVxdWlyZWRBbW91bnROb3JtYWxpemVkBQpscERlY2ltYWxzBRRwYXltZW50QXNzZXREZWNpbWFscwUHQ0VJTElORwQEZXJyMQMJAQIhPQIFD3BheW1lbnRBc3NldFN0cgUEZWxlbQkAAgEJAKwCAgIjZGVwb3NpdEFsbDogaW52YWxpZCBwYXltZW50OiBpbmRleD0JAKQDAQUFaW5kZXgDCQBnAgAABQ5yZXF1aXJlZEFtb3VudAkAAgECJmRlcG9zaXRBbGw6IHRvbyBsaXR0bGUgYW1vdW50IHJlcXVpcmVkBQR1bml0AwkAAAIFBGVycjEFBGVycjEEBmNoYW5nZQMJAGYCCAkAkQMCCAUBaQhwYXltZW50cwUFaW5kZXgGYW1vdW50BQ5yZXF1aXJlZEFtb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGUCCAkAkQMCCAUBaQhwYXltZW50cwUFaW5kZXgGYW1vdW50BQ5yZXF1aXJlZEFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMFBWluZGV4B2Fzc2V0SWQFA25pbAMJAGYCBQ5yZXF1aXJlZEFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMFBWluZGV4BmFtb3VudAkAAgEJAKwCAgkArAICCQCsAgICKGRlcG9zaXRBbGw6IGluc3VmZmljaWVudCBwYXltZW50LCBpbmRleD0JAKQDAQUFaW5kZXgCCywgcmVxdWlyZWQ9CQCkAwEFDnJlcXVpcmVkQW1vdW50BQNuaWwJAJUKAwkAZAIFBWluZGV4AAEJAM4IAggFA2FjYwJfMgUGY2hhbmdlCQDNCAIIBQNhY2MCXzMFGHJlcXVpcmVkQW1vdW50Tm9ybWFsaXplZAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQGcmVzdWx0CgACJGwFBmFzc2V0cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJUKAwAABQNuaWwFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZm9sZEZ1bmMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJAJUKAwUHYW1vdW50XwgFBnJlc3VsdAJfMggFBnJlc3VsdAJfMwQFcmF0aW8JALwCAwkAtgIBBQdhbW91bnRfBQ5QRVJDRU5UX0ZBQ1RPUgkAtgIBBRRwcmV2QXNzZXRUb3RhbFN1cHBseQoBCWZvbGRGdW5jMQIDYWNjBGVsZW0EBWluZGV4CAUDYWNjAl8xBA9wYXltZW50QXNzZXRTdHIJAQtfYXNzZXRUb1N0cgEICQCRAwIIBQFpCHBheW1lbnRzBQVpbmRleAdhc3NldElkBBRwYXltZW50QXNzZXREZWNpbWFscwkBDF9nZXREZWNpbWFscwEFD3BheW1lbnRBc3NldFN0cgQYcmVxdWlyZWRBbW91bnROb3JtYWxpemVkCQCgAwEJALwCAwUFcmF0aW8JALYCAQkAkQMCBRFwcmV2QXNzZXRCYWxhbmNlcwUFaW5kZXgFDlBFUkNFTlRfRkFDVE9SBA5yZXF1aXJlZEFtb3VudAkBEl9ub3JtYWxpemVEZWNpbWFscwQFGHJlcXVpcmVkQW1vdW50Tm9ybWFsaXplZAUKbHBEZWNpbWFscwUUcGF5bWVudEFzc2V0RGVjaW1hbHMFB0NFSUxJTkcEBGVycjEDCQECIT0CBQ9wYXltZW50QXNzZXRTdHIFBGVsZW0JAAIBCQCsAgICI2RlcG9zaXRBbGw6IGludmFsaWQgcGF5bWVudDogaW5kZXg9CQCkAwEFBWluZGV4AwkAZwIAAAUOcmVxdWlyZWRBbW91bnQJAAIBAiZkZXBvc2l0QWxsOiB0b28gbGl0dGxlIGFtb3VudCByZXFpdXJlZAUEdW5pdAMJAAACBQRlcnIxBQRlcnIxBAZjaGFuZ2UDCQBmAggJAJEDAggFAWkIcGF5bWVudHMFBWluZGV4BmFtb3VudAUOcmVxdWlyZWRBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQBlAggJAJEDAggFAWkIcGF5bWVudHMFBWluZGV4BmFtb3VudAUOcmVxdWlyZWRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzBQVpbmRleAdhc3NldElkBQNuaWwDCQBmAgUOcmVxdWlyZWRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzBQVpbmRleAZhbW91bnQJAAIBCQCsAgIJAKwCAgkArAICAihkZXBvc2l0QWxsOiBpbnN1ZmZpY2llbnQgcGF5bWVudCwgaW5kZXg9CQCkAwEFBWluZGV4AgssIHJlcXVpcmVkPQkApAMBBQ5yZXF1aXJlZEFtb3VudAUDbmlsCQCVCgMJAGQCBQVpbmRleAABCQDOCAIIBQNhY2MCXzIFBmNoYW5nZQkAzQgCCAUDYWNjAl8zBRhyZXF1aXJlZEFtb3VudE5vcm1hbGl6ZWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EBnJlc3VsdAoAAiRsBQZhc3NldHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCVCgMAAAUDbmlsBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCWZvbGRGdW5jMQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkAlQoDCQBrAwUHYW1vdW50XwUNbHBUb3RhbFN1cHBseQUUcHJldkFzc2V0VG90YWxTdXBwbHkIBQZyZXN1bHQCXzIIBQZyZXN1bHQCXzMEDmxwVG9rZW5zVG9NaW50CAUNJHQwMjkxNjAzMjQ2NQJfMQQNY2hhbmdlQWN0aW9ucwgFDSR0MDI5MTYwMzI0NjUCXzIEGXJlcXVpcmVkQW1vdW50c05vcm1hbGl6ZWQIBQ0kdDAyOTE2MDMyNDY1Al8zBA0kdDAzMjQ3MTMyNTg0CQEbX2luY3JlbWVudEJhbGFuY2VzQnlBbW91bnRzAgURcHJldkFzc2V0QmFsYW5jZXMFGXJlcXVpcmVkQW1vdW50c05vcm1hbGl6ZWQEDWFzc2V0QmFsYW5jZXMIBQ0kdDAzMjQ3MTMyNTg0Al8xBBBhc3NldFRvdGFsU3VwcGx5CAUNJHQwMzI0NzEzMjU4NAJfMgQEZXJyMgkBG192YWxpZGF0ZUxpcXVpZGl0eUludmFyaWFudAsFEXByZXZBc3NldEJhbGFuY2VzBRRwcmV2QXNzZXRUb3RhbFN1cHBseQUNYXNzZXRCYWxhbmNlcwUQYXNzZXRUb3RhbFN1cHBseQUNbHBUb3RhbFN1cHBseQkAZAIFDWxwVG90YWxTdXBwbHkFDmxwVG9rZW5zVG9NaW50BQxhc3NldFdlaWdodHMFC3NpZ21hV2VpZ2h0BQ93ZWlnaHRBbXBsaWZpZXIFDHNsaXBwYWdlUmF0ZQUKZmVlTWF4UmF0ZQMJAAACBQRlcnIyBQRlcnIyBA5zdG9yYWdlVXBkYXRlZAkAmwoJCAUHc3RvcmFnZQJfMQgFB3N0b3JhZ2UCXzIJAGQCBQ1scFRvdGFsU3VwcGx5BQ5scFRva2Vuc1RvTWludAgFB3N0b3JhZ2UCXzQIBQdzdG9yYWdlAl81CAUHc3RvcmFnZQJfNggFB3N0b3JhZ2UCXzcIBQdzdG9yYWdlAl84CAUHc3RvcmFnZQJfOQkAlAoCCQDOCAIJAM4IAgkAzggCCQDMCAIJAQdSZWlzc3VlAwUJbHBBc3NldElkBQ5scFRva2Vuc1RvTWludAYJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQ5scFRva2Vuc1RvTWludAUJbHBBc3NldElkBQNuaWwJAQxfc2F2ZVN0b3JhZ2UBBQ5zdG9yYWdlVXBkYXRlZAkBEl9zYXZlQXNzZXRCYWxhbmNlcwEFDWFzc2V0QmFsYW5jZXMFDWNoYW5nZUFjdGlvbnMFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEHZGVwb3NpdAEMbWluTHBBbW91bnRfBANlcnIJAQxfdmFsaWRhdGVJbnQEBQxtaW5McEFtb3VudF8AAAUHTUFYX0lOVAIeZGVwb3NpdDogaW52YWxpZCBtaW4gbHAgYW1vdW50AwkAAAIFA2VycgUDZXJyBAdzdG9yYWdlCQEMX2xvYWRTdG9yYWdlAAQJbHBBc3NldElkCAUHc3RvcmFnZQJfMQQKbHBEZWNpbWFscwkBDF9nZXREZWNpbWFscwEJANgEAQUJbHBBc3NldElkBA1scFRvdGFsU3VwcGx5CAUHc3RvcmFnZQJfMwQRbWF4QWxsb2NBbXBsaWZpZXIIBQdzdG9yYWdlAl82BA93ZWlnaHRBbXBsaWZpZXIIBQdzdG9yYWdlAl83BAxzbGlwcGFnZVJhdGUIBQdzdG9yYWdlAl84BApmZWVNYXhSYXRlCAUHc3RvcmFnZQJfOQQGYXNzZXRzCQELX2xvYWRBc3NldHMABA0kdDAzMzkwODMzOTYxCQERX2xvYWRBc3NldFdlaWdodHMABAxhc3NldFdlaWdodHMIBQ0kdDAzMzkwODMzOTYxAl8xBAtzaWdtYVdlaWdodAgFDSR0MDMzOTA4MzM5NjECXzIEDSR0MDMzOTY2MzQwMzQJARJfbG9hZEFzc2V0QmFsYW5jZXMABBFwcmV2QXNzZXRCYWxhbmNlcwgFDSR0MDMzOTY2MzQwMzQCXzEEFHByZXZBc3NldFRvdGFsU3VwcGx5CAUNJHQwMzM5NjYzNDAzNAJfMgQEZXJyMQMDCQESX3ZhbGlkYXRlSW50RXF1YWxzAwkAkAMBCAUBaQhwYXltZW50cwABAh5kZXBvc2l0OiBpbnZhbGlkIHBheW1lbnRzIHNpemUJARVfdmFsaWRhdGVMaXN0Q29udGFpbnMDBQZhc3NldHMJAQtfYXNzZXRUb1N0cgEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAIeZGVwb3NpdDogaW52YWxpZCBwYXltZW50IGFzc2V0BwkBDF92YWxpZGF0ZUludAQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50AAAFB01BWF9JTlQCH2RlcG9zaXQ6IGludmFsaWQgcGF5bWVudCBhbW91bnQHAwkAAAIFBGVycjEFBGVycjEECGFzc2V0U3RyCQELX2Fzc2V0VG9TdHIBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQEDWFzc2V0RGVjaW1hbHMJAQxfZ2V0RGVjaW1hbHMBBQhhc3NldFN0cgQQYW1vdW50Tm9ybWFsaXplZAkBEl9ub3JtYWxpemVEZWNpbWFscwQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BQ1hc3NldERlY2ltYWxzBQpscERlY2ltYWxzBQRET1dOBA1hc3NldEJhbGFuY2VzCQEYX2luY3JlbWVudEJhbGFuY2VCeUluZGV4AwURcHJldkFzc2V0QmFsYW5jZXMJAQV2YWx1ZQEJAM8IAgUGYXNzZXRzBQhhc3NldFN0cgUQYW1vdW50Tm9ybWFsaXplZAQQYXNzZXRUb3RhbFN1cHBseQkAZAIFFHByZXZBc3NldFRvdGFsU3VwcGx5BRBhbW91bnROb3JtYWxpemVkBARlcnIyCQETX3ZhbGlkYXRlQWxsb2NhdGlvbgcFDWFzc2V0QmFsYW5jZXMFEGFzc2V0VG90YWxTdXBwbHkFEXByZXZBc3NldEJhbGFuY2VzBRRwcmV2QXNzZXRUb3RhbFN1cHBseQUMYXNzZXRXZWlnaHRzBQtzaWdtYVdlaWdodAURbWF4QWxsb2NBbXBsaWZpZXIDCQAAAgUEZXJyMgUEZXJyMgQHcHJldkZlZQkBDV9jYWxjdWxhdGVGZWUHBRFwcmV2QXNzZXRCYWxhbmNlcwUUcHJldkFzc2V0VG90YWxTdXBwbHkFDGFzc2V0V2VpZ2h0cwULc2lnbWFXZWlnaHQFD3dlaWdodEFtcGxpZmllcgUMc2xpcHBhZ2VSYXRlBQpmZWVNYXhSYXRlBANmZWUJAQ1fY2FsY3VsYXRlRmVlBwUNYXNzZXRCYWxhbmNlcwUQYXNzZXRUb3RhbFN1cHBseQUMYXNzZXRXZWlnaHRzBQtzaWdtYVdlaWdodAUPd2VpZ2h0QW1wbGlmaWVyBQxzbGlwcGFnZVJhdGUFCmZlZU1heFJhdGUEDmxwVG9rZW5zVG9NaW50AwkAAAIFDWxwVG90YWxTdXBwbHkAAAkAZQIFEGFzc2V0VG90YWxTdXBwbHkFA2ZlZQQJYXNzZXREaWZmCQBlAgUQYXNzZXRUb3RhbFN1cHBseQUUcHJldkFzc2V0VG90YWxTdXBwbHkEB2ZlZURpZmYJAGUCBQNmZWUFB3ByZXZGZWUEE3V0aWxpdHlDaGFuZ2VGYWN0b3IJAGsDCQBlAgUJYXNzZXREaWZmBQdmZWVEaWZmBQtSQVRFX0ZBQ1RPUgkAZQIFFHByZXZBc3NldFRvdGFsU3VwcGx5BQdwcmV2RmVlBBNscFRva2Vuc1RvTWludElubmVyCQBrAwUNbHBUb3RhbFN1cHBseQUTdXRpbGl0eUNoYW5nZUZhY3RvcgULUkFURV9GQUNUT1IEBGVycjMJARtfdmFsaWRhdGVMaXF1aWRpdHlJbnZhcmlhbnQLBRFwcmV2QXNzZXRCYWxhbmNlcwUUcHJldkFzc2V0VG90YWxTdXBwbHkFDWFzc2V0QmFsYW5jZXMFEGFzc2V0VG90YWxTdXBwbHkFDWxwVG90YWxTdXBwbHkJAGQCBQ1scFRvdGFsU3VwcGx5BRNscFRva2Vuc1RvTWludElubmVyBQxhc3NldFdlaWdodHMFC3NpZ21hV2VpZ2h0BQ93ZWlnaHRBbXBsaWZpZXIFDHNsaXBwYWdlUmF0ZQUKZmVlTWF4UmF0ZQMJAAACBQRlcnIzBQRlcnIzBRNscFRva2Vuc1RvTWludElubmVyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBARlcnI0CQEMX3ZhbGlkYXRlSW50BAUObHBUb2tlbnNUb01pbnQFDG1pbkxwQW1vdW50XwUHTUFYX0lOVAIiZGVwb3NpdFNlbGVjdGl2ZTogbGVzcyB0aGFuIG1pbiBscAMJAAACBQRlcnI0BQRlcnI0BA5zdG9yYWdlVXBkYXRlZAkAmwoJCAUHc3RvcmFnZQJfMQgFB3N0b3JhZ2UCXzIJAGQCBQ1scFRvdGFsU3VwcGx5BQ5scFRva2Vuc1RvTWludAgFB3N0b3JhZ2UCXzQIBQdzdG9yYWdlAl81CAUHc3RvcmFnZQJfNggFB3N0b3JhZ2UCXzcIBQdzdG9yYWdlAl84CAUHc3RvcmFnZQJfOQkAlAoCCQDOCAIJAM4IAgkAzAgCCQEHUmVpc3N1ZQMFCWxwQXNzZXRJZAUObHBUb2tlbnNUb01pbnQGCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUObHBUb2tlbnNUb01pbnQFCWxwQXNzZXRJZAUDbmlsCQEMX3NhdmVTdG9yYWdlAQUOc3RvcmFnZVVwZGF0ZWQJARJfc2F2ZUFzc2V0QmFsYW5jZXMBBQ1hc3NldEJhbGFuY2VzBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBC3dpdGhkcmF3QWxsAAQHc3RvcmFnZQkBDF9sb2FkU3RvcmFnZQAECWxwQXNzZXRJZAgFB3N0b3JhZ2UCXzEECmxwRGVjaW1hbHMJAQxfZ2V0RGVjaW1hbHMBCQDYBAEFCWxwQXNzZXRJZAQNbHBUb3RhbFN1cHBseQgFB3N0b3JhZ2UCXzMECWxwRmVlUmF0ZQgFB3N0b3JhZ2UCXzQED3Byb3RvY29sRmVlUmF0ZQgFB3N0b3JhZ2UCXzUEEW1heEFsbG9jQW1wbGlmaWVyCAUHc3RvcmFnZQJfNgQPd2VpZ2h0QW1wbGlmaWVyCAUHc3RvcmFnZQJfNwQMc2xpcHBhZ2VSYXRlCAUHc3RvcmFnZQJfOAQKZmVlTWF4UmF0ZQgFB3N0b3JhZ2UCXzkEDGxwQXNzZXRJZFN0cgkA2AQBBQlscEFzc2V0SWQEBmFzc2V0cwkBC19sb2FkQXNzZXRzAAQNJHQwMzczMjAzNzM4OAkBEl9sb2FkQXNzZXRCYWxhbmNlcwAEEXByZXZBc3NldEJhbGFuY2VzCAUNJHQwMzczMjAzNzM4OAJfMQQUcHJldkFzc2V0VG90YWxTdXBwbHkIBQ0kdDAzNzMyMDM3Mzg4Al8yBA0kdDAzNzM5MzM3NDQ2CQERX2xvYWRBc3NldFdlaWdodHMABAxhc3NldFdlaWdodHMIBQ0kdDAzNzM5MzM3NDQ2Al8xBAtzaWdtYVdlaWdodAgFDSR0MDM3MzkzMzc0NDYCXzIEA2VycgMDCQESX3ZhbGlkYXRlSW50RXF1YWxzAwkAkAMBCAUBaQhwYXltZW50cwABAiJ3aXRoZHJhd0FsbDogaW52YWxpZCBwYXltZW50cyBzaXplCQEUX3ZhbGlkYXRlU3RyaW5nRXF1YWwDBQxscEFzc2V0SWRTdHIJAQtfYXNzZXRUb1N0cgEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAIid2l0aGRyYXdBbGw6IGludmFsaWQgcGF5bWVudCBhc3NldAcJAQxfdmFsaWRhdGVJbnQECAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAAABQdNQVhfSU5UAiN3aXRoZHJhd0FsbDogaW52YWxpZCBwYXltZW50IGFtb3VudAcDCQAAAgUDZXJyBQNlcnIEBWxwRmVlCQBrAwgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFCWxwRmVlUmF0ZQUHTUFYX0ZFRQQLcHJvdG9jb2xGZWUJAGsDCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAUPcHJvdG9jb2xGZWVSYXRlBQdNQVhfRkVFBAZhbW91bnQJAGUCCQBlAggJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFBWxwRmVlBQtwcm90b2NvbEZlZQQEZXJyMQkBDF92YWxpZGF0ZUludAQFBmFtb3VudAAABQdNQVhfSU5UAiB3aXRoZHJhd0FsbDogaW5zdWZmaWNpZW50IGFtb3VudAMJAAACBQRlcnIxBQRlcnIxBA0kdDAzODA3MDM4MjAwCQEcX2RlY3JlbWVudEJhbGFuY2VzQnlMcEFtb3VudAMFEXByZXZBc3NldEJhbGFuY2VzBQZhbW91bnQFDWxwVG90YWxTdXBwbHkEDWFzc2V0QmFsYW5jZXMIBQ0kdDAzODA3MDM4MjAwAl8xBBBhc3NldFRvdGFsU3VwcGx5CAUNJHQwMzgwNzAzODIwMAJfMgQSZGVsdGFBc3NldEJhbGFuY2VzCAUNJHQwMzgwNzAzODIwMAJfMwQUbHBUb3RhbFN1cHBseVVwZGF0ZWQJAGUCBQ1scFRvdGFsU3VwcGx5BQZhbW91bnQEDnBheW1lbnRBY3Rpb25zCQEYX2dldFBheW1lbnRzRnJvbUJhbGFuY2VzBAUGYXNzZXRzBRJkZWx0YUFzc2V0QmFsYW5jZXMIBQFpBmNhbGxlcgUKbHBEZWNpbWFscwQEZXJyMgkBG192YWxpZGF0ZUxpcXVpZGl0eUludmFyaWFudAsFEXByZXZBc3NldEJhbGFuY2VzBRRwcmV2QXNzZXRUb3RhbFN1cHBseQUNYXNzZXRCYWxhbmNlcwUQYXNzZXRUb3RhbFN1cHBseQUNbHBUb3RhbFN1cHBseQUUbHBUb3RhbFN1cHBseVVwZGF0ZWQFDGFzc2V0V2VpZ2h0cwULc2lnbWFXZWlnaHQFD3dlaWdodEFtcGxpZmllcgUMc2xpcHBhZ2VSYXRlBQpmZWVNYXhSYXRlAwkAAAIFBGVycjIFBGVycjIEDnN0b3JhZ2VVcGRhdGVkCQCbCgkIBQdzdG9yYWdlAl8xCAUHc3RvcmFnZQJfMgUUbHBUb3RhbFN1cHBseVVwZGF0ZWQIBQdzdG9yYWdlAl80CAUHc3RvcmFnZQJfNQgFB3N0b3JhZ2UCXzYIBQdzdG9yYWdlAl83CAUHc3RvcmFnZQJfOAgFB3N0b3JhZ2UCXzkJAJQKAgkAzggCCQDOCAIJAM4IAgkAzggCCQDOCAIJAMwIAgkBBEJ1cm4CBQlscEFzc2V0SWQFBmFtb3VudAUDbmlsBQ5wYXltZW50QWN0aW9ucwkBDF9zYXZlU3RvcmFnZQEFDnN0b3JhZ2VVcGRhdGVkCQESX3NhdmVBc3NldEJhbGFuY2VzAQUNYXNzZXRCYWxhbmNlcwkBCl9zYXZlTHBGZWUCBQxscEFzc2V0SWRTdHIJAGQCBQVscEZlZQkBCl9sb2FkTHBGZWUBBQxscEFzc2V0SWRTdHIJARBfc2F2ZVByb3RvY29sRmVlAgUMbHBBc3NldElkU3RyCQBkAgULcHJvdG9jb2xGZWUJARBfbG9hZFByb3RvY29sRmVlAQUMbHBBc3NldElkU3RyBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCHdpdGhkcmF3Aghhc3NldElkXwdhbW91bnRfBAdzdG9yYWdlCQEMX2xvYWRTdG9yYWdlAAQJbHBBc3NldElkCAUHc3RvcmFnZQJfMQQKbHBEZWNpbWFscwkBDF9nZXREZWNpbWFscwEJANgEAQUJbHBBc3NldElkBA1scFRvdGFsU3VwcGx5CAUHc3RvcmFnZQJfMwQJbHBGZWVSYXRlCAUHc3RvcmFnZQJfNAQPcHJvdG9jb2xGZWVSYXRlCAUHc3RvcmFnZQJfNQQRbWF4QWxsb2NBbXBsaWZpZXIIBQdzdG9yYWdlAl82BA93ZWlnaHRBbXBsaWZpZXIIBQdzdG9yYWdlAl83BAxzbGlwcGFnZVJhdGUIBQdzdG9yYWdlAl84BApmZWVNYXhSYXRlCAUHc3RvcmFnZQJfOQQMbHBBc3NldElkU3RyCQDYBAEFCWxwQXNzZXRJZAQGYXNzZXRzCQELX2xvYWRBc3NldHMABA0kdDAzOTc1NTM5ODIzCQESX2xvYWRBc3NldEJhbGFuY2VzAAQRcHJldkFzc2V0QmFsYW5jZXMIBQ0kdDAzOTc1NTM5ODIzAl8xBBRwcmV2QXNzZXRUb3RhbFN1cHBseQgFDSR0MDM5NzU1Mzk4MjMCXzIEDSR0MDM5ODI4Mzk4ODEJARFfbG9hZEFzc2V0V2VpZ2h0cwAEDGFzc2V0V2VpZ2h0cwgFDSR0MDM5ODI4Mzk4ODECXzEEC3NpZ21hV2VpZ2h0CAUNJHQwMzk4MjgzOTg4MQJfMgQDZXJyAwMDAwkBEl92YWxpZGF0ZUludEVxdWFscwMJAJADAQgFAWkIcGF5bWVudHMAAQIfd2l0aGRyYXc6IGludmFsaWQgcGF5bWVudHMgc2l6ZQkBFF92YWxpZGF0ZVN0cmluZ0VxdWFsAwUMbHBBc3NldElkU3RyCQELX2Fzc2V0VG9TdHIBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQCH3dpdGhkcmF3OiBpbnZhbGlkIHBheW1lbnQgYXNzZXQHCQEMX3ZhbGlkYXRlSW50BAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQAAAUHTUFYX0lOVAIgd2l0aGRyYXc6IGludmFsaWQgcGF5bWVudCBhbW91bnQHCQEVX3ZhbGlkYXRlTGlzdENvbnRhaW5zAwUGYXNzZXRzBQhhc3NldElkXwIZd2l0aGRyYXc6IGludmFsaWQgYXNzZXRJZAcJAQxfdmFsaWRhdGVJbnQEBQdhbW91bnRfAAAFB01BWF9JTlQCGHdpdGhkcmF3OiBpbnZhbGlkIGFtb3VudAcDCQAAAgUDZXJyBQNlcnIEDWFzc2V0RGVjaW1hbHMJAQxfZ2V0RGVjaW1hbHMBBQhhc3NldElkXwQQYW1vdW50Tm9ybWFsaXplZAkBEl9ub3JtYWxpemVEZWNpbWFscwQFB2Ftb3VudF8FDWFzc2V0RGVjaW1hbHMFCmxwRGVjaW1hbHMFBERPV04ECmFzc2V0SW5kZXgJAQV2YWx1ZQEJAM8IAgUGYXNzZXRzBQhhc3NldElkXwQNYXNzZXRCYWxhbmNlcwkBGF9kZWNyZW1lbnRCYWxhbmNlQnlJbmRleAMFEXByZXZBc3NldEJhbGFuY2VzBQphc3NldEluZGV4BRBhbW91bnROb3JtYWxpemVkBBBhc3NldFRvdGFsU3VwcGx5CQBlAgUUcHJldkFzc2V0VG90YWxTdXBwbHkFEGFtb3VudE5vcm1hbGl6ZWQEBGVycjEJARNfdmFsaWRhdGVBbGxvY2F0aW9uBwUNYXNzZXRCYWxhbmNlcwUQYXNzZXRUb3RhbFN1cHBseQURcHJldkFzc2V0QmFsYW5jZXMFFHByZXZBc3NldFRvdGFsU3VwcGx5BQxhc3NldFdlaWdodHMFC3NpZ21hV2VpZ2h0BRFtYXhBbGxvY0FtcGxpZmllcgMJAAACBQRlcnIxBQRlcnIxBAdwcmV2RmVlCQENX2NhbGN1bGF0ZUZlZQcFEXByZXZBc3NldEJhbGFuY2VzBRRwcmV2QXNzZXRUb3RhbFN1cHBseQUMYXNzZXRXZWlnaHRzBQtzaWdtYVdlaWdodAUPd2VpZ2h0QW1wbGlmaWVyBQxzbGlwcGFnZVJhdGUFCmZlZU1heFJhdGUEA2ZlZQkBDV9jYWxjdWxhdGVGZWUHBQ1hc3NldEJhbGFuY2VzBRBhc3NldFRvdGFsU3VwcGx5BQxhc3NldFdlaWdodHMFC3NpZ21hV2VpZ2h0BQ93ZWlnaHRBbXBsaWZpZXIFDHNsaXBwYWdlUmF0ZQUKZmVlTWF4UmF0ZQQObHBUb2tlbnNUb0J1cm4DCQAAAgUNbHBUb3RhbFN1cHBseQAACQBlAgUQYXNzZXRUb3RhbFN1cHBseQUDZmVlBAlhc3NldERpZmYJAGUCBRBhc3NldFRvdGFsU3VwcGx5BRRwcmV2QXNzZXRUb3RhbFN1cHBseQQHZmVlRGlmZgkAZQIFA2ZlZQUHcHJldkZlZQQTdXRpbGl0eUNoYW5nZUZhY3RvcgkAawMJAGUCBQlhc3NldERpZmYFB2ZlZURpZmYFC1JBVEVfRkFDVE9SCQBlAgUUcHJldkFzc2V0VG90YWxTdXBwbHkFB3ByZXZGZWUEE2xwVG9rZW5zVG9CdXJuSW5uZXIJAGgCAP///////////wEJAGsDBQ1scFRvdGFsU3VwcGx5BRN1dGlsaXR5Q2hhbmdlRmFjdG9yBQtSQVRFX0ZBQ1RPUgQEZXJyMgkBG192YWxpZGF0ZUxpcXVpZGl0eUludmFyaWFudAsFEXByZXZBc3NldEJhbGFuY2VzBRRwcmV2QXNzZXRUb3RhbFN1cHBseQUNYXNzZXRCYWxhbmNlcwUQYXNzZXRUb3RhbFN1cHBseQUNbHBUb3RhbFN1cHBseQkAZQIFDWxwVG90YWxTdXBwbHkFE2xwVG9rZW5zVG9CdXJuSW5uZXIFDGFzc2V0V2VpZ2h0cwULc2lnbWFXZWlnaHQFD3dlaWdodEFtcGxpZmllcgUMc2xpcHBhZ2VSYXRlBQpmZWVNYXhSYXRlAwkAAAIFBGVycjIFBGVycjIFE2xwVG9rZW5zVG9CdXJuSW5uZXIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EBWxwRmVlCQBrAwUObHBUb2tlbnNUb0J1cm4FCWxwRmVlUmF0ZQkAZQIJAGUCBQdNQVhfRkVFBQlscEZlZVJhdGUFD3Byb3RvY29sRmVlUmF0ZQQLcHJvdG9jb2xGZWUJAGsDBQ5scFRva2Vuc1RvQnVybgUPcHJvdG9jb2xGZWVSYXRlCQBlAgkAZQIFB01BWF9GRUUFCWxwRmVlUmF0ZQUPcHJvdG9jb2xGZWVSYXRlBBByZXF1aXJlZExwVG9rZW5zCQBkAgkAZAIFDmxwVG9rZW5zVG9CdXJuBQVscEZlZQULcHJvdG9jb2xGZWUEDGNoYW5nZUFjdGlvbgMJAGYCBRByZXF1aXJlZExwVG9rZW5zCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAkAAgECHXdpdGhkcmF3OiBpbnN1ZmZpY2llbnQgYW1vdW50AwkAZgIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BRByZXF1aXJlZExwVG9rZW5zCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgkAZQIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BRByZXF1aXJlZExwVG9rZW5zCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFA25pbAUDbmlsBA5zdG9yYWdlVXBkYXRlZAkAmwoJCAUHc3RvcmFnZQJfMQgFB3N0b3JhZ2UCXzIJAGUCBQ1scFRvdGFsU3VwcGx5BQ5scFRva2Vuc1RvQnVybggFB3N0b3JhZ2UCXzQIBQdzdG9yYWdlAl81CAUHc3RvcmFnZQJfNggFB3N0b3JhZ2UCXzcIBQdzdG9yYWdlAl84CAUHc3RvcmFnZQJfOQkAlAoCCQDOCAIJAM4IAgkAzggCCQDOCAIJAM4IAgkAzAgCCQEEQnVybgIFCWxwQXNzZXRJZAUObHBUb2tlbnNUb0J1cm4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQdhbW91bnRfCQELX3N0clRvQXNzZXQBBQhhc3NldElkXwUDbmlsBQxjaGFuZ2VBY3Rpb24JAQxfc2F2ZVN0b3JhZ2UBBQ5zdG9yYWdlVXBkYXRlZAkBEl9zYXZlQXNzZXRCYWxhbmNlcwEFDWFzc2V0QmFsYW5jZXMJAQpfc2F2ZUxwRmVlAgUMbHBBc3NldElkU3RyCQBkAgUFbHBGZWUJAQpfbG9hZExwRmVlAQUMbHBBc3NldElkU3RyCQEQX3NhdmVQcm90b2NvbEZlZQIFDGxwQXNzZXRJZFN0cgkAZAIFC3Byb3RvY29sRmVlCQEQX2xvYWRQcm90b2NvbEZlZQEFDGxwQXNzZXRJZFN0cgUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQRzd2FwAg50YXJnZXRBc3NldElkXwptaW5BbW91bnRfBAdzdG9yYWdlCQEMX2xvYWRTdG9yYWdlAAQJbHBBc3NldElkCAUHc3RvcmFnZQJfMQQKbHBEZWNpbWFscwkBDF9nZXREZWNpbWFscwEJANgEAQUJbHBBc3NldElkBA1scFRvdGFsU3VwcGx5CAUHc3RvcmFnZQJfMwQJbHBGZWVSYXRlCAUHc3RvcmFnZQJfNAQPcHJvdG9jb2xGZWVSYXRlCAUHc3RvcmFnZQJfNQQRbWF4QWxsb2NBbXBsaWZpZXIIBQdzdG9yYWdlAl82BA93ZWlnaHRBbXBsaWZpZXIIBQdzdG9yYWdlAl83BAxzbGlwcGFnZVJhdGUIBQdzdG9yYWdlAl84BApmZWVNYXhSYXRlCAUHc3RvcmFnZQJfOQQGYXNzZXRzCQELX2xvYWRBc3NldHMABA0kdDA0Mzk4MDQ0MDQ4CQESX2xvYWRBc3NldEJhbGFuY2VzAAQRcHJldkFzc2V0QmFsYW5jZXMIBQ0kdDA0Mzk4MDQ0MDQ4Al8xBBRwcmV2QXNzZXRUb3RhbFN1cHBseQgFDSR0MDQzOTgwNDQwNDgCXzIEDSR0MDQ0MDUzNDQxMDYJARFfbG9hZEFzc2V0V2VpZ2h0cwAEDGFzc2V0V2VpZ2h0cwgFDSR0MDQ0MDUzNDQxMDYCXzEEC3NpZ21hV2VpZ2h0CAUNJHQwNDQwNTM0NDEwNgJfMgQOc291cmNlQXNzZXRTdHIJAQtfYXNzZXRUb1N0cgEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQQc291cmNlQXNzZXRJbmRleAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDPCAIFBmFzc2V0cwUOc291cmNlQXNzZXRTdHICGnN3YXA6IGludmFsaWQgc291cmNlIGFzc2V0AwkAAAIFEHNvdXJjZUFzc2V0SW5kZXgFEHNvdXJjZUFzc2V0SW5kZXgEEHRhcmdldEFzc2V0SW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQZhc3NldHMFDnRhcmdldEFzc2V0SWRfAhpzd2FwOiBpbnZhbGlkIHRhcmdldCBhc3NldAMJAAACBRB0YXJnZXRBc3NldEluZGV4BRB0YXJnZXRBc3NldEluZGV4BANlcnIDAwkBDF92YWxpZGF0ZUludAQFCm1pbkFtb3VudF8AAAUHTUFYX0lOVAIfc3dhcDogaW52YWxpZCBtaW4gdGFyZ2V0IGFtb3VudAkBFF92YWxpZGF0ZVN0cmluZ05vdEVxAwUOc291cmNlQXNzZXRTdHIFDnRhcmdldEFzc2V0SWRfAhFzd2FwOiBzYW1lIGFzc2V0cwcJARJfdmFsaWRhdGVJbnRFcXVhbHMDCQCQAwEIBQFpCHBheW1lbnRzAAECG3N3YXA6IGludmFsaWQgcGF5bWVudHMgc2l6ZQcDCQAAAgUDZXJyBQNlcnIEDnNvdXJjZURlY2ltYWxzCQEMX2dldERlY2ltYWxzAQUOc291cmNlQXNzZXRTdHIEEGFtb3VudE5vcm1hbGl6ZWQJARJfbm9ybWFsaXplRGVjaW1hbHMECAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAUOc291cmNlRGVjaW1hbHMFCmxwRGVjaW1hbHMFBERPV04EDWFzc2V0QmFsYW5jZXMJARhfaW5jcmVtZW50QmFsYW5jZUJ5SW5kZXgDBRFwcmV2QXNzZXRCYWxhbmNlcwUQc291cmNlQXNzZXRJbmRleAUQYW1vdW50Tm9ybWFsaXplZAQQYXNzZXRUb3RhbFN1cHBseQkAZAIFFHByZXZBc3NldFRvdGFsU3VwcGx5BRBhbW91bnROb3JtYWxpemVkBAdwcmV2RmVlCQENX2NhbGN1bGF0ZUZlZQcFEXByZXZBc3NldEJhbGFuY2VzBRRwcmV2QXNzZXRUb3RhbFN1cHBseQUMYXNzZXRXZWlnaHRzBQtzaWdtYVdlaWdodAUPd2VpZ2h0QW1wbGlmaWVyBQxzbGlwcGFnZVJhdGUFCmZlZU1heFJhdGUKAQhmb2xkRnVuYwIDYWNjBGVsZW0DCAUDYWNjAl8xBQNhY2MEDHRhcmdldEFtb3VudAgFA2FjYwJfMgQRdGVtcEFzc2V0QmFsYW5jZXMJARhfZGVjcmVtZW50QmFsYW5jZUJ5SW5kZXgDBQ1hc3NldEJhbGFuY2VzBRB0YXJnZXRBc3NldEluZGV4BQx0YXJnZXRBbW91bnQEFHRlbXBBc3NldFRvdGFsU3VwcGx5CQBlAgUQYXNzZXRUb3RhbFN1cHBseQUMdGFyZ2V0QW1vdW50BANmZWUJAQ1fY2FsY3VsYXRlRmVlBwURdGVtcEFzc2V0QmFsYW5jZXMFFHRlbXBBc3NldFRvdGFsU3VwcGx5BQxhc3NldFdlaWdodHMFC3NpZ21hV2VpZ2h0BQ93ZWlnaHRBbXBsaWZpZXIFDHNsaXBwYWdlUmF0ZQUKZmVlTWF4UmF0ZQQHZmVlRGlmZgkAZQIFA2ZlZQUHcHJldkZlZQQKdGVtcEFtb3VudAkAZQIFEGFtb3VudE5vcm1hbGl6ZWQFB2ZlZURpZmYEBWNoZWNrAwkAZwIAAAUKdGVtcEFtb3VudAkAAgECEXN3YXA6IGxlc3MgdGhhbiAwBQR1bml0AwkAAAIFBWNoZWNrBQVjaGVjawMDCQBmAgkAZQIFDHRhcmdldEFtb3VudAUKdGVtcEFtb3VudAkAaAIA////////////AQUJUFJFQ0lTSU9OCQBmAgUJUFJFQ0lTSU9OCQBlAgUMdGFyZ2V0QW1vdW50BQp0ZW1wQW1vdW50BwQSZmluYWxBc3NldEJhbGFuY2VzCQEYX2RlY3JlbWVudEJhbGFuY2VCeUluZGV4AwUNYXNzZXRCYWxhbmNlcwUQdGFyZ2V0QXNzZXRJbmRleAUKdGVtcEFtb3VudAQVZmluYWxBc3NldFRvdGFsU3VwcGx5CQBlAgUQYXNzZXRUb3RhbFN1cHBseQUKdGVtcEFtb3VudAQEZXJyMQMJARNfdmFsaWRhdGVBbGxvY2F0aW9uBwUSZmluYWxBc3NldEJhbGFuY2VzBRVmaW5hbEFzc2V0VG90YWxTdXBwbHkFEXByZXZBc3NldEJhbGFuY2VzBRRwcmV2QXNzZXRUb3RhbFN1cHBseQUMYXNzZXRXZWlnaHRzBQtzaWdtYVdlaWdodAURbWF4QWxsb2NBbXBsaWZpZXIJARZfdmFsaWRhdGVTd2FwSW52YXJpYW50CQURcHJldkFzc2V0QmFsYW5jZXMFFHByZXZBc3NldFRvdGFsU3VwcGx5BRJmaW5hbEFzc2V0QmFsYW5jZXMFFWZpbmFsQXNzZXRUb3RhbFN1cHBseQUMYXNzZXRXZWlnaHRzBQtzaWdtYVdlaWdodAUPd2VpZ2h0QW1wbGlmaWVyBQxzbGlwcGFnZVJhdGUFCmZlZU1heFJhdGUHAwkAAAIFBGVycjEFBGVycjEJAJUKAwYFCnRlbXBBbW91bnQFEmZpbmFsQXNzZXRCYWxhbmNlcwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlQoDBwUKdGVtcEFtb3VudAURdGVtcEFzc2V0QmFsYW5jZXMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EDSR0MDQ2OTQ0NDcwNjIKAAIkbAUHTElTVF8yNQoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJUKAwcFEGFtb3VudE5vcm1hbGl6ZWQFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIZm9sZEZ1bmMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDI1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkEB3N1Y2Nlc3MIBQ0kdDA0Njk0NDQ3MDYyAl8xBBZ0YXJnZXRBbW91bnROb3JtYWxpemVkCAUNJHQwNDY5NDQ0NzA2MgJfMgQSZmluYWxBc3NldEJhbGFuY2VzCAUNJHQwNDY5NDQ0NzA2MgJfMwMJAQEhAQUHc3VjY2VzcwkAAgEJAKwCAgIjc3dhcDogY2FuJ3QgY2FsY3VsYXRlIHRhcmdldEFtb3VudD0JAKQDAQUWdGFyZ2V0QW1vdW50Tm9ybWFsaXplZAQFbHBGZWUJAGsDBRZ0YXJnZXRBbW91bnROb3JtYWxpemVkBQlscEZlZVJhdGUFB01BWF9GRUUEC3Byb3RvY29sRmVlCQBrAwUWdGFyZ2V0QW1vdW50Tm9ybWFsaXplZAUPcHJvdG9jb2xGZWVSYXRlBQdNQVhfRkVFBBVmaW5hbEFtb3VudE5vcm1hbGl6ZWQJAGUCCQBlAgUWdGFyZ2V0QW1vdW50Tm9ybWFsaXplZAUFbHBGZWUFC3Byb3RvY29sRmVlBA50YXJnZXREZWNpbWFscwkBDF9nZXREZWNpbWFscwEFDnRhcmdldEFzc2V0SWRfBAtmaW5hbEFtb3VudAkBEl9ub3JtYWxpemVEZWNpbWFscwQFFWZpbmFsQW1vdW50Tm9ybWFsaXplZAUKbHBEZWNpbWFscwUOdGFyZ2V0RGVjaW1hbHMFBERPV04EBGVycjIJAQxfdmFsaWRhdGVJbnQEBQtmaW5hbEFtb3VudAUKbWluQW1vdW50XwUHTUFYX0lOVAIfc3dhcDogaW5zdWZmaWNpZW50IGZpbmFsIGFtb3VudAMJAAACBQRlcnIyBQRlcnIyCQCUCgIJAM4IAgkAzggCCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQtmaW5hbEFtb3VudAkBC19zdHJUb0Fzc2V0AQUOdGFyZ2V0QXNzZXRJZF8FA25pbAkBEl9zYXZlQXNzZXRCYWxhbmNlcwEFEmZpbmFsQXNzZXRCYWxhbmNlcwkBCl9zYXZlTHBGZWUCBQ50YXJnZXRBc3NldElkXwkAZAIFBWxwRmVlCQEKX2xvYWRMcEZlZQEFDnRhcmdldEFzc2V0SWRfCQEQX3NhdmVQcm90b2NvbEZlZQIFDnRhcmdldEFzc2V0SWRfCQBkAgULcHJvdG9jb2xGZWUJARBfbG9hZFByb3RvY29sRmVlAQUOdGFyZ2V0QXNzZXRJZF8FBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEFc3Rha2UABAdzdG9yYWdlCQEMX2xvYWRTdG9yYWdlAAQMbHBBc3NldElkU3RyCQELX2Fzc2V0VG9TdHIBCAUHc3RvcmFnZQJfMQQGYXNzZXRzCQDMCAIFDGxwQXNzZXRJZFN0cgkBC19sb2FkQXNzZXRzAAQDZXJyAwMJARJfdmFsaWRhdGVJbnRFcXVhbHMDCQCQAwEIBQFpCHBheW1lbnRzAAECHHN0YWtlOiBpbnZhbGlkIHBheW1lbnRzIHNpemUJARRfdmFsaWRhdGVTdHJpbmdFcXVhbAMFDGxwQXNzZXRJZFN0cgkBC19hc3NldFRvU3RyAQgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkAhxzdGFrZTogaW52YWxpZCBwYXltZW50IGFzc2V0BwkBDF92YWxpZGF0ZUludAQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50AAAFB01BWF9JTlQCHXN0YWtlOiBpbnZhbGlkIHBheW1lbnQgYW1vdW50BwMJAAACBQNlcnIFA2VycgQNc3Rha2VkQmFsYW5jZQkBC19sb2FkVXNlckxwAQgFAWkGY2FsbGVyBA0kdDA0ODU1NDQ4NjMzCQELX2NoZWNrcG9pbnQBBQZhc3NldHMED2luY29tZUludGVncmFscwgFDSR0MDQ4NTU0NDg2MzMCXzEED3RvdGFsTHBJbnRlZ3JhbAgFDSR0MDQ4NTU0NDg2MzMCXzIEEWNoZWNrcG9pbnRBY3Rpb25zCAUNJHQwNDg1NTQ0ODYzMwJfMwQNJHQwNDg2Mzg0ODc1NQkBD191c2VyQ2hlY2twb2ludAQIBQFpBmNhbGxlcgUNc3Rha2VkQmFsYW5jZQUPaW5jb21lSW50ZWdyYWxzBQ90b3RhbExwSW50ZWdyYWwEC3VzZXJQcm9maXRzCAUNJHQwNDg2Mzg0ODc1NQJfMQQVdXNlckNoZWNrcG9pbnRBY3Rpb25zCAUNJHQwNDg2Mzg0ODc1NQJfMgkAlAoCCQDOCAIJAM4IAgkAzggCBRFjaGVja3BvaW50QWN0aW9ucwUVdXNlckNoZWNrcG9pbnRBY3Rpb25zCQELX3NhdmVVc2VyTHACCAUBaQZjYWxsZXIJAGQCBQ1zdGFrZWRCYWxhbmNlCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAkBDF9zYXZlVG90YWxMcAEJAGQCCQEMX2xvYWRUb3RhbExwAAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEHdW5zdGFrZQEHYW1vdW50XwQHc3RvcmFnZQkBDF9sb2FkU3RvcmFnZQAECWxwQXNzZXRJZAgFB3N0b3JhZ2UCXzEEBmFzc2V0cwkAzAgCCQELX2Fzc2V0VG9TdHIBBQlscEFzc2V0SWQJAQtfbG9hZEFzc2V0cwAEDXN0YWtlZEJhbGFuY2UJAQtfbG9hZFVzZXJMcAEIBQFpBmNhbGxlcgQDZXJyCQEMX3ZhbGlkYXRlSW50BAUHYW1vdW50XwAABQ1zdGFrZWRCYWxhbmNlAhd1bnN0YWtlOiBpbnZhbGlkIGFtb3VudAMJAAACBQNlcnIFA2VycgQNJHQwNDkyOTM0OTM3MgkBC19jaGVja3BvaW50AQUGYXNzZXRzBA9pbmNvbWVJbnRlZ3JhbHMIBQ0kdDA0OTI5MzQ5MzcyAl8xBA90b3RhbExwSW50ZWdyYWwIBQ0kdDA0OTI5MzQ5MzcyAl8yBBFjaGVja3BvaW50QWN0aW9ucwgFDSR0MDQ5MjkzNDkzNzICXzMEDSR0MDQ5Mzc3NDk0OTQJAQ9fdXNlckNoZWNrcG9pbnQECAUBaQZjYWxsZXIFDXN0YWtlZEJhbGFuY2UFD2luY29tZUludGVncmFscwUPdG90YWxMcEludGVncmFsBAt1c2VyUHJvZml0cwgFDSR0MDQ5Mzc3NDk0OTQCXzEEFXVzZXJDaGVja3BvaW50QWN0aW9ucwgFDSR0MDQ5Mzc3NDk0OTQCXzIJAJQKAgkAzggCCQDOCAIJAM4IAgkAzggCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUHYW1vdW50XwUJbHBBc3NldElkBQNuaWwFEWNoZWNrcG9pbnRBY3Rpb25zBRV1c2VyQ2hlY2twb2ludEFjdGlvbnMJAQtfc2F2ZVVzZXJMcAIIBQFpBmNhbGxlcgkAZQIFDXN0YWtlZEJhbGFuY2UFB2Ftb3VudF8JAQxfc2F2ZVRvdGFsTHABCQBlAgkBDF9sb2FkVG90YWxMcAAFB2Ftb3VudF8FBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEFY2xhaW0CCGFzc2V0SWRfB2Ftb3VudF8EB3N0b3JhZ2UJAQxfbG9hZFN0b3JhZ2UABAlscEFzc2V0SWQIBQdzdG9yYWdlAl8xBAxscEFzc2V0SWRTdHIJAQtfYXNzZXRUb1N0cgEFCWxwQXNzZXRJZAQGYXNzZXRzCQDMCAIFDGxwQXNzZXRJZFN0cgkBC19sb2FkQXNzZXRzAAQNc3Rha2VkQmFsYW5jZQkBC19sb2FkVXNlckxwAQgFAWkGY2FsbGVyBANlcnIDCQEVX3ZhbGlkYXRlTGlzdENvbnRhaW5zAwUGYXNzZXRzBQhhc3NldElkXwIWY2xhaW06IGludmFsaWQgYXNzZXRJZAkBDF92YWxpZGF0ZUludAQFB2Ftb3VudF8AAAUHTUFYX0lOVAIVY2xhaW06IGludmFsaWQgYW1vdW50BwMJAAACBQNlcnIFA2VycgQNJHQwNTAxODU1MDI2NAkBC19jaGVja3BvaW50AQUGYXNzZXRzBA9pbmNvbWVJbnRlZ3JhbHMIBQ0kdDA1MDE4NTUwMjY0Al8xBA90b3RhbExwSW50ZWdyYWwIBQ0kdDA1MDE4NTUwMjY0Al8yBBFjaGVja3BvaW50QWN0aW9ucwgFDSR0MDUwMTg1NTAyNjQCXzMEDSR0MDUwMjY5NTAzODYJAQ9fdXNlckNoZWNrcG9pbnQECAUBaQZjYWxsZXIFDXN0YWtlZEJhbGFuY2UFD2luY29tZUludGVncmFscwUPdG90YWxMcEludGVncmFsBAt1c2VyUHJvZml0cwgFDSR0MDUwMjY5NTAzODYCXzEEFXVzZXJDaGVja3BvaW50QWN0aW9ucwgFDSR0MDUwMjY5NTAzODYCXzIECmFzc2V0SW5kZXgJAQV2YWx1ZQEJAM8IAgUGYXNzZXRzBQhhc3NldElkXwoBCGZvbGRGdW5jAgNhY2MEZWxlbQQFaW5kZXgIBQNhY2MCXzEDCQAAAgUFaW5kZXgFCmFzc2V0SW5kZXgDCQBmAgUHYW1vdW50XwUEZWxlbQkAAgECGmNsYWltOiBpbnN1ZmZpY2llbnQgYW1vdW50CQCUCgIJAGQCBQVpbmRleAABCQDNCAIIBQNhY2MCXzIJAGUCBQRlbGVtBQdhbW91bnRfCQCUCgIJAGQCBQVpbmRleAABCQDNCAIIBQNhY2MCXzIFBGVsZW0EDSR0MDUwODM0NTA5MDYKAAIkbAULdXNlclByb2ZpdHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQhmb2xkRnVuYwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTEJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALBANpZHgIBQ0kdDA1MDgzNDUwOTA2Al8xBBJ1c2VyUHJvZml0c1VwZGF0ZWQIBQ0kdDA1MDgzNDUwOTA2Al8yCQCUCgIJAM4IAgkAzggCCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQdhbW91bnRfBQlscEFzc2V0SWQFA25pbAURY2hlY2twb2ludEFjdGlvbnMFFXVzZXJDaGVja3BvaW50QWN0aW9ucwkBEF9zYXZlVXNlclByb2ZpdHMCCAUBaQZjYWxsZXIFEnVzZXJQcm9maXRzVXBkYXRlZAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgBHX3IU", "height": 2652535, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: CsjsKnPhpJG2Q59nroVS4Hc8KdgcDQiLUTtqVfqyNW6y Full:
Old | New | Differences | |
---|---|---|---|
1 | - | # no script | |
1 | + | {-# STDLIB_VERSION 6 #-} | |
2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | + | {-# CONTENT_TYPE DAPP #-} | |
4 | + | let SEP = "__" | |
5 | + | ||
6 | + | let WAVES = "waves" | |
7 | + | ||
8 | + | let MAX_INT = 9223372036854775807 | |
9 | + | ||
10 | + | let MAX_FEE = 1000000 | |
11 | + | ||
12 | + | let MAX_AMPLIFIER = 1000000 | |
13 | + | ||
14 | + | let MAX_WEIGHT_AMPLIFIER = 1000000 | |
15 | + | ||
16 | + | let MAX_WEIGHT = 1000000000000 | |
17 | + | ||
18 | + | let SLIPPAGE_RATE_FACTOR = 1000000 | |
19 | + | ||
20 | + | let FEE_RATE_FACTOR = 1000000 | |
21 | + | ||
22 | + | let RATE_FACTOR = 1000000 | |
23 | + | ||
24 | + | let PERCENT_FACTOR = toBigInt(1000000000000) | |
25 | + | ||
26 | + | let ZERO_INT_LIST10 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] | |
27 | + | ||
28 | + | let ZERO_BIGINT = toBigInt(0) | |
29 | + | ||
30 | + | let ZERO_BIGINT_LIST11 = [ZERO_BIGINT, ZERO_BIGINT, ZERO_BIGINT, ZERO_BIGINT, ZERO_BIGINT, ZERO_BIGINT, ZERO_BIGINT, ZERO_BIGINT, ZERO_BIGINT, ZERO_BIGINT, ZERO_BIGINT] | |
31 | + | ||
32 | + | let INT_DECIMALS = 8 | |
33 | + | ||
34 | + | let BIGINT_DECIMALS = 18 | |
35 | + | ||
36 | + | let PRECISION = 1000000 | |
37 | + | ||
38 | + | let LIST_25 = split_51C("0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0", "_") | |
39 | + | ||
40 | + | let KEY_STORAGE = "STORAGE" | |
41 | + | ||
42 | + | let KEY_ASSETS = "ASSETS" | |
43 | + | ||
44 | + | let KEY_ASSET_BALANCES = "ASSET_BALANCES" | |
45 | + | ||
46 | + | let KEY_ASSET_WEIGHTS = "ASSET_WEIGHTS" | |
47 | + | ||
48 | + | let KEY_LP_FEE = "LP_FEE" | |
49 | + | ||
50 | + | let KEY_PROTOCOL_FEE = "PROTOCOL_FEE" | |
51 | + | ||
52 | + | let KEY_FEE_INCOME = "FEE_INCOME" | |
53 | + | ||
54 | + | let KEY_USER_LP = "USER_LP" | |
55 | + | ||
56 | + | let KEY_TOTAL_LP = "TOTAL_LP" | |
57 | + | ||
58 | + | let KEY_TOTAL_LP_INTEGRAL = "TOTAL_LP_INTEGRAL" | |
59 | + | ||
60 | + | let KEY_TOTAL_LP_INTEGRAL_AT = "TOTAL_LP_INTEGRAL_AT" | |
61 | + | ||
62 | + | let KEY_INCOME_INTEGRALS = "INCOME_INTEGRALS" | |
63 | + | ||
64 | + | let KEY_INCOME_INTEGRALS_AT = "INCOME_INTEGRALS_AT" | |
65 | + | ||
66 | + | let KEY_USER_INCOME_INTEGRALS = "USER_INCOME_INTEGRALS" | |
67 | + | ||
68 | + | let KEY_USER_TOTAL_LP_INTEGRALS = "USER_TOTAL_LP_INTEGRALS" | |
69 | + | ||
70 | + | let KEY_USER_PROFITS = "USER_PROFITS" | |
71 | + | ||
72 | + | func _validateAddress (address_,err_) = match addressFromString(address_) { | |
73 | + | case a: Address => | |
74 | + | true | |
75 | + | case _ => | |
76 | + | throw(err_) | |
77 | + | } | |
78 | + | ||
79 | + | ||
80 | + | func _validateAsset (assetId_,err_) = if ((assetId_ == WAVES)) | |
81 | + | then true | |
82 | + | else match assetInfo(fromBase58String(assetId_)) { | |
83 | + | case a: Asset => | |
84 | + | true | |
85 | + | case _ => | |
86 | + | throw(err_) | |
87 | + | } | |
88 | + | ||
89 | + | ||
90 | + | func _validateInt (val_,lowerBoundary_,upperBoundary_,err_) = if (if ((lowerBoundary_ > val_)) | |
91 | + | then true | |
92 | + | else (val_ > upperBoundary_)) | |
93 | + | then throw(err_) | |
94 | + | else true | |
95 | + | ||
96 | + | ||
97 | + | func _validateBool (val_,target_,err_) = if ((val_ != target_)) | |
98 | + | then throw(err_) | |
99 | + | else true | |
100 | + | ||
101 | + | ||
102 | + | func _validateStringEqual (val1_,val2_,err_) = if ((val1_ != val2_)) | |
103 | + | then throw(err_) | |
104 | + | else true | |
105 | + | ||
106 | + | ||
107 | + | func _validateStringNotEq (val1_,val2_,err_) = if ((val1_ == val2_)) | |
108 | + | then throw(err_) | |
109 | + | else true | |
110 | + | ||
111 | + | ||
112 | + | func _validateIntList (val_,lowerBoundary_,upperBoundary_,err_) = { | |
113 | + | func foldFunc (acc,elem) = match parseInt(elem) { | |
114 | + | case a: Int => | |
115 | + | if (acc) | |
116 | + | then _validateInt(a, lowerBoundary_, upperBoundary_, err_) | |
117 | + | else false | |
118 | + | case _ => | |
119 | + | throw(err_) | |
120 | + | } | |
121 | + | ||
122 | + | let $l = val_ | |
123 | + | let $s = size($l) | |
124 | + | let $acc0 = true | |
125 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
126 | + | then $a | |
127 | + | else foldFunc($a, $l[$i]) | |
128 | + | ||
129 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
130 | + | then $a | |
131 | + | else throw("List size exceeds 10") | |
132 | + | ||
133 | + | $f0_2($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) | |
134 | + | } | |
135 | + | ||
136 | + | ||
137 | + | func _validateAssets (assets_,err_) = { | |
138 | + | func foldFunc (acc,elem) = if (acc) | |
139 | + | then _validateAsset(elem, err_) | |
140 | + | else false | |
141 | + | ||
142 | + | let $l = assets_ | |
143 | + | let $s = size($l) | |
144 | + | let $acc0 = true | |
145 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
146 | + | then $a | |
147 | + | else foldFunc($a, $l[$i]) | |
148 | + | ||
149 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
150 | + | then $a | |
151 | + | else throw("List size exceeds 10") | |
152 | + | ||
153 | + | $f0_2($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) | |
154 | + | } | |
155 | + | ||
156 | + | ||
157 | + | func _validateIntEquals (val1_,val2_,err_) = if ((val1_ != val2_)) | |
158 | + | then throw(err_) | |
159 | + | else true | |
160 | + | ||
161 | + | ||
162 | + | func _validateTokenName (val_,err_) = if (if ((4 > size(val_))) | |
163 | + | then true | |
164 | + | else (size(val_) > 16)) | |
165 | + | then throw(err_) | |
166 | + | else true | |
167 | + | ||
168 | + | ||
169 | + | func _validateTokenDescr (val_,err_) = if ((size(val_) > 1000)) | |
170 | + | then throw(err_) | |
171 | + | else true | |
172 | + | ||
173 | + | ||
174 | + | func _validateDecimals (val_,err_) = if (if ((0 > val_)) | |
175 | + | then true | |
176 | + | else (val_ > 8)) | |
177 | + | then throw(err_) | |
178 | + | else true | |
179 | + | ||
180 | + | ||
181 | + | func _validatePayment (payment_,assetId_,requiredAmount_,err_) = match payment_.assetId { | |
182 | + | case a: ByteVector => | |
183 | + | if ((assetId_ != toBase58String(a))) | |
184 | + | then throw((err_ + ": asset")) | |
185 | + | else if ((requiredAmount_ > payment_.amount)) | |
186 | + | then throw((err_ + ": amount")) | |
187 | + | else true | |
188 | + | case _ => | |
189 | + | throw((err_ + ": asset")) | |
190 | + | } | |
191 | + | ||
192 | + | ||
193 | + | func _validateListContains (list_,val_,err_) = if (!(containsElement(list_, val_))) | |
194 | + | then throw(err_) | |
195 | + | else true | |
196 | + | ||
197 | + | ||
198 | + | func _assetToStr (asset_) = match asset_ { | |
199 | + | case a: ByteVector => | |
200 | + | toBase58String(a) | |
201 | + | case _ => | |
202 | + | WAVES | |
203 | + | } | |
204 | + | ||
205 | + | ||
206 | + | func _strToAsset (asset_) = if (if ((asset_ == WAVES)) | |
207 | + | then true | |
208 | + | else (asset_ == "")) | |
209 | + | then unit | |
210 | + | else fromBase58String(asset_) | |
211 | + | ||
212 | + | ||
213 | + | func _loadStorage () = match getString(KEY_STORAGE) { | |
214 | + | case a: String => | |
215 | + | let struct = split(a, SEP) | |
216 | + | $Tuple9(fromBase58String(struct[0]), (struct[1] == "1"), parseIntValue(struct[2]), parseIntValue(struct[3]), parseIntValue(struct[4]), parseIntValue(struct[5]), parseIntValue(struct[6]), parseIntValue(struct[7]), parseIntValue(struct[8])) | |
217 | + | case _ => | |
218 | + | $Tuple9(base58'', false, 0, 0, 0, 0, 0, 0, 0) | |
219 | + | } | |
220 | + | ||
221 | + | ||
222 | + | func _saveStorage (storage_) = [StringEntry(KEY_STORAGE, makeString([toBase58String(storage_._1), if (storage_._2) | |
223 | + | then "1" | |
224 | + | else "0", toString(storage_._3), toString(storage_._4), toString(storage_._5), toString(storage_._6), toString(storage_._7), toString(storage_._8), toString(storage_._9)], SEP))] | |
225 | + | ||
226 | + | ||
227 | + | func _loadAssets () = match getString(KEY_ASSETS) { | |
228 | + | case a: String => | |
229 | + | if ((size(a) > 0)) | |
230 | + | then split_51C(a, SEP) | |
231 | + | else nil | |
232 | + | case _ => | |
233 | + | nil | |
234 | + | } | |
235 | + | ||
236 | + | ||
237 | + | func _saveAssets (assets_) = [StringEntry(KEY_ASSETS, makeString_11C(assets_, SEP))] | |
238 | + | ||
239 | + | ||
240 | + | func _loadAssetBalances () = { | |
241 | + | func foldFunc (acc,elem) = { | |
242 | + | let balance = parseIntValue(elem) | |
243 | + | $Tuple2((acc._1 :+ balance), (acc._2 + balance)) | |
244 | + | } | |
245 | + | ||
246 | + | match getString(KEY_ASSET_BALANCES) { | |
247 | + | case a: String => | |
248 | + | if ((size(a) > 0)) | |
249 | + | then { | |
250 | + | let $l = split_51C(a, SEP) | |
251 | + | let $s = size($l) | |
252 | + | let $acc0 = $Tuple2(nil, 0) | |
253 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
254 | + | then $a | |
255 | + | else foldFunc($a, $l[$i]) | |
256 | + | ||
257 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
258 | + | then $a | |
259 | + | else throw("List size exceeds 10") | |
260 | + | ||
261 | + | $f0_2($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) | |
262 | + | } | |
263 | + | else $Tuple2(ZERO_INT_LIST10, 0) | |
264 | + | case _ => | |
265 | + | $Tuple2(ZERO_INT_LIST10, 0) | |
266 | + | } | |
267 | + | } | |
268 | + | ||
269 | + | ||
270 | + | func _saveAssetBalances (balances_) = { | |
271 | + | func foldFunc (acc,elem) = (acc :+ toString(elem)) | |
272 | + | ||
273 | + | [StringEntry(KEY_ASSET_BALANCES, makeString_11C({ | |
274 | + | let $l = balances_ | |
275 | + | let $s = size($l) | |
276 | + | let $acc0 = nil | |
277 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
278 | + | then $a | |
279 | + | else foldFunc($a, $l[$i]) | |
280 | + | ||
281 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
282 | + | then $a | |
283 | + | else throw("List size exceeds 10") | |
284 | + | ||
285 | + | $f0_2($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) | |
286 | + | }, SEP))] | |
287 | + | } | |
288 | + | ||
289 | + | ||
290 | + | func _loadAssetWeights () = { | |
291 | + | func foldFunc (acc,elem) = { | |
292 | + | let weight = parseIntValue(elem) | |
293 | + | $Tuple2((acc._1 :+ weight), (acc._2 + weight)) | |
294 | + | } | |
295 | + | ||
296 | + | match getString(KEY_ASSET_WEIGHTS) { | |
297 | + | case a: String => | |
298 | + | if ((size(a) > 0)) | |
299 | + | then { | |
300 | + | let $l = split_51C(a, SEP) | |
301 | + | let $s = size($l) | |
302 | + | let $acc0 = $Tuple2(nil, 0) | |
303 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
304 | + | then $a | |
305 | + | else foldFunc($a, $l[$i]) | |
306 | + | ||
307 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
308 | + | then $a | |
309 | + | else throw("List size exceeds 10") | |
310 | + | ||
311 | + | $f0_2($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) | |
312 | + | } | |
313 | + | else $Tuple2(ZERO_INT_LIST10, 0) | |
314 | + | case _ => | |
315 | + | $Tuple2(ZERO_INT_LIST10, 0) | |
316 | + | } | |
317 | + | } | |
318 | + | ||
319 | + | ||
320 | + | func _saveAssetWeights (weights_) = { | |
321 | + | func foldFunc (acc,elem) = (acc :+ toString(elem)) | |
322 | + | ||
323 | + | [StringEntry(KEY_ASSET_WEIGHTS, makeString_11C({ | |
324 | + | let $l = weights_ | |
325 | + | let $s = size($l) | |
326 | + | let $acc0 = nil | |
327 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
328 | + | then $a | |
329 | + | else foldFunc($a, $l[$i]) | |
330 | + | ||
331 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
332 | + | then $a | |
333 | + | else throw("List size exceeds 10") | |
334 | + | ||
335 | + | $f0_2($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) | |
336 | + | }, SEP))] | |
337 | + | } | |
338 | + | ||
339 | + | ||
340 | + | func _loadLpFee (assetId_) = match getInteger(makeString([KEY_LP_FEE, assetId_], SEP)) { | |
341 | + | case a: Int => | |
342 | + | a | |
343 | + | case _ => | |
344 | + | 0 | |
345 | + | } | |
346 | + | ||
347 | + | ||
348 | + | func _saveLpFee (assetId_,val_) = [IntegerEntry(makeString([KEY_LP_FEE, assetId_], SEP), val_)] | |
349 | + | ||
350 | + | ||
351 | + | func _loadProtocolFee (assetId_) = match getInteger(makeString([KEY_PROTOCOL_FEE, assetId_], SEP)) { | |
352 | + | case a: Int => | |
353 | + | a | |
354 | + | case _ => | |
355 | + | 0 | |
356 | + | } | |
357 | + | ||
358 | + | ||
359 | + | func _saveProtocolFee (assetId_,val_) = [IntegerEntry(makeString([KEY_PROTOCOL_FEE, assetId_], SEP), val_)] | |
360 | + | ||
361 | + | ||
362 | + | func _loadUserLp (address_) = match getInteger(makeString([KEY_USER_LP, toString(address_)], SEP)) { | |
363 | + | case a: Int => | |
364 | + | a | |
365 | + | case _ => | |
366 | + | 0 | |
367 | + | } | |
368 | + | ||
369 | + | ||
370 | + | func _saveUserLp (address_,val_) = [IntegerEntry(makeString([KEY_USER_LP, toString(address_)], SEP), val_)] | |
371 | + | ||
372 | + | ||
373 | + | func _loadTotalLp () = match getInteger(KEY_TOTAL_LP) { | |
374 | + | case a: Int => | |
375 | + | a | |
376 | + | case _ => | |
377 | + | 0 | |
378 | + | } | |
379 | + | ||
380 | + | ||
381 | + | func _saveTotalLp (val_) = [IntegerEntry(KEY_TOTAL_LP, val_)] | |
382 | + | ||
383 | + | ||
384 | + | func _loadFeeIncome (assetId_) = match getInteger(makeString([KEY_FEE_INCOME, assetId_], SEP)) { | |
385 | + | case a: Int => | |
386 | + | a | |
387 | + | case _ => | |
388 | + | 0 | |
389 | + | } | |
390 | + | ||
391 | + | ||
392 | + | func _saveFeeIncome (assetId_,val_) = [IntegerEntry(makeString([KEY_FEE_INCOME, assetId_], SEP), val_)] | |
393 | + | ||
394 | + | ||
395 | + | func _loadIncomeIntegrals () = { | |
396 | + | func foldFunc (acc,elem) = (acc :+ parseBigIntValue(elem)) | |
397 | + | ||
398 | + | match getString(KEY_INCOME_INTEGRALS) { | |
399 | + | case a: String => | |
400 | + | if ((size(a) > 0)) | |
401 | + | then { | |
402 | + | let $l = split_51C(a, SEP) | |
403 | + | let $s = size($l) | |
404 | + | let $acc0 = nil | |
405 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
406 | + | then $a | |
407 | + | else foldFunc($a, $l[$i]) | |
408 | + | ||
409 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
410 | + | then $a | |
411 | + | else throw("List size exceeds 11") | |
412 | + | ||
413 | + | $f0_2($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) | |
414 | + | } | |
415 | + | else ZERO_BIGINT_LIST11 | |
416 | + | case _ => | |
417 | + | ZERO_BIGINT_LIST11 | |
418 | + | } | |
419 | + | } | |
420 | + | ||
421 | + | ||
422 | + | func _saveIncomeIntegrals (val_) = { | |
423 | + | func foldFunc (acc,elem) = (acc :+ toString(elem)) | |
424 | + | ||
425 | + | [StringEntry(KEY_INCOME_INTEGRALS, makeString_11C({ | |
426 | + | let $l = val_ | |
427 | + | let $s = size($l) | |
428 | + | let $acc0 = nil | |
429 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
430 | + | then $a | |
431 | + | else foldFunc($a, $l[$i]) | |
432 | + | ||
433 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
434 | + | then $a | |
435 | + | else throw("List size exceeds 11") | |
436 | + | ||
437 | + | $f0_2($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) | |
438 | + | }, SEP))] | |
439 | + | } | |
440 | + | ||
441 | + | ||
442 | + | func _loadIncomeIntegralsAt () = { | |
443 | + | func foldFunc (acc,elem) = (acc :+ parseIntValue(elem)) | |
444 | + | ||
445 | + | match getString(KEY_INCOME_INTEGRALS_AT) { | |
446 | + | case a: String => | |
447 | + | if ((size(a) > 0)) | |
448 | + | then { | |
449 | + | let $l = split_51C(a, SEP) | |
450 | + | let $s = size($l) | |
451 | + | let $acc0 = nil | |
452 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
453 | + | then $a | |
454 | + | else foldFunc($a, $l[$i]) | |
455 | + | ||
456 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
457 | + | then $a | |
458 | + | else throw("List size exceeds 11") | |
459 | + | ||
460 | + | $f0_2($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) | |
461 | + | } | |
462 | + | else (ZERO_INT_LIST10 :+ 0) | |
463 | + | case _ => | |
464 | + | (ZERO_INT_LIST10 :+ 0) | |
465 | + | } | |
466 | + | } | |
467 | + | ||
468 | + | ||
469 | + | func _saveIncomeIntegralsAt (val_) = { | |
470 | + | func foldFunc (acc,elem) = (acc :+ toString(elem)) | |
471 | + | ||
472 | + | [StringEntry(KEY_INCOME_INTEGRALS_AT, makeString_11C({ | |
473 | + | let $l = val_ | |
474 | + | let $s = size($l) | |
475 | + | let $acc0 = nil | |
476 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
477 | + | then $a | |
478 | + | else foldFunc($a, $l[$i]) | |
479 | + | ||
480 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
481 | + | then $a | |
482 | + | else throw("List size exceeds 11") | |
483 | + | ||
484 | + | $f0_2($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) | |
485 | + | }, SEP))] | |
486 | + | } | |
487 | + | ||
488 | + | ||
489 | + | func _loadTotalLpIntegral () = match getString(KEY_TOTAL_LP_INTEGRAL) { | |
490 | + | case a: String => | |
491 | + | parseBigIntValue(a) | |
492 | + | case _ => | |
493 | + | toBigInt(0) | |
494 | + | } | |
495 | + | ||
496 | + | ||
497 | + | func _saveTotalLpIntegral (val_) = [StringEntry(KEY_TOTAL_LP_INTEGRAL, toString(val_))] | |
498 | + | ||
499 | + | ||
500 | + | func _loadTotalLpIntegralAt () = match getInteger(KEY_TOTAL_LP_INTEGRAL_AT) { | |
501 | + | case a: Int => | |
502 | + | a | |
503 | + | case _ => | |
504 | + | 0 | |
505 | + | } | |
506 | + | ||
507 | + | ||
508 | + | func _saveTotalLpIntegralAt (val_) = [IntegerEntry(KEY_TOTAL_LP_INTEGRAL_AT, val_)] | |
509 | + | ||
510 | + | ||
511 | + | func _loadUserIncomeIntegrals (user_) = { | |
512 | + | func foldFunc (acc,elem) = (acc :+ parseBigIntValue(elem)) | |
513 | + | ||
514 | + | match getString(makeString([KEY_USER_INCOME_INTEGRALS, toString(user_)], SEP)) { | |
515 | + | case a: String => | |
516 | + | if ((size(a) > 0)) | |
517 | + | then { | |
518 | + | let $l = split_51C(a, SEP) | |
519 | + | let $s = size($l) | |
520 | + | let $acc0 = nil | |
521 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
522 | + | then $a | |
523 | + | else foldFunc($a, $l[$i]) | |
524 | + | ||
525 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
526 | + | then $a | |
527 | + | else throw("List size exceeds 11") | |
528 | + | ||
529 | + | $f0_2($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) | |
530 | + | } | |
531 | + | else ZERO_BIGINT_LIST11 | |
532 | + | case _ => | |
533 | + | ZERO_BIGINT_LIST11 | |
534 | + | } | |
535 | + | } | |
536 | + | ||
537 | + | ||
538 | + | func _saveUserIncomeIntegrals (user_,val_) = { | |
539 | + | func foldFunc (acc,elem) = (acc :+ toString(elem)) | |
540 | + | ||
541 | + | [StringEntry(makeString([KEY_USER_INCOME_INTEGRALS, toString(user_)], SEP), makeString_11C({ | |
542 | + | let $l = val_ | |
543 | + | let $s = size($l) | |
544 | + | let $acc0 = nil | |
545 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
546 | + | then $a | |
547 | + | else foldFunc($a, $l[$i]) | |
548 | + | ||
549 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
550 | + | then $a | |
551 | + | else throw("List size exceeds 11") | |
552 | + | ||
553 | + | $f0_2($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) | |
554 | + | }, SEP))] | |
555 | + | } | |
556 | + | ||
557 | + | ||
558 | + | func _loadUserTotalLpIntegral (user_) = match getString(makeString([KEY_USER_TOTAL_LP_INTEGRALS, toString(user_)], SEP)) { | |
559 | + | case a: String => | |
560 | + | parseBigIntValue(a) | |
561 | + | case _ => | |
562 | + | toBigInt(0) | |
563 | + | } | |
564 | + | ||
565 | + | ||
566 | + | func _saveUserTotalLpIntegral (user_,val_) = [StringEntry(makeString([KEY_USER_TOTAL_LP_INTEGRALS, toString(user_)], SEP), toString(val_))] | |
567 | + | ||
568 | + | ||
569 | + | func _loadUserProfits (user_) = { | |
570 | + | func foldFunc (acc,elem) = (acc :+ parseIntValue(elem)) | |
571 | + | ||
572 | + | match getString(makeString([KEY_USER_PROFITS, toString(user_)], SEP)) { | |
573 | + | case a: String => | |
574 | + | if ((size(a) > 0)) | |
575 | + | then { | |
576 | + | let $l = split_51C(a, SEP) | |
577 | + | let $s = size($l) | |
578 | + | let $acc0 = nil | |
579 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
580 | + | then $a | |
581 | + | else foldFunc($a, $l[$i]) | |
582 | + | ||
583 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
584 | + | then $a | |
585 | + | else throw("List size exceeds 11") | |
586 | + | ||
587 | + | $f0_2($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) | |
588 | + | } | |
589 | + | else (ZERO_INT_LIST10 :+ 0) | |
590 | + | case _ => | |
591 | + | (ZERO_INT_LIST10 :+ 0) | |
592 | + | } | |
593 | + | } | |
594 | + | ||
595 | + | ||
596 | + | func _saveUserProfits (user_,val_) = { | |
597 | + | func foldFunc (acc,elem) = (acc :+ toString(elem)) | |
598 | + | ||
599 | + | [StringEntry(makeString([KEY_USER_PROFITS, toString(user_)], SEP), makeString_11C({ | |
600 | + | let $l = val_ | |
601 | + | let $s = size($l) | |
602 | + | let $acc0 = nil | |
603 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
604 | + | then $a | |
605 | + | else foldFunc($a, $l[$i]) | |
606 | + | ||
607 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
608 | + | then $a | |
609 | + | else throw("List size exceeds 11") | |
610 | + | ||
611 | + | $f0_2($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) | |
612 | + | }, SEP))] | |
613 | + | } | |
614 | + | ||
615 | + | ||
616 | + | func _whenNotInitialized () = { | |
617 | + | let storage = _loadStorage() | |
618 | + | if ((storage._1 != base58'')) | |
619 | + | then throw("_whenNotInitialized: revert") | |
620 | + | else true | |
621 | + | } | |
622 | + | ||
623 | + | ||
624 | + | func _whenInitialized () = { | |
625 | + | let storage = _loadStorage() | |
626 | + | if ((storage._1 == base58'')) | |
627 | + | then throw("_whenInitialized: revert") | |
628 | + | else true | |
629 | + | } | |
630 | + | ||
631 | + | ||
632 | + | func _getDecimals (assetId_) = match assetInfo(fromBase58String(assetId_)) { | |
633 | + | case a: Asset => | |
634 | + | a.decimals | |
635 | + | case _ => | |
636 | + | throw(("_getDecimals: no asset=" + assetId_)) | |
637 | + | } | |
638 | + | ||
639 | + | ||
640 | + | func _normalizeDecimals (amount_,sourceDecimals_,targetDecimals_,round_) = if ((sourceDecimals_ >= targetDecimals_)) | |
641 | + | then fraction(amount_, 1, pow(10, 0, (sourceDecimals_ - targetDecimals_), 0, 0, DOWN), round_) | |
642 | + | else (amount_ * pow(10, 0, (targetDecimals_ - sourceDecimals_), 0, 0, DOWN)) | |
643 | + | ||
644 | + | ||
645 | + | func _prepareAssetBalances (assets_) = { | |
646 | + | func foldFunc (acc,elem) = (acc :+ 0) | |
647 | + | ||
648 | + | let $l = assets_ | |
649 | + | let $s = size($l) | |
650 | + | let $acc0 = nil | |
651 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
652 | + | then $a | |
653 | + | else foldFunc($a, $l[$i]) | |
654 | + | ||
655 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
656 | + | then $a | |
657 | + | else throw("List size exceeds 10") | |
658 | + | ||
659 | + | $f0_2($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) | |
660 | + | } | |
661 | + | ||
662 | + | ||
663 | + | func _prepareAssetWeights (assetWeights_) = { | |
664 | + | func foldFunc (acc,elem) = { | |
665 | + | let weight = parseIntValue(elem) | |
666 | + | $Tuple2((acc._1 :+ weight), (acc._2 + weight)) | |
667 | + | } | |
668 | + | ||
669 | + | let $l = assetWeights_ | |
670 | + | let $s = size($l) | |
671 | + | let $acc0 = $Tuple2(nil, 0) | |
672 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
673 | + | then $a | |
674 | + | else foldFunc($a, $l[$i]) | |
675 | + | ||
676 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
677 | + | then $a | |
678 | + | else throw("List size exceeds 10") | |
679 | + | ||
680 | + | $f0_2($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) | |
681 | + | } | |
682 | + | ||
683 | + | ||
684 | + | func _getAssetBalances (assets_,decimals_) = { | |
685 | + | func foldFunc (acc,elem) = { | |
686 | + | let assetDecimals = _getDecimals(elem) | |
687 | + | let balance = _normalizeDecimals(assetBalance(this, fromBase58String(elem)), assetDecimals, decimals_, DOWN) | |
688 | + | $Tuple2((acc._1 :+ balance), (acc._2 + balance)) | |
689 | + | } | |
690 | + | ||
691 | + | let $l = assets_ | |
692 | + | let $s = size($l) | |
693 | + | let $acc0 = $Tuple2(nil, 0) | |
694 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
695 | + | then $a | |
696 | + | else foldFunc($a, $l[$i]) | |
697 | + | ||
698 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
699 | + | then $a | |
700 | + | else throw("List size exceeds 10") | |
701 | + | ||
702 | + | $f0_2($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) | |
703 | + | } | |
704 | + | ||
705 | + | ||
706 | + | func _toString (assets_) = { | |
707 | + | func foldFunc (acc,elem) = (acc :+ toString(elem)) | |
708 | + | ||
709 | + | makeString({ | |
710 | + | let $l = assets_ | |
711 | + | let $s = size($l) | |
712 | + | let $acc0 = nil | |
713 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
714 | + | then $a | |
715 | + | else foldFunc($a, $l[$i]) | |
716 | + | ||
717 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
718 | + | then $a | |
719 | + | else throw("List size exceeds 10") | |
720 | + | ||
721 | + | $f0_2($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) | |
722 | + | }, SEP) | |
723 | + | } | |
724 | + | ||
725 | + | ||
726 | + | func _getEquilibriums (sigmaBalances_,weights_,sigmaWeight_) = { | |
727 | + | func foldFunc (acc,elem) = (acc :+ fraction(sigmaBalances_, elem, sigmaWeight_)) | |
728 | + | ||
729 | + | let $l = weights_ | |
730 | + | let $s = size($l) | |
731 | + | let $acc0 = nil | |
732 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
733 | + | then $a | |
734 | + | else foldFunc($a, $l[$i]) | |
735 | + | ||
736 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
737 | + | then $a | |
738 | + | else throw("List size exceeds 10") | |
739 | + | ||
740 | + | $f0_2($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) | |
741 | + | } | |
742 | + | ||
743 | + | ||
744 | + | func _incrementBalancesByAmounts (balances_,amounts_) = { | |
745 | + | func foldFunc (acc,elem) = { | |
746 | + | let index = acc._1 | |
747 | + | let amount = amounts_[index] | |
748 | + | let newBalance = (elem + amount) | |
749 | + | $Tuple3((index + 1), (acc._2 :+ newBalance), (acc._3 + newBalance)) | |
750 | + | } | |
751 | + | ||
752 | + | let result = { | |
753 | + | let $l = balances_ | |
754 | + | let $s = size($l) | |
755 | + | let $acc0 = $Tuple3(0, nil, 0) | |
756 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
757 | + | then $a | |
758 | + | else foldFunc($a, $l[$i]) | |
759 | + | ||
760 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
761 | + | then $a | |
762 | + | else throw("List size exceeds 10") | |
763 | + | ||
764 | + | $f0_2($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) | |
765 | + | } | |
766 | + | $Tuple2(result._2, result._3) | |
767 | + | } | |
768 | + | ||
769 | + | ||
770 | + | func _incrementBalancesByPayments (balances_,payments_,assets_,decimals_,err_) = { | |
771 | + | func foldFunc (acc,elem) = { | |
772 | + | let index = acc._1 | |
773 | + | let payment = payments_[index] | |
774 | + | let paymentAssetStr = _assetToStr(payment.assetId) | |
775 | + | let err = if ((paymentAssetStr != assets_[index])) | |
776 | + | then throw(((err_ + ": index=") + toString(index))) | |
777 | + | else unit | |
778 | + | if ((err == err)) | |
779 | + | then { | |
780 | + | let assetDecimals = _getDecimals(paymentAssetStr) | |
781 | + | let newBalance = (elem + _normalizeDecimals(payments_[index].amount, assetDecimals, decimals_, DOWN)) | |
782 | + | $Tuple3((index + 1), (acc._2 :+ newBalance), (acc._3 + newBalance)) | |
783 | + | } | |
784 | + | else throw("Strict value is not equal to itself.") | |
785 | + | } | |
786 | + | ||
787 | + | let result = { | |
788 | + | let $l = balances_ | |
789 | + | let $s = size($l) | |
790 | + | let $acc0 = $Tuple3(0, nil, 0) | |
791 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
792 | + | then $a | |
793 | + | else foldFunc($a, $l[$i]) | |
794 | + | ||
795 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
796 | + | then $a | |
797 | + | else throw("List size exceeds 10") | |
798 | + | ||
799 | + | $f0_2($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) | |
800 | + | } | |
801 | + | $Tuple2(result._2, result._3) | |
802 | + | } | |
803 | + | ||
804 | + | ||
805 | + | func _incrementBalanceByIndex (balances_,index_,amount_) = { | |
806 | + | func foldFunc (acc,elem) = { | |
807 | + | let index = acc._1 | |
808 | + | if ((index == index_)) | |
809 | + | then $Tuple2((index + 1), (acc._2 :+ (elem + amount_))) | |
810 | + | else $Tuple2((index + 1), (acc._2 :+ elem)) | |
811 | + | } | |
812 | + | ||
813 | + | let result = { | |
814 | + | let $l = balances_ | |
815 | + | let $s = size($l) | |
816 | + | let $acc0 = $Tuple2(0, nil) | |
817 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
818 | + | then $a | |
819 | + | else foldFunc($a, $l[$i]) | |
820 | + | ||
821 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
822 | + | then $a | |
823 | + | else throw("List size exceeds 10") | |
824 | + | ||
825 | + | $f0_2($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) | |
826 | + | } | |
827 | + | result._2 | |
828 | + | } | |
829 | + | ||
830 | + | ||
831 | + | func _decrementBalanceByIndex (balances_,index_,amount_) = { | |
832 | + | func foldFunc (acc,elem) = { | |
833 | + | let index = acc._1 | |
834 | + | if ((index == index_)) | |
835 | + | then $Tuple2((index + 1), (acc._2 :+ (elem - amount_))) | |
836 | + | else $Tuple2((index + 1), (acc._2 :+ elem)) | |
837 | + | } | |
838 | + | ||
839 | + | let result = { | |
840 | + | let $l = balances_ | |
841 | + | let $s = size($l) | |
842 | + | let $acc0 = $Tuple2(0, nil) | |
843 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
844 | + | then $a | |
845 | + | else foldFunc($a, $l[$i]) | |
846 | + | ||
847 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
848 | + | then $a | |
849 | + | else throw("List size exceeds 10") | |
850 | + | ||
851 | + | $f0_2($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) | |
852 | + | } | |
853 | + | result._2 | |
854 | + | } | |
855 | + | ||
856 | + | ||
857 | + | func _decrementBalancesByLpAmount (balances_,amount_,lpTotalSupply_) = { | |
858 | + | let rate = fraction((lpTotalSupply_ - amount_), RATE_FACTOR, lpTotalSupply_, CEILING) | |
859 | + | func foldFunc (acc,elem) = { | |
860 | + | let newBalance = fraction(elem, rate, RATE_FACTOR, CEILING) | |
861 | + | let deltaBalance = (elem - newBalance) | |
862 | + | $Tuple3((acc._1 :+ newBalance), (acc._2 + newBalance), (acc._3 :+ deltaBalance)) | |
863 | + | } | |
864 | + | ||
865 | + | let $l = balances_ | |
866 | + | let $s = size($l) | |
867 | + | let $acc0 = $Tuple3(nil, 0, nil) | |
868 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
869 | + | then $a | |
870 | + | else foldFunc($a, $l[$i]) | |
871 | + | ||
872 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
873 | + | then $a | |
874 | + | else throw("List size exceeds 10") | |
875 | + | ||
876 | + | $f0_2($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) | |
877 | + | } | |
878 | + | ||
879 | + | ||
880 | + | func _getPaymentsFromBalances (assets_,balances_,recipient_,sourceDecimals_) = { | |
881 | + | func foldFunc (acc,elem) = { | |
882 | + | let index = acc._1 | |
883 | + | $Tuple2((index + 1), (acc._2 :+ ScriptTransfer(recipient_, _normalizeDecimals(balances_[index], sourceDecimals_, _getDecimals(elem), DOWN), _strToAsset(elem)))) | |
884 | + | } | |
885 | + | ||
886 | + | let result = { | |
887 | + | let $l = assets_ | |
888 | + | let $s = size($l) | |
889 | + | let $acc0 = $Tuple2(0, nil) | |
890 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
891 | + | then $a | |
892 | + | else foldFunc($a, $l[$i]) | |
893 | + | ||
894 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
895 | + | then $a | |
896 | + | else throw("List size exceeds 10") | |
897 | + | ||
898 | + | $f0_2($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) | |
899 | + | } | |
900 | + | result._2 | |
901 | + | } | |
902 | + | ||
903 | + | ||
904 | + | func _calculateMicroFee (balance_,equilibrium_,weightAmplifier_,slippageRate_,feeMaxRate_) = if ((equilibrium_ > balance_)) | |
905 | + | then { | |
906 | + | let threshold = fraction(equilibrium_, (MAX_WEIGHT_AMPLIFIER - weightAmplifier_), MAX_WEIGHT_AMPLIFIER) | |
907 | + | if ((threshold > balance_)) | |
908 | + | then { | |
909 | + | let maxDeviation = (threshold - balance_) | |
910 | + | let feeRate = fraction(fraction(maxDeviation, slippageRate_, SLIPPAGE_RATE_FACTOR), FEE_RATE_FACTOR, equilibrium_) | |
911 | + | if ((feeRate > feeMaxRate_)) | |
912 | + | then fraction(maxDeviation, feeMaxRate_, FEE_RATE_FACTOR) | |
913 | + | else fraction(maxDeviation, feeRate, FEE_RATE_FACTOR) | |
914 | + | } | |
915 | + | else 0 | |
916 | + | } | |
917 | + | else { | |
918 | + | let threshold = fraction(equilibrium_, (MAX_WEIGHT_AMPLIFIER + weightAmplifier_), MAX_WEIGHT_AMPLIFIER) | |
919 | + | if ((balance_ > threshold)) | |
920 | + | then { | |
921 | + | let maxDeviation = (balance_ - threshold) | |
922 | + | let feeRate = fraction(fraction(maxDeviation, slippageRate_, SLIPPAGE_RATE_FACTOR), FEE_RATE_FACTOR, equilibrium_) | |
923 | + | if ((feeRate > feeMaxRate_)) | |
924 | + | then fraction(maxDeviation, feeMaxRate_, FEE_RATE_FACTOR) | |
925 | + | else fraction(maxDeviation, feeRate, FEE_RATE_FACTOR) | |
926 | + | } | |
927 | + | else 0 | |
928 | + | } | |
929 | + | ||
930 | + | ||
931 | + | func _calculateFee (balances_,assetsTotalSupply_,weights_,sigmaWeight_,weightAmplifier_,slippageRate_,feeMaxRate_) = { | |
932 | + | func foldFunc (acc,balance) = { | |
933 | + | let index = acc._1 | |
934 | + | let equilibrium = fraction(assetsTotalSupply_, weights_[index], sigmaWeight_) | |
935 | + | $Tuple2((index + 1), (acc._2 + _calculateMicroFee(balance, equilibrium, weightAmplifier_, slippageRate_, feeMaxRate_))) | |
936 | + | } | |
937 | + | ||
938 | + | let result = { | |
939 | + | let $l = balances_ | |
940 | + | let $s = size($l) | |
941 | + | let $acc0 = $Tuple2(0, 0) | |
942 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
943 | + | then $a | |
944 | + | else foldFunc($a, $l[$i]) | |
945 | + | ||
946 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
947 | + | then $a | |
948 | + | else throw("List size exceeds 10") | |
949 | + | ||
950 | + | $f0_2($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) | |
951 | + | } | |
952 | + | result._2 | |
953 | + | } | |
954 | + | ||
955 | + | ||
956 | + | func _validateLiquidityInvariant (prevAssetBalances_,prevAssetTotalSupply_,assetBalances_,assetTotalSupply_,prevLpTotalSupply_,lpTotalSupply_,assetWeights_,sigmaWeight_,weightAmplifier_,slippageRate_,feeMaxRate_) = if (if ((prevLpTotalSupply_ == 0)) | |
957 | + | then true | |
958 | + | else (lpTotalSupply_ == 0)) | |
959 | + | then true | |
960 | + | else { | |
961 | + | let prevAssetsRate = fraction((prevAssetTotalSupply_ - _calculateFee(prevAssetBalances_, prevAssetTotalSupply_, assetWeights_, sigmaWeight_, weightAmplifier_, slippageRate_, feeMaxRate_)), RATE_FACTOR, prevLpTotalSupply_) | |
962 | + | let newAssetsRate = fraction((assetTotalSupply_ - _calculateFee(assetBalances_, assetTotalSupply_, assetWeights_, sigmaWeight_, weightAmplifier_, slippageRate_, feeMaxRate_)), RATE_FACTOR, lpTotalSupply_) | |
963 | + | let diff = (newAssetsRate - prevAssetsRate) | |
964 | + | if (if ((0 >= diff)) | |
965 | + | then ((-1 * RATE_FACTOR) > diff) | |
966 | + | else false) | |
967 | + | then throw(("_validateLiquidityInvariant: revert: diff=" + toString(diff))) | |
968 | + | else true | |
969 | + | } | |
970 | + | ||
971 | + | ||
972 | + | func _validateSwapInvariant (prevAssetBalances_,prevAssetTotalSupply_,assetBalances_,assetTotalSupply_,assetWeights_,sigmaWeight_,weightAmplifier_,slippageRate_,feeMaxRate_) = { | |
973 | + | let prevUtil = (prevAssetTotalSupply_ - _calculateFee(prevAssetBalances_, prevAssetTotalSupply_, assetWeights_, sigmaWeight_, weightAmplifier_, slippageRate_, feeMaxRate_)) | |
974 | + | let newUtil = (assetTotalSupply_ - _calculateFee(assetBalances_, assetTotalSupply_, assetWeights_, sigmaWeight_, weightAmplifier_, slippageRate_, feeMaxRate_)) | |
975 | + | let diff = (newUtil - prevUtil) | |
976 | + | if (if ((0 >= diff)) | |
977 | + | then ((-1 * RATE_FACTOR) > diff) | |
978 | + | else false) | |
979 | + | then throw(("_validateSwapInvariant: revert: diff=" + toString(diff))) | |
980 | + | else true | |
981 | + | } | |
982 | + | ||
983 | + | ||
984 | + | func _validateAssetAllocation (balance_,assetTotalSupply_,prevBalance_,prevAssetTotalSupply_,weight_,sigmaWeight_,maxAllocAmp_) = { | |
985 | + | let equilibrium = fraction(assetTotalSupply_, weight_, sigmaWeight_) | |
986 | + | let maxAllocationAmp = if ((balance_ > equilibrium)) | |
987 | + | then (MAX_AMPLIFIER + maxAllocAmp_) | |
988 | + | else (MAX_AMPLIFIER - maxAllocAmp_) | |
989 | + | let maxAllocation = fraction(equilibrium, maxAllocationAmp, MAX_AMPLIFIER) | |
990 | + | let prevMaxAllocation = fraction(fraction(prevAssetTotalSupply_, weight_, sigmaWeight_), maxAllocationAmp, MAX_AMPLIFIER) | |
991 | + | if ((balance_ > equilibrium)) | |
992 | + | then if ((balance_ > maxAllocation)) | |
993 | + | then if ((prevMaxAllocation > prevBalance_)) | |
994 | + | then throw("_validateAssetAllocation: new up") | |
995 | + | else if (((balance_ - maxAllocation) > (prevBalance_ - prevMaxAllocation))) | |
996 | + | then throw("_validateAssetAllocation: still up") | |
997 | + | else true | |
998 | + | else true | |
999 | + | else if ((maxAllocation > balance_)) | |
1000 | + | then if ((prevBalance_ > prevMaxAllocation)) | |
1001 | + | then throw("_validateAssetAllocation: new down") | |
1002 | + | else if (((prevMaxAllocation - prevBalance_) > (maxAllocation - balance_))) | |
1003 | + | then throw("_validateAssetAllocation: still down") | |
1004 | + | else true | |
1005 | + | else true | |
1006 | + | } | |
1007 | + | ||
1008 | + | ||
1009 | + | func _validateAllocation (assetBalances_,assetTotalSupply_,prevAssetBalances_,prevAssetTotalSupply_,assetWeights_,sigmaWeight_,maxAllocAmp_) = { | |
1010 | + | func foldFunc (acc,elem) = { | |
1011 | + | let index = acc._1 | |
1012 | + | $Tuple2((index + 1), if (acc._2) | |
1013 | + | then _validateAssetAllocation(elem, assetTotalSupply_, prevAssetBalances_[index], prevAssetTotalSupply_, assetWeights_[index], sigmaWeight_, maxAllocAmp_) | |
1014 | + | else false) | |
1015 | + | } | |
1016 | + | ||
1017 | + | let result = { | |
1018 | + | let $l = assetBalances_ | |
1019 | + | let $s = size($l) | |
1020 | + | let $acc0 = $Tuple2(0, true) | |
1021 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
1022 | + | then $a | |
1023 | + | else foldFunc($a, $l[$i]) | |
1024 | + | ||
1025 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
1026 | + | then $a | |
1027 | + | else throw("List size exceeds 10") | |
1028 | + | ||
1029 | + | $f0_2($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) | |
1030 | + | } | |
1031 | + | result._2 | |
1032 | + | } | |
1033 | + | ||
1034 | + | ||
1035 | + | func _userCheckpoint (user_,userLp_,totalIncomeIntegrals_,totalLpIntegral_) = { | |
1036 | + | let userProfits = _loadUserProfits(user_) | |
1037 | + | let userIncomeIntegrals = _loadUserIncomeIntegrals(user_) | |
1038 | + | let userTotalLpIntegral = _loadUserTotalLpIntegral(user_) | |
1039 | + | func foldFunc (acc,elem) = { | |
1040 | + | let index = acc._1 | |
1041 | + | let profitUpdated = (elem + toInt(fraction(toBigInt(userLp_), (totalIncomeIntegrals_[index] - userIncomeIntegrals[index]), (totalLpIntegral_ - userTotalLpIntegral)))) | |
1042 | + | $Tuple3((index + 1), (acc._2 :+ profitUpdated), acc._3) | |
1043 | + | } | |
1044 | + | ||
1045 | + | let $t02489224964 = { | |
1046 | + | let $l = userProfits | |
1047 | + | let $s = size($l) | |
1048 | + | let $acc0 = $Tuple3(0, nil, nil) | |
1049 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
1050 | + | then $a | |
1051 | + | else foldFunc($a, $l[$i]) | |
1052 | + | ||
1053 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
1054 | + | then $a | |
1055 | + | else throw("List size exceeds 11") | |
1056 | + | ||
1057 | + | $f0_2($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) | |
1058 | + | } | |
1059 | + | let idx = $t02489224964._1 | |
1060 | + | let profitsUpdated = $t02489224964._2 | |
1061 | + | $Tuple2(profitsUpdated, ((_saveUserIncomeIntegrals(user_, totalIncomeIntegrals_) ++ _saveUserTotalLpIntegral(user_, totalLpIntegral_)) ++ _saveUserProfits(user_, profitsUpdated))) | |
1062 | + | } | |
1063 | + | ||
1064 | + | ||
1065 | + | func _checkpoint (assets_) = { | |
1066 | + | let incomeIntegrals = _loadIncomeIntegrals() | |
1067 | + | let incomeIntegalsAt = _loadIncomeIntegralsAt() | |
1068 | + | func foldFunc (acc,elem) = { | |
1069 | + | let index = acc._1 | |
1070 | + | let incomeIntegral = (incomeIntegrals[index] + (toBigInt(_loadFeeIncome(elem)) * toBigInt((height - incomeIntegalsAt[index])))) | |
1071 | + | $Tuple3((index + 1), (acc._2 :+ incomeIntegral), (acc._3 :+ height)) | |
1072 | + | } | |
1073 | + | ||
1074 | + | let totalLpIntegralUpdated = (_loadTotalLpIntegral() + (toBigInt(_loadTotalLp()) * toBigInt((height - _loadTotalLpIntegralAt())))) | |
1075 | + | let $t02583725938 = { | |
1076 | + | let $l = assets_ | |
1077 | + | let $s = size($l) | |
1078 | + | let $acc0 = $Tuple3(0, nil, nil) | |
1079 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
1080 | + | then $a | |
1081 | + | else foldFunc($a, $l[$i]) | |
1082 | + | ||
1083 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
1084 | + | then $a | |
1085 | + | else throw("List size exceeds 11") | |
1086 | + | ||
1087 | + | $f0_2($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) | |
1088 | + | } | |
1089 | + | let idx = $t02583725938._1 | |
1090 | + | let incomeIntegralsUpdated = $t02583725938._2 | |
1091 | + | let incomeIntegalsAtUpdated = $t02583725938._3 | |
1092 | + | $Tuple3(incomeIntegralsUpdated, totalLpIntegralUpdated, (((_saveIncomeIntegrals(incomeIntegralsUpdated) ++ _saveIncomeIntegralsAt(incomeIntegalsAtUpdated)) ++ _saveTotalLpIntegral(totalLpIntegralUpdated)) ++ _saveTotalLpIntegralAt(height))) | |
1093 | + | } | |
1094 | + | ||
1095 | + | ||
1096 | + | @Callable(i) | |
1097 | + | func init (assets_,assetWeights_,lpFeeRate_,protocolFeeRate_,lpTokenName_,lpTokenDescr_,lpTokenDecimals_,maxAllocationAmplifier_,weightAmplifier_,slippageRate_,feeMaxRate_) = { | |
1098 | + | let err = if (if (if (if (if (if (if (if (if (if (if (if (_whenNotInitialized()) | |
1099 | + | then _validateAssets(assets_, "init: invalid assets") | |
1100 | + | else false) | |
1101 | + | then _validateIntList(assetWeights_, 0, MAX_WEIGHT, "init: invalid assetWeights") | |
1102 | + | else false) | |
1103 | + | then _validateIntEquals(size(assets_), size(assetWeights_), "init: invalid assetWeights size") | |
1104 | + | else false) | |
1105 | + | then _validateInt(lpFeeRate_, 0, MAX_FEE, "init: invalid lp fee") | |
1106 | + | else false) | |
1107 | + | then _validateInt(protocolFeeRate_, 0, MAX_FEE, "init: invalid protocol fee") | |
1108 | + | else false) | |
1109 | + | then _validateTokenName(lpTokenName_, "init: invalid name") | |
1110 | + | else false) | |
1111 | + | then _validateTokenDescr(lpTokenDescr_, "init: invalid descr") | |
1112 | + | else false) | |
1113 | + | then _validateDecimals(lpTokenDecimals_, "init: invalid decimals") | |
1114 | + | else false) | |
1115 | + | then _validateInt(maxAllocationAmplifier_, 0, MAX_AMPLIFIER, "init: invalid maxAllocationAmplifier") | |
1116 | + | else false) | |
1117 | + | then _validateInt(weightAmplifier_, 0, maxAllocationAmplifier_, "init: invalid weightAmplifier") | |
1118 | + | else false) | |
1119 | + | then _validateInt(slippageRate_, 0, MAX_INT, "init: invalid slippageRate") | |
1120 | + | else false) | |
1121 | + | then _validateInt(feeMaxRate_, 0, MAX_INT, "init: invalid feeMaxRate") | |
1122 | + | else false | |
1123 | + | if ((err == err)) | |
1124 | + | then { | |
1125 | + | let $t02763927708 = _prepareAssetWeights(assetWeights_) | |
1126 | + | let assetWeights = $t02763927708._1 | |
1127 | + | let sigmaWeight = $t02763927708._2 | |
1128 | + | let assetBalances = _prepareAssetBalances(assets_) | |
1129 | + | let issue = Issue(lpTokenName_, lpTokenDescr_, 0, lpTokenDecimals_, true) | |
1130 | + | let lpAssetId = calculateAssetId(issue) | |
1131 | + | let storageUpdated = $Tuple9(lpAssetId, true, 0, lpFeeRate_, protocolFeeRate_, maxAllocationAmplifier_, weightAmplifier_, slippageRate_, feeMaxRate_) | |
1132 | + | $Tuple2((((([issue] ++ _saveStorage(storageUpdated)) ++ _saveAssets(assets_)) ++ _saveAssetBalances(assetBalances)) ++ _saveAssetWeights(assetWeights)), unit) | |
1133 | + | } | |
1134 | + | else throw("Strict value is not equal to itself.") | |
1135 | + | } | |
1136 | + | ||
1137 | + | ||
1138 | + | ||
1139 | + | @Callable(i) | |
1140 | + | func depositAll (amount_) = { | |
1141 | + | let err = _validateInt(amount_, 0, MAX_INT, "depositAll: invalid amount") | |
1142 | + | if ((err == err)) | |
1143 | + | then { | |
1144 | + | let storage = _loadStorage() | |
1145 | + | let lpAssetId = storage._1 | |
1146 | + | let lpDecimals = _getDecimals(toBase58String(lpAssetId)) | |
1147 | + | let lpTotalSupply = storage._3 | |
1148 | + | let weightAmplifier = storage._7 | |
1149 | + | let slippageRate = storage._8 | |
1150 | + | let feeMaxRate = storage._9 | |
1151 | + | let assets = _loadAssets() | |
1152 | + | let $t02902829081 = _loadAssetWeights() | |
1153 | + | let assetWeights = $t02902829081._1 | |
1154 | + | let sigmaWeight = $t02902829081._2 | |
1155 | + | let $t02908629154 = _loadAssetBalances() | |
1156 | + | let prevAssetBalances = $t02908629154._1 | |
1157 | + | let prevAssetTotalSupply = $t02908629154._2 | |
1158 | + | let $t02916032465 = if ((prevAssetTotalSupply == 0)) | |
1159 | + | then { | |
1160 | + | func foldFunc (acc,elem) = { | |
1161 | + | let index = acc._1 | |
1162 | + | let paymentAssetStr = _assetToStr(i.payments[index].assetId) | |
1163 | + | let paymentAssetDecimals = _getDecimals(paymentAssetStr) | |
1164 | + | let requiredAmountNormalized = fraction(assetWeights[index], amount_, sigmaWeight) | |
1165 | + | let requiredAmount = _normalizeDecimals(requiredAmountNormalized, lpDecimals, paymentAssetDecimals, CEILING) | |
1166 | + | let err1 = if ((paymentAssetStr != elem)) | |
1167 | + | then throw(("depositAll: invalid payment: index=" + toString(index))) | |
1168 | + | else if ((0 >= requiredAmount)) | |
1169 | + | then throw("depositAll: too little amount required") | |
1170 | + | else unit | |
1171 | + | if ((err1 == err1)) | |
1172 | + | then { | |
1173 | + | let change = if ((i.payments[index].amount > requiredAmount)) | |
1174 | + | then [ScriptTransfer(i.caller, (i.payments[index].amount - requiredAmount), i.payments[index].assetId)] | |
1175 | + | else if ((requiredAmount > i.payments[index].amount)) | |
1176 | + | then throw(((("depositAll: insufficient payment, index=" + toString(index)) + ", required=") + toString(requiredAmount))) | |
1177 | + | else nil | |
1178 | + | $Tuple3((index + 1), (acc._2 ++ change), (acc._3 :+ requiredAmountNormalized)) | |
1179 | + | } | |
1180 | + | else throw("Strict value is not equal to itself.") | |
1181 | + | } | |
1182 | + | ||
1183 | + | let result = { | |
1184 | + | let $l = assets | |
1185 | + | let $s = size($l) | |
1186 | + | let $acc0 = $Tuple3(0, nil, nil) | |
1187 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
1188 | + | then $a | |
1189 | + | else foldFunc($a, $l[$i]) | |
1190 | + | ||
1191 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
1192 | + | then $a | |
1193 | + | else throw("List size exceeds 10") | |
1194 | + | ||
1195 | + | $f0_2($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) | |
1196 | + | } | |
1197 | + | $Tuple3(amount_, result._2, result._3) | |
1198 | + | } | |
1199 | + | else { | |
1200 | + | let ratio = fraction(toBigInt(amount_), PERCENT_FACTOR, toBigInt(prevAssetTotalSupply)) | |
1201 | + | func foldFunc1 (acc,elem) = { | |
1202 | + | let index = acc._1 | |
1203 | + | let paymentAssetStr = _assetToStr(i.payments[index].assetId) | |
1204 | + | let paymentAssetDecimals = _getDecimals(paymentAssetStr) | |
1205 | + | let requiredAmountNormalized = toInt(fraction(ratio, toBigInt(prevAssetBalances[index]), PERCENT_FACTOR)) | |
1206 | + | let requiredAmount = _normalizeDecimals(requiredAmountNormalized, lpDecimals, paymentAssetDecimals, CEILING) | |
1207 | + | let err1 = if ((paymentAssetStr != elem)) | |
1208 | + | then throw(("depositAll: invalid payment: index=" + toString(index))) | |
1209 | + | else if ((0 >= requiredAmount)) | |
1210 | + | then throw("depositAll: too little amount reqiured") | |
1211 | + | else unit | |
1212 | + | if ((err1 == err1)) | |
1213 | + | then { | |
1214 | + | let change = if ((i.payments[index].amount > requiredAmount)) | |
1215 | + | then [ScriptTransfer(i.caller, (i.payments[index].amount - requiredAmount), i.payments[index].assetId)] | |
1216 | + | else if ((requiredAmount > i.payments[index].amount)) | |
1217 | + | then throw(((("depositAll: insufficient payment, index=" + toString(index)) + ", required=") + toString(requiredAmount))) | |
1218 | + | else nil | |
1219 | + | $Tuple3((index + 1), (acc._2 ++ change), (acc._3 :+ requiredAmountNormalized)) | |
1220 | + | } | |
1221 | + | else throw("Strict value is not equal to itself.") | |
1222 | + | } | |
1223 | + | ||
1224 | + | let result = { | |
1225 | + | let $l = assets | |
1226 | + | let $s = size($l) | |
1227 | + | let $acc0 = $Tuple3(0, nil, nil) | |
1228 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
1229 | + | then $a | |
1230 | + | else foldFunc1($a, $l[$i]) | |
1231 | + | ||
1232 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
1233 | + | then $a | |
1234 | + | else throw("List size exceeds 10") | |
1235 | + | ||
1236 | + | $f0_2($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) | |
1237 | + | } | |
1238 | + | $Tuple3(fraction(amount_, lpTotalSupply, prevAssetTotalSupply), result._2, result._3) | |
1239 | + | } | |
1240 | + | let lpTokensToMint = $t02916032465._1 | |
1241 | + | let changeActions = $t02916032465._2 | |
1242 | + | let requiredAmountsNormalized = $t02916032465._3 | |
1243 | + | let $t03247132584 = _incrementBalancesByAmounts(prevAssetBalances, requiredAmountsNormalized) | |
1244 | + | let assetBalances = $t03247132584._1 | |
1245 | + | let assetTotalSupply = $t03247132584._2 | |
1246 | + | let err2 = _validateLiquidityInvariant(prevAssetBalances, prevAssetTotalSupply, assetBalances, assetTotalSupply, lpTotalSupply, (lpTotalSupply + lpTokensToMint), assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1247 | + | if ((err2 == err2)) | |
1248 | + | then { | |
1249 | + | let storageUpdated = $Tuple9(storage._1, storage._2, (lpTotalSupply + lpTokensToMint), storage._4, storage._5, storage._6, storage._7, storage._8, storage._9) | |
1250 | + | $Tuple2(((([Reissue(lpAssetId, lpTokensToMint, true), ScriptTransfer(i.caller, lpTokensToMint, lpAssetId)] ++ _saveStorage(storageUpdated)) ++ _saveAssetBalances(assetBalances)) ++ changeActions), unit) | |
1251 | + | } | |
1252 | + | else throw("Strict value is not equal to itself.") | |
1253 | + | } | |
1254 | + | else throw("Strict value is not equal to itself.") | |
1255 | + | } | |
1256 | + | ||
1257 | + | ||
1258 | + | ||
1259 | + | @Callable(i) | |
1260 | + | func deposit (minLpAmount_) = { | |
1261 | + | let err = _validateInt(minLpAmount_, 0, MAX_INT, "deposit: invalid min lp amount") | |
1262 | + | if ((err == err)) | |
1263 | + | then { | |
1264 | + | let storage = _loadStorage() | |
1265 | + | let lpAssetId = storage._1 | |
1266 | + | let lpDecimals = _getDecimals(toBase58String(lpAssetId)) | |
1267 | + | let lpTotalSupply = storage._3 | |
1268 | + | let maxAllocAmplifier = storage._6 | |
1269 | + | let weightAmplifier = storage._7 | |
1270 | + | let slippageRate = storage._8 | |
1271 | + | let feeMaxRate = storage._9 | |
1272 | + | let assets = _loadAssets() | |
1273 | + | let $t03390833961 = _loadAssetWeights() | |
1274 | + | let assetWeights = $t03390833961._1 | |
1275 | + | let sigmaWeight = $t03390833961._2 | |
1276 | + | let $t03396634034 = _loadAssetBalances() | |
1277 | + | let prevAssetBalances = $t03396634034._1 | |
1278 | + | let prevAssetTotalSupply = $t03396634034._2 | |
1279 | + | let err1 = if (if (_validateIntEquals(size(i.payments), 1, "deposit: invalid payments size")) | |
1280 | + | then _validateListContains(assets, _assetToStr(i.payments[0].assetId), "deposit: invalid payment asset") | |
1281 | + | else false) | |
1282 | + | then _validateInt(i.payments[0].amount, 0, MAX_INT, "deposit: invalid payment amount") | |
1283 | + | else false | |
1284 | + | if ((err1 == err1)) | |
1285 | + | then { | |
1286 | + | let assetStr = _assetToStr(i.payments[0].assetId) | |
1287 | + | let assetDecimals = _getDecimals(assetStr) | |
1288 | + | let amountNormalized = _normalizeDecimals(i.payments[0].amount, assetDecimals, lpDecimals, DOWN) | |
1289 | + | let assetBalances = _incrementBalanceByIndex(prevAssetBalances, value(indexOf(assets, assetStr)), amountNormalized) | |
1290 | + | let assetTotalSupply = (prevAssetTotalSupply + amountNormalized) | |
1291 | + | let err2 = _validateAllocation(assetBalances, assetTotalSupply, prevAssetBalances, prevAssetTotalSupply, assetWeights, sigmaWeight, maxAllocAmplifier) | |
1292 | + | if ((err2 == err2)) | |
1293 | + | then { | |
1294 | + | let prevFee = _calculateFee(prevAssetBalances, prevAssetTotalSupply, assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1295 | + | let fee = _calculateFee(assetBalances, assetTotalSupply, assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1296 | + | let lpTokensToMint = if ((lpTotalSupply == 0)) | |
1297 | + | then (assetTotalSupply - fee) | |
1298 | + | else { | |
1299 | + | let assetDiff = (assetTotalSupply - prevAssetTotalSupply) | |
1300 | + | let feeDiff = (fee - prevFee) | |
1301 | + | let utilityChangeFactor = fraction((assetDiff - feeDiff), RATE_FACTOR, (prevAssetTotalSupply - prevFee)) | |
1302 | + | let lpTokensToMintInner = fraction(lpTotalSupply, utilityChangeFactor, RATE_FACTOR) | |
1303 | + | let err3 = _validateLiquidityInvariant(prevAssetBalances, prevAssetTotalSupply, assetBalances, assetTotalSupply, lpTotalSupply, (lpTotalSupply + lpTokensToMintInner), assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1304 | + | if ((err3 == err3)) | |
1305 | + | then lpTokensToMintInner | |
1306 | + | else throw("Strict value is not equal to itself.") | |
1307 | + | } | |
1308 | + | let err4 = _validateInt(lpTokensToMint, minLpAmount_, MAX_INT, "depositSelective: less than min lp") | |
1309 | + | if ((err4 == err4)) | |
1310 | + | then { | |
1311 | + | let storageUpdated = $Tuple9(storage._1, storage._2, (lpTotalSupply + lpTokensToMint), storage._4, storage._5, storage._6, storage._7, storage._8, storage._9) | |
1312 | + | $Tuple2((([Reissue(lpAssetId, lpTokensToMint, true), ScriptTransfer(i.caller, lpTokensToMint, lpAssetId)] ++ _saveStorage(storageUpdated)) ++ _saveAssetBalances(assetBalances)), unit) | |
1313 | + | } | |
1314 | + | else throw("Strict value is not equal to itself.") | |
1315 | + | } | |
1316 | + | else throw("Strict value is not equal to itself.") | |
1317 | + | } | |
1318 | + | else throw("Strict value is not equal to itself.") | |
1319 | + | } | |
1320 | + | else throw("Strict value is not equal to itself.") | |
1321 | + | } | |
1322 | + | ||
1323 | + | ||
1324 | + | ||
1325 | + | @Callable(i) | |
1326 | + | func withdrawAll () = { | |
1327 | + | let storage = _loadStorage() | |
1328 | + | let lpAssetId = storage._1 | |
1329 | + | let lpDecimals = _getDecimals(toBase58String(lpAssetId)) | |
1330 | + | let lpTotalSupply = storage._3 | |
1331 | + | let lpFeeRate = storage._4 | |
1332 | + | let protocolFeeRate = storage._5 | |
1333 | + | let maxAllocAmplifier = storage._6 | |
1334 | + | let weightAmplifier = storage._7 | |
1335 | + | let slippageRate = storage._8 | |
1336 | + | let feeMaxRate = storage._9 | |
1337 | + | let lpAssetIdStr = toBase58String(lpAssetId) | |
1338 | + | let assets = _loadAssets() | |
1339 | + | let $t03732037388 = _loadAssetBalances() | |
1340 | + | let prevAssetBalances = $t03732037388._1 | |
1341 | + | let prevAssetTotalSupply = $t03732037388._2 | |
1342 | + | let $t03739337446 = _loadAssetWeights() | |
1343 | + | let assetWeights = $t03739337446._1 | |
1344 | + | let sigmaWeight = $t03739337446._2 | |
1345 | + | let err = if (if (_validateIntEquals(size(i.payments), 1, "withdrawAll: invalid payments size")) | |
1346 | + | then _validateStringEqual(lpAssetIdStr, _assetToStr(i.payments[0].assetId), "withdrawAll: invalid payment asset") | |
1347 | + | else false) | |
1348 | + | then _validateInt(i.payments[0].amount, 0, MAX_INT, "withdrawAll: invalid payment amount") | |
1349 | + | else false | |
1350 | + | if ((err == err)) | |
1351 | + | then { | |
1352 | + | let lpFee = fraction(i.payments[0].amount, lpFeeRate, MAX_FEE) | |
1353 | + | let protocolFee = fraction(i.payments[0].amount, protocolFeeRate, MAX_FEE) | |
1354 | + | let amount = ((i.payments[0].amount - lpFee) - protocolFee) | |
1355 | + | let err1 = _validateInt(amount, 0, MAX_INT, "withdrawAll: insufficient amount") | |
1356 | + | if ((err1 == err1)) | |
1357 | + | then { | |
1358 | + | let $t03807038200 = _decrementBalancesByLpAmount(prevAssetBalances, amount, lpTotalSupply) | |
1359 | + | let assetBalances = $t03807038200._1 | |
1360 | + | let assetTotalSupply = $t03807038200._2 | |
1361 | + | let deltaAssetBalances = $t03807038200._3 | |
1362 | + | let lpTotalSupplyUpdated = (lpTotalSupply - amount) | |
1363 | + | let paymentActions = _getPaymentsFromBalances(assets, deltaAssetBalances, i.caller, lpDecimals) | |
1364 | + | let err2 = _validateLiquidityInvariant(prevAssetBalances, prevAssetTotalSupply, assetBalances, assetTotalSupply, lpTotalSupply, lpTotalSupplyUpdated, assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1365 | + | if ((err2 == err2)) | |
1366 | + | then { | |
1367 | + | let storageUpdated = $Tuple9(storage._1, storage._2, lpTotalSupplyUpdated, storage._4, storage._5, storage._6, storage._7, storage._8, storage._9) | |
1368 | + | $Tuple2(((((([Burn(lpAssetId, amount)] ++ paymentActions) ++ _saveStorage(storageUpdated)) ++ _saveAssetBalances(assetBalances)) ++ _saveLpFee(lpAssetIdStr, (lpFee + _loadLpFee(lpAssetIdStr)))) ++ _saveProtocolFee(lpAssetIdStr, (protocolFee + _loadProtocolFee(lpAssetIdStr)))), unit) | |
1369 | + | } | |
1370 | + | else throw("Strict value is not equal to itself.") | |
1371 | + | } | |
1372 | + | else throw("Strict value is not equal to itself.") | |
1373 | + | } | |
1374 | + | else throw("Strict value is not equal to itself.") | |
1375 | + | } | |
1376 | + | ||
1377 | + | ||
1378 | + | ||
1379 | + | @Callable(i) | |
1380 | + | func withdraw (assetId_,amount_) = { | |
1381 | + | let storage = _loadStorage() | |
1382 | + | let lpAssetId = storage._1 | |
1383 | + | let lpDecimals = _getDecimals(toBase58String(lpAssetId)) | |
1384 | + | let lpTotalSupply = storage._3 | |
1385 | + | let lpFeeRate = storage._4 | |
1386 | + | let protocolFeeRate = storage._5 | |
1387 | + | let maxAllocAmplifier = storage._6 | |
1388 | + | let weightAmplifier = storage._7 | |
1389 | + | let slippageRate = storage._8 | |
1390 | + | let feeMaxRate = storage._9 | |
1391 | + | let lpAssetIdStr = toBase58String(lpAssetId) | |
1392 | + | let assets = _loadAssets() | |
1393 | + | let $t03975539823 = _loadAssetBalances() | |
1394 | + | let prevAssetBalances = $t03975539823._1 | |
1395 | + | let prevAssetTotalSupply = $t03975539823._2 | |
1396 | + | let $t03982839881 = _loadAssetWeights() | |
1397 | + | let assetWeights = $t03982839881._1 | |
1398 | + | let sigmaWeight = $t03982839881._2 | |
1399 | + | let err = if (if (if (if (_validateIntEquals(size(i.payments), 1, "withdraw: invalid payments size")) | |
1400 | + | then _validateStringEqual(lpAssetIdStr, _assetToStr(i.payments[0].assetId), "withdraw: invalid payment asset") | |
1401 | + | else false) | |
1402 | + | then _validateInt(i.payments[0].amount, 0, MAX_INT, "withdraw: invalid payment amount") | |
1403 | + | else false) | |
1404 | + | then _validateListContains(assets, assetId_, "withdraw: invalid assetId") | |
1405 | + | else false) | |
1406 | + | then _validateInt(amount_, 0, MAX_INT, "withdraw: invalid amount") | |
1407 | + | else false | |
1408 | + | if ((err == err)) | |
1409 | + | then { | |
1410 | + | let assetDecimals = _getDecimals(assetId_) | |
1411 | + | let amountNormalized = _normalizeDecimals(amount_, assetDecimals, lpDecimals, DOWN) | |
1412 | + | let assetIndex = value(indexOf(assets, assetId_)) | |
1413 | + | let assetBalances = _decrementBalanceByIndex(prevAssetBalances, assetIndex, amountNormalized) | |
1414 | + | let assetTotalSupply = (prevAssetTotalSupply - amountNormalized) | |
1415 | + | let err1 = _validateAllocation(assetBalances, assetTotalSupply, prevAssetBalances, prevAssetTotalSupply, assetWeights, sigmaWeight, maxAllocAmplifier) | |
1416 | + | if ((err1 == err1)) | |
1417 | + | then { | |
1418 | + | let prevFee = _calculateFee(prevAssetBalances, prevAssetTotalSupply, assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1419 | + | let fee = _calculateFee(assetBalances, assetTotalSupply, assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1420 | + | let lpTokensToBurn = if ((lpTotalSupply == 0)) | |
1421 | + | then (assetTotalSupply - fee) | |
1422 | + | else { | |
1423 | + | let assetDiff = (assetTotalSupply - prevAssetTotalSupply) | |
1424 | + | let feeDiff = (fee - prevFee) | |
1425 | + | let utilityChangeFactor = fraction((assetDiff - feeDiff), RATE_FACTOR, (prevAssetTotalSupply - prevFee)) | |
1426 | + | let lpTokensToBurnInner = (-1 * fraction(lpTotalSupply, utilityChangeFactor, RATE_FACTOR)) | |
1427 | + | let err2 = _validateLiquidityInvariant(prevAssetBalances, prevAssetTotalSupply, assetBalances, assetTotalSupply, lpTotalSupply, (lpTotalSupply - lpTokensToBurnInner), assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1428 | + | if ((err2 == err2)) | |
1429 | + | then lpTokensToBurnInner | |
1430 | + | else throw("Strict value is not equal to itself.") | |
1431 | + | } | |
1432 | + | let lpFee = fraction(lpTokensToBurn, lpFeeRate, ((MAX_FEE - lpFeeRate) - protocolFeeRate)) | |
1433 | + | let protocolFee = fraction(lpTokensToBurn, protocolFeeRate, ((MAX_FEE - lpFeeRate) - protocolFeeRate)) | |
1434 | + | let requiredLpTokens = ((lpTokensToBurn + lpFee) + protocolFee) | |
1435 | + | let changeAction = if ((requiredLpTokens > i.payments[0].amount)) | |
1436 | + | then throw("withdraw: insufficient amount") | |
1437 | + | else if ((i.payments[0].amount > requiredLpTokens)) | |
1438 | + | then [ScriptTransfer(i.caller, (i.payments[0].amount - requiredLpTokens), i.payments[0].assetId)] | |
1439 | + | else nil | |
1440 | + | let storageUpdated = $Tuple9(storage._1, storage._2, (lpTotalSupply - lpTokensToBurn), storage._4, storage._5, storage._6, storage._7, storage._8, storage._9) | |
1441 | + | $Tuple2(((((([Burn(lpAssetId, lpTokensToBurn), ScriptTransfer(i.caller, amount_, _strToAsset(assetId_))] ++ changeAction) ++ _saveStorage(storageUpdated)) ++ _saveAssetBalances(assetBalances)) ++ _saveLpFee(lpAssetIdStr, (lpFee + _loadLpFee(lpAssetIdStr)))) ++ _saveProtocolFee(lpAssetIdStr, (protocolFee + _loadProtocolFee(lpAssetIdStr)))), unit) | |
1442 | + | } | |
1443 | + | else throw("Strict value is not equal to itself.") | |
1444 | + | } | |
1445 | + | else throw("Strict value is not equal to itself.") | |
1446 | + | } | |
1447 | + | ||
1448 | + | ||
1449 | + | ||
1450 | + | @Callable(i) | |
1451 | + | func swap (targetAssetId_,minAmount_) = { | |
1452 | + | let storage = _loadStorage() | |
1453 | + | let lpAssetId = storage._1 | |
1454 | + | let lpDecimals = _getDecimals(toBase58String(lpAssetId)) | |
1455 | + | let lpTotalSupply = storage._3 | |
1456 | + | let lpFeeRate = storage._4 | |
1457 | + | let protocolFeeRate = storage._5 | |
1458 | + | let maxAllocAmplifier = storage._6 | |
1459 | + | let weightAmplifier = storage._7 | |
1460 | + | let slippageRate = storage._8 | |
1461 | + | let feeMaxRate = storage._9 | |
1462 | + | let assets = _loadAssets() | |
1463 | + | let $t04398044048 = _loadAssetBalances() | |
1464 | + | let prevAssetBalances = $t04398044048._1 | |
1465 | + | let prevAssetTotalSupply = $t04398044048._2 | |
1466 | + | let $t04405344106 = _loadAssetWeights() | |
1467 | + | let assetWeights = $t04405344106._1 | |
1468 | + | let sigmaWeight = $t04405344106._2 | |
1469 | + | let sourceAssetStr = _assetToStr(i.payments[0].assetId) | |
1470 | + | let sourceAssetIndex = valueOrErrorMessage(indexOf(assets, sourceAssetStr), "swap: invalid source asset") | |
1471 | + | if ((sourceAssetIndex == sourceAssetIndex)) | |
1472 | + | then { | |
1473 | + | let targetAssetIndex = valueOrErrorMessage(indexOf(assets, targetAssetId_), "swap: invalid target asset") | |
1474 | + | if ((targetAssetIndex == targetAssetIndex)) | |
1475 | + | then { | |
1476 | + | let err = if (if (_validateInt(minAmount_, 0, MAX_INT, "swap: invalid min target amount")) | |
1477 | + | then _validateStringNotEq(sourceAssetStr, targetAssetId_, "swap: same assets") | |
1478 | + | else false) | |
1479 | + | then _validateIntEquals(size(i.payments), 1, "swap: invalid payments size") | |
1480 | + | else false | |
1481 | + | if ((err == err)) | |
1482 | + | then { | |
1483 | + | let sourceDecimals = _getDecimals(sourceAssetStr) | |
1484 | + | let amountNormalized = _normalizeDecimals(i.payments[0].amount, sourceDecimals, lpDecimals, DOWN) | |
1485 | + | let assetBalances = _incrementBalanceByIndex(prevAssetBalances, sourceAssetIndex, amountNormalized) | |
1486 | + | let assetTotalSupply = (prevAssetTotalSupply + amountNormalized) | |
1487 | + | let prevFee = _calculateFee(prevAssetBalances, prevAssetTotalSupply, assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1488 | + | func foldFunc (acc,elem) = if (acc._1) | |
1489 | + | then acc | |
1490 | + | else { | |
1491 | + | let targetAmount = acc._2 | |
1492 | + | let tempAssetBalances = _decrementBalanceByIndex(assetBalances, targetAssetIndex, targetAmount) | |
1493 | + | let tempAssetTotalSupply = (assetTotalSupply - targetAmount) | |
1494 | + | let fee = _calculateFee(tempAssetBalances, tempAssetTotalSupply, assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1495 | + | let feeDiff = (fee - prevFee) | |
1496 | + | let tempAmount = (amountNormalized - feeDiff) | |
1497 | + | let check = if ((0 >= tempAmount)) | |
1498 | + | then throw("swap: less than 0") | |
1499 | + | else unit | |
1500 | + | if ((check == check)) | |
1501 | + | then if (if (((targetAmount - tempAmount) > (-1 * PRECISION))) | |
1502 | + | then (PRECISION > (targetAmount - tempAmount)) | |
1503 | + | else false) | |
1504 | + | then { | |
1505 | + | let finalAssetBalances = _decrementBalanceByIndex(assetBalances, targetAssetIndex, tempAmount) | |
1506 | + | let finalAssetTotalSupply = (assetTotalSupply - tempAmount) | |
1507 | + | let err1 = if (_validateAllocation(finalAssetBalances, finalAssetTotalSupply, prevAssetBalances, prevAssetTotalSupply, assetWeights, sigmaWeight, maxAllocAmplifier)) | |
1508 | + | then _validateSwapInvariant(prevAssetBalances, prevAssetTotalSupply, finalAssetBalances, finalAssetTotalSupply, assetWeights, sigmaWeight, weightAmplifier, slippageRate, feeMaxRate) | |
1509 | + | else false | |
1510 | + | if ((err1 == err1)) | |
1511 | + | then $Tuple3(true, tempAmount, finalAssetBalances) | |
1512 | + | else throw("Strict value is not equal to itself.") | |
1513 | + | } | |
1514 | + | else $Tuple3(false, tempAmount, tempAssetBalances) | |
1515 | + | else throw("Strict value is not equal to itself.") | |
1516 | + | } | |
1517 | + | ||
1518 | + | let $t04694447062 = { | |
1519 | + | let $l = LIST_25 | |
1520 | + | let $s = size($l) | |
1521 | + | let $acc0 = $Tuple3(false, amountNormalized, nil) | |
1522 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
1523 | + | then $a | |
1524 | + | else foldFunc($a, $l[$i]) | |
1525 | + | ||
1526 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
1527 | + | then $a | |
1528 | + | else throw("List size exceeds 25") | |
1529 | + | ||
1530 | + | $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($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), 21), 22), 23), 24), 25) | |
1531 | + | } | |
1532 | + | let success = $t04694447062._1 | |
1533 | + | let targetAmountNormalized = $t04694447062._2 | |
1534 | + | let finalAssetBalances = $t04694447062._3 | |
1535 | + | if (!(success)) | |
1536 | + | then throw(("swap: can't calculate targetAmount=" + toString(targetAmountNormalized))) | |
1537 | + | else { | |
1538 | + | let lpFee = fraction(targetAmountNormalized, lpFeeRate, MAX_FEE) | |
1539 | + | let protocolFee = fraction(targetAmountNormalized, protocolFeeRate, MAX_FEE) | |
1540 | + | let finalAmountNormalized = ((targetAmountNormalized - lpFee) - protocolFee) | |
1541 | + | let targetDecimals = _getDecimals(targetAssetId_) | |
1542 | + | let finalAmount = _normalizeDecimals(finalAmountNormalized, lpDecimals, targetDecimals, DOWN) | |
1543 | + | let err2 = _validateInt(finalAmount, minAmount_, MAX_INT, "swap: insufficient final amount") | |
1544 | + | if ((err2 == err2)) | |
1545 | + | then $Tuple2(((([ScriptTransfer(i.caller, finalAmount, _strToAsset(targetAssetId_))] ++ _saveAssetBalances(finalAssetBalances)) ++ _saveLpFee(targetAssetId_, (lpFee + _loadLpFee(targetAssetId_)))) ++ _saveProtocolFee(targetAssetId_, (protocolFee + _loadProtocolFee(targetAssetId_)))), unit) | |
1546 | + | else throw("Strict value is not equal to itself.") | |
1547 | + | } | |
1548 | + | } | |
1549 | + | else throw("Strict value is not equal to itself.") | |
1550 | + | } | |
1551 | + | else throw("Strict value is not equal to itself.") | |
1552 | + | } | |
1553 | + | else throw("Strict value is not equal to itself.") | |
1554 | + | } | |
1555 | + | ||
1556 | + | ||
1557 | + | ||
1558 | + | @Callable(i) | |
1559 | + | func stake () = { | |
1560 | + | let storage = _loadStorage() | |
1561 | + | let lpAssetIdStr = _assetToStr(storage._1) | |
1562 | + | let assets = [lpAssetIdStr, _loadAssets()] | |
1563 | + | let err = if (if (_validateIntEquals(size(i.payments), 1, "stake: invalid payments size")) | |
1564 | + | then _validateStringEqual(lpAssetIdStr, _assetToStr(i.payments[0].assetId), "stake: invalid payment asset") | |
1565 | + | else false) | |
1566 | + | then _validateInt(i.payments[0].amount, 0, MAX_INT, "stake: invalid payment amount") | |
1567 | + | else false | |
1568 | + | if ((err == err)) | |
1569 | + | then { | |
1570 | + | let stakedBalance = _loadUserLp(i.caller) | |
1571 | + | let $t04855448633 = _checkpoint(assets) | |
1572 | + | let incomeIntegrals = $t04855448633._1 | |
1573 | + | let totalLpIntegral = $t04855448633._2 | |
1574 | + | let checkpointActions = $t04855448633._3 | |
1575 | + | let $t04863848755 = _userCheckpoint(i.caller, stakedBalance, incomeIntegrals, totalLpIntegral) | |
1576 | + | let userProfits = $t04863848755._1 | |
1577 | + | let userCheckpointActions = $t04863848755._2 | |
1578 | + | $Tuple2((((checkpointActions ++ userCheckpointActions) ++ _saveUserLp(i.caller, (stakedBalance + i.payments[0].amount))) ++ _saveTotalLp((_loadTotalLp() + i.payments[0].amount))), unit) | |
1579 | + | } | |
1580 | + | else throw("Strict value is not equal to itself.") | |
1581 | + | } | |
1582 | + | ||
1583 | + | ||
1584 | + | ||
1585 | + | @Callable(i) | |
1586 | + | func unstake (amount_) = { | |
1587 | + | let storage = _loadStorage() | |
1588 | + | let lpAssetId = storage._1 | |
1589 | + | let assets = [_assetToStr(lpAssetId), _loadAssets()] | |
1590 | + | let stakedBalance = _loadUserLp(i.caller) | |
1591 | + | let err = _validateInt(amount_, 0, stakedBalance, "unstake: invalid amount") | |
1592 | + | if ((err == err)) | |
1593 | + | then { | |
1594 | + | let $t04929349372 = _checkpoint(assets) | |
1595 | + | let incomeIntegrals = $t04929349372._1 | |
1596 | + | let totalLpIntegral = $t04929349372._2 | |
1597 | + | let checkpointActions = $t04929349372._3 | |
1598 | + | let $t04937749494 = _userCheckpoint(i.caller, stakedBalance, incomeIntegrals, totalLpIntegral) | |
1599 | + | let userProfits = $t04937749494._1 | |
1600 | + | let userCheckpointActions = $t04937749494._2 | |
1601 | + | $Tuple2((((([ScriptTransfer(i.caller, amount_, lpAssetId)] ++ checkpointActions) ++ userCheckpointActions) ++ _saveUserLp(i.caller, (stakedBalance - amount_))) ++ _saveTotalLp((_loadTotalLp() - amount_))), unit) | |
1602 | + | } | |
1603 | + | else throw("Strict value is not equal to itself.") | |
1604 | + | } | |
1605 | + | ||
1606 | + | ||
1607 | + | ||
1608 | + | @Callable(i) | |
1609 | + | func claim (assetId_,amount_) = { | |
1610 | + | let storage = _loadStorage() | |
1611 | + | let lpAssetId = storage._1 | |
1612 | + | let lpAssetIdStr = _assetToStr(lpAssetId) | |
1613 | + | let assets = [lpAssetIdStr, _loadAssets()] | |
1614 | + | let stakedBalance = _loadUserLp(i.caller) | |
1615 | + | let err = if (_validateListContains(assets, assetId_, "claim: invalid assetId")) | |
1616 | + | then _validateInt(amount_, 0, MAX_INT, "claim: invalid amount") | |
1617 | + | else false | |
1618 | + | if ((err == err)) | |
1619 | + | then { | |
1620 | + | let $t05018550264 = _checkpoint(assets) | |
1621 | + | let incomeIntegrals = $t05018550264._1 | |
1622 | + | let totalLpIntegral = $t05018550264._2 | |
1623 | + | let checkpointActions = $t05018550264._3 | |
1624 | + | let $t05026950386 = _userCheckpoint(i.caller, stakedBalance, incomeIntegrals, totalLpIntegral) | |
1625 | + | let userProfits = $t05026950386._1 | |
1626 | + | let userCheckpointActions = $t05026950386._2 | |
1627 | + | let assetIndex = value(indexOf(assets, assetId_)) | |
1628 | + | func foldFunc (acc,elem) = { | |
1629 | + | let index = acc._1 | |
1630 | + | if ((index == assetIndex)) | |
1631 | + | then if ((amount_ > elem)) | |
1632 | + | then throw("claim: insufficient amount") | |
1633 | + | else $Tuple2((index + 1), (acc._2 :+ (elem - amount_))) | |
1634 | + | else $Tuple2((index + 1), (acc._2 :+ elem)) | |
1635 | + | } | |
1636 | + | ||
1637 | + | let $t05083450906 = { | |
1638 | + | let $l = userProfits | |
1639 | + | let $s = size($l) | |
1640 | + | let $acc0 = $Tuple2(0, nil) | |
1641 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
1642 | + | then $a | |
1643 | + | else foldFunc($a, $l[$i]) | |
1644 | + | ||
1645 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
1646 | + | then $a | |
1647 | + | else throw("List size exceeds 11") | |
1648 | + | ||
1649 | + | $f0_2($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) | |
1650 | + | } | |
1651 | + | let idx = $t05083450906._1 | |
1652 | + | let userProfitsUpdated = $t05083450906._2 | |
1653 | + | $Tuple2(((([ScriptTransfer(i.caller, amount_, lpAssetId)] ++ checkpointActions) ++ userCheckpointActions) ++ _saveUserProfits(i.caller, userProfitsUpdated)), unit) | |
1654 | + | } | |
1655 | + | else throw("Strict value is not equal to itself.") | |
1656 | + | } | |
1657 | + | ||
1658 | + |
github/deemru/w8io/fabc49c 113.58 ms ◑