tx · 585yRVUw4LP2txC7iF4XgTP7FiiRpxnUKmXgr9oeB4Ni

3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch:  -0.04300000 Waves

2024.08.25 09:30 [3254025] smart account 3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch > SELF 0.00000000 Waves

{ "type": 13, "id": "585yRVUw4LP2txC7iF4XgTP7FiiRpxnUKmXgr9oeB4Ni", "fee": 4300000, "feeAssetId": null, "timestamp": 1724567470131, "version": 2, "chainId": 84, "sender": "3MsqKJ6o1ABE37676cHHBxJRs6huYTt72ch", "senderPublicKey": "3xjN6fjYDXBGUE1mcRw2Fvr4R6tEZnuJA98QFGF99sXd", "proofs": [ "5DxYaSvd2JdRPN8K46hNp8rHApqhtaTNqELc5puZVWDsrn5XUzNSen7dTWXXCtVZFUazzcwAB9Zn4FuF2ifGy9pH" ], "script": "base64:CAJCCAISBgoECAgIARIHCgUICAEIARIHCgUICAEIARIICgYBCAgBCAESAwoBAhIAEgMKAQgSBgoECBIBARIGCgQIAQgIUAAHSU5UX01BWAD//////////38ABVdBVkVTAIDC1y8AC01JTl9CQUxBTkNFCQBoAgCgnAEFBVdBVkVTAANTRVACASwAD0JMT0NLX0hBU0hfU0laRQAgAAxBRERSRVNTX1NJWkUAGgAUUFVCTElDX0tFWV9IQVNIX1NJWkUAFAAOUk9PVF9IQVNIX1NJWkUAIAAWTUFYX0NMX1RPX0VMX1RSQU5TRkVSUwAQAAl6ZXJvZXNTdHICgAgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwABB0aGlzRXBvY2hEYXRhS2V5Ag10aGlzRXBvY2hEYXRhAAxhbGxNaW5lcnNLZXkCCWFsbE1pbmVycwAObWFpbkNoYWluSWRLZXkCC21haW5DaGFpbklkAA5sYXN0Q2hhaW5JZEtleQILbGFzdENoYWluSWQAF2ZpcnN0VmFsaWRBbHRDaGFpbklkS2V5AhRmaXJzdFZhbGlkQWx0Q2hhaW5JZAAObWluZXJSZXdhcmRLZXkCC21pbmVyUmV3YXJkABlzdGFraW5nQ29udHJhY3RBZGRyZXNzS2V5AhZzdGFraW5nQ29udHJhY3RBZGRyZXNzAApibG9ja01ldGFLAghibG9ja18weAARZmluYWxpemVkQmxvY2tLZXkCDmZpbmFsaXplZEJsb2NrAAp0b2tlbklkS2V5Agd0b2tlbklkABJlbEJyaWRnZUFkZHJlc3NLZXkCD2VsQnJpZGdlQWRkcmVzcwAXbmF0aXZlVHJhbnNmZXJzQ291bnRLZXkCFG5hdGl2ZVRyYW5zZmVyc0NvdW50AQNwYWQBAWkEAXMJAKQDAQUBaQQHJG1hdGNoMAkAsQIBBQFzAwkAAAIAAQUHJG1hdGNoMAkArAICAgcwMDAwMDAwBQFzAwkAAAIAAgUHJG1hdGNoMAkArAICAgYwMDAwMDAFAXMDCQAAAgADBQckbWF0Y2gwCQCsAgICBTAwMDAwBQFzAwkAAAIABAUHJG1hdGNoMAkArAICAgQwMDAwBQFzAwkAAAIABQUHJG1hdGNoMAkArAICAgMwMDAFAXMDCQAAAgAGBQckbWF0Y2gwCQCsAgICAjAwBQFzAwkAAAIABwUHJG1hdGNoMAkArAICAgEwBQFzBQFzARdibG9ja0VsVG9DbFRyYW5zZmVyc0tleQEMYmxvY2tIYXNoSGV4CQCsAgICEmVsVG9DbFRyYW5zZmVyc18weAUMYmxvY2tIYXNoSGV4AQxlcG9jaE1ldGFLZXkBBWVwb2NoCQCsAgICBmVwb2NoXwkBA3BhZAEFBWVwb2NoARRjaGFpbkZpcnN0QmxvY2tJZEtleQEHY2hhaW5JZAkArAICCQCsAgICBWNoYWluCQCkAwEFB2NoYWluSWQCCkZpcnN0QmxvY2sBDGNoYWluTWV0YUtleQEHY2hhaW5JZAkArAICAgZjaGFpbl8JAQNwYWQBBQdjaGFpbklkARJjaGFpbkxhc3RIZWlnaHRLZXkCB2NoYWluSWQFbWluZXIJAKwCAgkArAICCQCsAgICBmNoYWluXwkBA3BhZAEFB2NoYWluSWQCAV8JAKUIAQUFbWluZXIBFGNoYWluRm9ya2VkSGVpZ2h0S2V5AQdjaGFpbklkCQCsAgIJAKwCAgIGY2hhaW5fCQEDcGFkAQUHY2hhaW5JZAIMRm9ya2VkSGVpZ2h0AQ1zdXBwb3J0ZXJzS2V5AQdjaGFpbklkCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAIKU3VwcG9ydGVycwEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQltaW5lckFkZHIJAKwCAgkArAICAgZtaW5lcl8FCW1pbmVyQWRkcgIOX1Jld2FyZEFkZHJlc3MBCm1pbmVyUGtLZXkBDXJld2FyZEFkZHJlc3MJAKwCAgkArAICAghtaW5lcl8weAUNcmV3YXJkQWRkcmVzcwIDX1BLAQ9taW5lckNoYWluSWRLZXkBBW1pbmVyCQCsAgIJAKwCAgIGbWluZXJfCQClCAEFBW1pbmVyAghfQ2hhaW5JZAAUbmF0aXZlVHJhbnNmZXJzQ291bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUXbmF0aXZlVHJhbnNmZXJzQ291bnRLZXkAAAERbmF0aXZlVHJhbnNmZXJLZXkBBWluZGV4CQCsAgICD25hdGl2ZVRyYW5zZmVyXwkApAMBBQVpbmRleAEVbWtOYXRpdmVUcmFuc2ZlckVudHJ5AwVpbmRleBBkZXN0RWxBZGRyZXNzSGV4BmFtb3VudAkBC1N0cmluZ0VudHJ5AgkBEW5hdGl2ZVRyYW5zZmVyS2V5AQUFaW5kZXgJAKwCAgkArAICCQCsAgICAjB4BRBkZXN0RWxBZGRyZXNzSGV4BQNTRVAJAKQDAQUGYW1vdW50ARZlbnN1cmVDb3JyZWN0VHJhbnNmZXJzAxByZWZUcmFuc2ZlckluZGV4DXRyYW5zZmVySW5kZXgMZXhwZWN0UmV3YXJkBAxtYXhUcmFuc2ZlcnMDBQxleHBlY3RSZXdhcmQJAGUCBRZNQVhfQ0xfVE9fRUxfVFJBTlNGRVJTAAEFFk1BWF9DTF9UT19FTF9UUkFOU0ZFUlMED2FjdHVhbFRyYW5zZmVycwkAZQIFDXRyYW5zZmVySW5kZXgFEHJlZlRyYW5zZmVySW5kZXgEC2NoZWNrTnVtYmVyAwkAZgIFD2FjdHVhbFRyYW5zZmVycwUMbWF4VHJhbnNmZXJzCQACAQkArAICCQCsAgIJAKwCAgINQWxsb3dlZCBvbmx5IAkApAMBBQxtYXhUcmFuc2ZlcnMCECB0cmFuc2ZlcnMsIGdvdCAJAKQDAQUPYWN0dWFsVHJhbnNmZXJzBgMJAAACBQtjaGVja051bWJlcgULY2hlY2tOdW1iZXIDCQBnAgUNdHJhbnNmZXJJbmRleAUUbmF0aXZlVHJhbnNmZXJzQ291bnQJAAIBCQCsAgIJAKwCAgkArAICAhVBdHRlbXB0IHRvIHRyYW5zZmVyICMJAKQDAQUNdHJhbnNmZXJJbmRleAIXLiBBdmFpbGFibGUgdHJhbnNmZXJzOiAJAKQDAQUUbmF0aXZlVHJhbnNmZXJzQ291bnQGCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQphbW91bnRHdEVxAwF0BGd0RXEJcXVldWVTaXplAwkAZwIIBQF0BmFtb3VudAUEZ3RFcQYJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhRUcmFuc2ZlcnJpbmcgYW1vdW50IAkApAMBCAUBdAZhbW91bnQCDiBzaG91bGQgYmUgPj0gCQCkAwEFBGd0RXECEyBmb3IgcXVldWUgc2l6ZSBvZiAJAKQDAQUJcXVldWVTaXplAhcuIFRyYW5zZmVyIG1vcmUgb3Igd2FpdAAWc3Rha2luZ0NvbnRyYWN0QWRkcmVzcwQHJG1hdGNoMAkAnQgCBQR0aGlzBRlzdGFraW5nQ29udHJhY3RBZGRyZXNzS2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFAXMJAKwCAgIiaW52YWxpZCBzdGFraW5nIGNvbnRyYWN0IGFkZHJlc3M6IAUBcwkBB0FkZHJlc3MBCQERQGV4dHJOYXRpdmUoMTA1MikCBQR0aGlzBRlzdGFraW5nQ29udHJhY3RBZGRyZXNzS2V5ARFnZW5lcmF0aW5nQmFsYW5jZQEHYWRkcmVzcwQHJG1hdGNoMAkAnQgCBRZzdGFraW5nQ29udHJhY3RBZGRyZXNzCQCsAgICBCVzX18JAKUIAQUHYWRkcmVzcwMJAAECBQckbWF0Y2gwAgZTdHJpbmcEA3N0cgUHJG1hdGNoMAQJcGFyYW1MaXN0CQC1CQIFA3N0cgICX18ECnByZXZIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlwYXJhbUxpc3QAAQQLcHJldkJhbGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlwYXJhbUxpc3QAAgQKbmV4dEhlaWdodAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCXBhcmFtTGlzdAADBAtuZXh0QmFsYW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCXBhcmFtTGlzdAAEAwkAZwIFBmhlaWdodAUKbmV4dEhlaWdodAULbmV4dEJhbGFuY2UDCQBnAgUGaGVpZ2h0BQpwcmV2SGVpZ2h0BQtwcmV2QmFsYW5jZQAAAAABCWNoYWluTWV0YQEHY2hhaW5JZAQBcwkBEUBleHRyTmF0aXZlKDEwNTgpAQkBDGNoYWluTWV0YUtleQEFB2NoYWluSWQEBWl0ZW1zCQC1CQIFAXMFA1NFUAkAlAoCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUFaXRlbXMAAAkAkQMCBQVpdGVtcwABARBta0NoYWluTWV0YUVudHJ5AwdjaGFpbklkDm5ld0NoYWluSGVpZ2h0DGJsb2NrSGFzaEhleAkBC1N0cmluZ0VudHJ5AgkBDGNoYWluTWV0YUtleQEFB2NoYWluSWQJAKwCAgkArAICCQCkAwEFDm5ld0NoYWluSGVpZ2h0BQNTRVAFDGJsb2NrSGFzaEhleAALbWFpbkNoYWluSWQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUObWFpbkNoYWluSWRLZXkAAAALJHQwNTgyMTU4ODcJAQljaGFpbk1ldGEBBQttYWluQ2hhaW5JZAAPbWFpbkNoYWluSGVpZ2h0CAULJHQwNTgyMTU4ODcCXzEAEm1haW5DaGFpbkxhc3RCbG9jawgFCyR0MDU4MjE1ODg3Al8yAQllcG9jaE1ldGEBBWVwb2NoBAckbWF0Y2gwCQCiCAEJAQxlcG9jaE1ldGFLZXkBBQVlcG9jaAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAECWZyYWdtZW50cwkAtQkCBQFzBQNTRVAJAJUKAwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQlmcmFnbWVudHMAAAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCWZyYWdtZW50cwABCQCRAwIFCWZyYWdtZW50cwACBQR1bml0AAskdDA2MTE4NjU4MgQHJG1hdGNoMAkBCWVwb2NoTWV0YQEFBmhlaWdodAMJAAECBQckbWF0Y2gwAhYoQWRkcmVzcywgSW50LCBTdHJpbmcpBAFtBQckbWF0Y2gwBQFtBAckbWF0Y2gxCQCiCAEFEHRoaXNFcG9jaERhdGFLZXkDCQABAgUHJG1hdGNoMQIGU3RyaW5nBBByYXdUaGlzRXBvY2hEYXRhBQckbWF0Y2gxBA10aGlzRXBvY2hEYXRhCQC1CQIFEHJhd1RoaXNFcG9jaERhdGEFA1NFUAQJdGhpc0Vwb2NoCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNdGhpc0Vwb2NoRGF0YQAACQCVCgMDCQAAAgUJdGhpc0Vwb2NoBQZoZWlnaHQJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUNdGhpc0Vwb2NoRGF0YQABBQR1bml0AAACAAkAlQoDBQR1bml0AAACAAAOdGhpc0Vwb2NoTWluZXIIBQskdDA2MTE4NjU4MgJfMQAMdGhpc0Vwb2NoUmVmCAULJHQwNjExODY1ODICXzIAEnRoaXNFcG9jaExhc3RCbG9jawgFCyR0MDYxMTg2NTgyAl8zAAxhbGxNaW5lcnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUMYWxsTWluZXJzS2V5AgAACWFsbE1pbmVycwQHJG1hdGNoMAUMYWxsTWluZXJzU3RyAwkAAAICAAUHJG1hdGNoMAUDbmlsAwkAAQIFByRtYXRjaDACBlN0cmluZwQDcmF3BQckbWF0Y2gwCQC8CQIFA3JhdwUDU0VQCQACAQILTWF0Y2ggZXJyb3IBCWJsb2NrTWV0YQEHYmxvY2tJZAQEbWV0YQkBEUBleHRyTmF0aXZlKDEwNTcpAQkArAICBQpibG9ja01ldGFLBQdibG9ja0lkBAhtZXRhU2l6ZQkAyAEBBQRtZXRhBAtibG9ja0hlaWdodAkAsQkBBQRtZXRhBApibG9ja0Vwb2NoCQCyCQIFBG1ldGEACAQLYmxvY2tQYXJlbnQJAMkBAgkAygECBQRtZXRhABAFD0JMT0NLX0hBU0hfU0laRQQOYmxvY2tHZW5lcmF0b3IJAMkBAgkAygECBQRtZXRhCQBkAgAQBQ9CTE9DS19IQVNIX1NJWkUFDEFERFJFU1NfU0laRQQHY2hhaW5JZAkAsgkCBQRtZXRhCQBkAgkAZAIAEAUPQkxPQ0tfSEFTSF9TSVpFBQxBRERSRVNTX1NJWkUECmJhc2VPZmZzZXQJAGQCCQBkAgAYBQ9CTE9DS19IQVNIX1NJWkUFDEFERFJFU1NfU0laRQQOcmVtYWluaW5nQnl0ZXMJAGUCBQhtZXRhU2l6ZQUKYmFzZU9mZnNldAQXZWxUb0NsVHJhbnNmZXJzUm9vdEhhc2gDCQBnAgUOcmVtYWluaW5nQnl0ZXMFDlJPT1RfSEFTSF9TSVpFCQDJAQIJAMoBAgUEbWV0YQUKYmFzZU9mZnNldAUOUk9PVF9IQVNIX1NJWkUBAAQXbGFzdENsVG9FbFRyYW5zZmVySW5kZXgDAwkAAAIFDnJlbWFpbmluZ0J5dGVzAAgGCQBmAgUOcmVtYWluaW5nQnl0ZXMFDlJPT1RfSEFTSF9TSVpFCQCyCQIFBG1ldGEJAGQCBQpiYXNlT2Zmc2V0CQDIAQEFF2VsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoAP///////////wEJAJkKBwULYmxvY2tIZWlnaHQFCmJsb2NrRXBvY2gFC2Jsb2NrUGFyZW50BQ5ibG9ja0dlbmVyYXRvcgUHY2hhaW5JZAUXZWxUb0NsVHJhbnNmZXJzUm9vdEhhc2gFF2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4ARBta0Jsb2NrTWV0YUVudHJ5BwxibG9ja0hhc2hIZXgLYmxvY2tIZWlnaHQOYmxvY2tQYXJlbnRIZXgOYmxvY2tHZW5lcmF0b3IHY2hhaW5JZBplbFRvQ2xUcmFuc2ZlcnNSb290SGFzaEhleBdsYXN0Q2xUb0VsVHJhbnNmZXJJbmRleAQOYmxvY2tNZXRhQnl0ZXMJAMsBAgkAywECCQDLAQIJAMsBAgkAywECCQDLAQIJAJoDAQULYmxvY2tIZWlnaHQJAJoDAQUGaGVpZ2h0CQDdBAEFDmJsb2NrUGFyZW50SGV4CAUOYmxvY2tHZW5lcmF0b3IFYnl0ZXMJAJoDAQUHY2hhaW5JZAkA3QQBBRplbFRvQ2xUcmFuc2ZlcnNSb290SGFzaEhleAkAmgMBBRdsYXN0Q2xUb0VsVHJhbnNmZXJJbmRleAkBC0JpbmFyeUVudHJ5AgkArAICBQpibG9ja01ldGFLBQxibG9ja0hhc2hIZXgFDmJsb2NrTWV0YUJ5dGVzAQxsYXN0SGVpZ2h0QnkCBW1pbmVyB2NoYWluSWQEByRtYXRjaDAJAJ8IAQkBEmNoYWluTGFzdEhlaWdodEtleQIFB2NoYWluSWQFBW1pbmVyAwkAAQIFByRtYXRjaDACA0ludAQBaAUHJG1hdGNoMAUBaAQJYmxvY2tIYXNoCQERQGV4dHJOYXRpdmUoMTA1OCkBCQCsAgIJAKwCAgkArAICAgVjaGFpbgkApAMBBQdjaGFpbklkAgtMYXN0TWluZWRCeQkApQgBBQVtaW5lcggJAQlibG9ja01ldGEBBQlibG9ja0hhc2gCXzEACyR0MDg0ODA5NDQ2BAloaXRTb3VyY2UEByRtYXRjaDAIBQlsYXN0QmxvY2sDdnJmAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEA3ZyZgUHJG1hdGNoMAUDdnJmCAUJbGFzdEJsb2NrE2dlbmVyYXRpb25TaWduYXR1cmUKAQxwcm9jZXNzTWluZXICBHByZXYFbWluZXIECyR0MDg3Nzg4ODQxBQRwcmV2BAlwcmV2RGVsYXkIBQskdDA4Nzc4ODg0MQJfMQQJcHJldk1pbmVyCAULJHQwODc3ODg4NDECXzIEEHByZXZUb3RhbEJhbGFuY2UIBQskdDA4Nzc4ODg0MQJfMwQKcHJldk1pbmVycwgFCyR0MDg3Nzg4ODQxAl80BAxtaW5lckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBW1pbmVyBA93YXZlc0dlbkJhbGFuY2UICQDvBwEFDG1pbmVyQWRkcmVzcwpnZW5lcmF0aW5nBAxtaW5lckJhbGFuY2UJARFnZW5lcmF0aW5nQmFsYW5jZQEFDG1pbmVyQWRkcmVzcwMDCQBmAgULTUlOX0JBTEFOQ0UFD3dhdmVzR2VuQmFsYW5jZQYJAGcCAAAFDG1pbmVyQmFsYW5jZQUEcHJldgQJbmV4dERlbGF5CQCFBwIFDG1pbmVyQWRkcmVzcwUMbWluZXJCYWxhbmNlAwkAZgIFCXByZXZEZWxheQUJbmV4dERlbGF5CQCWCgQFCW5leHREZWxheQUFbWluZXIJAGQCBRBwcmV2VG90YWxCYWxhbmNlBQxtaW5lckJhbGFuY2UJAM0IAgUKcHJldk1pbmVycwUFbWluZXIJAJYKBAUJcHJldkRlbGF5BQlwcmV2TWluZXIJAGQCBRBwcmV2VG90YWxCYWxhbmNlBQxtaW5lckJhbGFuY2UJAM0IAgUKcHJldk1pbmVycwUFbWluZXIKAAIkbAUJYWxsTWluZXJzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlgoEBQdJTlRfTUFYAgAAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQxwcm9jZXNzTWluZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgANY29tcHV0ZWREZWxheQgFCyR0MDg0ODA5NDQ2Al8xABFjb21wdXRlZEdlbmVyYXRvcggFCyR0MDg0ODA5NDQ2Al8yABRjb21wdXRlZFRvdGFsQmFsYW5jZQgFCyR0MDg0ODA5NDQ2Al8zAA5maWx0ZXJlZE1pbmVycwgFCyR0MDg0ODA5NDQ2Al80ARNnZXRDaGFpbkxhc3RCbG9ja0lkAQdjaGFpbklkCAkBCWNoYWluTWV0YQEFB2NoYWluSWQCXzIACyR0MDk1MTI5NjE5CQEJYmxvY2tNZXRhAQUSbWFpbkNoYWluTGFzdEJsb2NrAAxtY2xiSWdub3JlZDEIBQskdDA5NTEyOTYxOQJfMQAObWFpbkNoYWluRXBvY2gIBQskdDA5NTEyOTYxOQJfMgATbWFpbkNoYWluUGFyZW50SGFzaAgFCyR0MDk1MTI5NjE5Al8zABJtYWluQ2hhaW5HZW5lcmF0b3IIBQskdDA5NTEyOTYxOQJfNAEbY2FsY3VsYXRlRmluYWxpemVkQmxvY2tIYXNoAwhjdXJNaW5lcgxjdXJQcmV2RXBvY2gQY3VyTGFzdEJsb2NrSGFzaAQLb2Zmc2V0c18xMDAJALwJAgJkOjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OgIABAtoYWxmQmFsYW5jZQkAaQIFFGNvbXB1dGVkVG90YWxCYWxhbmNlAAIKAQRzdGVwAgRwcmV2BG5leHQEDCR0MDk5ODUxMDA0OQUEcHJldgQJdGhpc0Vwb2NoCAUMJHQwOTk4NTEwMDQ5Al8xBAx0b3RhbEJhbGFuY2UIBQwkdDA5OTg1MTAwNDkCXzIEDm1heWJlU2FmZUVwb2NoCAUMJHQwOTk4NTEwMDQ5Al8zBApwcmV2TWluZXJzCAUMJHQwOTk4NTEwMDQ5Al80BAckbWF0Y2gwBQ5tYXliZVNhZmVFcG9jaAMJAAECBQckbWF0Y2gwAgRVbml0BA0kdDAxMDEwNzEwMjczAwkAAAIFCXRoaXNFcG9jaAUGaGVpZ2h0CQCVCgMFCGN1ck1pbmVyBQxjdXJQcmV2RXBvY2gFEGN1ckxhc3RCbG9ja0hhc2gJAQV2YWx1ZQEJAQllcG9jaE1ldGEBBQl0aGlzRXBvY2gEBW1pbmVyCAUNJHQwMTAxMDcxMDI3MwJfMQQJcHJldkVwb2NoCAUNJHQwMTAxMDcxMDI3MwJfMgQNbGFzdEJsb2NrSGFzaAgFDSR0MDEwMTA3MTAyNzMCXzMDCQAAAgUJcHJldkVwb2NoAAAJAJYKBAUJdGhpc0Vwb2NoBQx0b3RhbEJhbGFuY2UFDWxhc3RCbG9ja0hhc2gFCWFsbE1pbmVycwQNJHQwMTAzOTgxMDYwMAMJAQ9jb250YWluc0VsZW1lbnQCBQpwcmV2TWluZXJzBQVtaW5lcgkAlAoCBQx0b3RhbEJhbGFuY2UFCnByZXZNaW5lcnMJAJQKAgkAZAIFDHRvdGFsQmFsYW5jZQkBEWdlbmVyYXRpbmdCYWxhbmNlAQUFbWluZXIJAMwIAgUFbWluZXIFCnByZXZNaW5lcnMED25ld1RvdGFsQmFsYW5jZQgFDSR0MDEwMzk4MTA2MDACXzEECW5ld01pbmVycwgFDSR0MDEwMzk4MTA2MDACXzIDCQBmAgUPbmV3VG90YWxCYWxhbmNlBQtoYWxmQmFsYW5jZQkAlgoEBQl0aGlzRXBvY2gFD25ld1RvdGFsQmFsYW5jZQUNbGFzdEJsb2NrSGFzaAUJYWxsTWluZXJzCQCWCgQFCXByZXZFcG9jaAUPbmV3VG90YWxCYWxhbmNlBQR1bml0BQluZXdNaW5lcnMFBHByZXYEDSR0MDEwODMzMTA5NjYKAAIkbAkAzggCBQtvZmZzZXRzXzEwMAULb2Zmc2V0c18xMDAKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQFBmhlaWdodAAABQR1bml0BQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBHN0ZXACBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFUxpc3Qgc2l6ZSBleGNlZWRzIDIwMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAGIAYwBkAGUAZgBnAGgAaQBqAGsAbABtAG4AbwBwAHEAcgBzAHQAdQB2AHcAeAB5AHoAewB8AH0AfgB/AIABAIEBAIIBAIMBAIQBAIUBAIYBAIcBAIgBAIkBAIoBAIsBAIwBAI0BAI4BAI8BAJABAJEBAJIBAJMBAJQBAJUBAJYBAJcBAJgBAJkBAJoBAJsBAJwBAJ0BAJ4BAJ8BAKABAKEBAKIBAKMBAKQBAKUBAKYBAKcBAKgBAKkBAKoBAKsBAKwBAK0BAK4BAK8BALABALEBALIBALMBALQBALUBALYBALcBALgBALkBALoBALsBALwBAL0BAL4BAL8BAMABAMEBAMIBAMMBAMQBAMUBAMYBAMcBAMgBBA1mYWxsYmFja0Vwb2NoCAUNJHQwMTA4MzMxMDk2NgJfMQQMdG90YWxCYWxhbmNlCAUNJHQwMTA4MzMxMDk2NgJfMgQVZmluYWxpemVkQmxvY2tIYXNoT3B0CAUNJHQwMTA4MzMxMDk2NgJfMwQGbWluZXJzCAUNJHQwMTA4MzMxMDk2NgJfNAQHJG1hdGNoMAUVZmluYWxpemVkQmxvY2tIYXNoT3B0AwkAAQIFByRtYXRjaDACBlN0cmluZwQSZmluYWxpemVkQmxvY2tIYXNoBQckbWF0Y2gwBRJmaW5hbGl6ZWRCbG9ja0hhc2gICQEFdmFsdWUBCQEJZXBvY2hNZXRhAQUNZmFsbGJhY2tFcG9jaAJfMwERc3VwcG9ydGluZ0JhbGFuY2UBB2NoYWluSWQKAQphZGRCYWxhbmNlAgNhY2MMZ2VuZXJhdG9yU3RyBA0kdDAxMTIzNjExMjcyBQNhY2MEDHRvdGFsQmFsYW5jZQgFDSR0MDExMjM2MTEyNzICXzEECmdlbmVyYXRvcnMIBQ0kdDAxMTIzNjExMjcyAl8yBAlnZW5lcmF0b3IJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDGdlbmVyYXRvclN0cgMJAQ9jb250YWluc0VsZW1lbnQCBQpnZW5lcmF0b3JzBQlnZW5lcmF0b3IFA2FjYwQHYmFsYW5jZQkBEWdlbmVyYXRpbmdCYWxhbmNlAQUJZ2VuZXJhdG9yCQCUCgIJAGQCBQx0b3RhbEJhbGFuY2UFB2JhbGFuY2UJAM0IAgUKZ2VuZXJhdG9ycwUJZ2VuZXJhdG9yBA1hbGxHZW5lcmF0b3JzCQC8CQIJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAQ1zdXBwb3J0ZXJzS2V5AQUHY2hhaW5JZAUDU0VQBA0kdDAxMTU5NDExNjU5CgACJGwFDWFsbEdlbmVyYXRvcnMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQphZGRCYWxhbmNlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhVMaXN0IHNpemUgZXhjZWVkcyAxMDAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQBiAGMAZAQHYmFsYW5jZQgFDSR0MDExNTk0MTE2NTkCXzEEAl9nCAUNJHQwMTE1OTQxMTY1OQJfMgUHYmFsYW5jZQEPaXNDb250cmFjdFNldHVwAAkBCWlzRGVmaW5lZAEJAJ8IAQUObWluZXJSZXdhcmRLZXkBEWVuc3VyZU1pbmluZ0Vwb2NoAQlnZW5lcmF0b3IDCQECIT0CCQClCAEFCWdlbmVyYXRvcgURY29tcHV0ZWRHZW5lcmF0b3IJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJANgEAQgFCWdlbmVyYXRvcgVieXRlcwIbIGlzIG5vdCBhbGxvd2VkIHRvIG1pbmUgaW4gCQCkAwEFBmhlaWdodAIRIGVwb2NoLiBFeHBlY3RlZCAFEWNvbXB1dGVkR2VuZXJhdG9yBQR1bml0ARJpc1JlZmVyZW5jZUNvcnJlY3QCCXJlZmVyZW5jZQlsYXN0QmxvY2sDCQAAAgUJcmVmZXJlbmNlBQlsYXN0QmxvY2sFBHVuaXQJAAIBCQCsAgIJAKwCAgkArAICAjBFeHBlY3RlZCBhIHJlZmVyZW5jZSB0byB0aGUgY2hhaW4gbGFzdCBibG9jazogMHgFCWxhc3RCbG9jawIJLiBHb3Q6IDB4BQlyZWZlcmVuY2UBD2NoYWluSXNJbmFjdGl2ZQEHY2hhaW5JZAQMZmlyc3RCbG9ja0lkCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEUY2hhaW5GaXJzdEJsb2NrSWRLZXkBBQdjaGFpbklkBBRmaXJzdFZhbGlkQWx0Q2hhaW5JZAkBC3ZhbHVlT3JFbHNlAgkAnwgBBRdmaXJzdFZhbGlkQWx0Q2hhaW5JZEtleQAAAwkAZgIFFGZpcnN0VmFsaWRBbHRDaGFpbklkBQdjaGFpbklkBgkAZgIICQEJYmxvY2tNZXRhAQkBEUBleHRyTmF0aXZlKDEwNTgpAQURZmluYWxpemVkQmxvY2tLZXkCXzEICQEJYmxvY2tNZXRhAQUMZmlyc3RCbG9ja0lkAl8xAQxtaW5lckNoYWluSWQBBW1pbmVyCQELdmFsdWVPckVsc2UCCQCfCAEJAQ9taW5lckNoYWluSWRLZXkBBQVtaW5lcgkAnwgBCQCsAgICCWNoYWluSWRPZgkApQgBBQVtaW5lcgEdZW5zdXJlRXhwZWN0ZWRPckluYWN0aXZlQ2hhaW4DCWdlbmVyYXRvcg9leHBlY3RlZENoYWluSWQQY2hlY2tIZWlnaHRCbG9jawQPaGVpZ2h0SXNDb3JyZWN0BAckbWF0Y2gwBRBjaGVja0hlaWdodEJsb2NrAwkAAQIFByRtYXRjaDACBlN0cmluZwQJYmxvY2tIYXNoBQckbWF0Y2gwBBRsYXN0TWluZWRCbG9ja0hlaWdodAkBDGxhc3RIZWlnaHRCeQIFCWdlbmVyYXRvcgULbWFpbkNoYWluSWQJAGYCCQBkAggJAQlibG9ja01ldGEBBQlibG9ja0hhc2gCXzEAAQUUbGFzdE1pbmVkQmxvY2tIZWlnaHQGBAckbWF0Y2gwCQEMbWluZXJDaGFpbklkAQUJZ2VuZXJhdG9yAwkAAQIFByRtYXRjaDACA0ludAQJY3VycmVudElkBQckbWF0Y2gwAwMJAAACBQljdXJyZW50SWQFD2V4cGVjdGVkQ2hhaW5JZAYDCQEPY2hhaW5Jc0luYWN0aXZlAQUJY3VycmVudElkBQ9oZWlnaHRJc0NvcnJlY3QHBQR1bml0CQACAQkArAICAhxtaW5lciBpcyBtaW5pbmcgb3RoZXIgY2hhaW4gCQCkAwEFCWN1cnJlbnRJZAUEdW5pdAESZW5zdXJlQ29ycmVjdEVwb2NoAQVlcG9jaAMJAAACBQVlcG9jaAUGaGVpZ2h0BQR1bml0CQACAQkArAICCQCsAgIJAKwCAgIaRXhwZWN0ZWQgYmxvY2sgZnJvbSBlcG9jaCAJAKQDAQUGaGVpZ2h0AgYuIEdvdCAJAKQDAQUFZXBvY2gBDGFkZFN1cHBvcnRlcgIHY2hhaW5JZAlnZW5lcmF0b3IEDXN1cHBvcnRlcnNTdHIJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAQ1zdXBwb3J0ZXJzS2V5AQUHY2hhaW5JZAQKc3VwcG9ydGVycwkAvAkCBQ1zdXBwb3J0ZXJzU3RyBQNTRVADCQEPY29udGFpbnNFbGVtZW50AgUKc3VwcG9ydGVycwkApQgBBQlnZW5lcmF0b3IFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCCQENc3VwcG9ydGVyc0tleQEFB2NoYWluSWQJAKwCAgkArAICBQ1zdXBwb3J0ZXJzU3RyBQNTRVAJAKUIAQUJZ2VuZXJhdG9yBQNuaWwBCXNldE9yRmFpbAIFZmxhZ3MFaW5kZXgDCQBmAgAABQVpbmRleAkAAgEJAKwCAgIiQ2FuJ3Qgd2l0aGRyYXcgYXQgbmVnYXRpdmUgaW5kZXg6IAkApAMBBQVpbmRleAQJZmxhZ3NTaXplCQCxAgEFBWZsYWdzAwkAZwIFBWluZGV4BQlmbGFnc1NpemUECWFkZFplcm9lcwkAZQIFBWluZGV4BQlmbGFnc1NpemUDCQBmAgUJYWRkWmVyb2VzCQCxAgEFCXplcm9lc1N0cgkAAgEJAKwCAgkArAICAgpDYW4ndCBhZGQgCQCkAwEFCWFkZFplcm9lcwIlIGVtcHR5IGZsYWdzLiBDb250YWN0IHdpdGggZGV2ZWxvcGVycwkArAICCQCsAgIFBWZsYWdzCQCvAgIFCXplcm9lc1N0cgUJYWRkWmVyb2VzAgExBAR0YWlsCQCwAgIFBWZsYWdzBQVpbmRleAQHYXRJbmRleAkArwICBQR0YWlsAAEDCQAAAgUHYXRJbmRleAIBMAkArAICCQCsAgIJAK8CAgUFZmxhZ3MFBWluZGV4AgExCQCwAgIFBHRhaWwAAQkAAgEJAKwCAgkArAICAgpUcmFuc2ZlciAjCQCkAwEFBWluZGV4AhcgaGFzIGJlZW4gYWxyZWFkeSB0YWtlbgERdmFsaWRhdGVCbG9ja0hhc2gBBmhleFN0cgQMZGVjb2RlZEJ5dGVzCQDdBAEFBmhleFN0cgMJAQIhPQIJAMgBAQUMZGVjb2RlZEJ5dGVzACAJAAIBAhdpbnZhbGlkIGJsb2NrIGlkIGxlbmd0aAUGaGV4U3RyAR1nZXRVcGRhdGVGaW5hbGl6ZWRCbG9ja0FjdGlvbgMGY2FsbGVyD25ld0Jsb2NrSGFzaEhleAlwcmV2RXBvY2gEF2N1ckZpbmFsaXplZEJsb2NrSGVpZ2h0CAkBCWJsb2NrTWV0YQEJARFAZXh0ck5hdGl2ZSgxMDU4KQEFEWZpbmFsaXplZEJsb2NrS2V5Al8xBBVuZXdGaW5hbGl6ZWRCbG9ja0hhc2gJARtjYWxjdWxhdGVGaW5hbGl6ZWRCbG9ja0hhc2gDBQZjYWxsZXIFCXByZXZFcG9jaAUPbmV3QmxvY2tIYXNoSGV4AwMJAAACBRVuZXdGaW5hbGl6ZWRCbG9ja0hhc2gFD25ld0Jsb2NrSGFzaEhleAYJAGYCCAkBCWJsb2NrTWV0YQEFFW5ld0ZpbmFsaXplZEJsb2NrSGFzaAJfMQUXY3VyRmluYWxpemVkQmxvY2tIZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgURZmluYWxpemVkQmxvY2tLZXkFFW5ld0ZpbmFsaXplZEJsb2NrSGFzaAUDbmlsBQNuaWwJAWkBDmFwcGVuZEJsb2NrX3YzBAxibG9ja0hhc2hIZXgMcmVmZXJlbmNlSGV4GmVsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoSGV4F2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4BAtjaGVja0NhbGxlcgMJAAACBQ50aGlzRXBvY2hNaW5lcggFAWkMb3JpZ2luQ2FsbGVyBgQHJG1hdGNoMAUOdGhpc0Vwb2NoTWluZXIDCQABAgUHJG1hdGNoMAIHQWRkcmVzcwQKZXBvY2hNaW5lcgUHJG1hdGNoMAkAAgEJAKwCAgI5bm90IGFsbG93ZWQgdG8gZm9yZ2UgYmxvY2tzIGluIHRoaXMgZXBvY2gsIGV4cGVjdGVkIGZyb20gCQClCAEFCmVwb2NoTWluZXIJAAIBAkBub3QgYWxsb3dlZCB0byBmb3JnZSBibG9ja3MgaW4gdGhpcyBlcG9jaCwgZXBvY2ggbWluZXIgaXMgYWJzZW50AwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQHY2hhaW5JZAkBC3ZhbHVlT3JFbHNlAgkBDG1pbmVyQ2hhaW5JZAEIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQEDSR0MDE1ODA0MTU4NTUJAQljaGFpbk1ldGEBBQdjaGFpbklkBAtjaGFpbkhlaWdodAgFDSR0MDE1ODA0MTU4NTUCXzEEC2xhc3RCbG9ja0lkCAUNJHQwMTU4MDQxNTg1NQJfMgQOY2hlY2tSZWZlcmVuY2UJARJpc1JlZmVyZW5jZUNvcnJlY3QCBQxyZWZlcmVuY2VIZXgFC2xhc3RCbG9ja0lkAwkAAAIFDmNoZWNrUmVmZXJlbmNlBQ5jaGVja1JlZmVyZW5jZQQOY2hlY2tUcmFuc2ZlcnMJARZlbnN1cmVDb3JyZWN0VHJhbnNmZXJzAwgJAQlibG9ja01ldGEBBQxyZWZlcmVuY2VIZXgCXzcFF2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4BwMJAAACBQ5jaGVja1RyYW5zZmVycwUOY2hlY2tUcmFuc2ZlcnMEDm5ld0NoYWluSGVpZ2h0CQBkAgULY2hhaW5IZWlnaHQAAQQOY2hlY2tCbG9ja0hhc2gJARF2YWxpZGF0ZUJsb2NrSGFzaAEFDGJsb2NrSGFzaEhleAMJAAACBQ5jaGVja0Jsb2NrSGFzaAUOY2hlY2tCbG9ja0hhc2gJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkHBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BQtsYXN0QmxvY2tJZAgFAWkMb3JpZ2luQ2FsbGVyBQdjaGFpbklkBRplbFRvQ2xUcmFuc2ZlcnNSb290SGFzaEhleAUXbGFzdENsVG9FbFRyYW5zZmVySW5kZXgJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQdjaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFDm5ld0NoYWluSGVpZ2h0CQDMCAIJARBta0NoYWluTWV0YUVudHJ5AwUHY2hhaW5JZAUObmV3Q2hhaW5IZWlnaHQFDGJsb2NrSGFzaEhleAkAzAgCCQELU3RyaW5nRW50cnkCCQEMZXBvY2hNZXRhS2V5AQUGaGVpZ2h0CQCsAgIJAKwCAgkArAICCQCsAgIJAKUIAQkBBXZhbHVlAQUOdGhpc0Vwb2NoTWluZXIFA1NFUAkApAMBBQx0aGlzRXBvY2hSZWYFA1NFUAUMYmxvY2tIYXNoSGV4BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQESZXh0ZW5kTWFpbkNoYWluX3YzBQxibG9ja0hhc2hIZXgMcmVmZXJlbmNlSGV4BWVwb2NoGmVsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoSGV4F2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4BA5jaGVja0Jsb2NrSGFzaAkBEXZhbGlkYXRlQmxvY2tIYXNoAQUMYmxvY2tIYXNoSGV4AwkAAAIFDmNoZWNrQmxvY2tIYXNoBQ5jaGVja0Jsb2NrSGFzaAQKY2hlY2tFcG9jaAkBEmVuc3VyZUNvcnJlY3RFcG9jaAEFBWVwb2NoAwkAAAIFCmNoZWNrRXBvY2gFCmNoZWNrRXBvY2gECmNoZWNrQ2hhaW4JAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQFBHVuaXQDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQOY2hlY2tSZWZlcmVuY2UJARJpc1JlZmVyZW5jZUNvcnJlY3QCBQxyZWZlcmVuY2VIZXgFEm1haW5DaGFpbkxhc3RCbG9jawMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDmNoZWNrVHJhbnNmZXJzCQEWZW5zdXJlQ29ycmVjdFRyYW5zZmVycwMICQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4Al83BRdsYXN0Q2xUb0VsVHJhbnNmZXJJbmRleAYDCQAAAgUOY2hlY2tUcmFuc2ZlcnMFDmNoZWNrVHJhbnNmZXJzBA10aGlzRXBvY2hNZXRhBAckbWF0Y2gwCQEJZXBvY2hNZXRhAQUGaGVpZ2h0AwkAAQIFByRtYXRjaDACBFVuaXQJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCAUBaQxvcmlnaW5DYWxsZXIFA1NFUAkApAMBBQ5tYWluQ2hhaW5FcG9jaAUDU0VQBQxibG9ja0hhc2hIZXgEBW90aGVyBQckbWF0Y2gwCQACAQIVRXBvY2ggYWxyZWFkeSBzdGFydGVkAwkAAAIFDXRoaXNFcG9jaE1ldGEFDXRoaXNFcG9jaE1ldGEEDmNoZWNrR2VuZXJhdG9yCQERZW5zdXJlTWluaW5nRXBvY2gBCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUOY2hlY2tHZW5lcmF0b3IFDmNoZWNrR2VuZXJhdG9yBBR1cGRhdGVGaW5hbGl6ZWRCbG9jawkBHWdldFVwZGF0ZUZpbmFsaXplZEJsb2NrQWN0aW9uAwgFAWkMb3JpZ2luQ2FsbGVyBQxibG9ja0hhc2hIZXgFDm1haW5DaGFpbkVwb2NoBA5uZXdDaGFpbkhlaWdodAkAZAIFD21haW5DaGFpbkhlaWdodAABCQDOCAIJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkHBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BRJtYWluQ2hhaW5MYXN0QmxvY2sIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQFGmVsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoSGV4BRdsYXN0Q2xUb0VsVHJhbnNmZXJJbmRleAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMFC21haW5DaGFpbklkBQ5uZXdDaGFpbkhlaWdodAUMYmxvY2tIYXNoSGV4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEPbWluZXJDaGFpbklkS2V5AQgFAWkMb3JpZ2luQ2FsbGVyBQttYWluQ2hhaW5JZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmNoYWluTGFzdEhlaWdodEtleQIFC21haW5DaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFDm5ld0NoYWluSGVpZ2h0CQDMCAIFDXRoaXNFcG9jaE1ldGEFA25pbAUUdXBkYXRlRmluYWxpemVkQmxvY2sJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEQc3RhcnRBbHRDaGFpbl92MwUMYmxvY2tIYXNoSGV4DHJlZmVyZW5jZUhleAVlcG9jaBplbFRvQ2xUcmFuc2ZlcnNSb290SGFzaEhleBdsYXN0Q2xUb0VsVHJhbnNmZXJJbmRleAQOY2hlY2tCbG9ja0hhc2gJARF2YWxpZGF0ZUJsb2NrSGFzaAEFDGJsb2NrSGFzaEhleAMJAAACBQ5jaGVja0Jsb2NrSGFzaAUOY2hlY2tCbG9ja0hhc2gECmNoZWNrRXBvY2gJARJlbnN1cmVDb3JyZWN0RXBvY2gBBQVlcG9jaAMJAAACBQpjaGVja0Vwb2NoBQpjaGVja0Vwb2NoBA0kdDAxODI3ODE4NDAwCQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4BA5yZWZDaGFpbkhlaWdodAgFDSR0MDE4Mjc4MTg0MDACXzEECHJlZkVwb2NoCAUNJHQwMTgyNzgxODQwMAJfMgQGcmVmUmVmCAUNJHQwMTgyNzgxODQwMAJfMwQMcmVmR2VuZXJhdG9yCAUNJHQwMTgyNzgxODQwMAJfNAQLcmVmSWdub3JlZDUIBQ0kdDAxODI3ODE4NDAwAl81BAtyZWZJZ25vcmVkNggFDSR0MDE4Mjc4MTg0MDACXzYEEHJlZlRyYW5zZmVySW5kZXgIBQ0kdDAxODI3ODE4NDAwAl83BA5maW5hbGl6ZWRFcG9jaAgJAQlibG9ja01ldGEBCQERQGV4dHJOYXRpdmUoMTA1OCkBBRFmaW5hbGl6ZWRCbG9ja0tleQJfMgQIZXBvY2hSZWYDCQBnAgUIcmVmRXBvY2gFDmZpbmFsaXplZEVwb2NoBQhyZWZFcG9jaAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIjQ2FuIG5vdCBzdGFydCBhbHQgY2hhaW4gZnJvbSBlcG9jaCAJAKQDAQUIcmVmRXBvY2gCCCwgZXBvY2ggCQCkAwEFDmZpbmFsaXplZEVwb2NoAg0gaXMgZmluYWxpemVkBApjaGVja0NoYWluCQEdZW5zdXJlRXhwZWN0ZWRPckluYWN0aXZlQ2hhaW4DCAUBaQxvcmlnaW5DYWxsZXIFC21haW5DaGFpbklkBQxyZWZlcmVuY2VIZXgDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQOY2hlY2tUcmFuc2ZlcnMJARZlbnN1cmVDb3JyZWN0VHJhbnNmZXJzAwUQcmVmVHJhbnNmZXJJbmRleAUXbGFzdENsVG9FbFRyYW5zZmVySW5kZXgGAwkAAAIFDmNoZWNrVHJhbnNmZXJzBQ5jaGVja1RyYW5zZmVycwQKbmV3Q2hhaW5JZAkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUObGFzdENoYWluSWRLZXkAAAABBA5uZXdDaGFpbkhlaWdodAkAZAIFDnJlZkNoYWluSGVpZ2h0AAEEDXRoaXNFcG9jaE1ldGEEByRtYXRjaDAJAQllcG9jaE1ldGEBBQZoZWlnaHQDCQABAgUHJG1hdGNoMAIEVW5pdAkBC1N0cmluZ0VudHJ5AgkBDGVwb2NoTWV0YUtleQEFBmhlaWdodAkArAICCQCsAgIJAKwCAgkArAICCQClCAEIBQFpDG9yaWdpbkNhbGxlcgUDU0VQCQCkAwEFCGVwb2NoUmVmBQNTRVAFDGJsb2NrSGFzaEhleAQFb3RoZXIFByRtYXRjaDAJAAIBAhVFcG9jaCBhbHJlYWR5IHN0YXJ0ZWQEDmNoZWNrR2VuZXJhdG9yCQERZW5zdXJlTWluaW5nRXBvY2gBCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUOY2hlY2tHZW5lcmF0b3IFDmNoZWNrR2VuZXJhdG9yCQDMCAIFDXRoaXNFcG9jaE1ldGEJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkHBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BQxyZWZlcmVuY2VIZXgIBQFpDG9yaWdpbkNhbGxlcgUKbmV3Q2hhaW5JZAUaZWxUb0NsVHJhbnNmZXJzUm9vdEhhc2hIZXgFF2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4CQDMCAIJAQtTdHJpbmdFbnRyeQIJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEFCm5ld0NoYWluSWQFDGJsb2NrSGFzaEhleAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMFCm5ld0NoYWluSWQFDm5ld0NoYWluSGVpZ2h0BQxibG9ja0hhc2hIZXgJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9taW5lckNoYWluSWRLZXkBCAUBaQxvcmlnaW5DYWxsZXIFCm5ld0NoYWluSWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQpuZXdDaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFDm5ld0NoYWluSGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgULbWFpbkNoYWluSWQIBQFpDG9yaWdpbkNhbGxlcgUObmV3Q2hhaW5IZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDXN1cHBvcnRlcnNLZXkBBQpuZXdDaGFpbklkCQClCAEIBQFpDG9yaWdpbkNhbGxlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgUObGFzdENoYWluSWRLZXkFCm5ld0NoYWluSWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARFleHRlbmRBbHRDaGFpbl92MwYHY2hhaW5JZAxibG9ja0hhc2hIZXgMcmVmZXJlbmNlSGV4BWVwb2NoGmVsVG9DbFRyYW5zZmVyc1Jvb3RIYXNoSGV4F2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4BA5jaGVja0Jsb2NrSGFzaAkBEXZhbGlkYXRlQmxvY2tIYXNoAQUMYmxvY2tIYXNoSGV4AwkAAAIFDmNoZWNrQmxvY2tIYXNoBQ5jaGVja0Jsb2NrSGFzaAQKY2hlY2tFcG9jaAkBEmVuc3VyZUNvcnJlY3RFcG9jaAEFBWVwb2NoAwkAAAIFCmNoZWNrRXBvY2gFCmNoZWNrRXBvY2gEE2NoYWluRmlyc3RCbG9ja01ldGEJAQlibG9ja01ldGEBCQERQGV4dHJOYXRpdmUoMTA1OCkBCQEUY2hhaW5GaXJzdEJsb2NrSWRLZXkBBQdjaGFpbklkBApjaGVja0NoYWluCQEdZW5zdXJlRXhwZWN0ZWRPckluYWN0aXZlQ2hhaW4DCAUBaQxvcmlnaW5DYWxsZXIFB2NoYWluSWQJANwEAQgFE2NoYWluRmlyc3RCbG9ja01ldGECXzMDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQNJHQwMjA3NDQyMDc5OAkBCWNoYWluTWV0YQEFB2NoYWluSWQEC2NoYWluSGVpZ2h0CAUNJHQwMjA3NDQyMDc5OAJfMQQOY2hhaW5MYXN0QmxvY2sIBQ0kdDAyMDc0NDIwNzk4Al8yBA5jaGVja1JlZmVyZW5jZQkBEmlzUmVmZXJlbmNlQ29ycmVjdAIFDHJlZmVyZW5jZUhleAUOY2hhaW5MYXN0QmxvY2sDCQAAAgUOY2hlY2tSZWZlcmVuY2UFDmNoZWNrUmVmZXJlbmNlBA5jaGVja1RyYW5zZmVycwkBFmVuc3VyZUNvcnJlY3RUcmFuc2ZlcnMDCAkBCWJsb2NrTWV0YQEFDHJlZmVyZW5jZUhleAJfNwUXbGFzdENsVG9FbFRyYW5zZmVySW5kZXgGAwkAAAIFDmNoZWNrVHJhbnNmZXJzBQ5jaGVja1RyYW5zZmVycwQObmV3Q2hhaW5IZWlnaHQJAGQCBQtjaGFpbkhlaWdodAABBAlwcmV2RXBvY2gICQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4Al8yBBN1cGRhdGVNYWluQ2hhaW5EYXRhAwkAZgIJARFzdXBwb3J0aW5nQmFsYW5jZQEFB2NoYWluSWQJAGkCBRRjb21wdXRlZFRvdGFsQmFsYW5jZQACBAtsYXN0Q2hhaW5JZAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ5sYXN0Q2hhaW5JZEtleQAABBR1cGRhdGVGaW5hbGl6ZWRCbG9jawkBHWdldFVwZGF0ZUZpbmFsaXplZEJsb2NrQWN0aW9uAwgFAWkMb3JpZ2luQ2FsbGVyBQxibG9ja0hhc2hIZXgFCXByZXZFcG9jaAkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUY2hhaW5Gb3JrZWRIZWlnaHRLZXkBBQttYWluQ2hhaW5JZAgFE2NoYWluRmlyc3RCbG9ja01ldGECXzEJAMwIAgkBDEludGVnZXJFbnRyeQIFDm1haW5DaGFpbklkS2V5BQdjaGFpbklkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRdmaXJzdFZhbGlkQWx0Q2hhaW5JZEtleQkAZAIFC2xhc3RDaGFpbklkAAEFA25pbAUUdXBkYXRlRmluYWxpemVkQmxvY2sFA25pbAQNdGhpc0Vwb2NoTWV0YQQHJG1hdGNoMAkBCWVwb2NoTWV0YQEFBmhlaWdodAMJAAECBQckbWF0Y2gwAgRVbml0CQELU3RyaW5nRW50cnkCCQEMZXBvY2hNZXRhS2V5AQUGaGVpZ2h0CQCsAgIJAKwCAgkArAICCQCsAgIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBQNTRVAJAKQDAQUJcHJldkVwb2NoBQNTRVAFDGJsb2NrSGFzaEhleAQFb3RoZXIFByRtYXRjaDAJAAIBAhVFcG9jaCBhbHJlYWR5IHN0YXJ0ZWQDCQAAAgUNdGhpc0Vwb2NoTWV0YQUNdGhpc0Vwb2NoTWV0YQQOY2hlY2tHZW5lcmF0b3IJARFlbnN1cmVNaW5pbmdFcG9jaAEIBQFpDG9yaWdpbkNhbGxlcgMJAAACBQ5jaGVja0dlbmVyYXRvcgUOY2hlY2tHZW5lcmF0b3IEHXVwZGF0ZU1haW5DaGFpbkxhc3RNaW5lZEJsb2NrAwMJAAACBRN1cGRhdGVNYWluQ2hhaW5EYXRhBQNuaWwJAQIhPQIJAQt2YWx1ZU9yRWxzZQIJAQxtaW5lckNoYWluSWQBCAUBaQxvcmlnaW5DYWxsZXIAAAUHY2hhaW5JZAcJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQttYWluQ2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyCAUTY2hhaW5GaXJzdEJsb2NrTWV0YQJfMQUDbmlsBQNuaWwJAM4IAgkAzggCCQDOCAIJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkHBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BQxyZWZlcmVuY2VIZXgIBQFpDG9yaWdpbkNhbGxlcgUHY2hhaW5JZAUaZWxUb0NsVHJhbnNmZXJzUm9vdEhhc2hIZXgFF2xhc3RDbFRvRWxUcmFuc2ZlckluZGV4CQDMCAIJARBta0NoYWluTWV0YUVudHJ5AwUHY2hhaW5JZAUObmV3Q2hhaW5IZWlnaHQFDGJsb2NrSGFzaEhleAkAzAgCBQ10aGlzRXBvY2hNZXRhCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEPbWluZXJDaGFpbklkS2V5AQgFAWkMb3JpZ2luQ2FsbGVyBQdjaGFpbklkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgUHY2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBQ5uZXdDaGFpbkhlaWdodAUDbmlsBRN1cGRhdGVNYWluQ2hhaW5EYXRhCQEMYWRkU3VwcG9ydGVyAgUHY2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBR11cGRhdGVNYWluQ2hhaW5MYXN0TWluZWRCbG9jawkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQRqb2luAQ1yZXdhcmRBZGRyZXNzCgEdZW5zdXJlTm90T3ZlcnJpZGVPdGhlck1pbmVyUGsBDGVsQWRkcmVzc0hleAQHJG1hdGNoMAkAoQgBCQEKbWluZXJQa0tleQEFDGVsQWRkcmVzc0hleAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACBQJwawgFAWkVb3JpZ2luQ2FsbGVyUHVibGljS2V5BQR1bml0CQACAQkArAICCQCsAgIJAKwCAgIRRUwgbWluZXIgYWRkcmVzcyAFDGVsQWRkcmVzc0hleAIYIGlzIGFscmVhZHkgbGlua2VkIHdpdGggCQDYBAEFAnBrBQR1bml0AwkBASEBCQEPaXNDb250cmFjdFNldHVwAAkAAgECH1RoZSBjb250cmFjdCBoYXMgbm90IHlldCBzZXQgdXADCQBmAgULTUlOX0JBTEFOQ0UICQDvBwEIBQFpDG9yaWdpbkNhbGxlcgpnZW5lcmF0aW5nCQACAQkArAICCQCsAgIJAKwCAgIhSW5zdWZmaWNpZW50IGdlbmVyYXRpbmcgYmFsYW5jZTogCQCkAwEICQDvBwEIBQFpDG9yaWdpbkNhbGxlcgpnZW5lcmF0aW5nAgwuIFJlcXVpcmVkOiAJAKQDAQULTUlOX0JBTEFOQ0UDCQECIT0CCQDIAQEFDXJld2FyZEFkZHJlc3MAFAkAAgECJXJld2FyZEFkZHJlc3Mgc2hvdWxkIGJlIGFuIEwyIGFkZHJlc3MDCQBnAgkAkAMBBQlhbGxNaW5lcnMAMgkAAgECD3RvbyBtYW55IG1pbmVycwoBDmNoZWNrRXhpc3RlbmNlAgZleGlzdHMFbWluZXIDBQZleGlzdHMGCQAAAgUFbWluZXIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBA1hbHJlYWR5RXhpc3RzCgACJGwFCWFsbE1pbmVycwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAHCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQ5jaGVja0V4aXN0ZW5jZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyAwUNYWxyZWFkeUV4aXN0cwUDbmlsBAhuZXdNaW5lcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEEHJld2FyZEFkZHJlc3NIZXgJANwEAQUNcmV3YXJkQWRkcmVzcwQFY2hlY2sJAR1lbnN1cmVOb3RPdmVycmlkZU90aGVyTWluZXJQawEFEHJld2FyZEFkZHJlc3NIZXgDCQAAAgUFY2hlY2sFBWNoZWNrBAluZXdNaW5lcnMDCQAAAgkAkAMBBQlhbGxNaW5lcnMAAAUIbmV3TWluZXIJAKwCAgkArAICBQxhbGxNaW5lcnNTdHIFA1NFUAUIbmV3TWluZXIEGGRlbGV0ZU9sZFJld2FyZEFkZHJlc3NQawQHJG1hdGNoMAkAoggBCQEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQUIbmV3TWluZXIDCQABAgUHJG1hdGNoMAIGU3RyaW5nBApvbGRBZGRyZXNzBQckbWF0Y2gwAwkAAAIFCm9sZEFkZHJlc3MJANwEAQUNcmV3YXJkQWRkcmVzcwUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEJAQptaW5lclBrS2V5AQUKb2xkQWRkcmVzcwUDbmlsBQNuaWwJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCBQxhbGxNaW5lcnNLZXkFCW5ld01pbmVycwkAzAgCCQELU3RyaW5nRW50cnkCCQEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQUIbmV3TWluZXIJAKwCAgICMHgFEHJld2FyZEFkZHJlc3NIZXgJAMwIAgkBC0JpbmFyeUVudHJ5AgkBCm1pbmVyUGtLZXkBBRByZXdhcmRBZGRyZXNzSGV4CAUBaRVvcmlnaW5DYWxsZXJQdWJsaWNLZXkFA25pbAUYZGVsZXRlT2xkUmV3YXJkQWRkcmVzc1BrCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBWxlYXZlAAQMbGVhdmluZ01pbmVyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgoBEHNraXBMZWF2aW5nTWluZXICA2FjYwVtaW5lcgMJAAACBQVtaW5lcgUMbGVhdmluZ01pbmVyBQNhY2MJAM0IAgUDYWNjBQVtaW5lcgQPcmVtYWluaW5nTWluZXJzCgACJGwFCWFsbE1pbmVycwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEQc2tpcExlYXZpbmdNaW5lcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyBA1yZXdhcmRBZGRyS2V5CQEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQUMbGVhdmluZ01pbmVyBBFwcmV2UmV3YXJkQWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMFDXJld2FyZEFkZHJLZXkCFm1pbmVyIGhhcyBuZXZlciBqb2luZWQDCQAAAgUOdGhpc0Vwb2NoTWluZXIIBQFpDG9yaWdpbkNhbGxlcgkAAgECHGRlc2lnbmF0ZWQgbWluZXIgY2FuJ3QgbGVhdmUJAMwIAgkBC1N0cmluZ0VudHJ5AgUMYWxsTWluZXJzS2V5CQC6CQIFD3JlbWFpbmluZ01pbmVycwUDU0VQBQNuaWwBaQEIdHJhbnNmZXIBEGRlc3RFbEFkZHJlc3NIZXgEDGNoZWNrUGF5bWVudAMJAAACCQCQAwEIBQFpCHBheW1lbnRzAAEGCQACAQkArAICAi9FeHBlY3RlZCBvbmUgcGF5bWVudCBhcyBhIHRyYW5zZmVyIGFtb3VudCwgZ290IAkApAMBCQCQAwEIBQFpCHBheW1lbnRzAwkAAAIFDGNoZWNrUGF5bWVudAUMY2hlY2tQYXltZW50BBBjaGVja0Rlc3RBZGRyZXNzAwkAAAIJAMgBAQkA3QQBBRBkZXN0RWxBZGRyZXNzSGV4ABQGCQACAQI0RGVzdGluYXRpb24gYWRkcmVzcyBtdXN0IGJlIGEgdmFsaWQgZXRoZXJldW0gYWRkcmVzcwMJAAACBRBjaGVja0Rlc3RBZGRyZXNzBRBjaGVja0Rlc3RBZGRyZXNzBAp0b2tlbklkU3RyCQERQGV4dHJOYXRpdmUoMTA1OCkBBQp0b2tlbklkS2V5BAd0b2tlbklkCQDZBAEFCnRva2VuSWRTdHIEAXQJAJEDAggFAWkIcGF5bWVudHMAAAQMY2hlY2tBc3NldElkBAckbWF0Y2gwCAUBdAdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEB2Fzc2V0SWQFByRtYXRjaDADCQAAAgUHYXNzZXRJZAUHdG9rZW5JZAYJAAIBCQCsAgIJAKwCAgkArAICAglFeHBlY3RlZCAFCnRva2VuSWRTdHICFSBpbiB0aGUgcGF5bWVudCwgZ290IAkA2AQBBQdhc3NldElkCQACAQkArAICCQCsAgICCUV4cGVjdGVkIAUKdG9rZW5JZFN0cgIaIGluIHRoZSBwYXltZW50LCBnb3QgV2F2ZXMDCQAAAgUMY2hlY2tBc3NldElkBQxjaGVja0Fzc2V0SWQECWxhc3RJbmRleAgJAQlibG9ja01ldGEBBRJtYWluQ2hhaW5MYXN0QmxvY2sCXzcECXF1ZXVlU2l6ZQkAZAIJAGUCBRRuYXRpdmVUcmFuc2ZlcnNDb3VudAUJbGFzdEluZGV4AAEED2NoZWNrUXVldWVMaW1pdAMJAGYCAKABBQlxdWV1ZVNpemUJAQphbW91bnRHdEVxAwUBdADAhD0FCXF1ZXVlU2l6ZQMJAGYCAMAMBQlxdWV1ZVNpemUJAQphbW91bnRHdEVxAwUBdACAreIEBQlxdWV1ZVNpemUDCQBmAgCAGQUJcXVldWVTaXplCQEKYW1vdW50R3RFcQMFAXQAgMLXLwUJcXVldWVTaXplAwkAZgIAgDIFCXF1ZXVlU2l6ZQkBCmFtb3VudEd0RXEDBQF0AICU69wDBQlxdWV1ZVNpemUJAAIBCQCsAgIJAKwCAgIjVHJhbnNmZXJzIGRlbmllZCBmb3IgcXVldWUgc2l6ZSBvZiAJAKQDAQUJcXVldWVTaXplAiguIFdhaXQgdW50aWwgY3VycmVudCB0cmFuc2ZlcnMgcHJvY2Vzc2VkAwkAAAIFD2NoZWNrUXVldWVMaW1pdAUPY2hlY2tRdWV1ZUxpbWl0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRduYXRpdmVUcmFuc2ZlcnNDb3VudEtleQkAZAIFFG5hdGl2ZVRyYW5zZmVyc0NvdW50AAEJAMwIAgkBFW1rTmF0aXZlVHJhbnNmZXJFbnRyeQMFFG5hdGl2ZVRyYW5zZmVyc0NvdW50BRBkZXN0RWxBZGRyZXNzSGV4CAUBdAZhbW91bnQJAMwIAgkBBEJ1cm4CBQd0b2tlbklkCAUBdAZhbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQh3aXRoZHJhdwQMYmxvY2tIYXNoSGV4C21lcmtsZVByb29mFHRyYW5zZmVySW5kZXhJbkJsb2NrBmFtb3VudAQRd2l0aGRyYXdCbG9ja01ldGEJAQlibG9ja01ldGEBBQxibG9ja0hhc2hIZXgEE3dpdGhkcmF3QmxvY2tIZWlnaHQIBRF3aXRoZHJhd0Jsb2NrTWV0YQJfMQQUZmluYWxpemVkQmxvY2tIZWlnaHQICQEJYmxvY2tNZXRhAQkBEUBleHRyTmF0aXZlKDEwNTgpAQURZmluYWxpemVkQmxvY2tLZXkCXzEEGG1haW5DaGFpbkxhc3RCbG9ja0hlaWdodAgJAQlibG9ja01ldGEBBRJtYWluQ2hhaW5MYXN0QmxvY2sCXzEDCQBmAgUTd2l0aGRyYXdCbG9ja0hlaWdodAUUZmluYWxpemVkQmxvY2tIZWlnaHQJAAIBCQCsAgIJAKwCAgkArAICAgpFTCBibG9jayAjCQCkAwEFE3dpdGhkcmF3QmxvY2tIZWlnaHQCLSBpcyBub3QgZmluYWxpemVkLiBUaGUgY3VycmVudCBmaW5hbGl6ZWQgaXMgIwkApAMBBRRmaW5hbGl6ZWRCbG9ja0hlaWdodAQUd2l0aGRyYXdCbG9ja0NoYWluSWQIBRF3aXRoZHJhd0Jsb2NrTWV0YQJfNQQLaXNNYWluQ2hhaW4JAAACBRR3aXRoZHJhd0Jsb2NrQ2hhaW5JZAULbWFpbkNoYWluSWQEEnJlbGF0ZXNUb01haW5DaGFpbgQHJG1hdGNoMAkAnwgBCQEUY2hhaW5Gb3JrZWRIZWlnaHRLZXkBBRR3aXRoZHJhd0Jsb2NrQ2hhaW5JZAMJAAECBQckbWF0Y2gwAgNJbnQEDGZvcmtlZEhlaWdodAUHJG1hdGNoMAkAZgIFDGZvcmtlZEhlaWdodAUTd2l0aGRyYXdCbG9ja0hlaWdodAkAAgEJAKwCAgkArAICCQCsAgIFDGJsb2NrSGFzaEhleAIdIGlzIG9uIGFuIGFsdGVybmF0aXZlIGNoYWluICMJAKQDAQUUd2l0aGRyYXdCbG9ja0NoYWluSWQCOCB0aGF0IHdhcyBub3QgYXBwcm92ZWQgYnkgbWFqb3JpdHkuIFdhaXQgZm9yIHNvbWUgYmxvY2tzAwMFC2lzTWFpbkNoYWluBgUScmVsYXRlc1RvTWFpbkNoYWluBAlyZWNpcGllbnQIBQFpDG9yaWdpbkNhbGxlcgQPcmVjaXBpZW50UGtIYXNoCQDJAQIJAMoBAggFCXJlY2lwaWVudAVieXRlcwACBRRQVUJMSUNfS0VZX0hBU0hfU0laRQQPemVyb0Ftb3VudEJ5dGVzASwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQLYW1vdW50Qnl0ZXMJAJoDAQUGYW1vdW50BAtlbEV2ZW50RGF0YQkAywECCQDLAQIFD3JlY2lwaWVudFBrSGFzaAkAyQECBQ96ZXJvQW1vdW50Qnl0ZXMJAGUCCQDIAQEFD3plcm9BbW91bnRCeXRlcwkAyAEBBQthbW91bnRCeXRlcwULYW1vdW50Qnl0ZXMEEWVsRXZlbnREYXRhRGlnZXN0CQDwFQEFC2VsRXZlbnREYXRhBBJjYWxjdWxhdGVkUm9vdEhhc2gJAL0FAwULbWVya2xlUHJvb2YFEWVsRXZlbnREYXRhRGlnZXN0BRR0cmFuc2ZlckluZGV4SW5CbG9jawQQZXhwZWN0ZWRSb290SGFzaAgFEXdpdGhkcmF3QmxvY2tNZXRhAl82AwkAAAIFEmNhbGN1bGF0ZWRSb290SGFzaAUQZXhwZWN0ZWRSb290SGFzaAQHdG9rZW5JZAkA2QQBCQERQGV4dHJOYXRpdmUoMTA1OCkBBQp0b2tlbklkS2V5BAx0cmFuc2ZlcnNLZXkJARdibG9ja0VsVG9DbFRyYW5zZmVyc0tleQEFDGJsb2NrSGFzaEhleAkAzAgCCQEHUmVpc3N1ZQMFB3Rva2VuSWQFBmFtb3VudAYJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUJcmVjaXBpZW50BQZhbW91bnQFB3Rva2VuSWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUMdHJhbnNmZXJzS2V5CQEJc2V0T3JGYWlsAgkBC3ZhbHVlT3JFbHNlAgkAoggBBQx0cmFuc2ZlcnNLZXkCAAUUdHJhbnNmZXJJbmRleEluQmxvY2sFA25pbAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICFEV4cGVjdGVkIHJvb3QgaGFzaDogCQDcBAEFEGV4cGVjdGVkUm9vdEhhc2gCBywgZ290OiAJANwEAQUSY2FsY3VsYXRlZFJvb3RIYXNoAhUuIEV2ZW50IGRhdGEgZGlnZXN0OiAJANoEAQURZWxFdmVudERhdGFEaWdlc3QCHy4gQ2hlY2sgeW91ciB3aXRoZHJhdyBhcmd1bWVudHMJAAIBCQCsAgIJAKwCAgIJRXhwZWN0ZWQgBQxibG9ja0hhc2hIZXgCLyB0byBiZSBlaXRoZXIgb24gdGhlIG1haW4gY2hhaW4gb3IgcmVsYXRlIHRvIGl0AWkBBXNldHVwBBNnZW5lc2lzQmxvY2tIYXNoSGV4EW1pbmVyUmV3YXJkSW5Hd2VpGXN0YWtpbmdDb250cmFjdEFkZHJlc3NCNTgSZWxCcmlkZ2VBZGRyZXNzSGV4AwkBD2lzQ29udHJhY3RTZXR1cAAJAAIBAiRUaGUgY29udHJhY3QgaGFzIGJlZW4gYWxyZWFkeSBzZXQgdXADCQBmAgAABRFtaW5lclJld2FyZEluR3dlaQkAAgECJFRoZSBtaW5lciByZXdhcmQgbXVzdCBiZSBub25uZWdhdGl2ZQQQZ2VuZXNpc0Jsb2NrSGFzaAkA3QQBBRNnZW5lc2lzQmxvY2tIYXNoSGV4BAdlbXB0eVBrASAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQTZ2VuZXNpc01pbmVyQWRkcmVzcwkApwgBBQdlbXB0eVBrBBdnZW5lc2lzRXRoUmV3YXJkQWRkcmVzcwEUAAAAAAAAAAAAAAAAAAAAAAAAAAAEGWdlbmVzaXNCbG9ja1JlZmVyZW5jZUhhc2gCQDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAEBWlzc3VlCQDCCAUCBVVOSVQwAgxOYXRpdmUgdG9rZW4AAAAIBgQHdG9rZW5JZAkAuAgBBQVpc3N1ZQQQZ2VuZXNpc0Jsb2NrTWV0YQkBEG1rQmxvY2tNZXRhRW50cnkHBRNnZW5lc2lzQmxvY2tIYXNoSGV4BQZoZWlnaHQFGWdlbmVzaXNCbG9ja1JlZmVyZW5jZUhhc2gFE2dlbmVzaXNNaW5lckFkZHJlc3MAAAkA3AQBAQAA////////////AQkAzAgCBRBnZW5lc2lzQmxvY2tNZXRhCQDMCAIJAQtTdHJpbmdFbnRyeQIJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEAAAUTZ2VuZXNpc0Jsb2NrSGFzaEhleAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMAAAAABRNnZW5lc2lzQmxvY2tIYXNoSGV4CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5taW5lclJld2FyZEtleQURbWluZXJSZXdhcmRJbkd3ZWkJAMwIAgkBC1N0cmluZ0VudHJ5AgUZc3Rha2luZ0NvbnRyYWN0QWRkcmVzc0tleQUZc3Rha2luZ0NvbnRyYWN0QWRkcmVzc0I1OAkAzAgCCQELU3RyaW5nRW50cnkCCQEMZXBvY2hNZXRhS2V5AQUGaGVpZ2h0CQCsAgIJAKwCAgkApQgBBRNnZW5lc2lzTWluZXJBZGRyZXNzAgMsMCwFE2dlbmVzaXNCbG9ja0hhc2hIZXgJAMwIAgkBC1N0cmluZ0VudHJ5AgURZmluYWxpemVkQmxvY2tLZXkFE2dlbmVzaXNCbG9ja0hhc2hIZXgJAMwIAgUFaXNzdWUJAMwIAgkBC1N0cmluZ0VudHJ5AgUKdG9rZW5JZEtleQkA2AQBBQd0b2tlbklkCQDMCAIJAQtTdHJpbmdFbnRyeQIFEmVsQnJpZGdlQWRkcmVzc0tleQkArAICAgIweAUSZWxCcmlkZ2VBZGRyZXNzSGV4BQNuaWwArCuuAQ==", "height": 3254025, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5CHw1N17WqBX9atkNtchAvakKiL3RXKrEgPEe8Ce97Y2 Next: BQBbkSKsGaXUizoNRKY4fRvWjfiSvYxu7VfN1gVNdowc Diff:
OldNewDifferences
816816 else throw(("Expected one payment as a transfer amount, got " + toString(size(i.payments))))
817817 if ((checkPayment == checkPayment))
818818 then {
819- let checkDestAddress = if ((size(fromBase16String(split(destElAddressHex, "0x")[1])) == 20))
819+ let checkDestAddress = if ((size(fromBase16String(destElAddressHex)) == 20))
820820 then true
821821 else throw("Destination address must be a valid ethereum address")
822822 if ((checkDestAddress == checkDestAddress))
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 8 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let INT_MAX = 9223372036854775807
55
66 let WAVES = 100000000
77
88 let MIN_BALANCE = (20000 * WAVES)
99
1010 let SEP = ","
1111
1212 let BLOCK_HASH_SIZE = 32
1313
1414 let ADDRESS_SIZE = 26
1515
1616 let PUBLIC_KEY_HASH_SIZE = 20
1717
1818 let ROOT_HASH_SIZE = 32
1919
2020 let MAX_CL_TO_EL_TRANSFERS = 16
2121
2222 let zeroesStr = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
2323
2424 let thisEpochDataKey = "thisEpochData"
2525
2626 let allMinersKey = "allMiners"
2727
2828 let mainChainIdKey = "mainChainId"
2929
3030 let lastChainIdKey = "lastChainId"
3131
3232 let firstValidAltChainIdKey = "firstValidAltChainId"
3333
3434 let minerRewardKey = "minerReward"
3535
3636 let stakingContractAddressKey = "stakingContractAddress"
3737
3838 let blockMetaK = "block_0x"
3939
4040 let finalizedBlockKey = "finalizedBlock"
4141
4242 let tokenIdKey = "tokenId"
4343
4444 let elBridgeAddressKey = "elBridgeAddress"
4545
4646 let nativeTransfersCountKey = "nativeTransfersCount"
4747
4848 func pad (i) = {
4949 let s = toString(i)
5050 match size(s) {
5151 case _ =>
5252 if ((1 == $match0))
5353 then ("0000000" + s)
5454 else if ((2 == $match0))
5555 then ("000000" + s)
5656 else if ((3 == $match0))
5757 then ("00000" + s)
5858 else if ((4 == $match0))
5959 then ("0000" + s)
6060 else if ((5 == $match0))
6161 then ("000" + s)
6262 else if ((6 == $match0))
6363 then ("00" + s)
6464 else if ((7 == $match0))
6565 then ("0" + s)
6666 else s
6767 }
6868 }
6969
7070
7171 func blockElToClTransfersKey (blockHashHex) = ("elToClTransfers_0x" + blockHashHex)
7272
7373
7474 func epochMetaKey (epoch) = ("epoch_" + pad(epoch))
7575
7676
7777 func chainFirstBlockIdKey (chainId) = (("chain" + toString(chainId)) + "FirstBlock")
7878
7979
8080 func chainMetaKey (chainId) = ("chain_" + pad(chainId))
8181
8282
8383 func chainLastHeightKey (chainId,miner) = ((("chain_" + pad(chainId)) + "_") + toString(miner))
8484
8585
8686 func chainForkedHeightKey (chainId) = (("chain_" + pad(chainId)) + "ForkedHeight")
8787
8888
8989 func supportersKey (chainId) = (("chain" + toString(chainId)) + "Supporters")
9090
9191
9292 func minerRewardAddressKey (minerAddr) = (("miner_" + minerAddr) + "_RewardAddress")
9393
9494
9595 func minerPkKey (rewardAddress) = (("miner_0x" + rewardAddress) + "_PK")
9696
9797
9898 func minerChainIdKey (miner) = (("miner_" + toString(miner)) + "_ChainId")
9999
100100
101101 let nativeTransfersCount = valueOrElse(getInteger(this, nativeTransfersCountKey), 0)
102102
103103 func nativeTransferKey (index) = ("nativeTransfer_" + toString(index))
104104
105105
106106 func mkNativeTransferEntry (index,destElAddressHex,amount) = StringEntry(nativeTransferKey(index), ((("0x" + destElAddressHex) + SEP) + toString(amount)))
107107
108108
109109 func ensureCorrectTransfers (refTransferIndex,transferIndex,expectReward) = {
110110 let maxTransfers = if (expectReward)
111111 then (MAX_CL_TO_EL_TRANSFERS - 1)
112112 else MAX_CL_TO_EL_TRANSFERS
113113 let actualTransfers = (transferIndex - refTransferIndex)
114114 let checkNumber = if ((actualTransfers > maxTransfers))
115115 then throw(((("Allowed only " + toString(maxTransfers)) + " transfers, got ") + toString(actualTransfers)))
116116 else true
117117 if ((checkNumber == checkNumber))
118118 then if ((transferIndex >= nativeTransfersCount))
119119 then throw(((("Attempt to transfer #" + toString(transferIndex)) + ". Available transfers: ") + toString(nativeTransfersCount)))
120120 else true
121121 else throw("Strict value is not equal to itself.")
122122 }
123123
124124
125125 func amountGtEq (t,gtEq,queueSize) = if ((t.amount >= gtEq))
126126 then true
127127 else throw((((((("Transferring amount " + toString(t.amount)) + " should be >= ") + toString(gtEq)) + " for queue size of ") + toString(queueSize)) + ". Transfer more or wait"))
128128
129129
130130 let stakingContractAddress = match getString(this, stakingContractAddressKey) {
131131 case s: String =>
132132 valueOrErrorMessage(addressFromString(s), ("invalid staking contract address: " + s))
133133 case _ =>
134134 Address(getBinaryValue(this, stakingContractAddressKey))
135135 }
136136
137137 func generatingBalance (address) = match getString(stakingContractAddress, ("%s__" + toString(address))) {
138138 case str: String =>
139139 let paramList = split(str, "__")
140140 let prevHeight = parseIntValue(paramList[1])
141141 let prevBalance = parseIntValue(paramList[2])
142142 let nextHeight = parseIntValue(paramList[3])
143143 let nextBalance = parseIntValue(paramList[4])
144144 if ((height >= nextHeight))
145145 then nextBalance
146146 else if ((height >= prevHeight))
147147 then prevBalance
148148 else 0
149149 case _ =>
150150 0
151151 }
152152
153153
154154 func chainMeta (chainId) = {
155155 let s = getStringValue(chainMetaKey(chainId))
156156 let items = split(s, SEP)
157157 $Tuple2(parseIntValue(items[0]), items[1])
158158 }
159159
160160
161161 func mkChainMetaEntry (chainId,newChainHeight,blockHashHex) = StringEntry(chainMetaKey(chainId), ((toString(newChainHeight) + SEP) + blockHashHex))
162162
163163
164164 let mainChainId = valueOrElse(getInteger(mainChainIdKey), 0)
165165
166166 let $t058215887 = chainMeta(mainChainId)
167167
168168 let mainChainHeight = $t058215887._1
169169
170170 let mainChainLastBlock = $t058215887._2
171171
172172 func epochMeta (epoch) = match getString(epochMetaKey(epoch)) {
173173 case s: String =>
174174 let fragments = split(s, SEP)
175175 $Tuple3(addressFromStringValue(fragments[0]), parseIntValue(fragments[1]), fragments[2])
176176 case _ =>
177177 unit
178178 }
179179
180180
181181 let $t061186582 = match epochMeta(height) {
182182 case m: (Address, Int, String) =>
183183 m
184184 case _ =>
185185 match getString(thisEpochDataKey) {
186186 case rawThisEpochData: String =>
187187 let thisEpochData = split(rawThisEpochData, SEP)
188188 let thisEpoch = parseIntValue(thisEpochData[0])
189189 $Tuple3(if ((thisEpoch == height))
190190 then addressFromStringValue(thisEpochData[1])
191191 else unit, 0, "")
192192 case _ =>
193193 $Tuple3(unit, 0, "")
194194 }
195195 }
196196
197197 let thisEpochMiner = $t061186582._1
198198
199199 let thisEpochRef = $t061186582._2
200200
201201 let thisEpochLastBlock = $t061186582._3
202202
203203 let allMinersStr = valueOrElse(getString(allMinersKey), "")
204204
205205 let allMiners = match allMinersStr {
206206 case _ =>
207207 if (("" == $match0))
208208 then nil
209209 else if ($isInstanceOf($match0, "String"))
210210 then {
211211 let raw = $match0
212212 split_4C(raw, SEP)
213213 }
214214 else throw("Match error")
215215 }
216216
217217 func blockMeta (blockId) = {
218218 let meta = getBinaryValue((blockMetaK + blockId))
219219 let metaSize = size(meta)
220220 let blockHeight = toInt(meta)
221221 let blockEpoch = toInt(meta, 8)
222222 let blockParent = take(drop(meta, 16), BLOCK_HASH_SIZE)
223223 let blockGenerator = take(drop(meta, (16 + BLOCK_HASH_SIZE)), ADDRESS_SIZE)
224224 let chainId = toInt(meta, ((16 + BLOCK_HASH_SIZE) + ADDRESS_SIZE))
225225 let baseOffset = ((24 + BLOCK_HASH_SIZE) + ADDRESS_SIZE)
226226 let remainingBytes = (metaSize - baseOffset)
227227 let elToClTransfersRootHash = if ((remainingBytes >= ROOT_HASH_SIZE))
228228 then take(drop(meta, baseOffset), ROOT_HASH_SIZE)
229229 else base58''
230230 let lastClToElTransferIndex = if (if ((remainingBytes == 8))
231231 then true
232232 else (remainingBytes > ROOT_HASH_SIZE))
233233 then toInt(meta, (baseOffset + size(elToClTransfersRootHash)))
234234 else -1
235235 $Tuple7(blockHeight, blockEpoch, blockParent, blockGenerator, chainId, elToClTransfersRootHash, lastClToElTransferIndex)
236236 }
237237
238238
239239 func mkBlockMetaEntry (blockHashHex,blockHeight,blockParentHex,blockGenerator,chainId,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
240240 let blockMetaBytes = ((((((toBytes(blockHeight) + toBytes(height)) + fromBase16String(blockParentHex)) + blockGenerator.bytes) + toBytes(chainId)) + fromBase16String(elToClTransfersRootHashHex)) + toBytes(lastClToElTransferIndex))
241241 BinaryEntry((blockMetaK + blockHashHex), blockMetaBytes)
242242 }
243243
244244
245245 func lastHeightBy (miner,chainId) = match getInteger(chainLastHeightKey(chainId, miner)) {
246246 case h: Int =>
247247 h
248248 case _ =>
249249 let blockHash = getStringValue(((("chain" + toString(chainId)) + "LastMinedBy") + toString(miner)))
250250 blockMeta(blockHash)._1
251251 }
252252
253253
254254 let $t084809446 = {
255255 let hitSource = match lastBlock.vrf {
256256 case vrf: ByteVector =>
257257 vrf
258258 case _ =>
259259 lastBlock.generationSignature
260260 }
261261 func processMiner (prev,miner) = {
262262 let $t087788841 = prev
263263 let prevDelay = $t087788841._1
264264 let prevMiner = $t087788841._2
265265 let prevTotalBalance = $t087788841._3
266266 let prevMiners = $t087788841._4
267267 let minerAddress = addressFromStringValue(miner)
268268 let wavesGenBalance = wavesBalance(minerAddress).generating
269269 let minerBalance = generatingBalance(minerAddress)
270270 if (if ((MIN_BALANCE > wavesGenBalance))
271271 then true
272272 else (0 >= minerBalance))
273273 then prev
274274 else {
275275 let nextDelay = calculateDelay(minerAddress, minerBalance)
276276 if ((prevDelay > nextDelay))
277277 then $Tuple4(nextDelay, miner, (prevTotalBalance + minerBalance), (prevMiners :+ miner))
278278 else $Tuple4(prevDelay, prevMiner, (prevTotalBalance + minerBalance), (prevMiners :+ miner))
279279 }
280280 }
281281
282282 let $l = allMiners
283283 let $s = size($l)
284284 let $acc0 = $Tuple4(INT_MAX, "", 0, nil)
285285 func $f0_1 ($a,$i) = if (($i >= $s))
286286 then $a
287287 else processMiner($a, $l[$i])
288288
289289 func $f0_2 ($a,$i) = if (($i >= $s))
290290 then $a
291291 else throw("List size exceeds 50")
292292
293293 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
294294 }
295295
296296 let computedDelay = $t084809446._1
297297
298298 let computedGenerator = $t084809446._2
299299
300300 let computedTotalBalance = $t084809446._3
301301
302302 let filteredMiners = $t084809446._4
303303
304304 func getChainLastBlockId (chainId) = chainMeta(chainId)._2
305305
306306
307307 let $t095129619 = blockMeta(mainChainLastBlock)
308308
309309 let mclbIgnored1 = $t095129619._1
310310
311311 let mainChainEpoch = $t095129619._2
312312
313313 let mainChainParentHash = $t095129619._3
314314
315315 let mainChainGenerator = $t095129619._4
316316
317317 func calculateFinalizedBlockHash (curMiner,curPrevEpoch,curLastBlockHash) = {
318318 let offsets_100 = split_4C("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::", "")
319319 let halfBalance = (computedTotalBalance / 2)
320320 func step (prev,next) = {
321321 let $t0998510049 = prev
322322 let thisEpoch = $t0998510049._1
323323 let totalBalance = $t0998510049._2
324324 let maybeSafeEpoch = $t0998510049._3
325325 let prevMiners = $t0998510049._4
326326 match maybeSafeEpoch {
327327 case _: Unit =>
328328 let $t01010710273 = if ((thisEpoch == height))
329329 then $Tuple3(curMiner, curPrevEpoch, curLastBlockHash)
330330 else value(epochMeta(thisEpoch))
331331 let miner = $t01010710273._1
332332 let prevEpoch = $t01010710273._2
333333 let lastBlockHash = $t01010710273._3
334334 if ((prevEpoch == 0))
335335 then $Tuple4(thisEpoch, totalBalance, lastBlockHash, allMiners)
336336 else {
337337 let $t01039810600 = if (containsElement(prevMiners, miner))
338338 then $Tuple2(totalBalance, prevMiners)
339339 else $Tuple2((totalBalance + generatingBalance(miner)), miner :: prevMiners)
340340 let newTotalBalance = $t01039810600._1
341341 let newMiners = $t01039810600._2
342342 if ((newTotalBalance > halfBalance))
343343 then $Tuple4(thisEpoch, newTotalBalance, lastBlockHash, allMiners)
344344 else $Tuple4(prevEpoch, newTotalBalance, unit, newMiners)
345345 }
346346 case _ =>
347347 prev
348348 }
349349 }
350350
351351 let $t01083310966 = {
352352 let $l = (offsets_100 ++ offsets_100)
353353 let $s = size($l)
354354 let $acc0 = $Tuple4(height, 0, unit, nil)
355355 func $f0_1 ($a,$i) = if (($i >= $s))
356356 then $a
357357 else step($a, $l[$i])
358358
359359 func $f0_2 ($a,$i) = if (($i >= $s))
360360 then $a
361361 else throw("List size exceeds 200")
362362
363363 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100), 101), 102), 103), 104), 105), 106), 107), 108), 109), 110), 111), 112), 113), 114), 115), 116), 117), 118), 119), 120), 121), 122), 123), 124), 125), 126), 127), 128), 129), 130), 131), 132), 133), 134), 135), 136), 137), 138), 139), 140), 141), 142), 143), 144), 145), 146), 147), 148), 149), 150), 151), 152), 153), 154), 155), 156), 157), 158), 159), 160), 161), 162), 163), 164), 165), 166), 167), 168), 169), 170), 171), 172), 173), 174), 175), 176), 177), 178), 179), 180), 181), 182), 183), 184), 185), 186), 187), 188), 189), 190), 191), 192), 193), 194), 195), 196), 197), 198), 199), 200)
364364 }
365365 let fallbackEpoch = $t01083310966._1
366366 let totalBalance = $t01083310966._2
367367 let finalizedBlockHashOpt = $t01083310966._3
368368 let miners = $t01083310966._4
369369 match finalizedBlockHashOpt {
370370 case finalizedBlockHash: String =>
371371 finalizedBlockHash
372372 case _ =>
373373 value(epochMeta(fallbackEpoch))._3
374374 }
375375 }
376376
377377
378378 func supportingBalance (chainId) = {
379379 func addBalance (acc,generatorStr) = {
380380 let $t01123611272 = acc
381381 let totalBalance = $t01123611272._1
382382 let generators = $t01123611272._2
383383 let generator = addressFromStringValue(generatorStr)
384384 if (containsElement(generators, generator))
385385 then acc
386386 else {
387387 let balance = generatingBalance(generator)
388388 $Tuple2((totalBalance + balance), (generators :+ generator))
389389 }
390390 }
391391
392392 let allGenerators = split_4C(getStringValue(supportersKey(chainId)), SEP)
393393 let $t01159411659 = {
394394 let $l = allGenerators
395395 let $s = size($l)
396396 let $acc0 = $Tuple2(0, nil)
397397 func $f0_1 ($a,$i) = if (($i >= $s))
398398 then $a
399399 else addBalance($a, $l[$i])
400400
401401 func $f0_2 ($a,$i) = if (($i >= $s))
402402 then $a
403403 else throw("List size exceeds 100")
404404
405405 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90), 91), 92), 93), 94), 95), 96), 97), 98), 99), 100)
406406 }
407407 let balance = $t01159411659._1
408408 let _g = $t01159411659._2
409409 balance
410410 }
411411
412412
413413 func isContractSetup () = isDefined(getInteger(minerRewardKey))
414414
415415
416416 func ensureMiningEpoch (generator) = if ((toString(generator) != computedGenerator))
417417 then throw(((((toBase58String(generator.bytes) + " is not allowed to mine in ") + toString(height)) + " epoch. Expected ") + computedGenerator))
418418 else unit
419419
420420
421421 func isReferenceCorrect (reference,lastBlock) = if ((reference == lastBlock))
422422 then unit
423423 else throw(((("Expected a reference to the chain last block: 0x" + lastBlock) + ". Got: 0x") + reference))
424424
425425
426426 func chainIsInactive (chainId) = {
427427 let firstBlockId = getStringValue(chainFirstBlockIdKey(chainId))
428428 let firstValidAltChainId = valueOrElse(getInteger(firstValidAltChainIdKey), 0)
429429 if ((firstValidAltChainId > chainId))
430430 then true
431431 else (blockMeta(getStringValue(finalizedBlockKey))._1 > blockMeta(firstBlockId)._1)
432432 }
433433
434434
435435 func minerChainId (miner) = valueOrElse(getInteger(minerChainIdKey(miner)), getInteger(("chainIdOf" + toString(miner))))
436436
437437
438438 func ensureExpectedOrInactiveChain (generator,expectedChainId,checkHeightBlock) = {
439439 let heightIsCorrect = match checkHeightBlock {
440440 case blockHash: String =>
441441 let lastMinedBlockHeight = lastHeightBy(generator, mainChainId)
442442 ((blockMeta(blockHash)._1 + 1) > lastMinedBlockHeight)
443443 case _ =>
444444 true
445445 }
446446 match minerChainId(generator) {
447447 case currentId: Int =>
448448 if (if ((currentId == expectedChainId))
449449 then true
450450 else if (chainIsInactive(currentId))
451451 then heightIsCorrect
452452 else false)
453453 then unit
454454 else throw(("miner is mining other chain " + toString(currentId)))
455455 case _ =>
456456 unit
457457 }
458458 }
459459
460460
461461 func ensureCorrectEpoch (epoch) = if ((epoch == height))
462462 then unit
463463 else throw(((("Expected block from epoch " + toString(height)) + ". Got ") + toString(epoch)))
464464
465465
466466 func addSupporter (chainId,generator) = {
467467 let supportersStr = getStringValue(supportersKey(chainId))
468468 let supporters = split_4C(supportersStr, SEP)
469469 if (containsElement(supporters, toString(generator)))
470470 then nil
471471 else [StringEntry(supportersKey(chainId), ((supportersStr + SEP) + toString(generator)))]
472472 }
473473
474474
475475 func setOrFail (flags,index) = if ((0 > index))
476476 then throw(("Can't withdraw at negative index: " + toString(index)))
477477 else {
478478 let flagsSize = size(flags)
479479 if ((index >= flagsSize))
480480 then {
481481 let addZeroes = (index - flagsSize)
482482 if ((addZeroes > size(zeroesStr)))
483483 then throw((("Can't add " + toString(addZeroes)) + " empty flags. Contact with developers"))
484484 else ((flags + take(zeroesStr, addZeroes)) + "1")
485485 }
486486 else {
487487 let tail = drop(flags, index)
488488 let atIndex = take(tail, 1)
489489 if ((atIndex == "0"))
490490 then ((take(flags, index) + "1") + drop(tail, 1))
491491 else throw((("Transfer #" + toString(index)) + " has been already taken"))
492492 }
493493 }
494494
495495
496496 func validateBlockHash (hexStr) = {
497497 let decodedBytes = fromBase16String(hexStr)
498498 if ((size(decodedBytes) != 32))
499499 then throw("invalid block id length")
500500 else hexStr
501501 }
502502
503503
504504 func getUpdateFinalizedBlockAction (caller,newBlockHashHex,prevEpoch) = {
505505 let curFinalizedBlockHeight = blockMeta(getStringValue(finalizedBlockKey))._1
506506 let newFinalizedBlockHash = calculateFinalizedBlockHash(caller, prevEpoch, newBlockHashHex)
507507 if (if ((newFinalizedBlockHash == newBlockHashHex))
508508 then true
509509 else (blockMeta(newFinalizedBlockHash)._1 > curFinalizedBlockHeight))
510510 then [StringEntry(finalizedBlockKey, newFinalizedBlockHash)]
511511 else nil
512512 }
513513
514514
515515 @Callable(i)
516516 func appendBlock_v3 (blockHashHex,referenceHex,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
517517 let checkCaller = if ((thisEpochMiner == i.originCaller))
518518 then true
519519 else match thisEpochMiner {
520520 case epochMiner: Address =>
521521 throw(("not allowed to forge blocks in this epoch, expected from " + toString(epochMiner)))
522522 case _ =>
523523 throw("not allowed to forge blocks in this epoch, epoch miner is absent")
524524 }
525525 if ((checkCaller == checkCaller))
526526 then {
527527 let chainId = valueOrElse(minerChainId(i.originCaller), mainChainId)
528528 let $t01580415855 = chainMeta(chainId)
529529 let chainHeight = $t01580415855._1
530530 let lastBlockId = $t01580415855._2
531531 let checkReference = isReferenceCorrect(referenceHex, lastBlockId)
532532 if ((checkReference == checkReference))
533533 then {
534534 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._7, lastClToElTransferIndex, false)
535535 if ((checkTransfers == checkTransfers))
536536 then {
537537 let newChainHeight = (chainHeight + 1)
538538 let checkBlockHash = validateBlockHash(blockHashHex)
539539 if ((checkBlockHash == checkBlockHash))
540540 then [mkBlockMetaEntry(blockHashHex, newChainHeight, lastBlockId, i.originCaller, chainId, elToClTransfersRootHashHex, lastClToElTransferIndex), IntegerEntry(chainLastHeightKey(chainId, i.originCaller), newChainHeight), mkChainMetaEntry(chainId, newChainHeight, blockHashHex), StringEntry(epochMetaKey(height), ((((toString(value(thisEpochMiner)) + SEP) + toString(thisEpochRef)) + SEP) + blockHashHex))]
541541 else throw("Strict value is not equal to itself.")
542542 }
543543 else throw("Strict value is not equal to itself.")
544544 }
545545 else throw("Strict value is not equal to itself.")
546546 }
547547 else throw("Strict value is not equal to itself.")
548548 }
549549
550550
551551
552552 @Callable(i)
553553 func extendMainChain_v3 (blockHashHex,referenceHex,epoch,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
554554 let checkBlockHash = validateBlockHash(blockHashHex)
555555 if ((checkBlockHash == checkBlockHash))
556556 then {
557557 let checkEpoch = ensureCorrectEpoch(epoch)
558558 if ((checkEpoch == checkEpoch))
559559 then {
560560 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, mainChainId, unit)
561561 if ((checkChain == checkChain))
562562 then {
563563 let checkReference = isReferenceCorrect(referenceHex, mainChainLastBlock)
564564 if ((checkReference == checkReference))
565565 then {
566566 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._7, lastClToElTransferIndex, true)
567567 if ((checkTransfers == checkTransfers))
568568 then {
569569 let thisEpochMeta = match epochMeta(height) {
570570 case _: Unit =>
571571 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(mainChainEpoch)) + SEP) + blockHashHex))
572572 case other =>
573573 throw("Epoch already started")
574574 }
575575 if ((thisEpochMeta == thisEpochMeta))
576576 then {
577577 let checkGenerator = ensureMiningEpoch(i.originCaller)
578578 if ((checkGenerator == checkGenerator))
579579 then {
580580 let updateFinalizedBlock = getUpdateFinalizedBlockAction(i.originCaller, blockHashHex, mainChainEpoch)
581581 let newChainHeight = (mainChainHeight + 1)
582582 ([mkBlockMetaEntry(blockHashHex, newChainHeight, mainChainLastBlock, i.originCaller, mainChainId, elToClTransfersRootHashHex, lastClToElTransferIndex), mkChainMetaEntry(mainChainId, newChainHeight, blockHashHex), IntegerEntry(minerChainIdKey(i.originCaller), mainChainId), IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), newChainHeight), thisEpochMeta] ++ updateFinalizedBlock)
583583 }
584584 else throw("Strict value is not equal to itself.")
585585 }
586586 else throw("Strict value is not equal to itself.")
587587 }
588588 else throw("Strict value is not equal to itself.")
589589 }
590590 else throw("Strict value is not equal to itself.")
591591 }
592592 else throw("Strict value is not equal to itself.")
593593 }
594594 else throw("Strict value is not equal to itself.")
595595 }
596596 else throw("Strict value is not equal to itself.")
597597 }
598598
599599
600600
601601 @Callable(i)
602602 func startAltChain_v3 (blockHashHex,referenceHex,epoch,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
603603 let checkBlockHash = validateBlockHash(blockHashHex)
604604 if ((checkBlockHash == checkBlockHash))
605605 then {
606606 let checkEpoch = ensureCorrectEpoch(epoch)
607607 if ((checkEpoch == checkEpoch))
608608 then {
609609 let $t01827818400 = blockMeta(referenceHex)
610610 let refChainHeight = $t01827818400._1
611611 let refEpoch = $t01827818400._2
612612 let refRef = $t01827818400._3
613613 let refGenerator = $t01827818400._4
614614 let refIgnored5 = $t01827818400._5
615615 let refIgnored6 = $t01827818400._6
616616 let refTransferIndex = $t01827818400._7
617617 let finalizedEpoch = blockMeta(getStringValue(finalizedBlockKey))._2
618618 let epochRef = if ((refEpoch >= finalizedEpoch))
619619 then refEpoch
620620 else throw((((("Can not start alt chain from epoch " + toString(refEpoch)) + ", epoch ") + toString(finalizedEpoch)) + " is finalized"))
621621 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, mainChainId, referenceHex)
622622 if ((checkChain == checkChain))
623623 then {
624624 let checkTransfers = ensureCorrectTransfers(refTransferIndex, lastClToElTransferIndex, true)
625625 if ((checkTransfers == checkTransfers))
626626 then {
627627 let newChainId = (valueOrElse(getInteger(lastChainIdKey), 0) + 1)
628628 let newChainHeight = (refChainHeight + 1)
629629 let thisEpochMeta = match epochMeta(height) {
630630 case _: Unit =>
631631 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(epochRef)) + SEP) + blockHashHex))
632632 case other =>
633633 throw("Epoch already started")
634634 }
635635 let checkGenerator = ensureMiningEpoch(i.originCaller)
636636 if ((checkGenerator == checkGenerator))
637637 then [thisEpochMeta, mkBlockMetaEntry(blockHashHex, newChainHeight, referenceHex, i.originCaller, newChainId, elToClTransfersRootHashHex, lastClToElTransferIndex), StringEntry(chainFirstBlockIdKey(newChainId), blockHashHex), mkChainMetaEntry(newChainId, newChainHeight, blockHashHex), IntegerEntry(minerChainIdKey(i.originCaller), newChainId), IntegerEntry(chainLastHeightKey(newChainId, i.originCaller), newChainHeight), IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), newChainHeight), StringEntry(supportersKey(newChainId), toString(i.originCaller)), IntegerEntry(lastChainIdKey, newChainId)]
638638 else throw("Strict value is not equal to itself.")
639639 }
640640 else throw("Strict value is not equal to itself.")
641641 }
642642 else throw("Strict value is not equal to itself.")
643643 }
644644 else throw("Strict value is not equal to itself.")
645645 }
646646 else throw("Strict value is not equal to itself.")
647647 }
648648
649649
650650
651651 @Callable(i)
652652 func extendAltChain_v3 (chainId,blockHashHex,referenceHex,epoch,elToClTransfersRootHashHex,lastClToElTransferIndex) = {
653653 let checkBlockHash = validateBlockHash(blockHashHex)
654654 if ((checkBlockHash == checkBlockHash))
655655 then {
656656 let checkEpoch = ensureCorrectEpoch(epoch)
657657 if ((checkEpoch == checkEpoch))
658658 then {
659659 let chainFirstBlockMeta = blockMeta(getStringValue(chainFirstBlockIdKey(chainId)))
660660 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, chainId, toBase16String(chainFirstBlockMeta._3))
661661 if ((checkChain == checkChain))
662662 then {
663663 let $t02074420798 = chainMeta(chainId)
664664 let chainHeight = $t02074420798._1
665665 let chainLastBlock = $t02074420798._2
666666 let checkReference = isReferenceCorrect(referenceHex, chainLastBlock)
667667 if ((checkReference == checkReference))
668668 then {
669669 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._7, lastClToElTransferIndex, true)
670670 if ((checkTransfers == checkTransfers))
671671 then {
672672 let newChainHeight = (chainHeight + 1)
673673 let prevEpoch = blockMeta(referenceHex)._2
674674 let updateMainChainData = if ((supportingBalance(chainId) > (computedTotalBalance / 2)))
675675 then {
676676 let lastChainId = valueOrElse(getInteger(lastChainIdKey), 0)
677677 let updateFinalizedBlock = getUpdateFinalizedBlockAction(i.originCaller, blockHashHex, prevEpoch)
678678 ([IntegerEntry(chainForkedHeightKey(mainChainId), chainFirstBlockMeta._1), IntegerEntry(mainChainIdKey, chainId), IntegerEntry(firstValidAltChainIdKey, (lastChainId + 1))] ++ updateFinalizedBlock)
679679 }
680680 else nil
681681 let thisEpochMeta = match epochMeta(height) {
682682 case _: Unit =>
683683 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(prevEpoch)) + SEP) + blockHashHex))
684684 case other =>
685685 throw("Epoch already started")
686686 }
687687 if ((thisEpochMeta == thisEpochMeta))
688688 then {
689689 let checkGenerator = ensureMiningEpoch(i.originCaller)
690690 if ((checkGenerator == checkGenerator))
691691 then {
692692 let updateMainChainLastMinedBlock = if (if ((updateMainChainData == nil))
693693 then (valueOrElse(minerChainId(i.originCaller), 0) != chainId)
694694 else false)
695695 then [IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), chainFirstBlockMeta._1)]
696696 else nil
697697 ((([mkBlockMetaEntry(blockHashHex, newChainHeight, referenceHex, i.originCaller, chainId, elToClTransfersRootHashHex, lastClToElTransferIndex), mkChainMetaEntry(chainId, newChainHeight, blockHashHex), thisEpochMeta, IntegerEntry(minerChainIdKey(i.originCaller), chainId), IntegerEntry(chainLastHeightKey(chainId, i.originCaller), newChainHeight)] ++ updateMainChainData) ++ addSupporter(chainId, i.originCaller)) ++ updateMainChainLastMinedBlock)
698698 }
699699 else throw("Strict value is not equal to itself.")
700700 }
701701 else throw("Strict value is not equal to itself.")
702702 }
703703 else throw("Strict value is not equal to itself.")
704704 }
705705 else throw("Strict value is not equal to itself.")
706706 }
707707 else throw("Strict value is not equal to itself.")
708708 }
709709 else throw("Strict value is not equal to itself.")
710710 }
711711 else throw("Strict value is not equal to itself.")
712712 }
713713
714714
715715
716716 @Callable(i)
717717 func join (rewardAddress) = {
718718 func ensureNotOverrideOtherMinerPk (elAddressHex) = match getBinary(minerPkKey(elAddressHex)) {
719719 case pk: ByteVector =>
720720 if ((pk == i.originCallerPublicKey))
721721 then unit
722722 else throw(((("EL miner address " + elAddressHex) + " is already linked with ") + toBase58String(pk)))
723723 case _ =>
724724 unit
725725 }
726726
727727 if (!(isContractSetup()))
728728 then throw("The contract has not yet set up")
729729 else if ((MIN_BALANCE > wavesBalance(i.originCaller).generating))
730730 then throw(((("Insufficient generating balance: " + toString(wavesBalance(i.originCaller).generating)) + ". Required: ") + toString(MIN_BALANCE)))
731731 else if ((size(rewardAddress) != 20))
732732 then throw("rewardAddress should be an L2 address")
733733 else if ((size(allMiners) >= 50))
734734 then throw("too many miners")
735735 else {
736736 func checkExistence (exists,miner) = if (exists)
737737 then true
738738 else (miner == toString(i.originCaller))
739739
740740 let alreadyExists = {
741741 let $l = allMiners
742742 let $s = size($l)
743743 let $acc0 = false
744744 func $f0_1 ($a,$i) = if (($i >= $s))
745745 then $a
746746 else checkExistence($a, $l[$i])
747747
748748 func $f0_2 ($a,$i) = if (($i >= $s))
749749 then $a
750750 else throw("List size exceeds 50")
751751
752752 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
753753 }
754754 if (alreadyExists)
755755 then nil
756756 else {
757757 let newMiner = toString(i.originCaller)
758758 let rewardAddressHex = toBase16String(rewardAddress)
759759 let check = ensureNotOverrideOtherMinerPk(rewardAddressHex)
760760 if ((check == check))
761761 then {
762762 let newMiners = if ((size(allMiners) == 0))
763763 then newMiner
764764 else ((allMinersStr + SEP) + newMiner)
765765 let deleteOldRewardAddressPk = match getString(minerRewardAddressKey(newMiner)) {
766766 case oldAddress: String =>
767767 if ((oldAddress == toBase16String(rewardAddress)))
768768 then nil
769769 else [DeleteEntry(minerPkKey(oldAddress))]
770770 case _ =>
771771 nil
772772 }
773773 ([StringEntry(allMinersKey, newMiners), StringEntry(minerRewardAddressKey(newMiner), ("0x" + rewardAddressHex)), BinaryEntry(minerPkKey(rewardAddressHex), i.originCallerPublicKey)] ++ deleteOldRewardAddressPk)
774774 }
775775 else throw("Strict value is not equal to itself.")
776776 }
777777 }
778778 }
779779
780780
781781
782782 @Callable(i)
783783 func leave () = {
784784 let leavingMiner = toString(i.originCaller)
785785 func skipLeavingMiner (acc,miner) = if ((miner == leavingMiner))
786786 then acc
787787 else (acc :+ miner)
788788
789789 let remainingMiners = {
790790 let $l = allMiners
791791 let $s = size($l)
792792 let $acc0 = nil
793793 func $f0_1 ($a,$i) = if (($i >= $s))
794794 then $a
795795 else skipLeavingMiner($a, $l[$i])
796796
797797 func $f0_2 ($a,$i) = if (($i >= $s))
798798 then $a
799799 else throw("List size exceeds 50")
800800
801801 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
802802 }
803803 let rewardAddrKey = minerRewardAddressKey(leavingMiner)
804804 let prevRewardAddress = valueOrErrorMessage(getString(this, rewardAddrKey), "miner has never joined")
805805 if ((thisEpochMiner == i.originCaller))
806806 then throw("designated miner can't leave")
807807 else [StringEntry(allMinersKey, makeString_2C(remainingMiners, SEP))]
808808 }
809809
810810
811811
812812 @Callable(i)
813813 func transfer (destElAddressHex) = {
814814 let checkPayment = if ((size(i.payments) == 1))
815815 then true
816816 else throw(("Expected one payment as a transfer amount, got " + toString(size(i.payments))))
817817 if ((checkPayment == checkPayment))
818818 then {
819- let checkDestAddress = if ((size(fromBase16String(split(destElAddressHex, "0x")[1])) == 20))
819+ let checkDestAddress = if ((size(fromBase16String(destElAddressHex)) == 20))
820820 then true
821821 else throw("Destination address must be a valid ethereum address")
822822 if ((checkDestAddress == checkDestAddress))
823823 then {
824824 let tokenIdStr = getStringValue(tokenIdKey)
825825 let tokenId = fromBase58String(tokenIdStr)
826826 let t = i.payments[0]
827827 let checkAssetId = match t.assetId {
828828 case assetId: ByteVector =>
829829 if ((assetId == tokenId))
830830 then true
831831 else throw(((("Expected " + tokenIdStr) + " in the payment, got ") + toBase58String(assetId)))
832832 case _ =>
833833 throw((("Expected " + tokenIdStr) + " in the payment, got Waves"))
834834 }
835835 if ((checkAssetId == checkAssetId))
836836 then {
837837 let lastIndex = blockMeta(mainChainLastBlock)._7
838838 let queueSize = ((nativeTransfersCount - lastIndex) + 1)
839839 let checkQueueLimit = if ((160 > queueSize))
840840 then amountGtEq(t, 1000000, queueSize)
841841 else if ((1600 > queueSize))
842842 then amountGtEq(t, 10000000, queueSize)
843843 else if ((3200 > queueSize))
844844 then amountGtEq(t, 100000000, queueSize)
845845 else if ((6400 > queueSize))
846846 then amountGtEq(t, 1000000000, queueSize)
847847 else throw((("Transfers denied for queue size of " + toString(queueSize)) + ". Wait until current transfers processed"))
848848 if ((checkQueueLimit == checkQueueLimit))
849849 then [IntegerEntry(nativeTransfersCountKey, (nativeTransfersCount + 1)), mkNativeTransferEntry(nativeTransfersCount, destElAddressHex, t.amount), Burn(tokenId, t.amount)]
850850 else throw("Strict value is not equal to itself.")
851851 }
852852 else throw("Strict value is not equal to itself.")
853853 }
854854 else throw("Strict value is not equal to itself.")
855855 }
856856 else throw("Strict value is not equal to itself.")
857857 }
858858
859859
860860
861861 @Callable(i)
862862 func withdraw (blockHashHex,merkleProof,transferIndexInBlock,amount) = {
863863 let withdrawBlockMeta = blockMeta(blockHashHex)
864864 let withdrawBlockHeight = withdrawBlockMeta._1
865865 let finalizedBlockHeight = blockMeta(getStringValue(finalizedBlockKey))._1
866866 let mainChainLastBlockHeight = blockMeta(mainChainLastBlock)._1
867867 if ((withdrawBlockHeight > finalizedBlockHeight))
868868 then throw(((("EL block #" + toString(withdrawBlockHeight)) + " is not finalized. The current finalized is #") + toString(finalizedBlockHeight)))
869869 else {
870870 let withdrawBlockChainId = withdrawBlockMeta._5
871871 let isMainChain = (withdrawBlockChainId == mainChainId)
872872 let relatesToMainChain = match getInteger(chainForkedHeightKey(withdrawBlockChainId)) {
873873 case forkedHeight: Int =>
874874 (forkedHeight > withdrawBlockHeight)
875875 case _ =>
876876 throw((((blockHashHex + " is on an alternative chain #") + toString(withdrawBlockChainId)) + " that was not approved by majority. Wait for some blocks"))
877877 }
878878 if (if (isMainChain)
879879 then true
880880 else relatesToMainChain)
881881 then {
882882 let recipient = i.originCaller
883883 let recipientPkHash = take(drop(recipient.bytes, 2), PUBLIC_KEY_HASH_SIZE)
884884 let zeroAmountBytes = base58'11111111111111111111111111111111111111111111'
885885 let amountBytes = toBytes(amount)
886886 let elEventData = ((recipientPkHash + take(zeroAmountBytes, (size(zeroAmountBytes) - size(amountBytes)))) + amountBytes)
887887 let elEventDataDigest = blake2b256_16Kb(elEventData)
888888 let calculatedRootHash = createMerkleRoot(merkleProof, elEventDataDigest, transferIndexInBlock)
889889 let expectedRootHash = withdrawBlockMeta._6
890890 if ((calculatedRootHash == expectedRootHash))
891891 then {
892892 let tokenId = fromBase58String(getStringValue(tokenIdKey))
893893 let transfersKey = blockElToClTransfersKey(blockHashHex)
894894 [Reissue(tokenId, amount, true), ScriptTransfer(recipient, amount, tokenId), StringEntry(transfersKey, setOrFail(valueOrElse(getString(transfersKey), ""), transferIndexInBlock))]
895895 }
896896 else throw((((((("Expected root hash: " + toBase16String(expectedRootHash)) + ", got: ") + toBase16String(calculatedRootHash)) + ". Event data digest: ") + toBase64String(elEventDataDigest)) + ". Check your withdraw arguments"))
897897 }
898898 else throw((("Expected " + blockHashHex) + " to be either on the main chain or relate to it"))
899899 }
900900 }
901901
902902
903903
904904 @Callable(i)
905905 func setup (genesisBlockHashHex,minerRewardInGwei,stakingContractAddressB58,elBridgeAddressHex) = if (isContractSetup())
906906 then throw("The contract has been already set up")
907907 else if ((0 > minerRewardInGwei))
908908 then throw("The miner reward must be nonnegative")
909909 else {
910910 let genesisBlockHash = fromBase16String(genesisBlockHashHex)
911911 let emptyPk = base58'11111111111111111111111111111111'
912912 let genesisMinerAddress = addressFromPublicKey(emptyPk)
913913 let genesisEthRewardAddress = base58'11111111111111111111'
914914 let genesisBlockReferenceHash = "0000000000000000000000000000000000000000000000000000000000000000"
915915 let issue = Issue("UNIT0", "Native token", 0, 8, true)
916916 let tokenId = calculateAssetId(issue)
917917 let genesisBlockMeta = mkBlockMetaEntry(genesisBlockHashHex, height, genesisBlockReferenceHash, genesisMinerAddress, 0, toBase16String(base58''), -1)
918918 [genesisBlockMeta, StringEntry(chainFirstBlockIdKey(0), genesisBlockHashHex), mkChainMetaEntry(0, 0, genesisBlockHashHex), IntegerEntry(minerRewardKey, minerRewardInGwei), StringEntry(stakingContractAddressKey, stakingContractAddressB58), StringEntry(epochMetaKey(height), ((toString(genesisMinerAddress) + ",0,") + genesisBlockHashHex)), StringEntry(finalizedBlockKey, genesisBlockHashHex), issue, StringEntry(tokenIdKey, toBase58String(tokenId)), StringEntry(elBridgeAddressKey, ("0x" + elBridgeAddressHex))]
919919 }
920920
921921

github/deemru/w8io/169f3d6 
129.65 ms