tx · AFjVDxvJoiBdik8pa3osy9RKLfkpxoQcGqCsrACEssNh

3N1H9u5NsaU81rjvRAu949SMRGyFz6vqaZC:  -0.04300000 Waves

2024.10.28 14:59 [3346696] smart account 3N1H9u5NsaU81rjvRAu949SMRGyFz6vqaZC > SELF 0.00000000 Waves

{ "type": 13, "id": "AFjVDxvJoiBdik8pa3osy9RKLfkpxoQcGqCsrACEssNh", "fee": 4300000, "feeAssetId": null, "timestamp": 1730116759774, "version": 2, "chainId": 84, "sender": "3N1H9u5NsaU81rjvRAu949SMRGyFz6vqaZC", "senderPublicKey": "9aTD84jf1ceby2KXs5yiVosaXECPUxd4Gs3roy4Yncos", "proofs": [ "2i2K4dv3XKMNWjyMLLuHzEEfHADPfSXXHLpBBN9zw1BRw5R2UX7YY6WP127TBXCYiHHU7pkdqYaKu8XPfUmuT9DV" ], "script": "base64:CAJCCAISBwoFCAgCCAESBwoFCAgCCAESCAoGCAgCAQgBEgYKBAgICAESAwoBCBIAEgMKAQgSBgoECBIBARIGCgQIAQgBTQAHSU5UX01BWAD//////////38ABVdBVkVTAIDC1y8AC01JTl9CQUxBTkNFCQBoAgCgnAEFBVdBVkVTAANTRVACASwAD0JMT0NLX0hBU0hfU0laRQAgABRQVUJMSUNfS0VZX0hBU0hfU0laRQAUAA5ST09UX0hBU0hfU0laRQAgABRXSVRIRFJBV19QUk9PRlNfU0laRQAKABRFVEhfQUREUkVTU19TVFJfU0laRQAoABZNQVhfQ0xfVE9fRUxfVFJBTlNGRVJTABAACXplcm9lc1N0cgKACDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAC29mZnNldHNfMTAwCQC8CQICZDo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OjoCAAAMYWxsTWluZXJzS2V5AglhbGxNaW5lcnMADm1haW5DaGFpbklkS2V5AgttYWluQ2hhaW5JZAAObGFzdENoYWluSWRLZXkCC2xhc3RDaGFpbklkABdmaXJzdFZhbGlkQWx0Q2hhaW5JZEtleQIUZmlyc3RWYWxpZEFsdENoYWluSWQADm1pbmVyUmV3YXJkS2V5AgttaW5lclJld2FyZAAKYmxvY2tNZXRhSwIIYmxvY2tfMHgAEWZpbmFsaXplZEJsb2NrS2V5Ag5maW5hbGl6ZWRCbG9jawAKdG9rZW5JZEtleQIHdG9rZW5JZAASZWxCcmlkZ2VBZGRyZXNzS2V5Ag9lbEJyaWRnZUFkZHJlc3MAF25hdGl2ZVRyYW5zZmVyc0NvdW50S2V5AhRuYXRpdmVUcmFuc2ZlcnNDb3VudAANZGFvQWRkcmVzc0tleQIKZGFvQWRkcmVzcwAMZGFvUmV3YXJkS2V5AglkYW9SZXdhcmQBA3BhZAEBaQQBcwkApAMBBQFpBAckbWF0Y2gwCQCxAgEFAXMDCQAAAgABBQckbWF0Y2gwCQCsAgICBzAwMDAwMDAFAXMDCQAAAgACBQckbWF0Y2gwCQCsAgICBjAwMDAwMAUBcwMJAAACAAMFByRtYXRjaDAJAKwCAgIFMDAwMDAFAXMDCQAAAgAEBQckbWF0Y2gwCQCsAgICBDAwMDAFAXMDCQAAAgAFBQckbWF0Y2gwCQCsAgICAzAwMAUBcwMJAAACAAYFByRtYXRjaDAJAKwCAgICMDAFAXMDCQAAAgAHBQckbWF0Y2gwCQCsAgICATAFAXMFAXMBFGJsb2NrRTJDVHJhbnNmZXJzS2V5AQxibG9ja0hhc2hIZXgJAKwCAgISZWxUb0NsVHJhbnNmZXJzXzB4BQxibG9ja0hhc2hIZXgBDGVwb2NoTWV0YUtleQEFZXBvY2gJAKwCAgIGZXBvY2hfCQEDcGFkAQUFZXBvY2gBFGNoYWluRmlyc3RCbG9ja0lkS2V5AQdjaGFpbklkCQCsAgIJAKwCAgIFY2hhaW4JAKQDAQUHY2hhaW5JZAIKRmlyc3RCbG9jawEMY2hhaW5NZXRhS2V5AQdjaGFpbklkCQCsAgICBmNoYWluXwkBA3BhZAEFB2NoYWluSWQBEmNoYWluTGFzdEhlaWdodEtleQIHY2hhaW5JZAVtaW5lcgkArAICCQCsAgIJAKwCAgIGY2hhaW5fCQEDcGFkAQUHY2hhaW5JZAIBXwkApQgBBQVtaW5lcgEUY2hhaW5Gb3JrZWRIZWlnaHRLZXkBB2NoYWluSWQJAKwCAgkArAICAgZjaGFpbl8JAQNwYWQBBQdjaGFpbklkAgxGb3JrZWRIZWlnaHQBDXN1cHBvcnRlcnNLZXkBB2NoYWluSWQJAKwCAgkArAICAgVjaGFpbgkApAMBBQdjaGFpbklkAgpTdXBwb3J0ZXJzARVtaW5lclJld2FyZEFkZHJlc3NLZXkBCW1pbmVyQWRkcgkArAICCQCsAgICBm1pbmVyXwUJbWluZXJBZGRyAg5fUmV3YXJkQWRkcmVzcwEKbWluZXJQa0tleQENcmV3YXJkQWRkcmVzcwkArAICCQCsAgICCG1pbmVyXzB4BQ1yZXdhcmRBZGRyZXNzAgNfUEsBD21pbmVyQ2hhaW5JZEtleQEFbWluZXIJAKwCAgkArAICAgZtaW5lcl8JAKUIAQUFbWluZXICCF9DaGFpbklkABRuYXRpdmVUcmFuc2ZlcnNDb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRduYXRpdmVUcmFuc2ZlcnNDb3VudEtleQAAARFuYXRpdmVUcmFuc2ZlcktleQEFaW5kZXgJAKwCAgIPbmF0aXZlVHJhbnNmZXJfCQCkAwEFBWluZGV4ARVta05hdGl2ZVRyYW5zZmVyRW50cnkDBWluZGV4EGRlc3RFbEFkZHJlc3NIZXgGYW1vdW50CQELU3RyaW5nRW50cnkCCQERbmF0aXZlVHJhbnNmZXJLZXkBBQVpbmRleAkArAICCQCsAgIJAKwCAgICMHgFEGRlc3RFbEFkZHJlc3NIZXgFA1NFUAkApAMBBQZhbW91bnQBFmVuc3VyZUNvcnJlY3RUcmFuc2ZlcnMDEHJlZlRyYW5zZmVySW5kZXgNdHJhbnNmZXJJbmRleAxleHBlY3RSZXdhcmQEDG1heFRyYW5zZmVycwMFDGV4cGVjdFJld2FyZAkAZQIFFk1BWF9DTF9UT19FTF9UUkFOU0ZFUlMAAQUWTUFYX0NMX1RPX0VMX1RSQU5TRkVSUwQPYWN0dWFsVHJhbnNmZXJzCQBlAgUNdHJhbnNmZXJJbmRleAUQcmVmVHJhbnNmZXJJbmRleAQLY2hlY2tOdW1iZXIDCQBmAgUPYWN0dWFsVHJhbnNmZXJzBQxtYXhUcmFuc2ZlcnMJAAIBCQCsAgIJAKwCAgkArAICAg1BbGxvd2VkIG9ubHkgCQCkAwEFDG1heFRyYW5zZmVycwIQIHRyYW5zZmVycywgZ290IAkApAMBBQ9hY3R1YWxUcmFuc2ZlcnMGAwkAAAIFC2NoZWNrTnVtYmVyBQtjaGVja051bWJlcgMJAGcCBQ10cmFuc2ZlckluZGV4BRRuYXRpdmVUcmFuc2ZlcnNDb3VudAkAAgEJAKwCAgkArAICCQCsAgICFUF0dGVtcHQgdG8gdHJhbnNmZXIgIwkApAMBBQ10cmFuc2ZlckluZGV4AhcuIEF2YWlsYWJsZSB0cmFuc2ZlcnM6IAkApAMBBRRuYXRpdmVUcmFuc2ZlcnNDb3VudAYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BCmFtb3VudEd0RXEDAXQEZ3RFcQlxdWV1ZVNpemUDCQBnAggFAXQGYW1vdW50BQRndEVxBgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICFFRyYW5zZmVycmluZyBhbW91bnQgCQCkAwEIBQF0BmFtb3VudAIOIHNob3VsZCBiZSA+PSAJAKQDAQUEZ3RFcQITIGZvciBxdWV1ZSBzaXplIG9mIAkApAMBBQlxdWV1ZVNpemUCFy4gVHJhbnNmZXIgbW9yZSBvciB3YWl0ARFnZW5lcmF0aW5nQmFsYW5jZQEHYWRkcmVzcwgJAO8HAQUHYWRkcmVzcwpnZW5lcmF0aW5nAQljaGFpbk1ldGEBB2NoYWluSWQEAXMJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAQxjaGFpbk1ldGFLZXkBBQdjaGFpbklkBAVpdGVtcwkAtQkCBQFzBQNTRVAJAJQKAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBWl0ZW1zAAAJAJEDAgUFaXRlbXMAAQEQbWtDaGFpbk1ldGFFbnRyeQMHY2hhaW5JZA5uZXdDaGFpbkhlaWdodAxibG9ja0hhc2hIZXgJAQtTdHJpbmdFbnRyeQIJAQxjaGFpbk1ldGFLZXkBBQdjaGFpbklkCQCsAgIJAKwCAgkApAMBBQ5uZXdDaGFpbkhlaWdodAUDU0VQBQxibG9ja0hhc2hIZXgAC21haW5DaGFpbklkCQELdmFsdWVPckVsc2UCCQCfCAEFDm1haW5DaGFpbklkS2V5AAAACyR0MDUyNDk1MzE1CQEJY2hhaW5NZXRhAQULbWFpbkNoYWluSWQAD21haW5DaGFpbkhlaWdodAgFCyR0MDUyNDk1MzE1Al8xABJtYWluQ2hhaW5MYXN0QmxvY2sIBQskdDA1MjQ5NTMxNQJfMgEJZXBvY2hNZXRhAQVlcG9jaAQHJG1hdGNoMAkAoggBCQEMZXBvY2hNZXRhS2V5AQUFZXBvY2gDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwBAlmcmFnbWVudHMJALUJAgUBcwUDU0VQCQCVCgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUJZnJhZ21lbnRzAAAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQlmcmFnbWVudHMAAQkAkQMCBQlmcmFnbWVudHMAAgUEdW5pdAALJHQwNTU0NjU2NzAEByRtYXRjaDAJAQllcG9jaE1ldGEBBQZoZWlnaHQDCQABAgUHJG1hdGNoMAIWKEFkZHJlc3MsIEludCwgU3RyaW5nKQQBbQUHJG1hdGNoMAUBbQkAlAoCBQR1bml0AAAADnRoaXNFcG9jaE1pbmVyCAULJHQwNTU0NjU2NzACXzEADHRoaXNFcG9jaFJlZggFCyR0MDU1NDY1NjcwAl8yAAxhbGxNaW5lcnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUMYWxsTWluZXJzS2V5AgAACWFsbE1pbmVycwQHJG1hdGNoMAUMYWxsTWluZXJzU3RyAwkAAAICAAUHJG1hdGNoMAUDbmlsAwkAAQIFByRtYXRjaDACBlN0cmluZwQDcmF3BQckbWF0Y2gwCQC8CQIFA3JhdwUDU0VQCQACAQILTWF0Y2ggZXJyb3IBCWJsb2NrTWV0YQEHYmxvY2tJZAQEbWV0YQkBEUBleHRyTmF0aXZlKDEwNTcpAQkArAICBQpibG9ja01ldGFLBQdibG9ja0lkBAhtZXRhU2l6ZQkAyAEBBQRtZXRhBAtibG9ja0hlaWdodAkAsQkBBQRtZXRhBApibG9ja0Vwb2NoCQCyCQIFBG1ldGEACAQLYmxvY2tQYXJlbnQJAMkBAgkAygECBQRtZXRhABAFD0JMT0NLX0hBU0hfU0laRQQHY2hhaW5JZAkAsgkCBQRtZXRhCQBkAgAQBQ9CTE9DS19IQVNIX1NJWkUECmJhc2VPZmZzZXQJAGQCABgFD0JMT0NLX0hBU0hfU0laRQQOcmVtYWluaW5nQnl0ZXMJAGUCBQhtZXRhU2l6ZQUKYmFzZU9mZnNldAQUZTJjVHJhbnNmZXJzUm9vdEhhc2gDCQBnAgUOcmVtYWluaW5nQnl0ZXMFDlJPT1RfSEFTSF9TSVpFCQDJAQIJAMoBAgUEbWV0YQUKYmFzZU9mZnNldAUOUk9PVF9IQVNIX1NJWkUBAAQUbGFzdEMyRVRyYW5zZmVySW5kZXgDAwkAAAIFDnJlbWFpbmluZ0J5dGVzAAgGCQBmAgUOcmVtYWluaW5nQnl0ZXMFDlJPT1RfSEFTSF9TSVpFCQCyCQIFBG1ldGEJAGQCBQpiYXNlT2Zmc2V0CQDIAQEFFGUyY1RyYW5zZmVyc1Jvb3RIYXNoAP///////////wEJAJgKBgULYmxvY2tIZWlnaHQFCmJsb2NrRXBvY2gFC2Jsb2NrUGFyZW50BQdjaGFpbklkBRRlMmNUcmFuc2ZlcnNSb290SGFzaAUUbGFzdEMyRVRyYW5zZmVySW5kZXgBEG1rQmxvY2tNZXRhRW50cnkGDGJsb2NrSGFzaEhleAtibG9ja0hlaWdodA5ibG9ja1BhcmVudEhleAdjaGFpbklkF2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4FGxhc3RDMkVUcmFuc2ZlckluZGV4BBllMmNUcmFuc2ZlcnNSb290SGFzaEJ5dGVzCQDdBAEFF2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4BBFyb290SGFzaEJ5dGVzU2l6ZQkAyAEBBRllMmNUcmFuc2ZlcnNSb290SGFzaEJ5dGVzBA1jaGVja1Jvb3RIYXNoAwMJAAACBRFyb290SGFzaEJ5dGVzU2l6ZQAABgkAAAIFEXJvb3RIYXNoQnl0ZXNTaXplBQ5ST09UX0hBU0hfU0laRQYJAAIBCQCsAgIJAKwCAgkArAICAiVUcmFuc2ZlcnMgcm9vdCBoYXNoIHNob3VsZCBoYXZlIDAgb3IgCQCkAwEFDlJPT1RfSEFTSF9TSVpFAgwgYnl0ZXMsIGdvdCAJAKQDAQURcm9vdEhhc2hCeXRlc1NpemUDCQAAAgUNY2hlY2tSb290SGFzaAUNY2hlY2tSb290SGFzaAQOYmxvY2tNZXRhQnl0ZXMJAMsBAgkAywECCQDLAQIJAMsBAgkAywECCQCaAwEFC2Jsb2NrSGVpZ2h0CQCaAwEFBmhlaWdodAkA3QQBBQ5ibG9ja1BhcmVudEhleAkAmgMBBQdjaGFpbklkBRllMmNUcmFuc2ZlcnNSb290SGFzaEJ5dGVzCQCaAwEFFGxhc3RDMkVUcmFuc2ZlckluZGV4CQELQmluYXJ5RW50cnkCCQCsAgIFCmJsb2NrTWV0YUsFDGJsb2NrSGFzaEhleAUOYmxvY2tNZXRhQnl0ZXMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BDGxhc3RIZWlnaHRCeQIFbWluZXIHY2hhaW5JZAQHJG1hdGNoMAkAnwgBCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgUHY2hhaW5JZAUFbWluZXIDCQABAgUHJG1hdGNoMAIDSW50BAFoBQckbWF0Y2gwBQFoBAlibG9ja0hhc2gJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAKwCAgkArAICCQCsAgICBWNoYWluCQCkAwEFB2NoYWluSWQCC0xhc3RNaW5lZEJ5CQClCAEFBW1pbmVyCAkBCWJsb2NrTWV0YQEFCWJsb2NrSGFzaAJfMQALJHQwNzcxMDg2NDUECWhpdFNvdXJjZQQHJG1hdGNoMAgFCWxhc3RCbG9jawN2cmYDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQDdnJmBQckbWF0Y2gwBQN2cmYIBQlsYXN0QmxvY2sTZ2VuZXJhdGlvblNpZ25hdHVyZQoBDHByb2Nlc3NNaW5lcgIEcHJldgVtaW5lcgQLJHQwNzk3NzgwNDAFBHByZXYECXByZXZNaW5lcggFCyR0MDc5Nzc4MDQwAl8xBBBwcmV2VG90YWxCYWxhbmNlCAULJHQwNzk3NzgwNDACXzIECXByZXZEZWxheQgFCyR0MDc5Nzc4MDQwAl8zBApwcmV2TWluZXJzCAULJHQwNzk3NzgwNDACXzQEDG1pbmVyQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUFbWluZXIED3dhdmVzR2VuQmFsYW5jZQgJAO8HAQUMbWluZXJBZGRyZXNzCmdlbmVyYXRpbmcEDG1pbmVyQmFsYW5jZQkBEWdlbmVyYXRpbmdCYWxhbmNlAQUMbWluZXJBZGRyZXNzAwMJAGYCBQtNSU5fQkFMQU5DRQUPd2F2ZXNHZW5CYWxhbmNlBgkAZwIAAAUMbWluZXJCYWxhbmNlBQRwcmV2BAluZXh0RGVsYXkJAIUHAgUMbWluZXJBZGRyZXNzBQxtaW5lckJhbGFuY2UDCQBmAgUJcHJldkRlbGF5BQluZXh0RGVsYXkJAJYKBAUFbWluZXIJAGQCBRBwcmV2VG90YWxCYWxhbmNlBQxtaW5lckJhbGFuY2UFCW5leHREZWxheQkAzQgCBQpwcmV2TWluZXJzBQVtaW5lcgkAlgoEBQlwcmV2TWluZXIJAGQCBRBwcmV2VG90YWxCYWxhbmNlBQxtaW5lckJhbGFuY2UFCXByZXZEZWxheQkAzQgCBQpwcmV2TWluZXJzBQVtaW5lcgoAAiRsBQlhbGxNaW5lcnMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCWCgQCAAAABQdJTlRfTUFYBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBDHByb2Nlc3NNaW5lcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyABFjb21wdXRlZEdlbmVyYXRvcggFCyR0MDc3MTA4NjQ1Al8xABRjb21wdXRlZFRvdGFsQmFsYW5jZQgFCyR0MDc3MTA4NjQ1Al8yAAskdDA4NjQ3ODcxMwkBCWJsb2NrTWV0YQEFEm1haW5DaGFpbkxhc3RCbG9jawAMbWNsYklnbm9yZWQxCAULJHQwODY0Nzg3MTMCXzEADm1haW5DaGFpbkVwb2NoCAULJHQwODY0Nzg3MTMCXzIBI2NhbGN1bGF0ZUZpbmFsaXplZEJsb2NrSGFzaEFuZEVwb2NoAwhjdXJNaW5lcgxjdXJQcmV2RXBvY2gQY3VyTGFzdEJsb2NrSGFzaAQLaGFsZkJhbGFuY2UJAGkCBRRjb21wdXRlZFRvdGFsQmFsYW5jZQACCgEEc3RlcAIEcHJldgRuZXh0BAskdDA4OTUxOTAyNAUEcHJldgQJdGhpc0Vwb2NoCAULJHQwODk1MTkwMjQCXzEEF21heWJlRmluYWxpemVkQmxvY2tIYXNoCAULJHQwODk1MTkwMjQCXzIEDHRvdGFsQmFsYW5jZQgFCyR0MDg5NTE5MDI0Al8zBApwcmV2TWluZXJzCAULJHQwODk1MTkwMjQCXzQEByRtYXRjaDAFF21heWJlRmluYWxpemVkQmxvY2tIYXNoAwkAAQIFByRtYXRjaDACBFVuaXQECyR0MDkwOTE5MjU3AwkAAAIFCXRoaXNFcG9jaAUGaGVpZ2h0CQCVCgMFCGN1ck1pbmVyBQxjdXJQcmV2RXBvY2gFEGN1ckxhc3RCbG9ja0hhc2gJAQV2YWx1ZQEJAQllcG9jaE1ldGEBBQl0aGlzRXBvY2gEBW1pbmVyCAULJHQwOTA5MTkyNTcCXzEECXByZXZFcG9jaAgFCyR0MDkwOTE5MjU3Al8yBA1sYXN0QmxvY2tIYXNoCAULJHQwOTA5MTkyNTcCXzMDAwkAAAIFCXByZXZFcG9jaAAABgkAZwIJAGUCBQZoZWlnaHQFCXRoaXNFcG9jaABkCQCWCgQFCXRoaXNFcG9jaAUNbGFzdEJsb2NrSGFzaAUMdG90YWxCYWxhbmNlBQlhbGxNaW5lcnMECyR0MDk0MTE5NjEzAwkBD2NvbnRhaW5zRWxlbWVudAIFCnByZXZNaW5lcnMFBW1pbmVyCQCUCgIFDHRvdGFsQmFsYW5jZQUKcHJldk1pbmVycwkAlAoCCQBkAgUMdG90YWxCYWxhbmNlCQERZ2VuZXJhdGluZ0JhbGFuY2UBBQVtaW5lcgkAzAgCBQVtaW5lcgUKcHJldk1pbmVycwQPbmV3VG90YWxCYWxhbmNlCAUL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CQCsAgIJAKwCAgkA2AQBCAUJZ2VuZXJhdG9yBWJ5dGVzAhsgaXMgbm90IGFsbG93ZWQgdG8gbWluZSBpbiAJAKQDAQUGaGVpZ2h0AhEgZXBvY2guIEV4cGVjdGVkIAURY29tcHV0ZWRHZW5lcmF0b3IFBHVuaXQBEmlzUmVmZXJlbmNlQ29ycmVjdAIJcmVmZXJlbmNlCWxhc3RCbG9jawMJAAACBQlyZWZlcmVuY2UFCWxhc3RCbG9jawUEdW5pdAkAAgEJAKwCAgkArAICCQCsAgICMEV4cGVjdGVkIGEgcmVmZXJlbmNlIHRvIHRoZSBjaGFpbiBsYXN0IGJsb2NrOiAweAUJbGFzdEJsb2NrAgkuIEdvdDogMHgFCXJlZmVyZW5jZQEPY2hhaW5Jc0luYWN0aXZlAQdjaGFpbklkBAxmaXJzdEJsb2NrSWQJARFAZXh0ck5hdGl2ZSgxMDU4KQEJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEFB2NoYWluSWQEFGZpcnN0VmFsaWRBbHRDaGFpbklkCQELdmFsdWVPckVsc2UCCQCfCAEFF2ZpcnN0VmFsaWRBbHRDaGFpbklkS2V5AAADCQBmAgUUZmlyc3RWYWxpZEFsdENoYWluSWQFB2NoYWluSWQGCQBmAggJAQlibG9ja01ldGEBCQERQGV4dHJOYXRpdmUoMTA1OCkBBRFmaW5hbGl6ZWRCbG9ja0tleQJfMQgJAQlibG9ja01ldGEBBQxmaXJzdEJsb2NrSWQCXzEBDG1pbmVyQ2hhaW5JZAEFbWluZXIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBD21pbmVyQ2hhaW5JZEtleQEFBW1pbmVyCQCfCAEJAKwCAgIJY2hhaW5JZE9mCQClCAEFBW1pbmVyAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMJZ2VuZXJhdG9yD2V4cGVjdGVkQ2hhaW5JZBBjaGVja0hlaWdodEJsb2NrBA9oZWlnaHRJc0NvcnJlY3QEByRtYXRjaDAFEGNoZWNrSGVpZ2h0QmxvY2sDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAlibG9ja0hhc2gFByRtYXRjaDAEFGxhc3RNaW5lZEJsb2NrSGVpZ2h0CQEMbGFzdEhlaWdodEJ5AgUJZ2VuZXJhdG9yBQttYWluQ2hhaW5JZAkAZgIJAGQCCAkBCWJsb2NrTWV0YQEFCWJsb2NrSGFzaAJfMQABBRRsYXN0TWluZWRCbG9ja0hlaWdodAYEByRtYXRjaDAJAQxtaW5lckNoYWluSWQBBQlnZW5lcmF0b3IDCQABAgUHJG1hdGNoMAIDSW50BAljdXJyZW50SWQFByRtYXRjaDADAwkAAAIFCWN1cnJlbnRJZAUPZXhwZWN0ZWRDaGFpbklkBgMJAQ9jaGFpbklzSW5hY3RpdmUBBQljdXJyZW50SWQFD2hlaWdodElzQ29ycmVjdAcFBHVuaXQJAAIBCQCsAgICHG1pbmVyIGlzIG1pbmluZyBvdGhlciBjaGFpbiAJAKQDAQUJY3VycmVudElkBQR1bml0AAxoZWlnaHRTdHJpbmcJAKwCAgILIGF0IGhlaWdodCAJAKQDAQUGaGVpZ2h0AQV2cmZBdAEGaGVpZ2h0CQETdmFsdWVPckVycm9yTWVzc2FnZQIICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAO0HAQUGaGVpZ2h0CQCsAgICG2xhc3QgYmxvY2sgaXMgbm90IGF2YWlsYWJsZQUMaGVpZ2h0U3RyaW5nA3ZyZgkArAICAhRWUkYgaXMgbm90IGF2YWlsYWJsZQUMaGVpZ2h0U3RyaW5nARJlbnN1cmVDb3JyZWN0RXBvY2gBC2V4cGVjdGVkVlJGBAlhY3R1YWxWUkYJAQV2cmZBdAEFBmhlaWdodAMJAAACBQtleHBlY3RlZFZSRgUJYWN0dWFsVlJGBQR1bml0CQACAQkArAICCQCsAgIJAKwCAgkArAICAg1FeHBlY3RlZCBWUkYgCQDYBAEFC2V4cGVjdGVkVlJGAhcgZG9lcyBub3QgbWF0Y2ggYWN0dWFsIAkA2AQBBQlhY3R1YWxWUkYFDGhlaWdodFN0cmluZwEMYWRkU3VwcG9ydGVyAgdjaGFpbklkCWdlbmVyYXRvcgQNc3VwcG9ydGVyc1N0cgkBEUBleHRyTmF0aXZlKDEwNTgpAQkBDXN1cHBvcnRlcnNLZXkBBQdjaGFpbklkBApzdXBwb3J0ZXJzCQC8CQIFDXN1cHBvcnRlcnNTdHIFA1NFUAMJAQ9jb250YWluc0VsZW1lbnQCBQpzdXBwb3J0ZXJzCQClCAEFCWdlbmVyYXRvcgUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ1zdXBwb3J0ZXJzS2V5AQUHY2hhaW5JZAkArAICCQCsAgIFDXN1cHBvcnRlcnNTdHIFA1NFUAkApQgBBQlnZW5lcmF0b3IFA25pbAEJc2V0T3JGYWlsAgVmbGFncwVpbmRleAMJAGYCAAAFBWluZGV4CQACAQkArAICAiJDYW4ndCB3aXRoZHJhdyBhdCBuZWdhdGl2ZSBpbmRleDogCQCkAwEFBWluZGV4BAlmbGFnc1NpemUJALECAQUFZmxhZ3MDCQBnAgUFaW5kZXgFCWZsYWdzU2l6ZQQJYWRkWmVyb2VzCQBlAgUFaW5kZXgFCWZsYWdzU2l6ZQMJAGYCBQlhZGRaZXJvZXMJALECAQUJemVyb2VzU3RyCQACAQkArAICCQCsAgICCkNhbid0IGFkZCAJAKQDAQUJYWRkWmVyb2VzAiUgZW1wdHkgZmxhZ3MuIENvbnRhY3Qgd2l0aCBkZXZlbG9wZXJzCQCsAgIJAKwCAgUFZmxhZ3MJAK8CAgUJemVyb2VzU3RyBQlhZGRaZXJvZXMCATEEBHRhaWwJALACAgUFZmxhZ3MFBWluZGV4BAdhdEluZGV4CQCvAgIFBHRhaWwAAQMJAAACBQdhdEluZGV4AgEwCQCsAgIJAKwCAgkArwICBQVmbGFncwUFaW5kZXgCATEJALACAgUEdGFpbAABCQACAQkArAICCQCsAgICClRyYW5zZmVyICMJAKQDAQUFaW5kZXgCFyBoYXMgYmVlbiBhbHJlYWR5IHRha2VuARF2YWxpZGF0ZUJsb2NrSGFzaAEGaGV4U3RyBAxkZWNvZGVkQnl0ZXMJAN0EAQUGaGV4U3RyAwkBAiE9AgkAyAEBBQxkZWNvZGVkQnl0ZXMFD0JMT0NLX0hBU0hfU0laRQkAAgECF2ludmFsaWQgYmxvY2sgaWQgbGVuZ3RoBQZoZXhTdHIBHWdldFVwZGF0ZUZpbmFsaXplZEJsb2NrQWN0aW9uAwZjYWxsZXIPbmV3QmxvY2tIYXNoSGV4CXByZXZFcG9jaAQVY3VyRmluYWxpemVkQmxvY2tNZXRhCQEJYmxvY2tNZXRhAQkBEUBleHRyTmF0aXZlKDEwNTgpAQURZmluYWxpemVkQmxvY2tLZXkEDSR0MDE0MjczMTQzOTMJASNjYWxjdWxhdGVGaW5hbGl6ZWRCbG9ja0hhc2hBbmRFcG9jaAMFBmNhbGxlcgUJcHJldkVwb2NoBQ9uZXdCbG9ja0hhc2hIZXgEFW5ld0ZpbmFsaXplZEJsb2NrSGFzaAgFDSR0MDE0MjczMTQzOTMCXzEEEW5ld0ZpbmFsaXplZEVwb2NoCAUNJHQwMTQyNzMxNDM5MwJfMgQNcmV3YXJkQWN0aW9ucwQHJG1hdGNoMAkAoggBBQ1kYW9BZGRyZXNzS2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQEYWRkcgUHJG1hdGNoMAMJAAACBRFuZXdGaW5hbGl6ZWRFcG9jaAgFFWN1ckZpbmFsaXplZEJsb2NrTWV0YQJfMgUDbmlsCgETY291bnROb25FbXB0eUVwb2NocwIDYWNjBG5leHQDCQAAAggFA2FjYwJfMQgFFWN1ckZpbmFsaXplZEJsb2NrTWV0YQJfMgUDYWNjBAckbWF0Y2gxCQEJZXBvY2hNZXRhAQgFA2FjYwJfMQMJAAECBQckbWF0Y2gxAhYoQWRkcmVzcywgSW50LCBTdHJpbmcpBAFtBQckbWF0Y2gxCQCUCgIIBQFtAl8yCQBkAggFA2FjYwJfMgABBQNhY2MEDnN0YXJ0RnJvbUVwb2NoAwkAAAIFEW5ld0ZpbmFsaXplZEVwb2NoBQZoZWlnaHQFCXByZXZFcG9jaAgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkBCWVwb2NoTWV0YQEFEW5ld0ZpbmFsaXplZEVwb2NoAhdubyBwcmV2IGVwb2NoIGZvciBzdGFydAJfMgQKZGFvUmV3YXJkcwoAAiRsBQtvZmZzZXRzXzEwMAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUOc3RhcnRGcm9tRXBvY2gAAQoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQETY291bnROb25FbXB0eUVwb2NocwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIVTGlzdCBzaXplIGV4Y2VlZHMgMTAwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgAzADQANQA2ADcAOAA5ADoAOwA8AD0APgA/AEAAQQBCAEMARABFAEYARwBIAEkASgBLAEwATQBOAE8AUABRAFIAUwBUAFUAVgBXAFgAWQBaAFsAXABdAF4AXwBgAGEAYgBjAGQEDXJlaXNzdWVBbW91bnQJAGgCCAUKZGFvUmV3YXJkcwJfMgkBEUBleHRyTmF0aXZlKDEwNTUpAQUMZGFvUmV3YXJkS2V5BAd0b2tlbklkCQDZBAEJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCnRva2VuSWRLZXkJAMwIAgkBB1JlaXNzdWUDBQd0b2tlbklkBQ1yZWlzc3VlQW1vdW50BgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQEHQWRkcmVzcwEJANkEAQUEYWRkcgUNcmVpc3N1ZUFtb3VudAUHdG9rZW5JZAUDbmlsBQNuaWwJAM4IAgUNcmV3YXJkQWN0aW9ucwMDCQAAAgUVbmV3RmluYWxpemVkQmxvY2tIYXNoBQ9uZXdCbG9ja0hhc2hIZXgGCQBmAggJAQlibG9ja01ldGEBBRVuZXdGaW5hbGl6ZWRCbG9ja0hhc2gCXzEIBRVjdXJGaW5hbGl6ZWRCbG9ja01ldGECXzEJAMwIAgkBC1N0cmluZ0VudHJ5AgURZmluYWxpemVkQmxvY2tLZXkFFW5ld0ZpbmFsaXplZEJsb2NrSGFzaAUDbmlsBQNuaWwJAWkBD2V4dGVuZE1haW5DaGFpbgUMYmxvY2tIYXNoSGV4DHJlZmVyZW5jZUhleAN2cmYXZTJjVHJhbnNmZXJzUm9vdEhhc2hIZXgUbGFzdEMyRVRyYW5zZmVySW5kZXgEDmNoZWNrQmxvY2tIYXNoCQERdmFsaWRhdGVCbG9ja0hhc2gBBQxibG9ja0hhc2hIZXgDCQAAAgUOY2hlY2tCbG9ja0hhc2gFDmNoZWNrQmxvY2tIYXNoBApjaGVja0Vwb2NoCQESZW5zdXJlQ29ycmVjdEVwb2NoAQUDdnJmAwkAAAIFCmNoZWNrRXBvY2gFCmNoZWNrRXBvY2gECmNoZWNrQ2hhaW4JAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQFBHVuaXQDCQAAAgUKY2hlY2tDaGFpbgUKY2hlY2tDaGFpbgQOY2hlY2tSZWZlcmVuY2UJARJpc1JlZmVyZW5jZUNvcnJlY3QCBQxyZWZlcmVuY2VIZXgFEm1haW5DaGFpbkxhc3RCbG9jawMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDmNoZWNrVHJhbnNmZXJzCQEWZW5zdXJlQ29ycmVjdFRyYW5zZmVycwMICQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4Al82BRRsYXN0QzJFVHJhbnNmZXJJbmRleAYDCQAAAgUOY2hlY2tUcmFuc2ZlcnMFDmNoZWNrVHJhbnNmZXJzBA10aGlzRXBvY2hNZXRhBAckbWF0Y2gwCQEJZXBvY2hNZXRhAQUGaGVpZ2h0AwkAAQIFByRtYXRjaDACBFVuaXQJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCAUBaQxvcmlnaW5DYWxsZXIFA1NFUAkApAMBBQ5tYWluQ2hhaW5FcG9jaAUDU0VQBQxibG9ja0hhc2hIZXgEBW90aGVyBQckbWF0Y2gwCQACAQIVRXBvY2ggYWxyZWFkeSBzdGFydGVkAwkAAAIFDXRoaXNFcG9jaE1ldGEFDXRoaXNFcG9jaE1ldGEEDmNoZWNrR2VuZXJhdG9yCQERZW5zdXJlTWluaW5nRXBvY2gBCAUBaQxvcmlnaW5DYWxsZXIDCQAAAgUOY2hlY2tHZW5lcmF0b3IFDmNoZWNrR2VuZXJhdG9yBBR1cGRhdGVGaW5hbGl6ZWRCbG9jawkBHWdldFVwZGF0ZUZpbmFsaXplZEJsb2NrQWN0aW9uAwgFAWkMb3JpZ2luQ2FsbGVyBQxibG9ja0hhc2hIZXgFDm1haW5DaGFpbkVwb2NoBA5uZXdDaGFpbkhlaWdodAkAZAIFD21haW5DaGFpbkhlaWdodAABCQDOCAIJAMwIAgkBEG1rQmxvY2tNZXRhRW50cnkGBQxibG9ja0hhc2hIZXgFDm5ld0NoYWluSGVpZ2h0BRJtYWluQ2hhaW5MYXN0QmxvY2sFC21haW5DaGFpbklkBRdlMmNUcmFuc2ZlcnNSb290SGFzaEhleAUUbGFzdEMyRVRyYW5zZmVySW5kZXgJAMwIAgkBEG1rQ2hhaW5NZXRhRW50cnkDBQttYWluQ2hhaW5JZAUObmV3Q2hhaW5IZWlnaHQFDGJsb2NrSGFzaEhleAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBD21pbmVyQ2hhaW5JZEtleQEIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQttYWluQ2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBQ5uZXdDaGFpbkhlaWdodAkAzAgCBQ10aGlzRXBvY2hNZXRhBQNuaWwFFHVwZGF0ZUZpbmFsaXplZEJsb2NrCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDXN0YXJ0QWx0Q2hhaW4FDGJsb2NrSGFzaEhleAxyZWZlcmVuY2VIZXgDdnJmF2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4FGxhc3RDMkVUcmFuc2ZlckluZGV4BA5jaGVja0Jsb2NrSGFzaAkBEXZhbGlkYXRlQmxvY2tIYXNoAQUMYmxvY2tIYXNoSGV4AwkAAAIFDmNoZWNrQmxvY2tIYXNoBQ5jaGVja0Jsb2NrSGFzaAQKY2hlY2tFcG9jaAkBEmVuc3VyZUNvcnJlY3RFcG9jaAEFA3ZyZgMJAAACBQpjaGVja0Vwb2NoBQpjaGVja0Vwb2NoBA0kdDAxNzI5MDE3NDAzCQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4BA5yZWZDaGFpbkhlaWdodAgFDSR0MDE3MjkwMTc0MDMCXzEECHJlZkVwb2NoCAUNJHQwMTcyOTAxNzQwMwJfMgQLcmVmSWdub3JlZDEIBQ0kdDAxNzI5MDE3NDAzAl8zBAtyZWZJZ25vcmVkMggFDSR0MDE3MjkwMTc0MDMCXzQEC3JlZklnbm9yZWQzCAUNJHQwMTcyOTAxNzQwMwJfNQQQcmVmVHJhbnNmZXJJbmRleAgFDSR0MDE3MjkwMTc0MDMCXzYEDmZpbmFsaXplZEVwb2NoCAkBCWJsb2NrTWV0YQEJARFAZXh0ck5hdGl2ZSgxMDU4KQEFEWZpbmFsaXplZEJsb2NrS2V5Al8yBAhlcG9jaFJlZgMJAGcCBQhyZWZFcG9jaAUOZmluYWxpemVkRXBvY2gFCHJlZkVwb2NoCQACAQkArAICCQCsAgIJAKwCAgkArAICAiNDYW4gbm90IHN0YXJ0IGFsdCBjaGFpbiBmcm9tIGVwb2NoIAkApAMBBQhyZWZFcG9jaAIILCBlcG9jaCAJAKQDAQUOZmluYWxpemVkRXBvY2gCDSBpcyBmaW5hbGl6ZWQECmNoZWNrQ2hhaW4JAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMIBQFpDG9yaWdpbkNhbGxlcgULbWFpbkNoYWluSWQFDHJlZmVyZW5jZUhleAMJAAACBQpjaGVja0NoYWluBQpjaGVja0NoYWluBA5jaGVja1RyYW5zZmVycwkBFmVuc3VyZUNvcnJlY3RUcmFuc2ZlcnMDBRByZWZUcmFuc2ZlckluZGV4BRRsYXN0QzJFVHJhbnNmZXJJbmRleAYDCQAAAgUOY2hlY2tUcmFuc2ZlcnMFDmNoZWNrVHJhbnNmZXJzBApuZXdDaGFpbklkCQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ5sYXN0Q2hhaW5JZEtleQAAAAEEDm5ld0NoYWluSGVpZ2h0CQBkAgUOcmVmQ2hhaW5IZWlnaHQAAQQNdGhpc0Vwb2NoTWV0YQQHJG1hdGNoMAkBCWVwb2NoTWV0YQEFBmhlaWdodAMJAAECBQckbWF0Y2gwAgRVbml0CQELU3RyaW5nRW50cnkCCQEMZXBvY2hNZXRhS2V5AQUGaGVpZ2h0CQCsAgIJAKwCAgkArAICCQCsAgIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBQNTRVAJAKQDAQUIZXBvY2hSZWYFA1NFUAUMYmxvY2tIYXNoSGV4BAVvdGhlcgUHJG1hdGNoMAkAAgECFUVwb2NoIGFscmVhZHkgc3RhcnRlZAQOY2hlY2tHZW5lcmF0b3IJARFlbnN1cmVNaW5pbmdFcG9jaAEIBQFpDG9yaWdpbkNhbGxlcgMJAAACBQ5jaGVja0dlbmVyYXRvcgUOY2hlY2tHZW5lcmF0b3IJAMwIAgUNdGhpc0Vwb2NoTWV0YQkAzAgCCQEQbWtCbG9ja01ldGFFbnRyeQYFDGJsb2NrSGFzaEhleAUObmV3Q2hhaW5IZWlnaHQFDHJlZmVyZW5jZUhleAUKbmV3Q2hhaW5JZAUXZTJjVHJhbnNmZXJzUm9vdEhhc2hIZXgFFGxhc3RDMkVUcmFuc2ZlckluZGV4CQDMCAIJAQtTdHJpbmdFbnRyeQIJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEFCm5ld0NoYWluSWQFDGJsb2NrSGFzaEhleAkAzAgCCQEQbWtDaGFpbk1ldGFFbnRyeQMFCm5ld0NoYWluSWQFDm5ld0NoYWluSGVpZ2h0BQxibG9ja0hhc2hIZXgJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9taW5lckNoYWluSWRLZXkBCAUBaQxvcmlnaW5DYWxsZXIFCm5ld0NoYWluSWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARJjaGFpbkxhc3RIZWlnaHRLZXkCBQpuZXdDaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIFDm5ld0NoYWluSGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgULbWFpbkNoYWluSWQIBQFpDG9yaWdpbkNhbGxlcgUObmV3Q2hhaW5IZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDXN1cHBvcnRlcnNLZXkBBQpuZXdDaGFpbklkCQClCAEIBQFpDG9yaWdpbkNhbGxlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgUObGFzdENoYWluSWRLZXkFCm5ld0NoYWluSWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ5leHRlbmRBbHRDaGFpbgYMYmxvY2tIYXNoSGV4DHJlZmVyZW5jZUhleAN2cmYHY2hhaW5JZBdlMmNUcmFuc2ZlcnNSb290SGFzaEhleBRsYXN0QzJFVHJhbnNmZXJJbmRleAQOY2hlY2tCbG9ja0hhc2gJARF2YWxpZGF0ZUJsb2NrSGFzaAEFDGJsb2NrSGFzaEhleAMJAAACBQ5jaGVja0Jsb2NrSGFzaAUOY2hlY2tCbG9ja0hhc2gECmNoZWNrRXBvY2gJARJlbnN1cmVDb3JyZWN0RXBvY2gBBQN2cmYDCQAAAgUKY2hlY2tFcG9jaAUKY2hlY2tFcG9jaAQTY2hhaW5GaXJzdEJsb2NrTWV0YQkBCWJsb2NrTWV0YQEJARFAZXh0ck5hdGl2ZSgxMDU4KQEJARRjaGFpbkZpcnN0QmxvY2tJZEtleQEFB2NoYWluSWQECmNoZWNrQ2hhaW4JAR1lbnN1cmVFeHBlY3RlZE9ySW5hY3RpdmVDaGFpbgMIBQFpDG9yaWdpbkNhbGxlcgUHY2hhaW5JZAkA3AQBCAUTY2hhaW5GaXJzdEJsb2NrTWV0YQJfMwMJAAACBQpjaGVja0NoYWluBQpjaGVja0NoYWluBA0kdDAxOTcxNjE5NzcwCQEJY2hhaW5NZXRhAQUHY2hhaW5JZAQLY2hhaW5IZWlnaHQIBQ0kdDAxOTcxNjE5NzcwAl8xBA5jaGFpbkxhc3RCbG9jawgFDSR0MDE5NzE2MTk3NzACXzIEDmNoZWNrUmVmZXJlbmNlCQESaXNSZWZlcmVuY2VDb3JyZWN0AgUMcmVmZXJlbmNlSGV4BQ5jaGFpbkxhc3RCbG9jawMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDmNoZWNrVHJhbnNmZXJzCQEWZW5zdXJlQ29ycmVjdFRyYW5zZmVycwMICQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4Al82BRRsYXN0QzJFVHJhbnNmZXJJbmRleAYDCQAAAgUOY2hlY2tUcmFuc2ZlcnMFDmNoZWNrVHJhbnNmZXJzBA5uZXdDaGFpbkhlaWdodAkAZAIFC2NoYWluSGVpZ2h0AAEECXByZXZFcG9jaAgJAQlibG9ja01ldGEBBQxyZWZlcmVuY2VIZXgCXzIEE3VwZGF0ZU1haW5DaGFpbkRhdGEDCQBmAgkBEXN1cHBvcnRpbmdCYWxhbmNlAQUHY2hhaW5JZAkAaQIFFGNvbXB1dGVkVG90YWxCYWxhbmNlAAIEC2xhc3RDaGFpbklkCQELdmFsdWVPckVsc2UCCQCfCAEFDmxhc3RDaGFpbklkS2V5AAAEFHVwZGF0ZUZpbmFsaXplZEJsb2NrCQEdZ2V0VXBkYXRlRmluYWxpemVkQmxvY2tBY3Rpb24DCAUBaQxvcmlnaW5DYWxsZXIFDGJsb2NrSGFzaEhleAUJcHJldkVwb2NoCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJARRjaGFpbkZvcmtlZEhlaWdodEtleQEFC21haW5DaGFpbklkCAUTY2hhaW5GaXJzdEJsb2NrTWV0YQJfMQkAzAgCCQEMSW50ZWdlckVudHJ5AgUObWFpbkNoYWluSWRLZXkFB2NoYWluSWQJAMwIAgkBDEludGVnZXJFbnRyeQIFF2ZpcnN0VmFsaWRBbHRDaGFpbklkS2V5CQBkAgULbGFzdENoYWluSWQAAQUDbmlsBRR1cGRhdGVGaW5hbGl6ZWRCbG9jawUDbmlsBA10aGlzRXBvY2hNZXRhBAckbWF0Y2gwCQEJZXBvY2hNZXRhAQUGaGVpZ2h0AwkAAQIFByRtYXRjaDACBFVuaXQJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCAUBaQxvcmlnaW5DYWxsZXIFA1NFUAkApAMBBQlwcmV2RXBvY2gFA1NFUAUMYmxvY2tIYXNoSGV4BAVvdGhlcgUHJG1hdGNoMAkAAgECFUVwb2NoIGFscmVhZHkgc3RhcnRlZAMJAAACBQ10aGlzRXBvY2hNZXRhBQ10aGlzRXBvY2hNZXRhBA5jaGVja0dlbmVyYXRvcgkBEWVuc3VyZU1pbmluZ0Vwb2NoAQgFAWkMb3JpZ2luQ2FsbGVyAwkAAAIFDmNoZWNrR2VuZXJhdG9yBQ5jaGVja0dlbmVyYXRvcgQddXBkYXRlTWFpbkNoYWluTGFzdE1pbmVkQmxvY2sDAwkAAAIFE3VwZGF0ZU1haW5DaGFpbkRhdGEFA25pbAkBAiE9AgkBC3ZhbHVlT3JFbHNlAgkBDG1pbmVyQ2hhaW5JZAEIBQFpDG9yaWdpbkNhbGxlcgAABQdjaGFpbklkBwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmNoYWluTGFzdEhlaWdodEtleQIFC21haW5DaGFpbklkCAUBaQxvcmlnaW5DYWxsZXIIBRNjaGFpbkZpcnN0QmxvY2tNZXRhAl8xBQNuaWwFA25pbAkAzggCCQDOCAIJAM4IAgkAzAgCCQEQbWtCbG9ja01ldGFFbnRyeQYFDGJsb2NrSGFzaEhleAUObmV3Q2hhaW5IZWlnaHQFDHJlZmVyZW5jZUhleAUHY2hhaW5JZAUXZTJjVHJhbnNmZXJzUm9vdEhhc2hIZXgFFGxhc3RDMkVUcmFuc2ZlckluZGV4CQDMCAIJARBta0NoYWluTWV0YUVudHJ5AwUHY2hhaW5JZAUObmV3Q2hhaW5IZWlnaHQFDGJsb2NrSGFzaEhleAkAzAgCBQ10aGlzRXBvY2hNZXRhCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEPbWluZXJDaGFpbklkS2V5AQgFAWkMb3JpZ2luQ2FsbGVyBQdjaGFpbklkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESY2hhaW5MYXN0SGVpZ2h0S2V5AgUHY2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBQ5uZXdDaGFpbkhlaWdodAUDbmlsBRN1cGRhdGVNYWluQ2hhaW5EYXRhCQEMYWRkU3VwcG9ydGVyAgUHY2hhaW5JZAgFAWkMb3JpZ2luQ2FsbGVyBR11cGRhdGVNYWluQ2hhaW5MYXN0TWluZWRCbG9jawkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQthcHBlbmRCbG9jawQMYmxvY2tIYXNoSGV4DHJlZmVyZW5jZUhleBdlMmNUcmFuc2ZlcnNSb290SGFzaEhleBRsYXN0QzJFVHJhbnNmZXJJbmRleAQLY2hlY2tDYWxsZXIDCQAAAgUOdGhpc0Vwb2NoTWluZXIIBQFpDG9yaWdpbkNhbGxlcgYEByRtYXRjaDAFDnRoaXNFcG9jaE1pbmVyAwkAAQIFByRtYXRjaDACB0FkZHJlc3MECmVwb2NoTWluZXIFByRtYXRjaDAJAAIBCQCsAgICOW5vdCBhbGxvd2VkIHRvIGZvcmdlIGJsb2NrcyBpbiB0aGlzIGVwb2NoLCBleHBlY3RlZCBmcm9tIAkApQgBBQplcG9jaE1pbmVyCQACAQJAbm90IGFsbG93ZWQgdG8gZm9yZ2UgYmxvY2tzIGluIHRoaXMgZXBvY2gsIGVwb2NoIG1pbmVyIGlzIGFic2VudAMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIEB2NoYWluSWQJAQt2YWx1ZU9yRWxzZQIJAQxtaW5lckNoYWluSWQBCAUBaQxvcmlnaW5DYWxsZXIFC21haW5DaGFpbklkBA0kdDAyMjExOTIyMTcwCQEJY2hhaW5NZXRhAQUHY2hhaW5JZAQLY2hhaW5IZWlnaHQIBQ0kdDAyMjExOTIyMTcwAl8xBAtsYXN0QmxvY2tJZAgFDSR0MDIyMTE5MjIxNzACXzIEDmNoZWNrUmVmZXJlbmNlCQESaXNSZWZlcmVuY2VDb3JyZWN0AgUMcmVmZXJlbmNlSGV4BQtsYXN0QmxvY2tJZAMJAAACBQ5jaGVja1JlZmVyZW5jZQUOY2hlY2tSZWZlcmVuY2UEDmNoZWNrVHJhbnNmZXJzCQEWZW5zdXJlQ29ycmVjdFRyYW5zZmVycwMICQEJYmxvY2tNZXRhAQUMcmVmZXJlbmNlSGV4Al82BRRsYXN0QzJFVHJhbnNmZXJJbmRleAcDCQAAAgUOY2hlY2tUcmFuc2ZlcnMFDmNoZWNrVHJhbnNmZXJzBA5uZXdDaGFpbkhlaWdodAkAZAIFC2NoYWluSGVpZ2h0AAEEDmNoZWNrQmxvY2tIYXNoCQERdmFsaWRhdGVCbG9ja0hhc2gBBQxibG9ja0hhc2hIZXgDCQAAAgUOY2hlY2tCbG9ja0hhc2gFDmNoZWNrQmxvY2tIYXNoCQDMCAIJARBta0Jsb2NrTWV0YUVudHJ5BgUMYmxvY2tIYXNoSGV4BQ5uZXdDaGFpbkhlaWdodAULbGFzdEJsb2NrSWQFB2NoYWluSWQFF2UyY1RyYW5zZmVyc1Jvb3RIYXNoSGV4BRRsYXN0QzJFVHJhbnNmZXJJbmRleAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEmNoYWluTGFzdEhlaWdodEtleQIFB2NoYWluSWQIBQFpDG9yaWdpbkNhbGxlcgUObmV3Q2hhaW5IZWlnaHQJAMwIAgkBEG1rQ2hhaW5NZXRhRW50cnkDBQdjaGFpbklkBQ5uZXdDaGFpbkhlaWdodAUMYmxvY2tIYXNoSGV4CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQCsAgIJAKwCAgkApQgBCQEFdmFsdWUBBQ50aGlzRXBvY2hNaW5lcgUDU0VQCQCkAwEFDHRoaXNFcG9jaFJlZgUDU0VQBQxibG9ja0hhc2hIZXgFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQRqb2luARByZXdhcmRBZGRyZXNzSGV4CgEdZW5zdXJlTm90T3ZlcnJpZGVPdGhlck1pbmVyUGsBDGVsQWRkcmVzc0hleAQHJG1hdGNoMAkAoQgBCQEKbWluZXJQa0tleQEFDGVsQWRkcmVzc0hleAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJwawUHJG1hdGNoMAMJAAACBQJwawgFAWkVb3JpZ2luQ2FsbGVyUHVibGljS2V5BQR1bml0CQACAQkArAICCQCsAgIJAKwCAgIRRUwgbWluZXIgYWRkcmVzcyAFDGVsQWRkcmVzc0hleAIYIGlzIGFscmVhZHkgbGlua2VkIHdpdGggCQDYBAEFAnBrBQR1bml0BAVwYXJ0cwkAtQkCBRByZXdhcmRBZGRyZXNzSGV4AgIweAQNcmV3YXJkQWRkcmVzcwkA3QQBCQCRAwIFBXBhcnRzCQBlAgkAkAMBBQVwYXJ0cwABBBFuZXR3b3JrSXNMYXVuY2hlZAQHJG1hdGNoMAkAnwgBAgxsYXVuY2hIZWlnaHQDCQABAgUHJG1hdGNoMAIDSW50BAxsYXVuY2hIZWlnaHQFByRtYXRjaDAJAGcCBQZoZWlnaHQFDGxhdW5jaEhlaWdodAkAAgECEG5vdCBsYXVuY2hlZCB5ZXQDAwkBASEBCQEPaXNDb250cmFjdFNldHVwAAYJAQEhAQURbmV0d29ya0lzTGF1bmNoZWQJAAIBAh9UaGUgY29udHJhY3QgaGFzIG5vdCB5ZXQgc2V0IHVwAwkAZgIFC01JTl9CQUxBTkNFCAkA7wcBCAUBaQxvcmlnaW5DYWxsZXIKZ2VuZXJhdGluZwkAAgEJAKwCAgkArAICCQCsAgICIUluc3VmZmljaWVudCBnZW5lcmF0aW5nIGJhbGFuY2U6IAkApAMBCAkA7wcBCAUBaQxvcmlnaW5DYWxsZXIKZ2VuZXJhdGluZwIMLiBSZXF1aXJlZDogCQCkAwEFC01JTl9CQUxBTkNFAwkBAiE9AgkAyAEBBQ1yZXdhcmRBZGRyZXNzABQJAAIBAiVyZXdhcmRBZGRyZXNzIHNob3VsZCBiZSBhbiBMMiBhZGRyZXNzAwkAZwIJAJADAQUJYWxsTWluZXJzADIJAAIBAg90b28gbWFueSBtaW5lcnMKAQ5jaGVja0V4aXN0ZW5jZQIGZXhpc3RzBW1pbmVyAwUGZXhpc3RzBgkAAAIFBW1pbmVyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgQNYWxyZWFkeUV4aXN0cwoAAiRsBQlhbGxNaW5lcnMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBwoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEOY2hlY2tFeGlzdGVuY2UCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDUwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgMFDWFscmVhZHlFeGlzdHMFA25pbAQIbmV3TWluZXIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBBZsb3dlcmNhc2VSZXdhcmRBZGRyZXNzCQDcBAEFDXJld2FyZEFkZHJlc3MEBWNoZWNrCQEdZW5zdXJlTm90T3ZlcnJpZGVPdGhlck1pbmVyUGsBBRZsb3dlcmNhc2VSZXdhcmRBZGRyZXNzAwkAAAIFBWNoZWNrBQVjaGVjawQJbmV3TWluZXJzAwkAAAIJAJADAQUJYWxsTWluZXJzAAAFCG5ld01pbmVyCQCsAgIJAKwCAgUMYWxsTWluZXJzU3RyBQNTRVAFCG5ld01pbmVyBBlkZWxldGVQcmV2UmV3YXJkQWRkcmVzc1BrBAckbWF0Y2gwCQCiCAEJARVtaW5lclJld2FyZEFkZHJlc3NLZXkBBQhuZXdNaW5lcgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEC3ByZXZBZGRyZXNzBQckbWF0Y2gwAwkAAAIFC3ByZXZBZGRyZXNzCQDcBAEFDXJld2FyZEFkZHJlc3MFA25pbAkAzAgCCQELRGVsZXRlRW50cnkBCQEKbWluZXJQa0tleQEFC3ByZXZBZGRyZXNzBQNuaWwFA25pbAkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFDGFsbE1pbmVyc0tleQUJbmV3TWluZXJzCQDMCAIJAQtTdHJpbmdFbnRyeQIJARVtaW5lclJld2FyZEFkZHJlc3NLZXkBBQhuZXdNaW5lcgkArAICAgIweAUWbG93ZXJjYXNlUmV3YXJkQWRkcmVzcwkAzAgCCQELQmluYXJ5RW50cnkCCQEKbWluZXJQa0tleQEFFmxvd2VyY2FzZVJld2FyZEFkZHJlc3MIBQFpFW9yaWdpbkNhbGxlclB1YmxpY0tleQUDbmlsBRlkZWxldGVQcmV2UmV3YXJkQWRkcmVzc1BrCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBWxlYXZlAAQMbGVhdmluZ01pbmVyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgoBEHNraXBMZWF2aW5nTWluZXICA2FjYwVtaW5lcgMJAAACBQVtaW5lcgUMbGVhdmluZ01pbmVyBQNhY2MJAM0IAgUDYWNjBQVtaW5lcgQPcmVtYWluaW5nTWluZXJzCgACJGwFCWFsbE1pbmVycwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEQc2tpcExlYXZpbmdNaW5lcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgNTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyBA1yZXdhcmRBZGRyS2V5CQEVbWluZXJSZXdhcmRBZGRyZXNzS2V5AQUMbGVhdmluZ01pbmVyBBFwcmV2UmV3YXJkQWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMFDXJld2FyZEFkZHJLZXkCFm1pbmVyIGhhcyBuZXZlciBqb2luZWQDCQAAAgURcHJldlJld2FyZEFkZHJlc3MFEXByZXZSZXdhcmRBZGRyZXNzAwkAAAIFDnRoaXNFcG9jaE1pbmVyCAUBaQxvcmlnaW5DYWxsZXIJAAIBAhxkZXNpZ25hdGVkIG1pbmVyIGNhbid0IGxlYXZlCQDMCAIJAQtTdHJpbmdFbnRyeQIFDGFsbE1pbmVyc0tleQkAugkCBQ9yZW1haW5pbmdNaW5lcnMFA1NFUAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCHRyYW5zZmVyARBkZXN0RWxBZGRyZXNzSGV4BAxjaGVja0FkZHJlc3MDCQAAAgkAsQIBBRBkZXN0RWxBZGRyZXNzSGV4BRRFVEhfQUREUkVTU19TVFJfU0laRQkA3QQBBRBkZXN0RWxBZGRyZXNzSGV4CQACAQkArAICCQCsAgIJAKwCAgIUQWRkcmVzcyBzaG91bGQgaGF2ZSAJAKQDAQUURVRIX0FERFJFU1NfU1RSX1NJWkUCESBjaGFyYWN0ZXJzLCBnb3QgCQCkAwEJALECAQUQZGVzdEVsQWRkcmVzc0hleAMJAAACBQxjaGVja0FkZHJlc3MFDGNoZWNrQWRkcmVzcwQMY2hlY2tQYXltZW50AwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQYJAAIBCQCsAgICL0V4cGVjdGVkIG9uZSBwYXltZW50IGFzIGEgdHJhbnNmZXIgYW1vdW50LCBnb3QgCQCkAwEJAJADAQgFAWkIcGF5bWVudHMDCQAAAgUMY2hlY2tQYXltZW50BQxjaGVja1BheW1lbnQECnRva2VuSWRTdHIJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCnRva2VuSWRLZXkEB3Rva2VuSWQJANkEAQUKdG9rZW5JZFN0cgQBdAkAkQMCCAUBaQhwYXltZW50cwAABAxjaGVja0Fzc2V0SWQEByRtYXRjaDAIBQF0B2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQHYXNzZXRJZAUHJG1hdGNoMAMJAAACBQdhc3NldElkBQd0b2tlbklkBgkAAgEJAKwCAgkArAICCQCsAgICCUV4cGVjdGVkIAUKdG9rZW5JZFN0cgIVIGluIHRoZSBwYXltZW50LCBnb3QgCQDYBAEFB2Fzc2V0SWQJAAIBCQCsAgIJAKwCAgIJRXhwZWN0ZWQgBQp0b2tlbklkU3RyAhogaW4gdGhlIHBheW1lbnQsIGdvdCBXYXZlcwMJAAACBQxjaGVja0Fzc2V0SWQFDGNoZWNrQXNzZXRJZAQJbGFzdEluZGV4CAkBCWJsb2NrTWV0YQEFEm1haW5DaGFpbkxhc3RCbG9jawJfNgQJcXVldWVTaXplCQBlAgUUbmF0aXZlVHJhbnNmZXJzQ291bnQFCWxhc3RJbmRleAQPY2hlY2tRdWV1ZUxpbWl0AwkAZgIAoAEFCXF1ZXVlU2l6ZQkBCmFtb3VudEd0RXEDBQF0AMCEPQUJcXVldWVTaXplAwkAZgIAwAwFCXF1ZXVlU2l6ZQkBCmFtb3VudEd0RXEDBQF0AICt4gQFCXF1ZXVlU2l6ZQMJAGYCAIAZBQlxdWV1ZVNpemUJAQphbW91bnRHdEVxAwUBdACAwtcvBQlxdWV1ZVNpemUDCQBmAgCAMgUJcXVldWVTaXplCQEKYW1vdW50R3RFcQMFAXQAgJTr3AMFCXF1ZXVlU2l6ZQkAAgEJAKwCAgkArAICAiNUcmFuc2ZlcnMgZGVuaWVkIGZvciBxdWV1ZSBzaXplIG9mIAkApAMBBQlxdWV1ZVNpemUCKC4gV2FpdCB1bnRpbCBjdXJyZW50IHRyYW5zZmVycyBwcm9jZXNzZWQDCQAAAgUPY2hlY2tRdWV1ZUxpbWl0BQ9jaGVja1F1ZXVlTGltaXQJAMwIAgkBDEludGVnZXJFbnRyeQIFF25hdGl2ZVRyYW5zZmVyc0NvdW50S2V5CQBkAgUUbmF0aXZlVHJhbnNmZXJzQ291bnQAAQkAzAgCCQEVbWtOYXRpdmVUcmFuc2ZlckVudHJ5AwUUbmF0aXZlVHJhbnNmZXJzQ291bnQFEGRlc3RFbEFkZHJlc3NIZXgIBQF0BmFtb3VudAkAzAgCCQEEQnVybgIFB3Rva2VuSWQIBQF0BmFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCHdpdGhkcmF3BAxibG9ja0hhc2hIZXgLbWVya2xlUHJvb2YUdHJhbnNmZXJJbmRleEluQmxvY2sGYW1vdW50BBF3aXRoZHJhd0Jsb2NrTWV0YQkBCWJsb2NrTWV0YQEFDGJsb2NrSGFzaEhleAQTd2l0aGRyYXdCbG9ja0hlaWdodAgFEXdpdGhkcmF3QmxvY2tNZXRhAl8xBBRmaW5hbGl6ZWRCbG9ja0hlaWdodAgJAQlibG9ja01ldGEBCQERQGV4dHJOYXRpdmUoMTA1OCkBBRFmaW5hbGl6ZWRCbG9ja0tleQJfMQQYbWFpbkNoYWluTGFzdEJsb2NrSGVpZ2h0CAkBCWJsb2NrTWV0YQEFEm1haW5DaGFpbkxhc3RCbG9jawJfMQMJAGYCBRN3aXRoZHJhd0Jsb2NrSGVpZ2h0BRRmaW5hbGl6ZWRCbG9ja0hlaWdodAkAAgEJAKwCAgkArAICCQCsAgICCkVMIGJsb2NrICMJAKQDAQUTd2l0aGRyYXdCbG9ja0hlaWdodAItIGlzIG5vdCBmaW5hbGl6ZWQuIFRoZSBjdXJyZW50IGZpbmFsaXplZCBpcyAjCQCkAwEFFGZpbmFsaXplZEJsb2NrSGVpZ2h0AwkBAiE9AgkAkAMBBQttZXJrbGVQcm9vZgUUV0lUSERSQVdfUFJPT0ZTX1NJWkUJAAIBCQCsAgIJAKwCAgkArAICAglFeHBlY3RlZCAJAKQDAQUUV0lUSERSQVdfUFJPT0ZTX1NJWkUCDSBwcm9vZnMsIGdvdCAJAKQDAQkAkAMBBQttZXJrbGVQcm9vZgMJAGYCAAAFFHRyYW5zZmVySW5kZXhJbkJsb2NrCQACAQkArAICAjNUcmFuc2ZlciBpbmRleCBpbiBibG9jayBzaG91bGQgYmUgbm9ubmVnYXRpdmUsIGdvdCAJAKQDAQUUdHJhbnNmZXJJbmRleEluQmxvY2sDCQBnAgAABQZhbW91bnQJAAIBCQCsAgICH0Ftb3VudCBzaG91bGQgYmUgcG9zaXRpdmUsIGdvdCAJAKQDAQUGYW1vdW50BBR3aXRoZHJhd0Jsb2NrQ2hhaW5JZAgFEXdpdGhkcmF3QmxvY2tNZXRhAl80BAtpc01haW5DaGFpbgkAAAIFFHdpdGhkcmF3QmxvY2tDaGFpbklkBQttYWluQ2hhaW5JZAQScmVsYXRlc1RvTWFpbkNoYWluBAckbWF0Y2gwCQCfCAEJARRjaGFpbkZvcmtlZEhlaWdodEtleQEFFHdpdGhkcmF3QmxvY2tDaGFpbklkAwkAAQIFByRtYXRjaDACA0ludAQMZm9ya2VkSGVpZ2h0BQckbWF0Y2gwCQBmAgUMZm9ya2VkSGVpZ2h0BRN3aXRoZHJhd0Jsb2NrSGVpZ2h0CQACAQkArAICCQCsAgIJAKwCAgUMYmxvY2tIYXNoSGV4Ah0gaXMgb24gYW4gYWx0ZXJuYXRpdmUgY2hhaW4gIwkApAMBBRR3aXRoZHJhd0Jsb2NrQ2hhaW5JZAI4IHRoYXQgd2FzIG5vdCBhcHByb3ZlZCBieSBtYWpvcml0eS4gV2FpdCBmb3Igc29tZSBibG9ja3MDAwULaXNNYWluQ2hhaW4GBRJyZWxhdGVzVG9NYWluQ2hhaW4ECXJlY2lwaWVudAgFAWkMb3JpZ2luQ2FsbGVyBA9yZWNpcGllbnRQa0hhc2gJAMkBAgkAygECCAUJcmVjaXBpZW50BWJ5dGVzAAIFFFBVQkxJQ19LRVlfSEFTSF9TSVpFBA96ZXJvQW1vdW50Qnl0ZXMBLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAthbW91bnRCeXRlcwkAmgMBBQZhbW91bnQEC2VsRXZlbnREYXRhCQDLAQIJAMsBAgUPcmVjaXBpZW50UGtIYXNoCQDJAQIFD3plcm9BbW91bnRCeXRlcwkAZQIJAMgBAQUPemVyb0Ftb3VudEJ5dGVzCQDIAQEFC2Ftb3VudEJ5dGVzBQthbW91bnRCeXRlcwQRZWxFdmVudERhdGFEaWdlc3QJAPAVAQULZWxFdmVudERhdGEEEmNhbGN1bGF0ZWRSb290SGFzaAkAvQUDBQttZXJrbGVQcm9vZgURZWxFdmVudERhdGFEaWdlc3QFFHRyYW5zZmVySW5kZXhJbkJsb2NrBBBleHBlY3RlZFJvb3RIYXNoCAURd2l0aGRyYXdCbG9ja01ldGECXzUDCQAAAgUSY2FsY3VsYXRlZFJvb3RIYXNoBRBleHBlY3RlZFJvb3RIYXNoBAd0b2tlbklkCQDZBAEJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCnRva2VuSWRLZXkEDHRyYW5zZmVyc0tleQkBFGJsb2NrRTJDVHJhbnNmZXJzS2V5AQUMYmxvY2tIYXNoSGV4CQDMCAIJAQdSZWlzc3VlAwUHdG9rZW5JZAUGYW1vdW50BgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQlyZWNpcGllbnQFBmFtb3VudAUHdG9rZW5JZAkAzAgCCQELU3RyaW5nRW50cnkCBQx0cmFuc2ZlcnNLZXkJAQlzZXRPckZhaWwCCQELdmFsdWVPckVsc2UCCQCiCAEFDHRyYW5zZmVyc0tleQIABRR0cmFuc2ZlckluZGV4SW5CbG9jawUDbmlsCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIURXhwZWN0ZWQgcm9vdCBoYXNoOiAJANwEAQUQZXhwZWN0ZWRSb290SGFzaAIHLCBnb3Q6IAkA3AQBBRJjYWxjdWxhdGVkUm9vdEhhc2gCFS4gRXZlbnQgZGF0YSBkaWdlc3Q6IAkA2gQBBRFlbEV2ZW50RGF0YURpZ2VzdAIfLiBDaGVjayB5b3VyIHdpdGhkcmF3IGFyZ3VtZW50cwkAAgEJAKwCAgkArAICAglFeHBlY3RlZCAFDGJsb2NrSGFzaEhleAIvIHRvIGJlIGVpdGhlciBvbiB0aGUgbWFpbiBjaGFpbiBvciByZWxhdGUgdG8gaXQBaQEFc2V0dXAEE2dlbmVzaXNCbG9ja0hhc2hIZXgRbWluZXJSZXdhcmRJbkd3ZWkKZGFvQWRkcmVzcwlkYW9SZXdhcmQDCQEPaXNDb250cmFjdFNldHVwAAkAAgECJFRoZSBjb250cmFjdCBoYXMgYmVlbiBhbHJlYWR5IHNldCB1cAMJAGYCAAAFEW1pbmVyUmV3YXJkSW5Hd2VpCQACAQIkVGhlIG1pbmVyIHJld2FyZCBtdXN0IGJlIG5vbm5lZ2F0aXZlBBBnZW5lc2lzQmxvY2tIYXNoCQDdBAEFE2dlbmVzaXNCbG9ja0hhc2hIZXgEGWNoZWNrR2VuZXNpc0Jsb2NrSGFzaFNpemUDCQAAAgkAyAEBBRBnZW5lc2lzQmxvY2tIYXNoBQ9CTE9DS19IQVNIX1NJWkUGCQACAQIYV3JvbmcgZ2VuZXNpcyBibG9jayBoYXNoAwkAAAIFGWNoZWNrR2VuZXNpc0Jsb2NrSGFzaFNpemUFGWNoZWNrR2VuZXNpc0Jsb2NrSGFzaFNpemUEB2VtcHR5UGsBIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBNnZW5lc2lzTWluZXJBZGRyZXNzCQCnCAEFB2VtcHR5UGsEF2dlbmVzaXNFdGhSZXdhcmRBZGRyZXNzARQAAAAAAAAAAAAAAAAAAAAAAAAAAAQZZ2VuZXNpc0Jsb2NrUmVmZXJlbmNlSGFzaAJAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQFaXNzdWUJAMIIBQIFVU5JVDACDE5hdGl2ZSB0b2tlbgAAAAgGBAd0b2tlbklkCQC4CAEFBWlzc3VlBBBnZW5lc2lzQmxvY2tNZXRhCQEQbWtCbG9ja01ldGFFbnRyeQYFE2dlbmVzaXNCbG9ja0hhc2hIZXgAAAUZZ2VuZXNpc0Jsb2NrUmVmZXJlbmNlSGFzaAAACQDcBAEBAAD///////////8BBApkYW9FbnRyaWVzAwkAAAIFCmRhb0FkZHJlc3MCAAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIFDWRhb0FkZHJlc3NLZXkJAKUIAQkBB0FkZHJlc3MBCQDZBAEFCmRhb0FkZHJlc3MJAMwIAgkBDEludGVnZXJFbnRyeQIFDGRhb1Jld2FyZEtleQMJAGYCBQlkYW9SZXdhcmQAAAUJZGFvUmV3YXJkCQACAQIZaW52YWxpZCBEQU8gcmV3YXJkIGFtb3VudAUDbmlsCQDOCAIJAMwIAgUQZ2VuZXNpc0Jsb2NrTWV0YQkAzAgCCQELU3RyaW5nRW50cnkCCQEUY2hhaW5GaXJzdEJsb2NrSWRLZXkBAAAFE2dlbmVzaXNCbG9ja0hhc2hIZXgJAMwIAgkBEG1rQ2hhaW5NZXRhRW50cnkDAAAAAAUTZ2VuZXNpc0Jsb2NrSGFzaEhleAkAzAgCCQEMSW50ZWdlckVudHJ5AgUObWluZXJSZXdhcmRLZXkFEW1pbmVyUmV3YXJkSW5Hd2VpCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQxlcG9jaE1ldGFLZXkBBQZoZWlnaHQJAKwCAgkArAICCQClCAEFE2dlbmVzaXNNaW5lckFkZHJlc3MCAywwLAUTZ2VuZXNpc0Jsb2NrSGFzaEhleAkAzAgCCQELU3RyaW5nRW50cnkCBRFmaW5hbGl6ZWRCbG9ja0tleQUTZ2VuZXNpc0Jsb2NrSGFzaEhleAkAzAgCBQVpc3N1ZQkAzAgCCQELU3RyaW5nRW50cnkCBQp0b2tlbklkS2V5CQDYBAEFB3Rva2VuSWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUSZWxCcmlkZ2VBZGRyZXNzS2V5AioweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDZhN2UFA25pbAUKZGFvRW50cmllcwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECdHgBBnZlcmlmeQAEAnUwCQDGEwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAAASBLotVc9bgkmbEIYZ1IWa7O516VpzgDwHAQnhN4YjSKIQQCdTEJAMYTAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAEBINEXSiZaAhDIHLdD3FrmNz+Jw6flsxF6YbUoEYS6i8YvBAJ1MgkAxhMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAgEgPA+xIPa5y2eYDRZkHtToAfEwx+9Smn8cRUfuiEo1fFIDBQJ1MAMFAnUxBgUCdTIDBQJ1MQUCdTIHfLPzcw==", "height": 3346696, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 8 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let INT_MAX = 9223372036854775807
5+
6+let WAVES = 100000000
7+
8+let MIN_BALANCE = (20000 * WAVES)
9+
10+let SEP = ","
11+
12+let BLOCK_HASH_SIZE = 32
13+
14+let PUBLIC_KEY_HASH_SIZE = 20
15+
16+let ROOT_HASH_SIZE = 32
17+
18+let WITHDRAW_PROOFS_SIZE = 10
19+
20+let ETH_ADDRESS_STR_SIZE = 40
21+
22+let MAX_CL_TO_EL_TRANSFERS = 16
23+
24+let zeroesStr = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
25+
26+let offsets_100 = split_4C("::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::", "")
27+
28+let allMinersKey = "allMiners"
29+
30+let mainChainIdKey = "mainChainId"
31+
32+let lastChainIdKey = "lastChainId"
33+
34+let firstValidAltChainIdKey = "firstValidAltChainId"
35+
36+let minerRewardKey = "minerReward"
37+
38+let blockMetaK = "block_0x"
39+
40+let finalizedBlockKey = "finalizedBlock"
41+
42+let tokenIdKey = "tokenId"
43+
44+let elBridgeAddressKey = "elBridgeAddress"
45+
46+let nativeTransfersCountKey = "nativeTransfersCount"
47+
48+let daoAddressKey = "daoAddress"
49+
50+let daoRewardKey = "daoReward"
51+
52+func pad (i) = {
53+ let s = toString(i)
54+ match size(s) {
55+ case _ =>
56+ if ((1 == $match0))
57+ then ("0000000" + s)
58+ else if ((2 == $match0))
59+ then ("000000" + s)
60+ else if ((3 == $match0))
61+ then ("00000" + s)
62+ else if ((4 == $match0))
63+ then ("0000" + s)
64+ else if ((5 == $match0))
65+ then ("000" + s)
66+ else if ((6 == $match0))
67+ then ("00" + s)
68+ else if ((7 == $match0))
69+ then ("0" + s)
70+ else s
71+ }
72+ }
73+
74+
75+func blockE2CTransfersKey (blockHashHex) = ("elToClTransfers_0x" + blockHashHex)
76+
77+
78+func epochMetaKey (epoch) = ("epoch_" + pad(epoch))
79+
80+
81+func chainFirstBlockIdKey (chainId) = (("chain" + toString(chainId)) + "FirstBlock")
82+
83+
84+func chainMetaKey (chainId) = ("chain_" + pad(chainId))
85+
86+
87+func chainLastHeightKey (chainId,miner) = ((("chain_" + pad(chainId)) + "_") + toString(miner))
88+
89+
90+func chainForkedHeightKey (chainId) = (("chain_" + pad(chainId)) + "ForkedHeight")
91+
92+
93+func supportersKey (chainId) = (("chain" + toString(chainId)) + "Supporters")
94+
95+
96+func minerRewardAddressKey (minerAddr) = (("miner_" + minerAddr) + "_RewardAddress")
97+
98+
99+func minerPkKey (rewardAddress) = (("miner_0x" + rewardAddress) + "_PK")
100+
101+
102+func minerChainIdKey (miner) = (("miner_" + toString(miner)) + "_ChainId")
103+
104+
105+let nativeTransfersCount = valueOrElse(getInteger(this, nativeTransfersCountKey), 0)
106+
107+func nativeTransferKey (index) = ("nativeTransfer_" + toString(index))
108+
109+
110+func mkNativeTransferEntry (index,destElAddressHex,amount) = StringEntry(nativeTransferKey(index), ((("0x" + destElAddressHex) + SEP) + toString(amount)))
111+
112+
113+func ensureCorrectTransfers (refTransferIndex,transferIndex,expectReward) = {
114+ let maxTransfers = if (expectReward)
115+ then (MAX_CL_TO_EL_TRANSFERS - 1)
116+ else MAX_CL_TO_EL_TRANSFERS
117+ let actualTransfers = (transferIndex - refTransferIndex)
118+ let checkNumber = if ((actualTransfers > maxTransfers))
119+ then throw(((("Allowed only " + toString(maxTransfers)) + " transfers, got ") + toString(actualTransfers)))
120+ else true
121+ if ((checkNumber == checkNumber))
122+ then if ((transferIndex >= nativeTransfersCount))
123+ then throw(((("Attempt to transfer #" + toString(transferIndex)) + ". Available transfers: ") + toString(nativeTransfersCount)))
124+ else true
125+ else throw("Strict value is not equal to itself.")
126+ }
127+
128+
129+func amountGtEq (t,gtEq,queueSize) = if ((t.amount >= gtEq))
130+ then true
131+ else throw((((((("Transferring amount " + toString(t.amount)) + " should be >= ") + toString(gtEq)) + " for queue size of ") + toString(queueSize)) + ". Transfer more or wait"))
132+
133+
134+func generatingBalance (address) = wavesBalance(address).generating
135+
136+
137+func chainMeta (chainId) = {
138+ let s = getStringValue(chainMetaKey(chainId))
139+ let items = split(s, SEP)
140+ $Tuple2(parseIntValue(items[0]), items[1])
141+ }
142+
143+
144+func mkChainMetaEntry (chainId,newChainHeight,blockHashHex) = StringEntry(chainMetaKey(chainId), ((toString(newChainHeight) + SEP) + blockHashHex))
145+
146+
147+let mainChainId = valueOrElse(getInteger(mainChainIdKey), 0)
148+
149+let $t052495315 = chainMeta(mainChainId)
150+
151+let mainChainHeight = $t052495315._1
152+
153+let mainChainLastBlock = $t052495315._2
154+
155+func epochMeta (epoch) = match getString(epochMetaKey(epoch)) {
156+ case s: String =>
157+ let fragments = split(s, SEP)
158+ $Tuple3(addressFromStringValue(fragments[0]), parseIntValue(fragments[1]), fragments[2])
159+ case _ =>
160+ unit
161+}
162+
163+
164+let $t055465670 = match epochMeta(height) {
165+ case m: (Address, Int, String) =>
166+ m
167+ case _ =>
168+ $Tuple2(unit, 0)
169+}
170+
171+let thisEpochMiner = $t055465670._1
172+
173+let thisEpochRef = $t055465670._2
174+
175+let allMinersStr = valueOrElse(getString(allMinersKey), "")
176+
177+let allMiners = match allMinersStr {
178+ case _ =>
179+ if (("" == $match0))
180+ then nil
181+ else if ($isInstanceOf($match0, "String"))
182+ then {
183+ let raw = $match0
184+ split_4C(raw, SEP)
185+ }
186+ else throw("Match error")
187+}
188+
189+func blockMeta (blockId) = {
190+ let meta = getBinaryValue((blockMetaK + blockId))
191+ let metaSize = size(meta)
192+ let blockHeight = toInt(meta)
193+ let blockEpoch = toInt(meta, 8)
194+ let blockParent = take(drop(meta, 16), BLOCK_HASH_SIZE)
195+ let chainId = toInt(meta, (16 + BLOCK_HASH_SIZE))
196+ let baseOffset = (24 + BLOCK_HASH_SIZE)
197+ let remainingBytes = (metaSize - baseOffset)
198+ let e2cTransfersRootHash = if ((remainingBytes >= ROOT_HASH_SIZE))
199+ then take(drop(meta, baseOffset), ROOT_HASH_SIZE)
200+ else base58''
201+ let lastC2ETransferIndex = if (if ((remainingBytes == 8))
202+ then true
203+ else (remainingBytes > ROOT_HASH_SIZE))
204+ then toInt(meta, (baseOffset + size(e2cTransfersRootHash)))
205+ else -1
206+ $Tuple6(blockHeight, blockEpoch, blockParent, chainId, e2cTransfersRootHash, lastC2ETransferIndex)
207+ }
208+
209+
210+func mkBlockMetaEntry (blockHashHex,blockHeight,blockParentHex,chainId,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
211+ let e2cTransfersRootHashBytes = fromBase16String(e2cTransfersRootHashHex)
212+ let rootHashBytesSize = size(e2cTransfersRootHashBytes)
213+ let checkRootHash = if (if ((rootHashBytesSize == 0))
214+ then true
215+ else (rootHashBytesSize == ROOT_HASH_SIZE))
216+ then true
217+ else throw(((("Transfers root hash should have 0 or " + toString(ROOT_HASH_SIZE)) + " bytes, got ") + toString(rootHashBytesSize)))
218+ if ((checkRootHash == checkRootHash))
219+ then {
220+ let blockMetaBytes = (((((toBytes(blockHeight) + toBytes(height)) + fromBase16String(blockParentHex)) + toBytes(chainId)) + e2cTransfersRootHashBytes) + toBytes(lastC2ETransferIndex))
221+ BinaryEntry((blockMetaK + blockHashHex), blockMetaBytes)
222+ }
223+ else throw("Strict value is not equal to itself.")
224+ }
225+
226+
227+func lastHeightBy (miner,chainId) = match getInteger(chainLastHeightKey(chainId, miner)) {
228+ case h: Int =>
229+ h
230+ case _ =>
231+ let blockHash = getStringValue(((("chain" + toString(chainId)) + "LastMinedBy") + toString(miner)))
232+ blockMeta(blockHash)._1
233+}
234+
235+
236+let $t077108645 = {
237+ let hitSource = match lastBlock.vrf {
238+ case vrf: ByteVector =>
239+ vrf
240+ case _ =>
241+ lastBlock.generationSignature
242+ }
243+ func processMiner (prev,miner) = {
244+ let $t079778040 = prev
245+ let prevMiner = $t079778040._1
246+ let prevTotalBalance = $t079778040._2
247+ let prevDelay = $t079778040._3
248+ let prevMiners = $t079778040._4
249+ let minerAddress = addressFromStringValue(miner)
250+ let wavesGenBalance = wavesBalance(minerAddress).generating
251+ let minerBalance = generatingBalance(minerAddress)
252+ if (if ((MIN_BALANCE > wavesGenBalance))
253+ then true
254+ else (0 >= minerBalance))
255+ then prev
256+ else {
257+ let nextDelay = calculateDelay(minerAddress, minerBalance)
258+ if ((prevDelay > nextDelay))
259+ then $Tuple4(miner, (prevTotalBalance + minerBalance), nextDelay, (prevMiners :+ miner))
260+ else $Tuple4(prevMiner, (prevTotalBalance + minerBalance), prevDelay, (prevMiners :+ miner))
261+ }
262+ }
263+
264+ let $l = allMiners
265+ let $s = size($l)
266+ let $acc0 = $Tuple4("", 0, INT_MAX, nil)
267+ func $f0_1 ($a,$i) = if (($i >= $s))
268+ then $a
269+ else processMiner($a, $l[$i])
270+
271+ func $f0_2 ($a,$i) = if (($i >= $s))
272+ then $a
273+ else throw("List size exceeds 50")
274+
275+ $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)
276+ }
277+
278+let computedGenerator = $t077108645._1
279+
280+let computedTotalBalance = $t077108645._2
281+
282+let $t086478713 = blockMeta(mainChainLastBlock)
283+
284+let mclbIgnored1 = $t086478713._1
285+
286+let mainChainEpoch = $t086478713._2
287+
288+func calculateFinalizedBlockHashAndEpoch (curMiner,curPrevEpoch,curLastBlockHash) = {
289+ let halfBalance = (computedTotalBalance / 2)
290+ func step (prev,next) = {
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 {
297+ case _: Unit =>
298+ let $t090919257 = if ((thisEpoch == height))
299+ then $Tuple3(curMiner, curPrevEpoch, curLastBlockHash)
300+ else value(epochMeta(thisEpoch))
301+ let miner = $t090919257._1
302+ let prevEpoch = $t090919257._2
303+ let lastBlockHash = $t090919257._3
304+ if (if ((prevEpoch == 0))
305+ then true
306+ else ((height - thisEpoch) >= 100))
307+ then $Tuple4(thisEpoch, lastBlockHash, totalBalance, allMiners)
308+ else {
309+ let $t094119613 = if (containsElement(prevMiners, miner))
310+ then $Tuple2(totalBalance, prevMiners)
311+ else $Tuple2((totalBalance + generatingBalance(miner)), miner :: prevMiners)
312+ let newTotalBalance = $t094119613._1
313+ let newMiners = $t094119613._2
314+ if ((newTotalBalance > halfBalance))
315+ then $Tuple4(thisEpoch, lastBlockHash, newTotalBalance, allMiners)
316+ else $Tuple4(prevEpoch, unit, newTotalBalance, newMiners)
317+ }
318+ case _ =>
319+ prev
320+ }
321+ }
322+
323+ let $t098469943 = {
324+ let $l = offsets_100
325+ let $s = size($l)
326+ let $acc0 = $Tuple4(height, unit, 0, nil)
327+ func $f0_1 ($a,$i) = if (($i >= $s))
328+ then $a
329+ else step($a, $l[$i])
330+
331+ func $f0_2 ($a,$i) = if (($i >= $s))
332+ then $a
333+ else throw("List size exceeds 100")
334+
335+ $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)
336+ }
337+ let finalizedEpoch = $t098469943._1
338+ let finalizedBlockHashOpt = $t098469943._2
339+ $Tuple2( match finalizedBlockHashOpt {
340+ case finalizedBlockHash: String =>
341+ finalizedBlockHash
342+ case _ =>
343+ value(epochMeta(finalizedEpoch))._3
344+ }, finalizedEpoch)
345+ }
346+
347+
348+func supportingBalance (chainId) = {
349+ func addBalance (acc,generatorStr) = {
350+ let $t01022610262 = acc
351+ let totalBalance = $t01022610262._1
352+ let generators = $t01022610262._2
353+ let generator = addressFromStringValue(generatorStr)
354+ if (containsElement(generators, generator))
355+ then acc
356+ else {
357+ let balance = generatingBalance(generator)
358+ $Tuple2((totalBalance + balance), (generators :+ generator))
359+ }
360+ }
361+
362+ let allGenerators = split_4C(getStringValue(supportersKey(chainId)), SEP)
363+ let res = {
364+ let $l = allGenerators
365+ let $s = size($l)
366+ let $acc0 = $Tuple2(0, nil)
367+ func $f0_1 ($a,$i) = if (($i >= $s))
368+ then $a
369+ else addBalance($a, $l[$i])
370+
371+ func $f0_2 ($a,$i) = if (($i >= $s))
372+ then $a
373+ else throw("List size exceeds 100")
374+
375+ $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)
376+ }
377+ res._1
378+ }
379+
380+
381+func isContractSetup () = isDefined(getInteger(minerRewardKey))
382+
383+
384+func ensureMiningEpoch (generator) = if ((toString(generator) != computedGenerator))
385+ then throw(((((toBase58String(generator.bytes) + " is not allowed to mine in ") + toString(height)) + " epoch. Expected ") + computedGenerator))
386+ else unit
387+
388+
389+func isReferenceCorrect (reference,lastBlock) = if ((reference == lastBlock))
390+ then unit
391+ else throw(((("Expected a reference to the chain last block: 0x" + lastBlock) + ". Got: 0x") + reference))
392+
393+
394+func chainIsInactive (chainId) = {
395+ let firstBlockId = getStringValue(chainFirstBlockIdKey(chainId))
396+ let firstValidAltChainId = valueOrElse(getInteger(firstValidAltChainIdKey), 0)
397+ if ((firstValidAltChainId > chainId))
398+ then true
399+ else (blockMeta(getStringValue(finalizedBlockKey))._1 > blockMeta(firstBlockId)._1)
400+ }
401+
402+
403+func minerChainId (miner) = valueOrElse(getInteger(minerChainIdKey(miner)), getInteger(("chainIdOf" + toString(miner))))
404+
405+
406+func ensureExpectedOrInactiveChain (generator,expectedChainId,checkHeightBlock) = {
407+ let heightIsCorrect = match checkHeightBlock {
408+ case blockHash: String =>
409+ let lastMinedBlockHeight = lastHeightBy(generator, mainChainId)
410+ ((blockMeta(blockHash)._1 + 1) > lastMinedBlockHeight)
411+ case _ =>
412+ true
413+ }
414+ match minerChainId(generator) {
415+ case currentId: Int =>
416+ if (if ((currentId == expectedChainId))
417+ then true
418+ else if (chainIsInactive(currentId))
419+ then heightIsCorrect
420+ else false)
421+ then unit
422+ else throw(("miner is mining other chain " + toString(currentId)))
423+ case _ =>
424+ unit
425+ }
426+ }
427+
428+
429+let heightString = (" at height " + toString(height))
430+
431+func vrfAt (height) = valueOrErrorMessage(valueOrErrorMessage(blockInfoByHeight(height), ("last block is not available" + heightString)).vrf, ("VRF is not available" + heightString))
432+
433+
434+func ensureCorrectEpoch (expectedVRF) = {
435+ let actualVRF = vrfAt(height)
436+ if ((expectedVRF == actualVRF))
437+ then unit
438+ else throw((((("Expected VRF " + toBase58String(expectedVRF)) + " does not match actual ") + toBase58String(actualVRF)) + heightString))
439+ }
440+
441+
442+func addSupporter (chainId,generator) = {
443+ let supportersStr = getStringValue(supportersKey(chainId))
444+ let supporters = split_4C(supportersStr, SEP)
445+ if (containsElement(supporters, toString(generator)))
446+ then nil
447+ else [StringEntry(supportersKey(chainId), ((supportersStr + SEP) + toString(generator)))]
448+ }
449+
450+
451+func setOrFail (flags,index) = if ((0 > index))
452+ then throw(("Can't withdraw at negative index: " + toString(index)))
453+ else {
454+ let flagsSize = size(flags)
455+ if ((index >= flagsSize))
456+ then {
457+ let addZeroes = (index - flagsSize)
458+ if ((addZeroes > size(zeroesStr)))
459+ then throw((("Can't add " + toString(addZeroes)) + " empty flags. Contact with developers"))
460+ else ((flags + take(zeroesStr, addZeroes)) + "1")
461+ }
462+ else {
463+ let tail = drop(flags, index)
464+ let atIndex = take(tail, 1)
465+ if ((atIndex == "0"))
466+ then ((take(flags, index) + "1") + drop(tail, 1))
467+ else throw((("Transfer #" + toString(index)) + " has been already taken"))
468+ }
469+ }
470+
471+
472+func validateBlockHash (hexStr) = {
473+ let decodedBytes = fromBase16String(hexStr)
474+ if ((size(decodedBytes) != BLOCK_HASH_SIZE))
475+ then throw("invalid block id length")
476+ else hexStr
477+ }
478+
479+
480+func getUpdateFinalizedBlockAction (caller,newBlockHashHex,prevEpoch) = {
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))
524+ then true
525+ else (blockMeta(newFinalizedBlockHash)._1 > curFinalizedBlockMeta._1))
526+ then [StringEntry(finalizedBlockKey, newFinalizedBlockHash)]
527+ else nil))
528+ }
529+
530+
531+@Callable(i)
532+func extendMainChain (blockHashHex,referenceHex,vrf,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
533+ let checkBlockHash = validateBlockHash(blockHashHex)
534+ if ((checkBlockHash == checkBlockHash))
535+ then {
536+ let checkEpoch = ensureCorrectEpoch(vrf)
537+ if ((checkEpoch == checkEpoch))
538+ then {
539+ let checkChain = ensureExpectedOrInactiveChain(i.originCaller, mainChainId, unit)
540+ if ((checkChain == checkChain))
541+ then {
542+ let checkReference = isReferenceCorrect(referenceHex, mainChainLastBlock)
543+ if ((checkReference == checkReference))
544+ then {
545+ let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._6, lastC2ETransferIndex, true)
546+ if ((checkTransfers == checkTransfers))
547+ then {
548+ let thisEpochMeta = match epochMeta(height) {
549+ case _: Unit =>
550+ StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(mainChainEpoch)) + SEP) + blockHashHex))
551+ case other =>
552+ throw("Epoch already started")
553+ }
554+ if ((thisEpochMeta == thisEpochMeta))
555+ then {
556+ let checkGenerator = ensureMiningEpoch(i.originCaller)
557+ if ((checkGenerator == checkGenerator))
558+ then {
559+ let updateFinalizedBlock = getUpdateFinalizedBlockAction(i.originCaller, blockHashHex, mainChainEpoch)
560+ let newChainHeight = (mainChainHeight + 1)
561+ ([mkBlockMetaEntry(blockHashHex, newChainHeight, mainChainLastBlock, mainChainId, e2cTransfersRootHashHex, lastC2ETransferIndex), mkChainMetaEntry(mainChainId, newChainHeight, blockHashHex), IntegerEntry(minerChainIdKey(i.originCaller), mainChainId), IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), newChainHeight), thisEpochMeta] ++ updateFinalizedBlock)
562+ }
563+ else throw("Strict value is not equal to itself.")
564+ }
565+ else throw("Strict value is not equal to itself.")
566+ }
567+ else throw("Strict value is not equal to itself.")
568+ }
569+ else throw("Strict value is not equal to itself.")
570+ }
571+ else throw("Strict value is not equal to itself.")
572+ }
573+ else throw("Strict value is not equal to itself.")
574+ }
575+ else throw("Strict value is not equal to itself.")
576+ }
577+
578+
579+
580+@Callable(i)
581+func startAltChain (blockHashHex,referenceHex,vrf,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
582+ let checkBlockHash = validateBlockHash(blockHashHex)
583+ if ((checkBlockHash == checkBlockHash))
584+ then {
585+ let checkEpoch = ensureCorrectEpoch(vrf)
586+ if ((checkEpoch == checkEpoch))
587+ then {
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
595+ let finalizedEpoch = blockMeta(getStringValue(finalizedBlockKey))._2
596+ let epochRef = if ((refEpoch >= finalizedEpoch))
597+ then refEpoch
598+ else throw((((("Can not start alt chain from epoch " + toString(refEpoch)) + ", epoch ") + toString(finalizedEpoch)) + " is finalized"))
599+ let checkChain = ensureExpectedOrInactiveChain(i.originCaller, mainChainId, referenceHex)
600+ if ((checkChain == checkChain))
601+ then {
602+ let checkTransfers = ensureCorrectTransfers(refTransferIndex, lastC2ETransferIndex, true)
603+ if ((checkTransfers == checkTransfers))
604+ then {
605+ let newChainId = (valueOrElse(getInteger(lastChainIdKey), 0) + 1)
606+ let newChainHeight = (refChainHeight + 1)
607+ let thisEpochMeta = match epochMeta(height) {
608+ case _: Unit =>
609+ StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(epochRef)) + SEP) + blockHashHex))
610+ case other =>
611+ throw("Epoch already started")
612+ }
613+ let checkGenerator = ensureMiningEpoch(i.originCaller)
614+ if ((checkGenerator == checkGenerator))
615+ 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)]
616+ else throw("Strict value is not equal to itself.")
617+ }
618+ else throw("Strict value is not equal to itself.")
619+ }
620+ else throw("Strict value is not equal to itself.")
621+ }
622+ else throw("Strict value is not equal to itself.")
623+ }
624+ else throw("Strict value is not equal to itself.")
625+ }
626+
627+
628+
629+@Callable(i)
630+func extendAltChain (blockHashHex,referenceHex,vrf,chainId,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
631+ let checkBlockHash = validateBlockHash(blockHashHex)
632+ if ((checkBlockHash == checkBlockHash))
633+ then {
634+ let checkEpoch = ensureCorrectEpoch(vrf)
635+ if ((checkEpoch == checkEpoch))
636+ then {
637+ let chainFirstBlockMeta = blockMeta(getStringValue(chainFirstBlockIdKey(chainId)))
638+ let checkChain = ensureExpectedOrInactiveChain(i.originCaller, chainId, toBase16String(chainFirstBlockMeta._3))
639+ if ((checkChain == checkChain))
640+ then {
641+ let $t01971619770 = chainMeta(chainId)
642+ let chainHeight = $t01971619770._1
643+ let chainLastBlock = $t01971619770._2
644+ let checkReference = isReferenceCorrect(referenceHex, chainLastBlock)
645+ if ((checkReference == checkReference))
646+ then {
647+ let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._6, lastC2ETransferIndex, true)
648+ if ((checkTransfers == checkTransfers))
649+ then {
650+ let newChainHeight = (chainHeight + 1)
651+ let prevEpoch = blockMeta(referenceHex)._2
652+ let updateMainChainData = if ((supportingBalance(chainId) > (computedTotalBalance / 2)))
653+ then {
654+ let lastChainId = valueOrElse(getInteger(lastChainIdKey), 0)
655+ let updateFinalizedBlock = getUpdateFinalizedBlockAction(i.originCaller, blockHashHex, prevEpoch)
656+ ([IntegerEntry(chainForkedHeightKey(mainChainId), chainFirstBlockMeta._1), IntegerEntry(mainChainIdKey, chainId), IntegerEntry(firstValidAltChainIdKey, (lastChainId + 1))] ++ updateFinalizedBlock)
657+ }
658+ else nil
659+ let thisEpochMeta = match epochMeta(height) {
660+ case _: Unit =>
661+ StringEntry(epochMetaKey(height), ((((toString(i.originCaller) + SEP) + toString(prevEpoch)) + SEP) + blockHashHex))
662+ case other =>
663+ throw("Epoch already started")
664+ }
665+ if ((thisEpochMeta == thisEpochMeta))
666+ then {
667+ let checkGenerator = ensureMiningEpoch(i.originCaller)
668+ if ((checkGenerator == checkGenerator))
669+ then {
670+ let updateMainChainLastMinedBlock = if (if ((updateMainChainData == nil))
671+ then (valueOrElse(minerChainId(i.originCaller), 0) != chainId)
672+ else false)
673+ then [IntegerEntry(chainLastHeightKey(mainChainId, i.originCaller), chainFirstBlockMeta._1)]
674+ else nil
675+ ((([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)
676+ }
677+ else throw("Strict value is not equal to itself.")
678+ }
679+ else throw("Strict value is not equal to itself.")
680+ }
681+ else throw("Strict value is not equal to itself.")
682+ }
683+ else throw("Strict value is not equal to itself.")
684+ }
685+ else throw("Strict value is not equal to itself.")
686+ }
687+ else throw("Strict value is not equal to itself.")
688+ }
689+ else throw("Strict value is not equal to itself.")
690+ }
691+
692+
693+
694+@Callable(i)
695+func appendBlock (blockHashHex,referenceHex,e2cTransfersRootHashHex,lastC2ETransferIndex) = {
696+ let checkCaller = if ((thisEpochMiner == i.originCaller))
697+ then true
698+ else match thisEpochMiner {
699+ case epochMiner: Address =>
700+ throw(("not allowed to forge blocks in this epoch, expected from " + toString(epochMiner)))
701+ case _ =>
702+ throw("not allowed to forge blocks in this epoch, epoch miner is absent")
703+ }
704+ if ((checkCaller == checkCaller))
705+ then {
706+ let chainId = valueOrElse(minerChainId(i.originCaller), mainChainId)
707+ let $t02211922170 = chainMeta(chainId)
708+ let chainHeight = $t02211922170._1
709+ let lastBlockId = $t02211922170._2
710+ let checkReference = isReferenceCorrect(referenceHex, lastBlockId)
711+ if ((checkReference == checkReference))
712+ then {
713+ let checkTransfers = ensureCorrectTransfers(blockMeta(referenceHex)._6, lastC2ETransferIndex, false)
714+ if ((checkTransfers == checkTransfers))
715+ then {
716+ let newChainHeight = (chainHeight + 1)
717+ let checkBlockHash = validateBlockHash(blockHashHex)
718+ if ((checkBlockHash == checkBlockHash))
719+ 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))]
720+ else throw("Strict value is not equal to itself.")
721+ }
722+ else throw("Strict value is not equal to itself.")
723+ }
724+ else throw("Strict value is not equal to itself.")
725+ }
726+ else throw("Strict value is not equal to itself.")
727+ }
728+
729+
730+
731+@Callable(i)
732+func join (rewardAddressHex) = {
733+ func ensureNotOverrideOtherMinerPk (elAddressHex) = match getBinary(minerPkKey(elAddressHex)) {
734+ case pk: ByteVector =>
735+ if ((pk == i.originCallerPublicKey))
736+ then unit
737+ else throw(((("EL miner address " + elAddressHex) + " is already linked with ") + toBase58String(pk)))
738+ case _ =>
739+ unit
740+ }
741+
742+ let parts = split(rewardAddressHex, "0x")
743+ let rewardAddress = fromBase16String(parts[(size(parts) - 1)])
744+ let networkIsLaunched = match getInteger("launchHeight") {
745+ case launchHeight: Int =>
746+ (height >= launchHeight)
747+ case _ =>
748+ throw("not launched yet")
749+ }
750+ if (if (!(isContractSetup()))
751+ then true
752+ else !(networkIsLaunched))
753+ then throw("The contract has not yet set up")
754+ else if ((MIN_BALANCE > wavesBalance(i.originCaller).generating))
755+ then throw(((("Insufficient generating balance: " + toString(wavesBalance(i.originCaller).generating)) + ". Required: ") + toString(MIN_BALANCE)))
756+ else if ((size(rewardAddress) != 20))
757+ then throw("rewardAddress should be an L2 address")
758+ else if ((size(allMiners) >= 50))
759+ then throw("too many miners")
760+ else {
761+ func checkExistence (exists,miner) = if (exists)
762+ then true
763+ else (miner == toString(i.originCaller))
764+
765+ let alreadyExists = {
766+ let $l = allMiners
767+ let $s = size($l)
768+ let $acc0 = false
769+ func $f0_1 ($a,$i) = if (($i >= $s))
770+ then $a
771+ else checkExistence($a, $l[$i])
772+
773+ func $f0_2 ($a,$i) = if (($i >= $s))
774+ then $a
775+ else throw("List size exceeds 50")
776+
777+ $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)
778+ }
779+ if (alreadyExists)
780+ then nil
781+ else {
782+ let newMiner = toString(i.originCaller)
783+ let lowercaseRewardAddress = toBase16String(rewardAddress)
784+ let check = ensureNotOverrideOtherMinerPk(lowercaseRewardAddress)
785+ if ((check == check))
786+ then {
787+ let newMiners = if ((size(allMiners) == 0))
788+ then newMiner
789+ else ((allMinersStr + SEP) + newMiner)
790+ let deletePrevRewardAddressPk = match getString(minerRewardAddressKey(newMiner)) {
791+ case prevAddress: String =>
792+ if ((prevAddress == toBase16String(rewardAddress)))
793+ then nil
794+ else [DeleteEntry(minerPkKey(prevAddress))]
795+ case _ =>
796+ nil
797+ }
798+ ([StringEntry(allMinersKey, newMiners), StringEntry(minerRewardAddressKey(newMiner), ("0x" + lowercaseRewardAddress)), BinaryEntry(minerPkKey(lowercaseRewardAddress), i.originCallerPublicKey)] ++ deletePrevRewardAddressPk)
799+ }
800+ else throw("Strict value is not equal to itself.")
801+ }
802+ }
803+ }
804+
805+
806+
807+@Callable(i)
808+func leave () = {
809+ let leavingMiner = toString(i.originCaller)
810+ func skipLeavingMiner (acc,miner) = if ((miner == leavingMiner))
811+ then acc
812+ else (acc :+ miner)
813+
814+ let remainingMiners = {
815+ let $l = allMiners
816+ let $s = size($l)
817+ let $acc0 = nil
818+ func $f0_1 ($a,$i) = if (($i >= $s))
819+ then $a
820+ else skipLeavingMiner($a, $l[$i])
821+
822+ func $f0_2 ($a,$i) = if (($i >= $s))
823+ then $a
824+ else throw("List size exceeds 50")
825+
826+ $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)
827+ }
828+ let rewardAddrKey = minerRewardAddressKey(leavingMiner)
829+ let prevRewardAddress = valueOrErrorMessage(getString(this, rewardAddrKey), "miner has never joined")
830+ if ((prevRewardAddress == prevRewardAddress))
831+ then if ((thisEpochMiner == i.originCaller))
832+ then throw("designated miner can't leave")
833+ else [StringEntry(allMinersKey, makeString_2C(remainingMiners, SEP))]
834+ else throw("Strict value is not equal to itself.")
835+ }
836+
837+
838+
839+@Callable(i)
840+func transfer (destElAddressHex) = {
841+ let checkAddress = if ((size(destElAddressHex) == ETH_ADDRESS_STR_SIZE))
842+ then fromBase16String(destElAddressHex)
843+ else throw(((("Address should have " + toString(ETH_ADDRESS_STR_SIZE)) + " characters, got ") + toString(size(destElAddressHex))))
844+ if ((checkAddress == checkAddress))
845+ then {
846+ let checkPayment = if ((size(i.payments) == 1))
847+ then true
848+ else throw(("Expected one payment as a transfer amount, got " + toString(size(i.payments))))
849+ if ((checkPayment == checkPayment))
850+ then {
851+ let tokenIdStr = getStringValue(tokenIdKey)
852+ let tokenId = fromBase58String(tokenIdStr)
853+ let t = i.payments[0]
854+ let checkAssetId = match t.assetId {
855+ case assetId: ByteVector =>
856+ if ((assetId == tokenId))
857+ then true
858+ else throw(((("Expected " + tokenIdStr) + " in the payment, got ") + toBase58String(assetId)))
859+ case _ =>
860+ throw((("Expected " + tokenIdStr) + " in the payment, got Waves"))
861+ }
862+ if ((checkAssetId == checkAssetId))
863+ then {
864+ let lastIndex = blockMeta(mainChainLastBlock)._6
865+ let queueSize = (nativeTransfersCount - lastIndex)
866+ let checkQueueLimit = if ((160 > queueSize))
867+ then amountGtEq(t, 1000000, queueSize)
868+ else if ((1600 > queueSize))
869+ then amountGtEq(t, 10000000, queueSize)
870+ else if ((3200 > queueSize))
871+ then amountGtEq(t, 100000000, queueSize)
872+ else if ((6400 > queueSize))
873+ then amountGtEq(t, 1000000000, queueSize)
874+ else throw((("Transfers denied for queue size of " + toString(queueSize)) + ". Wait until current transfers processed"))
875+ if ((checkQueueLimit == checkQueueLimit))
876+ then [IntegerEntry(nativeTransfersCountKey, (nativeTransfersCount + 1)), mkNativeTransferEntry(nativeTransfersCount, destElAddressHex, t.amount), Burn(tokenId, t.amount)]
877+ else throw("Strict value is not equal to itself.")
878+ }
879+ else throw("Strict value is not equal to itself.")
880+ }
881+ else throw("Strict value is not equal to itself.")
882+ }
883+ else throw("Strict value is not equal to itself.")
884+ }
885+
886+
887+
888+@Callable(i)
889+func withdraw (blockHashHex,merkleProof,transferIndexInBlock,amount) = {
890+ let withdrawBlockMeta = blockMeta(blockHashHex)
891+ let withdrawBlockHeight = withdrawBlockMeta._1
892+ let finalizedBlockHeight = blockMeta(getStringValue(finalizedBlockKey))._1
893+ let mainChainLastBlockHeight = blockMeta(mainChainLastBlock)._1
894+ if ((withdrawBlockHeight > finalizedBlockHeight))
895+ then throw(((("EL block #" + toString(withdrawBlockHeight)) + " is not finalized. The current finalized is #") + toString(finalizedBlockHeight)))
896+ else if ((size(merkleProof) != WITHDRAW_PROOFS_SIZE))
897+ then throw(((("Expected " + toString(WITHDRAW_PROOFS_SIZE)) + " proofs, got ") + toString(size(merkleProof))))
898+ else if ((0 > transferIndexInBlock))
899+ then throw(("Transfer index in block should be nonnegative, got " + toString(transferIndexInBlock)))
900+ else if ((0 >= amount))
901+ then throw(("Amount should be positive, got " + toString(amount)))
902+ else {
903+ let withdrawBlockChainId = withdrawBlockMeta._4
904+ let isMainChain = (withdrawBlockChainId == mainChainId)
905+ let relatesToMainChain = match getInteger(chainForkedHeightKey(withdrawBlockChainId)) {
906+ case forkedHeight: Int =>
907+ (forkedHeight > withdrawBlockHeight)
908+ case _ =>
909+ throw((((blockHashHex + " is on an alternative chain #") + toString(withdrawBlockChainId)) + " that was not approved by majority. Wait for some blocks"))
910+ }
911+ if (if (isMainChain)
912+ then true
913+ else relatesToMainChain)
914+ then {
915+ let recipient = i.originCaller
916+ let recipientPkHash = take(drop(recipient.bytes, 2), PUBLIC_KEY_HASH_SIZE)
917+ let zeroAmountBytes = base58'11111111111111111111111111111111111111111111'
918+ let amountBytes = toBytes(amount)
919+ let elEventData = ((recipientPkHash + take(zeroAmountBytes, (size(zeroAmountBytes) - size(amountBytes)))) + amountBytes)
920+ let elEventDataDigest = blake2b256_16Kb(elEventData)
921+ let calculatedRootHash = createMerkleRoot(merkleProof, elEventDataDigest, transferIndexInBlock)
922+ let expectedRootHash = withdrawBlockMeta._5
923+ if ((calculatedRootHash == expectedRootHash))
924+ then {
925+ let tokenId = fromBase58String(getStringValue(tokenIdKey))
926+ let transfersKey = blockE2CTransfersKey(blockHashHex)
927+[Reissue(tokenId, amount, true), ScriptTransfer(recipient, amount, tokenId), StringEntry(transfersKey, setOrFail(valueOrElse(getString(transfersKey), ""), transferIndexInBlock))]
928+ }
929+ else throw((((((("Expected root hash: " + toBase16String(expectedRootHash)) + ", got: ") + toBase16String(calculatedRootHash)) + ". Event data digest: ") + toBase64String(elEventDataDigest)) + ". Check your withdraw arguments"))
930+ }
931+ else throw((("Expected " + blockHashHex) + " to be either on the main chain or relate to it"))
932+ }
933+ }
934+
935+
936+
937+@Callable(i)
938+func setup (genesisBlockHashHex,minerRewardInGwei,daoAddress,daoReward) = if (isContractSetup())
939+ then throw("The contract has been already set up")
940+ else if ((0 > minerRewardInGwei))
941+ then throw("The miner reward must be nonnegative")
942+ else {
943+ let genesisBlockHash = fromBase16String(genesisBlockHashHex)
944+ let checkGenesisBlockHashSize = if ((size(genesisBlockHash) == BLOCK_HASH_SIZE))
945+ then true
946+ else throw("Wrong genesis block hash")
947+ if ((checkGenesisBlockHashSize == checkGenesisBlockHashSize))
948+ then {
949+ let emptyPk = base58'11111111111111111111111111111111'
950+ let genesisMinerAddress = addressFromPublicKey(emptyPk)
951+ let genesisEthRewardAddress = base58'11111111111111111111'
952+ let genesisBlockReferenceHash = "0000000000000000000000000000000000000000000000000000000000000000"
953+ let issue = Issue("UNIT0", "Native token", 0, 8, true)
954+ let tokenId = calculateAssetId(issue)
955+ let genesisBlockMeta = mkBlockMetaEntry(genesisBlockHashHex, 0, genesisBlockReferenceHash, 0, toBase16String(base58''), -1)
956+ let daoEntries = if ((daoAddress == ""))
957+ then nil
958+ else [StringEntry(daoAddressKey, toString(Address(fromBase58String(daoAddress)))), IntegerEntry(daoRewardKey, if ((daoReward > 0))
959+ then daoReward
960+ else throw("invalid DAO reward amount"))]
961+ ([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)
962+ }
963+ else throw("Strict value is not equal to itself.")
964+ }
965+
966+
967+@Verifier(tx)
968+func verify () = {
969+ let u0 = sigVerify_32Kb(tx.bodyBytes, tx.proofs[0], base58'66Fb7Ef34ainTAL887b57BVCNBrtdRyA86dSAXuwt2mn')
970+ let u1 = sigVerify_32Kb(tx.bodyBytes, tx.proofs[1], base58'F5ComSeqBY46duPnYYh9YkrEAe12Ztaq1rDQqtYZFpKp')
971+ let u2 = sigVerify_32Kb(tx.bodyBytes, tx.proofs[2], base58'53TLiKfhLWr2tN9DLgEHs8sf42hbUj3JpE6uxsDPZtnM')
972+ if (u0)
973+ then if (u1)
974+ then true
975+ else u2
976+ else if (u1)
977+ then u2
978+ else false
979+ }
980+

github/deemru/w8io/169f3d6 
58.68 ms