tx · 3RcHvbUrvhacUkEbDF6sAbEsJWivQptXXP9H9oenS514

3Msx4Aq69zWUKy4d1wyKnQ4ofzEDAfv5Ngf:  -0.04300000 Waves

2024.10.24 11:06 [3340644] smart account 3Msx4Aq69zWUKy4d1wyKnQ4ofzEDAfv5Ngf > SELF 0.00000000 Waves

{ "type": 13, "id": "3RcHvbUrvhacUkEbDF6sAbEsJWivQptXXP9H9oenS514", "fee": 4300000, "feeAssetId": null, "timestamp": 1729757216282, "version": 2, "chainId": 84, "sender": "3Msx4Aq69zWUKy4d1wyKnQ4ofzEDAfv5Ngf", "senderPublicKey": "62i1XasxLi9NJmrEaq9UaHEGfZaonGKUL6EmFaA7gosh", "proofs": [ "3UoCkntvwb91wNJQrbPZKM8iKw7nth7gjRngRHtxk4BKKjAJHEbFqQxAR2o2xqNgyWtnoyY5xMEEEPPz6sqDRRYT" ], "script": "base64:CAJCCAISBwoFCAgCCAESBwoFCAgCCAESCAoGCAgCAQgBEgYKBAgICAESAwoBCBIAEgMKAQgSBgoECBIBARIGCgQIAQgBTQAHSU5UX01BWAD//////////38ABVdBVkVTAIDC1y8AC01JTl9CQUxBTkNFCQBoAgCgnAEFBVdBVkVTAANTRVACASwAD0JMT0NLX0hBU0hfU0laRQAgABRQVUJMSUNfS0VZX0hBU0hfU0laRQAUAA5ST09UX0hBU0hfU0laRQAgABRXSVRIRFJBV19QUk9PRlNfU0laRQAKABRFVEhfQUREUkVTU19TVFJfU0laRQAoABZNQVhfQ0xfVE9fRUxfVFJBTlNGRVJTABAACXplcm9lc1N0cgKACDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAC29mZnNldHNfMTAwCQC8CQICZDo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OjoCAAAMYWxsTWluZXJzS2V5AglhbGxNaW5lcnMADm1haW5DaGFpbklkS2V5AgttYWluQ2hhaW5JZAAObGFzdENoYWluSWRLZXkCC2xhc3RDaGFpbklkABdmaXJzdFZhbGlkQWx0Q2hhaW5JZEtleQIUZmlyc3RWYWxpZEFsdENoYWluSWQADm1pbmVyUmV3YXJkS2V5AgttaW5lclJld2FyZAAKYmxvY2tNZXRhSwIIYmxvY2tfMHgAEWZpbmFsaXplZEJsb2NrS2V5Ag5maW5hbGl6ZWRCbG9jawAKdG9rZW5JZEtleQIHdG9rZW5JZAASZWxCcmlkZ2VBZGRyZXNzS2V5Ag9lbEJyaWRnZUFkZHJlc3MAF25hdGl2ZVRyYW5zZmVyc0NvdW50S2V5AhRuYXRpdmVUcmFuc2ZlcnNDb3VudAANZGFvQWRkcmVzc0tleQIKZGFvQWRkcmVzcwAMZGFvUmV3YXJkS2V5AglkYW9SZXdhcmQBA3BhZAEBaQQBcwkApAMBBQFpBAckbWF0Y2gwCQCxAgEFAXMDCQAAAgABBQckbWF0Y2gwCQCsAgICBzAwMDAwMDAFAXMDCQAAAgACBQckbWF0Y2gwCQCsAgICBjAwMDAwMAUBcwMJAAACAAMFByRtYXRjaDAJAKwCAgIFMDAwMDAFAXMDCQAAAgAEBQckbWF0Y2gwCQCsAgICBDAwMDAFAXMDCQAAAgAFBQckbWF0Y2gwCQCsAgICAzAwMAUBcwMJAAACAAYFByRtYXRjaDAJAKwCAgICMDAFAXMDCQAAAgAHBQckbWF0Y2gwCQCsAgICATAFAXMFAXMBFGJsb2NrRTJDVHJhbnNmZXJzS2V5AQxibG9ja0hhc2hIZXgJAKwCAgISZWxUb0NsVHJhbnNmZXJzXzB4BQxibG9ja0hhc2hIZXgBDGVwb2NoTWV0YUtleQEFZXBvY2gJAKwCAgIGZXBvY2hfCQEDcGFkAQUFZXBvY2gBFGNoYWluRmlyc3RCbG9ja0lkS2V5AQdjaGFpbklkCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAIKRmlyc3RCbG9jawEMY2hhaW5NZXRhS2V5AQdjaGFpbklkCQCsAgICBmNoYWluXwkBA3BhZAEFB2NoYWluSWQBEmNoYWluTGFzdEhlaWdodEtleQIHY2hhaW5JZAVtaW5lcgkArAICCQCsAgIJAKwCAgIGY2hhaW5fCQEDcGFkAQUHY2hhaW5JZAIBXwkApQgBBQVtaW5lcgEUY2hhaW5Gb3JrZWRIZWlnaHRLZXkBB2NoYWluSWQJAKwCAgkArAICAgZjaGFpbl8JAQNwYWQBBQdjaGFpbklkAgxGb3JrZWRIZWlnaHQBDXN1cHBvcnRlcnNLZXkBB2NoYWluSWQJAKwCAgkArAICAgVjaGFpbgkApAMBBQdjaGFpbklkAgpTdXBwb3J0ZXJzARVtaW5lclJld2FyZEFkZHJlc3NLZXkBCW1pbmVyQWRkcgkArAICCQCsAgICBm1pbmVyXwUJbWluZXJBZGRyAg5fUmV3YXJkQWRkcmVzcwEKbWluZXJQa0tleQENcmV3YXJkQWRkcmVzcwkArAICCQCsAgICCG1pbmVyXzB4BQ1yZXdhcmRBZGRyZXNzAgNfUEsBD21pbmVyQ2hhaW5JZEtleQEFbWluZXIJAKwCAgkArAICAgZtaW5lcl8JAKUIAQUFbWluZXICCF9DaGFpbklkABRuYXRpdmVUcmFuc2ZlcnNDb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRduYXRpdmVUcmFuc2ZlcnNDb3VudEtleQAAARFuYXRpdmVUcmFuc2ZlcktleQEFaW5kZXgJAKwCAgIPbmF0aXZlVHJhbnNmZXJfCQCkAwEFBWluZGV4ARVta05hdGl2ZVRyYW5zZmVyRW50cnkDBWluZGV4EGRlc3RFbEFkZHJlc3NIZXgGYW1vdW50CQELU3RyaW5nRW50cnkCCQERbmF0aXZlVHJhbnNmZXJLZXkBBQVpbmRleAkArAICCQCsAgIJAKwCAgICMHgFEGRlc3RFbEFkZHJlc3NIZXgFA1NFUAkApAMBBQZhbW91bnQBFmVuc3VyZUNvcnJlY3RUcmFuc2ZlcnMDEHJlZlRyYW5zZmVySW5kZXgNdHJhbnNmZXJJbmRleAxleHBlY3RSZXdhcmQEDG1heFRyYW5zZmVycwMFDGV4cGVjdFJld2FyZAkAZQIFFk1BWF9DTF9UT19FTF9UUkFOU0ZFUlMAAQUWTUFYX0NMX1RPX0VMX1RSQU5TRkVSUwQPYWN0dWFsVHJhbnNmZXJzCQBlAgUNdHJhbnNmZXJJbmRleAUQcmVmVHJhbnNmZXJJbmRleAQLY2hlY2tOdW1iZXIDCQBmAgUPYWN0dWFsVHJhbnNmZXJzBQxtYXhUcmFuc2ZlcnMJAAIBCQCsAgIJAKwCAgkArAICAg1BbGxvd2VkIG9ubHkgCQCkAwEFDG1heFRyYW5zZmVycwIQIHRyYW5zZmVycywgZ290IAkApAMBBQ9hY3R1YWxUcmFuc2ZlcnMGAwkAAAIFC2NoZWNrTnVtYmVyBQtjaGVja051bWJlcgMJAGcCBQ10cmFuc2ZlckluZGV4BRRuYXRpdmVUcmFuc2ZlcnNDb3VudAkAAgEJAKwCAgkArAICCQCsAgICFUF0dGVtcHQgdG8gdHJhbnNmZXIgIwkApAMBBQ10cmFuc2ZlckluZGV4AhcuIEF2YWlsYWJsZSB0cmFuc2ZlcnM6IAkApAMBBRRuYXRpdmVUcmFuc2ZlcnNDb3VudAYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BCmFtb3VudEd0RXEDAXQEZ3RFcQlxdWV1ZVNpemUDCQBnAggFAXQGYW1vdW50BQRndEVxBgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICFFRyYW5zZmVycmluZyBhbW91bnQgCQCkAwEIBQF0BmFtb3VudAIOIHNob3VsZCBiZSA+PSAJAKQDAQUEZ3RFcQITIGZvciBxdWV1ZSBzaXplIG9mIAkApAMBBQlxdWV1ZVNpemUCFy4gVHJhbnNmZXIgbW9yZSBvciB3YWl0ARFnZW5lcmF0aW5nQmFsYW5jZQEHYWRkcmVzcwgJAO8HAQUHYWRkcmVzcwpnZW5lcmF0aW5nAQljaGFpbk1ldGEBB2NoYWluSWQEAXMJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAQxjaGFpbk1ldGFLZXkBBQdjaGFpbklkBAVpdGVtcwkAtQkCBQFzBQNTRVAJAJQKAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWl0ZW1zAAAJAJEDAgUFaXRlbXMAAQEQbWtDaGFpbk1ldGFFbnRyeQMHY2hhaW5JZA5uZXdDaGFpbkhlaWdodAxibG9ja0hhc2hIZXgJAQtTdHJpbmdFbnRyeQIJAQxjaGFpbk1ldGFLZXkBBQdjaGFpbklkCQCsAgIJAKwCAgkApAMBBQ5uZXdDaGFpbkhlaWdodAUDU0VQBQxibG9ja0hhc2hIZXgAC21haW5DaGFpbklkCQELdmFsdWVPckVsc2UCCQCfCAEFDm1haW5DaGFpbklkS2V5AAAACyR0MDUyNDk1MzE1CQEJY2hhaW5NZXRhAQULbWFpbkNoYWluSWQAD21haW5DaGFpbkhlaWdodAgFCyR0MDUyNDk1MzE1Al8xABJtYWluQ2hhaW5MYXN0QmxvY2sIBQskdDA1MjQ5NTMxNQJfMgEJZXBvY2hNZXRhAQVlcG9jaAQHJG1hdGNoMAkAoggBCQEMZXBvY2hNZXRhS2V5AQUFZXBvY2gDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwBAlmcmFnbWVudHMJALUJAgUBcwUDU0VQCQCVCgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUJZnJhZ21lbnRzAAAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlmcmFnbWVudHMAAQkAkQMCBQlmcmFnbWVudHMAAgUEdW5pdAALJHQwNTU0NjU2NzAEByRtYXRjaDAJAQllcG9jaE1ldGEBBQZoZWlnaHQDCQABAgUHJG1hdGNoMAIWKEFkZHJlc3MsIEludCwgU3RyaW5nKQQBbQUHJG1hdGNoMAUBbQkAlAoCBQR1bml0AAAADnRoaXNFcG9jaE1pbmVyCAULJHQwNTU0NjU2NzACXzEADHRoaXNFcG9jaFJlZggFCyR0MDU1NDY1NjcwAl8yAAxhbGxNaW5lcnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUMYWxsTWluZXJzS2V5AgAACWFsbE1pbmVycwQHJG1hdGNoMAUMYWxsTWluZXJzU3RyAwkAAAICAAUHJG1hdGNoMAUDbmlsAwkAAQIFByRtYXRjaDACBlN0cmluZwQDcmF3BQckbWF0Y2gwCQC8CQIFA3JhdwUDU0VQCQACAQILTWF0Y2ggZXJyb3IBCWJsb2NrTWV0YQEHYmxvY2tJZAQEbWV0YQkBEUBleHRyTmF0aXZlKDEwNTcpAQkArAICBQpibG9ja01ldGFLBQdibG9ja0lkBAhtZXRhU2l6ZQkAyAEBBQRtZXRhBAtibG9ja0hlaWdodAkAsQkBBQRtZXRhBApibG9ja0Vwb2NoCQCyCQIFBG1ldGEACAQLYmxvY2tQYXJlbnQJAMkBAgkAygECBQRtZXRhABAFD0JMT0NLX0hBU0hfU0laRQQHY2hhaW5JZAkAsgkCBQRtZXRhCQBkAgAQBQ9CTE9DS19IQVNIX1NJWkUECmJhc2VPZmZzZXQJAGQCABgFD0JMT0NLX0hBU0hfU0laRQQOcmVtYWluaW5nQnl0ZXMJAGUCBQhtZXRhU2l6ZQUKYmFzZU9mZnNldAQUZTJjVHJhbnNmZXJzUm9vdEhhc2gDCQBnAgUOcmVtYWluaW5nQnl0ZXMFDlJPT1RfSEFTSF9TSVpFCQDJAQIJAMoBAgUEbWV0YQUKYmFzZU9mZnNldAUOUk9PVF9IQVNIX1NJWkUBAAQUbGFzdEMyRVRyYW5zZmVySW5kZXgDAwkAAAIFDnJlbWFpbmluZ0J5dGVzAAgGCQBmAgUOcmVtYWluaW5nQnl0ZXMFDlJPT1RfSEFTSF9TSVpFCQCyCQIFBG1ldGEJAGQCBQpiYXNlT2Zmc2V0CQDIAQEFFGUyY1RyYW5zZmVyc1Jvb3RIYXNoAP///////////wEJAJgKBgULYmxvY2tIZWlnaHQFCmJsb2NrRXBvY2gFC2Jsb2NrUGFyZW50BQdjaGFpbklkBRRlMmNUcmFuc2ZlcnNSb290SGFzaAUUbGFzdEMyRVRyYW5zZmVySW5kZXgBEG1rQmxvY2tNZXRhRW50cnkGDGJsb2NrSGFzaEhleAtibG9ja0hlaWdodA5ibG9ja1BhcmVudEhleAdjaGFpbklkF2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4FGxhc3RDMkVUcmFuc2ZlckluZGV4BBllMmNUcmFuc2ZlcnNSb290SGFzaEJ5dGVzCQDdBAEFF2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4BBFyb290SGFzaEJ5dGVzU2l6ZQkAyAEBBRllMmNUcmFuc2ZlcnNSb290SGFzaEJ5dGVzBA1jaGVja1Jvb3RIYXNoAwMJAAACBRFyb290SGFzaEJ5dGVzU2l6ZQAABgkAAAIFEXJvb3RIYXNoQnl0ZXNTaXplBQ5ST09UX0hBU0hfU0laRQYJAAIBCQCsAgIJAKwCAgkArAICAiVUcmFuc2ZlcnMgcm9vdCBoYXNoIHNob3VsZCBoYXZlIDAgb3IgCQCkAwEFDlJPT1RfSEFTSF9TSVpFAgwgYnl0ZXMsIGdvdCAJAKQDAQURcm9vdEhhc2hCeXRlc1NpemUDCQAAAgUNY2hlY2tSb290SGFzaAUNY2hlY2tSb290SGFzaAQOYmxvY2tNZXRhQnl0ZXMJAMsBAgkAywECCQDLAQIJAMsBAgkAywECCQCaAwEFC2Jsb2NrSGVpZ2h0CQCaAwEFBmhlaWdodAkA3QQBBQ5ibG9ja1BhcmVudEhleAkAmgMBBQdjaGFpbklkBRllMmNUcmFuc2ZlcnNSb290SGFzaEJ5dGVzCQCaAwEFFGxhc3RDMkVUcmFuc2ZlckluZGV4CQELQmluYXJ5RW50cnkCCQCsAgIFCmJsb2NrTWV0YUsFDGJsb2NrSGFzaEhleAUOYmxvY2tNZXRhQnl0ZXMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BDGxhc3RIZWlnaHRCeQIFbWluZXIHY2hhaW5JZAQHJG1hdGNoMAkAnwgBCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgUHY2hhaW5JZAUFbWluZXIDCQABAgUHJG1hdGNoMAIDSW50BAFoBQckbWF0Y2gwBQFoBAlibG9ja0hhc2gJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAKwCAgkArAICCQCsAgICBWNoYWluCQCkAwEFB2NoYWluSWQCC0xhc3RNaW5lZEJ5CQClCAEFBW1pbmVyCAkBCWJsb2NrTWV0YQEFCWJsb2NrSGFzaAJfMQALJHQwNzcxMDg2NDUECWhpdFNvdXJjZQQHJG1hdGNoMAgFCWxhc3RCbG9jawN2cmYDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQDdnJmBQckbWF0Y2gwBQN2cmYIBQlsYXN0QmxvY2sTZ2VuZXJhdGlvblNpZ25hdHVyZQoBDHByb2Nlc3NNaW5lcgIEcHJldgVtaW5lcgQLJHQwNzk3NzgwNDAFBHByZXYECXByZXZNaW5lcggFCyR0MDc5Nzc4MDQwAl8xBBBwcmV2VG90YWxCYWxhbmNlCAULJHQwNzk3NzgwNDACXzIECXByZXZEZWxheQgFCyR0MDc5Nzc4MDQwAl8zBApwcmV2TWluZXJzCAULJHQwNzk3NzgwNDACXzQEDG1pbmVyQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUFbWluZXIED3dhdmVzR2VuQmFsYW5jZQgJAO8HAQUMbWluZXJBZGRyZXNzCmdlbmVyYXRpbmcEDG1pbmVyQmFsYW5jZQkBEWdlbmVyYXRpbmdCYWxhbmNlAQUMbWluZXJBZGRyZXNzAwMJAGYCBQtNSU5fQkFMQU5DRQUPd2F2ZXNHZW5CYWxhbmNlBgkAZwIAAAUMbWluZXJCYWxhbmNlBQRwcmV2BAluZXh0RGVsYXkJAIUHAgUMbWluZXJBZGRyZXNzBQxtaW5lckJhbGFuY2UDCQBmAgUJcHJldkRlbGF5BQluZXh0RGVsYXkJAJYKBAUFbWluZXIJAGQCBRBwcmV2VG90YWxCYWxhbmNlBQxtaW5lckJhbGFuY2UFCW5leHREZWxheQkAzQgCBQpwcmV2TWluZXJzBQVtaW5lcgkAlgoEBQlwcmV2TWluZXIJAGQCBRBwcmV2VG90YWxCYWxhbmNlBQxtaW5lckJhbGFuY2UFCXByZXZEZWxheQkAzQgCBQpwcmV2TWluZXJzBQVtaW5lcgoAAiRsBQlhbGxNaW5lcnMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQCAAAABQdJTlRfTUFYBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDHByb2Nlc3NNaW5lcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyABFjb21wdXRlZEdlbmVyYXRvcggFCyR0MDc3MTA4NjQ1Al8xABRjb21wdXRlZFRvdGFsQmFsYW5jZQgFCyR0MDc3MTA4NjQ1Al8yAAskdDA4NjQ3ODcxMwkBCWJsb2NrTWV0YQEFEm1haW5DaGFpbkxhc3RCbG9jawAMbWNsYklnbm9yZWQxCAULJHQwODY0Nzg3MTMCXzEADm1haW5DaGFpbkVwb2NoCAULJHQwODY0Nzg3MTMCXzIBI2NhbGN1bGF0ZUZpbmFsaXplZEJsb2NrSGFzaEFuZEVwb2NoAwhjdXJNaW5lcgxjdXJQcmV2RXBvY2gQY3VyTGFzdEJsb2NrSGFzaAQLaGFsZkJhbGFuY2UJAGkCBRRjb21wdXRlZFRvdGFsQmFsYW5jZQACCgEEc3RlcAIEcHJldgRuZXh0BAskdDA4OTUxOTAyNAUEcHJldgQJdGhpc0Vwb2NoCAULJHQwODk1MTkwMjQCXzEEF21heWJlRmluYWxpemVkQmxvY2tIYXNoCAULJHQwODk1MTkwMjQCXzIEDHRvdGFsQmFsYW5jZQgFCyR0MDg5NTE5MDI0Al8zBApwcmV2TWluZXJzCAULJHQwODk1MTkwMjQCXzQEByRtYXRjaDAFF21heWJlRmluYWxpemVkQmxvY2tIYXNoAwkAAQIFByRtYXRjaDACBFVuaXQECyR0MDkwOTE5MjU3AwkAAAIFCXRoaXNFcG9jaAUGaGVpZ2h0CQCVCgMFCGN1ck1pbmVyBQxjdXJQcmV2RXBvY2gFEGN1ckxhc3RCbG9ja0hhc2gJAQV2YWx1ZQEJAQllcG9jaE1ldGEBBQl0aGlzRXBvY2gEBW1pbmVyCAULJHQwOTA5MTkyNTcCXzEECXByZXZFcG9jaAgFCyR0MDkwOTE5MjU3Al8yBA1sYXN0QmxvY2tIYXNoCAULJHQwOTA5MTkyNTcCXzMDAwkAAAIFCXByZXZFcG9jaAAABgkAZwIJAGUCBQZoZWlnaHQFCXRoaXNFcG9jaABkCQCWCgQFCXRoaXNFcG9jaAUNbGFzdEJsb2NrSGFzaAUMdG90YWxCYWxhbmNlBQlhbGxNaW5lcnMECyR0MDk0MTE5NjEzAwkBD2NvbnRhaW5zRWxlbWVudAIFCnByZXZNaW5lcnMFBW1pbmVyCQCUCgIFDHRvdGFsQmFsYW5jZQUKcHJldk1pbmVycwkAlAoCCQBkAgUMdG90YWxCYWxhbmNlCQERZ2VuZXJhdGluZ0JhbGFuY2UBBQVtaW5lcgkAzAgCBQVtaW5lcgUKcHJldk1pbmVycwQPbmV3VG90YWxCYWxhbmNlCAUL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CQCsAgIJAKwCAgkA2AQBCAUJZ2VuZXJhdG9yBWJ5dGVzAhsgaXMgbm90IGFsbG93ZWQgdG8gbWluZSBpbiAJAKQDAQUGaGVpZ2h0AhEgZXBvY2guIEV4cGVjdGVkIAURY29tcHV0ZWRHZW5lcmF0b3IFBHVuaXQBEmlzUmVmZXJlbmNlQ29ycmVjdAIJcmVmZXJlbmNlCWxhc3RCbG9jawMJAAACBQlyZWZlcmVuY2UFCWxhc3RCbG9jawUEdW5pdAkAAgEJAKwCAgkArAICCQCsAgICMEV4cGVjdGVkIGEgcmVmZXJlbmNlIHRvIHRoZSBjaGFpbiBsYXN0IGJsb2NrOiAweAUJbGFzdEJsb2NrAgkuIEdvdDogMHgFCXJlZmVyZW5jZQEPY2hhaW5Jc0luYWN0aXZlAQdjaGFpbklkBAxmaXJzdEJsb2NrSWQJARFAZXh0ck5hdGl2ZSgxMDU4KQEJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEFB2NoYWluSWQEFGZpcnN0VmFsaWRBbHRDaGFpbklkCQELdmFsdWVPckVsc2UCCQCfCAEFF2ZpcnN0VmFsaWRBbHRDaGFpbklkS2V5AAADCQBmAgUUZmlyc3RWYWxpZEFsdENoYWluSWQFB2NoYWluSWQGCQBmAggJAQlibG9ja01ldGEBCQERQGV4dHJOYXRpdmUoMTA1OCkBBRFmaW5hbGl6ZWRCbG9ja0tleQJfMQgJAQlibG9ja01ldGEBBQxmaXJzdEJsb2NrSWQCXzEBDG1pbmVyQ2hhaW5JZAEFbWluZXIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBD21pbmVyQ2hhaW5JZEtleQEFBW1pbmVyCQCfCAEJAKwCAgIJY2hhaW5JZE9mCQClCAEFBW1pbmVyAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMJZ2VuZXJhdG9yD2V4cGVjdGVkQ2hhaW5JZBBjaGVja0hlaWdodEJsb2NrBA9oZWlnaHRJc0NvcnJlY3QEByRtYXRjaDAFEGNoZWNrSGVpZ2h0QmxvY2sDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAlibG9ja0hhc2gFByRtYXRjaDAEFGxhc3RNaW5lZEJsb2NrSGVpZ2h0CQEMbGFzdEhlaWdodEJ5AgUJZ2VuZXJhdG9yBQttYWluQ2hhaW5JZAkAZgIJAGQCCAkBCWJsb2NrTWV0YQEFCWJsb2NrSGFzaAJfMQABBRRsYXN0TWluZWRCbG9ja0hlaWdodAYEByRtYXRjaDAJAQxtaW5lckNoYWluSWQBBQlnZW5lcmF0b3IDCQABAgUHJG1hdGNoMAIDSW50BAljdXJyZW50SWQFByRtYXRjaDADAwkAAAIFCWN1cnJlbnRJZAUPZXhwZWN0ZWRDaGFpbklkBgMJAQ9jaGFpbklzSW5hY3RpdmUBBQljdXJyZW50SWQFD2hlaWdodElzQ29ycmVjdAcFBHVuaXQJAAIBCQCsAgICHG1pbmVyIGlzIG1pbmluZyBvdGhlciBjaGFpbiAJAKQDAQUJY3VycmVudElkBQR1bml0AAxoZWlnaHRTdHJpbmcJAKwCAgILIGF0IGhlaWdodCAJAKQDAQUGaGVpZ2h0AQV2cmZBdAEGaGVpZ2h0CQETdmFsdWVPckVycm9yTWVzc2FnZQIICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAO0HAQUGaGVpZ2h0CQCsAgICG2xhc3QgYmxvY2sgaXMgbm90IGF2YWlsYWJsZQUMaGVpZ2h0U3RyaW5nA3ZyZgkArAICAhRWUkYgaXMgbm90IGF2YWlsYWJsZQUMaGVpZ2h0U3RyaW5nARJlbnN1cmVDb3JyZWN0RXBvY2gBC2V4cGVjdGVkVlJGBAlhY3R1YWxWUkYJAQV2cmZBdAEFBmhlaWdodAMJAAACBQtleHBlY3RlZFZSRgUJYWN0dWFsVlJGBQR1bml0CQACAQkArAICCQCsAgIJAKwCAgkArAICAg1FeHBlY3RlZCBWUkYgCQDYBAEFC2V4cGVjdGVkVlJGAhcgZG9lcyBub3QgbWF0Y2ggYWN0dWFsIAkA2AQBBQlhY3R1YWxWUkYFDGhlaWdodFN0cmluZwEMYWRkU3VwcG9ydGVyAgdjaGFpbklkCWdlbmVyYXRvcgQNc3VwcG9ydGVyc1N0cgkBEUBleHRyTmF0aXZlKDEwNTgpAQkBDXN1cHBvcnRlcnNLZXkBBQdjaGFpbklkBApzdXBwb3J0ZXJzCQC8CQIFDXN1cHBvcnRlcnNTdHIFA1NFUAMJAQ9jb250YWluc0VsZW1lbnQCBQpzdXBwb3J0ZXJzCQClCAEFCWdlbmVyYXRvcgUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ1zdXBwb3J0ZXJzS2V5AQUHY2hhaW5JZAkArAICCQCsAgIFDXN1cHBvcnRlcnNTdHIFA1NFUAkApQgBBQlnZW5lcmF0b3IFA25pbAEJc2V0T3JGYWlsAgVmbGFncwVpbmRleAMJAGYCAAAFBWluZGV4CQACAQkArAICAiJDYW4ndCB3aXRoZHJhdyBhdCBuZWdhdGl2ZSBpbmRleDogCQCkAwEFBWluZGV4BAlmbGFnc1NpemUJALECAQUFZmxhZ3MDCQBnAgUFaW5kZXgFCWZsYWdzU2l6ZQQJYWRkWmVyb2VzCQBlAgUFaW5kZXgFCWZsYWdzU2l6ZQMJAGYCBQlhZGRaZXJvZXMJALECAQUJemVyb2VzU3RyCQACAQkArAICCQCsAgICCkNhbid0IGFkZCAJAKQDAQUJYWRkWmVyb2VzAiUgZW1wdHkgZmxhZ3MuIENvbnRhY3Qgd2l0aCBkZXZlbG9wZXJzCQCsAgIJAKwCAgUFZmxhZ3MJAK8CAgUJemVyb2VzU3RyBQlhZGRaZXJvZXMCATEEBHRhaWwJALACAgUFZmxhZ3MFBWluZGV4BAdhdEluZGV4CQCvAgIFBHRhaWwAAQMJAAACBQdhdEluZGV4AgEwCQCsAgIJAKwCAgkArwICBQVmbGFncwUFaW5kZXgCATEJALACAgUEdGFpbAABCQACAQkArAICCQCsAgICClRyYW5zZmVyICMJAKQDAQUFaW5kZXgCFyBoYXMgYmVlbiBhbHJlYWR5IHRha2VuARF2YWxpZGF0ZUJsb2NrSGFzaAEGaGV4U3RyBAxkZWNvZGVkQnl0ZXMJAN0EAQUGaGV4U3RyAwkBAiE9AgkAyAEBBQxkZWNvZGVkQnl0ZXMFD0JMT0NLX0hBU0hfU0laRQkAAgECF2ludmFsaWQgYmxvY2sgaWQgbGVuZ3RoBQZoZXhTdHIBHWdldFVwZGF0ZUZpbmFsaXplZEJsb2NrQWN0aW9uAwZjYWxsZXIPbmV3QmxvY2tIYXNoSGV4CXByZXZFcG9jaAQVY3VyRmluYWxpemVkQmxvY2tNZXRhCQEJYmxvY2tNZXRhAQkBEUBleHRyTmF0aXZlKDEwNTgpAQURZmluYWxpemVkQmxvY2tLZXkEDSR0MDE0MjczMTQzOTMJASNjYWxjdWxhdGVGaW5hbGl6ZWRCbG9ja0hhc2hBbmRFcG9jaAMFBmNhbGxlcgUJcHJldkVwb2NoBQ9uZXdCbG9ja0hhc2hIZXgEFW5ld0ZpbmFsaXplZEJsb2NrSGFzaAgFDSR0MDE0MjczMTQzOTMCXzEEEW5ld0ZpbmFsaXplZEVwb2NoCAUNJHQwMTQyNzMxNDM5MwJfMgQNcmV3YXJkQWN0aW9ucwQHJG1hdGNoMAkAoggBBQ1kYW9BZGRyZXNzS2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQEYWRkcgUHJG1hdGNoMAMJAAACBRFuZXdGaW5hbGl6ZWRFcG9jaAgFFWN1ckZpbmFsaXplZEJsb2NrTWV0YQJfMgUDbmlsCgETY291bnROb25FbXB0eUVwb2NocwIDYWNjBG5leHQDCQAAAggFA2FjYwJfMQgFFWN1ckZpbmFsaXplZEJsb2NrTWV0YQJfMgUDYWNjBAckbWF0Y2gxCQEJZXBvY2hNZXRhAQgFA2FjYwJfMQMJAAECBQckbWF0Y2gxAhYoQWRkcmVzcywgSW50LCBTdHJpbmcpBAFtBQckbWF0Y2gxCQCUCgIIBQFtAl8yCQBkAggFA2FjYwJfMgABBQNhY2MEDnN0YXJ0RnJvbUVwb2NoAwkAAAIFEW5ld0ZpbmFsaXplZEVwb2NoBQZoZWlnaHQFCXByZXZFcG9jaAgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkBCWVwb2NoTWV0YQEFEW5ld0ZpbmFsaXplZEVwb2NoAhdubyBwcmV2IGVwb2NoIGZvciBzdGFydAJfMgQKZGFvUmV3YXJkcwoAAiRsBQtvZmZzZXRzXzEwMAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUOc3RhcnRGcm9tRXBvY2gAAQoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQETY291bnROb25FbXB0eUVwb2NocwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIVTGlzdCBzaXplIGV4Y2VlZHMgMTAwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgAzADQANQA2ADcAOAA5ADoAOwA8AD0APgA/AEAAQQBCAEMARABFAEYARwBIAEkASgBLAEwATQBOAE8AUABRAFIAUwBUAFUAVgBXAFgAWQBaAFsAXABdAF4AXwBgAGEAYgBjAGQEDXJlaXNzdWVBbW91bnQJAGgCCAUKZGFvUmV3YXJkcwJfMgkBEUBleHRyTmF0aXZlKDEwNTUpAQUMZGFvUmV3YXJkS2V5BAd0b2tlbklkCQDZBAEJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCnRva2VuSWRLZXkJAMwIAgkBB1JlaXNzdWUDBQd0b2tlbklkBQ1yZWlzc3VlQW1vdW50BgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQEHQWRkcmVzcwEJANkEAQUEYWRkcgUNcmVpc3N1ZUFtb3VudAUHdG9rZW5JZAUDbmlsBQNuaWwJAM4IAgUNcmV3YXJkQWN0aW9ucwMDCQAAAgUVbmV3RmluYWxpemVkQmxvY2tIYXNoBQ9uZXdCbG9ja0hhc2hIZXgGCQBmAggJAQlibG9ja01ldGEBBRVuZXdGaW5hbGl6ZWRCbG9ja0hhc2gCXzEIBRVjdXJGaW5hbGl6ZWRCbG9ja01ldGECXzEJAMwIAgkBC1N0cmluZ0VudHJ5AgURZmluYWxpemVkQmxvY2tLZXkFFW5ld0ZpbmFsaXplZEJsb2NrSGFzaAUDbmlsBQNuaWwJAWkBD2V4dGVuZE1haW5DaGFpbgUMYmxvY2tIYXNoSGV4DHJlZmVyZW5jZUhleAN2cmYXZTJjVHJhbnNmZXJzUm9vdEhhc2hIZXgUbGFzdEMyRVRyYW5zZmVySW5kZXgEDmNoZWNrQmxvY2tIYXNoCQERdmFsaWRhdGVCbG9ja0hhc2gBBQxibG9ja0hhc2hIZXgDCQAAAgUOY2hlY2tCbG9ja0hhc2gFDmNoZWNrQmxvY2tIYXNoBApjaGVja0Vwb2NoCQESZW5zdXJlQ29ycmVjdEVwb2NoAQUDdnJmAwkAAAIFCmNoZWNrRXBvY2gFCmNoZWNrRXBvY2gECmNoZWNrQ2hhaW4JAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQFBHVuaXQDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQOY2hlY2tSZWZlcmVuY2UJARJpc1JlZmVyZW5jZUNvcnJlY3QCBQxyZWZlcmVuY2VIZXgFEm1haW5DaGFpbkxhc3RCbG9jawMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDmNoZWNrVHJhbnNmZXJzCQEWZW5zdXJlQ29ycmVjdFRyYW5zZmVycwMICQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4Al82BRRsYXN0QzJFVHJhbnNmZXJJbmRleAYDCQAAAgUOY2hlY2tUcmFuc2ZlcnMFDmNoZWNrVHJhbnNmZXJzBA10aGlzRXBvY2hNZXRhBAckbWF0Y2gwCQEJZXBvY2hNZXRhAQUGaGVpZ2h0AwkAAQIFByRtYXRjaDACBFVuaXQJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCAUBaQxvcmlnaW5DYWxsZXIFA1NFUAkApAMBBQ5tYWluQ2hhaW5FcG9jaAUDU0VQBQxibG9ja0hhc2hIZXgEBW90aGVyBQckbWF0Y2gwCQACAQIVRXBvY2ggYWxyZWFkeSBzdGFydGVkAwkAAAIFDXRoaXNFcG9jaE1ldGEFDXRoaXNFcG9jaE1ldGEEDmNoZWNrR2VuZXJhdG9yCQERZW5zdXJlTWluaW5nRXBvY2gBCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUOY2hlY2tHZW5lcmF0b3IFDmNoZWNrR2VuZXJhdG9yBBR1cGRhdGVGaW5hbGl6ZWRCbG9jawkBHWdldFVwZGF0ZUZpbmFsaXplZEJsb2NrQWN0aW9uAwgFAWkMb3JpZ2luQ2FsbGVyBQxibG9ja0hhc2hIZXgFDm1haW5DaGFpbkVwb2NoBA5uZXdDaGFpbkhlaWdodAkAZAIFD21haW5DaGFpbkhlaWdodAABCQDOCAIJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkGBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BRJtYWluQ2hhaW5MYXN0QmxvY2sFC21haW5DaGFpbklkBRdlMmNUcmFuc2ZlcnNSb290SGFzaEhleAUUbGFzdEMyRVRyYW5zZmVySW5kZXgJAMwIAgkBEG1rQ2hhaW5NZXRhRW50cnkDBQttYWluQ2hhaW5JZAUObmV3Q2hhaW5IZWlnaHQFDGJsb2NrSGFzaEhleAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBD21pbmVyQ2hhaW5JZEtleQEIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQttYWluQ2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBQ5uZXdDaGFpbkhlaWdodAkAzAgCBQ10aGlzRXBvY2hNZXRhBQNuaWwFFHVwZGF0ZUZpbmFsaXplZEJsb2NrCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDXN0YXJ0QWx0Q2hhaW4FDGJsb2NrSGFzaEhleAxyZWZlcmVuY2VIZXgDdnJmF2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4FGxhc3RDMkVUcmFuc2ZlckluZGV4BA5jaGVja0Jsb2NrSGFzaAkBEXZhbGlkYXRlQmxvY2tIYXNoAQUMYmxvY2tIYXNoSGV4AwkAAAIFDmNoZWNrQmxvY2tIYXNoBQ5jaGVja0Jsb2NrSGFzaAQKY2hlY2tFcG9jaAkBEmVuc3VyZUNvcnJlY3RFcG9jaAEFA3ZyZgMJAAACBQpjaGVja0Vwb2NoBQpjaGVja0Vwb2NoBA0kdDAxNzI5MDE3NDAzCQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4BA5yZWZDaGFpbkhlaWdodAgFDSR0MDE3MjkwMTc0MDMCXzEECHJlZkVwb2NoCAUNJHQwMTcyOTAxNzQwMwJfMgQLcmVmSWdub3JlZDEIBQ0kdDAxNzI5MDE3NDAzAl8zBAtyZWZJZ25vcmVkMggFDSR0MDE3MjkwMTc0MDMCXzQEC3JlZklnbm9yZWQzCAUNJHQwMTcyOTAxNzQwMwJfNQQQcmVmVHJhbnNmZXJJbmRleAgFDSR0MDE3MjkwMTc0MDMCXzYEDmZpbmFsaXplZEVwb2NoCAkBCWJsb2NrTWV0YQEJARFAZXh0ck5hdGl2ZSgxMDU4KQEFEWZpbmFsaXplZEJsb2NrS2V5Al8yBAhlcG9jaFJlZgMJAGcCBQhyZWZFcG9jaAUOZmluYWxpemVkRXBvY2gFCHJlZkVwb2NoCQACAQkArAICCQCsAgIJAKwCAgkArAICAiNDYW4gbm90IHN0YXJ0IGFsdCBjaGFpbiBmcm9tIGVwb2NoIAkApAMBBQhyZWZFcG9jaAIILCBlcG9jaCAJAKQDAQUOZmluYWxpemVkRXBvY2gCDSBpcyBmaW5hbGl6ZWQECmNoZWNrQ2hhaW4JAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQFDHJlZmVyZW5jZUhleAMJAAACBQpjaGVja0NoYWluBQpjaGVja0NoYWluBA5jaGVja1RyYW5zZmVycwkBFmVuc3VyZUNvcnJlY3RUcmFuc2ZlcnMDBRByZWZUcmFuc2ZlckluZGV4BRRsYXN0QzJFVHJhbnNmZXJJbmRleAYDCQAAAgUOY2hlY2tUcmFuc2ZlcnMFDmNoZWNrVHJhbnNmZXJzBApuZXdDaGFpbklkCQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ5sYXN0Q2hhaW5JZEtleQAAAAEEDm5ld0NoYWluSGVpZ2h0CQBkAgUOcmVmQ2hhaW5IZWlnaHQAAQQNdGhpc0Vwb2NoTWV0YQQHJG1hdGNoMAkBCWVwb2NoTWV0YQEFBmhlaWdodAMJAAECBQckbWF0Y2gwAgRVbml0CQELU3RyaW5nRW50cnkCCQEMZXBvY2hNZXRhS2V5AQUGaGVpZ2h0CQCsAgIJAKwCAgkArAICCQCsAgIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBQNTRVAJAKQDAQUIZXBvY2hSZWYFA1NFUAUMYmxvY2tIYXNoSGV4BAVvdGhlcgUHJG1hdGNoMAkAAgECFUVwb2NoIGFscmVhZHkgc3RhcnRlZAQOY2hlY2tHZW5lcmF0b3IJARFlbnN1cmVNaW5pbmdFcG9jaAEIBQFpDG9yaWdpbkNhbGxlcgMJAAACBQ5jaGVja0dlbmVyYXRvcgUOY2hlY2tHZW5lcmF0b3IJAMwIAgUNdGhpc0Vwb2NoTWV0YQkAzAgCCQEQbWtCbG9ja01ldGFFbnRyeQYFDGJsb2NrSGFzaEhleAUObmV3Q2hhaW5IZWlnaHQFDHJlZmVyZW5jZUhleAUKbmV3Q2hhaW5JZAUXZTJjVHJhbnNmZXJzUm9vdEhhc2hIZXgFFGxhc3RDMkVUcmFuc2ZlckluZGV4CQDMCAIJAQtTdHJpbmdFbnRyeQIJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEFCm5ld0NoYWluSWQFDGJsb2NrSGFzaEhleAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMFCm5ld0NoYWluSWQFDm5ld0NoYWluSGVpZ2h0BQxibG9ja0hhc2hIZXgJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9taW5lckNoYWluSWRLZXkBCAUBaQxvcmlnaW5DYWxsZXIFCm5ld0NoYWluSWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQpuZXdDaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFDm5ld0NoYWluSGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgULbWFpbkNoYWluSWQIBQFpDG9yaWdpbkNhbGxlcgUObmV3Q2hhaW5IZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDXN1cHBvcnRlcnNLZXkBBQpuZXdDaGFpbklkCQClCAEIBQFpDG9yaWdpbkNhbGxlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgUObGFzdENoYWluSWRLZXkFCm5ld0NoYWluSWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ5leHRlbmRBbHRDaGFpbgYMYmxvY2tIYXNoSGV4DHJlZmVyZW5jZUhleAN2cmYHY2hhaW5JZBdlMmNUcmFuc2ZlcnNSb290SGFzaEhleBRsYXN0QzJFVHJhbnNmZXJJbmRleAQOY2hlY2tCbG9ja0hhc2gJARF2YWxpZGF0ZUJsb2NrSGFzaAEFDGJsb2NrSGFzaEhleAMJAAACBQ5jaGVja0Jsb2NrSGFzaAUOY2hlY2tCbG9ja0hhc2gECmNoZWNrRXBvY2gJARJlbnN1cmVDb3JyZWN0RXBvY2gBBQN2cmYDCQAAAgUKY2hlY2tFcG9jaAUKY2hlY2tFcG9jaAQTY2hhaW5GaXJzdEJsb2NrTWV0YQkBCWJsb2NrTWV0YQEJARFAZXh0ck5hdGl2ZSgxMDU4KQEJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEFB2NoYWluSWQECmNoZWNrQ2hhaW4JAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMIBQFpDG9yaWdpbkNhbGxlcgUHY2hhaW5JZAkA3AQBCAUTY2hhaW5GaXJzdEJsb2NrTWV0YQJfMwMJAAACBQpjaGVja0NoYWluBQpjaGVja0NoYWluBA0kdDAxOTcxNjE5NzcwCQEJY2hhaW5NZXRhAQUHY2hhaW5JZAQLY2hhaW5IZWlnaHQIBQ0kdDAxOTcxNjE5NzcwAl8xBA5jaGFpbkxhc3RCbG9jawgFDSR0MDE5NzE2MTk3NzACXzIEDmNoZWNrUmVmZXJlbmNlCQESaXNSZWZlcmVuY2VDb3JyZWN0AgUMcmVmZXJlbmNlSGV4BQ5jaGFpbkxhc3RCbG9jawMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDmNoZWNrVHJhbnNmZXJzCQEWZW5zdXJlQ29ycmVjdFRyYW5zZmVycwMICQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4Al82BRRsYXN0QzJFVHJhbnNmZXJJbmRleAYDCQAAAgUOY2hlY2tUcmFuc2ZlcnMFDmNoZWNrVHJhbnNmZXJzBA5uZXdDaGFpbkhlaWdodAkAZAIFC2NoYWluSGVpZ2h0AAEECXByZXZFcG9jaAgJAQlibG9ja01ldGEBBQxyZWZlcmVuY2VIZXgCXzIEE3VwZGF0ZU1haW5DaGFpbkRhdGEDCQBmAgkBEXN1cHBvcnRpbmdCYWxhbmNlAQUHY2hhaW5JZAkAaQIFFGNvbXB1dGVkVG90YWxCYWxhbmNlAAIEC2xhc3RDaGFpbklkCQELdmFsdWVPckVsc2UCCQCfCAEFDmxhc3RDaGFpbklkS2V5AAAEFHVwZGF0ZUZpbmFsaXplZEJsb2NrCQEdZ2V0VXBkYXRlRmluYWxpemVkQmxvY2tBY3Rpb24DCAUBaQxvcmlnaW5DYWxsZXIFDGJsb2NrSGFzaEhleAUJcHJldkVwb2NoCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJARRjaGFpbkZvcmtlZEhlaWdodEtleQEFC21haW5DaGFpbklkCAUTY2hhaW5GaXJzdEJsb2NrTWV0YQJfMQkAzAgCCQEMSW50ZWdlckVudHJ5AgUObWFpbkNoYWluSWRLZXkFB2NoYWluSWQJAMwIAgkBDEludGVnZXJFbnRyeQIFF2ZpcnN0VmFsaWRBbHRDaGFpbklkS2V5CQBkAgULbGFzdENoYWluSWQAAQUDbmlsBRR1cGRhdGVGaW5hbGl6ZWRCbG9jawUDbmlsBA10aGlzRXBvY2hNZXRhBAckbWF0Y2gwCQEJZXBvY2hNZXRhAQUGaGVpZ2h0AwkAAQIFByRtYXRjaDACBFVuaXQJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCAUBaQxvcmlnaW5DYWxsZXIFA1NFUAkApAMBBQlwcmV2RXBvY2gFA1NFUAUMYmxvY2tIYXNoSGV4BAVvdGhlcgUHJG1hdGNoMAkAAgECFUVwb2NoIGFscmVhZHkgc3RhcnRlZAMJAAACBQ10aGlzRXBvY2hNZXRhBQ10aGlzRXBvY2hNZXRhBA5jaGVja0dlbmVyYXRvcgkBEWVuc3VyZU1pbmluZ0Vwb2NoAQgFAWkMb3JpZ2luQ2FsbGVyAwkAAAIFDmNoZWNrR2VuZXJhdG9yBQ5jaGVja0dlbmVyYXRvcgQddXBkYXRlTWFpbkNoYWluTGFzdE1pbmVkQmxvY2sDAwkAAAIFE3VwZGF0ZU1haW5DaGFpbkRhdGEFA25pbAkBAiE9AgkBC3ZhbHVlT3JFbHNlAgkBDG1pbmVyQ2hhaW5JZAEIBQFpDG9yaWdpbkNhbGxlcgAABQdjaGFpbklkBwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmNoYWluTGFzdEhlaWdodEtleQIFC21haW5DaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIIBRNjaGFpbkZpcnN0QmxvY2tNZXRhAl8xBQNuaWwFA25pbAkAzggCCQDOCAIJAM4IAgkAzAgCCQEQbWtCbG9ja01ldGFFbnRyeQYFDGJsb2NrSGFzaEhleAUObmV3Q2hhaW5IZWlnaHQFDHJlZmVyZW5jZUhleAUHY2hhaW5JZAUXZTJjVHJhbnNmZXJzUm9vdEhhc2hIZXgFFGxhc3RDMkVUcmFuc2ZlckluZGV4CQDMCAIJARBta0NoYWluTWV0YUVudHJ5AwUHY2hhaW5JZAUObmV3Q2hhaW5IZWlnaHQFDGJsb2NrSGFzaEhleAkAzAgCBQ10aGlzRXBvY2hNZXRhCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEPbWluZXJDaGFpbklkS2V5AQgFAWkMb3JpZ2luQ2FsbGVyBQdjaGFpbklkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgUHY2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBQ5uZXdDaGFpbkhlaWdodAUDbmlsBRN1cGRhdGVNYWluQ2hhaW5EYXRhCQEMYWRkU3VwcG9ydGVyAgUHY2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBR11cGRhdGVNYWluQ2hhaW5MYXN0TWluZWRCbG9jawkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQthcHBlbmRCbG9jawQMYmxvY2tIYXNoSGV4DHJlZmVyZW5jZUhleBdlMmNUcmFuc2ZlcnNSb290SGFzaEhleBRsYXN0QzJFVHJhbnNmZXJJbmRleAQLY2hlY2tDYWxsZXIDCQAAAgUOdGhpc0Vwb2NoTWluZXIIBQFpDG9yaWdpbkNhbGxlcgYEByRtYXRjaDAFDnRoaXNFcG9jaE1pbmVyAwkAAQIFByRtYXRjaDACB0FkZHJlc3MECmVwb2NoTWluZXIFByRtYXRjaDAJAAIBCQCsAgICOW5vdCBhbGxvd2VkIHRvIGZvcmdlIGJsb2NrcyBpbiB0aGlzIGVwb2NoLCBleHBlY3RlZCBmcm9tIAkApQgBBQplcG9jaE1pbmVyCQACAQJAbm90IGFsbG93ZWQgdG8gZm9yZ2UgYmxvY2tzIGluIHRoaXMgZXBvY2gsIGVwb2NoIG1pbmVyIGlzIGFic2VudAMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIEB2NoYWluSWQJAQt2YWx1ZU9yRWxzZQIJAQxtaW5lckNoYWluSWQBCAUBaQxvcmlnaW5DYWxsZXIFC21haW5DaGFpbklkBA0kdDAyMjExOTIyMTcwCQEJY2hhaW5NZXRhAQUHY2hhaW5JZAQLY2hhaW5IZWlnaHQIBQ0kdDAyMjExOTIyMTcwAl8xBAtsYXN0QmxvY2tJZAgFDSR0MDIyMTE5MjIxNzACXzIEDmNoZWNrUmVmZXJlbmNlCQESaXNSZWZlcmVuY2VDb3JyZWN0AgUMcmVmZXJlbmNlSGV4BQtsYXN0QmxvY2tJZAMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDmNoZWNrVHJhbnNmZXJzCQEWZW5zdXJlQ29ycmVjdFRyYW5zZmVycwMICQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4Al82BRRsYXN0QzJFVHJhbnNmZXJJbmRleAcDCQAAAgUOY2hlY2tUcmFuc2ZlcnMFDmNoZWNrVHJhbnNmZXJzBA5uZXdDaGFpbkhlaWdodAkAZAIFC2NoYWluSGVpZ2h0AAEEDmNoZWNrQmxvY2tIYXNoCQERdmFsaWRhdGVCbG9ja0hhc2gBBQxibG9ja0hhc2hIZXgDCQAAAgUOY2hlY2tCbG9ja0hhc2gFDmNoZWNrQmxvY2tIYXNoCQDMCAIJARBta0Jsb2NrTWV0YUVudHJ5BgUMYmxvY2tIYXNoSGV4BQ5uZXdDaGFpbkhlaWdodAULbGFzdEJsb2NrSWQFB2NoYWluSWQFF2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4BRRsYXN0QzJFVHJhbnNmZXJJbmRleAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmNoYWluTGFzdEhlaWdodEtleQIFB2NoYWluSWQIBQFpDG9yaWdpbkNhbGxlcgUObmV3Q2hhaW5IZWlnaHQJAMwIAgkBEG1rQ2hhaW5NZXRhRW50cnkDBQdjaGFpbklkBQ5uZXdDaGFpbkhlaWdodAUMYmxvY2tIYXNoSGV4CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCQEFdmFsdWUBBQ50aGlzRXBvY2hNaW5lcgUDU0VQCQCkAwEFDHRoaXNFcG9jaFJlZgUDU0VQBQxibG9ja0hhc2hIZXgFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQRqb2luARByZXdhcmRBZGRyZXNzSGV4CgEdZW5zdXJlTm90T3ZlcnJpZGVPdGhlck1pbmVyUGsBDGVsQWRkcmVzc0hleAQHJG1hdGNoMAkAoQgBCQEKbWluZXJQa0tleQEFDGVsQWRkcmVzc0hleAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACBQJwawgFAWkVb3JpZ2luQ2FsbGVyUHVibGljS2V5BQR1bml0CQACAQkArAICCQCsAgIJAKwCAgIRRUwgbWluZXIgYWRkcmVzcyAFDGVsQWRkcmVzc0hleAIYIGlzIGFscmVhZHkgbGlua2VkIHdpdGggCQDYBAEFAnBrBQR1bml0BAVwYXJ0cwkAtQkCBRByZXdhcmRBZGRyZXNzSGV4AgIweAQNcmV3YXJkQWRkcmVzcwkA3QQBCQCRAwIFBXBhcnRzCQBlAgkAkAMBBQVwYXJ0cwABAwkBASEBCQEPaXNDb250cmFjdFNldHVwAAkAAgECH1RoZSBjb250cmFjdCBoYXMgbm90IHlldCBzZXQgdXADCQBmAgULTUlOX0JBTEFOQ0UICQDvBwEIBQFpDG9yaWdpbkNhbGxlcgpnZW5lcmF0aW5nCQACAQkArAICCQCsAgIJAKwCAgIhSW5zdWZmaWNpZW50IGdlbmVyYXRpbmcgYmFsYW5jZTogCQCkAwEICQDvBwEIBQFpDG9yaWdpbkNhbGxlcgpnZW5lcmF0aW5nAgwuIFJlcXVpcmVkOiAJAKQDAQULTUlOX0JBTEFOQ0UDCQECIT0CCQDIAQEFDXJld2FyZEFkZHJlc3MAFAkAAgECJXJld2FyZEFkZHJlc3Mgc2hvdWxkIGJlIGFuIEwyIGFkZHJlc3MDCQBnAgkAkAMBBQlhbGxNaW5lcnMAMgkAAgECD3RvbyBtYW55IG1pbmVycwoBDmNoZWNrRXhpc3RlbmNlAgZleGlzdHMFbWluZXIDBQZleGlzdHMGCQAAAgUFbWluZXIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBA1hbHJlYWR5RXhpc3RzCgACJGwFCWFsbE1pbmVycwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAHCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQ5jaGVja0V4aXN0ZW5jZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyAwUNYWxyZWFkeUV4aXN0cwUDbmlsBAhuZXdNaW5lcgkApQgBCAUBaQxvcmlnaW5DYWxsZXIEFmxvd2VyY2FzZVJld2FyZEFkZHJlc3MJANwEAQUNcmV3YXJkQWRkcmVzcwQFY2hlY2sJAR1lbnN1cmVOb3RPdmVycmlkZU90aGVyTWluZXJQawEFFmxvd2VyY2FzZVJld2FyZEFkZHJlc3MDCQAAAgUFY2hlY2sFBWNoZWNrBAluZXdNaW5lcnMDCQAAAgkAkAMBBQlhbGxNaW5lcnMAAAUIbmV3TWluZXIJAKwCAgkArAICBQxhbGxNaW5lcnNTdHIFA1NFUAUIbmV3TWluZXIEGWRlbGV0ZVByZXZSZXdhcmRBZGRyZXNzUGsEByRtYXRjaDAJAKIIAQkBFW1pbmVyUmV3YXJkQWRkcmVzc0tleQEFCG5ld01pbmVyAwkAAQIFByRtYXRjaDACBlN0cmluZwQLcHJldkFkZHJlc3MFByRtYXRjaDADCQAAAgULcHJldkFkZHJlc3MJANwEAQUNcmV3YXJkQWRkcmVzcwUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEJAQptaW5lclBrS2V5AQULcHJldkFkZHJlc3MFA25pbAUDbmlsCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUMYWxsTWluZXJzS2V5BQluZXdNaW5lcnMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFW1pbmVyUmV3YXJkQWRkcmVzc0tleQEFCG5ld01pbmVyCQCsAgICAjB4BRZsb3dlcmNhc2VSZXdhcmRBZGRyZXNzCQDMCAIJAQtCaW5hcnlFbnRyeQIJAQptaW5lclBrS2V5AQUWbG93ZXJjYXNlUmV3YXJkQWRkcmVzcwgFAWkVb3JpZ2luQ2FsbGVyUHVibGljS2V5BQNuaWwFGWRlbGV0ZVByZXZSZXdhcmRBZGRyZXNzUGsJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEFbGVhdmUABAxsZWF2aW5nTWluZXIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyCgEQc2tpcExlYXZpbmdNaW5lcgIDYWNjBW1pbmVyAwkAAAIFBW1pbmVyBQxsZWF2aW5nTWluZXIFA2FjYwkAzQgCBQNhY2MFBW1pbmVyBA9yZW1haW5pbmdNaW5lcnMKAAIkbAUJYWxsTWluZXJzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARBza2lwTGVhdmluZ01pbmVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA1MAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIEDXJld2FyZEFkZHJLZXkJARVtaW5lclJld2FyZEFkZHJlc3NLZXkBBQxsZWF2aW5nTWluZXIEEXByZXZSZXdhcmRBZGRyZXNzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUNcmV3YXJkQWRkcktleQIWbWluZXIgaGFzIG5ldmVyIGpvaW5lZAMJAAACBRFwcmV2UmV3YXJkQWRkcmVzcwURcHJldlJld2FyZEFkZHJlc3MDCQAAAgUOdGhpc0Vwb2NoTWluZXIIBQFpDG9yaWdpbkNhbGxlcgkAAgECHGRlc2lnbmF0ZWQgbWluZXIgY2FuJ3QgbGVhdmUJAMwIAgkBC1N0cmluZ0VudHJ5AgUMYWxsTWluZXJzS2V5CQC6CQIFD3JlbWFpbmluZ01pbmVycwUDU0VQBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIdHJhbnNmZXIBEGRlc3RFbEFkZHJlc3NIZXgEDGNoZWNrQWRkcmVzcwMJAAACCQCxAgEFEGRlc3RFbEFkZHJlc3NIZXgFFEVUSF9BRERSRVNTX1NUUl9TSVpFCQDdBAEFEGRlc3RFbEFkZHJlc3NIZXgJAAIBCQCsAgIJAKwCAgkArAICAhRBZGRyZXNzIHNob3VsZCBoYXZlIAkApAMBBRRFVEhfQUREUkVTU19TVFJfU0laRQIRIGNoYXJhY3RlcnMsIGdvdCAJAKQDAQkAsQIBBRBkZXN0RWxBZGRyZXNzSGV4AwkAAAIFDGNoZWNrQWRkcmVzcwUMY2hlY2tBZGRyZXNzBAxjaGVja1BheW1lbnQDCQAAAgkAkAMBCAUBaQhwYXltZW50cwABBgkAAgEJAKwCAgIvRXhwZWN0ZWQgb25lIHBheW1lbnQgYXMgYSB0cmFuc2ZlciBhbW91bnQsIGdvdCAJAKQDAQkAkAMBCAUBaQhwYXltZW50cwMJAAACBQxjaGVja1BheW1lbnQFDGNoZWNrUGF5bWVudAQKdG9rZW5JZFN0cgkBEUBleHRyTmF0aXZlKDEwNTgpAQUKdG9rZW5JZEtleQQHdG9rZW5JZAkA2QQBBQp0b2tlbklkU3RyBAF0CQCRAwIIBQFpCHBheW1lbnRzAAAEDGNoZWNrQXNzZXRJZAQHJG1hdGNoMAgFAXQHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAdhc3NldElkBQckbWF0Y2gwAwkAAAIFB2Fzc2V0SWQFB3Rva2VuSWQGCQACAQkArAICCQCsAgIJAKwCAgIJRXhwZWN0ZWQgBQp0b2tlbklkU3RyAhUgaW4gdGhlIHBheW1lbnQsIGdvdCAJANgEAQUHYXNzZXRJZAkAAgEJAKwCAgkArAICAglFeHBlY3RlZCAFCnRva2VuSWRTdHICGiBpbiB0aGUgcGF5bWVudCwgZ290IFdhdmVzAwkAAAIFDGNoZWNrQXNzZXRJZAUMY2hlY2tBc3NldElkBAlsYXN0SW5kZXgICQEJYmxvY2tNZXRhAQUSbWFpbkNoYWluTGFzdEJsb2NrAl82BAlxdWV1ZVNpemUJAGUCBRRuYXRpdmVUcmFuc2ZlcnNDb3VudAUJbGFzdEluZGV4BA9jaGVja1F1ZXVlTGltaXQDCQBmAgCgAQUJcXVldWVTaXplCQEKYW1vdW50R3RFcQMFAXQAwIQ9BQlxdWV1ZVNpemUDCQBmAgDADAUJcXVldWVTaXplCQEKYW1vdW50R3RFcQMFAXQAgK3iBAUJcXVldWVTaXplAwkAZgIAgBkFCXF1ZXVlU2l6ZQkBCmFtb3VudEd0RXEDBQF0AIDC1y8FCXF1ZXVlU2l6ZQMJAGYCAIAyBQlxdWV1ZVNpemUJAQphbW91bnRHdEVxAwUBdACAlOvcAwUJcXVldWVTaXplCQACAQkArAICCQCsAgICI1RyYW5zZmVycyBkZW5pZWQgZm9yIHF1ZXVlIHNpemUgb2YgCQCkAwEFCXF1ZXVlU2l6ZQIoLiBXYWl0IHVudGlsIGN1cnJlbnQgdHJhbnNmZXJzIHByb2Nlc3NlZAMJAAACBQ9jaGVja1F1ZXVlTGltaXQFD2NoZWNrUXVldWVMaW1pdAkAzAgCCQEMSW50ZWdlckVudHJ5AgUXbmF0aXZlVHJhbnNmZXJzQ291bnRLZXkJAGQCBRRuYXRpdmVUcmFuc2ZlcnNDb3VudAABCQDMCAIJARVta05hdGl2ZVRyYW5zZmVyRW50cnkDBRRuYXRpdmVUcmFuc2ZlcnNDb3VudAUQZGVzdEVsQWRkcmVzc0hleAgFAXQGYW1vdW50CQDMCAIJAQRCdXJuAgUHdG9rZW5JZAgFAXQGYW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEId2l0aGRyYXcEDGJsb2NrSGFzaEhleAttZXJrbGVQcm9vZhR0cmFuc2ZlckluZGV4SW5CbG9jawZhbW91bnQEEXdpdGhkcmF3QmxvY2tNZXRhCQEJYmxvY2tNZXRhAQUMYmxvY2tIYXNoSGV4BBN3aXRoZHJhd0Jsb2NrSGVpZ2h0CAURd2l0aGRyYXdCbG9ja01ldGECXzEEFGZpbmFsaXplZEJsb2NrSGVpZ2h0CAkBCWJsb2NrTWV0YQEJARFAZXh0ck5hdGl2ZSgxMDU4KQEFEWZpbmFsaXplZEJsb2NrS2V5Al8xBBhtYWluQ2hhaW5MYXN0QmxvY2tIZWlnaHQICQEJYmxvY2tNZXRhAQUSbWFpbkNoYWluTGFzdEJsb2NrAl8xAwkAZgIFE3dpdGhkcmF3QmxvY2tIZWlnaHQFFGZpbmFsaXplZEJsb2NrSGVpZ2h0CQACAQkArAICCQCsAgIJAKwCAgIKRUwgYmxvY2sgIwkApAMBBRN3aXRoZHJhd0Jsb2NrSGVpZ2h0Ai0gaXMgbm90IGZpbmFsaXplZC4gVGhlIGN1cnJlbnQgZmluYWxpemVkIGlzICMJAKQDAQUUZmluYWxpemVkQmxvY2tIZWlnaHQDCQECIT0CCQCQAwEFC21lcmtsZVByb29mBRRXSVRIRFJBV19QUk9PRlNfU0laRQkAAgEJAKwCAgkArAICCQCsAgICCUV4cGVjdGVkIAkApAMBBRRXSVRIRFJBV19QUk9PRlNfU0laRQINIHByb29mcywgZ290IAkApAMBCQCQAwEFC21lcmtsZVByb29mAwkAZgIAAAUUdHJhbnNmZXJJbmRleEluQmxvY2sJAAIBCQCsAgICM1RyYW5zZmVyIGluZGV4IGluIGJsb2NrIHNob3VsZCBiZSBub25uZWdhdGl2ZSwgZ290IAkApAMBBRR0cmFuc2ZlckluZGV4SW5CbG9jawMJAGcCAAAFBmFtb3VudAkAAgEJAKwCAgIfQW1vdW50IHNob3VsZCBiZSBwb3NpdGl2ZSwgZ290IAkApAMBBQZhbW91bnQEFHdpdGhkcmF3QmxvY2tDaGFpbklkCAURd2l0aGRyYXdCbG9ja01ldGECXzQEC2lzTWFpbkNoYWluCQAAAgUUd2l0aGRyYXdCbG9ja0NoYWluSWQFC21haW5DaGFpbklkBBJyZWxhdGVzVG9NYWluQ2hhaW4EByRtYXRjaDAJAJ8IAQkBFGNoYWluRm9ya2VkSGVpZ2h0S2V5AQUUd2l0aGRyYXdCbG9ja0NoYWluSWQDCQABAgUHJG1hdGNoMAIDSW50BAxmb3JrZWRIZWlnaHQFByRtYXRjaDAJAGYCBQxmb3JrZWRIZWlnaHQFE3dpdGhkcmF3QmxvY2tIZWlnaHQJAAIBCQCsAgIJAKwCAgkArAICBQxibG9ja0hhc2hIZXgCHSBpcyBvbiBhbiBhbHRlcm5hdGl2ZSBjaGFpbiAjCQCkAwEFFHdpdGhkcmF3QmxvY2tDaGFpbklkAjggdGhhdCB3YXMgbm90IGFwcHJvdmVkIGJ5IG1ham9yaXR5LiBXYWl0IGZvciBzb21lIGJsb2NrcwMDBQtpc01haW5DaGFpbgYFEnJlbGF0ZXNUb01haW5DaGFpbgQJcmVjaXBpZW50CAUBaQxvcmlnaW5DYWxsZXIED3JlY2lwaWVudFBrSGFzaAkAyQECCQDKAQIIBQlyZWNpcGllbnQFYnl0ZXMAAgUUUFVCTElDX0tFWV9IQVNIX1NJWkUED3plcm9BbW91bnRCeXRlcwEsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEC2Ftb3VudEJ5dGVzCQCaAwEFBmFtb3VudAQLZWxFdmVudERhdGEJAMsBAgkAywECBQ9yZWNpcGllbnRQa0hhc2gJAMkBAgUPemVyb0Ftb3VudEJ5dGVzCQBlAgkAyAEBBQ96ZXJvQW1vdW50Qnl0ZXMJAMgBAQULYW1vdW50Qnl0ZXMFC2Ftb3VudEJ5dGVzBBFlbEV2ZW50RGF0YURpZ2VzdAkA8BUBBQtlbEV2ZW50RGF0YQQSY2FsY3VsYXRlZFJvb3RIYXNoCQC9BQMFC21lcmtsZVByb29mBRFlbEV2ZW50RGF0YURpZ2VzdAUUdHJhbnNmZXJJbmRleEluQmxvY2sEEGV4cGVjdGVkUm9vdEhhc2gIBRF3aXRoZHJhd0Jsb2NrTWV0YQJfNQMJAAACBRJjYWxjdWxhdGVkUm9vdEhhc2gFEGV4cGVjdGVkUm9vdEhhc2gEB3Rva2VuSWQJANkEAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUKdG9rZW5JZEtleQQMdHJhbnNmZXJzS2V5CQEUYmxvY2tFMkNUcmFuc2ZlcnNLZXkBBQxibG9ja0hhc2hIZXgJAMwIAgkBB1JlaXNzdWUDBQd0b2tlbklkBQZhbW91bnQGCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFCXJlY2lwaWVudAUGYW1vdW50BQd0b2tlbklkCQDMCAIJAQtTdHJpbmdFbnRyeQIFDHRyYW5zZmVyc0tleQkBCXNldE9yRmFpbAIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUMdHJhbnNmZXJzS2V5AgAFFHRyYW5zZmVySW5kZXhJbkJsb2NrBQNuaWwJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhRFeHBlY3RlZCByb290IGhhc2g6IAkA3AQBBRBleHBlY3RlZFJvb3RIYXNoAgcsIGdvdDogCQDcBAEFEmNhbGN1bGF0ZWRSb290SGFzaAIVLiBFdmVudCBkYXRhIGRpZ2VzdDogCQDaBAEFEWVsRXZlbnREYXRhRGlnZXN0Ah8uIENoZWNrIHlvdXIgd2l0aGRyYXcgYXJndW1lbnRzCQACAQkArAICCQCsAgICCUV4cGVjdGVkIAUMYmxvY2tIYXNoSGV4Ai8gdG8gYmUgZWl0aGVyIG9uIHRoZSBtYWluIGNoYWluIG9yIHJlbGF0ZSB0byBpdAFpAQVzZXR1cAQTZ2VuZXNpc0Jsb2NrSGFzaEhleBFtaW5lclJld2FyZEluR3dlaQpkYW9BZGRyZXNzCWRhb1Jld2FyZAMJAQ9pc0NvbnRyYWN0U2V0dXAACQACAQIkVGhlIGNvbnRyYWN0IGhhcyBiZWVuIGFscmVhZHkgc2V0IHVwAwkAZgIAAAURbWluZXJSZXdhcmRJbkd3ZWkJAAIBAiRUaGUgbWluZXIgcmV3YXJkIG11c3QgYmUgbm9ubmVnYXRpdmUEEGdlbmVzaXNCbG9ja0hhc2gJAN0EAQUTZ2VuZXNpc0Jsb2NrSGFzaEhleAQZY2hlY2tHZW5lc2lzQmxvY2tIYXNoU2l6ZQMJAAACCQDIAQEFEGdlbmVzaXNCbG9ja0hhc2gFD0JMT0NLX0hBU0hfU0laRQYJAAIBAhhXcm9uZyBnZW5lc2lzIGJsb2NrIGhhc2gDCQAAAgUZY2hlY2tHZW5lc2lzQmxvY2tIYXNoU2l6ZQUZY2hlY2tHZW5lc2lzQmxvY2tIYXNoU2l6ZQQHZW1wdHlQawEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEE2dlbmVzaXNNaW5lckFkZHJlc3MJAKcIAQUHZW1wdHlQawQXZ2VuZXNpc0V0aFJld2FyZEFkZHJlc3MBFAAAAAAAAAAAAAAAAAAAAAAAAAAABBlnZW5lc2lzQmxvY2tSZWZlcmVuY2VIYXNoAkAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBAVpc3N1ZQkAwggFAgVVTklUMAIMTmF0aXZlIHRva2VuAAAACAYEB3Rva2VuSWQJALgIAQUFaXNzdWUEEGdlbmVzaXNCbG9ja01ldGEJARBta0Jsb2NrTWV0YUVudHJ5BgUTZ2VuZXNpc0Jsb2NrSGFzaEhleAAABRlnZW5lc2lzQmxvY2tSZWZlcmVuY2VIYXNoAAAJANwEAQEAAP///////////wEECmRhb0VudHJpZXMDCQAAAgUKZGFvQWRkcmVzcwIABQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgUNZGFvQWRkcmVzc0tleQkApQgBCQEHQWRkcmVzcwEJANkEAQUKZGFvQWRkcmVzcwkAzAgCCQEMSW50ZWdlckVudHJ5AgUMZGFvUmV3YXJkS2V5AwkAZgIFCWRhb1Jld2FyZAAABQlkYW9SZXdhcmQJAAIBAhlpbnZhbGlkIERBTyByZXdhcmQgYW1vdW50BQNuaWwJAM4IAgkAzAgCBRBnZW5lc2lzQmxvY2tNZXRhCQDMCAIJAQtTdHJpbmdFbnRyeQIJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEAAAUTZ2VuZXNpc0Jsb2NrSGFzaEhleAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMAAAAABRNnZW5lc2lzQmxvY2tIYXNoSGV4CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5taW5lclJld2FyZEtleQURbWluZXJSZXdhcmRJbkd3ZWkJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDGVwb2NoTWV0YUtleQEFBmhlaWdodAkArAICCQCsAgIJAKUIAQUTZ2VuZXNpc01pbmVyQWRkcmVzcwIDLDAsBRNnZW5lc2lzQmxvY2tIYXNoSGV4CQDMCAIJAQtTdHJpbmdFbnRyeQIFEWZpbmFsaXplZEJsb2NrS2V5BRNnZW5lc2lzQmxvY2tIYXNoSGV4CQDMCAIFBWlzc3VlCQDMCAIJAQtTdHJpbmdFbnRyeQIFCnRva2VuSWRLZXkJANgEAQUHdG9rZW5JZAkAzAgCCQELU3RyaW5nRW50cnkCBRJlbEJyaWRnZUFkZHJlc3NLZXkCKjB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNmE3ZQUDbmlsBQpkYW9FbnRyaWVzCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAOKF2ww=", "height": 3340644, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 36fQejUN2YzRW7ooET6swSK1pmxdjwxwfafH8YBAXWyc Next: none Diff:
OldNewDifferences
2323
2424 let zeroesStr = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
2525
26+let offsets_100 = split_4C("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::", "")
27+
2628 let allMinersKey = "allMiners"
2729
2830 let mainChainIdKey = "mainChainId"
4244 let elBridgeAddressKey = "elBridgeAddress"
4345
4446 let nativeTransfersCountKey = "nativeTransfersCount"
47+
48+let daoAddressKey = "daoAddress"
49+
50+let daoRewardKey = "daoReward"
4551
4652 func pad (i) = {
4753 let s = toString(i)
140146
141147 let mainChainId = valueOrElse(getInteger(mainChainIdKey), 0)
142148
143-let $t050295095 = chainMeta(mainChainId)
149+let $t052495315 = chainMeta(mainChainId)
144150
145-let mainChainHeight = $t050295095._1
151+let mainChainHeight = $t052495315._1
146152
147-let mainChainLastBlock = $t050295095._2
153+let mainChainLastBlock = $t052495315._2
148154
149155 func epochMeta (epoch) = match getString(epochMetaKey(epoch)) {
150156 case s: String =>
155161 }
156162
157163
158-let $t053265450 = match epochMeta(height) {
164+let $t055465670 = match epochMeta(height) {
159165 case m: (Address, Int, String) =>
160166 m
161167 case _ =>
162168 $Tuple2(unit, 0)
163169 }
164170
165-let thisEpochMiner = $t053265450._1
171+let thisEpochMiner = $t055465670._1
166172
167-let thisEpochRef = $t053265450._2
173+let thisEpochRef = $t055465670._2
168174
169175 let allMinersStr = valueOrElse(getString(allMinersKey), "")
170176
227233 }
228234
229235
230-let $t074908425 = {
236+let $t077108645 = {
231237 let hitSource = match lastBlock.vrf {
232238 case vrf: ByteVector =>
233239 vrf
235241 lastBlock.generationSignature
236242 }
237243 func processMiner (prev,miner) = {
238- let $t077577820 = prev
239- let prevMiner = $t077577820._1
240- let prevTotalBalance = $t077577820._2
241- let prevDelay = $t077577820._3
242- let prevMiners = $t077577820._4
244+ let $t079778040 = prev
245+ let prevMiner = $t079778040._1
246+ let prevTotalBalance = $t079778040._2
247+ let prevDelay = $t079778040._3
248+ let prevMiners = $t079778040._4
243249 let minerAddress = addressFromStringValue(miner)
244250 let wavesGenBalance = wavesBalance(minerAddress).generating
245251 let minerBalance = generatingBalance(minerAddress)
269275 $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)
270276 }
271277
272-let computedGenerator = $t074908425._1
278+let computedGenerator = $t077108645._1
273279
274-let computedTotalBalance = $t074908425._2
280+let computedTotalBalance = $t077108645._2
275281
276-let $t084278493 = blockMeta(mainChainLastBlock)
282+let $t086478713 = blockMeta(mainChainLastBlock)
277283
278-let mclbIgnored1 = $t084278493._1
284+let mclbIgnored1 = $t086478713._1
279285
280-let mainChainEpoch = $t084278493._2
286+let mainChainEpoch = $t086478713._2
281287
282-func calculateFinalizedBlockHash (curMiner,curPrevEpoch,curLastBlockHash) = {
283- let offsets_100 = split_4C("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::", "")
288+func calculateFinalizedBlockHashAndEpoch (curMiner,curPrevEpoch,curLastBlockHash) = {
284289 let halfBalance = (computedTotalBalance / 2)
285290 func step (prev,next) = {
286- let $t088598923 = prev
287- let thisEpoch = $t088598923._1
288- let maybeSafeEpoch = $t088598923._2
289- let totalBalance = $t088598923._3
290- let prevMiners = $t088598923._4
291- match maybeSafeEpoch {
291+ let $t089519024 = prev
292+ let thisEpoch = $t089519024._1
293+ let maybeFinalizedBlockHash = $t089519024._2
294+ let totalBalance = $t089519024._3
295+ let prevMiners = $t089519024._4
296+ match maybeFinalizedBlockHash {
292297 case _: Unit =>
293- let $t089819147 = if ((thisEpoch == height))
298+ let $t090919257 = if ((thisEpoch == height))
294299 then $Tuple3(curMiner, curPrevEpoch, curLastBlockHash)
295300 else value(epochMeta(thisEpoch))
296- let miner = $t089819147._1
297- let prevEpoch = $t089819147._2
298- let lastBlockHash = $t089819147._3
301+ let miner = $t090919257._1
302+ let prevEpoch = $t090919257._2
303+ let lastBlockHash = $t090919257._3
299304 if (if ((prevEpoch == 0))
300305 then true
301306 else ((height - thisEpoch) >= 100))
302307 then $Tuple4(thisEpoch, lastBlockHash, totalBalance, allMiners)
303308 else {
304- let $t093019503 = if (containsElement(prevMiners, miner))
309+ let $t094119613 = if (containsElement(prevMiners, miner))
305310 then $Tuple2(totalBalance, prevMiners)
306311 else $Tuple2((totalBalance + generatingBalance(miner)), miner :: prevMiners)
307- let newTotalBalance = $t093019503._1
308- let newMiners = $t093019503._2
312+ let newTotalBalance = $t094119613._1
313+ let newMiners = $t094119613._2
309314 if ((newTotalBalance > halfBalance))
310315 then $Tuple4(thisEpoch, lastBlockHash, newTotalBalance, allMiners)
311316 else $Tuple4(prevEpoch, unit, newTotalBalance, newMiners)
315320 }
316321 }
317322
318- let $t097369832 = {
323+ let $t098469943 = {
319324 let $l = offsets_100
320325 let $s = size($l)
321326 let $acc0 = $Tuple4(height, unit, 0, nil)
329334
330335 $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)
331336 }
332- let fallbackEpoch = $t097369832._1
333- let finalizedBlockHashOpt = $t097369832._2
334- match finalizedBlockHashOpt {
337+ let finalizedEpoch = $t098469943._1
338+ let finalizedBlockHashOpt = $t098469943._2
339+ $Tuple2( match finalizedBlockHashOpt {
335340 case finalizedBlockHash: String =>
336341 finalizedBlockHash
337342 case _ =>
338- value(epochMeta(fallbackEpoch))._3
339- }
343+ value(epochMeta(finalizedEpoch))._3
344+ }, finalizedEpoch)
340345 }
341346
342347
343348 func supportingBalance (chainId) = {
344349 func addBalance (acc,generatorStr) = {
345- let $t01010210138 = acc
346- let totalBalance = $t01010210138._1
347- let generators = $t01010210138._2
350+ let $t01022610262 = acc
351+ let totalBalance = $t01022610262._1
352+ let generators = $t01022610262._2
348353 let generator = addressFromStringValue(generatorStr)
349354 if (containsElement(generators, generator))
350355 then acc
355360 }
356361
357362 let allGenerators = split_4C(getStringValue(supportersKey(chainId)), SEP)
358- let $t01046010525 = {
363+ let res = {
359364 let $l = allGenerators
360365 let $s = size($l)
361366 let $acc0 = $Tuple2(0, nil)
369374
370375 $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)
371376 }
372- let balance = $t01046010525._1
373- let _g = $t01046010525._2
374- balance
377+ res._1
375378 }
376379
377380
475478
476479
477480 func getUpdateFinalizedBlockAction (caller,newBlockHashHex,prevEpoch) = {
478- let curFinalizedBlockHeight = blockMeta(getStringValue(finalizedBlockKey))._1
479- let newFinalizedBlockHash = calculateFinalizedBlockHash(caller, prevEpoch, newBlockHashHex)
480- if (if ((newFinalizedBlockHash == newBlockHashHex))
481+ let curFinalizedBlockMeta = blockMeta(getStringValue(finalizedBlockKey))
482+ let $t01427314393 = calculateFinalizedBlockHashAndEpoch(caller, prevEpoch, newBlockHashHex)
483+ let newFinalizedBlockHash = $t01427314393._1
484+ let newFinalizedEpoch = $t01427314393._2
485+ let rewardActions = match getString(daoAddressKey) {
486+ case addr: String =>
487+ if ((newFinalizedEpoch == curFinalizedBlockMeta._2))
488+ then nil
489+ else {
490+ func countNonEmptyEpochs (acc,next) = if ((acc._1 == curFinalizedBlockMeta._2))
491+ then acc
492+ else match epochMeta(acc._1) {
493+ case m: (Address, Int, String) =>
494+ $Tuple2(m._2, (acc._2 + 1))
495+ case _ =>
496+ acc
497+ }
498+
499+ let startFromEpoch = if ((newFinalizedEpoch == height))
500+ then prevEpoch
501+ else valueOrErrorMessage(epochMeta(newFinalizedEpoch), "no prev epoch for start")._2
502+ let daoRewards = {
503+ let $l = offsets_100
504+ let $s = size($l)
505+ let $acc0 = $Tuple2(startFromEpoch, 1)
506+ func $f0_1 ($a,$i) = if (($i >= $s))
507+ then $a
508+ else countNonEmptyEpochs($a, $l[$i])
509+
510+ func $f0_2 ($a,$i) = if (($i >= $s))
511+ then $a
512+ else throw("List size exceeds 100")
513+
514+ $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)
515+ }
516+ let reissueAmount = (daoRewards._2 * getIntegerValue(daoRewardKey))
517+ let tokenId = fromBase58String(getStringValue(tokenIdKey))
518+[Reissue(tokenId, reissueAmount, true), ScriptTransfer(Address(fromBase58String(addr)), reissueAmount, tokenId)]
519+ }
520+ case _ =>
521+ nil
522+ }
523+ (rewardActions ++ (if (if ((newFinalizedBlockHash == newBlockHashHex))
481524 then true
482- else (blockMeta(newFinalizedBlockHash)._1 > curFinalizedBlockHeight))
525+ else (blockMeta(newFinalizedBlockHash)._1 > curFinalizedBlockMeta._1))
483526 then [StringEntry(finalizedBlockKey, newFinalizedBlockHash)]
484- else nil
527+ else nil))
485528 }
486529
487530
542585 let checkEpoch = ensureCorrectEpoch(vrf)
543586 if ((checkEpoch == checkEpoch))
544587 then {
545- let $t01613216245 = blockMeta(referenceHex)
546- let refChainHeight = $t01613216245._1
547- let refEpoch = $t01613216245._2
548- let refIgnored1 = $t01613216245._3
549- let refIgnored2 = $t01613216245._4
550- let refIgnored3 = $t01613216245._5
551- let refTransferIndex = $t01613216245._6
588+ let $t01729017403 = blockMeta(referenceHex)
589+ let refChainHeight = $t01729017403._1
590+ let refEpoch = $t01729017403._2
591+ let refIgnored1 = $t01729017403._3
592+ let refIgnored2 = $t01729017403._4
593+ let refIgnored3 = $t01729017403._5
594+ let refTransferIndex = $t01729017403._6
552595 let finalizedEpoch = blockMeta(getStringValue(finalizedBlockKey))._2
553596 let epochRef = if ((refEpoch >= finalizedEpoch))
554597 then refEpoch
595638 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, chainId, toBase16String(chainFirstBlockMeta._3))
596639 if ((checkChain == checkChain))
597640 then {
598- let $t01855818612 = chainMeta(chainId)
599- let chainHeight = $t01855818612._1
600- let chainLastBlock = $t01855818612._2
641+ let $t01971619770 = chainMeta(chainId)
642+ let chainHeight = $t01971619770._1
643+ let chainLastBlock = $t01971619770._2
601644 let checkReference = isReferenceCorrect(referenceHex, chainLastBlock)
602645 if ((checkReference == checkReference))
603646 then {
661704 if ((checkCaller == checkCaller))
662705 then {
663706 let chainId = valueOrElse(minerChainId(i.originCaller), mainChainId)
664- let $t02096121012 = chainMeta(chainId)
665- let chainHeight = $t02096121012._1
666- let lastBlockId = $t02096121012._2
707+ let $t02211922170 = chainMeta(chainId)
708+ let chainHeight = $t02211922170._1
709+ let lastBlockId = $t02211922170._2
667710 let checkReference = isReferenceCorrect(referenceHex, lastBlockId)
668711 if ((checkReference == checkReference))
669712 then {
884927
885928
886929 @Callable(i)
887-func setup (genesisBlockHashHex,minerRewardInGwei) = if (isContractSetup())
930+func setup (genesisBlockHashHex,minerRewardInGwei,daoAddress,daoReward) = if (isContractSetup())
888931 then throw("The contract has been already set up")
889932 else if ((0 > minerRewardInGwei))
890933 then throw("The miner reward must be nonnegative")
902945 let issue = Issue("UNIT0", "Native token", 0, 8, true)
903946 let tokenId = calculateAssetId(issue)
904947 let genesisBlockMeta = mkBlockMetaEntry(genesisBlockHashHex, 0, genesisBlockReferenceHash, 0, toBase16String(base58''), -1)
905-[genesisBlockMeta, StringEntry(chainFirstBlockIdKey(0), genesisBlockHashHex), mkChainMetaEntry(0, 0, genesisBlockHashHex), IntegerEntry(minerRewardKey, minerRewardInGwei), StringEntry(epochMetaKey(height), ((toString(genesisMinerAddress) + ",0,") + genesisBlockHashHex)), StringEntry(finalizedBlockKey, genesisBlockHashHex), issue, StringEntry(tokenIdKey, toBase58String(tokenId)), StringEntry(elBridgeAddressKey, "0x0000000000000000000000000000000000006a7e")]
948+ let daoEntries = if ((daoAddress == ""))
949+ then nil
950+ else [StringEntry(daoAddressKey, toString(Address(fromBase58String(daoAddress)))), IntegerEntry(daoRewardKey, if ((daoReward > 0))
951+ then daoReward
952+ else throw("invalid DAO reward amount"))]
953+ ([genesisBlockMeta, StringEntry(chainFirstBlockIdKey(0), genesisBlockHashHex), mkChainMetaEntry(0, 0, genesisBlockHashHex), IntegerEntry(minerRewardKey, minerRewardInGwei), StringEntry(epochMetaKey(height), ((toString(genesisMinerAddress) + ",0,") + genesisBlockHashHex)), StringEntry(finalizedBlockKey, genesisBlockHashHex), issue, StringEntry(tokenIdKey, toBase58String(tokenId)), StringEntry(elBridgeAddressKey, "0x0000000000000000000000000000000000006a7e")] ++ daoEntries)
906954 }
907955 else throw("Strict value is not equal to itself.")
908956 }
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 PUBLIC_KEY_HASH_SIZE = 20
1515
1616 let ROOT_HASH_SIZE = 32
1717
1818 let WITHDRAW_PROOFS_SIZE = 10
1919
2020 let ETH_ADDRESS_STR_SIZE = 40
2121
2222 let MAX_CL_TO_EL_TRANSFERS = 16
2323
2424 let zeroesStr = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
2525
26+let offsets_100 = split_4C("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::", "")
27+
2628 let allMinersKey = "allMiners"
2729
2830 let mainChainIdKey = "mainChainId"
2931
3032 let lastChainIdKey = "lastChainId"
3133
3234 let firstValidAltChainIdKey = "firstValidAltChainId"
3335
3436 let minerRewardKey = "minerReward"
3537
3638 let blockMetaK = "block_0x"
3739
3840 let finalizedBlockKey = "finalizedBlock"
3941
4042 let tokenIdKey = "tokenId"
4143
4244 let elBridgeAddressKey = "elBridgeAddress"
4345
4446 let nativeTransfersCountKey = "nativeTransfersCount"
47+
48+let daoAddressKey = "daoAddress"
49+
50+let daoRewardKey = "daoReward"
4551
4652 func pad (i) = {
4753 let s = toString(i)
4854 match size(s) {
4955 case _ =>
5056 if ((1 == $match0))
5157 then ("0000000" + s)
5258 else if ((2 == $match0))
5359 then ("000000" + s)
5460 else if ((3 == $match0))
5561 then ("00000" + s)
5662 else if ((4 == $match0))
5763 then ("0000" + s)
5864 else if ((5 == $match0))
5965 then ("000" + s)
6066 else if ((6 == $match0))
6167 then ("00" + s)
6268 else if ((7 == $match0))
6369 then ("0" + s)
6470 else s
6571 }
6672 }
6773
6874
6975 func blockE2CTransfersKey (blockHashHex) = ("elToClTransfers_0x" + blockHashHex)
7076
7177
7278 func epochMetaKey (epoch) = ("epoch_" + pad(epoch))
7379
7480
7581 func chainFirstBlockIdKey (chainId) = (("chain" + toString(chainId)) + "FirstBlock")
7682
7783
7884 func chainMetaKey (chainId) = ("chain_" + pad(chainId))
7985
8086
8187 func chainLastHeightKey (chainId,miner) = ((("chain_" + pad(chainId)) + "_") + toString(miner))
8288
8389
8490 func chainForkedHeightKey (chainId) = (("chain_" + pad(chainId)) + "ForkedHeight")
8591
8692
8793 func supportersKey (chainId) = (("chain" + toString(chainId)) + "Supporters")
8894
8995
9096 func minerRewardAddressKey (minerAddr) = (("miner_" + minerAddr) + "_RewardAddress")
9197
9298
9399 func minerPkKey (rewardAddress) = (("miner_0x" + rewardAddress) + "_PK")
94100
95101
96102 func minerChainIdKey (miner) = (("miner_" + toString(miner)) + "_ChainId")
97103
98104
99105 let nativeTransfersCount = valueOrElse(getInteger(this, nativeTransfersCountKey), 0)
100106
101107 func nativeTransferKey (index) = ("nativeTransfer_" + toString(index))
102108
103109
104110 func mkNativeTransferEntry (index,destElAddressHex,amount) = StringEntry(nativeTransferKey(index), ((("0x" + destElAddressHex) + SEP) + toString(amount)))
105111
106112
107113 func ensureCorrectTransfers (refTransferIndex,transferIndex,expectReward) = {
108114 let maxTransfers = if (expectReward)
109115 then (MAX_CL_TO_EL_TRANSFERS - 1)
110116 else MAX_CL_TO_EL_TRANSFERS
111117 let actualTransfers = (transferIndex - refTransferIndex)
112118 let checkNumber = if ((actualTransfers > maxTransfers))
113119 then throw(((("Allowed only " + toString(maxTransfers)) + " transfers, got ") + toString(actualTransfers)))
114120 else true
115121 if ((checkNumber == checkNumber))
116122 then if ((transferIndex >= nativeTransfersCount))
117123 then throw(((("Attempt to transfer #" + toString(transferIndex)) + ". Available transfers: ") + toString(nativeTransfersCount)))
118124 else true
119125 else throw("Strict value is not equal to itself.")
120126 }
121127
122128
123129 func amountGtEq (t,gtEq,queueSize) = if ((t.amount >= gtEq))
124130 then true
125131 else throw((((((("Transferring amount " + toString(t.amount)) + " should be >= ") + toString(gtEq)) + " for queue size of ") + toString(queueSize)) + ". Transfer more or wait"))
126132
127133
128134 func generatingBalance (address) = wavesBalance(address).generating
129135
130136
131137 func chainMeta (chainId) = {
132138 let s = getStringValue(chainMetaKey(chainId))
133139 let items = split(s, SEP)
134140 $Tuple2(parseIntValue(items[0]), items[1])
135141 }
136142
137143
138144 func mkChainMetaEntry (chainId,newChainHeight,blockHashHex) = StringEntry(chainMetaKey(chainId), ((toString(newChainHeight) + SEP) + blockHashHex))
139145
140146
141147 let mainChainId = valueOrElse(getInteger(mainChainIdKey), 0)
142148
143-let $t050295095 = chainMeta(mainChainId)
149+let $t052495315 = chainMeta(mainChainId)
144150
145-let mainChainHeight = $t050295095._1
151+let mainChainHeight = $t052495315._1
146152
147-let mainChainLastBlock = $t050295095._2
153+let mainChainLastBlock = $t052495315._2
148154
149155 func epochMeta (epoch) = match getString(epochMetaKey(epoch)) {
150156 case s: String =>
151157 let fragments = split(s, SEP)
152158 $Tuple3(addressFromStringValue(fragments[0]), parseIntValue(fragments[1]), fragments[2])
153159 case _ =>
154160 unit
155161 }
156162
157163
158-let $t053265450 = match epochMeta(height) {
164+let $t055465670 = match epochMeta(height) {
159165 case m: (Address, Int, String) =>
160166 m
161167 case _ =>
162168 $Tuple2(unit, 0)
163169 }
164170
165-let thisEpochMiner = $t053265450._1
171+let thisEpochMiner = $t055465670._1
166172
167-let thisEpochRef = $t053265450._2
173+let thisEpochRef = $t055465670._2
168174
169175 let allMinersStr = valueOrElse(getString(allMinersKey), "")
170176
171177 let allMiners = match allMinersStr {
172178 case _ =>
173179 if (("" == $match0))
174180 then nil
175181 else if ($isInstanceOf($match0, "String"))
176182 then {
177183 let raw = $match0
178184 split_4C(raw, SEP)
179185 }
180186 else throw("Match error")
181187 }
182188
183189 func blockMeta (blockId) = {
184190 let meta = getBinaryValue((blockMetaK + blockId))
185191 let metaSize = size(meta)
186192 let blockHeight = toInt(meta)
187193 let blockEpoch = toInt(meta, 8)
188194 let blockParent = take(drop(meta, 16), BLOCK_HASH_SIZE)
189195 let chainId = toInt(meta, (16 + BLOCK_HASH_SIZE))
190196 let baseOffset = (24 + BLOCK_HASH_SIZE)
191197 let remainingBytes = (metaSize - baseOffset)
192198 let e2cTransfersRootHash = if ((remainingBytes >= ROOT_HASH_SIZE))
193199 then take(drop(meta, baseOffset), ROOT_HASH_SIZE)
194200 else base58''
195201 let lastC2ETransferIndex = if (if ((remainingBytes == 8))
196202 then true
197203 else (remainingBytes > ROOT_HASH_SIZE))
198204 then toInt(meta, (baseOffset + size(e2cTransfersRootHash)))
199205 else -1
200206 $Tuple6(blockHeight, blockEpoch, blockParent, chainId, e2cTransfersRootHash, lastC2ETransferIndex)
201207 }
202208
203209
204210 func mkBlockMetaEntry (blockHashHex,blockHeight,blockParentHex,chainId,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
205211 let e2cTransfersRootHashBytes = fromBase16String(e2cTransfersRootHashHex)
206212 let rootHashBytesSize = size(e2cTransfersRootHashBytes)
207213 let checkRootHash = if (if ((rootHashBytesSize == 0))
208214 then true
209215 else (rootHashBytesSize == ROOT_HASH_SIZE))
210216 then true
211217 else throw(((("Transfers root hash should have 0 or " + toString(ROOT_HASH_SIZE)) + " bytes, got ") + toString(rootHashBytesSize)))
212218 if ((checkRootHash == checkRootHash))
213219 then {
214220 let blockMetaBytes = (((((toBytes(blockHeight) + toBytes(height)) + fromBase16String(blockParentHex)) + toBytes(chainId)) + e2cTransfersRootHashBytes) + toBytes(lastC2ETransferIndex))
215221 BinaryEntry((blockMetaK + blockHashHex), blockMetaBytes)
216222 }
217223 else throw("Strict value is not equal to itself.")
218224 }
219225
220226
221227 func lastHeightBy (miner,chainId) = match getInteger(chainLastHeightKey(chainId, miner)) {
222228 case h: Int =>
223229 h
224230 case _ =>
225231 let blockHash = getStringValue(((("chain" + toString(chainId)) + "LastMinedBy") + toString(miner)))
226232 blockMeta(blockHash)._1
227233 }
228234
229235
230-let $t074908425 = {
236+let $t077108645 = {
231237 let hitSource = match lastBlock.vrf {
232238 case vrf: ByteVector =>
233239 vrf
234240 case _ =>
235241 lastBlock.generationSignature
236242 }
237243 func processMiner (prev,miner) = {
238- let $t077577820 = prev
239- let prevMiner = $t077577820._1
240- let prevTotalBalance = $t077577820._2
241- let prevDelay = $t077577820._3
242- let prevMiners = $t077577820._4
244+ let $t079778040 = prev
245+ let prevMiner = $t079778040._1
246+ let prevTotalBalance = $t079778040._2
247+ let prevDelay = $t079778040._3
248+ let prevMiners = $t079778040._4
243249 let minerAddress = addressFromStringValue(miner)
244250 let wavesGenBalance = wavesBalance(minerAddress).generating
245251 let minerBalance = generatingBalance(minerAddress)
246252 if (if ((MIN_BALANCE > wavesGenBalance))
247253 then true
248254 else (0 >= minerBalance))
249255 then prev
250256 else {
251257 let nextDelay = calculateDelay(minerAddress, minerBalance)
252258 if ((prevDelay > nextDelay))
253259 then $Tuple4(miner, (prevTotalBalance + minerBalance), nextDelay, (prevMiners :+ miner))
254260 else $Tuple4(prevMiner, (prevTotalBalance + minerBalance), prevDelay, (prevMiners :+ miner))
255261 }
256262 }
257263
258264 let $l = allMiners
259265 let $s = size($l)
260266 let $acc0 = $Tuple4("", 0, INT_MAX, nil)
261267 func $f0_1 ($a,$i) = if (($i >= $s))
262268 then $a
263269 else processMiner($a, $l[$i])
264270
265271 func $f0_2 ($a,$i) = if (($i >= $s))
266272 then $a
267273 else throw("List size exceeds 50")
268274
269275 $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)
270276 }
271277
272-let computedGenerator = $t074908425._1
278+let computedGenerator = $t077108645._1
273279
274-let computedTotalBalance = $t074908425._2
280+let computedTotalBalance = $t077108645._2
275281
276-let $t084278493 = blockMeta(mainChainLastBlock)
282+let $t086478713 = blockMeta(mainChainLastBlock)
277283
278-let mclbIgnored1 = $t084278493._1
284+let mclbIgnored1 = $t086478713._1
279285
280-let mainChainEpoch = $t084278493._2
286+let mainChainEpoch = $t086478713._2
281287
282-func calculateFinalizedBlockHash (curMiner,curPrevEpoch,curLastBlockHash) = {
283- let offsets_100 = split_4C("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::", "")
288+func calculateFinalizedBlockHashAndEpoch (curMiner,curPrevEpoch,curLastBlockHash) = {
284289 let halfBalance = (computedTotalBalance / 2)
285290 func step (prev,next) = {
286- let $t088598923 = prev
287- let thisEpoch = $t088598923._1
288- let maybeSafeEpoch = $t088598923._2
289- let totalBalance = $t088598923._3
290- let prevMiners = $t088598923._4
291- match maybeSafeEpoch {
291+ let $t089519024 = prev
292+ let thisEpoch = $t089519024._1
293+ let maybeFinalizedBlockHash = $t089519024._2
294+ let totalBalance = $t089519024._3
295+ let prevMiners = $t089519024._4
296+ match maybeFinalizedBlockHash {
292297 case _: Unit =>
293- let $t089819147 = if ((thisEpoch == height))
298+ let $t090919257 = if ((thisEpoch == height))
294299 then $Tuple3(curMiner, curPrevEpoch, curLastBlockHash)
295300 else value(epochMeta(thisEpoch))
296- let miner = $t089819147._1
297- let prevEpoch = $t089819147._2
298- let lastBlockHash = $t089819147._3
301+ let miner = $t090919257._1
302+ let prevEpoch = $t090919257._2
303+ let lastBlockHash = $t090919257._3
299304 if (if ((prevEpoch == 0))
300305 then true
301306 else ((height - thisEpoch) >= 100))
302307 then $Tuple4(thisEpoch, lastBlockHash, totalBalance, allMiners)
303308 else {
304- let $t093019503 = if (containsElement(prevMiners, miner))
309+ let $t094119613 = if (containsElement(prevMiners, miner))
305310 then $Tuple2(totalBalance, prevMiners)
306311 else $Tuple2((totalBalance + generatingBalance(miner)), miner :: prevMiners)
307- let newTotalBalance = $t093019503._1
308- let newMiners = $t093019503._2
312+ let newTotalBalance = $t094119613._1
313+ let newMiners = $t094119613._2
309314 if ((newTotalBalance > halfBalance))
310315 then $Tuple4(thisEpoch, lastBlockHash, newTotalBalance, allMiners)
311316 else $Tuple4(prevEpoch, unit, newTotalBalance, newMiners)
312317 }
313318 case _ =>
314319 prev
315320 }
316321 }
317322
318- let $t097369832 = {
323+ let $t098469943 = {
319324 let $l = offsets_100
320325 let $s = size($l)
321326 let $acc0 = $Tuple4(height, unit, 0, nil)
322327 func $f0_1 ($a,$i) = if (($i >= $s))
323328 then $a
324329 else step($a, $l[$i])
325330
326331 func $f0_2 ($a,$i) = if (($i >= $s))
327332 then $a
328333 else throw("List size exceeds 100")
329334
330335 $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)
331336 }
332- let fallbackEpoch = $t097369832._1
333- let finalizedBlockHashOpt = $t097369832._2
334- match finalizedBlockHashOpt {
337+ let finalizedEpoch = $t098469943._1
338+ let finalizedBlockHashOpt = $t098469943._2
339+ $Tuple2( match finalizedBlockHashOpt {
335340 case finalizedBlockHash: String =>
336341 finalizedBlockHash
337342 case _ =>
338- value(epochMeta(fallbackEpoch))._3
339- }
343+ value(epochMeta(finalizedEpoch))._3
344+ }, finalizedEpoch)
340345 }
341346
342347
343348 func supportingBalance (chainId) = {
344349 func addBalance (acc,generatorStr) = {
345- let $t01010210138 = acc
346- let totalBalance = $t01010210138._1
347- let generators = $t01010210138._2
350+ let $t01022610262 = acc
351+ let totalBalance = $t01022610262._1
352+ let generators = $t01022610262._2
348353 let generator = addressFromStringValue(generatorStr)
349354 if (containsElement(generators, generator))
350355 then acc
351356 else {
352357 let balance = generatingBalance(generator)
353358 $Tuple2((totalBalance + balance), (generators :+ generator))
354359 }
355360 }
356361
357362 let allGenerators = split_4C(getStringValue(supportersKey(chainId)), SEP)
358- let $t01046010525 = {
363+ let res = {
359364 let $l = allGenerators
360365 let $s = size($l)
361366 let $acc0 = $Tuple2(0, nil)
362367 func $f0_1 ($a,$i) = if (($i >= $s))
363368 then $a
364369 else addBalance($a, $l[$i])
365370
366371 func $f0_2 ($a,$i) = if (($i >= $s))
367372 then $a
368373 else throw("List size exceeds 100")
369374
370375 $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)
371376 }
372- let balance = $t01046010525._1
373- let _g = $t01046010525._2
374- balance
377+ res._1
375378 }
376379
377380
378381 func isContractSetup () = isDefined(getInteger(minerRewardKey))
379382
380383
381384 func ensureMiningEpoch (generator) = if ((toString(generator) != computedGenerator))
382385 then throw(((((toBase58String(generator.bytes) + " is not allowed to mine in ") + toString(height)) + " epoch. Expected ") + computedGenerator))
383386 else unit
384387
385388
386389 func isReferenceCorrect (reference,lastBlock) = if ((reference == lastBlock))
387390 then unit
388391 else throw(((("Expected a reference to the chain last block: 0x" + lastBlock) + ". Got: 0x") + reference))
389392
390393
391394 func chainIsInactive (chainId) = {
392395 let firstBlockId = getStringValue(chainFirstBlockIdKey(chainId))
393396 let firstValidAltChainId = valueOrElse(getInteger(firstValidAltChainIdKey), 0)
394397 if ((firstValidAltChainId > chainId))
395398 then true
396399 else (blockMeta(getStringValue(finalizedBlockKey))._1 > blockMeta(firstBlockId)._1)
397400 }
398401
399402
400403 func minerChainId (miner) = valueOrElse(getInteger(minerChainIdKey(miner)), getInteger(("chainIdOf" + toString(miner))))
401404
402405
403406 func ensureExpectedOrInactiveChain (generator,expectedChainId,checkHeightBlock) = {
404407 let heightIsCorrect = match checkHeightBlock {
405408 case blockHash: String =>
406409 let lastMinedBlockHeight = lastHeightBy(generator, mainChainId)
407410 ((blockMeta(blockHash)._1 + 1) > lastMinedBlockHeight)
408411 case _ =>
409412 true
410413 }
411414 match minerChainId(generator) {
412415 case currentId: Int =>
413416 if (if ((currentId == expectedChainId))
414417 then true
415418 else if (chainIsInactive(currentId))
416419 then heightIsCorrect
417420 else false)
418421 then unit
419422 else throw(("miner is mining other chain " + toString(currentId)))
420423 case _ =>
421424 unit
422425 }
423426 }
424427
425428
426429 let heightString = (" at height " + toString(height))
427430
428431 func vrfAt (height) = valueOrErrorMessage(valueOrErrorMessage(blockInfoByHeight(height), ("last block is not available" + heightString)).vrf, ("VRF is not available" + heightString))
429432
430433
431434 func ensureCorrectEpoch (expectedVRF) = {
432435 let actualVRF = vrfAt(height)
433436 if ((expectedVRF == actualVRF))
434437 then unit
435438 else throw((((("Expected VRF " + toBase58String(expectedVRF)) + " does not match actual ") + toBase58String(actualVRF)) + heightString))
436439 }
437440
438441
439442 func addSupporter (chainId,generator) = {
440443 let supportersStr = getStringValue(supportersKey(chainId))
441444 let supporters = split_4C(supportersStr, SEP)
442445 if (containsElement(supporters, toString(generator)))
443446 then nil
444447 else [StringEntry(supportersKey(chainId), ((supportersStr + SEP) + toString(generator)))]
445448 }
446449
447450
448451 func setOrFail (flags,index) = if ((0 > index))
449452 then throw(("Can't withdraw at negative index: " + toString(index)))
450453 else {
451454 let flagsSize = size(flags)
452455 if ((index >= flagsSize))
453456 then {
454457 let addZeroes = (index - flagsSize)
455458 if ((addZeroes > size(zeroesStr)))
456459 then throw((("Can't add " + toString(addZeroes)) + " empty flags. Contact with developers"))
457460 else ((flags + take(zeroesStr, addZeroes)) + "1")
458461 }
459462 else {
460463 let tail = drop(flags, index)
461464 let atIndex = take(tail, 1)
462465 if ((atIndex == "0"))
463466 then ((take(flags, index) + "1") + drop(tail, 1))
464467 else throw((("Transfer #" + toString(index)) + " has been already taken"))
465468 }
466469 }
467470
468471
469472 func validateBlockHash (hexStr) = {
470473 let decodedBytes = fromBase16String(hexStr)
471474 if ((size(decodedBytes) != BLOCK_HASH_SIZE))
472475 then throw("invalid block id length")
473476 else hexStr
474477 }
475478
476479
477480 func getUpdateFinalizedBlockAction (caller,newBlockHashHex,prevEpoch) = {
478- let curFinalizedBlockHeight = blockMeta(getStringValue(finalizedBlockKey))._1
479- let newFinalizedBlockHash = calculateFinalizedBlockHash(caller, prevEpoch, newBlockHashHex)
480- if (if ((newFinalizedBlockHash == newBlockHashHex))
481+ let curFinalizedBlockMeta = blockMeta(getStringValue(finalizedBlockKey))
482+ let $t01427314393 = calculateFinalizedBlockHashAndEpoch(caller, prevEpoch, newBlockHashHex)
483+ let newFinalizedBlockHash = $t01427314393._1
484+ let newFinalizedEpoch = $t01427314393._2
485+ let rewardActions = match getString(daoAddressKey) {
486+ case addr: String =>
487+ if ((newFinalizedEpoch == curFinalizedBlockMeta._2))
488+ then nil
489+ else {
490+ func countNonEmptyEpochs (acc,next) = if ((acc._1 == curFinalizedBlockMeta._2))
491+ then acc
492+ else match epochMeta(acc._1) {
493+ case m: (Address, Int, String) =>
494+ $Tuple2(m._2, (acc._2 + 1))
495+ case _ =>
496+ acc
497+ }
498+
499+ let startFromEpoch = if ((newFinalizedEpoch == height))
500+ then prevEpoch
501+ else valueOrErrorMessage(epochMeta(newFinalizedEpoch), "no prev epoch for start")._2
502+ let daoRewards = {
503+ let $l = offsets_100
504+ let $s = size($l)
505+ let $acc0 = $Tuple2(startFromEpoch, 1)
506+ func $f0_1 ($a,$i) = if (($i >= $s))
507+ then $a
508+ else countNonEmptyEpochs($a, $l[$i])
509+
510+ func $f0_2 ($a,$i) = if (($i >= $s))
511+ then $a
512+ else throw("List size exceeds 100")
513+
514+ $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)
515+ }
516+ let reissueAmount = (daoRewards._2 * getIntegerValue(daoRewardKey))
517+ let tokenId = fromBase58String(getStringValue(tokenIdKey))
518+[Reissue(tokenId, reissueAmount, true), ScriptTransfer(Address(fromBase58String(addr)), reissueAmount, tokenId)]
519+ }
520+ case _ =>
521+ nil
522+ }
523+ (rewardActions ++ (if (if ((newFinalizedBlockHash == newBlockHashHex))
481524 then true
482- else (blockMeta(newFinalizedBlockHash)._1 > curFinalizedBlockHeight))
525+ else (blockMeta(newFinalizedBlockHash)._1 > curFinalizedBlockMeta._1))
483526 then [StringEntry(finalizedBlockKey, newFinalizedBlockHash)]
484- else nil
527+ else nil))
485528 }
486529
487530
488531 @Callable(i)
489532 func extendMainChain (blockHashHex,referenceHex,vrf,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
490533 let checkBlockHash = validateBlockHash(blockHashHex)
491534 if ((checkBlockHash == checkBlockHash))
492535 then {
493536 let checkEpoch = ensureCorrectEpoch(vrf)
494537 if ((checkEpoch == checkEpoch))
495538 then {
496539 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, mainChainId, unit)
497540 if ((checkChain == checkChain))
498541 then {
499542 let checkReference = isReferenceCorrect(referenceHex, mainChainLastBlock)
500543 if ((checkReference == checkReference))
501544 then {
502545 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._6, lastC2ETransferIndex, true)
503546 if ((checkTransfers == checkTransfers))
504547 then {
505548 let thisEpochMeta = match epochMeta(height) {
506549 case _: Unit =>
507550 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(mainChainEpoch)) + SEP) + blockHashHex))
508551 case other =>
509552 throw("Epoch already started")
510553 }
511554 if ((thisEpochMeta == thisEpochMeta))
512555 then {
513556 let checkGenerator = ensureMiningEpoch(i.originCaller)
514557 if ((checkGenerator == checkGenerator))
515558 then {
516559 let updateFinalizedBlock = getUpdateFinalizedBlockAction(i.originCaller, blockHashHex, mainChainEpoch)
517560 let newChainHeight = (mainChainHeight + 1)
518561 ([mkBlockMetaEntry(blockHashHex, newChainHeight, mainChainLastBlock, mainChainId, e2cTransfersRootHashHex, lastC2ETransferIndex), mkChainMetaEntry(mainChainId, newChainHeight, blockHashHex), IntegerEntry(minerChainIdKey(i.originCaller), mainChainId), IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), newChainHeight), thisEpochMeta] ++ updateFinalizedBlock)
519562 }
520563 else throw("Strict value is not equal to itself.")
521564 }
522565 else throw("Strict value is not equal to itself.")
523566 }
524567 else throw("Strict value is not equal to itself.")
525568 }
526569 else throw("Strict value is not equal to itself.")
527570 }
528571 else throw("Strict value is not equal to itself.")
529572 }
530573 else throw("Strict value is not equal to itself.")
531574 }
532575 else throw("Strict value is not equal to itself.")
533576 }
534577
535578
536579
537580 @Callable(i)
538581 func startAltChain (blockHashHex,referenceHex,vrf,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
539582 let checkBlockHash = validateBlockHash(blockHashHex)
540583 if ((checkBlockHash == checkBlockHash))
541584 then {
542585 let checkEpoch = ensureCorrectEpoch(vrf)
543586 if ((checkEpoch == checkEpoch))
544587 then {
545- let $t01613216245 = blockMeta(referenceHex)
546- let refChainHeight = $t01613216245._1
547- let refEpoch = $t01613216245._2
548- let refIgnored1 = $t01613216245._3
549- let refIgnored2 = $t01613216245._4
550- let refIgnored3 = $t01613216245._5
551- let refTransferIndex = $t01613216245._6
588+ let $t01729017403 = blockMeta(referenceHex)
589+ let refChainHeight = $t01729017403._1
590+ let refEpoch = $t01729017403._2
591+ let refIgnored1 = $t01729017403._3
592+ let refIgnored2 = $t01729017403._4
593+ let refIgnored3 = $t01729017403._5
594+ let refTransferIndex = $t01729017403._6
552595 let finalizedEpoch = blockMeta(getStringValue(finalizedBlockKey))._2
553596 let epochRef = if ((refEpoch >= finalizedEpoch))
554597 then refEpoch
555598 else throw((((("Can not start alt chain from epoch " + toString(refEpoch)) + ", epoch ") + toString(finalizedEpoch)) + " is finalized"))
556599 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, mainChainId, referenceHex)
557600 if ((checkChain == checkChain))
558601 then {
559602 let checkTransfers = ensureCorrectTransfers(refTransferIndex, lastC2ETransferIndex, true)
560603 if ((checkTransfers == checkTransfers))
561604 then {
562605 let newChainId = (valueOrElse(getInteger(lastChainIdKey), 0) + 1)
563606 let newChainHeight = (refChainHeight + 1)
564607 let thisEpochMeta = match epochMeta(height) {
565608 case _: Unit =>
566609 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(epochRef)) + SEP) + blockHashHex))
567610 case other =>
568611 throw("Epoch already started")
569612 }
570613 let checkGenerator = ensureMiningEpoch(i.originCaller)
571614 if ((checkGenerator == checkGenerator))
572615 then [thisEpochMeta, mkBlockMetaEntry(blockHashHex, newChainHeight, referenceHex, newChainId, e2cTransfersRootHashHex, lastC2ETransferIndex), 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)]
573616 else throw("Strict value is not equal to itself.")
574617 }
575618 else throw("Strict value is not equal to itself.")
576619 }
577620 else throw("Strict value is not equal to itself.")
578621 }
579622 else throw("Strict value is not equal to itself.")
580623 }
581624 else throw("Strict value is not equal to itself.")
582625 }
583626
584627
585628
586629 @Callable(i)
587630 func extendAltChain (blockHashHex,referenceHex,vrf,chainId,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
588631 let checkBlockHash = validateBlockHash(blockHashHex)
589632 if ((checkBlockHash == checkBlockHash))
590633 then {
591634 let checkEpoch = ensureCorrectEpoch(vrf)
592635 if ((checkEpoch == checkEpoch))
593636 then {
594637 let chainFirstBlockMeta = blockMeta(getStringValue(chainFirstBlockIdKey(chainId)))
595638 let checkChain = ensureExpectedOrInactiveChain(i.originCaller, chainId, toBase16String(chainFirstBlockMeta._3))
596639 if ((checkChain == checkChain))
597640 then {
598- let $t01855818612 = chainMeta(chainId)
599- let chainHeight = $t01855818612._1
600- let chainLastBlock = $t01855818612._2
641+ let $t01971619770 = chainMeta(chainId)
642+ let chainHeight = $t01971619770._1
643+ let chainLastBlock = $t01971619770._2
601644 let checkReference = isReferenceCorrect(referenceHex, chainLastBlock)
602645 if ((checkReference == checkReference))
603646 then {
604647 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._6, lastC2ETransferIndex, true)
605648 if ((checkTransfers == checkTransfers))
606649 then {
607650 let newChainHeight = (chainHeight + 1)
608651 let prevEpoch = blockMeta(referenceHex)._2
609652 let updateMainChainData = if ((supportingBalance(chainId) > (computedTotalBalance / 2)))
610653 then {
611654 let lastChainId = valueOrElse(getInteger(lastChainIdKey), 0)
612655 let updateFinalizedBlock = getUpdateFinalizedBlockAction(i.originCaller, blockHashHex, prevEpoch)
613656 ([IntegerEntry(chainForkedHeightKey(mainChainId), chainFirstBlockMeta._1), IntegerEntry(mainChainIdKey, chainId), IntegerEntry(firstValidAltChainIdKey, (lastChainId + 1))] ++ updateFinalizedBlock)
614657 }
615658 else nil
616659 let thisEpochMeta = match epochMeta(height) {
617660 case _: Unit =>
618661 StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(prevEpoch)) + SEP) + blockHashHex))
619662 case other =>
620663 throw("Epoch already started")
621664 }
622665 if ((thisEpochMeta == thisEpochMeta))
623666 then {
624667 let checkGenerator = ensureMiningEpoch(i.originCaller)
625668 if ((checkGenerator == checkGenerator))
626669 then {
627670 let updateMainChainLastMinedBlock = if (if ((updateMainChainData == nil))
628671 then (valueOrElse(minerChainId(i.originCaller), 0) != chainId)
629672 else false)
630673 then [IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), chainFirstBlockMeta._1)]
631674 else nil
632675 ((([mkBlockMetaEntry(blockHashHex, newChainHeight, referenceHex, chainId, e2cTransfersRootHashHex, lastC2ETransferIndex), mkChainMetaEntry(chainId, newChainHeight, blockHashHex), thisEpochMeta, IntegerEntry(minerChainIdKey(i.originCaller), chainId), IntegerEntry(chainLastHeightKey(chainId, i.originCaller), newChainHeight)] ++ updateMainChainData) ++ addSupporter(chainId, i.originCaller)) ++ updateMainChainLastMinedBlock)
633676 }
634677 else throw("Strict value is not equal to itself.")
635678 }
636679 else throw("Strict value is not equal to itself.")
637680 }
638681 else throw("Strict value is not equal to itself.")
639682 }
640683 else throw("Strict value is not equal to itself.")
641684 }
642685 else throw("Strict value is not equal to itself.")
643686 }
644687 else throw("Strict value is not equal to itself.")
645688 }
646689 else throw("Strict value is not equal to itself.")
647690 }
648691
649692
650693
651694 @Callable(i)
652695 func appendBlock (blockHashHex,referenceHex,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
653696 let checkCaller = if ((thisEpochMiner == i.originCaller))
654697 then true
655698 else match thisEpochMiner {
656699 case epochMiner: Address =>
657700 throw(("not allowed to forge blocks in this epoch, expected from " + toString(epochMiner)))
658701 case _ =>
659702 throw("not allowed to forge blocks in this epoch, epoch miner is absent")
660703 }
661704 if ((checkCaller == checkCaller))
662705 then {
663706 let chainId = valueOrElse(minerChainId(i.originCaller), mainChainId)
664- let $t02096121012 = chainMeta(chainId)
665- let chainHeight = $t02096121012._1
666- let lastBlockId = $t02096121012._2
707+ let $t02211922170 = chainMeta(chainId)
708+ let chainHeight = $t02211922170._1
709+ let lastBlockId = $t02211922170._2
667710 let checkReference = isReferenceCorrect(referenceHex, lastBlockId)
668711 if ((checkReference == checkReference))
669712 then {
670713 let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._6, lastC2ETransferIndex, false)
671714 if ((checkTransfers == checkTransfers))
672715 then {
673716 let newChainHeight = (chainHeight + 1)
674717 let checkBlockHash = validateBlockHash(blockHashHex)
675718 if ((checkBlockHash == checkBlockHash))
676719 then [mkBlockMetaEntry(blockHashHex, newChainHeight, lastBlockId, chainId, e2cTransfersRootHashHex, lastC2ETransferIndex), IntegerEntry(chainLastHeightKey(chainId, i.originCaller), newChainHeight), mkChainMetaEntry(chainId, newChainHeight, blockHashHex), StringEntry(epochMetaKey(height), ((((toString(value(thisEpochMiner)) + SEP) + toString(thisEpochRef)) + SEP) + blockHashHex))]
677720 else throw("Strict value is not equal to itself.")
678721 }
679722 else throw("Strict value is not equal to itself.")
680723 }
681724 else throw("Strict value is not equal to itself.")
682725 }
683726 else throw("Strict value is not equal to itself.")
684727 }
685728
686729
687730
688731 @Callable(i)
689732 func join (rewardAddressHex) = {
690733 func ensureNotOverrideOtherMinerPk (elAddressHex) = match getBinary(minerPkKey(elAddressHex)) {
691734 case pk: ByteVector =>
692735 if ((pk == i.originCallerPublicKey))
693736 then unit
694737 else throw(((("EL miner address " + elAddressHex) + " is already linked with ") + toBase58String(pk)))
695738 case _ =>
696739 unit
697740 }
698741
699742 let parts = split(rewardAddressHex, "0x")
700743 let rewardAddress = fromBase16String(parts[(size(parts) - 1)])
701744 if (!(isContractSetup()))
702745 then throw("The contract has not yet set up")
703746 else if ((MIN_BALANCE > wavesBalance(i.originCaller).generating))
704747 then throw(((("Insufficient generating balance: " + toString(wavesBalance(i.originCaller).generating)) + ". Required: ") + toString(MIN_BALANCE)))
705748 else if ((size(rewardAddress) != 20))
706749 then throw("rewardAddress should be an L2 address")
707750 else if ((size(allMiners) >= 50))
708751 then throw("too many miners")
709752 else {
710753 func checkExistence (exists,miner) = if (exists)
711754 then true
712755 else (miner == toString(i.originCaller))
713756
714757 let alreadyExists = {
715758 let $l = allMiners
716759 let $s = size($l)
717760 let $acc0 = false
718761 func $f0_1 ($a,$i) = if (($i >= $s))
719762 then $a
720763 else checkExistence($a, $l[$i])
721764
722765 func $f0_2 ($a,$i) = if (($i >= $s))
723766 then $a
724767 else throw("List size exceeds 50")
725768
726769 $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)
727770 }
728771 if (alreadyExists)
729772 then nil
730773 else {
731774 let newMiner = toString(i.originCaller)
732775 let lowercaseRewardAddress = toBase16String(rewardAddress)
733776 let check = ensureNotOverrideOtherMinerPk(lowercaseRewardAddress)
734777 if ((check == check))
735778 then {
736779 let newMiners = if ((size(allMiners) == 0))
737780 then newMiner
738781 else ((allMinersStr + SEP) + newMiner)
739782 let deletePrevRewardAddressPk = match getString(minerRewardAddressKey(newMiner)) {
740783 case prevAddress: String =>
741784 if ((prevAddress == toBase16String(rewardAddress)))
742785 then nil
743786 else [DeleteEntry(minerPkKey(prevAddress))]
744787 case _ =>
745788 nil
746789 }
747790 ([StringEntry(allMinersKey, newMiners), StringEntry(minerRewardAddressKey(newMiner), ("0x" + lowercaseRewardAddress)), BinaryEntry(minerPkKey(lowercaseRewardAddress), i.originCallerPublicKey)] ++ deletePrevRewardAddressPk)
748791 }
749792 else throw("Strict value is not equal to itself.")
750793 }
751794 }
752795 }
753796
754797
755798
756799 @Callable(i)
757800 func leave () = {
758801 let leavingMiner = toString(i.originCaller)
759802 func skipLeavingMiner (acc,miner) = if ((miner == leavingMiner))
760803 then acc
761804 else (acc :+ miner)
762805
763806 let remainingMiners = {
764807 let $l = allMiners
765808 let $s = size($l)
766809 let $acc0 = nil
767810 func $f0_1 ($a,$i) = if (($i >= $s))
768811 then $a
769812 else skipLeavingMiner($a, $l[$i])
770813
771814 func $f0_2 ($a,$i) = if (($i >= $s))
772815 then $a
773816 else throw("List size exceeds 50")
774817
775818 $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)
776819 }
777820 let rewardAddrKey = minerRewardAddressKey(leavingMiner)
778821 let prevRewardAddress = valueOrErrorMessage(getString(this, rewardAddrKey), "miner has never joined")
779822 if ((prevRewardAddress == prevRewardAddress))
780823 then if ((thisEpochMiner == i.originCaller))
781824 then throw("designated miner can't leave")
782825 else [StringEntry(allMinersKey, makeString_2C(remainingMiners, SEP))]
783826 else throw("Strict value is not equal to itself.")
784827 }
785828
786829
787830
788831 @Callable(i)
789832 func transfer (destElAddressHex) = {
790833 let checkAddress = if ((size(destElAddressHex) == ETH_ADDRESS_STR_SIZE))
791834 then fromBase16String(destElAddressHex)
792835 else throw(((("Address should have " + toString(ETH_ADDRESS_STR_SIZE)) + " characters, got ") + toString(size(destElAddressHex))))
793836 if ((checkAddress == checkAddress))
794837 then {
795838 let checkPayment = if ((size(i.payments) == 1))
796839 then true
797840 else throw(("Expected one payment as a transfer amount, got " + toString(size(i.payments))))
798841 if ((checkPayment == checkPayment))
799842 then {
800843 let tokenIdStr = getStringValue(tokenIdKey)
801844 let tokenId = fromBase58String(tokenIdStr)
802845 let t = i.payments[0]
803846 let checkAssetId = match t.assetId {
804847 case assetId: ByteVector =>
805848 if ((assetId == tokenId))
806849 then true
807850 else throw(((("Expected " + tokenIdStr) + " in the payment, got ") + toBase58String(assetId)))
808851 case _ =>
809852 throw((("Expected " + tokenIdStr) + " in the payment, got Waves"))
810853 }
811854 if ((checkAssetId == checkAssetId))
812855 then {
813856 let lastIndex = blockMeta(mainChainLastBlock)._6
814857 let queueSize = (nativeTransfersCount - lastIndex)
815858 let checkQueueLimit = if ((160 > queueSize))
816859 then amountGtEq(t, 1000000, queueSize)
817860 else if ((1600 > queueSize))
818861 then amountGtEq(t, 10000000, queueSize)
819862 else if ((3200 > queueSize))
820863 then amountGtEq(t, 100000000, queueSize)
821864 else if ((6400 > queueSize))
822865 then amountGtEq(t, 1000000000, queueSize)
823866 else throw((("Transfers denied for queue size of " + toString(queueSize)) + ". Wait until current transfers processed"))
824867 if ((checkQueueLimit == checkQueueLimit))
825868 then [IntegerEntry(nativeTransfersCountKey, (nativeTransfersCount + 1)), mkNativeTransferEntry(nativeTransfersCount, destElAddressHex, t.amount), Burn(tokenId, t.amount)]
826869 else throw("Strict value is not equal to itself.")
827870 }
828871 else throw("Strict value is not equal to itself.")
829872 }
830873 else throw("Strict value is not equal to itself.")
831874 }
832875 else throw("Strict value is not equal to itself.")
833876 }
834877
835878
836879
837880 @Callable(i)
838881 func withdraw (blockHashHex,merkleProof,transferIndexInBlock,amount) = {
839882 let withdrawBlockMeta = blockMeta(blockHashHex)
840883 let withdrawBlockHeight = withdrawBlockMeta._1
841884 let finalizedBlockHeight = blockMeta(getStringValue(finalizedBlockKey))._1
842885 let mainChainLastBlockHeight = blockMeta(mainChainLastBlock)._1
843886 if ((withdrawBlockHeight > finalizedBlockHeight))
844887 then throw(((("EL block #" + toString(withdrawBlockHeight)) + " is not finalized. The current finalized is #") + toString(finalizedBlockHeight)))
845888 else if ((size(merkleProof) != WITHDRAW_PROOFS_SIZE))
846889 then throw(((("Expected " + toString(WITHDRAW_PROOFS_SIZE)) + " proofs, got ") + toString(size(merkleProof))))
847890 else if ((0 > transferIndexInBlock))
848891 then throw(("Transfer index in block should be nonnegative, got " + toString(transferIndexInBlock)))
849892 else if ((0 >= amount))
850893 then throw(("Amount should be positive, got " + toString(amount)))
851894 else {
852895 let withdrawBlockChainId = withdrawBlockMeta._4
853896 let isMainChain = (withdrawBlockChainId == mainChainId)
854897 let relatesToMainChain = match getInteger(chainForkedHeightKey(withdrawBlockChainId)) {
855898 case forkedHeight: Int =>
856899 (forkedHeight > withdrawBlockHeight)
857900 case _ =>
858901 throw((((blockHashHex + " is on an alternative chain #") + toString(withdrawBlockChainId)) + " that was not approved by majority. Wait for some blocks"))
859902 }
860903 if (if (isMainChain)
861904 then true
862905 else relatesToMainChain)
863906 then {
864907 let recipient = i.originCaller
865908 let recipientPkHash = take(drop(recipient.bytes, 2), PUBLIC_KEY_HASH_SIZE)
866909 let zeroAmountBytes = base58'11111111111111111111111111111111111111111111'
867910 let amountBytes = toBytes(amount)
868911 let elEventData = ((recipientPkHash + take(zeroAmountBytes, (size(zeroAmountBytes) - size(amountBytes)))) + amountBytes)
869912 let elEventDataDigest = blake2b256_16Kb(elEventData)
870913 let calculatedRootHash = createMerkleRoot(merkleProof, elEventDataDigest, transferIndexInBlock)
871914 let expectedRootHash = withdrawBlockMeta._5
872915 if ((calculatedRootHash == expectedRootHash))
873916 then {
874917 let tokenId = fromBase58String(getStringValue(tokenIdKey))
875918 let transfersKey = blockE2CTransfersKey(blockHashHex)
876919 [Reissue(tokenId, amount, true), ScriptTransfer(recipient, amount, tokenId), StringEntry(transfersKey, setOrFail(valueOrElse(getString(transfersKey), ""), transferIndexInBlock))]
877920 }
878921 else throw((((((("Expected root hash: " + toBase16String(expectedRootHash)) + ", got: ") + toBase16String(calculatedRootHash)) + ". Event data digest: ") + toBase64String(elEventDataDigest)) + ". Check your withdraw arguments"))
879922 }
880923 else throw((("Expected " + blockHashHex) + " to be either on the main chain or relate to it"))
881924 }
882925 }
883926
884927
885928
886929 @Callable(i)
887-func setup (genesisBlockHashHex,minerRewardInGwei) = if (isContractSetup())
930+func setup (genesisBlockHashHex,minerRewardInGwei,daoAddress,daoReward) = if (isContractSetup())
888931 then throw("The contract has been already set up")
889932 else if ((0 > minerRewardInGwei))
890933 then throw("The miner reward must be nonnegative")
891934 else {
892935 let genesisBlockHash = fromBase16String(genesisBlockHashHex)
893936 let checkGenesisBlockHashSize = if ((size(genesisBlockHash) == BLOCK_HASH_SIZE))
894937 then true
895938 else throw("Wrong genesis block hash")
896939 if ((checkGenesisBlockHashSize == checkGenesisBlockHashSize))
897940 then {
898941 let emptyPk = base58'11111111111111111111111111111111'
899942 let genesisMinerAddress = addressFromPublicKey(emptyPk)
900943 let genesisEthRewardAddress = base58'11111111111111111111'
901944 let genesisBlockReferenceHash = "0000000000000000000000000000000000000000000000000000000000000000"
902945 let issue = Issue("UNIT0", "Native token", 0, 8, true)
903946 let tokenId = calculateAssetId(issue)
904947 let genesisBlockMeta = mkBlockMetaEntry(genesisBlockHashHex, 0, genesisBlockReferenceHash, 0, toBase16String(base58''), -1)
905-[genesisBlockMeta, StringEntry(chainFirstBlockIdKey(0), genesisBlockHashHex), mkChainMetaEntry(0, 0, genesisBlockHashHex), IntegerEntry(minerRewardKey, minerRewardInGwei), StringEntry(epochMetaKey(height), ((toString(genesisMinerAddress) + ",0,") + genesisBlockHashHex)), StringEntry(finalizedBlockKey, genesisBlockHashHex), issue, StringEntry(tokenIdKey, toBase58String(tokenId)), StringEntry(elBridgeAddressKey, "0x0000000000000000000000000000000000006a7e")]
948+ let daoEntries = if ((daoAddress == ""))
949+ then nil
950+ else [StringEntry(daoAddressKey, toString(Address(fromBase58String(daoAddress)))), IntegerEntry(daoRewardKey, if ((daoReward > 0))
951+ then daoReward
952+ else throw("invalid DAO reward amount"))]
953+ ([genesisBlockMeta, StringEntry(chainFirstBlockIdKey(0), genesisBlockHashHex), mkChainMetaEntry(0, 0, genesisBlockHashHex), IntegerEntry(minerRewardKey, minerRewardInGwei), StringEntry(epochMetaKey(height), ((toString(genesisMinerAddress) + ",0,") + genesisBlockHashHex)), StringEntry(finalizedBlockKey, genesisBlockHashHex), issue, StringEntry(tokenIdKey, toBase58String(tokenId)), StringEntry(elBridgeAddressKey, "0x0000000000000000000000000000000000006a7e")] ++ daoEntries)
906954 }
907955 else throw("Strict value is not equal to itself.")
908956 }
909957
910958

github/deemru/w8io/169f3d6 
137.86 ms