tx · 3vsNtcwzDpvLCegjr6j1nCENnHCgu7w7yNR3HieadK4i

3MDfQJCHVvSCKHed1PhC4DxeVgMFdBu1RSw:  -0.05500000 Waves

2025.09.25 19:21 [335361] smart account 3MDfQJCHVvSCKHed1PhC4DxeVgMFdBu1RSw > SELF 0.00000000 Waves

{ "type": 13, "id": "3vsNtcwzDpvLCegjr6j1nCENnHCgu7w7yNR3HieadK4i", "fee": 5500000, "feeAssetId": null, "timestamp": 1758817316754, "version": 2, "chainId": 82, "sender": "3MDfQJCHVvSCKHed1PhC4DxeVgMFdBu1RSw", "senderPublicKey": "6JV4YB1Kqavf8XtLMi9AJ91QnuA3bacpghgZ5NsUqA6b", "proofs": [ "2N7L9ndZmoFZF1xTR4oonqbBXYpbCRqPBoDuTRrRMCqJTrKzb2QzoaHJzRqhuLBRvSaeWt89VtbCWv7oBJHDD9A5" ], "script": "base64:BgJcCAISBAoCCAgSCQoHCAgICAgIARIAEgkKBwgICAgIAQgSAwoBBBIDCgEBEgASAwoBCBIDCgEBEgASAwoBCBIAEgQKAggBEgQKAggBEgUKAwgIARIDCgEIEgMKAQFmAAdWRVJTSU9OAhZQWi0zLjYuMSBQUk9ELXJlZmFjdG9yAAljb25maWdTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwINY29uZmlnQWRkcmVzcwIjM1BNb0VpYmRMZVdxY1VSUTgzNTFYaGFXd3lhY0RjN0c0ZTUADkNPTkZJR19BRERSRVNTAwkAAAIFCWNvbmZpZ1N0cgIABQR0aGlzCQEHQWRkcmVzcwEJANkEAQUJY29uZmlnU3RyABVBc3NldHNXZWlnaHRzRGVjaW1hbHMABAAFU2NhbGUAkE4ABlNjYWxlOACAwtcvAAlTY2FsZThfQkkJALYCAQUGU2NhbGU4AAdTY2FsZTEyAICglKWNHQAHU2NhbGUxNgCAgIT+pt7hEQAKU2NhbGUxNl9CSQkAtgIBBQdTY2FsZTE2AAhGZWVTY2FsZQCQTgARUG9vbFRva2VuRGVjaW1hbHMACAAOUG9vbFRva2VuU2NhbGUJAGwGAAoAAAURUG9vbFRva2VuRGVjaW1hbHMAAAAABQZIQUxGVVAAEE1JTl9TVEVQU19BTU9VTlQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOQ09ORklHX0FERFJFU1MCEG1pbl9zdGVwc19hbW91bnQAAQAQTUFYX1NURVBTX0FNT1VOVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5DT05GSUdfQUREUkVTUwIQbWF4X3N0ZXBzX2Ftb3VudAD0AwASTUlOX1NURVBTX0lOVEVSVkFMCQELdmFsdWVPckVsc2UCCQCaCAIFDkNPTkZJR19BRERSRVNTAhJtaW5fc3RlcHNfaW50ZXJ2YWwAAQASTUFYX1NURVBTX0lOVEVSVkFMCQELdmFsdWVPckVsc2UCCQCaCAIFDkNPTkZJR19BRERSRVNTAhJtYXhfc3RlcHNfaW50ZXJ2YWwAkE4ACk1JTl9XRUlHSFQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUOQ09ORklHX0FERFJFU1MCCm1pbl93ZWlnaHQAZAAKTUFYX1dFSUdIVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQ5DT05GSUdfQUREUkVTUwIKbWF4X3dlaWdodACsTQENdHJ5R2V0SW50ZWdlcgEDa2V5BAckbWF0Y2gwCQCaCAIFBHRoaXMFA2tleQMJAAECBQckbWF0Y2gwAgNJbnQEAWIFByRtYXRjaDAFAWIAAAEMdHJ5R2V0QmluYXJ5AQNrZXkEByRtYXRjaDAJAJwIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWIFByRtYXRjaDAFAWIBAAEMdHJ5R2V0U3RyaW5nAQNrZXkEByRtYXRjaDAJAJ0IAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQBYgUHJG1hdGNoMAUBYgIAARN0cnlHZXRTdHJpbmdPclRocm93AQNrZXkEByRtYXRjaDAJAJ0IAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQBYgUHJG1hdGNoMAUBYgkAAgEJAKwCAgIdbm8gc3VjaCBrZXkgaW4gZGF0YSBzdG9yYWdlOiAFA2tleQEOZ2V0QXNzZXRTdHJpbmcBB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAkA2AQBBQFiAgVXQVZFUwENZ2V0QXNzZXRCeXRlcwEKYXNzZXRJZFN0cgMJAAACBQphc3NldElkU3RyAgVXQVZFUwUEdW5pdAkA2QQBBQphc3NldElkU3RyAQ9nZXRUb2tlbkJhbGFuY2UBB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBdAUHJG1hdGNoMAkA8AcCBQR0aGlzBQF0CAkA7wcBBQR0aGlzCWF2YWlsYWJsZQETYWRkQXNzZXRCeXRlc1RvTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQENZ2V0QXNzZXRCeXRlcwEFBGl0ZW0FA25pbAEUYWRkQXNzZXRXZWlnaHRUb0xpc3QCBWFjY3VtBGl0ZW0JAM4IAgUFYWNjdW0JAMwIAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwkBDmdldEFzc2V0U3RyaW5nAQUEaXRlbQIHX3dlaWdodAUDbmlsARdhZGRBc3NldFdlaWdodFRvU3RyTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQCkAwEJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FBGl0ZW0CB193ZWlnaHQFA25pbAEWYWRkQXNzZXREZWNpbWFsc1RvTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQRpdGVtAglfZGVjaW1hbHMFA25pbAETYWRkQXNzZXRTY2FsZVRvTGlzdAIFYWNjdW0EaXRlbQkAzggCBQVhY2N1bQkAzAgCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfCQEOZ2V0QXNzZXRTdHJpbmcBBQRpdGVtAgZfc2NhbGUFA25pbAEMYWRkSW50VG9MaXN0AgVhY2N1bQRpdGVtCQDOCAIFBWFjY3VtCQDMCAIJAQ1wYXJzZUludFZhbHVlAQUEaXRlbQUDbmlsARFwYXJzdFN0clRvSW50TGlzdAEBcwoBAWYCBWFjY3VtBG5leHQJAM4IAgUFYWNjdW0JAMwIAgkBDXBhcnNlSW50VmFsdWUBBQRuZXh0BQNuaWwKAAIkbAkAtQkCBQFzAgEsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAA51c2RuQXNzZXRJZFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIOdXNkbkFzc2V0SWRTdHICLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwABBwdXp6bGVBc3NldElkU3RyCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAhBwdXp6bGVBc3NldElkU3RyAixIRUI4UWF3OXhyV3BXczh0SHNpQVRZR0JXREJ0UDJTN2tjUEFMck11NDNBUwAOdXNkdEFzc2V0SWRTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDnVzZHRBc3NldElkU3RyAiwzNE45WWNFRVRMV245M3FZUTY0RXNQMXg4OXRTcnVKVTQ0UnJFTVNYWEVQSgARdXNkdFBwdEFzc2V0SWRTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCEXVzZHRQcHRBc3NldElkU3RyAiw5d2MzTFhOQTRURUJzWHlLdG9MRTltcmJERDdXTUhYdlhyQ2padmFiTEFzaQAOcm9tZUFzc2V0SWRTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDnJvbWVBc3NldElkU3RyAixBUDRDYjV4TFlHSDZaaWdIcmVDWkhvWHBRVFdEa1BzRzJCSHFmRFV4NnRhSgAPd2F2ZXNBc3NldElkU3RyAgVXQVZFUwALdXNkbkFzc2V0SWQJANkEAQUOdXNkbkFzc2V0SWRTdHIADXB1enpsZUFzc2V0SWQJANkEAQUQcHV6emxlQXNzZXRJZFN0cgALdXNkdEFzc2V0SWQJANkEAQUOdXNkdEFzc2V0SWRTdHIADnVzZHRQcHRBc3NldElkCQDZBAEFEXVzZHRQcHRBc3NldElkU3RyAAtyb21lQXNzZXRJZAkA2QQBBQ5yb21lQXNzZXRJZFN0cgAMd2F2ZXNBc3NldElkBQR1bml0ABVzdXBwb3J0ZWRGZWVBc3NldHNTdHIJAMwIAgUOdXNkbkFzc2V0SWRTdHIJAMwIAgUQcHV6emxlQXNzZXRJZFN0cgkAzAgCBQ51c2R0QXNzZXRJZFN0cgkAzAgCBRF1c2R0UHB0QXNzZXRJZFN0cgkAzAgCBQ93YXZlc0Fzc2V0SWRTdHIJAMwIAgUOcm9tZUFzc2V0SWRTdHIFA25pbAARcGFyZW50UG9vbEFkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAhFwYXJlbnRQb29sQWRkcmVzcwIjM1BGRGd6dTFVdHN3QWtDTXhxcVFqYlRlSGFYNGNNYWI4S2gADW1hc3RlckFkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg1tYXN0ZXJBZGRyZXNzAiMzUExqd0hjejlORXVhVG82M05aUjlCOW9rUWlLUXhaU2JtZgAMbWFzdGVyUHViS2V5CQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDG1hc3RlclB1YktleQIsMmpUSkdxSFNvcHlqNWQxY2piVWU2ZjJqWHFHTUhFNDEyY3kzdkd3WW9SYlAADW9yYWNsZUFkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg1vcmFjbGVBZGRyZXNzAiMzUDhkMUUxQkxLb0Q1MnkzYlFKMWJEVGQyVEQxZ3BhTG45dAAOc3Rha2luZ0FkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg5zdGFraW5nQWRkcmVzcwIjM1BGVGJ5d3F4dEZmdWtYM0h5VDg4MWc0aVc1SzRRTDNGQVMAC2ZlZXNBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwILZmVlc0FkZHJlc3MCIzNQRldBVkttWGpmSFh5ekpiMTJqQ2JoUDRVaGk5dDR1V2lEAA9wb29sc0h1YkFkZHJlc3MJAQdBZGRyZXNzAQkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg9wb29sc0h1YkFkZHJlc3MCIzNQNVJHWXlDbkVMRjhKVFB4Z1g1NGRCR3p3a1FNS1VKNUg3ABJzaHV0ZG93bkFkZHJlc3NTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCD3NodXRkb3duQWRkcmVzcwIjM1BFcHY5aFJGV0VFQlUyMldSbkxzdzFiSDRZR3RjVTcyOG8AD2xheWVyMkFkZHJlc3NlcwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIPbGF5ZXIyQWRkcmVzc2VzAkczUFIxUXZpOW1IVDM1U3dXRWtMU3FxRTJMOHRoaVBMZFZXVSwzUFFvQmZVS0hrSkFlR1dob29MUDdXUzhvdmI1NGF2OUpwMgAKZ292QWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCCmdvdkFkZHJlc3MCIzNQNnVybzl4Q3NFOHRlNzhRWmp6cXk3YXE4bmF0U3pkY2VDABFjb2xkTWFzdGVyQWRkcmVzcwkBB0FkZHJlc3MBCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCEWNvbGRNYXN0ZXJBZGRyZXNzAiMzUEs5bmhQZlBiTUJ5Z0I5WmdIVk1IYVFiU29vandyQmZ4agABVAkBDXRyeUdldEludGVnZXIBAhNzdGF0aWNfdG9rZW5zQW1vdW50AAhhc3NldElkcwoAAiRsCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBE2FkZEFzc2V0Qnl0ZXNUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoADUFzc2V0c1dlaWdodHMKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjFfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBFGFkZEFzc2V0V2VpZ2h0VG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAhEZWNpbWFscwoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMl8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEWYWRkQXNzZXREZWNpbWFsc1RvTGlzdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMl8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjJfMgIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIJAQUkZjJfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgAGU2NhbGVzCgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYzXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARNhZGRBc3NldFNjYWxlVG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYzXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmM18yAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgkBBSRmM18xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAANGZWUJAQ10cnlHZXRJbnRlZ2VyAQIKc3RhdGljX2ZlZQAMZWFybmVkQXNzZXRzBQhhc3NldElkcwEEX2dldAIHYXNzZXRJZAVwYXJhbQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgkArAICAgdnbG9iYWxfBQdhc3NldElkAgFfBQVwYXJhbQEPX2dldF9mZWVzRWFybmVkAQdhc3NldElkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgISZ2xvYmFsX2ZlZXNFYXJuZWRfBQdhc3NldElkARdfZ2V0X2xhc3RDaGVja19pbnRlcmVzdAEHYXNzZXRJZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIRZ2xvYmFsX2xhc3RDaGVja18FB2Fzc2V0SWQCCV9pbnRlcmVzdAEQX2dldF9leHRyYUVhcm5lZAEHYXNzZXRJZAkBDXRyeUdldEludGVnZXIBCQCsAgICE2dsb2JhbF9leHRyYUVhcm5lZF8FB2Fzc2V0SWQBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEHYXNzZXRJZAQHJG1hdGNoMAkAoggBCQCsAgICDWdsb2JhbFBhcmFtc18FB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFwBQckbWF0Y2gwBAZwYXJhbXMJALUJAgUBcAICX18JAJoKCAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwAACQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcGFyYW1zAAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZwYXJhbXMAAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwADCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcGFyYW1zAAQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZwYXJhbXMABQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBnBhcmFtcwAGCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGcGFyYW1zAAcJAJoKCAkBBF9nZXQCBQdhc3NldElkAgdiYWxhbmNlCQEEX2dldAIFB2Fzc2V0SWQCC2ZhY3RCYWxhbmNlCQEPX2dldF9mZWVzRWFybmVkAQUHYXNzZXRJZAkBF19nZXRfbGFzdENoZWNrX2ludGVyZXN0AQUHYXNzZXRJZAkBEF9nZXRfZXh0cmFFYXJuZWQBBQdhc3NldElkCQEEX2dldAIFB2Fzc2V0SWQCB3NlbGxvZmYJAQRfZ2V0AgUHYXNzZXRJZAITc2VsbG9mZlN0YXJ0QmFsYW5jZQkBBF9nZXQCBQdhc3NldElkAhJzZWxsb2ZmU3RhcnRIZWlnaHQBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIHYXNzZXRJZAZwYXJhbXMJAQtTdHJpbmdFbnRyeQIJAKwCAgINZ2xvYmFsUGFyYW1zXwUHYXNzZXRJZAkAuQkCCQDMCAIJAKQDAQgFBnBhcmFtcwJfMQkAzAgCCQCkAwEIBQZwYXJhbXMCXzIJAMwIAgkApAMBCAUGcGFyYW1zAl8zCQDMCAIJAKQDAQgFBnBhcmFtcwJfNAkAzAgCCQCkAwEIBQZwYXJhbXMCXzUJAMwIAgkApAMBCAUGcGFyYW1zAl82CQDMCAIJAKQDAQgFBnBhcmFtcwJfNwkAzAgCCQCkAwEIBQZwYXJhbXMCXzgFA25pbAICX18BCmlzU2h1dGRvd24ABA9zaHV0ZG93bkFkZHJlc3MJAKYIAQUSc2h1dGRvd25BZGRyZXNzU3RyAwkAAAIFD3NodXRkb3duQWRkcmVzcwUEdW5pdAcEByRtYXRjaDAJAJsIAgkBBXZhbHVlAQUPc2h1dGRvd25BZGRyZXNzAgtpc19zaHV0ZG93bgMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAF4BQckbWF0Y2gwBQF4BwEOZ2V0RmFjdEJhbGFuY2UBCmFzc2V0SWRTdHIEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cggFC2Fzc2V0UGFyYW1zAl8yARZnZXRDdXJyZW50VG9rZW5CYWxhbmNlAQh0b2tlbk51bQQKdG9rZW5JZFN0cgkBDmdldEFzc2V0U3RyaW5nAQkAkQMCBQhhc3NldElkcwUIdG9rZW5OdW0EC3Rva2VuUGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKdG9rZW5JZFN0cggFC3Rva2VuUGFyYW1zAl8xAQ1zdGFrZUlmTmVlZGVkAgphc3NldElkU3RyBmFtb3VudAQHc3Rha2VUeAMJAQIhPQIJAQx0cnlHZXRTdHJpbmcBCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfBQphc3NldElkU3RyAgAJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDHRyeUdldFN0cmluZwEJAKwCAgIXc3RhdGljX3N0YWtpbmdDb250cmFjdF8FCmFzc2V0SWRTdHICBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgUGYW1vdW50BQNuaWwFBHVuaXQDCQAAAgUHc3Rha2VUeAUHc3Rha2VUeAYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BD3Vuc3Rha2VJZk5lZWRlZAIKYXNzZXRJZFN0cgZhbW91bnQECXVuc3Rha2VUeAMJAQIhPQIJAQx0cnlHZXRTdHJpbmcBCQCsAgICF3N0YXRpY19zdGFraW5nQ29udHJhY3RfBQphc3NldElkU3RyAgAJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBDHRyeUdldFN0cmluZwEJAKwCAgIXc3RhdGljX3N0YWtpbmdDb250cmFjdF8FCmFzc2V0SWRTdHICB3Vuc3Rha2UJAMwIAgUGYW1vdW50BQNuaWwFA25pbAUEdW5pdAMJAAACBQl1bnN0YWtlVHgFCXVuc3Rha2VUeAYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BEWJ1cm5JbmRleElmTmVlZGVkAQZhbW91bnQECmluZGV4SWRTdHIJAQx0cnlHZXRTdHJpbmcBAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyAwkAAAIFCmluZGV4SWRTdHICAAUDbmlsAwkAAAIJAOwHAQkA2QQBBQppbmRleElkU3RyBQR1bml0BQNuaWwJAMwIAgkBBEJ1cm4CCQDZBAEFCmluZGV4SWRTdHIFBmFtb3VudAUDbmlsARFtaW50SW5kZXhJZk5lZWRlZAEGYW1vdW50BAppbmRleElkU3RyCQEMdHJ5R2V0U3RyaW5nAQIWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgMJAAACBQppbmRleElkU3RyAgAFA25pbAMJAAACCQDsBwEJANkEAQUKaW5kZXhJZFN0cgUEdW5pdAUDbmlsCQDMCAIJAQdSZWlzc3VlAwkA2QQBBQppbmRleElkU3RyBQZhbW91bnQGBQNuaWwBCGdldEtNdWx0AAQHJG1hdGNoMAkAnwgBAgxzdGF0aWNfS011bHQDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4BQdTY2FsZTE2ARJzYXZlQ3VycmVudFdlaWdodHMABAphc3NldElkc0xpCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfdG9rZW5JZHMCASwKAQFzAgVhY2N1bQdhc3NldElkCQDOCAIFBWFjY3VtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICFnJlYmFsYW5jZV9zdGFydFdlaWdodF8FB2Fzc2V0SWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FB2Fzc2V0SWQCB193ZWlnaHQFA25pbAoAAiRsBQphc3NldElkc0xpCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAkAawMJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQJAQhnZXRLTXVsdAAFB1NjYWxlMTYBEGNhbGN1bGF0ZVBJc3N1ZWQCBmFtb3VudAd0b2tlbklkBAdQc3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEB0JhbGFuY2UJAQ5nZXRGYWN0QmFsYW5jZQEJAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQEAnQxCQBuBAUGYW1vdW50BQdQc3VwcGx5BQdCYWxhbmNlBQRET1dOBQJ0MQENZ2V0TWluUElzc3VlZAEIcGF5bWVudHMKAQdoYW5kbGVyAgVhY2N1bQdjdXJyZW50AwkAAAIJAQ5nZXRGYWN0QmFsYW5jZQEJAQ5nZXRBc3NldFN0cmluZwEIBQdjdXJyZW50B2Fzc2V0SWQAAAUFYWNjdW0EB1BJc3N1ZWQJARBjYWxjdWxhdGVQSXNzdWVkAggFB2N1cnJlbnQGYW1vdW50CAUHY3VycmVudAdhc3NldElkAwkAAAIFB1BJc3N1ZWQAAAkAAgECJG9uZSBvZiB0aGUgdG9rZW5zIGFtb3VudHMgaXMgdG9vIGxvdwMDCQAAAgUFYWNjdW0AAAYJAGYCBQVhY2N1bQUHUElzc3VlZAUHUElzc3VlZAUFYWNjdW0ECW1pblBJc3NlZAoAAiRsBQhwYXltZW50cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgUJbWluUElzc2VkARJnZXRQcmljZUZyb21PcmFjbGUBCmFzc2V0SWRTdHIEByRtYXRjaDAJAJoIAgUNb3JhY2xlQWRkcmVzcwkArAICBQphc3NldElkU3RyAgdfdHdhcDVCAwkAAQIFByRtYXRjaDACA0ludAQBeAUHJG1hdGNoMAUBeAAAARFjYWxjdWxhdGVVc2RWYWx1ZQQHYXNzZXRJZAZhbW91bnQIYUJhbGFuY2UPZmVlQXNzZXRCYWxhbmNlBAthc3NldFdlaWdodAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAIHX3dlaWdodAQLZmVlQXNzZXRTdHIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfZmVlVG9rZW4EDWZlZUFzc2V0U2NhbGUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgkArAICAgdzdGF0aWNfBQtmZWVBc3NldFN0cgIGX3NjYWxlBAtmZWVBc3NldE51bQkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwkBDWdldEFzc2V0Qnl0ZXMBBQtmZWVBc3NldFN0cgQOZmVlQXNzZXRXZWlnaHQJAJEDAgUNQXNzZXRzV2VpZ2h0cwULZmVlQXNzZXROdW0EB19hbW91bnQJALkCAgkAtgIBBQZhbW91bnQFCVNjYWxlOF9CSQQNX2ZlZUFzc2V0RGF0YQkAugICCQC5AgIJALYCAQUPZmVlQXNzZXRCYWxhbmNlBQlTY2FsZThfQkkJALYCAQUOZmVlQXNzZXRXZWlnaHQECl9hc3NldERhdGEJALoCAgkAuQICCQC2AgEFCGFCYWxhbmNlBQpTY2FsZTE2X0JJCQC2AgEFC2Fzc2V0V2VpZ2h0BA12YWxJbkZlZUFzc2V0CQCgAwEJALwCAwUHX2Ftb3VudAUNX2ZlZUFzc2V0RGF0YQUKX2Fzc2V0RGF0YQQNZmVlQXNzZXRQcmljZQkBEmdldFByaWNlRnJvbU9yYWNsZQEFC2ZlZUFzc2V0U3RyCQBrAwUNdmFsSW5GZWVBc3NldAUNZmVlQXNzZXRQcmljZQUNZmVlQXNzZXRTY2FsZQEUY2FsY0F2Z0NvbmNlbnRyYXRpb24ACgEBZgIFYWNjdW0EbmV4dAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUEbmV4dAQGd2VpZ2h0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQphc3NldElkU3RyAgdfd2VpZ2h0BAthc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCmFzc2V0SWRTdHIEEGFzc2V0RmFjdEJhbGFuY2UIBQthc3NldFBhcmFtcwJfMgQQYXNzZXRWaXJ0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl8xCQCUCgIJAGQCCAUFYWNjdW0CXzEJAGsDBRBhc3NldEZhY3RCYWxhbmNlBQZ3ZWlnaHQFEGFzc2V0VmlydEJhbGFuY2UJAGQCCAUFYWNjdW0CXzIFBndlaWdodAoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgAAAAAKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBE2NoZWNrVG9rZW5zVmFsaWRpdHkBCHBheW1lbnRzCgEIaGFuZGxlcjECBWFjY3VtB3BheW1lbnQJAM4IAgUFYWNjdW0JAMwIAggFB3BheW1lbnQHYXNzZXRJZAUDbmlsBANpZHMKAAIkbAUIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGhhbmRsZXIxAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIFA2lkcwUDaWRzCgEIaGFuZGxlcjICBWFjY3VtB2Fzc2V0SWQDCQECIT0CCQDPCAIFA2lkcwUHYXNzZXRJZAUEdW5pdAkAZAIFBWFjY3VtAAEJAAIBCQCsAgICFGFzc2V0IG5vdCBhdHRhY2hlZDogCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkBAZjaGVja3MKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjVfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCGhhbmRsZXIyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY1XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNV8yAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgkBBSRmNV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIFBmNoZWNrcwUGY2hlY2tzBgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgETaGFuZGxlUG9vbFRva2Vuc0FkZAQHUElzc3VlZAhwYXltZW50cwt1c2VyQWRkcmVzcwpuZWVkQ2hhbmdlCgEVZ2V0VG9rZW5QYXltZW50QW1vdW50AQd0b2tlbklkCgEHaGFuZGxlcgIFYWNjdW0HcGF5bWVudAMJAAACCAUHcGF5bWVudAdhc3NldElkBQd0b2tlbklkCAUHcGF5bWVudAZhbW91bnQFBWFjY3VtCgACJGwFCHBheW1lbnRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGY0XzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdoYW5kbGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKCgERaGFuZGxlVG9rZW5DaGFuZ2UCBWFjY3VtB3Rva2VuSWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFB3Rva2VuSWQEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cgQNcGF5bWVudEFtb3VudAkBFWdldFRva2VuUGF5bWVudEFtb3VudAEFB3Rva2VuSWQEAkJrCAULYXNzZXRQYXJhbXMCXzIEB1BTdXBwbHkJARlnZXRWaXJ0dWFsUG9vbFRva2VuQW1vdW50AAQNdG9rZW5EZWNpbWFscwkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUKYXNzZXRJZFN0cgIGX3NjYWxlBAJhMQkAvQIECQC5AgIJALYCAQkAZAIFB1BTdXBwbHkFB1BJc3N1ZWQJALYCAQUGU2NhbGU4CQC2AgEFDXRva2VuRGVjaW1hbHMJALYCAQUHUFN1cHBseQUHQ0VJTElORwQCRGsJAKADAQkAvQIECQC4AgIFAmExCQC5AgIJALYCAQUNdG9rZW5EZWNpbWFscwkAtgIBBQZTY2FsZTgJALYCAQUCQmsJALkCAgkAtgIBBQ10b2tlbkRlY2ltYWxzCQC2AgEFBlNjYWxlOAUHQ0VJTElORwQIdG9SZXR1cm4JAGUCBQ1wYXltZW50QW1vdW50BQJEawQHc3Rha2VUeAkBDXN0YWtlSWZOZWVkZWQCBQphc3NldElkU3RyBQJEawMJAAACBQdzdGFrZVR4BQdzdGFrZVR4BAF0AwMFCm5lZWRDaGFuZ2UJAGYCBQh0b1JldHVybgAABwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQt1c2VyQWRkcmVzcwUIdG9SZXR1cm4FB3Rva2VuSWQFA25pbAUDbmlsBBNzZWxsb2ZmU3RhcnRCYWxhbmNlAwkBAiE9AggFC2Fzc2V0UGFyYW1zAl84CQBoAgkAaQIFBmhlaWdodABkAGQIBQthc3NldFBhcmFtcwJfNwkAawMIBQthc3NldFBhcmFtcwJfNwkAZAIFB1BTdXBwbHkFB1BJc3N1ZWQFB1BTdXBwbHkEDmFzc2V0UGFyYW1zVXBkCQCaCggJAG4ECAULYXNzZXRQYXJhbXMCXzEJAGQCBQdQU3VwcGx5BQdQSXNzdWVkBQdQU3VwcGx5BQhIQUxGRVZFTgkAZAIIBQthc3NldFBhcmFtcwJfMgUCRGsIBQthc3NldFBhcmFtcwJfMwgFC2Fzc2V0UGFyYW1zAl80CAULYXNzZXRQYXJhbXMCXzUIBQthc3NldFBhcmFtcwJfNgUTc2VsbG9mZlN0YXJ0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl84CQDOCAIJAM4IAgUFYWNjdW0FAXQJAMwIAgkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFCmFzc2V0SWRTdHIFDmFzc2V0UGFyYW1zVXBkBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4KAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEWhhbmRsZVRva2VuQ2hhbmdlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGY0XzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmNF8yAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgkBBSRmNF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKARZjYWxjTWludGVkV2l0aE9uZVRva2VuAg9hc3NldEFkZGVkSWRTdHIGYW1vdW50BAdQU3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUPYXNzZXRBZGRlZElkU3RyBBBhc3NldEZhY3RCYWxhbmNlCAULYXNzZXRQYXJhbXMCXzIEEGFzc2V0VmlydEJhbGFuY2UIBQthc3NldFBhcmFtcwJfMQQLYXNzZXRXZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FD2Fzc2V0QWRkZWRJZFN0cgIHX3dlaWdodAQKYXNzZXRTY2FsZQkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUPYXNzZXRBZGRlZElkU3RyAgZfc2NhbGUEDWFzc2V0RGVjaW1hbHMJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FD2Fzc2V0QWRkZWRJZFN0cgIJX2RlY2ltYWxzBBNQSXNzdWVkTm9NdWx0aXBsaWVyCQBrAwUHUFN1cHBseQkAZQIJAKADAQkAdgYJALYCAQkAZAIFCmFzc2V0U2NhbGUJAGsDBQZhbW91bnQFCmFzc2V0U2NhbGUFEGFzc2V0VmlydEJhbGFuY2UFDWFzc2V0RGVjaW1hbHMJALYCAQULYXNzZXRXZWlnaHQABAAIBQRET1dOBQZTY2FsZTgFBlNjYWxlOAQHYXZnQ29uYwkBFGNhbGNBdmdDb25jZW50cmF0aW9uAAQHUElzc3VlZAkAawMFE1BJc3N1ZWROb011bHRpcGxpZXIIBQdhdmdDb25jAl8yCAUHYXZnQ29uYwJfMQQOYXNzZXRQYXJhbXNVcGQJAJoKCAkAZAIFEGFzc2V0VmlydEJhbGFuY2UFBmFtb3VudAkAZAIFEGFzc2V0RmFjdEJhbGFuY2UFBmFtb3VudAgFC2Fzc2V0UGFyYW1zAl8zCAULYXNzZXRQYXJhbXMCXzQIBQthc3NldFBhcmFtcwJfNQgFC2Fzc2V0UGFyYW1zAl82CAULYXNzZXRQYXJhbXMCXzcIBQthc3NldFBhcmFtcwJfOAkAlAoCCQDMCAIJARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCBQ9hc3NldEFkZGVkSWRTdHIFDmFzc2V0UGFyYW1zVXBkBQNuaWwFB1BJc3N1ZWQBFmNhbGNSZWRlZW1XaXRoT25lVG9rZW4CDWFzc2V0T3V0SWRTdHIJUFJlZGVlbWVkBAdQU3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUNYXNzZXRPdXRJZFN0cgQQYXNzZXRGYWN0QmFsYW5jZQgFC2Fzc2V0UGFyYW1zAl8yBBBhc3NldFZpcnRCYWxhbmNlCAULYXNzZXRQYXJhbXMCXzEEC2Fzc2V0V2VpZ2h0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQ1hc3NldE91dElkU3RyAgdfd2VpZ2h0BAphc3NldFNjYWxlCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQ1hc3NldE91dElkU3RyAgZfc2NhbGUEDWFzc2V0RGVjaW1hbHMJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FDWFzc2V0T3V0SWRTdHICCV9kZWNpbWFscwQVYW1vdW50T3V0Tm9NdWxpdHBsaWVyCQBrAwUQYXNzZXRWaXJ0QmFsYW5jZQkAZQIFBlNjYWxlOAkAoAMBCQB2BgkAtgIBCQBlAgUKYXNzZXRTY2FsZQkAawMFCVBSZWRlZW1lZAUKYXNzZXRTY2FsZQUHUFN1cHBseQUNYXNzZXREZWNpbWFscwkAtgIBCQBrAwCQTgCQTgULYXNzZXRXZWlnaHQABAAIBQRET1dOBQZTY2FsZTgEB2F2Z0NvbmMJARRjYWxjQXZnQ29uY2VudHJhdGlvbgAECWFtb3VudE91dAkAawMFFWFtb3VudE91dE5vTXVsaXRwbGllcggFB2F2Z0NvbmMCXzEIBQdhdmdDb25jAl8yAwkAZgIFCWFtb3VudE91dAUQYXNzZXRGYWN0QmFsYW5jZQkAAgECNG5vIGF2YWlsYWJsZSBmYWN0IGxpcXVpZGl0eSB0byB3aXRoZHJhdyBpbiBvbmUgdG9rZW4EDmFzc2V0UGFyYW1zVXBkCQCaCggJAGUCBRBhc3NldFZpcnRCYWxhbmNlBQlhbW91bnRPdXQJAGUCBRBhc3NldEZhY3RCYWxhbmNlBQlhbW91bnRPdXQIBQthc3NldFBhcmFtcwJfMwgFC2Fzc2V0UGFyYW1zAl80CAULYXNzZXRQYXJhbXMCXzUIBQthc3NldFBhcmFtcwJfNggFC2Fzc2V0UGFyYW1zAl83CAULYXNzZXRQYXJhbXMCXzgJAJQKAgkAzAgCCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUNYXNzZXRPdXRJZFN0cgUOYXNzZXRQYXJhbXNVcGQFA25pbAUJYW1vdW50T3V0ARZoYW5kbGVQb29sVG9rZW5zUmVkZWVtAglQUmVkZWVtZWQLdXNlckFkZHJlc3MKARFoYW5kbGVUb2tlblJlZGVlbQIFYWNjdW0HdG9rZW5JZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHdG9rZW5JZAQLYXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQphc3NldElkU3RyBAJCawgFC2Fzc2V0UGFyYW1zAl8yBAdQU3VwcGx5CQEZZ2V0VmlydHVhbFBvb2xUb2tlbkFtb3VudAAEDXRva2VuRGVjaW1hbHMJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCmFzc2V0SWRTdHICBl9zY2FsZQQGcHN1cHBsCQC9AgQJALkCAgkAtgIBCQBlAgUHUFN1cHBseQUJUFJlZGVlbWVkCQC2AgEFBlNjYWxlOAkAtgIBBQZTY2FsZTgJALYCAQUHUFN1cHBseQUERE9XTgQGYW1vdW50CQCgAwEJAL0CBAkAuAICCQC2AgEFB1NjYWxlMTYFBnBzdXBwbAkAtgIBBQJCawkAtgIBBQdTY2FsZTE2BQhIQUxGRVZFTgQJdW5zdGFrZVR4CQEPdW5zdGFrZUlmTmVlZGVkAgUKYXNzZXRJZFN0cgUGYW1vdW50AwkAAAIFCXVuc3Rha2VUeAUJdW5zdGFrZVR4BBNzZWxsb2ZmU3RhcnRCYWxhbmNlAwkBAiE9AggFC2Fzc2V0UGFyYW1zAl84CQBoAgkAaQIFBmhlaWdodABkAGQIBQthc3NldFBhcmFtcwJfNwkAawMIBQthc3NldFBhcmFtcwJfNwkAZQIFB1BTdXBwbHkFCVBSZWRlZW1lZAUHUFN1cHBseQQOYXNzZXRQYXJhbXNVcGQJAJoKCAkAawMIBQthc3NldFBhcmFtcwJfMQkAZQIFB1BTdXBwbHkFCVBSZWRlZW1lZAUHUFN1cHBseQkAZQIIBQthc3NldFBhcmFtcwJfMgUGYW1vdW50CAULYXNzZXRQYXJhbXMCXzMIBQthc3NldFBhcmFtcwJfNAgFC2Fzc2V0UGFyYW1zAl81CAULYXNzZXRQYXJhbXMCXzYFE3NlbGxvZmZTdGFydEJhbGFuY2UIBQthc3NldFBhcmFtcwJfOAkAzggCCQDOCAIFBWFjY3VtCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzBQZhbW91bnQFB3Rva2VuSWQFA25pbAkAzAgCCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUKYXNzZXRJZFN0cgUOYXNzZXRQYXJhbXNVcGQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQERaGFuZGxlVG9rZW5SZWRlZW0CBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBEmNhbGN1bGF0ZU91dEFtb3VudAUIQW1vdW50SW4HYXNzZXRJbghhc3NldE91dAlCYWxhbmNlSW4KQmFsYW5jZU91dAQHSW5kZXhJbgkBBXZhbHVlAQkAzwgCBQhhc3NldElkcwUHYXNzZXRJbgQISW5kZXhPdXQJAQV2YWx1ZQEJAM8IAgUIYXNzZXRJZHMFCGFzc2V0T3V0AwkAAAIFB0luZGV4SW4FCEluZGV4T3V0BQhBbW91bnRJbgkAbgQFCkJhbGFuY2VPdXQJAGUCCQBoAgUGU2NhbGU4BQZTY2FsZTgJAKADAQkAdgYJAL0CBAkAuQICCQC2AgEFCUJhbGFuY2VJbgkAtgIBAJBOCQC2AgEJAGgCBQZTY2FsZTgFBlNjYWxlOAkAuQICCQC2AgEJAGQCBQlCYWxhbmNlSW4FCEFtb3VudEluCQC2AgEAkE4FBkhBTEZVUAAQCQC2AgEJAGsDCQCRAwIFDUFzc2V0c1dlaWdodHMFB0luZGV4SW4AgKCUpY0dCQCRAwIFDUFzc2V0c1dlaWdodHMFCEluZGV4T3V0AAwAEAUHQ0VJTElORwkAaAIFBlNjYWxlOAUGU2NhbGU4BQhIQUxGRVZFTgELY2xhaW1SZXN1bHQBB2FkZHJlc3MECmFkZHJlc3NTdHIJAKUIAQUHYWRkcmVzcwQLaW5kZXhBbW91bnQJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQEC2ZlZUFzc2V0U3RyCQEMdHJ5R2V0U3RyaW5nAQIPc3RhdGljX2ZlZVRva2VuBA5mZWVBc3NldFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFC2ZlZUFzc2V0U3RyBA9mZWVUb2tlbkJhbGFuY2UIBQ5mZWVBc3NldFBhcmFtcwJfMQoBB2hhbmRsZXICBWFjY3VtB2Fzc2V0SWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cgQUY3VycmVudFRva2VuSW50ZXJlc3QIBQthc3NldFBhcmFtcwJfNAQIYUJhbGFuY2UIBQthc3NldFBhcmFtcwJfMQQMcmV3YXJkQW1vdW50CQBrAwULaW5kZXhBbW91bnQJAGUCBRRjdXJyZW50VG9rZW5JbnRlcmVzdAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgkArAICBQphZGRyZXNzU3RyAgtfbGFzdENoZWNrXwUKYXNzZXRJZFN0cgIJX2ludGVyZXN0BQdTY2FsZTE2BAp1bnN0YWtlSW52CQEPdW5zdGFrZUlmTmVlZGVkAgUKYXNzZXRJZFN0cgUMcmV3YXJkQW1vdW50AwkAAAIFCnVuc3Rha2VJbnYFCnVuc3Rha2VJbnYECHRyYW5zZmVyAwkAAAIFDHJld2FyZEFtb3VudAAABQNuaWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUHYWRkcmVzcwUMcmV3YXJkQW1vdW50BQdhc3NldElkBQNuaWwJAJQKAgkAzggCCQDOCAIIBQVhY2N1bQJfMQUIdHJhbnNmZXIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIFCmFkZHJlc3NTdHICC19sYXN0Q2hlY2tfBQphc3NldElkU3RyAglfaW50ZXJlc3QFFGN1cnJlbnRUb2tlbkludGVyZXN0BQNuaWwJAGQCCAUFYWNjdW0CXzIJARFjYWxjdWxhdGVVc2RWYWx1ZQQFB2Fzc2V0SWQFDHJld2FyZEFtb3VudAUIYUJhbGFuY2UFD2ZlZVRva2VuQmFsYW5jZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQFYWNjdW0KAAIkbAUMZWFybmVkQXNzZXRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwAAAoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHaGFuZGxlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjRfMgIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIJAQUkZjRfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkAlAoCCQDOCAIIBQVhY2N1bQJfMQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphZGRyZXNzU3RyAhFfY2xhaW1lZFJld2FyZFVTRAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphZGRyZXNzU3RyAhFfY2xhaW1lZFJld2FyZFVTRAgFBWFjY3VtAl8yCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFkZHJlc3NTdHICCl9sYXN0Q2xhaW0IBQlsYXN0QmxvY2sJdGltZXN0YW1wBQNuaWwIBQVhY2N1bQJfMgEQaW5kZXhTdGFrZVJlc3VsdAIKYWRkcmVzc1N0cgZhbW91bnQEAmxpCAkBC2NsYWltUmVzdWx0AQkBEUBleHRyTmF0aXZlKDEwNjIpAQUKYWRkcmVzc1N0cgJfMQkAzggCBQJsaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphZGRyZXNzU3RyAgxfaW5kZXhTdGFrZWQJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQICEmdsb2JhbF9pbmRleFN0YWtlZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQISZ2xvYmFsX2luZGV4U3Rha2VkBQZhbW91bnQFA25pbAEDc3VtAgVhY2N1bQFuCQBkAgUFYWNjdW0JAQ1wYXJzZUludFZhbHVlAQUBbgENY2hlY2tGZWVBc3NldAIFYWNjdW0EbmV4dAMDCQECIT0CCQDPCAIFFXN1cHBvcnRlZEZlZUFzc2V0c1N0cgUEbmV4dAUEdW5pdAkAAAIFBWFjY3VtAgAHBQRuZXh0BQVhY2N1bQESY2FsY0ludGVyZXN0Q2hhbmdlAgphc3NldElkU3RyBWxwRmVlBAp0b3RhbEluZGV4CQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAQNaW50ZXJlc3REZWx0YQkAawMFBWxwRmVlBQdTY2FsZTE2BQp0b3RhbEluZGV4BQ1pbnRlcmVzdERlbHRhAQ51cGRTZWxsb2ZmRGF0YQQKYXNzZXRJZFN0cghhbW91bnRJbgdiYWxhbmNlDXNlbGxvZmZQYXJhbXMEDWN1cnJlbnRQZXJpb2QJAGgCCQBpAgUGaGVpZ2h0AGQAZAQKcHJldlBlcmlvZAgFDXNlbGxvZmZQYXJhbXMCXzIEC3ByZXZTZWxsb2ZmAwkAAAIFDWN1cnJlbnRQZXJpb2QFCnByZXZQZXJpb2QIBQ1zZWxsb2ZmUGFyYW1zAl8xAAAEE3NlbGxvZmZTdGFydEJhbGFuY2UDCQAAAgUNY3VycmVudFBlcmlvZAUKcHJldlBlcmlvZAgFDXNlbGxvZmZQYXJhbXMCXzMFB2JhbGFuY2UEDHNlbGxvZmZEZWx0YQkAawMFB1NjYWxlMTYFCGFtb3VudEluBRNzZWxsb2ZmU3RhcnRCYWxhbmNlBAptYXhTZWxsb2ZmCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgdzdGF0aWNfBQphc3NldElkU3RyAgtfbWF4U2VsbG9mZgMDCQBmAgkAZAIFC3ByZXZTZWxsb2ZmBQxzZWxsb2ZmRGVsdGEFCm1heFNlbGxvZmYJAQIhPQIFCm1heFNlbGxvZmYAAAcJAAIBCQCsAgICI21heCBzZWxsb2ZmIHJlYWNoZWQgZm9yIHRoaXMgYXNzZXQgBQphc3NldElkU3RyBAZzdGFydEgDCQAAAgUNY3VycmVudFBlcmlvZAUKcHJldlBlcmlvZAUKcHJldlBlcmlvZAUNY3VycmVudFBlcmlvZAQGc3RhcnRCAwkAAAIFDWN1cnJlbnRQZXJpb2QFCnByZXZQZXJpb2QIBQ1zZWxsb2ZmUGFyYW1zAl8zBRNzZWxsb2ZmU3RhcnRCYWxhbmNlCQCVCgMJAGQCBQtwcmV2U2VsbG9mZgUMc2VsbG9mZkRlbHRhBQZzdGFydEgFBnN0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a2luZ0NvbnRyYWN0XwUKYXNzZXRJZFN0cgUNc3Rha2VyQWRkcmVzcwUDbmlsAWkBB3ByZUluaXQHC2Fzc2V0SWRzU3RyD2Fzc2V0V2VpZ2h0c1N0chJhc3NldE1heFNlbGxvZmZTdHIOYmFzZVRva2VuSWRTdHIKcG9vbERvbWFpbglwb29sT3duZXIDZmVlBBBwb29sT3duZXJBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQlwb29sT3duZXIEDWFzc2V0SWRzU3RyTGkJALUJAgULYXNzZXRJZHNTdHICASwEFGFzc2V0TWF4U2VsbG9mZlN0ckxpCQC1CQIFEmFzc2V0TWF4U2VsbG9mZlN0cgIBLAQRYXNzZXRXZWlnaHRzU3RyTGkJALUJAgUPYXNzZXRXZWlnaHRzU3RyAgEsBAphc3NldElkc0xpCgACJGwFDWFzc2V0SWRzU3RyTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBE2FkZEFzc2V0Qnl0ZXNUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEEWZlZUFzc2V0Q2hvc2VuU3RyCgACJGwFDWFzc2V0SWRzU3RyTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjVfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDWNoZWNrRmVlQXNzZXQCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjVfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY1XzICCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECCQEFJGY1XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoEC2ZlZUFzc2V0U3RyAwkAAAIFEWZlZUFzc2V0Q2hvc2VuU3RyAgAFDmJhc2VUb2tlbklkU3RyBRFmZWVBc3NldENob3NlblN0cgMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3ADCQECIT0CBQR0aGlzCAUBaQZjYWxsZXIJAAIBAgphZG1pbiBvbmx5AwkAZgIJALECAQUKcG9vbERvbWFpbgANCQACAQIVdG9vIGxhcmdlIHBvb2wgZG9tYWluAwMJAGYCBQNmZWUA9AMGCQBmAgAABQNmZWUJAAIBAipmZWUgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDUwMCAoMC01JSkDCQECIT0CCQEPdmFsaWRhdGVXZWlnaHRzAQURYXNzZXRXZWlnaHRzU3RyTGkAkE4JAAIBCQCsAgICJndlaWdodHMgc3VtIHNob3VsZCBiZSAxMDAwMCwgY3VycmVudDogCQCkAwEJAQ92YWxpZGF0ZVdlaWdodHMBBRFhc3NldFdlaWdodHNTdHJMaQoBE2FkZFRva2VuRGF0YUVudHJpZXMCBWFjY3VtCGFzc2V0TnVtAwkAZwIFCGFzc2V0TnVtCQCQAwEFCmFzc2V0SWRzTGkFBWFjY3VtBBNhc3NldFN0YWtpbmdBZGRyZXNzCgABQAkA/AcEBQ9wb29sc0h1YkFkZHJlc3MCEHVzZUVtcHR5Q29udHJhY3QJAMwIAgkArAICAgdzdGFrZXJfCQCRAwIFDWFzc2V0SWRzU3RyTGkFCGFzc2V0TnVtBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcDCQAAAgUTYXNzZXRTdGFraW5nQWRkcmVzcwUTYXNzZXRTdGFraW5nQWRkcmVzcwQNYXNzZXREZWNpbWFscwQHJG1hdGNoMAkAkQMCBQphc3NldElkc0xpBQhhc3NldE51bQMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAF4BQckbWF0Y2gwCAkBBXZhbHVlAQkA7AcBBQF4CGRlY2ltYWxzAAgJAM4IAgkAzggCBQVhY2N1bQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB3N0YXRpY18JAJEDAgUNYXNzZXRJZHNTdHJMaQUIYXNzZXROdW0CBl9zY2FsZQkAbAYACgAABQ1hc3NldERlY2ltYWxzAAAAAAUERE9XTgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB3N0YXRpY18JAJEDAgUNYXNzZXRJZHNTdHJMaQUIYXNzZXROdW0CCV9kZWNpbWFscwUNYXNzZXREZWNpbWFscwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB3N0YXRpY18JAJEDAgUNYXNzZXRJZHNTdHJMaQUIYXNzZXROdW0CB193ZWlnaHQJAQV2YWx1ZQEJALYJAQkAkQMCBRFhc3NldFdlaWdodHNTdHJMaQUIYXNzZXROdW0JAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICAhdzdGF0aWNfc3Rha2luZ0NvbnRyYWN0XwkAkQMCBQ1hc3NldElkc1N0ckxpBQhhc3NldE51bQUTYXNzZXRTdGFraW5nQWRkcmVzcwUDbmlsAwkAAAIJAJEDAgUUYXNzZXRNYXhTZWxsb2ZmU3RyTGkFCGFzc2V0TnVtAgAFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICB3N0YXRpY18JAJEDAgUNYXNzZXRJZHNTdHJMaQUIYXNzZXROdW0CC19tYXhTZWxsb2ZmCQBoAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFFGFzc2V0TWF4U2VsbG9mZlN0ckxpBQhhc3NldE51bQUHU2NhbGUxMgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDOCAIKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkFA25pbAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmNl8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQETYWRkVG9rZW5EYXRhRW50cmllcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmNl8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjZfMgIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIJAQUkZjZfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkAzAgCCQELU3RyaW5nRW50cnkCAg9zdGF0aWNfdG9rZW5JZHMFC2Fzc2V0SWRzU3RyCQDMCAIJAQtTdHJpbmdFbnRyeQICD3N0YXRpY19mZWVUb2tlbgULZmVlQXNzZXRTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgITc3RhdGljX3Rva2VuV2VpZ2h0cwUPYXNzZXRXZWlnaHRzU3RyCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhNzdGF0aWNfdG9rZW5zQW1vdW50CQCQAwEFCmFzc2V0SWRzTGkJAMwIAgkBC1N0cmluZ0VudHJ5AgIRc3RhdGljX3Bvb2xEb21haW4FCnBvb2xEb21haW4JAMwIAgkBC1N0cmluZ0VudHJ5AgIWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgIACQDMCAIJAQtTdHJpbmdFbnRyeQICEnN0YXRpY19iYXNlVG9rZW5JZAUOYmFzZVRva2VuSWRTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgIQc3RhdGljX3Bvb2xPd25lcgUJcG9vbE93bmVyCQDMCAIJAQxJbnRlZ2VyRW50cnkCAgpzdGF0aWNfZmVlBQNmZWUJAMwIAgkBDEludGVnZXJFbnRyeQICDHN0YXRpY19LTXVsdAUHU2NhbGUxNgkAzAgCCQEMSW50ZWdlckVudHJ5AgISZ2xvYmFsX2luZGV4U3Rha2VkAAAJAMwIAgkBDEludGVnZXJFbnRyeQICF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50AAAJAMwIAgkBDEludGVnZXJFbnRyeQICE2dsb2JhbF93YXNQcmVJbml0ZWQAAQUDbmlsAWkBBmRlSW5pdAADCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIKYWRtaW4gb25seQkAzAgCCQEMSW50ZWdlckVudHJ5AgIQZ2xvYmFsX3dhc0luaXRlZAAABQNuaWwBaQEEaW5pdAcLYXNzZXRJZHNTdHIPYXNzZXRXZWlnaHRzU3RyEmFzc2V0TWF4U2VsbG9mZlN0cg5iYXNlVG9rZW5JZFN0cgpwb29sRG9tYWluA2ZlZQx2QmFsYW5jZXNTdHIECnByZUluaXRJbnYJAPwHBAUEdGhpcwIHcHJlSW5pdAkAzAgCBQthc3NldElkc1N0cgkAzAgCBQ9hc3NldFdlaWdodHNTdHIJAMwIAgUSYXNzZXRNYXhTZWxsb2ZmU3RyCQDMCAIFDmJhc2VUb2tlbklkU3RyCQDMCAIFCnBvb2xEb21haW4JAMwIAgkApQgBCAUBaQZjYWxsZXIJAMwIAgUDZmVlBQNuaWwFA25pbAMJAAACBQpwcmVJbml0SW52BQpwcmVJbml0SW52BAl2QmFsYW5jZXMJARFwYXJzdFN0clRvSW50TGlzdAEFDHZCYWxhbmNlc1N0cgoBEGdldFBheW1lbnRBbW91bnQBCmFzc2V0SWRTdHIKAQdoYW5kbGVyAgVhY2N1bQdwYXltZW50AwkAAAIJAQ5nZXRBc3NldFN0cmluZwEIBQdwYXltZW50B2Fzc2V0SWQFCmFzc2V0SWRTdHIIBQdwYXltZW50BmFtb3VudAUFYWNjdW0KAAIkbAgFAWkIcGF5bWVudHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoKAQtwcmVwYXJlTGlzdAAKAQdoYW5kbGVyAgVhY2N1bQdhc3NldElkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBBQdhc3NldElkBAFuCQEFdmFsdWUBCQDPCAIFCGFzc2V0SWRzBQdhc3NldElkBA1wYXltZW50QW1vdW50CQEQZ2V0UGF5bWVudEFtb3VudAEFCmFzc2V0SWRTdHIEC2Fzc2V0UGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cgQOYXNzZXRQYXJhbXNVcGQJAJoKCAkAkQMCBQl2QmFsYW5jZXMFAW4FDXBheW1lbnRBbW91bnQIBQthc3NldFBhcmFtcwJfMwgFC2Fzc2V0UGFyYW1zAl80CAULYXNzZXRQYXJhbXMCXzUIBQthc3NldFBhcmFtcwJfNggFC2Fzc2V0UGFyYW1zAl83CAULYXNzZXRQYXJhbXMCXzgJAM4IAgUFYWNjdW0JAMwIAgkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFCmFzc2V0SWRTdHIFDmFzc2V0UGFyYW1zVXBkBQNuaWwKAAIkbAUIYXNzZXRJZHMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoKARljYWxjdWxhdGVQb29sVG9rZW5zQW1vdW50AQdhc3NldElkCgEHaGFuZGxlcgIFYWNjdW0HYXNzZXRJZAoBCGhhbmRsZXIyAgVhY2N1bQFuAwkAAAIFAW4FB2Fzc2V0SWQJAQV2YWx1ZQEJAM8IAgUIYXNzZXRJZHMFAW4FBWFjY3VtBAVUb2tlbgoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAQoBBSRmNF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEIaGFuZGxlcjICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoJAGsDBQVhY2N1bQkAbAYJAJEDAgUJdkJhbGFuY2VzBQVUb2tlbgkAkQMCBQhEZWNpbWFscwUFVG9rZW4JAJEDAgUNQXNzZXRzV2VpZ2h0cwUFVG9rZW4FFUFzc2V0c1dlaWdodHNEZWNpbWFscwAIBQVGTE9PUgUGU2NhbGU4CgACJGwFCGFzc2V0SWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUOUG9vbFRva2VuU2NhbGUKAQUkZjRfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBB2hhbmRsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjRfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGY0XzICCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECCQEFJGY0XzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECOWF0IGxlYXN0IHNvbWUgb2YgdGhlIGFzc2V0cyBzaG91bGQgYmUgcHJvdmlkZWQgYXMgcGF5bWVudAMJAGYCCQENdHJ5R2V0SW50ZWdlcgECEGdsb2JhbF93YXNJbml0ZWQAAAkAAgECE3Bvb2wgYWxyZWFkeSBpbml0ZWQEEWluaXRpYWxQb29sVG9rZW5zCQEZY2FsY3VsYXRlUG9vbFRva2Vuc0Ftb3VudAEFCGFzc2V0SWRzBAxub3RpZnlJbnZva2UJAPwHBAUPcG9vbHNIdWJBZGRyZXNzAgthZGRTZWxmUG9vbAUDbmlsBQNuaWwDCQAAAgUMbm90aWZ5SW52b2tlBQxub3RpZnlJbnZva2UDCQAAAgURaW5pdGlhbFBvb2xUb2tlbnMAAAkAAgECMnlvdSBuZWVkIGEgYmlnZ2VyIHRva2VucyBhbW91bnQgdG8gbGF1bmNoIHRoZSBwb29sCQDOCAIJAQtwcmVwYXJlTGlzdAAJAMwIAgkBDEludGVnZXJFbnRyeQICF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BRFpbml0aWFsUG9vbFRva2VucwkAzAgCCQEMSW50ZWdlckVudHJ5AgIQZ2xvYmFsX3dhc0luaXRlZAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQFEWluaXRpYWxQb29sVG9rZW5zCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQFEWluaXRpYWxQb29sVG9rZW5zBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENZ2VuZXJhdGVJbmRleAEKbmVlZENoYW5nZQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMFAVQJAAIBCQCsAgICO3lvdSBuZWVkIHRvIGF0dGFjaCBhbGwgcG9vbCB0b2tlbnMuIGFtb3VudCBvZiBwb29sIHRva2VuczogCQCkAwEFAVQDCQEBIQEJARNjaGVja1Rva2Vuc1ZhbGlkaXR5AQgFAWkIcGF5bWVudHMJAAIBAhV3cm9uZyBhc3NldHMgYXR0YWNoZWQEDVBJc3N1ZWROb011bHQJAQ1nZXRNaW5QSXNzdWVkAQgFAWkIcGF5bWVudHMEBnJlc3VsdAkBE2hhbmRsZVBvb2xUb2tlbnNBZGQEBQ1QSXNzdWVkTm9NdWx0CAUBaQhwYXltZW50cwgFAWkMb3JpZ2luQ2FsbGVyBQpuZWVkQ2hhbmdlBA9QSXNzdWVkV2l0aE11bHQJAG4EBQ1QSXNzdWVkTm9NdWx0BQdTY2FsZTE2CQEIZ2V0S011bHQABQRET1dOCQCUCgIJAM4IAgkAzggCCQDOCAIFBnJlc3VsdAgJAQtjbGFpbVJlc3VsdAEIBQFpBmNhbGxlcgJfMQkBEW1pbnRJbmRleElmTmVlZGVkAQUPUElzc3VlZFdpdGhNdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkApQgBCAUBaQZjYWxsZXICDF9pbmRleFN0YWtlZAUPUElzc3VlZFdpdGhNdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQJAGQCCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAUPUElzc3VlZFdpdGhNdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQIXZ2xvYmFsX3Bvb2xUb2tlbl9hbW91bnQFD1BJc3N1ZWRXaXRoTXVsdAUDbmlsBQ9QSXNzdWVkV2l0aE11bHQBaQELcmVkZWVtSW5kZXgBD3Bvb2xUb2tlbkFtb3VudAMJAGYCBQ9wb29sVG9rZW5BbW91bnQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQClCAEIBQFpBmNhbGxlcgIMX2luZGV4U3Rha2VkCQACAQIsdXNlciBkb2Vzbid0IGhhdmUgdGhpcyBhbW91bnQgb2YgcG9vbCB0b2tlbnMDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wBBFQUmVkZWVtZWRXaXRoTXVsdAUPcG9vbFRva2VuQW1vdW50BBNQUmVkZWVtZWRXaXRoTm9NdWx0CQBuBAURUFJlZGVlbWVkV2l0aE11bHQJAQhnZXRLTXVsdAAFB1NjYWxlMTYFBERPV04EBnJlc3VsdAkBFmhhbmRsZVBvb2xUb2tlbnNSZWRlZW0CBRNQUmVkZWVtZWRXaXRoTm9NdWx0CAUBaQZjYWxsZXIJAM4IAgkAzggCCQDOCAIFBnJlc3VsdAgJAQtjbGFpbVJlc3VsdAEIBQFpBmNhbGxlcgJfMQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQClCAEIBQFpBmNhbGxlcgIMX2luZGV4U3Rha2VkCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgxfaW5kZXhTdGFrZWQFEVBSZWRlZW1lZFdpdGhNdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQJAGUCCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAURUFJlZGVlbWVkV2l0aE11bHQJAMwIAgkBDEludGVnZXJFbnRyeQICF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50CQBlAgkBDXRyeUdldEludGVnZXIBAhdnbG9iYWxfcG9vbFRva2VuX2Ftb3VudAURUFJlZGVlbWVkV2l0aE11bHQFA25pbAkBEWJ1cm5JbmRleElmTmVlZGVkAQUPcG9vbFRva2VuQW1vdW50AWkBCnN0YWtlSW5kZXgABAphZGRyZXNzU3RyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAADCQECIT0CCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQJANkEAQkBDHRyeUdldFN0cmluZwECFnN0YXRpY19wb29sVG9rZW5faWRTdHIJAAIBAhR3cm9uZyBhc3NldCBhdHRhY2hlZAkBEGluZGV4U3Rha2VSZXN1bHQCBQphZGRyZXNzU3RyCAUDcG10BmFtb3VudAFpAQ1zdGFrZUluZGV4Rm9yAQphZGRyZXNzU3RyBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAMJAQIhPQIJAQV2YWx1ZQEIBQNwbXQHYXNzZXRJZAkA2QQBCQEMdHJ5R2V0U3RyaW5nAQIWc3RhdGljX3Bvb2xUb2tlbl9pZFN0cgkAAgECFHdyb25nIGFzc2V0IGF0dGFjaGVkCQEQaW5kZXhTdGFrZVJlc3VsdAIFCmFkZHJlc3NTdHIIBQNwbXQGYW1vdW50AWkBDHVuc3Rha2VJbmRleAELaW5kZXhBbW91bnQKAQppc3N1ZUluZGV4AAQFaXNzdWUJAMMIBwkArAICAgNQUiAJAQx0cnlHZXRTdHJpbmcBAhFzdGF0aWNfcG9vbERvbWFpbgISUHV6emxlIFJhbmdlIEluZGV4CQENdHJ5R2V0SW50ZWdlcgECF2dsb2JhbF9wb29sVG9rZW5fYW1vdW50BRFQb29sVG9rZW5EZWNpbWFscwYFBHVuaXQAAAQOcG9vbFRva2VuSWRTdHIJANgEAQkAuAgBBQVpc3N1ZQkAlAoCCQDMCAIFBWlzc3VlCQDMCAIJAQtTdHJpbmdFbnRyeQICFnN0YXRpY19wb29sVG9rZW5faWRTdHIFDnBvb2xUb2tlbklkU3RyBQNuaWwFDnBvb2xUb2tlbklkU3RyBA0kdDA0MDQzMjQwNTk4AwkAAAIJAQx0cnlHZXRTdHJpbmcBAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyAgAJAQppc3N1ZUluZGV4AAkAlAoCBQNuaWwJAQx0cnlHZXRTdHJpbmcBAhZzdGF0aWNfcG9vbFRva2VuX2lkU3RyBBRwb29sVG9rZW5Jc3N1ZVJlc3VsdAgFDSR0MDQwNDMyNDA1OTgCXzEEDnBvb2xUb2tlbklkU3RyCAUNJHQwNDA0MzI0MDU5OAJfMgQLcG9vbFRva2VuSWQJANkEAQUOcG9vbFRva2VuSWRTdHIECmFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyBA5pbmRleEF2YWlsYWJsZQkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFkZHJlc3NTdHICDF9pbmRleFN0YWtlZAMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3ADCQBmAgULaW5kZXhBbW91bnQFDmluZGV4QXZhaWxhYmxlCQACAQIleW91IGRvbid0IGhhdmUgaW5kZXggdG9rZW5zIGF2YWlsYWJsZQMJAQppc1NodXRkb3duAAkAAgECE2NvbnRyYWN0IGlzIG9uIHN0b3AJAM4IAgkAzggCBRRwb29sVG9rZW5Jc3N1ZVJlc3VsdAgJAQtjbGFpbVJlc3VsdAEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCmFkZHJlc3NTdHICXzEJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYWRkcmVzc1N0cgIMX2luZGV4U3Rha2VkCQBlAgUOaW5kZXhBdmFpbGFibGUFC2luZGV4QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCAhJnbG9iYWxfaW5kZXhTdGFrZWQJAGUCCQENdHJ5R2V0SW50ZWdlcgECEmdsb2JhbF9pbmRleFN0YWtlZAULaW5kZXhBbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQtpbmRleEFtb3VudAULcG9vbFRva2VuSWQFA25pbAFpARFjbGFpbUluZGV4UmV3YXJkcwADCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wCQELY2xhaW1SZXN1bHQBCAUBaQZjYWxsZXIBaQENZXZhbHVhdGVDbGFpbQEEdXNlcgkAlAoCBQNuaWwICQELY2xhaW1SZXN1bHQBCQERQGV4dHJOYXRpdmUoMTA2MikBBQR1c2VyAl8yAWkBE2FkZEludGVyZXN0RXh0ZXJuYWwABAdhc3NldElkCAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQEBmFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEB3N0YWtlVHgJAQ1zdGFrZUlmTmVlZGVkAgUKYXNzZXRJZFN0cgUGYW1vdW50AwkAAAIFB3N0YWtlVHgFB3N0YWtlVHgDCQAAAgkAzwgCBQhhc3NldElkcwUHYXNzZXRJZAUEdW5pdAkAAgECMHlvdSBjYW4gb25seSBhZGQgaW50ZXJlc3QgZm9yIGFzc2V0cyBpbiB0aGUgcG9vbAQGcGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQUKYXNzZXRJZFN0cgQNaW50ZXJlc3REZWx0YQkBEmNhbGNJbnRlcmVzdENoYW5nZQIFCmFzc2V0SWRTdHIFBmFtb3VudAQJdXBkUGFyYW1zCQCaCggIBQZwYXJhbXMCXzEIBQZwYXJhbXMCXzIIBQZwYXJhbXMCXzMJAGQCCAUGcGFyYW1zAl80BQ1pbnRlcmVzdERlbHRhCQBkAggFBnBhcmFtcwJfNQUGYW1vdW50CAUGcGFyYW1zAl82CAUGcGFyYW1zAl83CAUGcGFyYW1zAl84CQDMCAIJARVzYXZlR2xvYmFsVG9rZW5QYXJhbXMCBQphc3NldElkU3RyBQl1cGRQYXJhbXMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARRub3RpZnlTdGFraW5nUGF5bWVudAIKYXNzZXRJZFN0cgZhbW91bnQEB2Fzc2V0SWQJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgMJAAACCQDPCAIFCGFzc2V0SWRzBQdhc3NldElkBQR1bml0CQACAQIweW91IGNhbiBvbmx5IGFkZCBpbnRlcmVzdCBmb3IgYXNzZXRzIGluIHRoZSBwb29sAwkBAiE9AgkBDHRyeUdldFN0cmluZwEJAKwCAgIXc3RhdGljX3N0YWtpbmdDb250cmFjdF8FCmFzc2V0SWRTdHIJAKUIAQgFAWkGY2FsbGVyCQACAQImY2FuIG9ubHkgYmUgaW52b2tlZCBieSBzdGFrZXIgY29udHJhY3QEBnBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCmFzc2V0SWRTdHIEDWludGVyZXN0RGVsdGEJARJjYWxjSW50ZXJlc3RDaGFuZ2UCBQphc3NldElkU3RyBQZhbW91bnQECXVwZFBhcmFtcwkAmgoICAUGcGFyYW1zAl8xCAUGcGFyYW1zAl8yCAUGcGFyYW1zAl8zCQBkAggFBnBhcmFtcwJfNAUNaW50ZXJlc3REZWx0YQkAZAIIBQZwYXJhbXMCXzUFBmFtb3VudAgFBnBhcmFtcwJfNggFBnBhcmFtcwJfNwgFBnBhcmFtcwJfOAkAzAgCCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUKYXNzZXRJZFN0cgUJdXBkUGFyYW1zBQNuaWwBaQEEc3dhcAIIYXNzZXRPdXQHbWluaW11bQQDcG10AwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAACQACAQIhcGxlYXNlIGF0dGFjaCBleGFjdGx5IG9uZSBwYXltZW50BAhBbW91bnRJbgkBBXZhbHVlAQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEB0Fzc2V0SW4IBQNwbXQHYXNzZXRJZAQIQXNzZXRPdXQJAQ1nZXRBc3NldEJ5dGVzAQUIYXNzZXRPdXQEB2Fzc2V0SW4JAQ5nZXRBc3NldFN0cmluZwEFB0Fzc2V0SW4EB3NjYWxlSW4JAGkCBQZTY2FsZTgJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FB2Fzc2V0SW4CBl9zY2FsZQQIc2NhbGVPdXQJAGkCBQZTY2FsZTgJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgICB3N0YXRpY18FCGFzc2V0T3V0AgZfc2NhbGUEDWFzc2V0SW5QYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBCQEOZ2V0QXNzZXRTdHJpbmcBBQdBc3NldEluBA5hc3NldE91dFBhcmFtcwkBFWxvYWRHbG9iYWxUb2tlblBhcmFtcwEFCGFzc2V0T3V0BA5Bc3NldEluQmFsYW5jZQgFDWFzc2V0SW5QYXJhbXMCXzEEEkFzc2V0SW5GYWN0QmFsYW5jZQgFDWFzc2V0SW5QYXJhbXMCXzIEEWFzc2V0SW5GZWVzRWFybmVkCAUNYXNzZXRJblBhcmFtcwJfMwQYYXNzZXRJbkxhc3RDaGVja0ludGVyZXN0CAUNYXNzZXRJblBhcmFtcwJfNAQPQXNzZXRPdXRCYWxhbmNlCAUOYXNzZXRPdXRQYXJhbXMCXzEEE2Fzc2V0T3V0RmFjdEJhbGFuY2UIBQ5hc3NldE91dFBhcmFtcwJfMgQUQXNzZXRJbkJhbGFuY2VTY2FsZWQJAGgCBQ5Bc3NldEluQmFsYW5jZQUHc2NhbGVJbgQVQXNzZXRPdXRCYWxhbmNlU2NhbGVkCQBoAgUPQXNzZXRPdXRCYWxhbmNlBQhzY2FsZU91dAQLZmVlQW1vdW50SW4JAGsDBQhBbW91bnRJbgUDRmVlBQhGZWVTY2FsZQQNY2xlYW5BbW91bnRJbgkAZQIFCEFtb3VudEluBQtmZWVBbW91bnRJbgQTY2xlYW5BbW91bnRJblNjYWxlZAkAaAIFDWNsZWFuQW1vdW50SW4FB3NjYWxlSW4ECkFtb3VudE91dDEJARJjYWxjdWxhdGVPdXRBbW91bnQFBRNjbGVhbkFtb3VudEluU2NhbGVkBQdBc3NldEluBQhBc3NldE91dAUUQXNzZXRJbkJhbGFuY2VTY2FsZWQFFUFzc2V0T3V0QmFsYW5jZVNjYWxlZAQJQW1vdW50T3V0CQBrAwUKQW1vdW50T3V0MQABBQhzY2FsZU91dAQQQXNzZXRPdXRCYWxhbmNlMgkAZQIFD0Fzc2V0T3V0QmFsYW5jZQUJQW1vdW50T3V0BA9Bc3NldEluQmFsYW5jZTIJAGQCBQ5Bc3NldEluQmFsYW5jZQUNY2xlYW5BbW91bnRJbgMJAGYCBQdtaW5pbXVtBQlBbW91bnRPdXQJAAIBAilhbW91bnQgdG8gcmVjaWV2ZSBpcyBsb3dlciB0aGFuIGdpdmVuIG9uZQMJAAACBQhBc3NldE91dAUHQXNzZXRJbgkAAgECGHRoaXMgc3dhcCBpcyBub3QgYWxsb3dlZAMJAGYCAAAJAGUCBRNhc3NldE91dEZhY3RCYWxhbmNlBQlBbW91bnRPdXQJAAIBAhtjb250cmFjdCBpcyBvdXQgb2YgcmVzZXJ2ZXMDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wAwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQ9wb29sc0h1YkFkZHJlc3MJAKwCAgISZ2xvYmFsX3NodXRkb3duSW5fBQdhc3NldEluBwkAAgECG3Rva2VuIElOIHRyYWRlcyBhcmUgc3RvcHBlZAMJAQt2YWx1ZU9yRWxzZQIJAJsIAgUPcG9vbHNIdWJBZGRyZXNzCQCsAgICE2dsb2JhbF9zaHV0ZG93bk91dF8FCGFzc2V0T3V0BwkAAgECHHRva2VuIE9VVCB0cmFkZXMgYXJlIHN0b3BwZWQEC3Byb3RvY29sRmVlCQBrAwULZmVlQW1vdW50SW4ABQAKBAVscEZlZQkAZQIFC2ZlZUFtb3VudEluBQtwcm90b2NvbEZlZQQNaW50ZXJlc3REZWx0YQkBEmNhbGNJbnRlcmVzdENoYW5nZQIFB2Fzc2V0SW4FBWxwRmVlBAdzdGFrZVR4CQENc3Rha2VJZk5lZWRlZAIFB2Fzc2V0SW4JAGQCBQ1jbGVhbkFtb3VudEluBQVscEZlZQMJAAACBQdzdGFrZVR4BQdzdGFrZVR4BAl1bnN0YWtlVHgJAQ91bnN0YWtlSWZOZWVkZWQCBQhhc3NldE91dAUJQW1vdW50T3V0AwkAAAIFCXVuc3Rha2VUeAUJdW5zdGFrZVR4BAxuZXdCYWxhbmNlSW4FD0Fzc2V0SW5CYWxhbmNlMgQNbmV3QmFsYW5jZU91dAUQQXNzZXRPdXRCYWxhbmNlMgQSYXNzZXRJblNlbGxvZmZEYXRhCQEOdXBkU2VsbG9mZkRhdGEEBQdhc3NldEluBQ1jbGVhbkFtb3VudEluBQ5Bc3NldEluQmFsYW5jZQkAlQoDCAUNYXNzZXRJblBhcmFtcwJfNggFDWFzc2V0SW5QYXJhbXMCXzcIBQ1hc3NldEluUGFyYW1zAl84BBNhc3NldE91dFNlbGxvZmZEYXRhCQEOdXBkU2VsbG9mZkRhdGEEBQhhc3NldE91dAkBAS0BBQlBbW91bnRPdXQFD0Fzc2V0T3V0QmFsYW5jZQkAlQoDCAUOYXNzZXRPdXRQYXJhbXMCXzYIBQ5hc3NldE91dFBhcmFtcwJfNwgFDmFzc2V0T3V0UGFyYW1zAl84BBJhc3NldEluRmluYWxQYXJhbXMJAJoKCAUMbmV3QmFsYW5jZUluCQBkAgUSQXNzZXRJbkZhY3RCYWxhbmNlBQ1jbGVhbkFtb3VudEluCQBkAgURYXNzZXRJbkZlZXNFYXJuZWQFBWxwRmVlCQBkAgUYYXNzZXRJbkxhc3RDaGVja0ludGVyZXN0BQ1pbnRlcmVzdERlbHRhCAUNYXNzZXRJblBhcmFtcwJfNQgFEmFzc2V0SW5TZWxsb2ZmRGF0YQJfMQgFEmFzc2V0SW5TZWxsb2ZmRGF0YQJfMggFEmFzc2V0SW5TZWxsb2ZmRGF0YQJfMwQTYXNzZXRPdXRGaW5hbFBhcmFtcwkAmgoIBQ1uZXdCYWxhbmNlT3V0CQBlAgUTYXNzZXRPdXRGYWN0QmFsYW5jZQUJQW1vdW50T3V0CAUOYXNzZXRPdXRQYXJhbXMCXzMIBQ5hc3NldE91dFBhcmFtcwJfNAgFDmFzc2V0T3V0UGFyYW1zAl81CAUTYXNzZXRPdXRTZWxsb2ZmRGF0YQJfMQgFE2Fzc2V0T3V0U2VsbG9mZkRhdGECXzIIBRNhc3NldE91dFNlbGxvZmZEYXRhAl8zBA1hc3NldEluQ2hhbmdlCQEVc2F2ZUdsb2JhbFRva2VuUGFyYW1zAgUHYXNzZXRJbgUSYXNzZXRJbkZpbmFsUGFyYW1zBA5hc3NldE91dENoYW5nZQkBFXNhdmVHbG9iYWxUb2tlblBhcmFtcwIFCGFzc2V0T3V0BRNhc3NldE91dEZpbmFsUGFyYW1zBAtmZWVBc3NldFN0cgkBDHRyeUdldFN0cmluZwECD3N0YXRpY19mZWVUb2tlbgQOZmVlQXNzZXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQtmZWVBc3NldFN0cgQPZmVlVG9rZW5CYWxhbmNlCAUOZmVlQXNzZXRQYXJhbXMCXzEED3ZvbHVtZVVzZFVwZGF0ZQkBEWNhbGN1bGF0ZVVzZFZhbHVlBAUHQXNzZXRJbgUIQW1vdW50SW4FDkFzc2V0SW5CYWxhbmNlBQ9mZWVUb2tlbkJhbGFuY2UJAJQKAgkAzAgCBQ1hc3NldEluQ2hhbmdlCQDMCAIFDmFzc2V0T3V0Q2hhbmdlCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUJQW1vdW50T3V0BQhBc3NldE91dAkAzAgCCQEMSW50ZWdlckVudHJ5AgIRZ2xvYmFsX3ZvbHVtZV91c2QJAGQCCQENdHJ5R2V0SW50ZWdlcgECEWdsb2JhbF92b2x1bWVfdXNkBQ92b2x1bWVVc2RVcGRhdGUJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULZmVlc0FkZHJlc3MFC3Byb3RvY29sRmVlCQENZ2V0QXNzZXRCeXRlcwEFB2Fzc2V0SW4FA25pbAUJQW1vdW50T3V0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDHN3YXBSZWFkT25seQMHYXNzZXRJbghhc3NldE91dAhBbW91bnRJbgQHQXNzZXRJbgkBDWdldEFzc2V0Qnl0ZXMBBQdhc3NldEluBAhBc3NldE91dAkBDWdldEFzc2V0Qnl0ZXMBBQhhc3NldE91dAQHc2NhbGVJbgkAaQIFBlNjYWxlOAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUHYXNzZXRJbgIGX3NjYWxlBAhzY2FsZU91dAkAaQIFBlNjYWxlOAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIHc3RhdGljXwUIYXNzZXRPdXQCBl9zY2FsZQQOZmVlQXNzZXRPdXRTdHIJAQx0cnlHZXRTdHJpbmcBAg9zdGF0aWNfZmVlVG9rZW4EC2ZlZUFzc2V0T3V0AwkAAAIFDmZlZUFzc2V0T3V0U3RyAgAFC3VzZG5Bc3NldElkCQENZ2V0QXNzZXRCeXRlcwEFDmZlZUFzc2V0T3V0U3RyBA1hc3NldEluUGFyYW1zCQEVbG9hZEdsb2JhbFRva2VuUGFyYW1zAQkBDmdldEFzc2V0U3RyaW5nAQUHQXNzZXRJbgQOYXNzZXRPdXRQYXJhbXMJARVsb2FkR2xvYmFsVG9rZW5QYXJhbXMBBQhhc3NldE91dAQOQXNzZXRJbkJhbGFuY2UIBQ1hc3NldEluUGFyYW1zAl8xBBJBc3NldEluRmFjdEJhbGFuY2UIBQ1hc3NldEluUGFyYW1zAl8yBBFhc3NldEluRmVlc0Vhcm5lZAgFDWFzc2V0SW5QYXJhbXMCXzMEGGFzc2V0SW5MYXN0Q2hlY2tJbnRlcmVzdAgFDWFzc2V0SW5QYXJhbXMCXzQED0Fzc2V0T3V0QmFsYW5jZQgFDmFzc2V0T3V0UGFyYW1zAl8xBBNhc3NldE91dEZhY3RCYWxhbmNlCAUOYXNzZXRPdXRQYXJhbXMCXzIEFEFzc2V0SW5CYWxhbmNlU2NhbGVkCQBoAgUOQXNzZXRJbkJhbGFuY2UFB3NjYWxlSW4EFUFzc2V0T3V0QmFsYW5jZVNjYWxlZAkAaAIFD0Fzc2V0T3V0QmFsYW5jZQUIc2NhbGVPdXQEC2ZlZUFtb3VudEluCQBrAwUIQW1vdW50SW4FA0ZlZQUIRmVlU2NhbGUEDWNsZWFuQW1vdW50SW4JAGUCBQhBbW91bnRJbgULZmVlQW1vdW50SW4EE2NsZWFuQW1vdW50SW5TY2FsZWQJAGgCBQ1jbGVhbkFtb3VudEluBQdzY2FsZUluBApBbW91bnRPdXQxCQESY2FsY3VsYXRlT3V0QW1vdW50BQUTY2xlYW5BbW91bnRJblNjYWxlZAUHQXNzZXRJbgUIQXNzZXRPdXQFFEFzc2V0SW5CYWxhbmNlU2NhbGVkBRVBc3NldE91dEJhbGFuY2VTY2FsZWQECUFtb3VudE91dAkAawMFCkFtb3VudE91dDEAAQUIc2NhbGVPdXQEEEFzc2V0T3V0QmFsYW5jZTIJAGUCBQ9Bc3NldE91dEJhbGFuY2UFCUFtb3VudE91dAQPQXNzZXRJbkJhbGFuY2UyCQBkAgUOQXNzZXRJbkJhbGFuY2UFDWNsZWFuQW1vdW50SW4DCQAAAgUIQXNzZXRPdXQFB0Fzc2V0SW4JAAIBAhh0aGlzIHN3YXAgaXMgbm90IGFsbG93ZWQDCQBmAgAACQBlAggFDmFzc2V0T3V0UGFyYW1zAl8yBQlBbW91bnRPdXQJAAIBAhtjb250cmFjdCBpcyBvdXQgb2YgcmVzZXJ2ZXMDCQEKaXNTaHV0ZG93bgAJAAIBAhNjb250cmFjdCBpcyBvbiBzdG9wCQCUCgIFA25pbAUJQW1vdW50T3V0AWkBEXRyYW5zZmVyT3duZXJzaGlwAQ9uZXdPd25lckFkZHJlc3MDCQECIT0CCQClCAEIBQFpBmNhbGxlcgkBDHRyeUdldFN0cmluZwECEHN0YXRpY19wb29sT3duZXIJAAIBAid0aGlzIGNhbGwgYXZhaWxhYmxlIG9ubHkgZm9yIHBvb2wgb3duZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgIQc3RhdGljX3Bvb2xPd25lcgUPbmV3T3duZXJBZGRyZXNzBQNuaWwBaQEGc2V0RmVlAQZuZXdGZWUDCQECIT0CCQClCAEIBQFpBmNhbGxlcgkBDHRyeUdldFN0cmluZwECEHN0YXRpY19wb29sT3duZXIJAAIBAid0aGlzIGNhbGwgYXZhaWxhYmxlIG9ubHkgZm9yIHBvb2wgb3duZXIJAMwIAgkBDEludGVnZXJFbnRyeQICCnN0YXRpY19mZWUFBm5ld0ZlZQUDbmlsAQJ0eAEGdmVyaWZ5AAkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUMbWFzdGVyUHViS2V5Pjo9UQ==", "height": 335361, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 6g8EumwxjLfD6QW7pSY9g6Dayqp1E8fcUMLGfJPKLcM Next: none Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let VERSION = "PZ-3.6.1 PROD-refactor"
55
66 let configStr = valueOrElse(getString(this, "configAddress"), "3PMoEibdLeWqcURQ8351XhaWwyacDc7G4e5")
77
88 let CONFIG_ADDRESS = if ((configStr == ""))
99 then this
1010 else Address(fromBase58String(configStr))
1111
1212 let AssetsWeightsDecimals = 4
1313
1414 let Scale = 10000
1515
1616 let Scale8 = 100000000
1717
1818 let Scale8_BI = toBigInt(Scale8)
1919
2020 let Scale12 = 1000000000000
2121
2222 let Scale16 = 10000000000000000
2323
2424 let Scale16_BI = toBigInt(Scale16)
2525
2626 let FeeScale = 10000
2727
2828 let PoolTokenDecimals = 8
2929
3030 let PoolTokenScale = pow(10, 0, PoolTokenDecimals, 0, 0, HALFUP)
3131
3232 let MIN_STEPS_AMOUNT = valueOrElse(getInteger(CONFIG_ADDRESS, "min_steps_amount"), 1)
3333
3434 let MAX_STEPS_AMOUNT = valueOrElse(getInteger(CONFIG_ADDRESS, "max_steps_amount"), 500)
3535
3636 let MIN_STEPS_INTERVAL = valueOrElse(getInteger(CONFIG_ADDRESS, "min_steps_interval"), 1)
3737
3838 let MAX_STEPS_INTERVAL = valueOrElse(getInteger(CONFIG_ADDRESS, "max_steps_interval"), 10000)
3939
4040 let MIN_WEIGHT = valueOrElse(getInteger(CONFIG_ADDRESS, "min_weight"), 100)
4141
4242 let MAX_WEIGHT = valueOrElse(getInteger(CONFIG_ADDRESS, "max_weight"), 9900)
4343
4444 func tryGetInteger (key) = match getInteger(this, key) {
4545 case b: Int =>
4646 b
4747 case _ =>
4848 0
4949 }
5050
5151
5252 func tryGetBinary (key) = match getBinary(this, key) {
5353 case b: ByteVector =>
5454 b
5555 case _ =>
5656 base58''
5757 }
5858
5959
6060 func tryGetString (key) = match getString(this, key) {
6161 case b: String =>
6262 b
6363 case _ =>
6464 ""
6565 }
6666
6767
6868 func tryGetStringOrThrow (key) = match getString(this, key) {
6969 case b: String =>
7070 b
7171 case _ =>
7272 throw(("no such key in data storage: " + key))
7373 }
7474
7575
7676 func getAssetString (assetId) = match assetId {
7777 case b: ByteVector =>
7878 toBase58String(b)
7979 case _ =>
8080 "WAVES"
8181 }
8282
8383
8484 func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
8585 then unit
8686 else fromBase58String(assetIdStr)
8787
8888
8989 func getTokenBalance (assetId) = match assetId {
9090 case t: ByteVector =>
9191 assetBalance(this, t)
9292 case _ =>
9393 wavesBalance(this).available
9494 }
9595
9696
9797 func addAssetBytesToList (accum,item) = (accum ++ [getAssetBytes(item)])
9898
9999
100100 func addAssetWeightToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_weight"))])
101101
102102
103103 func addAssetWeightToStrList (accum,item) = (accum ++ [toString(tryGetInteger((("static_" + item) + "_weight")))])
104104
105105
106106 func addAssetDecimalsToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_decimals"))])
107107
108108
109109 func addAssetScaleToList (accum,item) = (accum ++ [tryGetInteger((("static_" + getAssetString(item)) + "_scale"))])
110110
111111
112112 func addIntToList (accum,item) = (accum ++ [parseIntValue(item)])
113113
114114
115115 func parstStrToIntList (s) = {
116116 func f (accum,next) = (accum ++ [parseIntValue(next)])
117117
118118 let $l = split(s, ",")
119119 let $s = size($l)
120120 let $acc0 = nil
121121 func $f0_1 ($a,$i) = if (($i >= $s))
122122 then $a
123123 else f($a, $l[$i])
124124
125125 func $f0_2 ($a,$i) = if (($i >= $s))
126126 then $a
127127 else throw("List size exceeds 10")
128128
129129 $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)
130130 }
131131
132132
133133 let usdnAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdnAssetIdStr"), "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
134134
135135 let puzzleAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "puzzleAssetIdStr"), "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS")
136136
137137 let usdtAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdtAssetIdStr"), "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ")
138138
139139 let usdtPptAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdtPptAssetIdStr"), "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi")
140140
141141 let romeAssetIdStr = valueOrElse(getString(CONFIG_ADDRESS, "romeAssetIdStr"), "AP4Cb5xLYGH6ZigHreCZHoXpQTWDkPsG2BHqfDUx6taJ")
142142
143143 let wavesAssetIdStr = "WAVES"
144144
145145 let usdnAssetId = fromBase58String(usdnAssetIdStr)
146146
147147 let puzzleAssetId = fromBase58String(puzzleAssetIdStr)
148148
149149 let usdtAssetId = fromBase58String(usdtAssetIdStr)
150150
151151 let usdtPptAssetId = fromBase58String(usdtPptAssetIdStr)
152152
153153 let romeAssetId = fromBase58String(romeAssetIdStr)
154154
155155 let wavesAssetId = unit
156156
157157 let supportedFeeAssetsStr = [usdnAssetIdStr, puzzleAssetIdStr, usdtAssetIdStr, usdtPptAssetIdStr, wavesAssetIdStr, romeAssetIdStr]
158158
159159 let parentPoolAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "parentPoolAddress"), "3PFDgzu1UtswAkCMxqqQjbTeHaX4cMab8Kh")))
160160
161161 let masterAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "masterAddress"), "3PLjwHcz9NEuaTo63NZR9B9okQiKQxZSbmf")))
162162
163163 let masterPubKey = fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "masterPubKey"), "2jTJGqHSopyj5d1cjbUe6f2jXqGMHE412cy3vGwYoRbP"))
164164
165165 let oracleAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "oracleAddress"), "3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t")))
166166
167167 let stakingAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "stakingAddress"), "3PFTbywqxtFfukX3HyT881g4iW5K4QL3FAS")))
168168
169169 let feesAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "feesAddress"), "3PFWAVKmXjfHXyzJb12jCbhP4Uhi9t4uWiD")))
170170
171171 let poolsHubAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "poolsHubAddress"), "3P5RGYyCnELF8JTPxgX54dBGzwkQMKUJ5H7")))
172172
173173 let shutdownAddressStr = valueOrElse(getString(CONFIG_ADDRESS, "shutdownAddress"), "3PEpv9hRFWEEBU22WRnLsw1bH4YGtcU728o")
174174
175175 let layer2Addresses = valueOrElse(getString(CONFIG_ADDRESS, "layer2Addresses"), "3PR1Qvi9mHT35SwWEkLSqqE2L8thiPLdVWU,3PQoBfUKHkJAeGWhooLP7WS8ovb54av9Jp2")
176176
177177 let govAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "govAddress"), "3P6uro9xCsE8te78QZjzqy7aq8natSzdceC")))
178178
179179 let coldMasterAddress = Address(fromBase58String(valueOrElse(getString(CONFIG_ADDRESS, "coldMasterAddress"), "3PK9nhPfPbMBygB9ZgHVMHaQbSoojwrBfxj")))
180180
181181 let T = tryGetInteger("static_tokensAmount")
182182
183183 let assetIds = {
184184 let $l = split(tryGetString("static_tokenIds"), ",")
185185 let $s = size($l)
186186 let $acc0 = nil
187187 func $f0_1 ($a,$i) = if (($i >= $s))
188188 then $a
189189 else addAssetBytesToList($a, $l[$i])
190190
191191 func $f0_2 ($a,$i) = if (($i >= $s))
192192 then $a
193193 else throw("List size exceeds 10")
194194
195195 $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)
196196 }
197197
198198 let AssetsWeights = {
199199 let $l = assetIds
200200 let $s = size($l)
201201 let $acc0 = nil
202202 func $f1_1 ($a,$i) = if (($i >= $s))
203203 then $a
204204 else addAssetWeightToList($a, $l[$i])
205205
206206 func $f1_2 ($a,$i) = if (($i >= $s))
207207 then $a
208208 else throw("List size exceeds 10")
209209
210210 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
211211 }
212212
213213 let Decimals = {
214214 let $l = assetIds
215215 let $s = size($l)
216216 let $acc0 = nil
217217 func $f2_1 ($a,$i) = if (($i >= $s))
218218 then $a
219219 else addAssetDecimalsToList($a, $l[$i])
220220
221221 func $f2_2 ($a,$i) = if (($i >= $s))
222222 then $a
223223 else throw("List size exceeds 10")
224224
225225 $f2_2($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($f2_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
226226 }
227227
228228 let Scales = {
229229 let $l = assetIds
230230 let $s = size($l)
231231 let $acc0 = nil
232232 func $f3_1 ($a,$i) = if (($i >= $s))
233233 then $a
234234 else addAssetScaleToList($a, $l[$i])
235235
236236 func $f3_2 ($a,$i) = if (($i >= $s))
237237 then $a
238238 else throw("List size exceeds 10")
239239
240240 $f3_2($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($f3_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
241241 }
242242
243243 let Fee = tryGetInteger("static_fee")
244244
245245 let earnedAssets = assetIds
246246
247247 func _get (assetId,param) = tryGetInteger(((("global_" + assetId) + "_") + param))
248248
249249
250250 func _get_feesEarned (assetId) = tryGetInteger(("global_feesEarned_" + assetId))
251251
252252
253253 func _get_lastCheck_interest (assetId) = tryGetInteger((("global_lastCheck_" + assetId) + "_interest"))
254254
255255
256256 func _get_extraEarned (assetId) = tryGetInteger(("global_extraEarned_" + assetId))
257257
258258
259259 func loadGlobalTokenParams (assetId) = match getString(("globalParams_" + assetId)) {
260260 case p: String =>
261261 let params = split(p, "__")
262262 $Tuple8(parseIntValue(params[0]), parseIntValue(params[1]), parseIntValue(params[2]), parseIntValue(params[3]), parseIntValue(params[4]), parseIntValue(params[5]), parseIntValue(params[6]), parseIntValue(params[7]))
263263 case _ =>
264264 $Tuple8(_get(assetId, "balance"), _get(assetId, "factBalance"), _get_feesEarned(assetId), _get_lastCheck_interest(assetId), _get_extraEarned(assetId), _get(assetId, "selloff"), _get(assetId, "selloffStartBalance"), _get(assetId, "selloffStartHeight"))
265265 }
266266
267267
268268 func saveGlobalTokenParams (assetId,params) = StringEntry(("globalParams_" + assetId), makeString([toString(params._1), toString(params._2), toString(params._3), toString(params._4), toString(params._5), toString(params._6), toString(params._7), toString(params._8)], "__"))
269269
270270
271271 func isShutdown () = {
272272 let shutdownAddress = addressFromString(shutdownAddressStr)
273273 if ((shutdownAddress == unit))
274274 then false
275275 else match getBoolean(value(shutdownAddress), "is_shutdown") {
276276 case x: Boolean =>
277277 x
278278 case _ =>
279279 false
280280 }
281281 }
282282
283283
284284 func getFactBalance (assetIdStr) = {
285285 let assetParams = loadGlobalTokenParams(assetIdStr)
286286 assetParams._2
287287 }
288288
289289
290290 func getCurrentTokenBalance (tokenNum) = {
291291 let tokenIdStr = getAssetString(assetIds[tokenNum])
292292 let tokenParams = loadGlobalTokenParams(tokenIdStr)
293293 tokenParams._1
294294 }
295295
296296
297297 func stakeIfNeeded (assetIdStr,amount) = {
298298 let stakeTx = if ((tryGetString(("static_stakingContract_" + assetIdStr)) != ""))
299299 then invoke(addressFromStringValue(tryGetString(("static_stakingContract_" + assetIdStr))), "stake", nil, [AttachedPayment(getAssetBytes(assetIdStr), amount)])
300300 else unit
301301 if ((stakeTx == stakeTx))
302302 then true
303303 else throw("Strict value is not equal to itself.")
304304 }
305305
306306
307307 func unstakeIfNeeded (assetIdStr,amount) = {
308308 let unstakeTx = if ((tryGetString(("static_stakingContract_" + assetIdStr)) != ""))
309309 then invoke(addressFromStringValue(tryGetString(("static_stakingContract_" + assetIdStr))), "unstake", [amount], nil)
310310 else unit
311311 if ((unstakeTx == unstakeTx))
312312 then true
313313 else throw("Strict value is not equal to itself.")
314314 }
315315
316316
317317 func burnIndexIfNeeded (amount) = {
318318 let indexIdStr = tryGetString("static_poolToken_idStr")
319319 if ((indexIdStr == ""))
320320 then nil
321321 else if ((assetInfo(fromBase58String(indexIdStr)) == unit))
322322 then nil
323323 else [Burn(fromBase58String(indexIdStr), amount)]
324324 }
325325
326326
327327 func mintIndexIfNeeded (amount) = {
328328 let indexIdStr = tryGetString("static_poolToken_idStr")
329329 if ((indexIdStr == ""))
330330 then nil
331331 else if ((assetInfo(fromBase58String(indexIdStr)) == unit))
332332 then nil
333333 else [Reissue(fromBase58String(indexIdStr), amount, true)]
334334 }
335335
336336
337337 func getKMult () = match getInteger("static_KMult") {
338338 case x: Int =>
339339 x
340340 case _ =>
341341 Scale16
342342 }
343343
344344
345345 func saveCurrentWeights () = {
346346 let assetIdsLi = split(tryGetString("static_tokenIds"), ",")
347347 func s (accum,assetId) = (accum ++ [IntegerEntry(("rebalance_startWeight_" + assetId), tryGetInteger((("static_" + assetId) + "_weight")))])
348348
349349 let $l = assetIdsLi
350350 let $s = size($l)
351351 let $acc0 = nil
352352 func $f4_1 ($a,$i) = if (($i >= $s))
353353 then $a
354354 else s($a, $l[$i])
355355
356356 func $f4_2 ($a,$i) = if (($i >= $s))
357357 then $a
358358 else throw("List size exceeds 10")
359359
360360 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
361361 }
362362
363363
364364 func getVirtualPoolTokenAmount () = fraction(tryGetInteger("global_poolToken_amount"), getKMult(), Scale16)
365365
366366
367367 func calculatePIssued (amount,tokenId) = {
368368 let Psupply = getVirtualPoolTokenAmount()
369369 let Balance = getFactBalance(getAssetString(tokenId))
370370 let t1 = fraction(amount, Psupply, Balance, DOWN)
371371 t1
372372 }
373373
374374
375375 func getMinPIssued (payments) = {
376376 func handler (accum,current) = if ((getFactBalance(getAssetString(current.assetId)) == 0))
377377 then accum
378378 else {
379379 let PIssued = calculatePIssued(current.amount, current.assetId)
380380 if ((PIssued == 0))
381381 then throw("one of the tokens amounts is too low")
382382 else if (if ((accum == 0))
383383 then true
384384 else (accum > PIssued))
385385 then PIssued
386386 else accum
387387 }
388388
389389 let minPIssed = {
390390 let $l = payments
391391 let $s = size($l)
392392 let $acc0 = 0
393393 func $f4_1 ($a,$i) = if (($i >= $s))
394394 then $a
395395 else handler($a, $l[$i])
396396
397397 func $f4_2 ($a,$i) = if (($i >= $s))
398398 then $a
399399 else throw("List size exceeds 10")
400400
401401 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
402402 }
403403 minPIssed
404404 }
405405
406406
407407 func getPriceFromOracle (assetIdStr) = match getInteger(oracleAddress, (assetIdStr + "_twap5B")) {
408408 case x: Int =>
409409 x
410410 case _ =>
411411 0
412412 }
413413
414414
415415 func calculateUsdValue (assetId,amount,aBalance,feeAssetBalance) = {
416416 let assetWeight = tryGetInteger((("static_" + getAssetString(assetId)) + "_weight"))
417417 let feeAssetStr = tryGetString("static_feeToken")
418418 let feeAssetScale = getIntegerValue(this, (("static_" + feeAssetStr) + "_scale"))
419419 let feeAssetNum = value(indexOf(assetIds, getAssetBytes(feeAssetStr)))
420420 let feeAssetWeight = AssetsWeights[feeAssetNum]
421421 let _amount = (toBigInt(amount) * Scale8_BI)
422422 let _feeAssetData = ((toBigInt(feeAssetBalance) * Scale8_BI) / toBigInt(feeAssetWeight))
423423 let _assetData = ((toBigInt(aBalance) * Scale16_BI) / toBigInt(assetWeight))
424424 let valInFeeAsset = toInt(fraction(_amount, _feeAssetData, _assetData))
425425 let feeAssetPrice = getPriceFromOracle(feeAssetStr)
426426 fraction(valInFeeAsset, feeAssetPrice, feeAssetScale)
427427 }
428428
429429
430430 func calcAvgConcentration () = {
431431 func f (accum,next) = {
432432 let assetIdStr = getAssetString(next)
433433 let weight = tryGetInteger((("static_" + assetIdStr) + "_weight"))
434434 let assetParams = loadGlobalTokenParams(assetIdStr)
435435 let assetFactBalance = assetParams._2
436436 let assetVirtBalance = assetParams._1
437437 $Tuple2((accum._1 + fraction(assetFactBalance, weight, assetVirtBalance)), (accum._2 + weight))
438438 }
439439
440440 let $l = assetIds
441441 let $s = size($l)
442442 let $acc0 = $Tuple2(0, 0)
443443 func $f4_1 ($a,$i) = if (($i >= $s))
444444 then $a
445445 else f($a, $l[$i])
446446
447447 func $f4_2 ($a,$i) = if (($i >= $s))
448448 then $a
449449 else throw("List size exceeds 10")
450450
451451 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
452452 }
453453
454454
455455 func checkTokensValidity (payments) = {
456456 func handler1 (accum,payment) = (accum ++ [payment.assetId])
457457
458458 let ids = {
459459 let $l = payments
460460 let $s = size($l)
461461 let $acc0 = nil
462462 func $f4_1 ($a,$i) = if (($i >= $s))
463463 then $a
464464 else handler1($a, $l[$i])
465465
466466 func $f4_2 ($a,$i) = if (($i >= $s))
467467 then $a
468468 else throw("List size exceeds 10")
469469
470470 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
471471 }
472472 if ((ids == ids))
473473 then {
474474 func handler2 (accum,assetId) = if ((indexOf(ids, assetId) != unit))
475475 then (accum + 1)
476476 else throw(("asset not attached: " + getAssetString(assetId)))
477477
478478 let checks = {
479479 let $l = assetIds
480480 let $s = size($l)
481481 let $acc0 = 0
482482 func $f5_1 ($a,$i) = if (($i >= $s))
483483 then $a
484484 else handler2($a, $l[$i])
485485
486486 func $f5_2 ($a,$i) = if (($i >= $s))
487487 then $a
488488 else throw("List size exceeds 10")
489489
490490 $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
491491 }
492492 if ((checks == checks))
493493 then true
494494 else throw("Strict value is not equal to itself.")
495495 }
496496 else throw("Strict value is not equal to itself.")
497497 }
498498
499499
500500 func handlePoolTokensAdd (PIssued,payments,userAddress,needChange) = {
501501 func getTokenPaymentAmount (tokenId) = {
502502 func handler (accum,payment) = if ((payment.assetId == tokenId))
503503 then payment.amount
504504 else accum
505505
506506 let $l = payments
507507 let $s = size($l)
508508 let $acc0 = 0
509509 func $f4_1 ($a,$i) = if (($i >= $s))
510510 then $a
511511 else handler($a, $l[$i])
512512
513513 func $f4_2 ($a,$i) = if (($i >= $s))
514514 then $a
515515 else throw("List size exceeds 10")
516516
517517 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
518518 }
519519
520520 func handleTokenChange (accum,tokenId) = {
521521 let assetIdStr = getAssetString(tokenId)
522522 let assetParams = loadGlobalTokenParams(assetIdStr)
523523 let paymentAmount = getTokenPaymentAmount(tokenId)
524524 let Bk = assetParams._2
525525 let PSupply = getVirtualPoolTokenAmount()
526526 let tokenDecimals = tryGetInteger((("static_" + assetIdStr) + "_scale"))
527527 let a1 = fraction((toBigInt((PSupply + PIssued)) * toBigInt(Scale8)), toBigInt(tokenDecimals), toBigInt(PSupply), CEILING)
528528 let Dk = toInt(fraction((a1 - (toBigInt(tokenDecimals) * toBigInt(Scale8))), toBigInt(Bk), (toBigInt(tokenDecimals) * toBigInt(Scale8)), CEILING))
529529 let toReturn = (paymentAmount - Dk)
530530 let stakeTx = stakeIfNeeded(assetIdStr, Dk)
531531 if ((stakeTx == stakeTx))
532532 then {
533533 let t = if (if (needChange)
534534 then (toReturn > 0)
535535 else false)
536536 then [ScriptTransfer(userAddress, toReturn, tokenId)]
537537 else nil
538538 let selloffStartBalance = if ((assetParams._8 != ((height / 100) * 100)))
539539 then assetParams._7
540540 else fraction(assetParams._7, (PSupply + PIssued), PSupply)
541541 let assetParamsUpd = $Tuple8(fraction(assetParams._1, (PSupply + PIssued), PSupply, HALFEVEN), (assetParams._2 + Dk), assetParams._3, assetParams._4, assetParams._5, assetParams._6, selloffStartBalance, assetParams._8)
542542 ((accum ++ t) ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
543543 }
544544 else throw("Strict value is not equal to itself.")
545545 }
546546
547547 let $l = assetIds
548548 let $s = size($l)
549549 let $acc0 = nil
550550 func $f4_1 ($a,$i) = if (($i >= $s))
551551 then $a
552552 else handleTokenChange($a, $l[$i])
553553
554554 func $f4_2 ($a,$i) = if (($i >= $s))
555555 then $a
556556 else throw("List size exceeds 10")
557557
558558 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
559559 }
560560
561561
562562 func calcMintedWithOneToken (assetAddedIdStr,amount) = {
563563 let PSupply = getVirtualPoolTokenAmount()
564564 let assetParams = loadGlobalTokenParams(assetAddedIdStr)
565565 let assetFactBalance = assetParams._2
566566 let assetVirtBalance = assetParams._1
567567 let assetWeight = tryGetInteger((("static_" + assetAddedIdStr) + "_weight"))
568568 let assetScale = tryGetInteger((("static_" + assetAddedIdStr) + "_scale"))
569569 let assetDecimals = tryGetInteger((("static_" + assetAddedIdStr) + "_decimals"))
570570 let PIssuedNoMultiplier = fraction(PSupply, (toInt(pow(toBigInt((assetScale + fraction(amount, assetScale, assetVirtBalance))), assetDecimals, toBigInt(assetWeight), 4, 8, DOWN)) - Scale8), Scale8)
571571 let avgConc = calcAvgConcentration()
572572 let PIssued = fraction(PIssuedNoMultiplier, avgConc._2, avgConc._1)
573573 let assetParamsUpd = $Tuple8((assetVirtBalance + amount), (assetFactBalance + amount), assetParams._3, assetParams._4, assetParams._5, assetParams._6, assetParams._7, assetParams._8)
574574 $Tuple2([saveGlobalTokenParams(assetAddedIdStr, assetParamsUpd)], PIssued)
575575 }
576576
577577
578578 func calcRedeemWithOneToken (assetOutIdStr,PRedeemed) = {
579579 let PSupply = getVirtualPoolTokenAmount()
580580 let assetParams = loadGlobalTokenParams(assetOutIdStr)
581581 let assetFactBalance = assetParams._2
582582 let assetVirtBalance = assetParams._1
583583 let assetWeight = tryGetInteger((("static_" + assetOutIdStr) + "_weight"))
584584 let assetScale = tryGetInteger((("static_" + assetOutIdStr) + "_scale"))
585585 let assetDecimals = tryGetInteger((("static_" + assetOutIdStr) + "_decimals"))
586586 let amountOutNoMulitplier = fraction(assetVirtBalance, (Scale8 - toInt(pow(toBigInt((assetScale - fraction(PRedeemed, assetScale, PSupply))), assetDecimals, toBigInt(fraction(10000, 10000, assetWeight)), 4, 8, DOWN))), Scale8)
587587 let avgConc = calcAvgConcentration()
588588 let amountOut = fraction(amountOutNoMulitplier, avgConc._1, avgConc._2)
589589 if ((amountOut > assetFactBalance))
590590 then throw("no available fact liquidity to withdraw in one token")
591591 else {
592592 let assetParamsUpd = $Tuple8((assetVirtBalance - amountOut), (assetFactBalance - amountOut), assetParams._3, assetParams._4, assetParams._5, assetParams._6, assetParams._7, assetParams._8)
593593 $Tuple2([saveGlobalTokenParams(assetOutIdStr, assetParamsUpd)], amountOut)
594594 }
595595 }
596596
597597
598598 func handlePoolTokensRedeem (PRedeemed,userAddress) = {
599599 func handleTokenRedeem (accum,tokenId) = {
600600 let assetIdStr = getAssetString(tokenId)
601601 let assetParams = loadGlobalTokenParams(assetIdStr)
602602 let Bk = assetParams._2
603603 let PSupply = getVirtualPoolTokenAmount()
604604 let tokenDecimals = tryGetInteger((("static_" + assetIdStr) + "_scale"))
605605 let psuppl = fraction((toBigInt((PSupply - PRedeemed)) * toBigInt(Scale8)), toBigInt(Scale8), toBigInt(PSupply), DOWN)
606606 let amount = toInt(fraction((toBigInt(Scale16) - psuppl), toBigInt(Bk), toBigInt(Scale16), HALFEVEN))
607607 let unstakeTx = unstakeIfNeeded(assetIdStr, amount)
608608 if ((unstakeTx == unstakeTx))
609609 then {
610610 let selloffStartBalance = if ((assetParams._8 != ((height / 100) * 100)))
611611 then assetParams._7
612612 else fraction(assetParams._7, (PSupply - PRedeemed), PSupply)
613613 let assetParamsUpd = $Tuple8(fraction(assetParams._1, (PSupply - PRedeemed), PSupply), (assetParams._2 - amount), assetParams._3, assetParams._4, assetParams._5, assetParams._6, selloffStartBalance, assetParams._8)
614614 ((accum ++ [ScriptTransfer(userAddress, amount, tokenId)]) ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
615615 }
616616 else throw("Strict value is not equal to itself.")
617617 }
618618
619619 let $l = assetIds
620620 let $s = size($l)
621621 let $acc0 = nil
622622 func $f4_1 ($a,$i) = if (($i >= $s))
623623 then $a
624624 else handleTokenRedeem($a, $l[$i])
625625
626626 func $f4_2 ($a,$i) = if (($i >= $s))
627627 then $a
628628 else throw("List size exceeds 10")
629629
630630 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
631631 }
632632
633633
634634 func calculateOutAmount (AmountIn,assetIn,assetOut,BalanceIn,BalanceOut) = {
635635 let IndexIn = value(indexOf(assetIds, assetIn))
636636 let IndexOut = value(indexOf(assetIds, assetOut))
637637 if ((IndexIn == IndexOut))
638638 then AmountIn
639639 else fraction(BalanceOut, ((Scale8 * Scale8) - toInt(pow(fraction((toBigInt(BalanceIn) * toBigInt(10000)), toBigInt((Scale8 * Scale8)), (toBigInt((BalanceIn + AmountIn)) * toBigInt(10000)), HALFUP), 16, toBigInt(fraction(AssetsWeights[IndexIn], 1000000000000, AssetsWeights[IndexOut])), 12, 16, CEILING))), (Scale8 * Scale8), HALFEVEN)
640640 }
641641
642642
643643 func claimResult (address) = {
644644 let addressStr = toString(address)
645645 let indexAmount = tryGetInteger((addressStr + "_indexStaked"))
646646 let feeAssetStr = tryGetString("static_feeToken")
647647 let feeAssetParams = loadGlobalTokenParams(feeAssetStr)
648648 let feeTokenBalance = feeAssetParams._1
649649 func handler (accum,assetId) = {
650650 let assetIdStr = getAssetString(assetId)
651651 let assetParams = loadGlobalTokenParams(assetIdStr)
652652 let currentTokenInterest = assetParams._4
653653 let aBalance = assetParams._1
654654 let rewardAmount = fraction(indexAmount, (currentTokenInterest - tryGetInteger((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"))), Scale16)
655655 let unstakeInv = unstakeIfNeeded(assetIdStr, rewardAmount)
656656 if ((unstakeInv == unstakeInv))
657657 then {
658658 let transfer = if ((rewardAmount == 0))
659659 then nil
660660 else [ScriptTransfer(address, rewardAmount, assetId)]
661661 $Tuple2(((accum._1 ++ transfer) ++ [IntegerEntry((((addressStr + "_lastCheck_") + assetIdStr) + "_interest"), currentTokenInterest)]), (accum._2 + calculateUsdValue(assetId, rewardAmount, aBalance, feeTokenBalance)))
662662 }
663663 else throw("Strict value is not equal to itself.")
664664 }
665665
666666 let accum = {
667667 let $l = earnedAssets
668668 let $s = size($l)
669669 let $acc0 = $Tuple2(nil, 0)
670670 func $f4_1 ($a,$i) = if (($i >= $s))
671671 then $a
672672 else handler($a, $l[$i])
673673
674674 func $f4_2 ($a,$i) = if (($i >= $s))
675675 then $a
676676 else throw("List size exceeds 10")
677677
678678 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
679679 }
680680 $Tuple2((accum._1 ++ [IntegerEntry((addressStr + "_claimedRewardUSD"), (tryGetInteger((addressStr + "_claimedRewardUSD")) + accum._2)), IntegerEntry((addressStr + "_lastClaim"), lastBlock.timestamp)]), accum._2)
681681 }
682682
683683
684684 func indexStakeResult (addressStr,amount) = {
685685 let li = claimResult(addressFromStringValue(addressStr))._1
686686 (li ++ [IntegerEntry((addressStr + "_indexStaked"), (tryGetInteger((addressStr + "_indexStaked")) + amount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + amount))])
687687 }
688688
689689
690690 func sum (accum,n) = (accum + parseIntValue(n))
691691
692692
693693 func checkFeeAsset (accum,next) = if (if ((indexOf(supportedFeeAssetsStr, next) != unit))
694694 then (accum == "")
695695 else false)
696696 then next
697697 else accum
698698
699699
700700 func calcInterestChange (assetIdStr,lpFee) = {
701701 let totalIndex = tryGetInteger("global_indexStaked")
702702 let interestDelta = fraction(lpFee, Scale16, totalIndex)
703703 interestDelta
704704 }
705705
706706
707707 func updSelloffData (assetIdStr,amountIn,balance,selloffParams) = {
708708 let currentPeriod = ((height / 100) * 100)
709709 let prevPeriod = selloffParams._2
710710 let prevSelloff = if ((currentPeriod == prevPeriod))
711711 then selloffParams._1
712712 else 0
713713 let selloffStartBalance = if ((currentPeriod == prevPeriod))
714714 then selloffParams._3
715715 else balance
716716 let selloffDelta = fraction(Scale16, amountIn, selloffStartBalance)
717717 let maxSelloff = tryGetInteger((("static_" + assetIdStr) + "_maxSelloff"))
718718 if (if (((prevSelloff + selloffDelta) > maxSelloff))
719719 then (maxSelloff != 0)
720720 else false)
721721 then throw(("max selloff reached for this asset " + assetIdStr))
722722 else {
723723 let startH = if ((currentPeriod == prevPeriod))
724724 then prevPeriod
725725 else currentPeriod
726726 let startB = if ((currentPeriod == prevPeriod))
727727 then selloffParams._3
728728 else selloffStartBalance
729729 $Tuple3((prevSelloff + selloffDelta), startH, startB)
730730 }
731731 }
732732
733733
734734 func getTmpRebalanceIds (newAssetIdsLi) = {
735735 let currentAssetIdsLi = split(tryGetString("static_tokenIds"), ",")
736736 let result = newAssetIdsLi
737737 func f (accum,assetId) = if ((indexOf(result, assetId) == unit))
738738 then (accum ++ [assetId])
739739 else accum
740740
741741 let $l = currentAssetIdsLi
742742 let $s = size($l)
743743 let $acc0 = result
744744 func $f4_1 ($a,$i) = if (($i >= $s))
745745 then $a
746746 else f($a, $l[$i])
747747
748748 func $f4_2 ($a,$i) = if (($i >= $s))
749749 then $a
750750 else throw("List size exceeds 10")
751751
752752 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
753753 }
754754
755755
756756 func checkTokensChange (newAssetIdsLi) = {
757757 let currentAssetIdsLi = split(tryGetString("static_tokenIds"), ",")
758758 func rem (accum,assetId) = if ((indexOf(newAssetIdsLi, assetId) == unit))
759759 then (accum + 1)
760760 else accum
761761
762762 func add (accum,assetId) = if ((indexOf(currentAssetIdsLi, assetId) == unit))
763763 then (accum + 1)
764764 else accum
765765
766766 let removed = {
767767 let $l = currentAssetIdsLi
768768 let $s = size($l)
769769 let $acc0 = 0
770770 func $f4_1 ($a,$i) = if (($i >= $s))
771771 then $a
772772 else rem($a, $l[$i])
773773
774774 func $f4_2 ($a,$i) = if (($i >= $s))
775775 then $a
776776 else throw("List size exceeds 10")
777777
778778 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
779779 }
780780 let added = {
781781 let $l = newAssetIdsLi
782782 let $s = size($l)
783783 let $acc0 = 0
784784 func $f5_1 ($a,$i) = if (($i >= $s))
785785 then $a
786786 else add($a, $l[$i])
787787
788788 func $f5_2 ($a,$i) = if (($i >= $s))
789789 then $a
790790 else throw("List size exceeds 10")
791791
792792 $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
793793 }
794794 (removed + added)
795795 }
796796
797797
798798 func validatePayments (assetsList,payments) = {
799799 func getPaymentAssets (accum,next) = if ((0 >= next.amount))
800800 then throw(((("Too low payment amount for " + getAssetString(next.assetId)) + ": ") + toString(next.amount)))
801801 else (accum ++ [getAssetString(next.assetId)])
802802
803803 let paymentList = {
804804 let $l = payments
805805 let $s = size($l)
806806 let $acc0 = nil
807807 func $f4_1 ($a,$i) = if (($i >= $s))
808808 then $a
809809 else getPaymentAssets($a, $l[$i])
810810
811811 func $f4_2 ($a,$i) = if (($i >= $s))
812812 then $a
813813 else throw("List size exceeds 10")
814814
815815 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
816816 }
817817 func f1 (accum,next) = if ((indexOf(assetsList, next) == unit))
818818 then throw(((next + " asset is present in payments, but is not in new assets: ") + makeString(assetsList, ",")))
819819 else (accum + 1)
820820
821821 func f2 (accum,next) = if ((indexOf(paymentList, next) == unit))
822822 then throw(((next + " asset is present in new assets, but is not in payments: ") + makeString(paymentList, ",")))
823823 else (accum + 1)
824824
825825 let a1 = {
826826 let $l = paymentList
827827 let $s = size($l)
828828 let $acc0 = 0
829829 func $f5_1 ($a,$i) = if (($i >= $s))
830830 then $a
831831 else f1($a, $l[$i])
832832
833833 func $f5_2 ($a,$i) = if (($i >= $s))
834834 then $a
835835 else throw("List size exceeds 10")
836836
837837 $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
838838 }
839839 let a2 = {
840840 let $l = assetsList
841841 let $s = size($l)
842842 let $acc0 = 0
843843 func $f6_1 ($a,$i) = if (($i >= $s))
844844 then $a
845845 else f2($a, $l[$i])
846846
847847 func $f6_2 ($a,$i) = if (($i >= $s))
848848 then $a
849849 else throw("List size exceeds 10")
850850
851851 $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
852852 }
853853 (a1 + a2)
854854 }
855855
856856
857857 func validateWeights (weights) = {
858858 func v (accum,w) = {
859859 let wInt = valueOrErrorMessage(parseInt(w), ("Wrong weight format: " + w))
860860 if (if ((MIN_WEIGHT > wInt))
861861 then true
862862 else (wInt > MAX_WEIGHT))
863863 then throw(((((("Weight should be in range " + toString(MIN_WEIGHT)) + " - ") + toString(MAX_WEIGHT)) + ", current: ") + w))
864864 else (accum + wInt)
865865 }
866866
867867 let $l = weights
868868 let $s = size($l)
869869 let $acc0 = 0
870870 func $f4_1 ($a,$i) = if (($i >= $s))
871871 then $a
872872 else v($a, $l[$i])
873873
874874 func $f4_2 ($a,$i) = if (($i >= $s))
875875 then $a
876876 else throw("List size exceeds 10")
877877
878878 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
879879 }
880880
881881
882882 func getP1P2 (assetIdStr,baseAssetIdStr) = {
883883 let assetParams = loadGlobalTokenParams(assetIdStr)
884884 let baseAssetParams = loadGlobalTokenParams(baseAssetIdStr)
885885 let B1 = baseAssetParams._1
886886 let B2 = assetParams._1
887887 let F1 = baseAssetParams._2
888888 let F2 = assetParams._2
889889 let S1 = tryGetInteger((("static_" + baseAssetIdStr) + "_scale"))
890890 let S2 = tryGetInteger((("static_" + assetIdStr) + "_scale"))
891891 let D1 = tryGetInteger((("static_" + baseAssetIdStr) + "_decimals"))
892892 let D2 = tryGetInteger((("static_" + assetIdStr) + "_decimals"))
893893 let W1 = tryGetInteger((("static_" + baseAssetIdStr) + "_weight"))
894894 let W2 = tryGetInteger((("static_" + assetIdStr) + "_weight"))
895895 let W1W2 = fraction(W1, 10000, W2)
896896 let W2W1 = fraction(W2, 10000, W1)
897897 let p1_unweighted = fraction((B1 - F1), S1, fraction(B2, pow(fraction(B1, S1, (B1 - F1)), D1, W1W2, 4, D1, CEILING), S2))
898898 let p1 = fraction(p1_unweighted, W2W1, 10000)
899899 if ((B2 == F2))
900900 then $Tuple2(p1, unit)
901901 else {
902902 let p2_unweighted = fraction(fraction(B1, pow(fraction(B2, S2, (B2 - F2)), D2, W2W1, 4, D2, FLOOR), S2), S2, (B2 - F2))
903903 let p2 = fraction(p2_unweighted, W2W1, 10000)
904904 $Tuple2(p1, p2)
905905 }
906906 }
907907
908908
909909 @Callable(i)
910910 func addUnderlyingStaker (stakerAddress,assetIdStr) = if ((this != i.caller))
911911 then throw("admin only")
912912 else [StringEntry(("static_stakingContract_" + assetIdStr), stakerAddress)]
913913
914914
915915
916916 @Callable(i)
917917 func preInit (assetIdsStr,assetWeightsStr,assetMaxSelloffStr,baseTokenIdStr,poolDomain,poolOwner,fee) = {
918918 let poolOwnerAddress = addressFromStringValue(poolOwner)
919919 let assetIdsStrLi = split(assetIdsStr, ",")
920920 let assetMaxSelloffStrLi = split(assetMaxSelloffStr, ",")
921921 let assetWeightsStrLi = split(assetWeightsStr, ",")
922922 let assetIdsLi = {
923923 let $l = assetIdsStrLi
924924 let $s = size($l)
925925 let $acc0 = nil
926926 func $f4_1 ($a,$i) = if (($i >= $s))
927927 then $a
928928 else addAssetBytesToList($a, $l[$i])
929929
930930 func $f4_2 ($a,$i) = if (($i >= $s))
931931 then $a
932932 else throw("List size exceeds 10")
933933
934934 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
935935 }
936936 let feeAssetChosenStr = {
937937 let $l = assetIdsStrLi
938938 let $s = size($l)
939939 let $acc0 = ""
940940 func $f5_1 ($a,$i) = if (($i >= $s))
941941 then $a
942942 else checkFeeAsset($a, $l[$i])
943943
944944 func $f5_2 ($a,$i) = if (($i >= $s))
945945 then $a
946946 else throw("List size exceeds 10")
947947
948948 $f5_2($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($f5_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
949949 }
950950 let feeAssetStr = if ((feeAssetChosenStr == ""))
951951 then baseTokenIdStr
952952 else feeAssetChosenStr
953953 if (isShutdown())
954954 then throw("contract is on stop")
955955 else if ((this != i.caller))
956956 then throw("admin only")
957957 else if ((size(poolDomain) > 13))
958958 then throw("too large pool domain")
959959 else if (if ((fee > 500))
960960 then true
961961 else (0 > fee))
962962 then throw("fee value must be between 0 and 500 (0-5%)")
963963 else if ((validateWeights(assetWeightsStrLi) != 10000))
964964 then throw(("weights sum should be 10000, current: " + toString(validateWeights(assetWeightsStrLi))))
965965 else {
966966 func addTokenDataEntries (accum,assetNum) = if ((assetNum >= size(assetIdsLi)))
967967 then accum
968968 else {
969969 let assetStakingAddress = {
970970 let @ = invoke(poolsHubAddress, "useEmptyContract", [("staker_" + assetIdsStrLi[assetNum])], nil)
971971 if ($isInstanceOf(@, "String"))
972972 then @
973973 else throw(($getType(@) + " couldn't be cast to String"))
974974 }
975975 if ((assetStakingAddress == assetStakingAddress))
976976 then {
977977 let assetDecimals = match assetIdsLi[assetNum] {
978978 case x: ByteVector =>
979979 value(assetInfo(x)).decimals
980980 case _ =>
981981 8
982982 }
983983 ((accum ++ [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_scale"), pow(10, 0, assetDecimals, 0, 0, DOWN)), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_decimals"), assetDecimals), IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_weight"), value(parseInt(assetWeightsStrLi[assetNum]))), StringEntry(("static_stakingContract_" + assetIdsStrLi[assetNum]), assetStakingAddress)]) ++ (if ((assetMaxSelloffStrLi[assetNum] == ""))
984984 then nil
985985 else [IntegerEntry((("static_" + assetIdsStrLi[assetNum]) + "_maxSelloff"), (parseIntValue(assetMaxSelloffStrLi[assetNum]) * Scale12))]))
986986 }
987987 else throw("Strict value is not equal to itself.")
988988 }
989989
990990 ({
991991 let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
992992 let $s = size($l)
993993 let $acc0 = nil
994994 func $f6_1 ($a,$i) = if (($i >= $s))
995995 then $a
996996 else addTokenDataEntries($a, $l[$i])
997997
998998 func $f6_2 ($a,$i) = if (($i >= $s))
999999 then $a
10001000 else throw("List size exceeds 10")
10011001
10021002 $f6_2($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($f6_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
10031003 } ++ [StringEntry("static_tokenIds", assetIdsStr), StringEntry("static_feeToken", feeAssetStr), StringEntry("static_tokenWeights", assetWeightsStr), IntegerEntry("static_tokensAmount", size(assetIdsLi)), StringEntry("static_poolDomain", poolDomain), StringEntry("static_poolToken_idStr", ""), StringEntry("static_baseTokenId", baseTokenIdStr), StringEntry("static_poolOwner", poolOwner), IntegerEntry("static_fee", fee), IntegerEntry("static_KMult", Scale16), IntegerEntry("global_indexStaked", 0), IntegerEntry("global_poolToken_amount", 0), IntegerEntry("global_wasPreInited", 1)])
10041004 }
10051005 }
10061006
10071007
10081008
10091009 @Callable(i)
10101010 func deInit () = if (isShutdown())
10111011 then throw("contract is on stop")
10121012 else if ((i.caller != this))
10131013 then throw("admin only")
10141014 else [IntegerEntry("global_wasInited", 0)]
10151015
10161016
10171017
10181018 @Callable(i)
10191019 func init (assetIdsStr,assetWeightsStr,assetMaxSelloffStr,baseTokenIdStr,poolDomain,fee,vBalancesStr) = {
10201020 let preInitInv = invoke(this, "preInit", [assetIdsStr, assetWeightsStr, assetMaxSelloffStr, baseTokenIdStr, poolDomain, toString(i.caller), fee], nil)
10211021 if ((preInitInv == preInitInv))
10221022 then {
10231023 let vBalances = parstStrToIntList(vBalancesStr)
10241024 func getPaymentAmount (assetIdStr) = {
10251025 func handler (accum,payment) = if ((getAssetString(payment.assetId) == assetIdStr))
10261026 then payment.amount
10271027 else accum
10281028
10291029 let $l = i.payments
10301030 let $s = size($l)
10311031 let $acc0 = 0
10321032 func $f4_1 ($a,$i) = if (($i >= $s))
10331033 then $a
10341034 else handler($a, $l[$i])
10351035
10361036 func $f4_2 ($a,$i) = if (($i >= $s))
10371037 then $a
10381038 else throw("List size exceeds 10")
10391039
10401040 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
10411041 }
10421042
10431043 func prepareList () = {
10441044 func handler (accum,assetId) = {
10451045 let assetIdStr = getAssetString(assetId)
10461046 let n = value(indexOf(assetIds, assetId))
10471047 let paymentAmount = getPaymentAmount(assetIdStr)
10481048 let assetParams = loadGlobalTokenParams(assetIdStr)
10491049 let assetParamsUpd = $Tuple8(vBalances[n], paymentAmount, assetParams._3, assetParams._4, assetParams._5, assetParams._6, assetParams._7, assetParams._8)
10501050 (accum ++ [saveGlobalTokenParams(assetIdStr, assetParamsUpd)])
10511051 }
10521052
10531053 let $l = assetIds
10541054 let $s = size($l)
10551055 let $acc0 = nil
10561056 func $f4_1 ($a,$i) = if (($i >= $s))
10571057 then $a
10581058 else handler($a, $l[$i])
10591059
10601060 func $f4_2 ($a,$i) = if (($i >= $s))
10611061 then $a
10621062 else throw("List size exceeds 10")
10631063
10641064 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
10651065 }
10661066
10671067 func calculatePoolTokensAmount (assetId) = {
10681068 func handler (accum,assetId) = {
10691069 func handler2 (accum,n) = if ((n == assetId))
10701070 then value(indexOf(assetIds, n))
10711071 else accum
10721072
10731073 let Token = {
10741074 let $l = assetIds
10751075 let $s = size($l)
10761076 let $acc0 = 1
10771077 func $f4_1 ($a,$i) = if (($i >= $s))
10781078 then $a
10791079 else handler2($a, $l[$i])
10801080
10811081 func $f4_2 ($a,$i) = if (($i >= $s))
10821082 then $a
10831083 else throw("List size exceeds 10")
10841084
10851085 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
10861086 }
10871087 fraction(accum, pow(vBalances[Token], Decimals[Token], AssetsWeights[Token], AssetsWeightsDecimals, 8, FLOOR), Scale8)
10881088 }
10891089
10901090 let $l = assetIds
10911091 let $s = size($l)
10921092 let $acc0 = PoolTokenScale
10931093 func $f4_1 ($a,$i) = if (($i >= $s))
10941094 then $a
10951095 else handler($a, $l[$i])
10961096
10971097 func $f4_2 ($a,$i) = if (($i >= $s))
10981098 then $a
10991099 else throw("List size exceeds 10")
11001100
11011101 $f4_2($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($f4_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
11021102 }
11031103
11041104 if (isShutdown())
11051105 then throw("contract is on stop")
11061106 else if ((size(i.payments) == 0))
11071107 then throw("at least some of the assets should be provided as payment")
11081108 else if ((tryGetInteger("global_wasInited") > 0))
11091109 then throw("pool already inited")
11101110 else {
11111111 let initialPoolTokens = calculatePoolTokensAmount(assetIds)
11121112 let notifyInvoke = invoke(poolsHubAddress, "addSelfPool", nil, nil)
11131113 if ((notifyInvoke == notifyInvoke))
11141114 then if ((initialPoolTokens == 0))
11151115 then throw("you need a bigger tokens amount to launch the pool")
11161116 else (prepareList() ++ [IntegerEntry("global_poolToken_amount", initialPoolTokens), IntegerEntry("global_wasInited", 1), IntegerEntry((toString(i.caller) + "_indexStaked"), initialPoolTokens), IntegerEntry("global_indexStaked", initialPoolTokens)])
11171117 else throw("Strict value is not equal to itself.")
11181118 }
11191119 }
11201120 else throw("Strict value is not equal to itself.")
11211121 }
11221122
11231123
11241124
11251125 @Callable(i)
11261126 func generateIndex (needChange) = if ((size(i.payments) != T))
11271127 then throw(("you need to attach all pool tokens. amount of pool tokens: " + toString(T)))
11281128 else if (!(checkTokensValidity(i.payments)))
11291129 then throw("wrong assets attached")
11301130 else {
11311131 let PIssuedNoMult = getMinPIssued(i.payments)
11321132 let result = handlePoolTokensAdd(PIssuedNoMult, i.payments, i.originCaller, needChange)
11331133 let PIssuedWithMult = fraction(PIssuedNoMult, Scale16, getKMult(), DOWN)
11341134 $Tuple2((((result ++ claimResult(i.caller)._1) ++ mintIndexIfNeeded(PIssuedWithMult)) ++ [IntegerEntry((toString(i.caller) + "_indexStaked"), (tryGetInteger((toString(i.caller) + "_indexStaked")) + PIssuedWithMult)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") + PIssuedWithMult)), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") + PIssuedWithMult))]), PIssuedWithMult)
11351135 }
11361136
11371137
11381138
11391139 @Callable(i)
11401140 func redeemIndex (poolTokenAmount) = if ((poolTokenAmount > tryGetInteger((toString(i.caller) + "_indexStaked"))))
11411141 then throw("user doesn't have this amount of pool tokens")
11421142 else if (isShutdown())
11431143 then throw("contract is on stop")
11441144 else {
11451145 let PRedeemedWithMult = poolTokenAmount
11461146 let PRedeemedWithNoMult = fraction(PRedeemedWithMult, getKMult(), Scale16, DOWN)
11471147 let result = handlePoolTokensRedeem(PRedeemedWithNoMult, i.caller)
11481148 (((result ++ claimResult(i.caller)._1) ++ [IntegerEntry((toString(i.caller) + "_indexStaked"), (tryGetInteger((toString(i.caller) + "_indexStaked")) - PRedeemedWithMult)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - PRedeemedWithMult)), IntegerEntry("global_poolToken_amount", (tryGetInteger("global_poolToken_amount") - PRedeemedWithMult))]) ++ burnIndexIfNeeded(poolTokenAmount))
11491149 }
11501150
11511151
11521152
11531153 @Callable(i)
11541154 func stakeIndex () = {
11551155 let addressStr = toString(i.originCaller)
11561156 let pmt = i.payments[0]
11571157 if ((value(pmt.assetId) != fromBase58String(tryGetString("static_poolToken_idStr"))))
11581158 then throw("wrong asset attached")
11591159 else indexStakeResult(addressStr, pmt.amount)
11601160 }
11611161
11621162
11631163
11641164 @Callable(i)
11651165 func stakeIndexFor (addressStr) = {
11661166 let pmt = i.payments[0]
11671167 if ((value(pmt.assetId) != fromBase58String(tryGetString("static_poolToken_idStr"))))
11681168 then throw("wrong asset attached")
11691169 else indexStakeResult(addressStr, pmt.amount)
11701170 }
11711171
11721172
11731173
11741174 @Callable(i)
11751175 func unstakeIndex (indexAmount) = {
11761176 func issueIndex () = {
11771177 let issue = Issue(("PR " + tryGetString("static_poolDomain")), "Puzzle Range Index", tryGetInteger("global_poolToken_amount"), PoolTokenDecimals, true, unit, 0)
11781178 let poolTokenIdStr = toBase58String(calculateAssetId(issue))
11791179 $Tuple2([issue, StringEntry("static_poolToken_idStr", poolTokenIdStr)], poolTokenIdStr)
11801180 }
11811181
11821182 let $t04043240598 = if ((tryGetString("static_poolToken_idStr") == ""))
11831183 then issueIndex()
11841184 else $Tuple2(nil, tryGetString("static_poolToken_idStr"))
11851185 let poolTokenIssueResult = $t04043240598._1
11861186 let poolTokenIdStr = $t04043240598._2
11871187 let poolTokenId = fromBase58String(poolTokenIdStr)
11881188 let addressStr = toString(i.caller)
11891189 let indexAvailable = tryGetInteger((addressStr + "_indexStaked"))
11901190 if (isShutdown())
11911191 then throw("contract is on stop")
11921192 else if ((indexAmount > indexAvailable))
11931193 then throw("you don't have index tokens available")
11941194 else if (isShutdown())
11951195 then throw("contract is on stop")
11961196 else ((poolTokenIssueResult ++ claimResult(addressFromStringValue(addressStr))._1) ++ [IntegerEntry((addressStr + "_indexStaked"), (indexAvailable - indexAmount)), IntegerEntry("global_indexStaked", (tryGetInteger("global_indexStaked") - indexAmount)), ScriptTransfer(i.caller, indexAmount, poolTokenId)])
11971197 }
11981198
11991199
12001200
12011201 @Callable(i)
12021202 func claimIndexRewards () = if (isShutdown())
12031203 then throw("contract is on stop")
12041204 else claimResult(i.caller)
12051205
12061206
12071207
12081208 @Callable(i)
12091209 func evaluateClaim (user) = $Tuple2(nil, claimResult(addressFromStringValue(user))._2)
12101210
12111211
12121212
12131213 @Callable(i)
12141214 func addInterestExternal () = {
12151215 let assetId = value(i.payments[0]).assetId
12161216 let assetIdStr = getAssetString(assetId)
12171217 let amount = i.payments[0].amount
12181218 let stakeTx = stakeIfNeeded(assetIdStr, amount)
12191219 if ((stakeTx == stakeTx))
12201220 then if ((indexOf(assetIds, assetId) == unit))
12211221 then throw("you can only add interest for assets in the pool")
12221222 else {
12231223 let params = loadGlobalTokenParams(assetIdStr)
12241224 let interestDelta = calcInterestChange(assetIdStr, amount)
12251225 let updParams = $Tuple8(params._1, params._2, params._3, (params._4 + interestDelta), (params._5 + amount), params._6, params._7, params._8)
12261226 [saveGlobalTokenParams(assetIdStr, updParams)]
12271227 }
12281228 else throw("Strict value is not equal to itself.")
12291229 }
12301230
12311231
12321232
12331233 @Callable(i)
12341234 func notifyStakingPayment (assetIdStr,amount) = {
12351235 let assetId = getAssetBytes(assetIdStr)
12361236 if ((indexOf(assetIds, assetId) == unit))
12371237 then throw("you can only add interest for assets in the pool")
12381238 else if ((tryGetString(("static_stakingContract_" + assetIdStr)) != toString(i.caller)))
12391239 then throw("can only be invoked by staker contract")
12401240 else {
12411241 let params = loadGlobalTokenParams(assetIdStr)
12421242 let interestDelta = calcInterestChange(assetIdStr, amount)
12431243 let updParams = $Tuple8(params._1, params._2, params._3, (params._4 + interestDelta), (params._5 + amount), params._6, params._7, params._8)
12441244 [saveGlobalTokenParams(assetIdStr, updParams)]
12451245 }
12461246 }
12471247
12481248
12491249
12501250 @Callable(i)
12511251 func swap (assetOut,minimum) = {
12521252 let pmt = if ((size(i.payments) == 1))
12531253 then value(i.payments[0])
12541254 else throw("please attach exactly one payment")
12551255 let AmountIn = value(i.payments[0].amount)
12561256 let AssetIn = pmt.assetId
12571257 let AssetOut = getAssetBytes(assetOut)
12581258 let assetIn = getAssetString(AssetIn)
12591259 let scaleIn = (Scale8 / tryGetInteger((("static_" + assetIn) + "_scale")))
12601260 let scaleOut = (Scale8 / tryGetInteger((("static_" + assetOut) + "_scale")))
12611261 let assetInParams = loadGlobalTokenParams(getAssetString(AssetIn))
12621262 let assetOutParams = loadGlobalTokenParams(assetOut)
12631263 let AssetInBalance = assetInParams._1
12641264 let AssetInFactBalance = assetInParams._2
12651265 let assetInFeesEarned = assetInParams._3
12661266 let assetInLastCheckInterest = assetInParams._4
12671267 let AssetOutBalance = assetOutParams._1
12681268 let assetOutFactBalance = assetOutParams._2
12691269 let AssetInBalanceScaled = (AssetInBalance * scaleIn)
12701270 let AssetOutBalanceScaled = (AssetOutBalance * scaleOut)
12711271 let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
12721272 let cleanAmountIn = (AmountIn - feeAmountIn)
12731273 let cleanAmountInScaled = (cleanAmountIn * scaleIn)
12741274 let AmountOut1 = calculateOutAmount(cleanAmountInScaled, AssetIn, AssetOut, AssetInBalanceScaled, AssetOutBalanceScaled)
12751275 let AmountOut = fraction(AmountOut1, 1, scaleOut)
12761276 let AssetOutBalance2 = (AssetOutBalance - AmountOut)
12771277 let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
12781278 if ((minimum > AmountOut))
12791279 then throw("amount to recieve is lower than given one")
12801280 else if ((AssetOut == AssetIn))
12811281 then throw("this swap is not allowed")
12821282 else if ((0 > (assetOutFactBalance - AmountOut)))
12831283 then throw("contract is out of reserves")
12841284 else if (isShutdown())
12851285 then throw("contract is on stop")
12861286 else if (valueOrElse(getBoolean(poolsHubAddress, ("global_shutdownIn_" + assetIn)), false))
12871287 then throw("token IN trades are stopped")
12881288 else if (valueOrElse(getBoolean(poolsHubAddress, ("global_shutdownOut_" + assetOut)), false))
12891289 then throw("token OUT trades are stopped")
12901290 else {
12911291 let protocolFee = fraction(feeAmountIn, 5, 10)
12921292 let lpFee = (feeAmountIn - protocolFee)
12931293 let interestDelta = calcInterestChange(assetIn, lpFee)
12941294 let stakeTx = stakeIfNeeded(assetIn, (cleanAmountIn + lpFee))
12951295 if ((stakeTx == stakeTx))
12961296 then {
12971297 let unstakeTx = unstakeIfNeeded(assetOut, AmountOut)
12981298 if ((unstakeTx == unstakeTx))
12991299 then {
13001300 let newBalanceIn = AssetInBalance2
13011301 let newBalanceOut = AssetOutBalance2
13021302 let assetInSelloffData = updSelloffData(assetIn, cleanAmountIn, AssetInBalance, $Tuple3(assetInParams._6, assetInParams._7, assetInParams._8))
13031303 let assetOutSelloffData = updSelloffData(assetOut, -(AmountOut), AssetOutBalance, $Tuple3(assetOutParams._6, assetOutParams._7, assetOutParams._8))
13041304 let assetInFinalParams = $Tuple8(newBalanceIn, (AssetInFactBalance + cleanAmountIn), (assetInFeesEarned + lpFee), (assetInLastCheckInterest + interestDelta), assetInParams._5, assetInSelloffData._1, assetInSelloffData._2, assetInSelloffData._3)
13051305 let assetOutFinalParams = $Tuple8(newBalanceOut, (assetOutFactBalance - AmountOut), assetOutParams._3, assetOutParams._4, assetOutParams._5, assetOutSelloffData._1, assetOutSelloffData._2, assetOutSelloffData._3)
13061306 let assetInChange = saveGlobalTokenParams(assetIn, assetInFinalParams)
13071307 let assetOutChange = saveGlobalTokenParams(assetOut, assetOutFinalParams)
13081308 let feeAssetStr = tryGetString("static_feeToken")
13091309 let feeAssetParams = loadGlobalTokenParams(feeAssetStr)
13101310 let feeTokenBalance = feeAssetParams._1
13111311 let volumeUsdUpdate = calculateUsdValue(AssetIn, AmountIn, AssetInBalance, feeTokenBalance)
13121312 $Tuple2([assetInChange, assetOutChange, ScriptTransfer(i.caller, AmountOut, AssetOut), IntegerEntry("global_volume_usd", (tryGetInteger("global_volume_usd") + volumeUsdUpdate)), ScriptTransfer(feesAddress, protocolFee, getAssetBytes(assetIn))], AmountOut)
13131313 }
13141314 else throw("Strict value is not equal to itself.")
13151315 }
13161316 else throw("Strict value is not equal to itself.")
13171317 }
13181318 }
13191319
13201320
13211321
13221322 @Callable(i)
13231323 func swapReadOnly (assetIn,assetOut,AmountIn) = {
13241324 let AssetIn = getAssetBytes(assetIn)
13251325 let AssetOut = getAssetBytes(assetOut)
13261326 let scaleIn = (Scale8 / tryGetInteger((("static_" + assetIn) + "_scale")))
13271327 let scaleOut = (Scale8 / tryGetInteger((("static_" + assetOut) + "_scale")))
13281328 let feeAssetOutStr = tryGetString("static_feeToken")
13291329 let feeAssetOut = if ((feeAssetOutStr == ""))
13301330 then usdnAssetId
13311331 else getAssetBytes(feeAssetOutStr)
13321332 let assetInParams = loadGlobalTokenParams(getAssetString(AssetIn))
13331333 let assetOutParams = loadGlobalTokenParams(assetOut)
13341334 let AssetInBalance = assetInParams._1
13351335 let AssetInFactBalance = assetInParams._2
13361336 let assetInFeesEarned = assetInParams._3
13371337 let assetInLastCheckInterest = assetInParams._4
13381338 let AssetOutBalance = assetOutParams._1
13391339 let assetOutFactBalance = assetOutParams._2
13401340 let AssetInBalanceScaled = (AssetInBalance * scaleIn)
13411341 let AssetOutBalanceScaled = (AssetOutBalance * scaleOut)
13421342 let feeAmountIn = fraction(AmountIn, Fee, FeeScale)
13431343 let cleanAmountIn = (AmountIn - feeAmountIn)
13441344 let cleanAmountInScaled = (cleanAmountIn * scaleIn)
13451345 let AmountOut1 = calculateOutAmount(cleanAmountInScaled, AssetIn, AssetOut, AssetInBalanceScaled, AssetOutBalanceScaled)
13461346 let AmountOut = fraction(AmountOut1, 1, scaleOut)
13471347 let AssetOutBalance2 = (AssetOutBalance - AmountOut)
13481348 let AssetInBalance2 = (AssetInBalance + cleanAmountIn)
13491349 if ((AssetOut == AssetIn))
13501350 then throw("this swap is not allowed")
13511351 else if ((0 > (assetOutParams._2 - AmountOut)))
13521352 then throw("contract is out of reserves")
13531353 else if (isShutdown())
13541354 then throw("contract is on stop")
13551355 else $Tuple2(nil, AmountOut)
13561356 }
13571357
13581358
13591359
13601360 @Callable(i)
13611361 func transferOwnership (newOwnerAddress) = if ((toString(i.caller) != tryGetString("static_poolOwner")))
13621362 then throw("this call available only for pool owner")
13631363 else [StringEntry("static_poolOwner", newOwnerAddress)]
13641364
13651365
13661366
13671367 @Callable(i)
13681368 func setFee (newFee) = if ((toString(i.caller) != tryGetString("static_poolOwner")))
13691369 then throw("this call available only for pool owner")
13701370 else [IntegerEntry("static_fee", newFee)]
13711371
13721372
13731373 @Verifier(tx)
13741374 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], masterPubKey)
13751375

github/deemru/w8io
87.04 ms